diff --git a/controllers/registry/module.js b/controllers/registry/module.js index 58729b7c4..0c2f64f52 100644 --- a/controllers/registry/module.js +++ b/controllers/registry/module.js @@ -46,7 +46,7 @@ var downloadAsReadStream = require('../utils').downloadAsReadStream; * GET /:name */ exports.show = function* (next) { - var name = this.params.name; + var name = this.params.name || this.params[0]; var rs = yield [ Module.getLastModified(name), Module.listTags(name) @@ -234,12 +234,13 @@ exports.show = function* (next) { * GET /:name/:version * GET /:name/:tag */ -exports.get = function *(next) { - var name = this.params.name; - var tag = this.params.version; +exports.get = function* (next) { + var name = this.params.name || this.params[0]; + var tag = this.params.version || this.params[1]; var version = semver.valid(tag); var method = version ? 'get' : 'getByTag'; var queryLabel = version ? version : tag; + debug('%s %s with %j', method, name, this.params); var rs = yield [ Module[method](name, queryLabel), diff --git a/controllers/sync.js b/controllers/sync.js index 0f5485303..127fe5e40 100644 --- a/controllers/sync.js +++ b/controllers/sync.js @@ -1,5 +1,5 @@ /**! - * cnpmjs.org - controllers/download.js + * cnpmjs.org - controllers/sync.js * * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed @@ -14,14 +14,16 @@ * Module dependencies. */ +var debug = require('debug')('cnpmjs.org:controllers:sync'); var Log = require('../proxy/module_log'); var SyncModuleWorker = require('../proxy/sync_module_worker'); -exports.sync = function *() { +exports.sync = function* () { var username = this.user.name || 'anonymous'; - var name = this.params.name; + var name = this.params.name || this.params[0]; var publish = this.query.publish === 'true'; var noDep = this.query.nodeps === 'true'; + debug('sync %s with query: %j', name, this.query); if (publish && !this.user.isAdmin) { this.status = 403; this.body = { @@ -37,6 +39,7 @@ exports.sync = function *() { }; var result = yield SyncModuleWorker.sync(name, username, options); + debug('sync %s got %j', name, result); // friendly 404 reason info if (result.statusCode === 404) { @@ -59,8 +62,9 @@ exports.sync = function *() { }; }; -exports.getSyncLog = function *(next) { - var logId = this.params.id; +exports.getSyncLog = function* (next) { + // params: [$name, $id] on scope package + var logId = this.params.id || this.params[1]; var offset = Number(this.query.offset) || 0; var row = yield Log.get(logId); if (!row) { diff --git a/controllers/web/package.js b/controllers/web/package.js index 134da2c71..8fea39bc2 100644 --- a/controllers/web/package.js +++ b/controllers/web/package.js @@ -14,6 +14,7 @@ * Module dependencies. */ +var debug = require('debug')('cnpmjs.org:controllers:web:package'); var bytes = require('bytes'); var giturl = require('giturl'); var moment = require('moment'); @@ -32,10 +33,13 @@ var setDownloadURL = require('../../lib/common').setDownloadURL; var ModuleStar = require('../../proxy/module_star'); var packageService = require('../../services/package'); -exports.display = function *(next) { +exports.display = function* (next) { var params = this.params; - var name = params.name; - var tag = params.version; + // normal: {name: $name, version: $version} + // scope: [$name, $version] + var name = params.name || params[0]; + var tag = params.version || params[1]; + debug('display %s with %j', name, params); var getPackageMethod; var getPackageArgs; @@ -129,7 +133,8 @@ exports.display = function *(next) { exports.search = function *(next) { var params = this.params; - var word = params.word; + var word = params.word || params[0]; + debug('search %j', word); var result = yield Module.search(word); var match = null; @@ -192,8 +197,8 @@ exports.rangeSearch = function *(next) { }; }; -exports.displaySync = function *(next) { - var name = this.params.name || this.query.name; +exports.displaySync = function* (next) { + var name = this.params.name || this.params[0] || this.query.name; yield this.render('sync', { name: name, title: 'Sync - ' + name diff --git a/middleware/web_not_found.js b/middleware/web_not_found.js index 7b21f1347..dfc16c9fd 100644 --- a/middleware/web_not_found.js +++ b/middleware/web_not_found.js @@ -22,6 +22,9 @@ module.exports = function *notFound(next) { if (this.status && this.status !== 404) { return; } + if (this.body) { + return; + } var m = /^\/([\w\-\_\.]+)\/?$/.exec(this.url); debug('%s match %j', this.url, m); diff --git a/routes/registry.js b/routes/registry.js index 970bb0fef..c60f98e97 100644 --- a/routes/registry.js +++ b/routes/registry.js @@ -43,6 +43,11 @@ function routes(app) { app.get('/-/short', mod.listAllModuleNames); // module + // scope package: params: [$name] + app.get(/\/(@[\w\-\.]+\/[\w\-\.]+)$/, syncByInstall, mod.show); + // scope package: params: [$name, $version] + app.get(/\/(@[\w\-\.]+\/[\w\-\.]+)\/([\w\.\-]+)$/, syncByInstall, mod.get); + app.get('/:name', syncByInstall, mod.show); app.get('/:name/:version', syncByInstall, mod.get); // try to add module diff --git a/routes/web.js b/routes/web.js index ce76cdcde..0d2104554 100644 --- a/routes/web.js +++ b/routes/web.js @@ -23,15 +23,29 @@ var dist = require('../controllers/web/dist'); function routes(app) { app.get('/total', total.show); + + // scope package without version + app.get(/\/package\/(@[\w\-\.]+\/[\w\-\.]+)$/, pkg.display); + // scope package with version + app.get(/\/package\/(@[\w\-\.]+\/[\w\-\.]+)\/([\w\d\.]+)$/, pkg.display); app.get('/package/:name', pkg.display); app.get('/package/:name/:version', pkg.display); + + app.get(/\/browse\/keyword\/(@[\w\-\.]+\/[\w\-\.]+)$/, pkg.search); app.get('/browse/keyword/:word', pkg.search); app.get('/~:name', user.display); + app.get(/\/sync\/(@[\w\-\.]+\/[\w\-\.]+)$/, pkg.displaySync); app.get('/sync/:name', pkg.displaySync); + + app.put(/\/sync\/(@[\w\-\.]+\/[\w\-\.]+)$/, sync.sync); app.put('/sync/:name', sync.sync); + + // params: [$name, $id] + app.get(/\/sync\/(@[\w\-\.]+\/[\w\-\.]+)\/log\/(\d+)$/, sync.getSyncLog); app.get('/sync/:name/log/:id', sync.getSyncLog); + app.get('/sync', pkg.displaySync); app.get('/_list/search/search', pkg.rangeSearch); diff --git a/test/controllers/registry/module.test.js b/test/controllers/registry/module.test.js index fdd347b6b..5b40ecefb 100644 --- a/test/controllers/registry/module.test.js +++ b/test/controllers/registry/module.test.js @@ -262,9 +262,9 @@ describe('controllers/registry/module.test.js', function () { should.not.exist(err); var body = res.body; body.name.should.equal('mk2testmodule'); - body.version.should.equal('0.0.1'); - body._id.should.equal('mk2testmodule@0.0.1'); - body.dist.tarball.should.containEql('/mk2testmodule/download/mk2testmodule-0.0.1.tgz'); + body.version.should.equal('0.0.2'); + body._id.should.equal('mk2testmodule@0.0.2'); + body.dist.tarball.should.containEql('/mk2testmodule/download/mk2testmodule-0.0.2.tgz'); done(); }); }); diff --git a/test/controllers/registry/module/scope_package.test.js b/test/controllers/registry/module/scope_package.test.js new file mode 100644 index 000000000..250978e16 --- /dev/null +++ b/test/controllers/registry/module/scope_package.test.js @@ -0,0 +1,120 @@ +/**! + * cnpmjs.org - test/controllers/registry/module/scope_package.test.js + * + * Copyright(c) fengmk2 and other contributors. + * MIT Licensed + * + * Authors: + * fengmk2 (http://fengmk2.github.com) + */ + +'use strict'; + +/** + * Module dependencies. + */ + +var should = require('should'); +var request = require('supertest'); +var app = require('../../../../servers/registry'); +var utils = require('../../../utils'); + +describe('controllers/registry/module/scope_package.test.js', function () { + var pkgname = '@cnpm/test-scope-package'; + var pkgURL = '/@' + encodeURIComponent(pkgname.substring(1)); + before(function (done) { + // add scope package + var pkg = utils.getPackage(pkgname, '0.0.1', utils.admin); + + request(app.listen()) + .put(pkgURL) + .set('authorization', utils.adminAuth) + .send(pkg) + .expect(201, function (err) { + should.not.exist(err); + pkg = utils.getPackage(pkgname, '0.0.2', utils.admin); + // publish 0.0.2 + request(app.listen()) + .put(pkgURL) + .set('authorization', utils.adminAuth) + .send(pkg) + .expect(201, done); + }); + }); + + it('should get scope package info: /@scope%2Fname', function (done) { + request(app.listen()) + .get(pkgURL) + .expect(200, function (err, res) { + should.not.exist(err); + var pkg = res.body; + pkg.name.should.equal(pkgname); + pkg.versions.should.have.keys('0.0.1', '0.0.2'); + pkg['dist-tags'].latest.should.equal('0.0.2'); + pkg.versions['0.0.1'].name.should.equal(pkgname); + pkg.versions['0.0.1'].dist.tarball + .should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.1.tgz'); + done(); + }); + }); + + it('should get scope package info: /@scope/name', function (done) { + request(app.listen()) + .get('/' + pkgname) + .expect(200, function (err, res) { + should.not.exist(err); + var pkg = res.body; + pkg.name.should.equal(pkgname); + pkg.versions.should.have.keys('0.0.1', '0.0.2'); + pkg['dist-tags'].latest.should.equal('0.0.2'); + pkg.versions['0.0.1'].name.should.equal(pkgname); + pkg.versions['0.0.1'].dist.tarball + .should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.1.tgz'); + done(); + }); + }); + + it('should get scope package info: /%40scope%2Fname', function (done) { + request(app.listen()) + .get('/' + encodeURIComponent(pkgname)) + .expect(200, function (err, res) { + should.not.exist(err); + var pkg = res.body; + pkg.name.should.equal(pkgname); + pkg.versions.should.have.keys('0.0.1', '0.0.2'); + pkg['dist-tags'].latest.should.equal('0.0.2'); + pkg.versions['0.0.1'].name.should.equal(pkgname); + pkg.versions['0.0.1'].dist.tarball + .should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.1.tgz'); + done(); + }); + }); + + it('should get scope package with version', function (done) { + request(app.listen()) + .get('/' + pkgname + '/0.0.1') + .expect(200, function (err, res) { + should.not.exist(err); + var pkg = res.body; + pkg.name.should.equal(pkgname); + pkg.version.should.equal('0.0.1'); + pkg.dist.tarball + .should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.1.tgz'); + done(); + }); + }); + + it('should get scope package with tag', function (done) { + request(app.listen()) + .get('/' + pkgname + '/latest') + .expect(200, function (err, res) { + should.not.exist(err); + var pkg = res.body; + pkg.name.should.equal(pkgname); + pkg.version.should.equal('0.0.2'); + pkg.dist.tarball + .should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.2.tgz'); + done(); + }); + }); +}); diff --git a/test/controllers/sync.test.js b/test/controllers/sync.test.js index 8475ac0bf..39c778946 100644 --- a/test/controllers/sync.test.js +++ b/test/controllers/sync.test.js @@ -27,8 +27,8 @@ var webApp = require('../../servers/web'); describe('controllers/sync.test.js', function () { before(function (done) { done = pedding(2, done); - registryApp.listen(0, done); - webApp.listen(0, done); + registryApp = registryApp.listen(0, done); + webApp = webApp.listen(0, done); }); afterEach(mm.restore); @@ -116,4 +116,16 @@ describe('controllers/sync.test.js', function () { }); }); }); + + describe('scope package', function () { + it('should sync scope package not found', function (done) { + request(webApp) + .put('/sync/@cnpm/not-exists-package') + .expect({ + "ok":false, + "reason":"can not found @cnpm/not-exists-package in the source registry" + }) + .expect(404, done); + }); + }); }); diff --git a/test/controllers/web/package/scope_package.test.js b/test/controllers/web/package/scope_package.test.js new file mode 100644 index 000000000..928654fac --- /dev/null +++ b/test/controllers/web/package/scope_package.test.js @@ -0,0 +1,99 @@ +/**! + * cnpmjs.org - test/controllers/web/package/scope_package.test.js + * + * Copyright(c) fengmk2 and other contributors. + * MIT Licensed + * + * Authors: + * fengmk2 (http://fengmk2.github.com) + */ + +'use strict'; + +/** + * Module dependencies. + */ + +var should = require('should'); +var request = require('supertest'); +var registry = require('../../../../servers/registry'); +var web = require('../../../../servers/web'); +var utils = require('../../../utils'); + +describe('controllers/web/package/scope_package.test.js', function () { + var pkgname = '@cnpm/test-web-scope-package'; + var pkgURL = '/@' + encodeURIComponent(pkgname.substring(1)); + before(function (done) { + // add scope package + var pkg = utils.getPackage(pkgname, '0.0.1', utils.admin); + + request(registry.listen()) + .put(pkgURL) + .set('authorization', utils.adminAuth) + .send(pkg) + .expect(201, function (err) { + should.not.exist(err); + pkg = utils.getPackage(pkgname, '0.0.2', utils.admin); + // publish 0.0.2 + request(registry.listen()) + .put(pkgURL) + .set('authorization', utils.adminAuth) + .send(pkg) + .expect(201, done); + }); + }); + + it('should show scope package info page: /@scope%2Fname', function (done) { + request(web.listen()) + .get('/package' + pkgURL) + .expect(200, function (err, res) { + should.not.exist(err); + var body = res.text; + body.should.containEql('$ cnpm install @cnpm/test-web-scope-package'); + body.should.containEql('/@cnpm/test-web-scope-package/download/@cnpm/test-web-scope-package-0.0.2.tgz'); + done(); + }); + }); + + it('should show scope package info page: encodeURIComponent("/@scope/name")', function (done) { + request(web.listen()) + .get('/package/' + encodeURIComponent(pkgname)) + .expect(200, function (err, res) { + should.not.exist(err); + var body = res.text; + body.should.containEql('$ cnpm install @cnpm/test-web-scope-package'); + body.should.containEql('/@cnpm/test-web-scope-package/download/@cnpm/test-web-scope-package-0.0.2.tgz'); + done(); + }); + }); + + it('should show scope package info page: /@scope/name', function (done) { + request(web.listen()) + .get('/package/' + pkgname) + .expect(200, function (err, res) { + should.not.exist(err); + var body = res.text; + body.should.containEql('$ cnpm install @cnpm/test-web-scope-package'); + body.should.containEql('/@cnpm/test-web-scope-package/download/@cnpm/test-web-scope-package-0.0.2.tgz'); + done(); + }); + }); + + it('should /@scope/name/ 404', function (done) { + request(web.listen()) + .get('/package/' + pkgname + '/') + .expect(404, done); + }); + + it('should show scope package with version: /@scope/name/0.0.2', function (done) { + request(web.listen()) + .get('/package/' + pkgname + '/0.0.2') + .expect(200, function (err, res) { + should.not.exist(err); + var body = res.text; + body.should.containEql('$ cnpm install @cnpm/test-web-scope-package'); + body.should.containEql('/@cnpm/test-web-scope-package/download/@cnpm/test-web-scope-package-0.0.2.tgz'); + done(); + }); + }); +}); diff --git a/test/fixtures/scope-package/.gitignore b/test/fixtures/scope-package/.gitignore new file mode 100644 index 000000000..c0a64901c --- /dev/null +++ b/test/fixtures/scope-package/.gitignore @@ -0,0 +1,16 @@ +coverage.html +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +node_modules +npm-debug.log +coverage/ diff --git a/test/fixtures/scope-package/.jshintignore b/test/fixtures/scope-package/.jshintignore new file mode 100644 index 000000000..63c6333da --- /dev/null +++ b/test/fixtures/scope-package/.jshintignore @@ -0,0 +1,4 @@ +node_modules/ +coverage/ +.tmp/ +.git/ diff --git a/test/fixtures/scope-package/.jshintrc b/test/fixtures/scope-package/.jshintrc new file mode 100644 index 000000000..5988707d8 --- /dev/null +++ b/test/fixtures/scope-package/.jshintrc @@ -0,0 +1,95 @@ +{ + // JSHint Default Configuration File (as on JSHint website) + // See http://jshint.com/docs/ for more details + + "maxerr" : 50, // {int} Maximum error before stopping + + // Enforcing + "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.) + "camelcase" : false, // true: Identifiers must be in camelCase + "curly" : true, // true: Require {} for every new block or scope + "eqeqeq" : true, // true: Require triple equals (===) for comparison + "forin" : false, // true: Require filtering for..in loops with obj.hasOwnProperty() + "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` + "indent" : false, // {int} Number of spaces to use for indentation + "latedef" : false, // true: Require variables/functions to be defined before being used + "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()` + "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` + "noempty" : true, // true: Prohibit use of empty blocks + "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment) + "plusplus" : false, // true: Prohibit use of `++` & `--` + "quotmark" : false, // Quotation mark consistency: + // false : do nothing (default) + // true : ensure whatever is used is consistent + // "single" : require single quotes + // "double" : require double quotes + "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) + "unused" : false, // true: Require all defined variables be used + "strict" : true, // true: Requires all functions run in ES5 Strict Mode + "trailing" : false, // true: Prohibit trailing whitespaces + "maxparams" : false, // {int} Max number of formal params allowed per function + "maxdepth" : false, // {int} Max depth of nested blocks (within functions) + "maxstatements" : false, // {int} Max number statements per function + "maxcomplexity" : false, // {int} Max cyclomatic complexity per function + "maxlen" : false, // {int} Max number of characters per line + + // Relaxing + "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons) + "boss" : true, // true: Tolerate assignments where comparisons would be expected + "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. + "eqnull" : false, // true: Tolerate use of `== null` + "es5" : false, // true: Allow ES5 syntax (ex: getters and setters) + "esnext" : true, // true: Allow ES.next (ES6) syntax (ex: `const`) + "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) + // (ex: `for each`, multiple try/catch, function expression…) + "evil" : false, // true: Tolerate use of `eval` and `new Function()` + "expr" : true, // true: Tolerate `ExpressionStatement` as Programs + "funcscope" : false, // true: Tolerate defining variables inside control statements" + "globalstrict" : false, // true: Allow global "use strict" (also enables 'strict') + "iterator" : false, // true: Tolerate using the `__iterator__` property + "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block + "laxbreak" : true, // true: Tolerate possibly unsafe line breakings + "laxcomma" : false, // true: Tolerate comma-first style coding + "loopfunc" : false, // true: Tolerate functions being defined in loops + "multistr" : true, // true: Tolerate multi-line strings + "proto" : false, // true: Tolerate using the `__proto__` property + "scripturl" : false, // true: Tolerate script-targeted URLs + "smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment + "shadow" : true, // true: Allows re-define variables later in code e.g. `var x=1; x=2;` + "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation + "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;` + "validthis" : false, // true: Tolerate using this in a non-constructor function + + // Environments + "browser" : true, // Web Browser (window, document, etc) + "couch" : false, // CouchDB + "devel" : true, // Development/debugging (alert, confirm, etc) + "dojo" : false, // Dojo Toolkit + "jquery" : false, // jQuery + "mootools" : false, // MooTools + "node" : true, // Node.js + "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) + "prototypejs" : false, // Prototype and Scriptaculous + "rhino" : false, // Rhino + "worker" : false, // Web Workers + "wsh" : false, // Windows Scripting Host + "yui" : false, // Yahoo User Interface + "noyield" : true, // allow generators without a yield + + // Legacy + "nomen" : false, // true: Prohibit dangling `_` in variables + "onevar" : false, // true: Allow only one `var` statement per function + "passfail" : false, // true: Stop on first error + "white" : false, // true: Check against strict whitespace and indentation rules + + // Custom Globals + "globals" : { // additional predefined global variables + // mocha + "describe": true, + "it": true, + "before": true, + "afterEach": true, + "beforeEach": true, + "after": true + } +} diff --git a/test/fixtures/scope-package/.npmignore b/test/fixtures/scope-package/.npmignore new file mode 100644 index 000000000..3ea0ef28e --- /dev/null +++ b/test/fixtures/scope-package/.npmignore @@ -0,0 +1,8 @@ +test/ +Makefile +.travis.yml +logo.png +.jshintignore +.jshintrc +.gitingore +coverage/ diff --git a/test/fixtures/scope-package/.travis.yml b/test/fixtures/scope-package/.travis.yml new file mode 100644 index 000000000..0019b375a --- /dev/null +++ b/test/fixtures/scope-package/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - '0.11' + - '0.10' +script: "make test-travis" +after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" diff --git a/test/fixtures/scope-package/AUTHORS b/test/fixtures/scope-package/AUTHORS new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/scope-package/LICENSE.txt b/test/fixtures/scope-package/LICENSE.txt new file mode 100644 index 000000000..186a552c4 --- /dev/null +++ b/test/fixtures/scope-package/LICENSE.txt @@ -0,0 +1,21 @@ +This software is licensed under the MIT License. + +Copyright (c) 2014 fengmk2 and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/test/fixtures/scope-package/Makefile b/test/fixtures/scope-package/Makefile new file mode 100644 index 000000000..ca847edae --- /dev/null +++ b/test/fixtures/scope-package/Makefile @@ -0,0 +1,51 @@ +TESTS = test/*.test.js +REPORTER = spec +TIMEOUT = 1000 +MOCHA_OPTS = + +install: + @npm install --registry=https://registry.npm.taobao.org --disturl=https://npm.taobao.org/dist + +jshint: install + @./node_modules/.bin/jshint . + +test: install + @NODE_ENV=test ./node_modules/.bin/mocha \ + --harmony \ + --reporter $(REPORTER) \ + --timeout $(TIMEOUT) \ + $(MOCHA_OPTS) \ + $(TESTS) + +test-cov cov: install + @NODE_ENV=test node --harmony \ + node_modules/.bin/istanbul cover --preserve-comments \ + ./node_modules/.bin/_mocha \ + -- \ + --reporter $(REPORTER) \ + --timeout $(TIMEOUT) \ + $(MOCHA_OPTS) \ + $(TESTS) + @./node_modules/.bin/cov coverage + +test-travis: install + @NODE_ENV=test node --harmony \ + node_modules/.bin/istanbul cover --preserve-comments \ + ./node_modules/.bin/_mocha \ + --report lcovonly \ + -- \ + --reporter dot \ + --timeout $(TIMEOUT) \ + $(MOCHA_OPTS) \ + $(TESTS) + +test-all: install jshint test cov + +autod: install + @./node_modules/.bin/autod -w --prefix "~" + @$(MAKE) install + +contributors: install + @./node_modules/.bin/contributors -f plain -o AUTHORS + +.PHONY: test diff --git a/test/fixtures/scope-package/README.md b/test/fixtures/scope-package/README.md new file mode 100644 index 000000000..677b48472 --- /dev/null +++ b/test/fixtures/scope-package/README.md @@ -0,0 +1,64 @@ +scope-package +======= + +[![NPM version][npm-image]][npm-url] +[![build status][travis-image]][travis-url] +[![Test coverage][coveralls-image]][coveralls-url] +[![Gittip][gittip-image]][gittip-url] +[![David deps][david-image]][david-url] + +[npm-image]: https://img.shields.io/npm/v/scope-package.svg?style=flat +[npm-url]: https://npmjs.org/package/scope-package +[travis-image]: https://img.shields.io/travis/node-modules/scope-package.svg?style=flat +[travis-url]: https://travis-ci.org/node-modules/scope-package +[coveralls-image]: https://img.shields.io/coveralls/node-modules/scope-package.svg?style=flat +[coveralls-url]: https://coveralls.io/r/node-modules/scope-package?branch=master +[gittip-image]: https://img.shields.io/gittip/fengmk2.svg?style=flat +[gittip-url]: https://www.gittip.com/fengmk2/ +[david-image]: https://img.shields.io/david/node-modules/scope-package.svg?style=flat +[david-url]: https://david-dm.org/node-modules/scope-package + +![logo](https://raw.github.com/node-modules/scope-package/master/logo.png) + +scope-package desc + +## Install + +```bash +$ npm install scope-package +``` + +## Usage + +```js +var scope-package = require('scope-package'); + +scope-package.foo(function (err) { + +}); +``` + +## License + +(The MIT License) + +Copyright (c) 2014 fengmk2 <fengmk2@gmail.com> and other contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/test/fixtures/scope-package/index.js b/test/fixtures/scope-package/index.js new file mode 100644 index 000000000..107ed5731 --- /dev/null +++ b/test/fixtures/scope-package/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/scope-package'); \ No newline at end of file diff --git a/test/fixtures/scope-package/lib/scope-package.js b/test/fixtures/scope-package/lib/scope-package.js new file mode 100644 index 000000000..79c1af739 --- /dev/null +++ b/test/fixtures/scope-package/lib/scope-package.js @@ -0,0 +1,17 @@ +/**! + * scope-package - lib/scope-package.js + * + * Copyright(c) 2014 fengmk2 and other contributors. + * MIT Licensed + * + * Authors: + * fengmk2 (http://fengmk2.github.com) + */ + +"use strict"; + +/** + * Module dependencies. + */ + +var varname = require('modulename'); diff --git a/test/fixtures/scope-package/package.json b/test/fixtures/scope-package/package.json new file mode 100644 index 000000000..1375029b5 --- /dev/null +++ b/test/fixtures/scope-package/package.json @@ -0,0 +1,44 @@ +{ + "name": "@cnpm/scope-package", + "version": "0.0.1", + "description": "scope-package", + "main": "index.js", + "scripts": { + "test": "make test-all" + }, + "config": { + "cov": { + "threshold": 100 + } + }, + "dependencies": { + + }, + "devDependencies": { + "autod": "*", + "contributors": "*", + "should": "*", + "jshint": "*", + "cov": "*", + "istanbul-harmony": "*", + "mocha": "*" + }, + "homepage": "https://github.com/node-modules/scope-package", + "repository": { + "type": "git", + "url": "git://github.com/node-modules/scope-package.git", + "web": "https://github.com/node-modules/scope-package" + }, + "bugs": { + "url": "https://github.com/node-modules/scope-package/issues", + "email": "fengmk2@gmail.com" + }, + "keywords": [ + "scope-package" + ], + "engines": { + "node": ">= 0.10.0" + }, + "author": "fengmk2 (http://fengmk2.github.com)", + "license": "MIT" +} diff --git a/test/utils.js b/test/utils.js index 3c534862c..6b3cf4a51 100644 --- a/test/utils.js +++ b/test/utils.js @@ -40,6 +40,9 @@ exports.getPackage = function (name, version, user) { pkg.maintainers[0].name = user; pkg.versions[version].maintainers[0].name = user; pkg.versions[version].name = name; + pkg.versions[version].version = version; + pkg.versions[version]._id = name + '@' + version; pkg.name = name; + pkg['dist-tags'] = {latest: version}; return pkg; };