Skip to content

lint, update namespace/debug to be plugins, and their logic #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions example.js
Original file line number Diff line number Diff line change
@@ -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');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome, great example

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, I also very like the idea that the this.debug is as compose part, and others are just copy of original debug function.

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you change zaz to fez? jk

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sometimes I see people nitpick about stuff that seems almost as arbitrary... lol


var templates = new Templates();
templates.debug('one:two', 'three:four')('okey, that is awesome');
//=> base:templates:one:two:three:four okey, that is awesome
14 changes: 5 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use strict';

var debug = require('debug');
var util = require('util');

function namespace(name) {
Expand Down Expand Up @@ -96,19 +95,16 @@ 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', 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;
};
// internal plugins
this.use(utils.namespacePlugin(parent));
this.use(utils.debugPlugin());
return this;
};

Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"node": ">=0.10.0"
},
"scripts": {
"test": "mocha"
"test": "gulp"
},
"dependencies": {
"arr-union": "^3.1.0",
Expand All @@ -43,8 +43,7 @@
"gulp-istanbul": "^0.10.3",
"gulp-mocha": "^2.2.0",
"helper-coverage": "^0.1.3",
"mocha": "*",
"should": "*"
"mocha": "*"
},
"keywords": [
"boilerplate",
Expand Down
84 changes: 49 additions & 35 deletions test.js
Original file line number Diff line number Diff line change
@@ -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');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't all have mocha globally, that's a bad practice. users shouldn't be forced to install it with -g

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will also work if it is installed locally when just npm install && npm test, without requiring it.

I don't know how much it is a bad practice, but hate to waste time to install shitty-mitty-bitty-biggy modules every time i'm going to test or pr to some project.
"every time i'm going to test" meaning, that there are many project that just have one devDependency and it is some testing framework.

But yea, preferences, religious things.. anyway. :)

edit: Another question is that that mocha is bad in general, exactly because this globals. I'm agree here - that is bad practice. That's why there is absolutely better and smaller testit, which is almost drop-in replacement for mocha. That's why i created assertit on top of testit with few lines enhancement and using it everywhere from one year or so.

var base;

describe('constructor', function() {
Expand Down Expand Up @@ -312,68 +309,85 @@ describe('prototype methods', function() {
assert.equal(typeof base.debug, 'function');
});

it('should append child namespaces', function() {
function Foo(options) {
Base.call(this, null, options);
this.is('foo');
}
Base.extend(Foo);

function Bar(options) {
Foo.call(this, options);
this.is('bar');
}
Foo.extend(Bar);
it('should debug return a `debug` function', function() {
assert.equal(typeof base.debug('one'), 'function');
});

var bar = new Bar();
assert.equal(bar.debug.namespace, 'base:foo:bar');
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 not double-append the same child namespace', function() {
function Foo(options) {
Base.call(this, null, options);
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);
function Baz() {
Bar.call(this);
this.is('bar');
}
Bar.extend(Baz);

var baz = new Baz();
assert.equal(baz.debug.namespace, 'base:foo:bar');
assert.equal(baz._debugNamespace, 'base:foo:bar');
});

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 a custom debug namespace', function() {
function Foo(options) {
Base.call(this, null, options);
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');
this.debug.append('a:b:c');
function Baz() {
Bar.call(this);
this.is('baz');
}
Bar.extend(Baz);

var baz = new Baz();
assert.equal(baz.debug.namespace, 'base:foo:bar:a:b:c');
assert.equal(baz._debugNamespace, 'base:foo:bar:baz');
});
});

Expand Down
87 changes: 82 additions & 5 deletions utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this line is working the way you think. Since app.debug is acting as a debugFactory instead of a debugger method, it doesn't have a .color on it.

If you're going the approach that a user needs to do app.debug()('this is a message') to access the default debugger, then I think that debugger needs to be cached with the namespace and the color from that can be used on the children to match the application color.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this line is working the way you think.

Haha, actually yea, i noticed it.

If you're going the approach that a user needs to do

It's intentional, to be used as compose thingy for other namespaces (methods on app.debug.*)

}
}
};
};

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
*/
Expand Down