summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamy Pessé <samypesse@gmail.com>2015-10-13 14:31:11 +0200
committerSamy Pessé <samypesse@gmail.com>2015-10-13 14:31:11 +0200
commitb742b29259aced60ec03d5577da96a2c7f2e1277 (patch)
treed8582baaf807233856fd2958664f7be45a03dc14
parentdf5d27ab6103389294795a7fada76d46f36fc00f (diff)
downloadgitbook-b742b29259aced60ec03d5577da96a2c7f2e1277.zip
gitbook-b742b29259aced60ec03d5577da96a2c7f2e1277.tar.gz
gitbook-b742b29259aced60ec03d5577da96a2c7f2e1277.tar.bz2
Add tests for plugins config validation
-rw-r--r--lib/configuration.js12
-rw-r--r--lib/plugin.js41
-rw-r--r--lib/pluginslist.js4
-rw-r--r--package.json1
-rw-r--r--test/assertions.js34
-rw-r--r--test/plugins.js31
-rw-r--r--test/plugins/config/index.js1
-rw-r--r--test/plugins/config/package.json21
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