diff options
-rw-r--r-- | lib/configuration.js | 12 | ||||
-rw-r--r-- | lib/plugin.js | 41 | ||||
-rw-r--r-- | lib/pluginslist.js | 4 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | test/assertions.js | 34 | ||||
-rw-r--r-- | test/plugins.js | 31 | ||||
-rw-r--r-- | test/plugins/config/index.js | 1 | ||||
-rw-r--r-- | test/plugins/config/package.json | 21 |
8 files changed, 112 insertions, 33 deletions
diff --git a/lib/configuration.js b/lib/configuration.js index 64d4b17..d514720 100644 --- a/lib/configuration.js +++ b/lib/configuration.js @@ -168,7 +168,7 @@ Configuration.prototype.extend = function(options) { _.extend(this.options, options); }; -// Replace the configuration +// Replace the whole configuration Configuration.prototype.replace = function(options) { this.options = _.cloneDeep(DEFAULT_CONFIG); this.options = _.merge(this.options, options || {}); @@ -199,16 +199,6 @@ Configuration.prototype.set = function(key, value) { return _.set(this.options, key, value); }; -// Return a configuration for a plugin -Configuration.prototype.getForPlugin = function(pluginName) { - return this.get('pluginsConfig.'+pluginName, {}); -}; - -// Set a configuration for a plugin -Configuration.prototype.setForPlugin = function(pluginName, config) { - return this.get('pluginsConfig.'+pluginName, config); -}; - // Default configuration Configuration.DEFAULT = DEFAULT_CONFIG; diff --git a/lib/plugin.js b/lib/plugin.js index 45d77b8..4095231 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -10,9 +10,18 @@ var jsonSchemaDefaults = require('json-schema-defaults'); var pkg = require('../package.json'); +var PLUGIN_PREFIX = 'gitbook-plugin-'; + +// Return an absolute name for the plugin (the one on NPM) +function absoluteName(name) { + if (name.indexOf(PLUGIN_PREFIX) === 0) return name; + return [PLUGIN_PREFIX, name].join(''); +} + + var Plugin = function(book, name) { this.book = book; - this.name = name; + this.name = absoluteName(name); this.packageInfos = {}; this.infos = {}; @@ -20,8 +29,7 @@ var Plugin = function(book, name) { _.bindAll(this); _.each([ - 'gitbook-plugin-'+name, - 'gitbook-'+name, + absoluteName(name), name ], function(_name) { // Load from the book @@ -38,6 +46,13 @@ Plugin.HOOKS = [ 'init', 'finish', 'finish:before', 'config', 'page', 'page:before' ]; +// Return the reduce name for the plugin +// "gitbook-plugin-test" -> "test" +// Return a relative name for the plugin (the one on GitBook) +Plugin.prototype.reducedName = function() { + return this.name.replace(PLUGIN_PREFIX, ''); +}; + // Load from a name Plugin.prototype.load = function(name, baseDir) { try { @@ -152,11 +167,19 @@ Plugin.prototype.validateConfig = function(config) { if (!schema) return config; // Normalize schema + schema.id = '/pluginsConfig.'+that.reducedName(); schema.type = 'object'; // Validate and throw if invalid var v = new jsonschema.Validator(); - v.validate(config, schema); + var result = v.validate(config, schema, { + propertyName: 'pluginsConfig.'+that.reducedName() + }); + + // Throw error + if (result.errors.length > 0) { + throw new Error('Configuration Error: '+result.errors[0].stack); + } // Insert default values var defaults = jsonSchemaDefaults(schema); @@ -205,4 +228,14 @@ Plugin.prototype.copyAssets = function(out, base) { }, _.constant(false)); }; +// Get config from book +Plugin.prototype.getConfig = function() { + return this.book.config.get('pluginsCOnfig.'+this.reducedName()); +}; + +// Set configuration for this plugin +Plugin.prototype.setConfig = function(values) { + return this.book.config.set('pluginsCOnfig.'+this.reducedName(), values); +}; + module.exports = Plugin; diff --git a/lib/pluginslist.js b/lib/pluginslist.js index 636eddc..8830950 100644 --- a/lib/pluginslist.js +++ b/lib/pluginslist.js @@ -82,12 +82,12 @@ PluginsList.prototype.load = function(plugin) { // Validate and normalize configuration .then(function() { - var config = that.book.config.getForPlugin(plugin.name); + var config = plugin.getConfig(); return plugin.validateConfig(config); }) .then(function(config) { // Update configuration - that.book.config.getForPlugin(plugin.name, config); + plugin.setConfig(config); // Extract filters that.book.template.addFilters(plugin.getFilters()); diff --git a/package.json b/package.json index a9467f5..4cba6a8 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "eslint": "1.5.0", "mocha": "2.3.2", "should": "7.1.0", + "should-promised": "0.3.1", "gulp": "^3.8.11", "gulp-rename": "^1.2.2", "gulp-uglify": "1.1.0", diff --git a/test/assertions.js b/test/assertions.js index 7e14ecb..f9c4ba3 100644 --- a/test/assertions.js +++ b/test/assertions.js @@ -1,27 +1,29 @@ -var _ = require("lodash"); -var fs = require("fs"); -var path = require("path"); -var should = require("should"); -var cheerio = require("cheerio"); +var _ = require('lodash'); +var fs = require('fs'); +var path = require('path'); +var should = require('should'); +var cheerio = require('cheerio'); -should.Assertion.add("file", function(file, description) { - this.params = { actual: this.obj.toString(), operator: "have file " + file, message: description }; +require('should-promised'); - this.obj.should.have.property("options").which.is.an.Object(); - this.obj.options.should.have.property("output").which.is.a.String(); +should.Assertion.add('file', function(file, description) { + this.params = { actual: this.obj.toString(), operator: 'have file ' + file, message: description }; + + this.obj.should.have.property('options').which.is.an.Object(); + this.obj.options.should.have.property('output').which.is.a.String(); this.assert(fs.existsSync(path.resolve(this.obj.options.output, file))); }); -should.Assertion.add("jsonfile", function(file, description) { - this.params = { actual: this.obj.toString(), operator: "have valid jsonfile " + file, message: description }; +should.Assertion.add('jsonfile', function(file, description) { + this.params = { actual: this.obj.toString(), operator: 'have valid jsonfile ' + file, message: description }; - this.obj.should.have.property("options").which.is.an.Object(); - this.obj.options.should.have.property("output").which.is.a.String(); - this.assert(JSON.parse(fs.readFileSync(path.resolve(this.obj.options.output, file), { encoding: "utf-8" }))); + this.obj.should.have.property('options').which.is.an.Object(); + this.obj.options.should.have.property('output').which.is.a.String(); + this.assert(JSON.parse(fs.readFileSync(path.resolve(this.obj.options.output, file), { encoding: 'utf-8' }))); }); -should.Assertion.add("html", function(rules, description) { - this.params = { actual: "HTML string", operator: "valid html", message: description }; +should.Assertion.add('html', function(rules, description) { + this.params = { actual: 'HTML string', operator: 'valid html', message: description }; var $ = cheerio.load(this.obj); _.each(rules, function(validations, query) { diff --git a/test/plugins.js b/test/plugins.js index 4f91e9a..db2d225 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -51,6 +51,37 @@ describe('Plugins', function () { }); }); + describe('Configuration', function() { + var plugin; + + before(function() { + plugin = new Plugin(book, 'testconfig'); + plugin.load('./config', PLUGINS_ROOT); + }); + + it('should throw error for invalid configuration', function() { + return plugin.validateConfig({}) + .should.be.rejectedWith('Configuration Error: pluginsConfig.testconfig.testRequired is required'); + }); + + it('should throw error for invalid types', function() { + return plugin.validateConfig({ + testRequired: 'hello' + }) + .should.be.rejectedWith('Configuration Error: pluginsConfig.testconfig.testRequired is not of a type(s) number'); + }); + + it('should extend with default values', function() { + return plugin.validateConfig({ + testRequired: 12 + }) + .should.be.fulfilledWith({ + hello: 'world', + testRequired: 12 + }); + }); + }); + describe('Resources', function() { var plugin; diff --git a/test/plugins/config/index.js b/test/plugins/config/index.js new file mode 100644 index 0000000..f053ebf --- /dev/null +++ b/test/plugins/config/index.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/test/plugins/config/package.json b/test/plugins/config/package.json new file mode 100644 index 0000000..03ef744 --- /dev/null +++ b/test/plugins/config/package.json @@ -0,0 +1,21 @@ +{ + "name": "gitbook-plugin-testconfig", + "description": "Test plugin configuration", + "main": "index.js", + "version": "0.0.1", + "engines": { + "gitbook": "*" + }, + "gitbook": { + "properties": { + "hello": { + "type": "string", + "default": "world" + }, + "testRequired": { + "type": "number", + "required": true + } + } + } +}
\ No newline at end of file |