From a05ae8403ed54d8d3804a97bfe80694b2bc7c76d Mon Sep 17 00:00:00 2001 From: tunnckoCore Date: Mon, 29 Feb 2016 06:58:40 +0200 Subject: [PATCH 1/3] lint, update namespace/debug to be plugins, and their logic --- index.js | 31 ++++++++++----- package.json | 5 +-- test.js | 107 +++++++++++++++++++++++++++++++++++++-------------- utils.js | 87 ++++++++++++++++++++++++++++++++++++++--- 4 files changed, 183 insertions(+), 47 deletions(-) diff --git a/index.js b/index.js index 2d436b0..45affc0 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,5 @@ 'use strict'; -var debug = require('debug'); var util = require('util'); function namespace(name) { @@ -96,19 +95,31 @@ function namespace(name) { Base.prototype.is = function(name) { var parent = (this._namespace || this._name || '').toLowerCase(); - name = name.toLowerCase(); + this.define('is' + utils.pascal(name), true); this.define('_name', name); this.define('_appname', name); - - this.define('_namespace', this._name); - utils.namespace(this, parent); - this.define('debug', debug(this._namespace)); - - this.debug.append = function(prop) { - this.namespace = parent + ':' + prop; - }; + this.define('_namespace', name); + + // internal plugins + this.use(utils.namespacePlugin(parent)); + this.use(utils.debugPlugin([ + 'collection', + 'context', + 'engine', + 'helper', + 'helpers', + 'item', + 'layout', + 'list', + 'lookup', + 'plugin', + 'render', + 'routes', + 'view', + 'views' + ])); return this; }; diff --git a/package.json b/package.json index b4ab521..52826e5 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=0.10.0" }, "scripts": { - "test": "mocha" + "test": "gulp" }, "dependencies": { "arr-union": "^3.1.0", @@ -43,8 +43,7 @@ "gulp-istanbul": "^0.10.3", "gulp-mocha": "^2.2.0", "helper-coverage": "^0.1.3", - "mocha": "*", - "should": "*" + "mocha": "*" }, "keywords": [ "boilerplate", diff --git a/test.js b/test.js index b0037e1..17203bd 100644 --- a/test.js +++ b/test.js @@ -1,10 +1,7 @@ 'use strict'; -require('mocha'); -require('should'); var assert = require('assert'); -var utils = require('./utils'); -var Base = require('./'); +var Base = require('./index'); var base; describe('constructor', function() { @@ -312,68 +309,120 @@ describe('prototype methods', function() { assert.equal(typeof base.debug, 'function'); }); - it('should append child namespaces', function() { - function Foo(options) { - Base.call(this, null, options); + it('should debug return a `debug` function', function() { + assert.equal(typeof base.debug('one'), 'function'); + }); + + it('should debug without arguments be base namespace', function() { + var app = base.debug()('foo bar baz') + assert.equal(app._namespace, 'base'); + assert.equal(base._namespace, 'base'); + assert.equal(app._debugNamespace, 'base'); + assert.equal(base._debugNamespace, 'base'); + }); + + it('should have built-in debug namespaced methods', function() { + var app = new Base(); + var foo = app.debug.helper('loading foo helper'); + + assert.equal(app._debugNamespace, 'base:helper'); + assert.equal(foo._debugNamespace, 'base:helper'); + assert.notEqual(app._debugNamespace, app._namespace); + assert.notEqual(app._debugNamespace, foo._namespace); + assert.notEqual(foo._debugNamespace, foo._namespace); + }); + + it('should not double-append the same child namespace', function() { + function Foo() { + Base.call(this); this.is('foo'); } Base.extend(Foo); - function Bar(options) { - Foo.call(this, options); + function Bar() { + Foo.call(this); this.is('bar'); } Foo.extend(Bar); - var bar = new Bar(); - assert.equal(bar.debug.namespace, 'base:foo:bar'); + function Baz() { + Bar.call(this); + this.is('bar'); + } + Bar.extend(Baz); + + var baz = new Baz(); + assert.equal(baz._debugNamespace, 'base:foo:bar'); }); - it('should not double-append the same child namespace', function() { - function Foo(options) { - Base.call(this, null, options); + it('should `debug` method return a new `debug` function', function() { + var one = base.debug('one'); + var app1 = one('that is okey'); + assert.equal(typeof one, 'function'); + assert.equal(app1._debugNamespace, 'base:one'); + + /** + * Be careful with the order of calling the things + * if you move this two lines above respectively + * below `one` and below `app1`, then `app1._debugNamespace` + * will fail, that's logical. + * + * More guaranteed is always to lookup `app._namespace`, it is + * real app namespace, but not the `debug` namespace. + * One is sure, debug namespace is bigger and always starts + * with `app._namespace`. + */ + var two = base.debug('one:two', 123, 'three', 'four:five'); + var app2 = two('that is awesome'); + assert.equal(typeof two, 'function'); + assert.equal(app2._debugNamespace, 'base:one:two:three:four:five'); + }); + + it('should append child namespaces', function() { + function Foo() { + Base.call(this); this.is('foo'); } Base.extend(Foo); - function Bar(options) { - Foo.call(this, options); + function Bar() { + Foo.call(this); this.is('bar'); } Foo.extend(Bar); - function Baz(options) { - Bar.call(this, options); - this.is('bar'); + function Baz() { + Bar.call(this); + this.is('baz'); } Bar.extend(Baz); var baz = new Baz(); - assert.equal(baz.debug.namespace, 'base:foo:bar'); + assert.equal(baz._debugNamespace, 'base:foo:bar:baz'); }); - it('should append a custom debug namespace', function() { - function Foo(options) { - Base.call(this, null, options); + it.skip('should append a custom debug namespace', function() { + function Foo() { + Base.call(this); this.is('foo'); } Base.extend(Foo); - function Bar(options) { - Foo.call(this, options); + function Bar() { + Foo.call(this); this.is('bar'); } Foo.extend(Bar); - function Baz(options) { - Bar.call(this, options); - this.is('bar'); + function Baz() { + Bar.call(this); + this.is('baz'); this.debug.append('a:b:c'); } Bar.extend(Baz); var baz = new Baz(); - assert.equal(baz.debug.namespace, 'base:foo:bar:a:b:c'); + assert.equal(baz.debug.namespace, 'base:foo:bar:baz:a:b:c'); }); }); diff --git a/utils.js b/utils.js index 93fa443..8f55b94 100644 --- a/utils.js +++ b/utils.js @@ -35,14 +35,91 @@ utils.pascal = function(name) { return name.charAt(0).toUpperCase() + name.slice(1); }; -utils.namespace = function(app, parent) { - var parentSegs = parent ? parent.split(':') : []; - var segs = app._name.split(':'); +/** + * Plugins, should be moved out + */ + +utils.namespacePlugin = function namespacePlugin(parent) { + return function plugin(app) { + parent = typeof parent === 'string' && parent.length ? parent : false; + + var parentSegs = parent ? parent.split(':') : []; + var nameSegs = app._name.split(':'); + var namespace = utils.union([], parentSegs, nameSegs); + + app.define('_namespace', namespace.join(':')); + }; +}; + +/** + * Plugin that adds `debug` method to the instance + * and `namespaces` are added to this method. + * + * ```js + * app.debug()('debugging on main namespace') + * //=> base debugging on main namespace + * + * app.debug.one = app.debug('one') + * app.debug.one('testing %s, whatever', 'foo, bar') + * //=> base:one testing foo, bar, whatever + * + * app.debug.mix = app.debug('two', 123 'three:four', 'five') + * app.debug.mix('okey, %s awesome', 'this is') + * //=> base:two:three:four:five okey, this is awesome + * + * app.debug.helper('is one of internal namespaces added') + * //=> base:helper is one of internal namespaces added + * ``` + * + * @name .debug + * @param {Array} `namespaces` + * @return {Function} + */ + +utils.debugPlugin = function debugPlugin(namespaces) { + namespaces = Array.isArray(namespaces) ? namespaces : [namespaces]; - var namespace = utils.union([], parentSegs, segs); - app._namespace = namespace.join(':'); + return function plugin(app) { + app.define('_debugNamespace', app._namespace); + app.define('debug', function debug() { + return debugFactory.apply(app, arguments); + }); + if (namespaces.length) { + var len = namespaces.length + var i = 0 + + while (i < len) { + var ns = namespaces[i++]; + app.debug[ns] = debugFactory.call(app, ns); + app.debug[ns].color = app.debug.color; + } + } + }; }; +function debugFactory() { + var app = this; + var args = [].slice.call(arguments); + var segs = app._namespace.split(':'); + var len = args.length; + var i = 0; + + while (i < len) { + var val = args[i++]; + if (typeof val === 'string') { + segs.push.apply(segs, val.split(':')); + } + } + + return function debug() { + var fn = require('debug'); + var namespace = segs.join(':'); + app.define('_debugNamespace', namespace); + fn(namespace).apply(fn, arguments); + return app; + }; +} + /** * Expose `utils` modules */ From e17831c08c24aa446cdf53ea96cc95eb93c58ce8 Mon Sep 17 00:00:00 2001 From: tunnckoCore Date: Mon, 29 Feb 2016 07:26:32 +0200 Subject: [PATCH 2/3] lint, add example.js --- example.js | 46 ++++++++++++++++++++++++++++++++++++++++++++++ test.js | 2 +- utils.js | 4 ++-- 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 example.js diff --git a/example.js b/example.js new file mode 100644 index 0000000..da80298 --- /dev/null +++ b/example.js @@ -0,0 +1,46 @@ +'use strict'; + +var Base = require('./index'); + +function Templates() { + Base.call(this); + this.is('templates'); +} +Base.extend(Templates); + +function Assemble() { + Templates.call(this); + this.is('assemble'); +} +Templates.extend(Assemble); + +function Generate() { + Assemble.call(this); + this.is('generate'); +} +Assemble.extend(Generate); + +function Verb() { + Generate.call(this); + this.is('verb'); +} +Generate.extend(Verb); + +var verb = new Verb(); + +console.log(verb._namespace); +//=> base:templates:assemble:generate:verb + +var one = verb.debug('one'); +one('debugging with %s Mike Reagent', 'Charlike'); +//=> base:templates:assemble:generate:verb:one debugging with %s Mike Reagent + +verb.debug.helper('loading foo helper'); +//=> base:templates:assemble:generate:verb:helper loading foo helper + +verb.debug('foo:bar', 123, 'baz:qux', 'zaz')('hello world'); +//=> base:templates:assemble:generate:verb:foo:bar:baz:qux:zaz hello world + +var templates = new Templates(); +templates.debug('one:two', 'three:four')('okey, that is awesome'); +//=> base:templates:one:two:three:four okey, that is awesome diff --git a/test.js b/test.js index 17203bd..ce0c902 100644 --- a/test.js +++ b/test.js @@ -314,7 +314,7 @@ describe('prototype methods', function() { }); it('should debug without arguments be base namespace', function() { - var app = base.debug()('foo bar baz') + var app = base.debug()('foo bar baz'); assert.equal(app._namespace, 'base'); assert.equal(base._namespace, 'base'); assert.equal(app._debugNamespace, 'base'); diff --git a/utils.js b/utils.js index 8f55b94..b3ae02d 100644 --- a/utils.js +++ b/utils.js @@ -85,8 +85,8 @@ utils.debugPlugin = function debugPlugin(namespaces) { return debugFactory.apply(app, arguments); }); if (namespaces.length) { - var len = namespaces.length - var i = 0 + var len = namespaces.length; + var i = 0; while (i < len) { var ns = namespaces[i++]; From 594c64dd70ab2d8802b70433fc47388a423554a0 Mon Sep 17 00:00:00 2001 From: tunnckoCore Date: Mon, 29 Feb 2016 17:29:26 +0200 Subject: [PATCH 3/3] base does not need default debug namespaces --- index.js | 17 +---------------- test.js | 35 ----------------------------------- 2 files changed, 1 insertion(+), 51 deletions(-) diff --git a/index.js b/index.js index 45affc0..7783fda 100644 --- a/index.js +++ b/index.js @@ -104,22 +104,7 @@ function namespace(name) { // internal plugins this.use(utils.namespacePlugin(parent)); - this.use(utils.debugPlugin([ - 'collection', - 'context', - 'engine', - 'helper', - 'helpers', - 'item', - 'layout', - 'list', - 'lookup', - 'plugin', - 'render', - 'routes', - 'view', - 'views' - ])); + this.use(utils.debugPlugin()); return this; }; diff --git a/test.js b/test.js index ce0c902..b521109 100644 --- a/test.js +++ b/test.js @@ -321,17 +321,6 @@ describe('prototype methods', function() { assert.equal(base._debugNamespace, 'base'); }); - it('should have built-in debug namespaced methods', function() { - var app = new Base(); - var foo = app.debug.helper('loading foo helper'); - - assert.equal(app._debugNamespace, 'base:helper'); - assert.equal(foo._debugNamespace, 'base:helper'); - assert.notEqual(app._debugNamespace, app._namespace); - assert.notEqual(app._debugNamespace, foo._namespace); - assert.notEqual(foo._debugNamespace, foo._namespace); - }); - it('should not double-append the same child namespace', function() { function Foo() { Base.call(this); @@ -400,30 +389,6 @@ describe('prototype methods', function() { var baz = new Baz(); assert.equal(baz._debugNamespace, 'base:foo:bar:baz'); }); - - it.skip('should append a custom debug namespace', function() { - function Foo() { - Base.call(this); - this.is('foo'); - } - Base.extend(Foo); - - function Bar() { - Foo.call(this); - this.is('bar'); - } - Foo.extend(Bar); - - function Baz() { - Bar.call(this); - this.is('baz'); - this.debug.append('a:b:c'); - } - Bar.extend(Baz); - - var baz = new Baz(); - assert.equal(baz.debug.namespace, 'base:foo:bar:baz:a:b:c'); - }); }); describe('use', function() {