From d9d4471678982111a5e56ef500ebeda0e287efb3 Mon Sep 17 00:00:00 2001 From: Fede Ramirez Date: Mon, 23 Mar 2015 05:15:10 -0300 Subject: [PATCH 1/5] refactoring the testing process --- test/index.js | 164 ++++++++++++++++++++++------ test/lib/JsonFile.js | 15 ++- test/lib/OverrideFile.js | 88 --------------- test/lib/RegistryEntryCollection.js | 53 +++++++++ test/lib/RegistryFile.js | 33 +++++- 5 files changed, 219 insertions(+), 134 deletions(-) delete mode 100644 test/lib/OverrideFile.js create mode 100644 test/lib/RegistryEntryCollection.js diff --git a/test/index.js b/test/index.js index 288aa6f..b058d0c 100644 --- a/test/index.js +++ b/test/index.js @@ -1,69 +1,161 @@ -"use strict"; +'use strict'; + +var util = require('util'); +var mout = require('mout'); +var colors = require('colors/safe'); +var registries = { + github: require('jspm-github'), + npm: require('jspm-npm') +}; + +var forOwn = mout.object.forOwn; +var gray = colors.gray; var log = require('./lib/log'); +var JsonFile = require('./lib/JsonFile'); var RegistryFile = require('./lib/RegistryFile'); -var OverrideFile = require('./lib/OverrideFile'); -var summary = []; +var RegistryEntryCollection = require('./lib/RegistryEntryCollection'); -/** - * Commander - */ + +// +// COMMANDER CONFIGURATION +// var program = require('commander'); program .version('0.0.1') .usage('[options] ') - .option('-e, --only-errors', 'Show only summary', 0) + .option('-e, --only-errors', 'Show only errors', 0) .parse(process.argv); + +// +// LOG HELPERS +// + +/** + * @function error - log errors messages + * @param {String|Array} msg + * @return {Function} error + */ +var error = function(msg){ + + log.error(msg); + + if(Array.isArray(msg)) { + error.summary.concat(msg); + + } else { + error.summary.push(msg); + + } + + return error; +}; + +/** + * @type {Array} list all errors + */ +error.summary = []; + +/** + * function ok - log validation passed messages + * @param {String|Array} msg + * @return {Function} ok + */ +var ok = function(msg){ + + if(!program.onlyErrors) + log.ok(msg); + + return ok; +}; + +// +// VALIDATION PROCESS +// + /** * registry.json */ -var registry = RegistryFile(); -if(registry.errors().length) -{ - summary = summary.concat(registry.errors()); - log.error(registry.errors()); - process.exit(1); -} +var registryFile = new RegistryFile(); -// log ok -if(!program.onlyErrors) - log.ok('registry.json'); +if(registryFile.errors().length) { + // json format errors + error(registryFile.errors()); + +} else { + ok('registry.json is valid json'); + + registryFile.forEachPackage(function(pkg, name){ + + // validate specific packages + if(program.args.length) { + + var pos = program.args.indexOf(name); + + if(pos === -1) + return; + + // replace for test the package-override + program.args[pos] = pkg.value; + } + + if(!pkg.endpoint || !pkg.name) + return error( util.format('%s not respects the format {ENDPOINT}:{PACKAGE_NAME}', gray(pkg.value)) ); + + if(!registries[pkg.endpoint]) + return error( util.format('%s is not valid registry', gray(pkg.endpoint)) ); + + if(!registries[pkg.endpoint].packageFormat.test( pkg.name )) + return error( util.format('%s is not valid package name from %s endpoint', gray(pkg.name), gray(pkg.endpoint)) ); + + ok( util.format('%s => %s', name, pkg.value) ); + }); + +} /** - * Packages + * package overrides files */ -registry.forEach(function(endpoint, name){ +forOwn(registries, function(endpointPackage, registryName){ - if(program.args.length && program.args.indexOf(name) === -1) - return; + var registryEntryCollection = new RegistryEntryCollection(registryName); - var override = new OverrideFile(endpoint); + registryEntryCollection.forEachFile(function(fileinfo){ - if(override.errors().length) { + if(fileinfo.ext !== 'json') + return error( util.format('%s is not json file', gray(fileinfo.path)) ); + + if(!fileinfo.packageName || !fileinfo.packageVersion) + return error( util.format('%s not respects the file name format {PACKAGE_NAME}@{PACKAGE_VERSION}.json', gray(fileinfo.path)) ); - var errorDescription = name + ' => ' + endpoint + '\n\t' + override.errors().join('\n\t'); - summary.push(errorDescription); + if(!endpointPackage.packageFormat.test( fileinfo.packageName )) + return error( util.format('%s is not valid package name from %s endpoint', gray(fileinfo.packageName), gray(fileinfo.endpoint)) ); - } else if(!program.onlyErrors) { - log.ok(name + ' => ' + endpoint); + // validate specific packages + if(program.args.length && program.args.indexOf(fileinfo.packageValue) === -1 ) + return; - if(!override.isFile()) - log.info(' not override file from ' + name); - } + var jsonFile = new JsonFile(fileinfo.path); + if(jsonFile.errors().length) + return error( util.format('%s is not valid json file \n - %s', gray(fileinfo.path), jsonFile.errors().join('\n -')) ); + + ok( fileinfo.packageValue + '@' + fileinfo.packageVersion ); + }); }); -/** - * Summary - */ -if(summary.length) { +// +// SUMMARY LOG +// + +if(error.summary.length) { log.n() ('Error summary ................') - .error(summary) + .error(error.summary) .n(); process.exit(1); @@ -71,7 +163,7 @@ if(summary.length) { } log.n() - ('Summary ................') + ('errorSummary ................') .ok('excellent!! all is well.') .n(); diff --git a/test/lib/JsonFile.js b/test/lib/JsonFile.js index 708f565..694e58e 100644 --- a/test/lib/JsonFile.js +++ b/test/lib/JsonFile.js @@ -1,5 +1,5 @@ -"use strict;" -var fs = require('fs'); +'use strict'; + var mout = require('mout'); var extend = mout.object.deepMixIn; var forOwn = mout.object.forOwn; @@ -14,19 +14,18 @@ var JsonFile = module.exports = function JsonFile(file){ return new JsonFile(file); this._file = String(file); - this._errors = this._errors || []; - this._json = this._json || {}; + this._errors = []; + this._json = {}; if( !(/\.json$/.test(file)) ){ this.error(this._file + ' is not json file'); } else { - try{ + try { extend(this._json, require(this._file)); } catch(e) { - this.error(e.message); } @@ -38,12 +37,12 @@ JsonFile.prototype.error = function(msg){ this._errors.push(msg); return this; -} +}; JsonFile.prototype.errors = function(){ return this._errors; -} +}; JsonFile.prototype.forEach = function(fn){ diff --git a/test/lib/OverrideFile.js b/test/lib/OverrideFile.js deleted file mode 100644 index 16de9fc..0000000 --- a/test/lib/OverrideFile.js +++ /dev/null @@ -1,88 +0,0 @@ -"use strict;" - -var fs = require('fs'); -var util = require('util'); -var path = require('path'); -var glob = require('glob'); -var mout = require('mout'); -var colors = require('colors/safe'); -var JsonFile = require('./JsonFile'); - -var registries = { - github: require('jspm-github'), - npm: require('jspm-npm') -}; - -/** - * @constructor OverrideFile - */ -var OverrideFile = module.exports = function OverrideFile(endpoint){ - - if( !(this instanceof OverrideFile) ) - return new OverrideFile(endpoint); - - this._endpoint = endpoint; - this._files = []; - this._errors = this._errors || []; - this._registry; - this._package; - - var match = /^([^:\s]*):([^\s]*)$/.exec(endpoint); - - if(!match) - { - this.error('invalid enpoint package'); - } - else - { - this._registry = match[1]; - this._package = match[2]; - - if(!registries[this._registry]) - { - this.error('invalid registry'); - } - else if(!registries[this._registry].packageFormat.test(this._package)) - { - this.error('invalid pacakge name'); - } - - this._glob = path.resolve('./package-overrides', this._registry) + '/' + this._package + '@*.json'; - - - this._files = glob.sync(this._glob); - this.forEach(function(file){ - - var err = JsonFile(file).errors(); - - if(err.length > 0) - this.error(JsonFile(file).errors().join('\n')); - - }); - } - -}; - -util.inherits(OverrideFile, JsonFile); - -OverrideFile.prototype.error = function(msg){ - - var result = ''; - result += this._endpoint ? colors.gray(this._endpoint) + ' ' : ''; - result += msg; - - return JsonFile.prototype.error.call(this, result); -}; - -OverrideFile.prototype.forEach = function(fn){ - - mout.array.forEach(this._files, fn, this); - - return this; -}; - -OverrideFile.prototype.isFile = function(){ - - return this._files.length > 0; -}; - diff --git a/test/lib/RegistryEntryCollection.js b/test/lib/RegistryEntryCollection.js new file mode 100644 index 0000000..51f1bd3 --- /dev/null +++ b/test/lib/RegistryEntryCollection.js @@ -0,0 +1,53 @@ +'use strict'; + +var path = require('path'); +var glob = require('glob'); +var mout = require('mout'); +var forOwn = mout.object.forOwn; +var FILE_EXTENSION = /[^.]*$/i; +var PACKAGE_EXPECTATION = /(.*)@(.*).json$/; + +/** + * @constructor RegistryEntry + */ + +var RegistryEntryCollection = module.exports = function RegistryEntry(endpoint){ + + this._endpoint = endpoint; + this._basePath = path.resolve('./package-overrides', this._endpoint); + this._files = glob.sync('**/*', {cwd: this._basePath, nodir: true}); + +}; + +RegistryEntryCollection.prototype.forEachFile = function(fn){ + + forOwn(this._files, function(file, index){ + + var pathfile = path.resolve(this._basePath, file); + var extfile = FILE_EXTENSION.exec(pathfile)[0]; + + var fileinfo = { + packageName: undefined, + packageVersion: undefined, + packageValue: undefined, + + file: file, + endpoint: this._endpoint, + path: pathfile, + ext: extfile + }; + + var match = PACKAGE_EXPECTATION.exec(file); + + if (match) { + fileinfo.packageName = match[1]; + fileinfo.packageVersion = match[2]; + fileinfo.packageValue = fileinfo.endpoint + ':' + fileinfo.packageName; + } + + fn.call(this, fileinfo, index); + + }, this); + + return this; +} diff --git a/test/lib/RegistryFile.js b/test/lib/RegistryFile.js index ad26846..9ae1378 100644 --- a/test/lib/RegistryFile.js +++ b/test/lib/RegistryFile.js @@ -1,7 +1,9 @@ -"use strict;" +'use strict'; + var util = require('util'); var path = require('path'); var JsonFile = require('./JsonFile'); +var PACKAGE_EXPECTATION = /^([^:\s]*):([^\s]*)$/; /** * @constructor RegistryFile @@ -15,5 +17,32 @@ var RegistryFile = module.exports = function RegistryFile(){ JsonFile.call(this, path.resolve('./registry.json')); }; +util.inherits(RegistryFile, JsonFile); -util.inherits(RegistryFile, JsonFile); \ No newline at end of file +RegistryFile.prototype.forEachPackage = function(fn){ + + return this.forEach(function(redirection, name){ + + var pkg = {}; + var match = PACKAGE_EXPECTATION.exec(redirection); + + if (!match) { + pkg = { + value: redirection, + endpoint: undefined, + name: undefined, + }; + + } else { + pkg = { + value: match[0], + endpoint: match[1], + name: match[2], + }; + + } + + fn.call(this, pkg, name); + + }); +}; \ No newline at end of file From 6b0ae259b39f5b261f8db572e1a06873dffc6c59 Mon Sep 17 00:00:00 2001 From: Fede Ramirez Date: Mon, 23 Mar 2015 05:26:04 -0300 Subject: [PATCH 2/5] fix log only errors --- test/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/index.js b/test/index.js index b058d0c..d19bd78 100644 --- a/test/index.js +++ b/test/index.js @@ -40,7 +40,8 @@ program */ var error = function(msg){ - log.error(msg); + if(!program.onlyErrors) + log.error(msg); if(Array.isArray(msg)) { error.summary.concat(msg); From b5333e44fcada42f941ea2f4491f1e7b8b6f3132 Mon Sep 17 00:00:00 2001 From: Fede Ramirez Date: Mon, 23 Mar 2015 06:38:44 -0300 Subject: [PATCH 3/5] fix ok message --- test/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/index.js b/test/index.js index d19bd78..dc596a6 100644 --- a/test/index.js +++ b/test/index.js @@ -164,7 +164,7 @@ if(error.summary.length) { } log.n() - ('errorSummary ................') + ('Summary ................') .ok('excellent!! all is well.') .n(); From 9ccd7e11eb41975dcf831b7bc798c5215ec45b51 Mon Sep 17 00:00:00 2001 From: Fede Ramirez Date: Mon, 23 Mar 2015 18:35:35 -0300 Subject: [PATCH 4/5] normalize terminology --- test/GLOSSARY.md | 7 ++++ test/index.js | 42 +++++++++---------- test/lib/JsonFile.js | 2 +- ...tryEntryCollection.js => OverridesList.js} | 10 ++--- test/lib/RegistryFile.js | 20 ++++----- 5 files changed, 42 insertions(+), 39 deletions(-) create mode 100644 test/GLOSSARY.md rename test/lib/{RegistryEntryCollection.js => OverridesList.js} (76%) diff --git a/test/GLOSSARY.md b/test/GLOSSARY.md new file mode 100644 index 0000000..623a0fd --- /dev/null +++ b/test/GLOSSARY.md @@ -0,0 +1,7 @@ +# GLOSSARY + +- `canonical package name`: is the combination of a `package name` with an `endpoint` (example: `github:components/jquery`). +- `endpoint`: is platform where packets are hosted (`npm` or `github`). +- `override` or `override file`: is a `package.json` override file. +- `package name`: is the name of a package at some endpoint (example: `components/jquery` from `github` endpoint or `d3` from `npm` endpoint). +- `registry entry`: is just the mapping represented in the `registry.json` (example: `"jquery": "github:components/jquery"`). \ No newline at end of file diff --git a/test/index.js b/test/index.js index dc596a6..ea0c813 100644 --- a/test/index.js +++ b/test/index.js @@ -3,7 +3,7 @@ var util = require('util'); var mout = require('mout'); var colors = require('colors/safe'); -var registries = { +var endpoints = { github: require('jspm-github'), npm: require('jspm-npm') }; @@ -14,8 +14,7 @@ var gray = colors.gray; var log = require('./lib/log'); var JsonFile = require('./lib/JsonFile'); var RegistryFile = require('./lib/RegistryFile'); -var RegistryEntryCollection = require('./lib/RegistryEntryCollection'); - +var OverridesList = require('./lib/OverridesList'); // // COMMANDER CONFIGURATION @@ -88,43 +87,42 @@ if(registryFile.errors().length) { } else { ok('registry.json is valid json'); - registryFile.forEachPackage(function(pkg, name){ + registryFile.forEachRegistryEntry(function(pkg, registryEntryName){ // validate specific packages if(program.args.length) { - var pos = program.args.indexOf(name); + var pos = program.args.indexOf(registryEntryName); - if(pos === -1) + if(pos === -1) return; // replace for test the package-override - program.args[pos] = pkg.value; + program.args[pos] = pkg.canonical; } if(!pkg.endpoint || !pkg.name) - return error( util.format('%s not respects the format {ENDPOINT}:{PACKAGE_NAME}', gray(pkg.value)) ); + return error( util.format('%s not respects the format {ENDPOINT}:{PACKAGE_NAME}', gray(pkg.canonical)) ); - if(!registries[pkg.endpoint]) - return error( util.format('%s is not valid registry', gray(pkg.endpoint)) ); + if(!endpoints[pkg.endpoint]) + return error( util.format('%s is not valid enpoint', gray(pkg.endpoint)) ); - if(!registries[pkg.endpoint].packageFormat.test( pkg.name )) + if(!endpoints[pkg.endpoint].packageFormat.test( pkg.name )) return error( util.format('%s is not valid package name from %s endpoint', gray(pkg.name), gray(pkg.endpoint)) ); - ok( util.format('%s => %s', name, pkg.value) ); + ok( util.format('%s => %s', registryEntryName, pkg.canonical) ); }); } - /** * package overrides files */ -forOwn(registries, function(endpointPackage, registryName){ +forOwn(endpoints, function(Endpoint, endpointName){ - var registryEntryCollection = new RegistryEntryCollection(registryName); + var overridesList = new OverridesList(endpointName); - registryEntryCollection.forEachFile(function(fileinfo){ + overridesList.forEachOverrideFile(function(fileinfo){ if(fileinfo.ext !== 'json') return error( util.format('%s is not json file', gray(fileinfo.path)) ); @@ -132,18 +130,18 @@ forOwn(registries, function(endpointPackage, registryName){ if(!fileinfo.packageName || !fileinfo.packageVersion) return error( util.format('%s not respects the file name format {PACKAGE_NAME}@{PACKAGE_VERSION}.json', gray(fileinfo.path)) ); - if(!endpointPackage.packageFormat.test( fileinfo.packageName )) + if(!Endpoint.packageFormat.test( fileinfo.packageName )) return error( util.format('%s is not valid package name from %s endpoint', gray(fileinfo.packageName), gray(fileinfo.endpoint)) ); // validate specific packages - if(program.args.length && program.args.indexOf(fileinfo.packageValue) === -1 ) + if(program.args.length && program.args.indexOf(fileinfo.canonicalPackageName) === -1 ) return; - var jsonFile = new JsonFile(fileinfo.path); - if(jsonFile.errors().length) - return error( util.format('%s is not valid json file \n - %s', gray(fileinfo.path), jsonFile.errors().join('\n -')) ); + var overrideFile = new JsonFile(fileinfo.path); + if(overrideFile.errors().length) + return error( util.format('%s is not valid json file \n - %s', gray(fileinfo.path), overrideFile.errors().join('\n -')) ); - ok( fileinfo.packageValue + '@' + fileinfo.packageVersion ); + ok( fileinfo.canonicalPackageName + '@' + fileinfo.packageVersion ); }); }); diff --git a/test/lib/JsonFile.js b/test/lib/JsonFile.js index 694e58e..165d563 100644 --- a/test/lib/JsonFile.js +++ b/test/lib/JsonFile.js @@ -48,7 +48,7 @@ JsonFile.prototype.forEach = function(fn){ forOwn(this._json, fn, this); - return this; + return this; }; diff --git a/test/lib/RegistryEntryCollection.js b/test/lib/OverridesList.js similarity index 76% rename from test/lib/RegistryEntryCollection.js rename to test/lib/OverridesList.js index 51f1bd3..2bea171 100644 --- a/test/lib/RegistryEntryCollection.js +++ b/test/lib/OverridesList.js @@ -8,10 +8,10 @@ var FILE_EXTENSION = /[^.]*$/i; var PACKAGE_EXPECTATION = /(.*)@(.*).json$/; /** - * @constructor RegistryEntry + * @constructor OverridesList */ -var RegistryEntryCollection = module.exports = function RegistryEntry(endpoint){ +var OverridesList = module.exports = function OverridesList(endpoint){ this._endpoint = endpoint; this._basePath = path.resolve('./package-overrides', this._endpoint); @@ -19,7 +19,7 @@ var RegistryEntryCollection = module.exports = function RegistryEntry(endpoint){ }; -RegistryEntryCollection.prototype.forEachFile = function(fn){ +OverridesList.prototype.forEachOverrideFile = function(fn){ forOwn(this._files, function(file, index){ @@ -29,7 +29,7 @@ RegistryEntryCollection.prototype.forEachFile = function(fn){ var fileinfo = { packageName: undefined, packageVersion: undefined, - packageValue: undefined, + canonicalPackageName: undefined, file: file, endpoint: this._endpoint, @@ -42,7 +42,7 @@ RegistryEntryCollection.prototype.forEachFile = function(fn){ if (match) { fileinfo.packageName = match[1]; fileinfo.packageVersion = match[2]; - fileinfo.packageValue = fileinfo.endpoint + ':' + fileinfo.packageName; + fileinfo.canonicalPackageName = fileinfo.endpoint + ':' + fileinfo.packageName; } fn.call(this, fileinfo, index); diff --git a/test/lib/RegistryFile.js b/test/lib/RegistryFile.js index 9ae1378..ae66944 100644 --- a/test/lib/RegistryFile.js +++ b/test/lib/RegistryFile.js @@ -3,12 +3,11 @@ var util = require('util'); var path = require('path'); var JsonFile = require('./JsonFile'); -var PACKAGE_EXPECTATION = /^([^:\s]*):([^\s]*)$/; +var CANONICAL_NAME_EXPECTATION = /^([^:\s]*):([^\s]*)$/; /** * @constructor RegistryFile - */ - + */ var RegistryFile = module.exports = function RegistryFile(){ if( !(this instanceof RegistryFile) ) @@ -19,30 +18,29 @@ var RegistryFile = module.exports = function RegistryFile(){ util.inherits(RegistryFile, JsonFile); -RegistryFile.prototype.forEachPackage = function(fn){ +RegistryFile.prototype.forEachRegistryEntry = function(fn){ - return this.forEach(function(redirection, name){ + return this.forEach(function(canonicalPackageName, registryEntryName){ var pkg = {}; - var match = PACKAGE_EXPECTATION.exec(redirection); + var match = CANONICAL_NAME_EXPECTATION.exec(canonicalPackageName); if (!match) { pkg = { - value: redirection, + canonical: canonicalPackageName, endpoint: undefined, name: undefined, }; } else { pkg = { - value: match[0], + canonical: match[0], endpoint: match[1], name: match[2], }; - } - fn.call(this, pkg, name); - + fn.call(this, pkg, registryEntryName); }); + }; \ No newline at end of file From b8b76485795a526cb20e2021d27a423ac140de8b Mon Sep 17 00:00:00 2001 From: Fede Ramirez Date: Tue, 24 Mar 2015 21:47:19 -0300 Subject: [PATCH 5/5] RegistryFile to OverrideFile --- test/index.js | 10 +++++----- test/lib/{RegistryFile.js => OverrideFile.js} | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) rename test/lib/{RegistryFile.js => OverrideFile.js} (72%) diff --git a/test/index.js b/test/index.js index ea0c813..ec06fd2 100644 --- a/test/index.js +++ b/test/index.js @@ -13,7 +13,7 @@ var gray = colors.gray; var log = require('./lib/log'); var JsonFile = require('./lib/JsonFile'); -var RegistryFile = require('./lib/RegistryFile'); +var OverrideFile = require('./lib/OverrideFile'); var OverridesList = require('./lib/OverridesList'); // @@ -78,16 +78,16 @@ var ok = function(msg){ /** * registry.json */ -var registryFile = new RegistryFile(); +var overrideFile = new OverrideFile(); -if(registryFile.errors().length) { +if(overrideFile.errors().length) { // json format errors - error(registryFile.errors()); + error(overrideFile.errors()); } else { ok('registry.json is valid json'); - registryFile.forEachRegistryEntry(function(pkg, registryEntryName){ + overrideFile.forEachRegistryEntry(function(pkg, registryEntryName){ // validate specific packages if(program.args.length) { diff --git a/test/lib/RegistryFile.js b/test/lib/OverrideFile.js similarity index 72% rename from test/lib/RegistryFile.js rename to test/lib/OverrideFile.js index ae66944..adf8215 100644 --- a/test/lib/RegistryFile.js +++ b/test/lib/OverrideFile.js @@ -6,19 +6,19 @@ var JsonFile = require('./JsonFile'); var CANONICAL_NAME_EXPECTATION = /^([^:\s]*):([^\s]*)$/; /** - * @constructor RegistryFile + * @constructor OverrideFile */ -var RegistryFile = module.exports = function RegistryFile(){ +var OverrideFile = module.exports = function OverrideFile(){ - if( !(this instanceof RegistryFile) ) - return new RegistryFile(); + if( !(this instanceof OverrideFile) ) + return new OverrideFile(); JsonFile.call(this, path.resolve('./registry.json')); }; -util.inherits(RegistryFile, JsonFile); +util.inherits(OverrideFile, JsonFile); -RegistryFile.prototype.forEachRegistryEntry = function(fn){ +OverrideFile.prototype.forEachRegistryEntry = function(fn){ return this.forEach(function(canonicalPackageName, registryEntryName){