From a62ef744bcfe9437cc9c95bc28d078a2e5307642 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Thu, 27 Nov 2014 12:14:08 -0400 Subject: [PATCH] Implement pluginLoader.loadPackage --- lib/plugin-loader/plugin-loader.coffee | 48 +++++++++++++ lib/plugin-loader/plugin-loader.spec.coffee | 74 +++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/lib/plugin-loader/plugin-loader.coffee b/lib/plugin-loader/plugin-loader.coffee index 74ba6825..97d40139 100644 --- a/lib/plugin-loader/plugin-loader.coffee +++ b/lib/plugin-loader/plugin-loader.coffee @@ -1,4 +1,7 @@ _ = require('lodash') +async = require('async') +path = require('path') +fs = require('fs') resin = require('../resin') exports.use = (plugin) -> @@ -6,3 +9,48 @@ exports.use = (plugin) -> throw new Error('Plugin should be a function') plugin.call(null, resin) + +exports.loadPackage = (pluginPath, callback) -> + pluginPackageJSON = path.join(pluginPath, 'package.json') + + async.waterfall [ + + (callback) -> + fs.exists pluginPackageJSON, (exists) -> + error = new Error("#{pluginPackageJSON} doesn't exist") + return callback(if not exists then error) + + (callback) -> + fs.stat(pluginPackageJSON, callback) + + (stats, callback) -> + error = new Error("#{pluginPackageJSON} is not a file") + return callback(if not stats.isFile() then error) + + (callback) -> + try + packageJSON = require(pluginPackageJSON) + catch error + return callback(error) + + if not _.isObject(packageJSON) + error = new Error('package.json is not a valid JSON file') + return callback(error) + + if not packageJSON.main? + error = new Error('package.json is missing main') + return callback(error) + + mainFilePath = path.join(pluginPath, packageJSON.main) + + try + mainFile = require(mainFilePath) + catch error + return callback(error) + + if not _.isFunction(mainFile) + return callback(new Error('Entry point should be a function')) + + return callback(null, mainFile) + + ], callback diff --git a/lib/plugin-loader/plugin-loader.spec.coffee b/lib/plugin-loader/plugin-loader.spec.coffee index 2da1a64b..3e01b9db 100644 --- a/lib/plugin-loader/plugin-loader.spec.coffee +++ b/lib/plugin-loader/plugin-loader.spec.coffee @@ -3,11 +3,44 @@ chai = require('chai') chai.use(require('sinon-chai')) expect = chai.expect sinon = require('sinon') +mock = require('../../tests/utils/mock') resin = require('../resin') pluginLoader = require('../plugin-loader/plugin-loader') +FILESYSTEM = + text: + name: 'text' + contents: 'Hello World' + invalidPackage: + name: 'invalidPackage' + contents: {} + invalidPackageWithPackageJSON: + name: 'invalidPackageWithPackageJSON' + contents: + 'package.json': '' + validPackage: + name: 'validPackage' + contents: + 'package.json': JSON.stringify + name: 'myPackage' + main: 'app.js' + 'app.js': 'module.exports = function() {};' + validPackageNoFunction: + name: 'validPackageNoFunction' + contents: + 'package.json': JSON.stringify + name: 'myPackage' + main: 'app.js' + 'app.js': 'module.exports = {};' + describe 'Plugin Loader:', -> + beforeEach -> + mock.fs.init(FILESYSTEM) + + afterEach -> + mock.fs.restore() + describe '#use()', -> it 'should pass the resin object to the function', -> @@ -26,3 +59,44 @@ describe 'Plugin Loader:', -> ] func = _.partial(pluginLoader.use, nonFunction) expect(func).to.throw(Error) + + describe '#loadPackage()', -> + + it 'should return an error if path doesn\'t exist', (done) -> + pluginLoader.loadPackage 'foobar', (error, plugin) -> + expect(error).to.be.an.instanceof(Error) + expect(plugin).to.not.exist + done() + + it 'should return an error if path is not a directory', (done) -> + pluginLoader.loadPackage FILESYSTEM.text.name, (error, plugin) -> + expect(error).to.be.an.instanceof(Error) + expect(plugin).to.not.exist + done() + + it 'should return an error if there is no package.json', (done) -> + pluginLoader.loadPackage FILESYSTEM.invalidPackage.name, (error, plugin) -> + expect(error).to.be.an.instanceof(Error) + expect(plugin).to.not.exist + done() + + it 'should return an error if package.json is missing main', (done) -> + pluginPackage = FILESYSTEM.invalidPackageWithPackageJSON + pluginLoader.loadPackage pluginPackage.name, (error, plugin) -> + expect(error).to.be.an.instanceof(Error) + expect(plugin).to.not.exist + done() + + it 'should return the entry point if package is valid', (done) -> + pluginPackage = FILESYSTEM.validPackage + pluginLoader.loadPackage pluginPackage.name, (error, plugin) -> + expect(error).to.not.exist + expect(_.isFunction(plugin)).to.be.true + done() + + it 'should return the entry point is not a function', (done) -> + pluginPackage = FILESYSTEM.validPackageNoFunction + pluginLoader.loadPackage pluginPackage.name, (error, plugin) -> + expect(error).to.be.an.instanceof(Error) + expect(plugin).to.not.exist + done()