From 6d3f453dd75e08ae9ba0d3535084601a9cd902ef Mon Sep 17 00:00:00 2001 From: jdunsby Date: Tue, 11 Jul 2023 16:04:18 +0100 Subject: [PATCH] feat: ignore platform qualifiers BREAKING CHANGE: this separates platform qualifiers from the version being processed and disregards it when performing comparisons and other operations. --- .circleci/config.yml | 82 ++++++++++++++++++++++++++++++ .github/CODEOWNERS | 2 +- .nvmrc | 2 +- .pre-commit-config.yaml | 5 ++ jest.config.js | 3 +- lib/functions.ts | 17 ++++++- lib/ranges.ts | 4 +- lib/ruby/gem-requirement.ts | 6 ++- lib/ruby/gem-version.ts | 28 +++++++++- package.json | 14 ++--- test/comparison/cmp.test.ts | 38 +++++++++----- test/comparison/compare.test.ts | 5 +- test/comparison/diff.test.ts | 8 ++- test/comparison/eq.test.ts | 7 ++- test/comparison/gt.test.ts | 9 +++- test/comparison/gte.test.ts | 9 +++- test/comparison/lt.test.ts | 8 ++- test/comparison/lte.test.ts | 9 +++- test/comparison/neq.test.ts | 5 +- test/comparison/rcompare.test.ts | 11 +++- test/functions/major.test.ts | 13 ++++- test/functions/platform.test.ts | 28 ++++++++++ test/functions/prerelease.test.ts | 8 ++- test/functions/valid.test.ts | 6 ++- test/ranges/max-satisfying.test.ts | 31 +++++++++-- test/ranges/min-satisfying.test.ts | 27 ++++++++-- test/ranges/satisfies.test.ts | 9 +++- test/ranges/valid-range.test.ts | 4 +- tsconfig.json | 10 ++-- 29 files changed, 344 insertions(+), 64 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .pre-commit-config.yaml create mode 100644 test/functions/platform.test.ts diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..3011562 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,82 @@ +version: 2.1 + +orbs: + prodsec: snyk/prodsec-orb@1.0 + +executors: + docker-node: + parameters: + version: + default: 'lts' + type: string + docker: + - image: cimg/node:<> + +commands: + install: + steps: + - run: + name: Install + command: npm install + test: + steps: + - run: + name: Test + command: npm test + release: + steps: + - run: + name: Release + command: npx semantic-release + +jobs: + test: + resource_class: small + parameters: + node-version: + type: string + executor: + name: docker-node + version: << parameters.node-version >> + steps: + - checkout + - install + - test + + release: + resource_class: small + executor: + name: docker-node + steps: + - checkout + - install + - release + +workflows: + version: 2 + test: + jobs: + - prodsec/secrets-scan: + name: Scan repository for secrets + context: + - snyk-bot-slack + channel: os-team-managed-alerts + - test: + name: Test Node << matrix.node-version >> + context: nodejs-install + matrix: + parameters: + node-version: ['16.1.0'] + filters: + branches: + ignore: + - master + release: + jobs: + - release: + name: Release + context: nodejs-lib-release + filters: + branches: + only: + - master diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a820c5e..bc4ad40 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @snyk/loki +* @snyk/os-managed diff --git a/.nvmrc b/.nvmrc index 45a4fb7..b6a7d89 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -8 +16 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..c9528f4 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,5 @@ +repos: + - repo: https://github.com/gitleaks/gitleaks + rev: v8.16.1 + hooks: + - id: gitleaks diff --git a/jest.config.js b/jest.config.js index c40fe2a..e068a42 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,8 +1,7 @@ // remove the noise from express server logs -process.env.LOG_LEVEL="fatal"; +process.env.LOG_LEVEL = 'fatal'; module.exports = { preset: 'ts-jest', testEnvironment: 'node', }; - diff --git a/lib/functions.ts b/lib/functions.ts index a45f30e..0a4ab3b 100644 --- a/lib/functions.ts +++ b/lib/functions.ts @@ -1,6 +1,6 @@ -import { GemVersion, MaybeGemVersion } from './ruby/gem-version'; +import { GemVersion, MaybeGemVersion, Platform } from './ruby/gem-version'; -export { valid, prerelease, major, minor, patch, inc }; +export { valid, prerelease, platform, major, minor, patch, inc }; type Segment = string | number; @@ -37,6 +37,19 @@ function prerelease(v: MaybeGemVersion): Segment[] | null { } } +function platform(v: MaybeGemVersion): Platform | null { + try { + const version = GemVersion.create(v); + if (version.platform) { + return version.platform + } else { + return null; + } + } catch (err) { + return null; + } +} + function _segmentAt(v, index): Segment | null { try { const segment = GemVersion.create(v).getSegments()[index]; diff --git a/lib/ranges.ts b/lib/ranges.ts index 28d1085..9a6a638 100644 --- a/lib/ranges.ts +++ b/lib/ranges.ts @@ -77,11 +77,11 @@ function _firstSatisfying( compareFunction, ): string { const requirement = _createRequirement(range); - const maxSatisfying = versions + const firstSatisfyingVersion = versions .map((v) => GemVersion.create(v)) .sort(compareFunction) .find((v) => requirement.satisfiedBy(v)); - return maxSatisfying ? maxSatisfying.toString() : null; + return firstSatisfyingVersion ? firstSatisfyingVersion.toString() : null; } function maxSatisfying(versions: MaybeGemVersion[], range: string): string { diff --git a/lib/ruby/gem-requirement.ts b/lib/ruby/gem-requirement.ts index 33d71ca..ca90c76 100644 --- a/lib/ruby/gem-requirement.ts +++ b/lib/ruby/gem-requirement.ts @@ -14,6 +14,8 @@ const OPS = { '~>': (v, r) => v.compare(r) >= 0 && v.release().compare(r.bump()) < 0, }; +type OP = keyof typeof OPS; + const quoted = Object.keys(OPS) .map((k) => _escapeRegExp(k)) .join('|'); @@ -24,12 +26,12 @@ const PATTERN = new RegExp(`^${PATTERN_RAW}$`); // -- // The default requirement matches any version -const DefaultRequirement: [string, GemVersion] = ['>=', new GemVersion('0')]; +const DefaultRequirement: [OP, GemVersion] = ['>=', new GemVersion('0')]; type RequirementParts = GemVersion | string | Array; export class GemRequirement { - requirements: Array; + requirements: Array<[OP, GemVersion]>; // -- // Factory method to create a GemRequirement object. Input may be diff --git a/lib/ruby/gem-version.ts b/lib/ruby/gem-version.ts index 49e57d7..dc8b5ad 100644 --- a/lib/ruby/gem-version.ts +++ b/lib/ruby/gem-version.ts @@ -152,11 +152,26 @@ const VERSION_PATTERN = '[0-9]+(\\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?'; const ANCHORED_VERSION_PATTERN = new RegExp(`^\\s*(${VERSION_PATTERN})?\\s*$`); +export const VALID_PLATFORM_QUALIFIERS = [ + 'x86_64-darwin', + 'arm-linux', + 'java', + 'arm64-darwin', + 'x86-mingw32', + 'aarch64-linux', + 'x64-mingw-ucrt', + 'x86-linux', + 'x64-mingw32', + 'x86_64-linux', +] as const; + export type MaybeGemVersion = GemVersion | string; export type Ordering = 1 | 0 | -1; +export type Platform = typeof VALID_PLATFORM_QUALIFIERS[number]; export class GemVersion { version: string; + platform?: Platform; _release?: GemVersion; _isPrerelease?: boolean; _bump?: GemVersion; @@ -168,7 +183,7 @@ export class GemVersion { // ----------------------------- // A string representation of this Version. toString(): string { - return this.version; + return this.platform ? `${this.version}-${this.platform as string}` : this.version; } // ----------------------------- @@ -210,6 +225,17 @@ export class GemVersion { // series of digits or ASCII letters separated by dots. constructor(version: string) { + const platform: Platform | undefined = VALID_PLATFORM_QUALIFIERS.find( + (platform) => { + return version.endsWith(`-${platform}`); + }, + ); + + if (platform) { + this.platform = platform; + version = version.slice(0, -platform.length - 1); + } + if (!GemVersion.isCorrect(version)) { throw new Error(`Malformed version number string ${version}`); } diff --git a/package.json b/package.json index 29c46c7..4d85c61 100644 --- a/package.json +++ b/package.json @@ -9,20 +9,20 @@ "prepare": "npm run build", "build": "tsc", "lint": "eslint 'lib/**/*.?s'", - "test": "jest \"test/.*\\.test\\.ts\"" + "test": "jest \"test/.*\\.test\\.ts\" --runInBand --no-cache" }, "author": "Gareth Visagie ", "license": "Apache-2.0", "devDependencies": { - "@types/jest": "^25.0.0", + "@types/jest": "^29.5.2", "@typescript-eslint/eslint-plugin": "^3.5.0", "@typescript-eslint/parser": "^3.5.0", "eslint": "^6.8.0", "eslint-config-prettier": "^6.11.0", - "jest": "^25.0.0", - "prettier": "^2.0.5", - "ts-jest": "^25.0.0", - "typescript": "~3.8.3" + "jest": "^29.5.0", + "prettier": "^2.8.8", + "ts-jest": "^29.1.0", + "typescript": "^5.1.3" }, "repository": { "type": "git", @@ -35,6 +35,6 @@ "lodash.escaperegexp": "^4.1.0", "lodash.flatten": "^4.4.0", "lodash.uniq": "^4.5.0", - "tslib": "^1.13.0" + "tslib": "^2.5.3" } } diff --git a/test/comparison/cmp.test.ts b/test/comparison/cmp.test.ts index a194e24..8f0c310 100644 --- a/test/comparison/cmp.test.ts +++ b/test/comparison/cmp.test.ts @@ -6,57 +6,71 @@ import { cmp } from '../../'; // Throws if an invalid comparison string is provided. describe('test cmp', () => { - it('cmp(v1, ">", v2)', () => { + it('cmp(v1, ">", v2)', () => { expect(cmp('2', '>', '1')).toBeTruthy(); expect(cmp('2', '>', '2')).toBeFalsy(); expect(cmp('1', '>', '2')).toBeFalsy(); + expect(cmp('1.0.0-x86_64-linux', '>', '1.0.0-java')).toBeFalsy(); }); - it('cmp(v1, ">=", v2)', () => { + it('cmp(v1, ">=", v2)', () => { expect(cmp('2', '>=', '1')).toBeTruthy(); expect(cmp('2', '>=', '2')).toBeTruthy(); expect(cmp('1', '>=', '2')).toBeFalsy(); + expect(cmp('1.0.0-x86_64-linux', '>=', '1.0.0-java')).toBeTruthy(); }); - it('cmp(v1, "<", v2)', () => { + it('cmp(v1, "<", v2)', () => { expect(cmp('1', '<', '2')).toBeTruthy(); expect(cmp('2', '<', '2')).toBeFalsy(); expect(cmp('2', '<', '1')).toBeFalsy(); + expect(cmp('1.0.0-x86_64-linux', '<', '1.0.0-java')).toBeFalsy(); }); - it('cmp(v1, "<=", v2)', () => { + it('cmp(v1, "<=", v2)', () => { expect(cmp('1', '<=', '2')).toBeTruthy(); expect(cmp('2', '<=', '2')).toBeTruthy(); expect(cmp('2', '<=', '1')).toBeFalsy(); + expect(cmp('1.0.0-x86_64-linux', '<=', '1.0.0-java')).toBeTruthy(); }); - it('cmp(v1, "==", v2)', () => { + it('cmp(v1, "==", v2)', () => { expect(cmp('2', '==', '2')).toBeTruthy(); expect(cmp('2', '==', '2.0')).toBeTruthy(); expect(cmp('2', '==', '1')).toBeFalsy(); + expect(cmp('1.0.0-x86_64-linux', '==', '1.0.0-java')).toBeTruthy(); }); - it('cmp(v1, "!=", v2)', () => { + it('cmp(v1, "!=", v2)', () => { expect(cmp('2', '!=', '1')).toBeTruthy(); expect(cmp('2', '!=', '2')).toBeFalsy(); expect(cmp('2', '!=', '2.0')).toBeFalsy(); + expect(cmp('1.0.0-x86_64-linux', '!=', '1.0.0-java')).toBeFalsy(); }); - it('cmp(v1, "===", v2)', () => { + it('cmp(v1, "===", v2)', () => { expect(cmp('2', '===', '2')).toBeTruthy(); expect(cmp('2', '===', '1')).toBeFalsy(); expect(cmp('2', '===', '2.0')).toBeFalsy(); + expect(cmp('1', '===', '1.0.0-java')).toBeFalsy(); }); - it('cmp(v1, "!==", v2)', () => { + it('cmp(v1, "!==", v2)', () => { expect(cmp('2', '!==', '2')).toBeFalsy(); expect(cmp('2', '!==', '2.0')).toBeTruthy(); expect(cmp('2', '!==', '1')).toBeTruthy(); + expect(cmp('1', '!==', '1.0.0-java')).toBeTruthy(); }); - it('cmp(v1, "nonsense", v2)', () => { - expect(() => {cmp('2', 'nonsense', '2')}).toThrow(new Error('Invalid comparator: nonsense')); - expect(() => {cmp('2', '!====', '2')}).toThrow(new Error('Invalid comparator: !====')); - expect(() => {cmp('2', '>broken', '2')}).toThrow(new Error('Invalid comparator: >broken')); + it('cmp(v1, "nonsense", v2)', () => { + expect(() => { + cmp('2', 'nonsense', '2'); + }).toThrow(new Error('Invalid comparator: nonsense')); + expect(() => { + cmp('2', '!====', '2'); + }).toThrow(new Error('Invalid comparator: !====')); + expect(() => { + cmp('2', '>broken', '2'); + }).toThrow(new Error('Invalid comparator: >broken')); }); }); diff --git a/test/comparison/compare.test.ts b/test/comparison/compare.test.ts index c080332..d7a3ad2 100644 --- a/test/comparison/compare.test.ts +++ b/test/comparison/compare.test.ts @@ -11,6 +11,7 @@ describe('test compare', () => { expect(compare('1.1.0.1', '1.1.0.1')).toBe(0); expect(compare('1.1.0.1-alpha', '1.1.0.1-alpha')).toBe(0); expect(compare('1.1.0.1-alpha.2', '1.1.0.1-alpha.2')).toBe(0); + expect(compare('1.0.0-x86_64-linux', '1.0.0-java')).toBe(0); }); it('compare(v1, v2): 1 if v1 > v2', () => { @@ -20,6 +21,7 @@ describe('test compare', () => { expect(compare('1.1.0.2', '1.1.0.1')).toBe(1); expect(compare('1.1.0.1-beta', '1.1.0.1-alpha')).toBe(1); expect(compare('1.1.0.1-alpha.3', '1.1.0.1-alpha.2')).toBe(1); + expect(compare('1.0.1-x86_64-linux', '1.0.0-java')).toBe(1); }); it('compare(v1, v2): -1 if v1 < v2', () => { @@ -29,5 +31,6 @@ describe('test compare', () => { expect(compare('1.1.0.1', '1.1.0.2')).toBe(-1); expect(compare('1.1.0.1-alpha', '1.1.0.1-beta')).toBe(-1); expect(compare('1.1.0.1-alpha.2', '1.1.0.1-alpha.3')).toBe(-1); - }) + expect(compare('1.0.0-x86_64-linux', '1.0.1-java')).toBe(-1); + }); }); diff --git a/test/comparison/diff.test.ts b/test/comparison/diff.test.ts index 3462647..e9f6784 100644 --- a/test/comparison/diff.test.ts +++ b/test/comparison/diff.test.ts @@ -8,7 +8,6 @@ const diff = semver.diff; // if the versions are the same. describe('test diff', () => { - it('diff(v1, v2): same versions', () => { expect(diff('1', '1')).toBe(null); expect(diff('1.1', '1.1')).toBe(null); @@ -23,6 +22,8 @@ describe('test diff', () => { expect(diff('2.0.0', '2')).toBe(null); expect(diff('2', '2.0.0.0')).toBe(null); expect(diff('2.0.0.0', '2')).toBe(null); + expect(diff('5.0.1-x86_64-linux', '5.0.1')).toBe(null); + expect(diff('5.0.1-x86_64-linux', '5.0.1-java')).toBe(null); }); it('diff(v1, v2): major versions', () => { @@ -31,6 +32,7 @@ describe('test diff', () => { expect(diff('1.1.2', '3.0.0')).toBe('major'); expect(diff('1.1.2', '2.0.0')).toBe('major'); expect(diff('1.1.1.1', '2.0.0')).toBe('major'); + expect(diff('1.0.0-x86_64-linux', '2.0.0-java')).toBe('major'); }); it('diff(v1, v2): minor versions', () => { @@ -39,6 +41,7 @@ describe('test diff', () => { expect(diff('1.1.2', '1.2.0')).toBe('minor'); expect(diff('1.1.2.1', '1.2.0')).toBe('minor'); expect(diff('1.1.2.1', '1.2.0.1')).toBe('minor'); + expect(diff('1.1.0-x86_64-linux', '1.0.0-java')).toBe('minor'); }); it('diff(v1, v2): patch versions', () => { @@ -48,6 +51,7 @@ describe('test diff', () => { expect(diff('1.1.2.1', '1.1.3.2.1')).toBe('patch'); expect(diff('1.1.2.1', '1.1.2.1.1.1.2')).toBe('patch'); expect(diff('1.1.2.1.1.1.1', '1.1.2.1.1.1.2')).toBe('patch'); + expect(diff('1.1.1-x86_64-linux', '1.1.0-java')).toBe('patch'); }); it('diff(v1, v2): premajor versions', () => { @@ -69,5 +73,5 @@ describe('test diff', () => { expect(diff('1.1.2.alpha.1', '1.1.2.alpha.2')).toBe('prerelease'); expect(diff('1.1.2.3.alpha.1', '1.1.2.3.alpha.2')).toBe('prerelease'); expect(diff('1.alpha.1', '1')).toBe('prerelease'); - }) + }); }); diff --git a/test/comparison/eq.test.ts b/test/comparison/eq.test.ts index 4e94743..5b50e61 100644 --- a/test/comparison/eq.test.ts +++ b/test/comparison/eq.test.ts @@ -20,5 +20,10 @@ describe('test eq', () => { expect(eq('5.0.1.52.200', '5.0.1.52.176')).toBeFalsy(); expect(eq('5.0.1-beta.3', '5.0.1-beta.1')).toBeFalsy(); expect(eq('5.0.1-beta', '5.0.1-alpha')).toBeFalsy(); - }) + + // versions with recognised platform qualifiers + expect(eq('5.0.1-x86_64-linux', '5.0.1')).toBeTruthy(); + expect(eq('5.0.1-java', '5.0.1-x86_64-linux')).toBeTruthy(); + expect(eq('5.0.1-x86_64-linux', '5.0.1.beta')).toBeFalsy(); + }); }); diff --git a/test/comparison/gt.test.ts b/test/comparison/gt.test.ts index cf2fba9..d84091a 100644 --- a/test/comparison/gt.test.ts +++ b/test/comparison/gt.test.ts @@ -27,5 +27,12 @@ describe('test gt', () => { expect(gt('5.0.1-beta.1', '5.0.1-beta.3')).toBeFalsy(); expect(gt('5.0.1-alpha', '5.0.1-beta')).toBeFalsy(); expect(gt('5.0.1.beta', '5.0.1')).toBeFalsy(); - }) + + // versions with recognised platform qualifiers + expect(gt('5.0.1-x86_64-linux', '5.0.1')).toBeFalsy(); + expect(gt('5.0.1', '5.0.1-x86_64-linux')).toBeFalsy(); + expect(gt('5.0.1-java', '5.0.1-x86_64-linux')).toBeFalsy(); + expect(gt('5.0.1-x86_64-linux', '5.0.1.beta')).toBeTruthy(); + expect(gt('5.0.1.beta', '5.0.1-x86_64-linux')).toBeFalsy(); + }); }); diff --git a/test/comparison/gte.test.ts b/test/comparison/gte.test.ts index 058f0e3..2ea7735 100644 --- a/test/comparison/gte.test.ts +++ b/test/comparison/gte.test.ts @@ -27,5 +27,12 @@ describe('test gte', () => { expect(gte('5.0.1-beta.1', '5.0.1-beta.3')).toBeFalsy(); expect(gte('5.0.1-alpha', '5.0.1-beta')).toBeFalsy(); expect(gte('5.0.1.beta', '5.0.1')).toBeFalsy(); - }) + + // versions with recognised platform qualifiers + expect(gte('5.0.1-x86_64-linux', '5.0.1')).toBeTruthy(); + expect(gte('5.0.1', '5.0.1-x86_64-linux')).toBeTruthy(); + expect(gte('5.0.1-java', '5.0.1-x86_64-linux')).toBeTruthy(); + expect(gte('5.0.1-x86_64-linux', '5.0.1.beta')).toBeTruthy(); + expect(gte('5.0.1.beta', '5.0.1-x86_64-linux')).toBeFalsy(); + }); }); diff --git a/test/comparison/lt.test.ts b/test/comparison/lt.test.ts index 5bcf5c0..6a7a9d2 100644 --- a/test/comparison/lt.test.ts +++ b/test/comparison/lt.test.ts @@ -27,5 +27,11 @@ describe('test lt', () => { expect(lt('5.0.1-beta.3', '5.0.1-beta.1')).toBeFalsy(); expect(lt('5.0.1-beta', '5.0.1-alpha')).toBeFalsy(); expect(lt('5.0.1', '5.0.1.beta')).toBeFalsy(); - }) + + // versions with recognised platform qualifiers + expect(lt('5.0.1-x86_64-linux', '5.0.1')).toBeFalsy(); + expect(lt('5.0.1', '5.0.1-x86_64-linux')).toBeFalsy(); + expect(lt('5.0.1-x86_64-linux', '5.0.1.beta')).toBeFalsy(); + expect(lt('5.0.1.beta', '5.0.1-x86_64-linux')).toBeTruthy(); + }); }); diff --git a/test/comparison/lte.test.ts b/test/comparison/lte.test.ts index bb2027d..7b9d8fc 100644 --- a/test/comparison/lte.test.ts +++ b/test/comparison/lte.test.ts @@ -27,5 +27,12 @@ describe('test lte', () => { expect(lte('5.0.1-beta.3', '5.0.1-beta.1')).toBeFalsy(); expect(lte('5.0.1-beta', '5.0.1-alpha')).toBeFalsy(); expect(lte('5.0.1', '5.0.1.beta')).toBeFalsy(); - }) + + // versions with recognised platform qualifiers + expect(lte('5.0.1-x86_64-linux', '5.0.1')).toBeTruthy(); + expect(lte('5.0.1', '5.0.1-x86_64-linux')).toBeTruthy(); + expect(lte('5.0.1-java', '5.0.1-x86_64-linux')).toBeTruthy(); + expect(lte('5.0.1-x86_64-linux', '5.0.1.beta')).toBeFalsy(); + expect(lte('5.0.1.beta', '5.0.1-x86_64-linux')).toBeTruthy(); + }); }); diff --git a/test/comparison/neq.test.ts b/test/comparison/neq.test.ts index b441df7..3da10ff 100644 --- a/test/comparison/neq.test.ts +++ b/test/comparison/neq.test.ts @@ -9,6 +9,8 @@ describe('test neq', () => { expect(neq('5.0.1.52.200', '5.0.1.52.176')).toBeTruthy(); expect(neq('5.0.1-beta.3', '5.0.1-beta.1')).toBeTruthy(); expect(neq('5.0.1-beta', '5.0.1-alpha')).toBeTruthy(); + expect(neq('5.0.1-x86_64-darwin', '5.0.2-x86_64-darwin')).toBeTruthy(); + expect(neq('5.0.1-x86_64-darwin', '5.0.1-alpha')).toBeTruthy(); expect(neq('2', '2')).toBeFalsy(); expect(neq('2', '2.0')).toBeFalsy(); @@ -20,5 +22,6 @@ describe('test neq', () => { expect(neq('5.0.1.52.200', '5.0.1.52.200')).toBeFalsy(); expect(neq('5.0.1-beta.3', '5.0.1-beta.3')).toBeFalsy(); expect(neq('5.0.1-beta', '5.0.1-beta')).toBeFalsy(); - }) + expect(neq('5.0.1-x86_64-darwin', '5.0.1-java')).toBeFalsy(); + }); }); diff --git a/test/comparison/rcompare.test.ts b/test/comparison/rcompare.test.ts index 657f459..55313da 100644 --- a/test/comparison/rcompare.test.ts +++ b/test/comparison/rcompare.test.ts @@ -10,6 +10,9 @@ describe('test rcompare', () => { expect(rcompare('1.1.0.1', '1.1.0.1')).toBe(0); expect(rcompare('1.1.0.1-alpha', '1.1.0.1-alpha')).toBe(0); expect(rcompare('1.1.0.1-alpha.2', '1.1.0.1-alpha.2')).toBe(0); + expect(rcompare('1.1.0.1-java', '1.1.0.1-java')).toBe(0); + expect(rcompare('1.1.0.1-x86_64-darwin', '1.1.0.1-x86_64-darwin')).toBe(0); + expect(rcompare('1.1.0.1-x86_64-darwin', '1.1.0.1-java')).toBe(0); }); it('rcompare(v1, v2): -1 if v1 > v2', () => { @@ -19,6 +22,9 @@ describe('test rcompare', () => { expect(rcompare('1.1.0.2', '1.1.0.1')).toBe(-1); expect(rcompare('1.1.0.1-beta', '1.1.0.1-alpha')).toBe(-1); expect(rcompare('1.1.0.1-alpha.3', '1.1.0.1-alpha.2')).toBe(-1); + expect(rcompare('1.1.0.2-java', '1.1.0.1-java')).toBe(-1); + expect(rcompare('1.1.0.2-x86_64-darwin', '1.1.0.1-x86_64-darwin')).toBe(-1); + expect(rcompare('1.1.0.2-x86_64-darwin', '1.1.0.1-java')).toBe(-1); }); it('rcompare(v1, v2): 1 if v1 < v2', () => { @@ -28,5 +34,8 @@ describe('test rcompare', () => { expect(rcompare('1.1.0.1', '1.1.0.2')).toBe(1); expect(rcompare('1.1.0.1-alpha', '1.1.0.1-beta')).toBe(1); expect(rcompare('1.1.0.1-alpha.2', '1.1.0.1-alpha.3')).toBe(1); - }) + expect(rcompare('1.1.0.1-java', '1.1.0.2-java')).toBe(1); + expect(rcompare('1.1.0.1-x86_64-darwin', '1.1.0.2-x86_64-darwin')).toBe(1); + expect(rcompare('1.1.0.1-x86_64-darwin', '1.1.0.2-java')).toBe(1); + }); }); diff --git a/test/functions/major.test.ts b/test/functions/major.test.ts index 879f763..58a0899 100644 --- a/test/functions/major.test.ts +++ b/test/functions/major.test.ts @@ -11,5 +11,16 @@ describe('test major', () => { expect(major('1.2.3-123')).toBe(1); expect(major('1.2.3.alpha.4')).toBe(1); expect(major('0.0.1')).toBe(0); - }) + }); + + it('major(v) multi-platform', () => { + expect(major('1-x86_64-darwin')).toBe(1); + expect(major('1.2-x86_64-darwin')).toBe(1); + expect(major('1.2.3-x86_64-darwin')).toBe(1); + expect(major('1.2.3.4-x86_64-darwin')).toBe(1); + expect(major('1.2.3.4.5-x86_64-darwin')).toBe(1); + expect(major('1.2.3-123-x86_64-darwin')).toBe(1); + expect(major('1.2.3.alpha.4-x86_64-darwin')).toBe(1); + expect(major('0.0.1-x86_64-darwin')).toBe(0); + }); }); diff --git a/test/functions/platform.test.ts b/test/functions/platform.test.ts new file mode 100644 index 0000000..eb7d022 --- /dev/null +++ b/test/functions/platform.test.ts @@ -0,0 +1,28 @@ +import { platform } from '../../'; + +// platform(v): Returns a platform found in the version, or null if none +// exist. Example: platform('1.2.3-x86_64-darwin') -> 'x86_64-darwin' + +describe('test platform', () => { + it('platform(v)', () => { + expect(platform('1.2.3-x86_64-darwin')).toEqual('x86_64-darwin'); + expect(platform('1.2.3-java')).toEqual('java'); + + expect(platform('1')).toEqual(null); + expect(platform('1.2')).toEqual(null); + expect(platform('1.2.3')).toEqual(null); + expect(platform('1.2.3.4')).toEqual(null); + expect(platform('1.2.3.4.5')).toEqual(null); + + // prerelease qualifiers + expect(platform('1.2.3-alpha')).toEqual(null); + expect(platform('1.2.3.alpha')).toEqual(null); + expect(platform('1.2.3-alpha.1.2')).toEqual(null); + expect(platform('1.2.3.alpha.1.2')).toEqual(null); + + expect(platform('nonsense')).toEqual(null); + expect(platform('')).toEqual(null); + expect(platform(null as any)).toEqual(null); + expect(platform('1.2.3-x86_64-darwind')).toEqual(null); + }); +}); diff --git a/test/functions/prerelease.test.ts b/test/functions/prerelease.test.ts index 66b18df..a63db7f 100644 --- a/test/functions/prerelease.test.ts +++ b/test/functions/prerelease.test.ts @@ -16,9 +16,13 @@ describe('test prerelease', () => { expect(prerelease('1.2.3.4')).toStrictEqual(null); expect(prerelease('1.2.3.4.5')).toStrictEqual(null); + // recognised platform qualifiers + expect(prerelease('1.2.3-java')).toStrictEqual(null); + expect(prerelease('1.2.3-x86_64-darwin')).toStrictEqual(null); + expect(prerelease('nonsense')).toStrictEqual(null); expect(prerelease('')).toStrictEqual(null); // expect(prerelease()).toStrictEqual(null); not valid with typescript - expect(prerelease(null)).toStrictEqual(null); - }) + expect(prerelease(null as any)).toStrictEqual(null); + }); }); diff --git a/test/functions/valid.test.ts b/test/functions/valid.test.ts index 3b1074e..1984d40 100644 --- a/test/functions/valid.test.ts +++ b/test/functions/valid.test.ts @@ -17,7 +17,9 @@ describe('test valid', () => { expect(valid('1.2<3')).toBe(null); expect(valid('1.2 3')).toBe(null); expect(valid('')).toBe(null); - expect(valid(null)).toBe(null); + expect(valid(null as any)).toBe(null); // expect(valid()).toBe(null); not valid with typescript - }) + expect(valid('1.13.10-x86_64-darwin')).toBe('1.13.10-x86_64-darwin'); + expect(valid('1.13.10-java')).toBe('1.13.10-java'); + }); }); diff --git a/test/ranges/max-satisfying.test.ts b/test/ranges/max-satisfying.test.ts index 138d5f9..d0f56fc 100644 --- a/test/ranges/max-satisfying.test.ts +++ b/test/ranges/max-satisfying.test.ts @@ -6,9 +6,13 @@ import { maxSatisfying } from '../../'; describe('test maxSatisfying', () => { it('maxSatisfying(versions, range)', () => { expect(maxSatisfying(['1.2.3', '1.2.4'], '~> 1.2')).toBe('1.2.4'); - expect(maxSatisfying(['1.2.3', '1.2.4', '1.2.5'], '~> 1.2, <= 1.2.4')).toBe('1.2.4'); + expect(maxSatisfying(['1.2.3', '1.2.4', '1.2.5'], '~> 1.2, <= 1.2.4')).toBe( + '1.2.4', + ); expect(maxSatisfying(['1.2.4', '1.2.3'], '~> 1.2')).toBe('1.2.4'); - expect(maxSatisfying(['1.2.3', '1.2.4', '1.2.5', '1.2.6'], '~> 1.2.3')).toBe('1.2.6',); + expect( + maxSatisfying(['1.2.3', '1.2.4', '1.2.5', '1.2.6'], '~> 1.2.3'), + ).toBe('1.2.6'); expect( maxSatisfying( [ @@ -21,8 +25,25 @@ describe('test maxSatisfying', () => { '2.0.0b3', '2.0.0', '2.1.0', - ], '~> 2.0.0', - )).toBe('2.0.0'); + ], + '~> 2.0.0', + ), + ).toBe('2.0.0'); expect(maxSatisfying(['1.2.3', '1.2.4'], '> 3.2')).toBeNull(); - }) + }); + + it('maxSatisfying(versions, range) multi-platform', () => { + expect( + maxSatisfying( + [ + '1.2.3-x86_64-linux', + '1.2.4-x86_64-linux', + '1.2.5-x86_64-linux', + '1.2.6-x86_64-linux', + '1.3.0-x86_64-linux', + ], + '~>1.2.3', + ), + ).toBe('1.2.6-x86_64-linux'); + }); }); diff --git a/test/ranges/min-satisfying.test.ts b/test/ranges/min-satisfying.test.ts index 2d61bd1..5dd63c3 100644 --- a/test/ranges/min-satisfying.test.ts +++ b/test/ranges/min-satisfying.test.ts @@ -6,8 +6,12 @@ describe('test minSatisfying', () => { it('minSatisfying(versions, range)', () => { expect(minSatisfying(['1.2.3', '1.2.4'], '~> 1.2')).toBe('1.2.3'); expect(minSatisfying(['1.2.4', '1.2.3'], '~> 1.2')).toBe('1.2.3'); - expect(minSatisfying(['1.2.3', '1.2.4', '1.2.5'], '~> 1.2, >= 1.2.4')).toBe('1.2.4'); - expect(minSatisfying(['1.2.3', '1.2.4', '1.2.5', '1.2.6'], '~>1.2.3')).toBe('1.2.3'); + expect(minSatisfying(['1.2.3', '1.2.4', '1.2.5'], '~> 1.2, >= 1.2.4')).toBe( + '1.2.4', + ); + expect(minSatisfying(['1.2.3', '1.2.4', '1.2.5', '1.2.6'], '~>1.2.3')).toBe( + '1.2.3', + ); expect( minSatisfying( [ @@ -22,7 +26,22 @@ describe('test minSatisfying', () => { '2.1.0', ], '~> 2.0.0', - )).toBe('2.0.0'); + ), + ).toBe('2.0.0'); expect(minSatisfying(['1.2.3', '1.2.4'], '> 3.2')).toBeNull(); - }) + }); + it('minSatisfying(versions, range) multi-platform', () => { + expect( + minSatisfying( + [ + '1.2.2-x86_64-linux', + '1.2.3-x86_64-linux', + '1.2.4-x86_64-linux', + '1.2.5-x86_64-linux', + '1.2.6-x86_64-linux', + ], + '~>1.2.3', + ), + ).toBe('1.2.3-x86_64-linux'); + }); }); diff --git a/test/ranges/satisfies.test.ts b/test/ranges/satisfies.test.ts index 2dce7de..8da8fd9 100644 --- a/test/ranges/satisfies.test.ts +++ b/test/ranges/satisfies.test.ts @@ -14,5 +14,12 @@ describe('test satisfies', () => { expect(satisfies('1.5.2', '>= 1.3, < 1.5')).toBeFalsy(); expect(satisfies('1.2.1', 'nonsense')).toBeFalsy(); - }) + }); + + it('satisfies(version, range) multi-platform', () => { + expect(satisfies('1.13.10-x86_64-darwin', '< 1.14.0')).toBeTruthy(); + expect(satisfies('1.13.10-x86_64-darwin', '> 1.14.0')).toBeFalsy(); + expect(satisfies('1.15.10-x86_64-darwin', '> 1.14.0')).toBeTruthy(); + expect(satisfies('1.15.10-x86_64-darwin', '< 1.14.0')).toBeFalsy(); + }); }); diff --git a/test/ranges/valid-range.test.ts b/test/ranges/valid-range.test.ts index e8f190e..2051fa1 100644 --- a/test/ranges/valid-range.test.ts +++ b/test/ranges/valid-range.test.ts @@ -11,7 +11,7 @@ describe('test validRange', () => { expect(validRange('> 2.1, < 2.4')).toBe('< 2.4, > 2.1'); expect(validRange('')).toBe('>= 0'); - // expect(validRange()).toBe(null); not valie with typescript + expect((validRange as Function)()).toBe(null); expect(validRange('nonsense')).toBe(null); - }) + }); }); diff --git a/tsconfig.json b/tsconfig.json index 865ed10..cfe80fe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,8 @@ { "compilerOptions": { "outDir": "./dist", - "target": "es2017", - "lib": [ - "es2017" - ], + "target": "es2020", + "lib": ["es2020"], "module": "commonjs", "declaration": true, "sourceMap": true, @@ -16,7 +14,5 @@ "noUnusedLocals": true, "noImplicitReturns": true }, - "include": [ - "./lib/**/*" - ] + "include": ["./lib/**/*"] }