From 787f71566ca1c52f30339948f1001c58b09734dd Mon Sep 17 00:00:00 2001 From: metaraine Date: Sat, 6 Jun 2015 15:22:04 -0600 Subject: [PATCH 1/5] Add mocha unit tests. --- .gitignore | 1 + package.json | 9 ++- semver-utils-test.js | 131 ----------------------------------- test/deepOwnEqual.js | 26 +++++++ test/spec.js | 161 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 195 insertions(+), 133 deletions(-) create mode 100644 .gitignore delete mode 100644 semver-utils-test.js create mode 100644 test/deepOwnEqual.js create mode 100644 test/spec.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/package.json b/package.json index 5f679c9..83aaf1c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Tools for manipulating semver strings and objects", "main": "semver-utils.js", "scripts": { - "test": "node semver-utils-test.js" + "test": "mocha" }, "repository": { "type": "git", @@ -18,5 +18,10 @@ ], "author": "AJ ONeal", "license": "APACHEv2", - "readmeFilename": "README.md" + "readmeFilename": "README.md", + "devDependencies": { + "chai": "^3.0.0", + "deep-equal": "^1.0.0", + "mocha": "^2.2.5" + } } diff --git a/semver-utils-test.js b/semver-utils-test.js deleted file mode 100644 index 9bfa0a2..0000000 --- a/semver-utils-test.js +++ /dev/null @@ -1,131 +0,0 @@ -(function () { - var semverutils = require('./semver-utils') - ; - - function testParseRange() { - console.info('testParseRange'); - var good = - [ 'v1.0.0' - , '< v2.0.0' - , '~v2.0.0' - , '~1.0.0' - , '~1.0.0 || >= 1.1.7 < 2.0.0+build.1848' - , '~1.0.0 || >= 1.1.7 < 2.0.0+build.1848 || v1.1.3' - , '~1.0.0 || >= 1.1.7 < 2.0.0+build.1848 || v1.1.3 || 2.0.1-alpha.1227' - , '~1.0.0 || >= 1.1.7 < 2.0.0+build.1848 || v1.1.3 || 2.0.1-alpha.1227 || 1.0.0 - 1.0.x' - , '~1.0.0 || >= 1.1.7 < 2.0.0+build.1848 || v1.1.3 || 2.0.1-alpha.1227 || 1.0.0 - 1.0.x || 1.*' - ] - ; - - good.every(function (range) { - var result = semverutils.parseRange(range) - ; - - if (!result || 0 === result.length) { - throw new Error("didn't parse something that should be parseable: " + range); - } - - return true; - }); - - console.log(good[good.length - 1]); - console.log(semverutils.stringifyRange(semverutils.parseRange(good[good.length - 1]))); - } - - function testParse() { - console.info('testParse'); - var good - , bad - ; - - good = [ - "1.0.8" - , "1.23.7" - , "2.0.0-alpha.123.abc" - , "2.0.0-alpha.123.abc+build.acebfde1284" - , "1.0.0-alpha" - , "1.0.0-alpha.1" - , "1.0.0-0.3.7" - , "1.0.0-x.7.z.92" - , "1.0.0-alpha" - , "1.0.0-alpha.1" - , "1.0.0-beta.2" - , "1.0.0-beta.11" - , "1.0.0-rc.1" - , "1.0.0-rc.1+build.1" - , "1.0.0-rc.1+build.1-b" - , "1.0.0" - , "1.0.0+0.3.7" - , "1.3.7+build" - , "1.3.7+build.2.b8f12d7" - , "1.3.7+build.11.e0f985a" - , "1.3.7+build.11.e0f9-85a" - , "1.0.0+build-acbe" - , "2.0.0+build.acebfde1284-alpha.123.abc" - ]; - - bad = [ - // "v1.0.0" now allows optional 'v' - , "a.b.c" - , "1" - , "1.0.0b" - , "1.0" - , "1.0.0+b[\\]^_`uild" // [,\,],^,_,` are between A-z, but not A-Za-z - , "1.0.0+build-acbe." // trailing period - , "1.0.0+build.!@#$%" - ]; - - good.every(function (version) { - var result = semverutils.parse(version) - ; - - if (!result) { - throw new Error("didn't parse something that should be parseable: " + version); - } - - return true; - }); - - bad.every(function (version) { - var result = semverutils.parse(version) - ; - - if (result) { - throw new Error("parsed something that should not be parseable: " + version); - } - - return true; - }); - - console.log(semverutils.parse("a.b.c")); // null - console.log(semverutils.parse("1.0.3")); - /* - { - semver: 1.0.3 - , major: 1 - , minor: 0 - , patch: 3 - } - */ - - console.log(semverutils.parse("1.0.3-rc.1+build.aef312")); - /* - { - semver: v1.0.3-rc.1+build.aef312 - , major: 1 - , minor: 0 - , patch: 3 - , build: build.aef312 - , release: rc.1 - } - */ - - console.log(semverutils.parse("1.0.0-rc.1-1")); - console.log(semverutils.parse("1.0.0-rc.1+build.1-b")); - console.log(semverutils.parse("1.0.0-rc.1-1+build.1-b")); - console.log(semverutils.parse("2.0.0+build.acebfde1284-alpha.123.abc")); - } - - testParse(); - testParseRange(); -}()); diff --git a/test/deepOwnEqual.js b/test/deepOwnEqual.js new file mode 100644 index 0000000..b7dd276 --- /dev/null +++ b/test/deepOwnEqual.js @@ -0,0 +1,26 @@ +var assert = require('chai').assert; + +// we need to define our own deepEqual function that ignores properties that are not hasOwnProperty. Not supported in chai.assert.deepEqual as of v3.0.0. +function deepOwnEqual(a, b) { + + // if arrays of objects, recurse down to the objects + if(Array.isArray(a) && Array.isArray(b)) { + assert.deepEqual(a.length, b.length, 'Arrays have different lengths') + for(var i=0; i Date: Sat, 6 Jun 2015 15:22:32 -0600 Subject: [PATCH 2/5] prune results of .parse, not just .parseRange --- semver-utils.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/semver-utils.js b/semver-utils.js index 20b3fff..3f6c143 100644 --- a/semver-utils.js +++ b/semver-utils.js @@ -11,6 +11,18 @@ , reSemverRange = /\s*((\|\||\-)|(([<>~]?=?)\s*(v)?([0-9]+)(\.(x|\*|[0-9]+))?(\.(x|\*|[0-9]+))?(([\-+])([a-zA-Z0-9\.]+))?))\s*/g ; + // Returns a new object with all of the undefined properties removed from the given object + function pruned(obj) { + var o = {}; + for(var key in obj) { + if ('undefined' !== typeof obj[key]) { + o[key] = obj[key]; + } + } + return o; + } + + function stringifySemver(obj) { var str = '' ; @@ -86,7 +98,7 @@ // https://github.com/isaacs/node-semver/issues/10 // optional v var m = reSemver.exec(version) || [] - , ver = new SemVer({ + , ver = new SemVer(pruned({ semver: m[0] , version: m[1] , major: m[2] @@ -94,7 +106,7 @@ , patch: m[4] , release: m[5] , build: m[6] - }) + })) ; if (0 === m.length) { @@ -110,12 +122,7 @@ , obj ; - function prune(key) { - if ('undefined' === typeof obj[key]) { - delete obj[key]; - } - } - + while (true) { m = reSemverRange.exec(str); if (!m) { @@ -134,8 +141,7 @@ if ('-' === m[12]) { obj.release = m[13]; } - Object.keys(obj).forEach(prune); - arr.push(new SemVer(obj)); + arr.push(new SemVer(pruned(obj))); //console.log(m); } From 74cc0b238e6cfb98238b290022f9c9ca1692e3dc Mon Sep 17 00:00:00 2001 From: metaraine Date: Sat, 6 Jun 2015 15:27:43 -0600 Subject: [PATCH 3/5] Add support for caret (^) --- semver-utils.js | 9 ++------- test/spec.js | 10 ++++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/semver-utils.js b/semver-utils.js index 3f6c143..994239f 100644 --- a/semver-utils.js +++ b/semver-utils.js @@ -8,7 +8,7 @@ // | | | |optional build prefixed by '+' var reSemver = /^v?((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/ //, reSemverRange = /\s*((\|\||\-)|(([<>~]?=?)\s*(v)?([0-9]+)(\.(x|[0-9]+))?(\.(x|[0-9]+))?(([\-+])([a-zA-Z0-9\.]+))?))\s*/g - , reSemverRange = /\s*((\|\||\-)|(([<>~]?=?)\s*(v)?([0-9]+)(\.(x|\*|[0-9]+))?(\.(x|\*|[0-9]+))?(([\-+])([a-zA-Z0-9\.]+))?))\s*/g + , reSemverRange = /\s*((\|\||\-)|(([<>~^]?=?)\s*(v)?([0-9]+)(\.(x|\*|[0-9]+))?(\.(x|\*|[0-9]+))?(([\-+])([a-zA-Z0-9\.]+))?))\s*/g ; // Returns a new object with all of the undefined properties removed from the given object @@ -22,7 +22,6 @@ return o; } - function stringifySemver(obj) { var str = '' ; @@ -123,11 +122,7 @@ ; - while (true) { - m = reSemverRange.exec(str); - if (!m) { - break; - } + while (m = reSemverRange.exec(str)) { obj = { semver: m[3] , operator: m[4] || m[2] diff --git a/test/spec.js b/test/spec.js index 76a37a9..0417f17 100644 --- a/test/spec.js +++ b/test/spec.js @@ -88,6 +88,16 @@ describe('parseRange', function() { }]); }); + it('should parse caret', function() { + deepOwnEqual(semverutils.parseRange('^1.0.0'), [{ + semver: '^1.0.0', + operator: '^', + major: '1', + minor: '0', + patch: '0' + }]); + }); + it('should parse tilde and v- prefix', function() { deepOwnEqual(semverutils.parseRange('~v1.0.0'), [{ semver: '~v1.0.0', From ff978dc8ad32afe06fa63281566f1fcefc55869b Mon Sep 17 00:00:00 2001 From: metaraine Date: Sat, 6 Jun 2015 15:39:50 -0600 Subject: [PATCH 4/5] Remove unnecessary deep-equal dependency. --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 83aaf1c..57dd498 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ "readmeFilename": "README.md", "devDependencies": { "chai": "^3.0.0", - "deep-equal": "^1.0.0", "mocha": "^2.2.5" } } From 86ea225075e5e528d1be4be2601a8ebd6f208f12 Mon Sep 17 00:00:00 2001 From: metaraine Date: Mon, 3 Aug 2015 11:12:58 -0600 Subject: [PATCH 5/5] Fix reSemverRange to parse pre-release versions that contain hyphens. --- semver-utils.js | 12 ++++++------ test/spec.js | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/semver-utils.js b/semver-utils.js index 994239f..4307a12 100644 --- a/semver-utils.js +++ b/semver-utils.js @@ -8,7 +8,7 @@ // | | | |optional build prefixed by '+' var reSemver = /^v?((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/ //, reSemverRange = /\s*((\|\||\-)|(([<>~]?=?)\s*(v)?([0-9]+)(\.(x|[0-9]+))?(\.(x|[0-9]+))?(([\-+])([a-zA-Z0-9\.]+))?))\s*/g - , reSemverRange = /\s*((\|\||\-)|(([<>~^]?=?)\s*(v)?([0-9]+)(\.(x|\*|[0-9]+))?(\.(x|\*|[0-9]+))?(([\-+])([a-zA-Z0-9\.]+))?))\s*/g + , reSemverRange = /\s*((\|\||\-)|(([<>~^]?=?)\s*(v)?([0-9]+)(\.(x|\*|[0-9]+))?(\.(x|\*|[0-9]+))?(([\-+])([a-zA-Z0-9\.-]+))?))\s*/g ; // Returns a new object with all of the undefined properties removed from the given object @@ -54,7 +54,7 @@ } arr.forEach(stringify); - + return str.trim(); } @@ -107,11 +107,11 @@ , build: m[6] })) ; - + if (0 === m.length) { ver = null; } - + return ver; } @@ -120,7 +120,7 @@ , arr = [] , obj ; - + while (m = reSemverRange.exec(str)) { obj = { @@ -139,7 +139,7 @@ arr.push(new SemVer(pruned(obj))); //console.log(m); } - + //return new SemVerRange(arr); return arr; } diff --git a/test/spec.js b/test/spec.js index 0417f17..4017b11 100644 --- a/test/spec.js +++ b/test/spec.js @@ -136,6 +136,27 @@ describe('parseRange', function() { }]); }); + it('should parse pre-release versions', function() { + deepOwnEqual(semverutils.parseRange('1.0.0-rc1'), [{ + semver: '1.0.0-rc1', + major: '1', + minor: '0', + patch: '0', + release: 'rc1' + }]); + }); + + it('should parse pre-release versions with hyphens', function() { + + deepOwnEqual(semverutils.parseRange('1.0.0-rc-2'), [{ + semver: '1.0.0-rc-2', + major: '1', + minor: '0', + patch: '0', + release: 'rc-2' + }]); + }); + it('should parse hyphen ranges', function() { deepOwnEqual(semverutils.parseRange('1.0.0 - 1.0.x'), [{ semver: '1.0.0',