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