Skip to content

Commit 91c6852

Browse files
committed
Merge pull request #5 from tunnckoCore/master
part of the things in #4
2 parents 3355c16 + 8659d18 commit 91c6852

File tree

4 files changed

+152
-16
lines changed

4 files changed

+152
-16
lines changed

index.js

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@
77

88
'use strict';
99

10-
var define = require('define-property');
11-
var isObject = require('isobject');
10+
var utils = require('./utils')
1211

13-
module.exports = function base(app) {
14-
if (!app.fns) {
15-
define(app, 'fns', []);
12+
module.exports = function base(app, opts) {
13+
if (!utils.isObject(app) && typeof app !== 'function') {
14+
throw new TypeError('use: expect `app` be an object or function');
15+
}
16+
17+
opts = utils.isObject(opts) ? opts : {};
18+
opts.prop = typeof opts.prop === 'string' ? opts.prop : 'fns';
19+
opts.prop = opts.prop.length > 0 ? opts.prop : 'fns';
20+
21+
if (!utils.isArray(app[opts.prop])) {
22+
utils.define(app, opts.prop, []);
1623
}
1724

1825
/**
@@ -45,7 +52,7 @@ module.exports = function base(app) {
4552
* @api public
4653
*/
4754

48-
define(app, 'use', use);
55+
utils.define(app, 'use', use);
4956

5057
/**
5158
* Run all plugins on `fns`. Any plugin that returns a function
@@ -61,10 +68,12 @@ module.exports = function base(app) {
6168
* @api public
6269
*/
6370

64-
define(app, 'run', function (val) {
71+
utils.define(app, 'run', function (val) {
72+
var self = this || app;
73+
var fns = self[opts.prop];
6574
decorate(val);
66-
var len = this.fns.length, i = -1;
67-
while (++i < len) val.use(this.fns[i]);
75+
var len = fns.length, i = -1;
76+
while (++i < len) val.use(fns[i]);
6877
return val;
6978
});
7079

@@ -73,20 +82,30 @@ module.exports = function base(app) {
7382
* `fns` array to be called by the `run` method.
7483
*/
7584

76-
function use(fn) {
77-
var plugin = fn.call(this, this);
85+
function use(fn, options) {
86+
if (typeof fn !== 'function') {
87+
throw new TypeError('.use expect `fn` be function');
88+
}
89+
var self = this || app;
90+
91+
if (typeof opts.fn === 'function') {
92+
opts.fn.call(self, self, options);
93+
}
94+
95+
var plugin = fn.call(self, self);
7896
if (typeof plugin === 'function') {
79-
this.fns.push(plugin);
97+
var fns = self[opts.prop];
98+
fns.push(plugin);
8099
}
81-
return this;
100+
return self;
82101
}
83102

84103
/**
85104
* Ensure the `.use` method exists on `val`
86105
*/
87106

88107
function decorate(val) {
89-
if (isObject(val) && (!val.use || !val.run)) {
108+
if (utils.isObject(val) && (!val.use || !val.run)) {
90109
base(val);
91110
}
92111
}

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
},
1111
"license": "MIT",
1212
"files": [
13-
"index.js"
13+
"index.js",
14+
"utils.js"
1415
],
1516
"main": "index.js",
1617
"engines": {
@@ -21,10 +22,13 @@
2122
},
2223
"dependencies": {
2324
"define-property": "^0.2.5",
24-
"isobject": "^2.0.0"
25+
"isarray": "^1.0.0",
26+
"isobject": "^2.1.0",
27+
"lazy-cache": "^2.0.1"
2528
},
2629
"devDependencies": {
2730
"base-plugins": "^0.4.1",
31+
"extend-shallow": "^2.0.1",
2832
"gulp": "^3.9.0",
2933
"gulp-eslint": "^1.1.0",
3034
"gulp-istanbul": "^0.10.2",

test.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,75 @@ require('mocha');
44
var assert = require('assert');
55
var define = require('define-property');
66
var use = require('./');
7+
var extend = require('extend-shallow');
78

89
describe('use', function() {
910
it('should export a function', function() {
1011
assert.equal(typeof use, 'function');
1112
});
1213

14+
it('should throw TypeError `app` not a function or object', function() {
15+
function fixture() {
16+
use(123);
17+
}
18+
assert.throws(fixture, TypeError);
19+
assert.throws(fixture, /expect `app` be an object or function/);
20+
});
21+
22+
it('should throw TypeError if not a function passed to `.use` method', function() {
23+
function fixture() {
24+
use({}).use(123);
25+
}
26+
assert.throws(fixture, TypeError);
27+
assert.throws(fixture, /expect `fn` be function/);
28+
});
29+
30+
it('should allow passing `opts.fn` to merge options from each plugin to app options', function() {
31+
var limon = {options: {
32+
foo: 'bar'
33+
}};
34+
use(limon, {
35+
fn: function(app, options) {
36+
assert.strictEqual(this.options.foo, 'bar');
37+
this.options = extend(this.options, options);
38+
this.options.qux = 123;
39+
}
40+
});
41+
42+
limon
43+
.use(function() {
44+
assert.strictEqual(this.options.foo, 'bar');
45+
assert.strictEqual(this.options.xxx, 'yyy');
46+
assert.strictEqual(this.options.qux, 123);
47+
}, { xxx: 'yyy' })
48+
.use(function() {
49+
assert.strictEqual(this.options.foo, 'bar');
50+
assert.strictEqual(this.options.xxx, 'yyy');
51+
assert.strictEqual(this.options.qux, 123);
52+
assert.strictEqual(this.options.ccc, 'ddd');
53+
}, { ccc: 'ddd' });
54+
});
55+
56+
it('should not extend options if `opts.fn` not given (#3)', function () {
57+
var limon = {options: {
58+
foo: 'bar'
59+
}};
60+
use(limon);
61+
62+
limon
63+
.use(function() {
64+
assert.strictEqual(this.options.foo, 'bar');
65+
assert.strictEqual(this.options.xxx, undefined);
66+
assert.strictEqual(this.options.qux, undefined);
67+
}, { xxx: 'yyy' })
68+
.use(function() {
69+
assert.strictEqual(this.options.foo, 'bar');
70+
assert.strictEqual(this.options.xxx, undefined);
71+
assert.strictEqual(this.options.qux, undefined);
72+
assert.strictEqual(this.options.ccc, undefined);
73+
}, { ccc: 'ddd' });
74+
});
75+
1376
it('should decorate "use" onto the given object', function() {
1477
var app = {};
1578
use(app);
@@ -37,6 +100,15 @@ describe('use', function() {
37100
assert(app.fns.length === 1);
38101
});
39102

103+
it('should allow passing custom property to be used for plugins stack', function() {
104+
var app = {};
105+
use(app, { prop: 'plugins' });
106+
assert.strictEqual(Array.isArray(app.fns), false);
107+
assert.strictEqual(Array.isArray(app.plugins), true);
108+
assert(app.plugins.length === 0);
109+
110+
});
111+
40112
it('should immediately invoke a plugin function', function() {
41113
var app = {};
42114
use(app);

utils.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict'
2+
3+
/**
4+
* Module dependencies
5+
*/
6+
7+
var utils = require('lazy-cache')(require);
8+
9+
/**
10+
* Temporarily re-assign `require` to trick browserify and
11+
* webpack into reconizing lazy dependencies.
12+
*
13+
* This tiny bit of ugliness has the huge dual advantage of
14+
* only loading modules that are actually called at some
15+
* point in the lifecycle of the application, whilst also
16+
* allowing browserify and webpack to find modules that
17+
* are depended on but never actually called.
18+
*/
19+
20+
var fn = require;
21+
require = utils; // eslint-disable-line no-undef, no-native-reassign
22+
23+
/**
24+
* Lazily required module dependencies
25+
*/
26+
27+
require('define-property', 'define');
28+
require('isarray', 'isArray');
29+
require('isobject', 'isObject');
30+
31+
/**
32+
* Restore `require`
33+
*/
34+
35+
require = fn; // eslint-disable-line no-undef, no-native-reassign
36+
37+
/**
38+
* Expose `utils` modules
39+
*/
40+
41+
module.exports = utils;

0 commit comments

Comments
 (0)