Skip to content
Source
Sign inSign up
Open History to see the last commit

semver.test.ts

94 lines4.1 KB

1import { describe, expect, it } from "vite-plus/test";
2​
3import {
4 compareSemverVersions,
5 normalizeSemverVersion,
6 parseSemver,
7 satisfiesSemverRange,
8} from "./semver.ts";
9​
10describe("semver helpers", () => {
11 it("matches supported range groups", () => {
12 const range = "^22.16 || ^23.11 || >=24.10";
13​
14 expect(satisfiesSemverRange("22.16.0", range)).toBe(true);
15 expect(satisfiesSemverRange("23.11.1", range)).toBe(true);
16 expect(satisfiesSemverRange("24.10.0", range)).toBe(true);
17 expect(satisfiesSemverRange("22.15.9", range)).toBe(false);
18 expect(satisfiesSemverRange("23.10.9", range)).toBe(false);
19 expect(satisfiesSemverRange("24.9.9", range)).toBe(false);
20 });
21​
22 it("normalizes and parses shorthand major-only versions", () => {
23 expect(normalizeSemverVersion("20")).toBe("20.0.0");
24 expect(normalizeSemverVersion("v18")).toBe("v18.0.0");
25 expect(normalizeSemverVersion("20-rc.1")).toBe("20.0.0-rc.1");
26 expect(parseSemver("20")).toEqual({ major: 20, minor: 0, patch: 0, prerelease: [] });
27 });
28​
29 it("compares shorthand versions numerically instead of lexically", () => {
30 expect(compareSemverVersions("20", "9")).toBeGreaterThan(0);
31 expect(compareSemverVersions("18", "18.0.0")).toBe(0);
32 });
33​
34 it("compares prerelease versions before stable versions", () => {
35 expect(compareSemverVersions("2.1.111-beta.1", "2.1.111")).toBeLessThan(0);
36 });
37​
38 it("preserves hyphens within prerelease identifiers", () => {
39 expect(normalizeSemverVersion("20-alpha-1")).toBe("20.0.0-alpha-1");
40 expect(parseSemver("1.2.3-alpha-1.2")).toEqual({
41 major: 1,
42 minor: 2,
43 patch: 3,
44 prerelease: ["alpha-1", "2"],
45 });
46 expect(parseSemver("1.2.3-x-y-z.--")?.prerelease).toEqual(["x-y-z", "--"]);
47 });
48​
49 it("distinguishes releases whose identifiers differ after a hyphen", () => {
50 expect(compareSemverVersions("1.2.3-alpha-1", "1.2.3-alpha-2")).toBeLessThan(0);
51 expect(compareSemverVersions("1.2.3-alpha-2", "1.2.3-alpha-1")).toBeGreaterThan(0);
52 expect(compareSemverVersions("1.2.3-alpha-1.2", "1.2.3-alpha-1.10")).toBeLessThan(0);
53 expect(compareSemverVersions("1.2.3-alpha.1+build-2", "1.2.3-alpha.1+build-3")).toBe(0);
54 });
55​
56 it("supports comparison comparators", () => {
57 expect(satisfiesSemverRange("24.9.0", ">=24.0 <24.10")).toBe(true);
58 expect(satisfiesSemverRange("24.10.0", ">=24.0 <24.10")).toBe(false);
59 for (const gap of [" ", "\t", "\n"]) {
60 const range = `>=${gap}24.0 <${gap}24.10`;
61 expect(satisfiesSemverRange("24.9.0", range)).toBe(true);
62 expect(satisfiesSemverRange("24.10.0", range)).toBe(false);
63 expect(satisfiesSemverRange("22.16.0", `^${gap}22.16 || >=${gap}24.10`)).toBe(true);
64 }
65 });
66​
67 it("honors caret range upper bounds for zero-major versions", () => {
68 expect(satisfiesSemverRange("0.5.0", "^0")).toBe(true);
69 expect(satisfiesSemverRange("0.0.4", "^0.0")).toBe(true);
70 expect(satisfiesSemverRange("1.0.0", "^0")).toBe(false);
71 expect(satisfiesSemverRange("0.1.0", "^0.0")).toBe(false);
72 expect(satisfiesSemverRange("0.2.3", "^0.2.3")).toBe(true);
73 expect(satisfiesSemverRange("0.2.9", "^0.2.3")).toBe(true);
74 expect(satisfiesSemverRange("0.3.0", "^0.2.3")).toBe(false);
75 expect(satisfiesSemverRange("0.5.0", "^0.2.3")).toBe(false);
76 expect(satisfiesSemverRange("0.0.3", "^0.0.3")).toBe(true);
77 expect(satisfiesSemverRange("0.0.4", "^0.0.3")).toBe(false);
78 expect(satisfiesSemverRange("0.0.0", "^0.0.0")).toBe(true);
79 expect(satisfiesSemverRange("0.0.1", "^0.0.0")).toBe(false);
80 });
81​
82 it("keeps the range checker stringifiable and executable as plain JavaScript", () => {
83 const source = satisfiesSemverRange.toString();
84 const recreated = Function(`return (${source});`)() as typeof satisfiesSemverRange;
85​
86 expect(source).toContain("function satisfiesSemverRange");
87 expect(source).not.toContain(": string");
88 expect(source).not.toContain(": boolean");
89 expect(recreated("0.5.0", "^0")).toBe(true);
90 expect(recreated("0.0.4", "^0.0")).toBe(true);
91 expect(recreated("24.10.0", ">=24.10")).toBe(true);
92 expect(recreated("24.9.9", ">=24.10")).toBe(false);
93 });
94});