UNPKG

@cyclonedx/cdxgen

Version:

Creates CycloneDX Software Bill of Materials (SBOM) from source or container image

316 lines (278 loc) 10.3 kB
import { strict as assert } from "node:assert"; import { describe, it } from "poku"; import { toVersRange } from "./versutils.js"; describe("toVersRange", () => { // === Basic Validation === describe("input validation", () => { it("should return empty for null/undefined/empty", () => { assert.strictEqual(toVersRange(null), ""); assert.strictEqual(toVersRange(undefined), ""); assert.strictEqual(toVersRange(""), ""); assert.strictEqual(toVersRange(" "), ""); }); it("should return empty for non-string input", () => { assert.strictEqual(toVersRange(123), ""); assert.strictEqual(toVersRange({}), ""); assert.strictEqual(toVersRange([]), ""); }); }); // === Special Markers === describe("special markers", () => { it("should handle wildcard '*'", () => { assert.strictEqual(toVersRange("*"), "vers:npm/*"); }); it("should return empty for 'latest'", () => { assert.strictEqual(toVersRange("latest"), ""); }); it("should return empty for workspace:* references", () => { assert.strictEqual(toVersRange("workspace:*"), ""); assert.strictEqual(toVersRange("workspace:^1.0.0"), ""); assert.strictEqual(toVersRange("workspace:~"), ""); }); }); // === Simple Operators === describe("simple comparison operators", () => { it("should handle >= operator", () => { assert.strictEqual(toVersRange(">=4.1.0"), "vers:npm/>=4.1.0"); assert.strictEqual(toVersRange(">= 1.6.9"), "vers:npm/>=1.6.9"); assert.strictEqual( toVersRange(">=v2.0.0-alpha8"), "vers:npm/>=2.0.0-alpha8", ); }); it("should handle <= operator", () => { assert.strictEqual(toVersRange("<=4.0.4"), "vers:npm/<=4.0.4"); assert.strictEqual(toVersRange("<= 1.6.8"), "vers:npm/<=1.6.8"); assert.strictEqual( toVersRange("<=v2.0.0-alpha7"), "vers:npm/<=2.0.0-alpha7", ); }); it("should handle < operator", () => { assert.strictEqual(toVersRange("<0.0.0"), "vers:npm/<0.0.0"); assert.strictEqual(toVersRange("<2.11.2"), "vers:npm/<2.11.2"); assert.strictEqual(toVersRange("< 6.1.0"), "vers:npm/<6.1.0"); }); it("should handle > operator", () => { assert.strictEqual(toVersRange(">0.12.7"), "vers:npm/>0.12.7"); assert.strictEqual(toVersRange("> 0.9.6"), "vers:npm/>0.9.6"); assert.strictEqual(toVersRange(">3.0.0"), "vers:npm/>3.0.0"); }); it("should handle = operator (exact version)", () => { assert.strictEqual(toVersRange("=3.0.0-rc.1"), "vers:npm/3.0.0-rc.1"); }); }); // === Exact Versions === describe("exact versions", () => { it("should convert plain version strings", () => { assert.strictEqual(toVersRange("2.1.4"), "vers:npm/2.1.4"); assert.strictEqual(toVersRange("7.0.0"), "vers:npm/7.0.0"); assert.strictEqual(toVersRange("2.3.21"), "vers:npm/2.3.21"); }); it("should handle prerelease exact versions", () => { assert.strictEqual(toVersRange("2.1.0-M1"), "vers:npm/2.1.0-M1"); assert.strictEqual(toVersRange("3.0.0-rc.1"), "vers:npm/3.0.0-rc.1"); }); it("should strip 'v' prefix from versions", () => { assert.strictEqual(toVersRange("v2.0.0"), "vers:npm/2.0.0"); assert.strictEqual( toVersRange(">=v2.0.0-alpha8"), "vers:npm/>=2.0.0-alpha8", ); }); }); // === AND Conditions (space-separated) === describe("AND conditions (space-separated)", () => { it("should convert space-separated ranges to pipe-separated", () => { assert.strictEqual( toVersRange(">=2.0.0 <=4.0.4"), "vers:npm/>=2.0.0|<=4.0.4", ); assert.strictEqual( toVersRange(">= 2.0.1 <3.0.2"), "vers:npm/>=2.0.1|<3.0.2", ); assert.strictEqual( toVersRange(">= 15.0.0 <= 16.1.0"), "vers:npm/>=15.0.0|<=16.1.0", ); assert.strictEqual( toVersRange(">=5.0.3 >=4.2.1"), "vers:npm/>=4.2.1|>=5.0.3", ); }); it("should handle two-part version padding in AND ranges", () => { assert.strictEqual( toVersRange("<=2.1 >=1.1"), "vers:npm/>=1.1.0|<=2.1.0", ); }); }); // === OR Conditions (||) === describe("OR conditions (||)", () => { it("should convert || to single |", () => { assert.strictEqual( toVersRange(">=1.5.2 || >=1.4.11 <1.5.0 || >=1.3.2 <1.4.0"), "vers:npm/>=1.3.2|<1.4.0|>=1.4.11|<1.5.0|>=1.5.2", ); assert.strictEqual( toVersRange(">=1.3.0 <1.3.2 || >=1.4.0 <1.4.11 || >=1.5.0 <1.5.2"), "vers:npm/>=1.3.0|<1.3.2|>=1.4.0|<1.4.11|>=1.5.0|<1.5.2", ); }); it("should handle complex OR ranges", () => { assert.strictEqual( toVersRange( ">=3.5.1 <4.0.0 || >=4.1.3 <5.0.0 || >=5.6.1 <6.0.0 || >=6.1.2", ), "vers:npm/>=3.5.1|<4.0.0|>=4.1.3|<5.0.0|>=5.6.1|<6.0.0|>=6.1.2", ); assert.strictEqual( toVersRange(">=2.5.0 <= 3.0.0 || >=3.1.0"), "vers:npm/>=2.5.0|<=3.0.0|>=3.1.0", ); }); it("should handle exact versions in OR ranges", () => { assert.strictEqual( toVersRange("2.1.0-M1 || 2.1.0-M2"), "vers:npm/2.1.0-M1|2.1.0-M2", ); assert.strictEqual( toVersRange("=3.10.1 || >=3.10.3"), "vers:npm/3.10.1|>=3.10.3", ); assert.strictEqual(toVersRange("2.1 || 2.6"), "vers:npm/2.1.0|2.6.0"); }); }); // === Caret Ranges (^) === describe("caret ranges (^)", () => { it("should expand caret for major >= 1", () => { assert.strictEqual(toVersRange("^1.2.9"), "vers:npm/>=1.2.9|<2.0.0"); assert.strictEqual(toVersRange("^2.0.18"), "vers:npm/>=2.0.18|<3.0.0"); assert.strictEqual(toVersRange("^4.0.8"), "vers:npm/>=4.0.8|<5.0.0"); }); it("should expand caret for major = 0, minor > 0", () => { assert.strictEqual( toVersRange("^0.2.1-beta"), "vers:npm/>=0.2.1-beta|<0.3.0", ); assert.strictEqual(toVersRange("^0.2.3"), "vers:npm/>=0.2.3|<0.3.0"); }); it("should expand caret for major = 0, minor = 0", () => { assert.strictEqual( toVersRange("^0.0.2-beta"), "vers:npm/>=0.0.2-beta|<0.0.3", ); assert.strictEqual(toVersRange("^0.0.3"), "vers:npm/>=0.0.3|<0.0.4"); }); it("should handle caret with prerelease", () => { assert.strictEqual( toVersRange("^1.2.3-beta.1"), "vers:npm/>=1.2.3-beta.1|<2.0.0", ); assert.strictEqual( toVersRange("^5.0.0-beta.5"), "vers:npm/>=5.0.0-beta.5|<6.0.0", ); }); it("should handle multiple caret ranges with OR", () => { assert.strictEqual( toVersRange("^2.0.18 || ^3.0.16 || ^3.1.6 || ^4.0.8 || ^5.0.0-beta.5"), "vers:npm/>=2.0.18|<3.0.0|>=3.0.16|>=3.1.6|<4.0.0|<4.0.0|>=4.0.8|>=5.0.0-beta.5|<5.0.0|<6.0.0", ); }); }); // === Tilde Ranges (~) === describe("tilde ranges (~)", () => { it("should expand tilde ranges", () => { assert.strictEqual(toVersRange("~3.8.2"), "vers:npm/>=3.8.2|<3.9.0"); assert.strictEqual(toVersRange("~1.6.5"), "vers:npm/>=1.6.5|<1.7.0"); }); it("should handle tilde with prerelease", () => { assert.strictEqual( toVersRange("~0.8.0-pre"), "vers:npm/>=0.8.0-pre|<0.8.0|>=0.8.0|<0.8.1", ); }); it("should handle tilde in OR ranges", () => { assert.strictEqual( toVersRange("~1.6.5 || >=1.7.2"), "vers:npm/>=1.6.5|<1.7.0|>=1.7.2", ); assert.strictEqual( toVersRange("~0.2.2 || >=0.3.2"), "vers:npm/>=0.2.2|<0.3.0|>=0.3.2", ); }); }); // === X-Wildcard Ranges === describe("x-wildcard ranges", () => { it("should expand major.x patterns", () => { assert.strictEqual(toVersRange(">= 1.x"), "vers:npm/>=1.0.0|<2.0.0"); assert.strictEqual(toVersRange(">= 2.2.x"), "vers:npm/>=2.2.0|<2.3.0"); }); it("should expand minor.x patterns", () => { assert.strictEqual(toVersRange("1.2.x"), "vers:npm/>=1.2.0|<1.3.0"); assert.strictEqual( toVersRange("2.0.x || 2.1.x"), "vers:npm/>=2.0.0|<2.1.0|>=2.1.0|<2.2.0", ); }); }); // === Hyphen Ranges === describe("hyphen ranges", () => { it("should convert hyphen ranges to >= and <=", () => { assert.strictEqual( toVersRange("5.0.0 - 7.2.3"), "vers:npm/>=5.0.0|<=7.2.3", ); }); }); // === Version Padding === describe("version padding", () => { it("should pad two-part versions to three parts", () => { assert.strictEqual(toVersRange(">= 1.1"), "vers:npm/>=1.1.0"); assert.strictEqual(toVersRange("<= 1.0"), "vers:npm/<=1.0.0"); assert.strictEqual(toVersRange(">= 3.11"), "vers:npm/>=3.11.0"); assert.strictEqual(toVersRange("<3.11"), "vers:npm/<3.11.0"); assert.strictEqual(toVersRange(">=4.5"), "vers:npm/>=4.5.0"); }); it("should handle padded versions in ranges", () => { assert.strictEqual( toVersRange(">=3.11 <4 || >=4.5"), "vers:npm/>=3.11.0|<4.0.0|>=4.5.0", ); }); }); // === Edge Cases === describe("edge cases", () => { it("should handle large version numbers", () => { assert.strictEqual( toVersRange("<=99.999.99999"), "vers:npm/<=99.999.99999", ); assert.strictEqual(toVersRange("<99.999.9999"), "vers:npm/<99.999.9999"); }); it("should handle spacing variations", () => { assert.strictEqual(toVersRange(">= 1.6.9"), "vers:npm/>=1.6.9"); assert.strictEqual(toVersRange("< 2.0.5"), "vers:npm/<2.0.5"); assert.strictEqual( toVersRange(">=3.4.6 < 4.0.0|| >=4.0.5"), "vers:npm/>=3.4.6|<4.0.0|>=4.0.5", ); }); it("should handle mixed operators in compound ranges", () => { assert.strictEqual( toVersRange("<5.0.3 >=5.0.0 || < 4.2.1"), "vers:npm/<4.2.1|>=5.0.0|<5.0.3", ); assert.strictEqual( toVersRange("<1.6.5 || < 2.1.7 > 2.0.0"), "vers:npm/<1.6.5|>2.0.0|<2.1.7", ); }); it("should handle multiple exact versions", () => { assert.strictEqual(toVersRange("1.1.2 1.2.2"), "vers:npm/1.1.2|1.2.2"); }); }); });