Skip to content

Commit

Permalink
fix: Support all valid SemVer syntax in version comparison helper (#695)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmilan-dev authored and raphinesse committed Oct 23, 2019
1 parent be68c9f commit f43812a
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 28 deletions.
37 changes: 11 additions & 26 deletions bin/templates/scripts/cordova/lib/versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

var child_process = require('child_process');
var Q = require('q');
var semver = require('semver');

exports.get_apple_ios_version = function () {
var d = Q.defer();
Expand Down Expand Up @@ -159,36 +160,20 @@ exports.get_tool_version = function (toolName) {
};

/**
* Compares two semver-notated version strings. Returns number
* that indicates equality of provided version strings.
* Compares two version strings that can be coerced to semver.
*
* @param {String} version1 Version to compare
* @param {String} version2 Another version to compare
* @return {Number} Negative number if first version is lower than the second,
* positive otherwise and 0 if versions are equal.
*/
exports.compareVersions = function (version1, version2) {
function parseVer (version) {
return version.split('.').map(function (value) {
// try to convert version segment to Number
var parsed = Number(value);
// Number constructor is strict enough and will return NaN
// if conversion fails. In this case we won't be able to compare versions properly
if (isNaN(parsed)) {
throw 'Version should contain only numbers and dots';
}
return parsed;
});
}
var parsedVer1 = parseVer(version1);
var parsedVer2 = parseVer(version2);
exports.compareVersions = (...args) => {
const coerceToSemverIfInvalid = v => {
const semverVersion = semver.parse(v) || semver.coerce(v);
if (!semverVersion) throw new TypeError(`Invalid Version: ${v}`);
return semverVersion;
};

// Compare corresponding segments of each version
for (var i = 0; i < Math.max(parsedVer1.length, parsedVer2.length); i++) {
// if segment is not specified, assume that it is 0
// E.g. 3.1 is equal to 3.1.0
var ret = (parsedVer1[i] || 0) - (parsedVer2[i] || 0);
// if segments are not equal, we're finished
if (ret !== 0) return ret;
}
return 0;
const semverVersions = args.map(coerceToSemverIfInvalid);
return semver.compare(...semverVersions);
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"nopt": "^4.0.1",
"plist": "^3.0.1",
"q": "^1.5.1",
"semver": "^6.3.0",
"shelljs": "^0.5.3",
"unorm": "^1.4.1",
"xcode": "^2.0.0",
Expand Down
4 changes: 2 additions & 2 deletions tests/spec/unit/lib/check_reqs.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ describe('check_reqs', function () {
compareVersions: originalVersion.compareVersions
});

checkTool('node', 'v1.0.0').catch((error) => {
expect(error).toEqual('Version should contain only numbers and dots');
checkTool('node', 'a.b.c').catch(err => {
expect(err).toEqual(new TypeError('Invalid Version: a.b.c'));
done();
});
});
Expand Down
35 changes: 35 additions & 0 deletions tests/spec/unit/versions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
under the License.
*/

var semver = require('semver');
var rewire = require('rewire');
var versions = rewire('../../../bin/templates/scripts/cordova/lib/versions');

Expand Down Expand Up @@ -52,3 +53,37 @@ if (process.platform === 'darwin') {
});
});
}

describe('versions', () => {
describe('compareVersions method', () => {
it('calls semver.compare, given valid semver', () => {
const testVersions = ['1.0.0', '1.1.0'];
spyOn(semver, 'compare');

versions.compareVersions(...testVersions);
expect(semver.compare).toHaveBeenCalledWith(
...testVersions.map(version =>
jasmine.objectContaining({ version })
)
);
});

it('handles pre-release identifiers', () => {
expect(
versions.compareVersions('1.0.0-rc.0', '1.0.0')
).toBe(-1);
});

it('handles non-semver versions', () => {
expect(
versions.compareVersions('10.1', '10')
).toBe(1);
});

it('does not handle pre-release identifiers on non-semver versions', () => {
expect(
versions.compareVersions('10.1-beta.1', '10.1')
).toBe(0);
});
});
});

0 comments on commit f43812a

Please sign in to comment.