Skip to content

Commit

Permalink
fix: intersects with v0.0.0 and v0.0.0-0 (#538)
Browse files Browse the repository at this point in the history
  • Loading branch information
wraithgar authored Apr 10, 2023
1 parent aa516b5 commit 940723d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 56 deletions.
63 changes: 37 additions & 26 deletions classes/comparator.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,32 +90,43 @@ class Comparator {
return new Range(this.value, options).test(comp.semver)
}

const sameDirectionIncreasing =
(this.operator === '>=' || this.operator === '>') &&
(comp.operator === '>=' || comp.operator === '>')
const sameDirectionDecreasing =
(this.operator === '<=' || this.operator === '<') &&
(comp.operator === '<=' || comp.operator === '<')
const sameSemVer = this.semver.version === comp.semver.version
const differentDirectionsInclusive =
(this.operator === '>=' || this.operator === '<=') &&
(comp.operator === '>=' || comp.operator === '<=')
const oppositeDirectionsLessThan =
cmp(this.semver, '<', comp.semver, options) &&
(this.operator === '>=' || this.operator === '>') &&
(comp.operator === '<=' || comp.operator === '<')
const oppositeDirectionsGreaterThan =
cmp(this.semver, '>', comp.semver, options) &&
(this.operator === '<=' || this.operator === '<') &&
(comp.operator === '>=' || comp.operator === '>')

return (
sameDirectionIncreasing ||
sameDirectionDecreasing ||
(sameSemVer && differentDirectionsInclusive) ||
oppositeDirectionsLessThan ||
oppositeDirectionsGreaterThan
)
options = parseOptions(options)

// Special cases where nothing can possibly be lower
if (options.includePrerelease &&
(this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) {
return false
}
if (!options.includePrerelease &&
(this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) {
return false
}

// Same direction increasing (> or >=)
if (this.operator.startsWith('>') && comp.operator.startsWith('>')) {
return true
}
// Same direction decreasing (< or <=)
if (this.operator.startsWith('<') && comp.operator.startsWith('<')) {
return true
}
// same SemVer and both sides are inclusive (<= or >=)
if (
(this.semver.version === comp.semver.version) &&
this.operator.includes('=') && comp.operator.includes('=')) {
return true
}
// opposite directions less than
if (cmp(this.semver, '<', comp.semver, options) &&
this.operator.startsWith('>') && comp.operator.startsWith('<')) {
return true
}
// opposite directions greater than
if (cmp(this.semver, '>', comp.semver, options) &&
this.operator.startsWith('<') && comp.operator.startsWith('>')) {
return true
}
return false
}
}

Expand Down
2 changes: 1 addition & 1 deletion ranges/intersects.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ const Range = require('../classes/range')
const intersects = (r1, r2, options) => {
r1 = new Range(r1, options)
r2 = new Range(r2, options)
return r1.intersects(r2)
return r1.intersects(r2, options)
}
module.exports = intersects
23 changes: 12 additions & 11 deletions test/classes/comparator.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ test('tostrings', (t) => {

test('intersect comparators', (t) => {
t.plan(comparatorIntersection.length)
comparatorIntersection.forEach(([c0, c1, expect]) => t.test(`${c0} ${c1} ${expect}`, t => {
const comp0 = new Comparator(c0)
const comp1 = new Comparator(c1)

t.equal(comp0.intersects(comp1, false), expect,
`${c0} intersects ${c1}`)

t.equal(comp1.intersects(comp0, { loose: false }), expect,
`${c1} intersects ${c0}`)
t.end()
}))
comparatorIntersection.forEach(([c0, c1, expect, includePrerelease]) =>
t.test(`${c0} ${c1} ${expect}`, t => {
const comp0 = new Comparator(c0)
const comp1 = new Comparator(c1)

t.equal(comp0.intersects(comp1, { includePrerelease }), expect,
`${c0} intersects ${c1}`)

t.equal(comp1.intersects(comp0, { includePrerelease }), expect,
`${c1} intersects ${c0}`)
t.end()
}))
})

test('intersect demands another comparator', t => {
Expand Down
8 changes: 7 additions & 1 deletion test/fixtures/comparator-intersection.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// c0, c1, expected intersection
// c0, c1, expected intersection, includePrerelease
module.exports = [
// One is a Version
['1.3.0', '>=1.3.0', true],
Expand Down Expand Up @@ -33,4 +33,10 @@ module.exports = [
['', '', true],
['', '>1.0.0', true],
['<=2.0.0', '', true],
['<0.0.0', '<0.1.0', false],
['<0.1.0', '<0.0.0', false],
['<0.0.0-0', '<0.1.0', false],
['<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],
]
34 changes: 17 additions & 17 deletions test/ranges/intersects.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ const rangeIntersection = require('../fixtures/range-intersection.js')

test('intersect comparators', t => {
t.plan(comparatorIntersection.length)
comparatorIntersection.forEach(([c0, c1, expect]) => t.test(`${c0} ${c1} ${expect}`, t => {
const comp0 = new Comparator(c0)
const comp1 = new Comparator(c1)
comparatorIntersection.forEach(([c0, c1, expect, includePrerelease]) =>
t.test(`${c0} ${c1} ${expect}`, t => {
const opts = { loose: false, includePrerelease }
const comp0 = new Comparator(c0)
const comp1 = new Comparator(c1)

t.equal(intersects(comp0, comp1), expect, `${c0} intersects ${c1} objects`)
t.equal(intersects(comp1, comp0), expect, `${c1} intersects ${c0} objects`)
t.equal(intersects(comp0, comp1, true), expect,
`${c0} intersects ${c1} loose, objects`)
t.equal(intersects(comp1, comp0, true), expect,
`${c1} intersects ${c0} loose, objects`)
t.equal(intersects(c0, c1), expect, `${c0} intersects ${c1}`)
t.equal(intersects(c1, c0), expect, `${c1} intersects ${c0}`)
t.equal(intersects(c0, c1, true), expect,
`${c0} intersects ${c1} loose`)
t.equal(intersects(c1, c0, true), expect,
`${c1} intersects ${c0} loose`)
t.end()
}))
t.equal(intersects(comp0, comp1, opts), expect, `${c0} intersects ${c1} objects`)
t.equal(intersects(comp1, comp0, opts), expect, `${c1} intersects ${c0} objects`)
t.equal(intersects(c0, c1, opts), expect, `${c0} intersects ${c1}`)
t.equal(intersects(c1, c0, opts), expect, `${c1} intersects ${c0}`)

opts.loose = true
t.equal(intersects(comp0, comp1, opts), expect, `${c0} intersects ${c1} loose, objects`)
t.equal(intersects(comp1, comp0, opts), expect, `${c1} intersects ${c0} loose, objects`)
t.equal(intersects(c0, c1, opts), expect, `${c0} intersects ${c1} loose`)
t.equal(intersects(c1, c0, opts), expect, `${c1} intersects ${c0} loose`)
t.end()
}))
})

test('ranges intersect', (t) => {
Expand Down

0 comments on commit 940723d

Please sign in to comment.