Skip to content

Commit

Permalink
Move methods to comparator and range
Browse files Browse the repository at this point in the history
  • Loading branch information
rtfpessoa authored and isaacs committed Jul 24, 2017
1 parent 67c9ed7 commit afbe8ca
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 61 deletions.
104 changes: 54 additions & 50 deletions semver.js
Expand Up @@ -704,6 +704,48 @@ Comparator.prototype.test = function(version) {
return cmp(version, this.operator, this.semver, this.loose);
};

Comparator.prototype.intersects = function(comp, loose, platform) {
if (!(comp instanceof Comparator)) {
throw new TypeError('a Comparator is required');
}

var rangeTmp;

if (this.operator === '') {
rangeTmp = new Range(comp.value, loose, platform);
return satisfies(this.value, rangeTmp, loose, platform);
} else if (comp.operator === '') {
rangeTmp = new Range(this.value, loose, platform);
return satisfies(comp.semver, rangeTmp, loose, platform);
}

var sameDirectionIncreasing = (this.operator === '>=' || this.operator === '>') && (comp.operator === '>=' || comp.operator === '>');
var sameDirectionDecreasing = (this.operator === '<=' || this.operator === '<') && (comp.operator === '<=' || comp.operator === '<');
var sameSemVer = this.semver.raw === comp.semver.raw;
var differentDirectionsInclusive = (this.operator === '>=' || this.operator === '<=') && (comp.operator === '>=' || comp.operator === '<=');
var oppositeDirectionsLessThan = cmp(this.semver, '<', comp.semver, loose) &&
((this.operator === '>=' || this.operator === '>') && (comp.operator === '<=' || comp.operator === '<'));
var oppositeDirectionsGreaterThan = cmp(this.semver, '>', comp.semver, loose) &&
((this.operator === '<=' || this.operator === '<') && (comp.operator === '>=' || comp.operator === '>'));

return sameDirectionIncreasing || sameDirectionDecreasing || (sameSemVer && differentDirectionsInclusive) ||
oppositeDirectionsLessThan || oppositeDirectionsGreaterThan;
};

Comparator.prototype.satisfiesRange = function(range, loose, platform) {
if (!(range instanceof Range)) {
throw new TypeError('a Range is required');
}

var comp = this;

return range.set.some(function(comparators) {
return comparators.every(function(comparator) {
return comp.intersects(comparator, loose, platform);
});
});
};


exports.Range = Range;
function Range(range, loose) {
Expand Down Expand Up @@ -783,6 +825,18 @@ Range.prototype.parseRange = function(range) {
return set;
};

Range.prototype.intersects = function(range, loose, platform) {
if (!(range instanceof Range)) {
throw new TypeError('a Range is required');
}

return this.set.some(function(comparators) {
return comparators.every(function(comparator) {
return comparator.satisfiesRange(range, loose, platform);
});
});
};

// Mostly just for testing and legacy API reasons
exports.toComparators = toComparators;
function toComparators(range, loose) {
Expand All @@ -793,56 +847,6 @@ function toComparators(range, loose) {
});
}

exports.comparatorsIntersect = comparatorsIntersect;
function comparatorsIntersect(compA, compB, loose, platform) {
compA = new Comparator(compA, loose);
compB = new Comparator(compB, loose);

if (compA.operator === '') {
var rangeB = new Range(compB.value, loose, platform);
return satisfies(compA.value, rangeB, loose, platform);
} else if (compB.operator === '') {
var rangeA = new Range(compA.value, loose, platform);
return satisfies(compB.semver, rangeA, loose, platform);
}
// Same direction increasing
return ((compA.operator === '>=' || compA.operator === '>') && (compB.operator === '>=' || compB.operator === '>')) ||
// Same direction decreasing
((compA.operator === '<=' || compA.operator === '<') && (compB.operator === '<=' || compB.operator === '<')) ||
// Different directions, same semver and inclusive operator
(compA.semver.raw === compB.semver.raw &&
(compA.operator === '>=' || compA.operator === '<=') && (compB.operator === '>=' || compB.operator === '<=')) ||
// Opposite matching directions
(cmp(compA.semver, '<', compB.semver, loose) &&
((compA.operator === '>=' || compA.operator === '>') && (compB.operator === '<=' || compB.operator === '<'))) ||
(cmp(compA.semver, '>', compB.semver, loose) &&
((compA.operator === '<=' || compA.operator === '<') && (compB.operator === '>=' || compB.operator === '>')));
}

