From 6049c46f15e0f9b8cf7bae25477e8f2c1766c111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Fri, 12 May 2017 19:18:11 -0400 Subject: [PATCH] meta dependecy tests --- src/meta/dependencies.js | 82 +++++++++++++++++++++++----------------- test/meta.js | 50 ++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 34 deletions(-) diff --git a/src/meta/dependencies.js b/src/meta/dependencies.js index 034061f636..3a16f0e9e5 100644 --- a/src/meta/dependencies.js +++ b/src/meta/dependencies.js @@ -11,46 +11,15 @@ var pkg = require('../../package.json'); module.exports = function (Meta) { Meta.dependencies = {}; + var depsMissing = false; + var depsOutdated = false; Meta.dependencies.check = function (callback) { var modules = Object.keys(pkg.dependencies); - var depsOutdated = false; - var depsMissing = false; winston.verbose('Checking dependencies for outdated modules'); - async.each(modules, function (module, next) { - fs.readFile(path.join(__dirname, '../../node_modules/', module, 'package.json'), { - encoding: 'utf-8', - }, function (err, pkgData) { - if (err) { - // If a bundled plugin/theme is not present, skip the dep check (#3384) - if (err.code === 'ENOENT' && (module === 'nodebb-rewards-essentials' || module.startsWith('nodebb-plugin') || module.startsWith('nodebb-theme'))) { - winston.warn('[meta/dependencies] Bundled plugin ' + module + ' not found, skipping dependency check.'); - return next(); - } - return next(err); - } - - try { - pkgData = JSON.parse(pkgData); - } catch (e) { - process.stdout.write('[' + 'missing'.red + '] ' + module.bold + ' is a required dependency but could not be found\n'); - depsMissing = true; - return next(); - } - - var ok = !semver.validRange(pkg.dependencies[module]) || semver.satisfies(pkgData.version, pkg.dependencies[module]); - - if (ok || (pkgData._resolved && pkgData._resolved.indexOf('//github.com') !== -1)) { - next(); - } else { - process.stdout.write('[' + 'outdated'.yellow + '] ' + module.bold + ' installed v' + pkgData.version + ', package.json requires ' + pkg.dependencies[module] + '\n'); - depsOutdated = true; - next(); - } - }); - }, function (err) { + async.each(modules, Meta.dependencies.checkModule, function (err) { if (err) { return callback(err); } @@ -64,4 +33,49 @@ module.exports = function (Meta) { } }); }; + + Meta.dependencies.checkModule = function (moduleName, callback) { + fs.readFile(path.join(__dirname, '../../node_modules/', moduleName, 'package.json'), { + encoding: 'utf-8', + }, function (err, pkgData) { + if (err) { + // If a bundled plugin/theme is not present, skip the dep check (#3384) + if (err.code === 'ENOENT' && (moduleName === 'nodebb-rewards-essentials' || moduleName.startsWith('nodebb-plugin') || moduleName.startsWith('nodebb-theme'))) { + winston.warn('[meta/dependencies] Bundled plugin ' + moduleName + ' not found, skipping dependency check.'); + return callback(null, true); + } + return callback(err); + } + + pkgData = Meta.dependencies.parseModuleData(moduleName, pkgData); + + var satisfies = Meta.dependencies.doesSatisfy(pkgData, pkg.dependencies[moduleName]); + callback(null, satisfies); + }); + }; + + Meta.dependencies.parseModuleData = function (moduleName, pkgData) { + try { + pkgData = JSON.parse(pkgData); + } catch (e) { + winston.warn('[' + 'missing'.red + '] ' + moduleName.bold + ' is a required dependency but could not be found\n'); + depsMissing = true; + return null; + } + return pkgData; + }; + + Meta.dependencies.doesSatisfy = function (moduleData, packageJSONVersion) { + if (!moduleData) { + return false; + } + var versionOk = !semver.validRange(packageJSONVersion) || semver.satisfies(moduleData.version, packageJSONVersion); + var githubRepo = moduleData._resolved && moduleData._resolved.indexOf('//github.com') !== -1; + var satisfies = versionOk || githubRepo; + if (!satisfies) { + winston.warn('[' + 'outdated'.yellow + '] ' + moduleData.name.bold + ' installed v' + moduleData.version + ', package.json requires ' + packageJSONVersion + '\n'); + depsOutdated = true; + } + return satisfies; + }; }; diff --git a/test/meta.js b/test/meta.js index 9c2f6d89b3..8b32e90070 100644 --- a/test/meta.js +++ b/test/meta.js @@ -211,6 +211,56 @@ describe('meta', function () { }); }); + describe('dependencies', function () { + it('should return ENOENT if module is not found', function (done) { + meta.dependencies.checkModule('some-module-that-does-not-exist', function (err) { + assert.equal(err.code, 'ENOENT'); + done(); + }); + }); + + it('should not error if module is a nodebb-plugin-*', function (done) { + meta.dependencies.checkModule('nodebb-plugin-somePlugin', function (err) { + assert.ifError(err); + done(); + }); + }); + + it('should not error if module is nodebb-theme-*', function (done) { + meta.dependencies.checkModule('nodebb-theme-someTheme', function (err) { + assert.ifError(err); + done(); + }); + }); + + it('should parse json package data', function (done) { + var pkgData = meta.dependencies.parseModuleData('nodebb-plugin-test', '{"a": 1}'); + assert.equal(pkgData.a, 1); + done(); + }); + + it('should return null data with invalid json', function (done) { + var pkgData = meta.dependencies.parseModuleData('nodebb-plugin-test', 'asdasd'); + assert.strictEqual(pkgData, null); + done(); + }); + + it('should return false if moduleData is falsy', function (done) { + assert(!meta.dependencies.doesSatisfy(null, '1.0.0')); + done(); + }); + + it('should return false if moduleData doesnt not satisfy package.json', function (done) { + assert(!meta.dependencies.doesSatisfy({ name: 'nodebb-plugin-test', version: '0.9.0' }, '1.0.0')); + done(); + }); + + it('should return true if _resolved is from github', function (done) { + assert(meta.dependencies.doesSatisfy({ name: 'nodebb-plugin-test', _resolved: 'https://github.com/some/repo', version: '0.9.0' }, '1.0.0')); + done(); + }); + }); + after(function (done) { db.emptydb(done);