Support for single version in Forge ranges (#98)

* Added test cases for forge style single version "range"

* Made forge version range separator optional to allow single version

* Verify closed end version range is treated as typo for open end

* Interpret range as single version only in absence of separator

Fixes #95

---------

Co-authored-by: Kir_Antipov <40232067+Kir-Antipov@users.noreply.github.com>
This commit is contained in:
Luca v. d. W 2024-01-14 21:59:41 +01:00 committed by GitHub
parent f8cee9e545
commit cb6e2c96e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 1 deletions

View file

@ -85,7 +85,7 @@ function mixedToSemver(range: string): string {
/**
* Regular expression for matching interval expressions in version range strings.
*/
const INTERVAL_REGEX = /(?<from_bracket>\[|\()\s*(?<from>[^,\s]+)?\s*,\s*(?<to>[^,\s\])]+)?\s*(?<to_bracket>\]|\))/;
const INTERVAL_REGEX = /(?<from_bracket>\[|\()\s*(?<from>[^,\s]+)?\s*(?<separator>,)?\s*(?<to>[^,\s\])]+)?\s*(?<to_bracket>\]|\))/;
/**
* Converts an interval expression into a semver-compatible range expression.
@ -102,6 +102,7 @@ function intervalToSemver(range: string): string {
const fromOperator = match.groups.from_bracket === "[" ? ">=" : ">";
const from = match.groups.from;
const separator = match.groups.separator;
const toOperator = match.groups.to_bracket === "]" ? "<=" : "<";
const to = match.groups.to;
if (!from && !to) {
@ -112,6 +113,10 @@ function intervalToSemver(range: string): string {
return `${toOperator}${to}`;
}
if (!separator) {
return from;
}
if (!to) {
return `${fromOperator}${from}`;
}

View file

@ -69,6 +69,48 @@ describe("parseVersionRange", () => {
expect(versionRange.includes("2.0.1")).toBe(false);
});
test("parses an interval notation string with single version correctly", () => {
const versionRange = parseVersionRange("[1.2.3]");
expect(versionRange).toBeDefined();
expect(versionRange.toString()).toBe("[1.2.3]");
expect(versionRange.includes("1.2.3")).toBe(true);
expect(versionRange.includes("1.2.4")).toBe(false);
expect(versionRange.includes("2.0.0")).toBe(false);
expect(versionRange.includes("1.0.0")).toBe(false);
expect(versionRange.includes("1.2.2")).toBe(false);
expect(versionRange.includes("2.0.1")).toBe(false);
});
test("parses an interval notation string with single version open end correctly", () => {
const versionRange = parseVersionRange("[1.2.3,)");
expect(versionRange).toBeDefined();
expect(versionRange.toString()).toBe("[1.2.3,)");
expect(versionRange.includes("1.2.3")).toBe(true);
expect(versionRange.includes("1.2.4")).toBe(true);
expect(versionRange.includes("2.0.0")).toBe(true);
expect(versionRange.includes("2.0.1")).toBe(true);
expect(versionRange.includes("1.0.0")).toBe(false);
expect(versionRange.includes("1.2.2")).toBe(false);
});
test("parses an interval notation string with single version closed end as typo for open end", () => {
const versionRange = parseVersionRange("[1.2.3,]");
expect(versionRange).toBeDefined();
expect(versionRange.toString()).toBe("[1.2.3,]");
expect(versionRange.includes("1.2.3")).toBe(true);
expect(versionRange.includes("1.2.4")).toBe(true);
expect(versionRange.includes("2.0.0")).toBe(true);
expect(versionRange.includes("2.0.1")).toBe(true);
expect(versionRange.includes("1.0.0")).toBe(false);
expect(versionRange.includes("1.2.2")).toBe(false);
});
test("parses an interval notation string with X-ranges correctly", () => {
const versionRange = parseVersionRange("[1.2.x,2.0.X)");