exports.comparatorSatisfiesRange = comparatorSatisfiesRange;
function comparatorSatisfiesRange(comp, range, loose, platform) {
comp = new Comparator(comp, loose);
range = new Range(range, loose, platform);

return range.set.some(function(comparators) {
return comparators.every(function(comparator) {
return comparatorsIntersect(comparator, comp, loose, platform);
});
});
}

exports.rangesIntersect = rangesIntersect;
function rangesIntersect(rangeA, rangeB, loose, platform) {
rangeA = new Range(rangeA, loose, platform);
rangeB = new Range(rangeB, loose, platform);

return rangeA.set.some(function(comparators) {
return comparators.every(function(comparator) {
return comparatorSatisfiesRange(comparator, rangeB, loose, platform);
});
});
}

// comprised of xranges, tildes, stars, and gtlt's at this point.
// already replaced the hyphen ranges
// turn into a set of JUST comparators.
Expand Down
53 changes: 42 additions & 11 deletions test/index.js
Expand Up @@ -18,6 +18,7 @@ var replaceStars = semver.replaceStars;
var toComparators = semver.toComparators;
var SemVer = semver.SemVer;
var Range = semver.Range;
var Comparator = semver.Comparator;

test('\ncomparison tests', function(t) {
// [version1, version2]
Expand Down Expand Up @@ -744,45 +745,75 @@ test('\nintersect comparators', function(t) {
['<=2.0.0', '>1.0.0', true],
['<=1.0.0', '>=2.0.0', false]
].forEach(function(v) {
var comparator1 = v[0];
var comparator2 = v[1];
var comparator1 = new Comparator(v[0]);
var comparator2 = new Comparator(v[1]);
var expect = v[2];
var actual = semver.comparatorsIntersect(comparator1, comparator2);
t.equal(actual, expect);

var actual1 = comparator1.intersects(comparator2);
var actual2 = comparator2.intersects(comparator1);
t.equal(actual1, expect);
t.equal(actual2, expect);
});
t.end();
});

test('\nmissing comparator parameter in intersect comparators', function(t) {
t.throws(function() {
new Comparator('>1.0.0').intersects();
}, new TypeError('a Comparator is required'),
'throws type error');
t.end();
});

test('\ncomparator satisfies range', function(t) {
[
['1.3.0', '1.3.0 || <1.0.0 >2.0.0', true],
['1.3.0', '<1.0.0 >2.0.0', false],
['>=1.3.0', '<1.3.0', false],
['<1.3.0', '>=1.3.0', false]
].forEach(function(v) {
var comparator = v[0];
var range = v[1];
var comparator = new Comparator(v[0]);
var range = new Range(v[1]);
var expect = v[2];
var actual = semver.comparatorSatisfiesRange(comparator, range);
var actual = comparator.satisfiesRange(range);
t.equal(actual, expect);
});
t.end();
});

test('\nmissing range parameter in comparator satisfies range', function(t) {
t.throws(function() {
new Comparator('>1.0.0').satisfiesRange();
}, new TypeError('a Range is required'),
'throws type error');
t.end();
});

test('\nranges intersect', function(t) {
[
['1.3.0 || <1.0.0 >2.0.0', '1.3.0 || <1.0.0 >2.0.0', true],
['<1.0.0 >2.0.0', '>0.0.0', true],
['<1.0.0 >2.0.0', '>1.4.0 <1.6.0', false],
['<1.0.0 >2.0.0', '>1.4.0 <1.6.0 || 2.0.0', false],
['>1.0.0 <=2.0.0', '2.0.0', true],
['<1.0.0 >=2.0.0', '2.1.0', false],
['<1.0.0 >=2.0.0', '>1.4.0 <1.6.0 || 2.0.0', false]
].forEach(function(v) {
var range1 = v[0];
var range2 = v[1];
var range1 = new Range(v[0]);
var range2 = new Range(v[1]);
var expect = v[2];
var actual = semver.rangesIntersect(range1, range2);
t.equal(actual, expect);
var actual1 = range1.intersects(range2);
var actual2 = range2.intersects(range1);
t.equal(actual1, expect);
t.equal(actual2, expect);
});
t.end();
});

test('\nmissing range parameter in range intersect', function(t) {
t.throws(function() {
new Range('1.0.0').intersects();
}, new TypeError('a Range is required'),
'throws type error');
t.end();
});

0 comments on commit afbe8ca

Please sign in to comment.