diff --git a/classes/comparator.js b/classes/comparator.js index 647c1f09..50856b2f 100644 --- a/classes/comparator.js +++ b/classes/comparator.js @@ -95,6 +95,15 @@ class Comparator { options = parseOptions(options) + // Appending .0 to a prerelease gives its immediate successor, so two + // exclusive bounds around that pair cannot contain any version. + if ((this.operator === '>' && comp.operator === '<' && + comp.semver.version === `${this.semver.version}.0`) || + (this.operator === '<' && comp.operator === '>' && + this.semver.version === `${comp.semver.version}.0`)) { + return false + } + // Special cases where nothing can possibly be lower if (options.includePrerelease && (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { diff --git a/test/classes/comparator.js b/test/classes/comparator.js index 477b2ab6..f19bc0d4 100644 --- a/test/classes/comparator.js +++ b/test/classes/comparator.js @@ -44,6 +44,21 @@ test('intersect demands another comparator', t => { t.end() }) +test('adjacent prereleases with loose numeric identifiers', t => { + const options = { loose: true, includePrerelease: true } + for (const [lower, upper] of [ + ['1.0.0-01', '1.0.0-1.00'], + ['1.0.0-0009007199254740992', '1.0.0-9007199254740992.0'], + ['1.0.0-9007199254740992', '1.0.0-0009007199254740992.0'], + ]) { + const a = new Comparator(`>${lower}`, options) + const b = new Comparator(`<${upper}`, options) + t.notOk(a.intersects(b, options)) + t.notOk(b.intersects(a, options)) + } + t.end() +}) + test('ANY matches anything', t => { const c = new Comparator('') t.ok(c.test('1.2.3'), 'ANY matches anything') diff --git a/test/fixtures/comparator-intersection.js b/test/fixtures/comparator-intersection.js index 08c4bc08..9bcfb070 100644 --- a/test/fixtures/comparator-intersection.js +++ b/test/fixtures/comparator-intersection.js @@ -41,4 +41,16 @@ module.exports = [ ['<0.1.0', '<0.0.0-0', false], ['<0.0.0-0', '<0.1.0', false, true], ['<0.1.0', '<0.0.0-0', false, true], + // No version lies strictly between a prerelease and its extension by .0. + ['>1.0.0-alpha', '<1.0.0-alpha.0', false], + ['>1.0.0-alpha', '<1.0.0-alpha.0', false, true], + ['>1.0.0-0', '<1.0.0-0.0', false], + ['>1.0.0-alpha.1', '<1.0.0-alpha.1.0', false], + ['>1.0.0-alpha+left', '<1.0.0-alpha.0+right', false], + ['>1.0.0-9007199254740992', '<1.0.0-9007199254740992.0', false], + ['>=1.0.0-alpha', '<1.0.0-alpha.0', true], + ['>1.0.0-alpha', '<=1.0.0-alpha.0', true], + ['>1.0.0-alpha', '<1.0.0-alpha.1', true], + ['>1.0.0-alpha', '<1.0.0-alpha.0.0', true], + ['>1.0.0-alpha', '<1.0.0-beta.0', true], ] diff --git a/test/fixtures/range-intersection.js b/test/fixtures/range-intersection.js index 217bee22..86b0063d 100644 --- a/test/fixtures/range-intersection.js +++ b/test/fixtures/range-intersection.js @@ -58,4 +58,8 @@ module.exports = [ ['1.x', '1.3.0 || <1.0.0 >2.0.0', true], ['*', '*', true], ['x', '', true], + ['>1.0.0-alpha <1.0.0-alpha.0', '>=1.0.0-alpha', false], + ['>1.0.0-alpha <1.0.0-alpha.0', '>1.0.0-alpha <1.0.0-alpha.0', false], + ['>1.0.0-alpha <1.0.0-alpha.0 || 2.0.0', '*', true], + ['>1.0.0-alpha <1.0.0-alpha.0 || 2.0.0', '3.0.0', false], ]