[Pkg-javascript-commits] [libjs-microplugin.js] 01/03: Imported Upstream version 0.0.3+dfsg

Sergio Durigan Junior sergiodj-guest at moszumanska.debian.org
Mon Aug 15 13:08:50 UTC 2016


This is an automated email from the git hooks/post-receive script.

sergiodj-guest pushed a commit to branch master
in repository libjs-microplugin.js.

commit 77dd2d077053be208e3070d24361640ddbee8040
Author: Sergio Durigan Junior <sergiodj at sergiodj.net>
Date:   Mon Aug 15 08:45:23 2016 -0400

    Imported Upstream version 0.0.3+dfsg
---
 .gitignore         |   2 +
 .npmignore         |   3 +
 .travis.yml        |   8 ++
 Makefile           |  20 +++++
 README.md          | 115 ++++++++++++++++++++++++++
 bower.json         |  22 +++++
 package.json       |  15 ++++
 src/microplugin.js | 135 +++++++++++++++++++++++++++++++
 test/index.js      | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 554 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fbe153a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.DS_store
+node_modules
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..46c03e5
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,3 @@
+*.md
+.git*
+test/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..5c5e805
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,8 @@
+language: node_js
+node_js:
+  - "0.10"
+before_script:
+  - npm install -g mocha
+  - make
+script:
+  - mocha --reporter tap
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..521040b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,20 @@
+.PHONY: test release
+
+test:
+	mocha --reporter spec
+release:
+ifeq ($(strip $(version)),)
+	@echo "\033[31mERROR:\033[0;39m No version provided."
+	@echo "\033[1;30mmake release version=1.0.0\033[0;39m"
+else
+	sed -i.bak 's/"version": "[^"]*"/"version": "$(version)"/' package.json
+	sed -i.bak 's/"version": "[^"]*"/"version": "$(version)"/' bower.json
+	rm *.bak
+	git add .
+	git commit -a -m "Released $(version)."
+	git tag v$(version)
+	git push origin master
+	git push origin --tags
+	npm publish
+	@echo "\033[32mv${version} released\033[0;39m"
+endif
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..985ae45
--- /dev/null
+++ b/README.md
@@ -0,0 +1,115 @@
+# microplugin.js
+[![NPM version](https://badge.fury.io/js/microplugin.png)](http://badge.fury.io/js/microplugin)
+[![Build Status](https://travis-ci.org/brianreavis/microplugin.js.png?branch=master)](https://travis-ci.org/brianreavis/microplugin.js)
+
+*Keep code modularized & extensible.* MicroPlugin is a lightweight drop-in plugin architecture for your JavaScript library. Plugins can [declare dependencies](#dependencies) to other plugins and can be [initialized with options](#loading-plugins) (in a variety of formats). It [AMD](http://en.wikipedia.org/wiki/Asynchronous_module_definition)-compatible and it works identically in Node.js and in a browser.
+
+```sh
+$ npm install microplugin
+$ bower install microplugin
+```
+
+## Integration
+
+Using the provided mixin, extend your function with the [API](#mixin-methods) for declaring and loading plugins:
+
+```js
+var TextEditor = function(options) {
+	this.initializePlugins(options.plugins);
+};
+
+MicroPlugin.mixin(TextEditor);
+```
+
+That's it for integration! Now you can selectively load the plugins on an instance-by-instance basis.
+
+```js
+var editor = new TextEditor({
+	plugins: ['links','images']
+});
+```
+
+### Loading Plugins
+
+The [`initializePlugins()`](#prototypeinitializepluginsplugins) method sets up the plugin system and loads a list of plugins (with options). It accepts the list in three styles, depending on your preference.
+
+#### List (no options)
+```js
+["plugin_a","plugin_b","plugin_c"]
+```
+
+#### List (with options)
+```js
+[
+	{name: "plugin_a", options: { /* ... */ }},
+	{name: "plugin_b", options: { /* ... */ }},
+	{name: "plugin_c", options: { /* ... */ }}
+]
+```
+
+#### Hash (with options)
+```js
+{
+	"plugin_a": { /* ... */ },
+	"plugin_b": { /* ... */ },
+	"plugin_c": { /* ... */ }
+}
+```
+
+## Plugin Design
+
+Plugins aren't extravagant—they are barebones by design. A plugin is simply a function that gets called when an instance of your object is being constructed. Within that function, you can manually override methods, set up event listeners, etc. The `this` context will be the instance of your object.
+
+### Defining Plugins
+
+```js
+MyLibrary.define("math", function(options) {
+	// You can return values which will be available to other plugins
+	// when they load the plugin via "require()". Explained more in
+	// the next section.
+	return {
+		random : Math.random,
+		sqrt   : Math.sqrt,
+		sin2   : function(t) { return Math.pow(Math.sin(t), 2); },
+		cos2   : function(t) { return Math.pow(Math.sin(t), 2); }
+	};
+});
+```
+
+#### Dependencies
+
+Plugins can declare dependencies to other plugins (and use any exports they provide) through the [`require`](#prototyperequirename) function.
+
+```js
+MyLibrary.define("calculations", function(options) {
+	var math    = this.require("math");
+	var theta   = math.random();
+	var success = math.sqrt(math.sin2(theta) + math.cos2(theta)) === 1;
+
+	alert("Does the law of sines work? " + success);
+});
+```
+
+## API Reference
+
+#### MicroPlugin.mixin(fn)
+Sets up all methods on the function and its prototype for defining and loading plugins.
+
+### Mixin Methods
+
+#### define(name, fn)
+Declares a new plugin with the specified name.
+
+#### [prototype].require(name)
+Loads a plugin as a dependency and returns whatever it exports (if anything).
+
+#### [prototype].initializePlugins(plugins)
+Initializes the plugin system and loads a list of plugins with the provided options. The "plugins" argument can be in a [variety of formats](#loading-plugins).
+
+## License
+
+Copyright © 2013 [Brian Reavis](http://twitter.com/brianreavis) & [Contributors](https://github.com/brianreavis/microplugin.js/graphs/contributors)
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
diff --git a/bower.json b/bower.json
new file mode 100644
index 0000000..5ea782c
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,22 @@
+{
+	"name": "microplugin",
+	"keywords": ["extensibility","plugins","architecture","require","dependencies"],
+	"description": "A lightweight plugin / dependency system for javascript libraries.",
+	"version": "0.0.3",
+	"license": "Apache License, Version 2.0",
+	"readmeFilename": "README.md",
+	"repository": {
+		"type": "git",
+		"url": "git://github.com/brianreavis/microplugin.js.git"
+	},
+	"main": [
+		"src/microplugin.js"
+	],
+	"ignore": [
+		"Makefile",
+		"test",
+		".travis.yml",
+		".npmignore.yml"
+	],
+	"dependencies": {}
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..317d01f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,15 @@
+{
+	"name": "microplugin",
+	"keywords": ["extensibility","plugins","architecture","require","dependencies"],
+	"description": "A lightweight plugin / dependency system for javascript libraries.",
+	"version": "0.0.3",
+	"author": "Brian Reavis <brian at thirdroute.com>",
+	"main": "src/microplugin.js",
+	"repository": {
+		"type": "git",
+		"url": "git://github.com/brianreavis/microplugin.js.git"
+	},
+	"dependencies": {},
+	"devDependencies": {},
+	"engines": {"node": "*"}
+}
diff --git a/src/microplugin.js b/src/microplugin.js
new file mode 100644
index 0000000..0b53c50
--- /dev/null
+++ b/src/microplugin.js
@@ -0,0 +1,135 @@
+/**
+ * microplugin.js
+ * Copyright (c) 2013 Brian Reavis & contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+ * file except in compliance with the License. You may obtain a copy of the License at:
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ *
+ * @author Brian Reavis <brian at thirdroute.com>
+ */
+
+(function(root, factory) {
+	if (typeof define === 'function' && define.amd) {
+		define(factory);
+	} else if (typeof exports === 'object') {
+		module.exports = factory();
+	} else {
+		root.MicroPlugin = factory();
+	}
+}(this, function() {
+	var MicroPlugin = {};
+
+	MicroPlugin.mixin = function(Interface) {
+		Interface.plugins = {};
+
+		/**
+		 * Initializes the listed plugins (with options).
+		 * Acceptable formats:
+		 *
+		 * List (without options):
+		 *   ['a', 'b', 'c']
+		 *
+		 * List (with options):
+		 *   [{'name': 'a', options: {}}, {'name': 'b', options: {}}]
+		 *
+		 * Hash (with options):
+		 *   {'a': { ... }, 'b': { ... }, 'c': { ... }}
+		 *
+		 * @param {mixed} plugins
+		 */
+		Interface.prototype.initializePlugins = function(plugins) {
+			var i, n, key;
+			var self  = this;
+			var queue = [];
+
+			self.plugins = {
+				names     : [],
+				settings  : {},
+				requested : {},
+				loaded    : {}
+			};
+
+			if (utils.isArray(plugins)) {
+				for (i = 0, n = plugins.length; i < n; i++) {
+					if (typeof plugins[i] === 'string') {
+						queue.push(plugins[i]);
+					} else {
+						self.plugins.settings[plugins[i].name] = plugins[i].options;
+						queue.push(plugins[i].name);
+					}
+				}
+			} else if (plugins) {
+				for (key in plugins) {
+					if (plugins.hasOwnProperty(key)) {
+						self.plugins.settings[key] = plugins[key];
+						queue.push(key);
+					}
+				}
+			}
+
+			while (queue.length) {
+				self.require(queue.shift());
+			}
+		};
+
+		Interface.prototype.loadPlugin = function(name) {
+			var self    = this;
+			var plugins = self.plugins;
+			var plugin  = Interface.plugins[name];
+
+			if (!Interface.plugins.hasOwnProperty(name)) {
+				throw new Error('Unable to find "' +  name + '" plugin');
+			}
+
+			plugins.requested[name] = true;
+			plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);
+			plugins.names.push(name);
+		};
+
+		/**
+		 * Initializes a plugin.
+		 *
+		 * @param {string} name
+		 */
+		Interface.prototype.require = function(name) {
+			var self = this;
+			var plugins = self.plugins;
+
+			if (!self.plugins.loaded.hasOwnProperty(name)) {
+				if (plugins.requested[name]) {
+					throw new Error('Plugin has circular dependency ("' + name + '")');
+				}
+				self.loadPlugin(name);
+			}
+
+			return plugins.loaded[name];
+		};
+
+		/**
+		 * Registers a plugin.
+		 *
+		 * @param {string} name
+		 * @param {function} fn
+		 */
+		Interface.define = function(name, fn) {
+			Interface.plugins[name] = {
+				'name' : name,
+				'fn'   : fn
+			};
+		};
+	};
+
+	var utils = {
+		isArray: Array.isArray || function(vArg) {
+			return Object.prototype.toString.call(vArg) === '[object Array]';
+		}
+	};
+
+	return MicroPlugin;
+}));
\ No newline at end of file
diff --git a/test/index.js b/test/index.js
new file mode 100644
index 0000000..84254f7
--- /dev/null
+++ b/test/index.js
@@ -0,0 +1,234 @@
+var assert = require('assert');
+var MicroPlugin = require('../src/microplugin.js');
+
+describe('MicroPlugin', function() {
+
+	describe('mixin()', function() {
+
+		it('should add "define" method', function() {
+			var Lib = function() {};
+			MicroPlugin.mixin(Lib);
+			assert.equal(typeof Lib.define, 'function');
+		});
+
+		it('should add "require" method to prototype', function() {
+			var Lib = function() {};
+			MicroPlugin.mixin(Lib);
+			assert.equal(typeof Lib.prototype.require, 'function');
+		});
+
+		it('should add "initializePlugins" method to prototype', function() {
+			var Lib = function() {};
+			MicroPlugin.mixin(Lib);
+			assert.equal(typeof Lib.prototype.initializePlugins, 'function');
+		});
+
+	});
+
+	describe('#initializePlugins()', function() {
+
+		describe('format: array of plugin names', function() {
+
+			it('should load plugins with options empty', function() {
+				var Lib = function() {
+					this.initializePlugins(['a','b']);
+				};
+				MicroPlugin.mixin(Lib);
+
+				var loaded = 0;
+				Lib.define('a', function(options) { loaded++; assert.deepEqual(options, {}); });
+				Lib.define('b', function(options) { loaded++; assert.deepEqual(options, {}); });
+
+				new Lib();
+				assert.equal(loaded, 2);
+			});
+
+			it('should not load plugins that are not listed', function() {
+				var Lib = function() {
+					this.initializePlugins(['a','b']);
+				};
+				MicroPlugin.mixin(Lib);
+
+				var loaded = false;
+				Lib.define('a', function(options) { });
+				Lib.define('b', function(options) { });
+				Lib.define('c', function(options) { loaded = true; });
+
+				new Lib();
+				assert.equal(loaded, false);
+			});
+
+			it('should only execute plugins once, even if listed more than once', function() {
+				var Lib = function() {
+					this.initializePlugins(['a','a']);
+				};
+				MicroPlugin.mixin(Lib);
+
+				var counter = 0;
+				Lib.define('a', function(options) { counter++; });
+
+				new Lib();
+				assert.equal(counter, 1);
+			});
+
+		});
+
+		describe('format: hash of plugin options', function() {
+
+			it('should load plugins with correct options', function() {
+				var Lib = function() {
+					this.initializePlugins({
+						'a': {test: 'hello_a'},
+						'b': {test: 'hello_b'}
+					});
+				};
+				MicroPlugin.mixin(Lib);
+
+				var loaded = 0;
+				Lib.define('a', function(options) { loaded++; assert.equal(options.test, 'hello_a'); });
+				Lib.define('b', function(options) { loaded++; assert.equal(options.test, 'hello_b'); });
+
+				new Lib();
+				assert.equal(loaded, 2);
+			});
+
+			it('should not load plugins that are not listed', function() {
+				var Lib = function() {
+					this.initializePlugins({
+						'a': {test: 'hello_a'},
+						'b': {test: 'hello_b'}
+					});
+				};
+				MicroPlugin.mixin(Lib);
+
+				var loaded = false;
+				Lib.define('a', function(options) { });
+				Lib.define('b', function(options) { });
+				Lib.define('c', function(options) { loaded = true; });
+
+				new Lib();
+				assert.equal(loaded, false);
+			});
+
+		});
+
+
+		describe('format: array of plugin options', function() {
+
+			it('should load plugins with correct options', function() {
+				var Lib = function() {
+					this.initializePlugins([
+						{name: 'a', options: {test: 'hello_a'}},
+						{name: 'b', options: {test: 'hello_b'}}
+					]);
+				};
+				MicroPlugin.mixin(Lib);
+
+				var loaded = 0;
+				Lib.define('a', function(options) { loaded++; assert.deepEqual(options, {test: 'hello_a'}); });
+				Lib.define('b', function(options) { loaded++; assert.deepEqual(options, {test: 'hello_b'}); });
+
+				new Lib();
+				assert.equal(loaded, 2);
+			});
+
+			it('should not load plugins that are not listed', function() {
+				var Lib = function() {
+					this.initializePlugins([
+						{name: 'a', options: {test: 'hello_a'}},
+						{name: 'b', options: {test: 'hello_b'}}
+					]);
+				};
+				MicroPlugin.mixin(Lib);
+
+				var loaded = false;
+				Lib.define('a', function(options) { });
+				Lib.define('b', function(options) { });
+				Lib.define('c', function(options) { loaded = true; });
+
+				new Lib();
+				assert.equal(loaded, false);
+			});
+
+			it('should only execute plugins once, even if listed more than once', function() {
+				var Lib = function() {
+					this.initializePlugins([
+						{name: 'a', options: {test: 'hello_a'}},
+						{name: 'a', options: {test: 'hello_a'}},
+						{name: 'a', options: {test: 'hello_a'}}
+					]);
+				};
+				MicroPlugin.mixin(Lib);
+
+				var counter = 0;
+				Lib.define('a', function(options) { counter++; });
+
+				new Lib();
+				assert.equal(counter, 1);
+			});
+
+		});
+
+	});
+
+	describe('#require()', function() {
+
+		it('should throw error if requested plugin not defined', function() {
+			var Lib = function() { this.initializePlugins(); };
+			MicroPlugin.mixin(Lib);
+
+			assert.throws(function() {
+				var instance = new Lib();
+				instance.require('a');
+			});
+		});
+
+		it('should throw error if circular dependency exists', function() {
+			var Lib = function() { this.initializePlugins(); };
+			MicroPlugin.mixin(Lib);
+
+			Lib.define('a', function() { this.require('b'); });
+			Lib.define('b', function() { this.require('a'); });
+
+			assert.throws(function() {
+				var instance = new Lib();
+				instance.require('b');
+			}, /dependency/);
+		});
+
+		it('should not execute plugin code more than once', function() {
+			var Lib = function() { this.initializePlugins(); };
+			MicroPlugin.mixin(Lib);
+
+			var counter = 0;
+			Lib.define('a', function() { counter++; });
+			Lib.define('b', function() { this.require('a'); });
+
+			var instance = new Lib();
+			instance.require('a');
+			instance.require('a');
+			instance.require('b');
+
+			assert.equal(counter, 1);
+		});
+
+		it('should return plugin exports', function() {
+			var Lib = function() { this.initializePlugins(); };
+			MicroPlugin.mixin(Lib);
+
+			Lib.define('a', function() { return 'test'; });
+			Lib.define('b', function() { return {test: true}; });
+			Lib.define('c', function() { return false; });
+			Lib.define('d', function() { });
+
+			var instance = new Lib();
+			assert.equal(instance.require('a'), 'test');
+			assert.equal(instance.require('a'), 'test');
+			assert.equal(instance.require('b').test, true);
+			assert.equal(instance.require('c'), false);
+			assert.equal(typeof instance.require('d'), 'undefined');
+		});
+
+	});
+
+});
\ No newline at end of file

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/libjs-microplugin.js.git



More information about the Pkg-javascript-commits mailing list