From d31381d4e227e63542977b995d1e35be1d2bd81f Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 22 Nov 2019 10:54:26 -0800 Subject: [PATCH] range class test coverage to 100 --- classes/range.js | 16 ++- test/classes/range.js | 64 +++++++++ test/fixtures/range-exclude.js | 81 +++++++++++ test/fixtures/range-include.js | 118 +++++++++++++++ test/fixtures/range-parse.js | 85 +++++++++++ test/functions/satisfies.js | 252 +++------------------------------ test/ranges/valid-range.js | 88 +----------- 7 files changed, 380 insertions(+), 324 deletions(-) create mode 100644 test/fixtures/range-exclude.js create mode 100644 test/fixtures/range-include.js create mode 100644 test/fixtures/range-parse.js diff --git a/classes/range.js b/classes/range.js index b05b8537..90876c38 100644 --- a/classes/range.js +++ b/classes/range.js @@ -20,7 +20,11 @@ class Range { } if (range instanceof Comparator) { - return new Range(range.value, options) + // just put it in the set and return + this.raw = range.value + this.set = [[range]] + this.format() + return this } this.options = options @@ -31,11 +35,12 @@ class Range { this.raw = range this.set = range .split(/\s*\|\|\s*/) + // map the range to a 2d array of comparators .map(range => this.parseRange(range.trim())) - .filter((c) => { - // throw out any that are not relevant for whatever reason - return c.length - }) + // throw out any comparator lists that are empty + // this generally means that it was not a valid range, which is allowed + // in loose mode, but will still throw if the WHOLE range is invalid. + .filter(c => c.length) if (!this.set.length) { throw new TypeError(`Invalid SemVer Range: ${range}`) @@ -331,7 +336,6 @@ const replaceXRange = (comp, options) => { if (gtlt === '>') { // >1 => >=2.0.0 // >1.2 => >=1.3.0 - // >1.2.3 => >= 1.2.4 gtlt = '>=' if (xm) { M = +M + 1 diff --git a/test/classes/range.js b/test/classes/range.js index 91979d3b..267fa80b 100644 --- a/test/classes/range.js +++ b/test/classes/range.js @@ -1,7 +1,71 @@ const { test } = require('tap') const Range = require('../../classes/range') +const Comparator = require('../../classes/comparator') const rangeIntersection = require('../fixtures/range-intersection.js') +const rangeInclude = require('../fixtures/range-include.js') +const rangeExclude = require('../fixtures/range-exclude.js') +const rangeParse = require('../fixtures/range-parse.js') + +test('range tests', t => { + t.plan(rangeInclude.length) + rangeInclude.forEach(([range, ver, options]) => { + const r = new Range(range, options) + t.ok(r.test(ver), `${range} satisfied by ${ver}`) + }) +}) + +test('range parsing', t => { + t.plan(rangeParse.length) + rangeParse.forEach(([range, expect, options]) => t.test(`${range} ${expect}`, t => { + if (expect === null) + t.throws(() => new Range(range), TypeError, `invalid range: ${range}`) + else { + t.equal(new Range(range, options).range || '*', expect, + `${range} => ${expect}`) + t.equal(new Range(range, options).range, new Range(expect).range, + 'parsing both yields same result') + } + t.end() + })) +}) + +test('throw for empty comparator set, even in loose mode', t => { + t.throws(() => new Range('sadf||asdf', { loose: true }), + TypeError('Invalid SemVer Range: sadf||asdf')) + t.end() +}) + +test('convert comparator to range', t => { + const c = new Comparator('>=1.2.3') + const r = new Range(c) + t.equal(r.raw, c.value, 'created range from comparator') + t.end() +}) + +test('range as argument to range ctor', t => { + const loose = new Range('1.2.3', { loose: true }) + t.equal(new Range(loose, { loose: true }), loose, 'loose option') + t.equal(new Range(loose, true), loose, 'loose boolean') + t.notEqual(new Range(loose), loose, 'created new range if not matched') + + const incPre = new Range('1.2.3', {includePrerelease: true}) + t.equal(new Range(incPre, {includePrerelease: true}), incPre, + 'include prerelease, option match returns argument') + t.notEqual(new Range(incPre), incPre, + 'include prerelease, option mismatch does not return argument') + + t.end() +}) + +test('negative range tests', t => { + t.plan(rangeExclude.length) + rangeExclude.forEach(([range, ver, options]) => { + const r = new Range(range, options) + t.notOk(r.test(ver), `${range} not satisfied by ${ver}`) + }) +}) + test('strict vs loose ranges', (t) => { [ ['>=01.02.03', '>=1.2.3'], diff --git a/test/fixtures/range-exclude.js b/test/fixtures/range-exclude.js new file mode 100644 index 00000000..2d764bd4 --- /dev/null +++ b/test/fixtures/range-exclude.js @@ -0,0 +1,81 @@ +// [range, version, options] +// version should not be included by range +module.exports = [ + ['1.0.0 - 2.0.0', '2.2.3'], + ['1.2.3+asdf - 2.4.3+asdf', '1.2.3-pre.2'], + ['1.2.3+asdf - 2.4.3+asdf', '2.4.3-alpha'], + ['^1.2.3+build', '2.0.0'], + ['^1.2.3+build', '1.2.0'], + ['^1.2.3', '1.2.3-pre'], + ['^1.2', '1.2.0-pre'], + ['>1.2', '1.3.0-beta'], + ['<=1.2.3', '1.2.3-beta'], + ['^1.2.3', '1.2.3-beta'], + ['=0.7.x', '0.7.0-asdf'], + ['>=0.7.x', '0.7.0-asdf'], + ['1', '1.0.0beta', { loose: 420 }], + ['<1', '1.0.0beta', true], + ['< 1', '1.0.0beta', true], + ['1.0.0', '1.0.1'], + ['>=1.0.0', '0.0.0'], + ['>=1.0.0', '0.0.1'], + ['>=1.0.0', '0.1.0'], + ['>1.0.0', '0.0.1'], + ['>1.0.0', '0.1.0'], + ['<=2.0.0', '3.0.0'], + ['<=2.0.0', '2.9999.9999'], + ['<=2.0.0', '2.2.9'], + ['<2.0.0', '2.9999.9999'], + ['<2.0.0', '2.2.9'], + ['>=0.1.97', 'v0.1.93', true], + ['>=0.1.97', '0.1.93'], + ['0.1.20 || 1.2.4', '1.2.3'], + ['>=0.2.3 || <0.0.1', '0.0.3'], + ['>=0.2.3 || <0.0.1', '0.2.2'], + ['2.x.x', '1.1.3', { loose: NaN }], + ['2.x.x', '3.1.3'], + ['1.2.x', '1.3.3'], + ['1.2.x || 2.x', '3.1.3'], + ['1.2.x || 2.x', '1.1.3'], + ['2.*.*', '1.1.3'], + ['2.*.*', '3.1.3'], + ['1.2.*', '1.3.3'], + ['1.2.* || 2.*', '3.1.3'], + ['1.2.* || 2.*', '1.1.3'], + ['2', '1.1.2'], + ['2.3', '2.4.1'], + ['~0.0.1', '0.1.0-alpha'], + ['~0.0.1', '0.1.0'], + ['~2.4', '2.5.0'], // >=2.4.0 <2.5.0 + ['~2.4', '2.3.9'], + ['~>3.2.1', '3.3.2'], // >=3.2.1 <3.3.0 + ['~>3.2.1', '3.2.0'], // >=3.2.1 <3.3.0 + ['~1', '0.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '2.2.3'], + ['~1.0', '1.1.0'], // >=1.0.0 <1.1.0 + ['<1', '1.0.0'], + ['>=1.2', '1.1.1'], + ['1', '2.0.0beta', true], + ['~v0.5.4-beta', '0.5.4-alpha'], + ['=0.7.x', '0.8.2'], + ['>=0.7.x', '0.6.2'], + ['<0.7.x', '0.7.2'], + ['<1.2.3', '1.2.3-beta'], + ['=1.2.3', '1.2.3-beta'], + ['>1.2', '1.2.8'], + ['^0.0.1', '0.0.2-alpha'], + ['^0.0.1', '0.0.2'], + ['^1.2.3', '2.0.0-alpha'], + ['^1.2.3', '1.2.2'], + ['^1.2', '1.1.9'], + ['*', 'v1.2.3-foo', true], + + // invalid versions never satisfy, but shouldn't throw + ['*', 'not a version'], + ['>=2', 'glorp'], + ['>=2', false], + + ['2.x', '3.0.0-pre.0', { includePrerelease: true }], + ['^1.0.0', '1.0.0-rc1', { includePrerelease: true }], + ['^1.2.3-rc2', '2.0.0', { includePrerelease: true }], +] diff --git a/test/fixtures/range-include.js b/test/fixtures/range-include.js new file mode 100644 index 00000000..d523b2c7 --- /dev/null +++ b/test/fixtures/range-include.js @@ -0,0 +1,118 @@ +// [range, version, options] +// version should be included by range +module.exports = [ + ['1.0.0 - 2.0.0', '1.2.3'], + ['^1.2.3+build', '1.2.3'], + ['^1.2.3+build', '1.3.0'], + ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3'], + ['1.2.3pre+asdf - 2.4.3-pre+asdf', '1.2.3', true], + ['1.2.3-pre+asdf - 2.4.3pre+asdf', '1.2.3', true], + ['1.2.3pre+asdf - 2.4.3pre+asdf', '1.2.3', true], + ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3-pre.2'], + ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '2.4.3-alpha'], + ['1.2.3+asdf - 2.4.3+asdf', '1.2.3'], + ['1.0.0', '1.0.0'], + ['>=*', '0.2.4'], + ['', '1.0.0'], + ['*', '1.2.3', {}], + ['*', 'v1.2.3', { loose: 123 }], + ['>=1.0.0', '1.0.0', /asdf/], + ['>=1.0.0', '1.0.1', { loose: null }], + ['>=1.0.0', '1.1.0', { loose: 0 }], + ['>1.0.0', '1.0.1', { loose: undefined }], + ['>1.0.0', '1.1.0'], + ['<=2.0.0', '2.0.0'], + ['<=2.0.0', '1.9999.9999'], + ['<=2.0.0', '0.2.9'], + ['<2.0.0', '1.9999.9999'], + ['<2.0.0', '0.2.9'], + ['>= 1.0.0', '1.0.0'], + ['>= 1.0.0', '1.0.1'], + ['>= 1.0.0', '1.1.0'], + ['> 1.0.0', '1.0.1'], + ['> 1.0.0', '1.1.0'], + ['<= 2.0.0', '2.0.0'], + ['<= 2.0.0', '1.9999.9999'], + ['<= 2.0.0', '0.2.9'], + ['< 2.0.0', '1.9999.9999'], + ['<\t2.0.0', '0.2.9'], + ['>=0.1.97', 'v0.1.97', true], + ['>=0.1.97', '0.1.97'], + ['0.1.20 || 1.2.4', '1.2.4'], + ['>=0.2.3 || <0.0.1', '0.0.0'], + ['>=0.2.3 || <0.0.1', '0.2.3'], + ['>=0.2.3 || <0.0.1', '0.2.4'], + ['||', '1.3.4'], + ['2.x.x', '2.1.3'], + ['1.2.x', '1.2.3'], + ['1.2.x || 2.x', '2.1.3'], + ['1.2.x || 2.x', '1.2.3'], + ['x', '1.2.3'], + ['2.*.*', '2.1.3'], + ['1.2.*', '1.2.3'], + ['1.2.* || 2.*', '2.1.3'], + ['1.2.* || 2.*', '1.2.3'], + ['*', '1.2.3'], + ['2', '2.1.2'], + ['2.3', '2.3.1'], + ['~0.0.1', '0.0.1'], + ['~0.0.1', '0.0.2'], + ['~x', '0.0.9'], // >=2.4.0 <2.5.0 + ['~2', '2.0.9'], // >=2.4.0 <2.5.0 + ['~2.4', '2.4.0'], // >=2.4.0 <2.5.0 + ['~2.4', '2.4.5'], + ['~>3.2.1', '3.2.2'], // >=3.2.1 <3.3.0, + ['~1', '1.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '1.2.3'], + ['~> 1', '1.2.3'], + ['~1.0', '1.0.2'], // >=1.0.0 <1.1.0, + ['~ 1.0', '1.0.2'], + ['~ 1.0.3', '1.0.12'], + ['~ 1.0.3alpha', '1.0.12', { loose: true }], + ['>=1', '1.0.0'], + ['>= 1', '1.0.0'], + ['<1.2', '1.1.1'], + ['< 1.2', '1.1.1'], + ['~v0.5.4-pre', '0.5.5'], + ['~v0.5.4-pre', '0.5.4'], + ['=0.7.x', '0.7.2'], + ['<=0.7.x', '0.7.2'], + ['>=0.7.x', '0.7.2'], + ['<=0.7.x', '0.6.2'], + ['~1.2.1 >=1.2.3', '1.2.3'], + ['~1.2.1 =1.2.3', '1.2.3'], + ['~1.2.1 1.2.3', '1.2.3'], + ['~1.2.1 >=1.2.3 1.2.3', '1.2.3'], + ['~1.2.1 1.2.3 >=1.2.3', '1.2.3'], + ['~1.2.1 1.2.3', '1.2.3'], + ['>=1.2.1 1.2.3', '1.2.3'], + ['1.2.3 >=1.2.1', '1.2.3'], + ['>=1.2.3 >=1.2.1', '1.2.3'], + ['>=1.2.1 >=1.2.3', '1.2.3'], + ['>=1.2', '1.2.8'], + ['^1.2.3', '1.8.1'], + ['^0.1.2', '0.1.2'], + ['^0.1', '0.1.2'], + ['^0.0.1', '0.0.1'], + ['^1.2', '1.4.2'], + ['^1.2 ^1', '1.4.2'], + ['^1.2.3-alpha', '1.2.3-pre'], + ['^1.2.0-alpha', '1.2.0-pre'], + ['^0.0.1-alpha', '0.0.1-beta'], + ['^0.0.1-alpha', '0.0.1'], + ['^0.1.1-alpha', '0.1.1-beta'], + ['^x', '1.2.3'], + ['x - 1.0.0', '0.9.7'], + ['x - 1.x', '0.9.7'], + ['1.0.0 - x', '1.9.7'], + ['1.x - x', '1.9.7'], + ['<=7.x', '7.9.9'], + ['2.x', '2.0.0-pre.0', { includePrerelease: true }], + ['2.x', '2.1.0-pre.0', { includePrerelease: true }], + ['*', '1.0.0-rc1', { includePrerelease: true }], + ['^1.0.0', '2.0.0-rc1', { includePrerelease: true }], + ['^1.0.0-0', '1.0.1-rc1', { includePrerelease: true }], + ['^1.0.0-rc2', '1.0.1-rc1', { includePrerelease: true }], + ['^1.0.0', '1.0.1-rc1', { includePrerelease: true }], + ['^1.0.0', '1.1.0-rc1', { includePrerelease: true }], +] diff --git a/test/fixtures/range-parse.js b/test/fixtures/range-parse.js new file mode 100644 index 00000000..a09c1f7d --- /dev/null +++ b/test/fixtures/range-parse.js @@ -0,0 +1,85 @@ +// [range, canonical result, options] +// null result means it's not a valid range +// '*' is the return value from functions.validRange(), but +// new Range().range will be '' in those cases +module.exports = [ + ['1.0.0 - 2.0.0', '>=1.0.0 <=2.0.0'], + ['1.0.0', '1.0.0', { loose: false }], + ['>=*', '*'], + ['', '*'], + ['*', '*'], + ['*', '*'], + ['>=1.0.0', '>=1.0.0'], + ['>1.0.0', '>1.0.0'], + ['<=2.0.0', '<=2.0.0'], + ['1', '>=1.0.0 <2.0.0'], + ['<=2.0.0', '<=2.0.0'], + ['<=2.0.0', '<=2.0.0'], + ['<2.0.0', '<2.0.0'], + ['<2.0.0', '<2.0.0'], + ['>= 1.0.0', '>=1.0.0'], + ['>= 1.0.0', '>=1.0.0'], + ['>= 1.0.0', '>=1.0.0'], + ['> 1.0.0', '>1.0.0'], + ['> 1.0.0', '>1.0.0'], + ['<= 2.0.0', '<=2.0.0'], + ['<= 2.0.0', '<=2.0.0'], + ['<= 2.0.0', '<=2.0.0'], + ['< 2.0.0', '<2.0.0'], + ['<\t2.0.0', '<2.0.0'], + ['>=0.1.97', '>=0.1.97'], + ['>=0.1.97', '>=0.1.97'], + ['0.1.20 || 1.2.4', '0.1.20||1.2.4'], + ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], + ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], + ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], + ['||', '||'], + ['2.x.x', '>=2.0.0 <3.0.0'], + ['1.2.x', '>=1.2.0 <1.3.0'], + ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], + ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], + ['x', '*'], + ['2.*.*', '>=2.0.0 <3.0.0'], + ['1.2.*', '>=1.2.0 <1.3.0'], + ['1.2.* || 2.*', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], + ['*', '*'], + ['2', '>=2.0.0 <3.0.0'], + ['2.3', '>=2.3.0 <2.4.0'], + ['~2.4', '>=2.4.0 <2.5.0'], + ['~2.4', '>=2.4.0 <2.5.0'], + ['~>3.2.1', '>=3.2.1 <3.3.0'], + ['~1', '>=1.0.0 <2.0.0'], + ['~>1', '>=1.0.0 <2.0.0'], + ['~> 1', '>=1.0.0 <2.0.0'], + ['~1.0', '>=1.0.0 <1.1.0'], + ['~ 1.0', '>=1.0.0 <1.1.0'], + ['^0', '>=0.0.0 <1.0.0'], + ['^ 1', '>=1.0.0 <2.0.0'], + ['^0.1', '>=0.1.0 <0.2.0'], + ['^1.0', '>=1.0.0 <2.0.0'], + ['^1.2', '>=1.2.0 <2.0.0'], + ['^0.0.1', '>=0.0.1 <0.0.2'], + ['^0.0.1-beta', '>=0.0.1-beta <0.0.2'], + ['^0.1.2', '>=0.1.2 <0.2.0'], + ['^1.2.3', '>=1.2.3 <2.0.0'], + ['^1.2.3-beta.4', '>=1.2.3-beta.4 <2.0.0'], + ['<1', '<1.0.0'], + ['< 1', '<1.0.0'], + ['>=1', '>=1.0.0'], + ['>= 1', '>=1.0.0'], + ['<1.2', '<1.2.0'], + ['< 1.2', '<1.2.0'], + ['1', '>=1.0.0 <2.0.0'], + ['>01.02.03', '>1.2.3', true], + ['>01.02.03', null], + ['~1.2.3beta', '>=1.2.3-beta <1.3.0', { loose: true }], + ['~1.2.3beta', null], + ['^ 1.2 ^ 1', '>=1.2.0 <2.0.0 >=1.0.0 <2.0.0'], + ['1.2 - 3.4.5', '>=1.2.0 <=3.4.5'], + ['1.2.3 - 3.4', '>=1.2.3 <3.5.0'], + ['1.2 - 3.4', '>=1.2.0 <3.5.0'], + ['>1', '>=2.0.0'], + ['>1.2', '>=1.3.0'], + ['>X', '<0.0.0-0'], + [' { + t.plan(rangeInclude.length) + rangeInclude.forEach(([range, ver, options]) => + t.ok(satisfies(ver, range, options), `${range} satisfied by ${ver}`)) +}) -test('range tests', (t) => { - // [range, version] - // version should be included by range - [['1.0.0 - 2.0.0', '1.2.3'], - ['^1.2.3+build', '1.2.3'], - ['^1.2.3+build', '1.3.0'], - ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3'], - ['1.2.3pre+asdf - 2.4.3-pre+asdf', '1.2.3', true], - ['1.2.3-pre+asdf - 2.4.3pre+asdf', '1.2.3', true], - ['1.2.3pre+asdf - 2.4.3pre+asdf', '1.2.3', true], - ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3-pre.2'], - ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '2.4.3-alpha'], - ['1.2.3+asdf - 2.4.3+asdf', '1.2.3'], - ['1.0.0', '1.0.0'], - ['>=*', '0.2.4'], - ['', '1.0.0'], - ['*', '1.2.3', {}], - ['*', 'v1.2.3', { loose: 123 }], - ['>=1.0.0', '1.0.0', /asdf/], - ['>=1.0.0', '1.0.1', { loose: null }], - ['>=1.0.0', '1.1.0', { loose: 0 }], - ['>1.0.0', '1.0.1', { loose: undefined }], - ['>1.0.0', '1.1.0'], - ['<=2.0.0', '2.0.0'], - ['<=2.0.0', '1.9999.9999'], - ['<=2.0.0', '0.2.9'], - ['<2.0.0', '1.9999.9999'], - ['<2.0.0', '0.2.9'], - ['>= 1.0.0', '1.0.0'], - ['>= 1.0.0', '1.0.1'], - ['>= 1.0.0', '1.1.0'], - ['> 1.0.0', '1.0.1'], - ['> 1.0.0', '1.1.0'], - ['<= 2.0.0', '2.0.0'], - ['<= 2.0.0', '1.9999.9999'], - ['<= 2.0.0', '0.2.9'], - ['< 2.0.0', '1.9999.9999'], - ['<\t2.0.0', '0.2.9'], - ['>=0.1.97', 'v0.1.97', true], - ['>=0.1.97', '0.1.97'], - ['0.1.20 || 1.2.4', '1.2.4'], - ['>=0.2.3 || <0.0.1', '0.0.0'], - ['>=0.2.3 || <0.0.1', '0.2.3'], - ['>=0.2.3 || <0.0.1', '0.2.4'], - ['||', '1.3.4'], - ['2.x.x', '2.1.3'], - ['1.2.x', '1.2.3'], - ['1.2.x || 2.x', '2.1.3'], - ['1.2.x || 2.x', '1.2.3'], - ['x', '1.2.3'], - ['2.*.*', '2.1.3'], - ['1.2.*', '1.2.3'], - ['1.2.* || 2.*', '2.1.3'], - ['1.2.* || 2.*', '1.2.3'], - ['*', '1.2.3'], - ['2', '2.1.2'], - ['2.3', '2.3.1'], - ['~0.0.1', '0.0.1'], - ['~0.0.1', '0.0.2'], - ['~x', '0.0.9'], // >=2.4.0 <2.5.0 - ['~2', '2.0.9'], // >=2.4.0 <2.5.0 - ['~2.4', '2.4.0'], // >=2.4.0 <2.5.0 - ['~2.4', '2.4.5'], - ['~>3.2.1', '3.2.2'], // >=3.2.1 <3.3.0, - ['~1', '1.2.3'], // >=1.0.0 <2.0.0 - ['~>1', '1.2.3'], - ['~> 1', '1.2.3'], - ['~1.0', '1.0.2'], // >=1.0.0 <1.1.0, - ['~ 1.0', '1.0.2'], - ['~ 1.0.3', '1.0.12'], - ['~ 1.0.3alpha', '1.0.12', { loose: true }], - ['>=1', '1.0.0'], - ['>= 1', '1.0.0'], - ['<1.2', '1.1.1'], - ['< 1.2', '1.1.1'], - ['~v0.5.4-pre', '0.5.5'], - ['~v0.5.4-pre', '0.5.4'], - ['=0.7.x', '0.7.2'], - ['<=0.7.x', '0.7.2'], - ['>=0.7.x', '0.7.2'], - ['<=0.7.x', '0.6.2'], - ['~1.2.1 >=1.2.3', '1.2.3'], - ['~1.2.1 =1.2.3', '1.2.3'], - ['~1.2.1 1.2.3', '1.2.3'], - ['~1.2.1 >=1.2.3 1.2.3', '1.2.3'], - ['~1.2.1 1.2.3 >=1.2.3', '1.2.3'], - ['~1.2.1 1.2.3', '1.2.3'], - ['>=1.2.1 1.2.3', '1.2.3'], - ['1.2.3 >=1.2.1', '1.2.3'], - ['>=1.2.3 >=1.2.1', '1.2.3'], - ['>=1.2.1 >=1.2.3', '1.2.3'], - ['>=1.2', '1.2.8'], - ['^1.2.3', '1.8.1'], - ['^0.1.2', '0.1.2'], - ['^0.1', '0.1.2'], - ['^0.0.1', '0.0.1'], - ['^1.2', '1.4.2'], - ['^1.2 ^1', '1.4.2'], - ['^1.2.3-alpha', '1.2.3-pre'], - ['^1.2.0-alpha', '1.2.0-pre'], - ['^0.0.1-alpha', '0.0.1-beta'], - ['^0.0.1-alpha', '0.0.1'], - ['^0.1.1-alpha', '0.1.1-beta'], - ['^x', '1.2.3'], - ['x - 1.0.0', '0.9.7'], - ['x - 1.x', '0.9.7'], - ['1.0.0 - x', '1.9.7'], - ['1.x - x', '1.9.7'], - ['<=7.x', '7.9.9'], - ['2.x', '2.0.0-pre.0', { includePrerelease: true }], - ['2.x', '2.1.0-pre.0', { includePrerelease: true }] - ].forEach((v) => { - const range = v[0] - const ver = v[1] - const options = v[2] - t.ok(satisfies(ver, range, options), `${range} satisfied by ${ver}`) - }) - t.end() +test('negative range tests', t => { + t.plan(rangeExclude.length) + rangeExclude.forEach(([range, ver, options]) => + t.notOk(satisfies(ver, range, options), `${range} not satisfied by ${ver}`)) }) -test('negative range tests', (t) => { - // [range, version] - // version should not be included by range - [['1.0.0 - 2.0.0', '2.2.3'], - ['1.2.3+asdf - 2.4.3+asdf', '1.2.3-pre.2'], - ['1.2.3+asdf - 2.4.3+asdf', '2.4.3-alpha'], - ['^1.2.3+build', '2.0.0'], - ['^1.2.3+build', '1.2.0'], - ['^1.2.3', '1.2.3-pre'], - ['^1.2', '1.2.0-pre'], - ['>1.2', '1.3.0-beta'], - ['<=1.2.3', '1.2.3-beta'], - ['^1.2.3', '1.2.3-beta'], - ['=0.7.x', '0.7.0-asdf'], - ['>=0.7.x', '0.7.0-asdf'], - ['1', '1.0.0beta', { loose: 420 }], - ['<1', '1.0.0beta', true], - ['< 1', '1.0.0beta', true], - ['1.0.0', '1.0.1'], - ['>=1.0.0', '0.0.0'], - ['>=1.0.0', '0.0.1'], - ['>=1.0.0', '0.1.0'], - ['>1.0.0', '0.0.1'], - ['>1.0.0', '0.1.0'], - ['<=2.0.0', '3.0.0'], - ['<=2.0.0', '2.9999.9999'], - ['<=2.0.0', '2.2.9'], - ['<2.0.0', '2.9999.9999'], - ['<2.0.0', '2.2.9'], - ['>=0.1.97', 'v0.1.93', true], - ['>=0.1.97', '0.1.93'], - ['0.1.20 || 1.2.4', '1.2.3'], - ['>=0.2.3 || <0.0.1', '0.0.3'], - ['>=0.2.3 || <0.0.1', '0.2.2'], - ['2.x.x', '1.1.3', { loose: NaN }], - ['2.x.x', '3.1.3'], - ['1.2.x', '1.3.3'], - ['1.2.x || 2.x', '3.1.3'], - ['1.2.x || 2.x', '1.1.3'], - ['2.*.*', '1.1.3'], - ['2.*.*', '3.1.3'], - ['1.2.*', '1.3.3'], - ['1.2.* || 2.*', '3.1.3'], - ['1.2.* || 2.*', '1.1.3'], - ['2', '1.1.2'], - ['2.3', '2.4.1'], - ['~0.0.1', '0.1.0-alpha'], - ['~0.0.1', '0.1.0'], - ['~2.4', '2.5.0'], // >=2.4.0 <2.5.0 - ['~2.4', '2.3.9'], - ['~>3.2.1', '3.3.2'], // >=3.2.1 <3.3.0 - ['~>3.2.1', '3.2.0'], // >=3.2.1 <3.3.0 - ['~1', '0.2.3'], // >=1.0.0 <2.0.0 - ['~>1', '2.2.3'], - ['~1.0', '1.1.0'], // >=1.0.0 <1.1.0 - ['<1', '1.0.0'], - ['>=1.2', '1.1.1'], - ['1', '2.0.0beta', true], - ['~v0.5.4-beta', '0.5.4-alpha'], - ['=0.7.x', '0.8.2'], - ['>=0.7.x', '0.6.2'], - ['<0.7.x', '0.7.2'], - ['<1.2.3', '1.2.3-beta'], - ['=1.2.3', '1.2.3-beta'], - ['>1.2', '1.2.8'], - ['^0.0.1', '0.0.2-alpha'], - ['^0.0.1', '0.0.2'], - ['^1.2.3', '2.0.0-alpha'], - ['^1.2.3', '1.2.2'], - ['^1.2', '1.1.9'], - ['*', 'v1.2.3-foo', true], - // invalid ranges never satisfied! +test('invalid ranges never satisfied (but do not throw)', t => { + const cases = [ ['blerg', '1.2.3'], ['git+https://user:password0123@github.com/foo', '123.0.0', true], ['^1.2.3', '2.0.0-pre'], ['0.x', undefined], ['*', undefined], - // invalid versions never satisfy, but shouldn't throw - ['*', 'not a version'], - ['>=2', 'glorp'], - ['2.x', '3.0.0-pre.0', { includePrerelease: true }] - ].forEach((v) => { - const range = v[0] - const ver = v[1] - const options = v[2] - const found = satisfies(ver, range, options) - t.ok(!found, `${ver} not satisfied by ${range}`) - }) - t.end() -}) - -test('unlocked prerelease range tests', (t) => { - // [range, version] - // version should be included by range - [['*', '1.0.0-rc1'], - ['^1.0.0', '2.0.0-rc1'], - ['^1.0.0-0', '1.0.1-rc1'], - ['^1.0.0-rc2', '1.0.1-rc1'], - ['^1.0.0', '1.0.1-rc1'], - ['^1.0.0', '1.1.0-rc1'] - ].forEach((v) => { - const range = v[0] - const ver = v[1] - const options = { includePrerelease: true } - t.ok(satisfies(ver, range, options), `${range} satisfied by ${ver}`) - }) - t.end() -}) - -test('negative unlocked prerelease range tests', (t) => { - // [range, version] - // version should not be included by range - [['^1.0.0', '1.0.0-rc1'], - ['^1.2.3-rc2', '2.0.0'] - ].forEach((v) => { - const range = v[0] - const ver = v[1] - const options = { includePrerelease: true } - const found = satisfies(ver, range, options) - t.ok(!found, `${ver} not satisfied by ${range}`) - }) - t.end() + ] + t.plan(cases.length) + cases.forEach(([range, ver]) => + t.notOk(satisfies(ver, range), `${range} not satisfied because invalid`)) }) diff --git a/test/ranges/valid-range.js b/test/ranges/valid-range.js index 238164c8..515b4c19 100644 --- a/test/ranges/valid-range.js +++ b/test/ranges/valid-range.js @@ -1,90 +1,12 @@ const { test } = require('tap') const validRange = require('../../ranges/valid-range') +const rangeParse = require('../fixtures/range-parse.js') test('valid range test', (t) => { - // [range, result] // validRange(range) -> result // translate ranges into their canonical form - [['1.0.0 - 2.0.0', '>=1.0.0 <=2.0.0'], - ['1.0.0', '1.0.0'], - ['>=*', '*'], - ['', '*'], - ['*', '*'], - ['*', '*'], - ['>=1.0.0', '>=1.0.0'], - ['>1.0.0', '>1.0.0'], - ['<=2.0.0', '<=2.0.0'], - ['1', '>=1.0.0 <2.0.0'], - ['<=2.0.0', '<=2.0.0'], - ['<=2.0.0', '<=2.0.0'], - ['<2.0.0', '<2.0.0'], - ['<2.0.0', '<2.0.0'], - ['>= 1.0.0', '>=1.0.0'], - ['>= 1.0.0', '>=1.0.0'], - ['>= 1.0.0', '>=1.0.0'], - ['> 1.0.0', '>1.0.0'], - ['> 1.0.0', '>1.0.0'], - ['<= 2.0.0', '<=2.0.0'], - ['<= 2.0.0', '<=2.0.0'], - ['<= 2.0.0', '<=2.0.0'], - ['< 2.0.0', '<2.0.0'], - ['<\t2.0.0', '<2.0.0'], - ['>=0.1.97', '>=0.1.97'], - ['>=0.1.97', '>=0.1.97'], - ['0.1.20 || 1.2.4', '0.1.20||1.2.4'], - ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], - ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], - ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], - ['||', '||'], - ['2.x.x', '>=2.0.0 <3.0.0'], - ['1.2.x', '>=1.2.0 <1.3.0'], - ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], - ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], - ['x', '*'], - ['2.*.*', '>=2.0.0 <3.0.0'], - ['1.2.*', '>=1.2.0 <1.3.0'], - ['1.2.* || 2.*', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], - ['*', '*'], - ['2', '>=2.0.0 <3.0.0'], - ['2.3', '>=2.3.0 <2.4.0'], - ['~2.4', '>=2.4.0 <2.5.0'], - ['~2.4', '>=2.4.0 <2.5.0'], - ['~>3.2.1', '>=3.2.1 <3.3.0'], - ['~1', '>=1.0.0 <2.0.0'], - ['~>1', '>=1.0.0 <2.0.0'], - ['~> 1', '>=1.0.0 <2.0.0'], - ['~1.0', '>=1.0.0 <1.1.0'], - ['~ 1.0', '>=1.0.0 <1.1.0'], - ['^0', '>=0.0.0 <1.0.0'], - ['^ 1', '>=1.0.0 <2.0.0'], - ['^0.1', '>=0.1.0 <0.2.0'], - ['^1.0', '>=1.0.0 <2.0.0'], - ['^1.2', '>=1.2.0 <2.0.0'], - ['^0.0.1', '>=0.0.1 <0.0.2'], - ['^0.0.1-beta', '>=0.0.1-beta <0.0.2'], - ['^0.1.2', '>=0.1.2 <0.2.0'], - ['^1.2.3', '>=1.2.3 <2.0.0'], - ['^1.2.3-beta.4', '>=1.2.3-beta.4 <2.0.0'], - ['<1', '<1.0.0'], - ['< 1', '<1.0.0'], - ['>=1', '>=1.0.0'], - ['>= 1', '>=1.0.0'], - ['<1.2', '<1.2.0'], - ['< 1.2', '<1.2.0'], - ['1', '>=1.0.0 <2.0.0'], - ['>01.02.03', '>1.2.3', true], - ['>01.02.03', null], - ['~1.2.3beta', '>=1.2.3-beta <1.3.0', true], - ['~1.2.3beta', null], - ['^ 1.2 ^ 1', '>=1.2.0 <2.0.0 >=1.0.0 <2.0.0'] - ].forEach((v) => { - const pre = v[0] - const wanted = v[1] - const loose = v[2] - const found = validRange(pre, loose) - - t.equal(found, wanted, `validRange(${pre}) === ${wanted}`) - }) - - t.end() + t.plan(rangeParse.length) + rangeParse.forEach(([pre, wanted, options]) => + t.equal(validRange(pre, options), wanted, + `validRange(${pre}) === ${wanted}`)) })