| 1 | import { describe, expect, test } from "alchemy-test"; |
| 2 | |
| 3 | import { _internal } from "../../src/Cli/checkVersion"; |
| 4 | |
| 5 | const { pickDistTag, compareVersions } = _internal; |
| 6 | |
| 7 | describe("pickDistTag", { tags: ["unit", "local"] }, () => { |
| 8 | // Real shape returned by https://registry.npmjs.org/-/package/alchemy/dist-tags |
| 9 | const realDistTags = { latest: "0.93.7", next: "2.0.0-beta.33" }; |
| 10 | |
| 11 | test("beta version picks the matching prerelease tag (next) over latest", () => { |
| 12 | expect(pickDistTag("2.0.0-beta.30", realDistTags)).toBe("2.0.0-beta.33"); |
| 13 | }); |
| 14 | |
| 15 | test("stable version picks latest", () => { |
| 16 | expect(pickDistTag("0.93.6", realDistTags)).toBe("0.93.7"); |
| 17 | }); |
| 18 | |
| 19 | test("prefers identifier-named tag when present", () => { |
| 20 | expect( |
| 21 | pickDistTag("2.0.0-beta.30", { |
| 22 | latest: "0.93.7", |
| 23 | next: "2.0.0-rc.1", |
| 24 | beta: "2.0.0-beta.40", |
| 25 | }), |
| 26 | ).toBe("2.0.0-beta.40"); |
| 27 | }); |
| 28 | |
| 29 | test("falls back to next when no identifier-named tag exists", () => { |
| 30 | expect( |
| 31 | pickDistTag("2.0.0-rc.1", { latest: "0.93.7", next: "2.0.0-rc.2" }), |
| 32 | ).toBe("2.0.0-rc.2"); |
| 33 | }); |
| 34 | |
| 35 | test("falls back to latest when no prerelease channel exists", () => { |
| 36 | expect(pickDistTag("2.0.0-beta.30", { latest: "0.93.7" })).toBe("0.93.7"); |
| 37 | }); |
| 38 | |
| 39 | test("offers latest when it runs ahead of the channel tag (force-latest releases)", () => { |
| 40 | // Regression: a force-latest beta release left `next` stranded behind |
| 41 | // `latest` (latest=beta.68, next=beta.67). |
| 42 | expect( |
| 43 | pickDistTag("2.0.0-beta.67", { |
| 44 | latest: "2.0.0-beta.68", |
| 45 | next: "2.0.0-beta.67", |
| 46 | }), |
| 47 | ).toBe("2.0.0-beta.68"); |
| 48 | }); |
| 49 | }); |
| 50 | |
| 51 | describe("compareVersions", { tags: ["unit", "local"] }, () => { |
| 52 | test("orders prerelease numbers numerically, not lexically", () => { |
| 53 | expect(compareVersions("2.0.0-beta.68", "2.0.0-beta.67")).toBeGreaterThan( |
| 54 | 0, |
| 55 | ); |
| 56 | expect(compareVersions("2.0.0-beta.9", "2.0.0-beta.10")).toBeLessThan(0); |
| 57 | }); |
| 58 | |
| 59 | test("release outranks its prereleases", () => { |
| 60 | expect(compareVersions("2.0.0", "2.0.0-rc.1")).toBeGreaterThan(0); |
| 61 | expect(compareVersions("2.0.0-rc.1", "2.0.0")).toBeLessThan(0); |
| 62 | }); |
| 63 | |
| 64 | test("core versions compare numerically", () => { |
| 65 | expect(compareVersions("0.93.7", "0.93.6")).toBeGreaterThan(0); |
| 66 | expect(compareVersions("0.93.7", "2.0.0-beta.1")).toBeLessThan(0); |
| 67 | }); |
| 68 | |
| 69 | test("equal versions compare as 0 (stale tag must not warn)", () => { |
| 70 | expect(compareVersions("2.0.0-beta.68", "2.0.0-beta.68")).toBe(0); |
| 71 | }); |
| 72 | |
| 73 | test("alphanumeric prerelease identifiers rank above numeric ones", () => { |
| 74 | expect(compareVersions("2.0.0-rc.1", "2.0.0-beta.99")).toBeGreaterThan(0); |
| 75 | expect(compareVersions("2.0.0-beta.1", "2.0.0-1")).toBeGreaterThan(0); |
| 76 | }); |
| 77 | }); |