Add SemVer.compare static method for version comparison

This commit is contained in:
CPTProgrammer 2026-07-10 14:58:51 +08:00
parent 9bc693e3a1
commit f7e468f28f
No known key found for this signature in database
2 changed files with 63 additions and 0 deletions

View File

@ -48,6 +48,49 @@ describe("SemVer", () => {
}); });
}); });
describe("compare", () => {
test("相等", () => {
expect(SemVer.compare("1.0.0", "1.0.0")).toBe(0);
expect(SemVer.compare("1.0", "1.0")).toBe(0);
});
test("major 不同", () => {
expect(SemVer.compare("1.0.0", "2.0.0")).toBeLessThan(0);
expect(SemVer.compare("2.0.0", "1.0.0")).toBeGreaterThan(0);
});
test("minor 不同", () => {
expect(SemVer.compare("1.0.0", "1.1.0")).toBeLessThan(0);
expect(SemVer.compare("1.1.0", "1.0.0")).toBeGreaterThan(0);
});
test("patch 不同", () => {
expect(SemVer.compare("1.0.1", "1.0.2")).toBeLessThan(0);
expect(SemVer.compare("1.0.2", "1.0.1")).toBeGreaterThan(0);
});
test("缺 patch 视为 0", () => {
expect(SemVer.compare("1.0", "1.0.0")).toBe(0);
expect(SemVer.compare("1.0.1", "1.0")).toBeGreaterThan(0);
});
test("pre-release < 正式版", () => {
expect(SemVer.compare("1.0.0-alpha", "1.0.0")).toBeLessThan(0);
expect(SemVer.compare("1.0.0", "1.0.0-beta")).toBeGreaterThan(0);
});
test("可作排序用", () => {
const input = ["1.10.0", "1.2.0", "1.2.1", "1.2.0-beta"];
const sorted = input.toSorted(SemVer.compare);
expect(sorted).toEqual(["1.2.0-beta", "1.2.0", "1.2.1", "1.10.0"]);
});
test(">=26 版本", () => {
expect(SemVer.compare("26.1", "26.2")).toBeLessThan(0);
expect(SemVer.compare("27.0", "26.99")).toBeGreaterThan(0);
});
});
describe("format", () => { describe("format", () => {
test("两段", () => { test("两段", () => {
expect(new SemVer(1, 2).format()).toBe("1.2"); expect(new SemVer(1, 2).format()).toBe("1.2");

View File

@ -46,4 +46,24 @@ export class SemVer implements TemplateValue {
match[4] ?? null, match[4] ?? null,
); );
}; };
/**
* /0/
* Array.toSorted
*/
static compare(a: string, b: string): number {
const va = SemVer.parse(a);
const vb = SemVer.parse(b);
if (va.major !== vb.major) return va.major - vb.major;
if (va.minor !== vb.minor) return va.minor - vb.minor;
const pa = va.patch ?? 0;
const pb = vb.patch ?? 0;
if (pa !== pb) return pa - pb;
if (va.preRelease === null && vb.preRelease !== null) return 1;
if (va.preRelease !== null && vb.preRelease === null) return -1;
if (va.preRelease !== null && vb.preRelease !== null) {
return va.preRelease.localeCompare(vb.preRelease);
}
return 0;
}
} }