Skip to content
Open
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
31 changes: 18 additions & 13 deletions lib/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function Container() {
this._order = [];
this._resolvers = [];
this._special = {};

this.resolver(require('./resolvers/id')());
}

Expand Down Expand Up @@ -70,32 +70,32 @@ Container.prototype.create = function(id, parent) {
// resolve relative component ID
id = path.join(path.dirname(parent.id), id);
}

// built-ins
switch (id) {
case '!container':
// TODO: Get the source prefix and pass it here. Isolate introspected specs
// to the prefix.
return new InjectedContainer(this);
}


id = this.resolve(id, parent && parent.id);

var spec = this._specs[id];
if (!spec) {
// No specification is registered with the given ID. Attempt to register
// the specification by loading its corresponding module.
this._loadSpec(id);
}

spec = this._specs[id];
if (!spec) {
// After attemting auto-loading, the component ID is still unregistered,
// which is a terminal condition.
throw new Error("Unable to create object '" + id + "'");
}

var obj = spec.create(this);
this.emit('create', obj, spec);
return obj;
Expand Down Expand Up @@ -139,12 +139,12 @@ Container.prototype.use = function(prefix, fn) {
if (typeof fn != 'function') {
throw new Error("Container#use requires a function, was passed a '" + (typeof fn) + "'");
}

if (prefix.length && prefix[prefix.length - 1] != '/') { prefix += '/'; }
var id = this._order.length;
this._sources[id] = { load: fn, prefix: prefix };
this._order.unshift(id);

if (fn && fn.used) {
var wc = new UsingContainer(this, prefix);
fn.used(wc);
Expand Down Expand Up @@ -172,7 +172,7 @@ Container.prototype._loadSpec = function(id) {
if (id.indexOf(prefix) !== 0) { continue; }
rid = id.slice(prefix.length);
mod = source.load(rid);

if (mod) {
this._registerSpec(id, mod, order[i]);
break;
Expand All @@ -185,7 +185,12 @@ Container.prototype._registerSpec = function(id, mod, hsource) {
, pattern = 'literal'
, singleton = mod['@singleton']
, spec


if (typeof mod == 'object' && mod['@literal'] !== true) {
var name = mod.name || 'default';
mod = mod[name];
}

if (typeof mod == 'function' && mod['@literal'] !== true) {
var name = mod.name || 'anonymous';
if (name[0] == name[0].toUpperCase()) {
Expand All @@ -194,7 +199,7 @@ Container.prototype._registerSpec = function(id, mod, hsource) {
pattern = 'factory';
}
}

switch (pattern) {
case 'factory':
debug('register factory %s %s', id, dependencies);
Expand All @@ -209,7 +214,7 @@ Container.prototype._registerSpec = function(id, mod, hsource) {
spec = new LiteralSpec(id, [], mod);
break;
}

spec._hsource = hsource;
this._specs[spec.id] = spec;
}
Expand Down
21 changes: 21 additions & 0 deletions test/integration/node/devices.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,27 @@ describe('integration of Node loader', function() {
});
});


describe('creating tablet (es6 module)', function() {
var obj = container.create('devices/tablet');

it('should create an object', function() {
expect(obj).to.be.an('object');
expect(obj.constructor.name).to.equal('Tablet');
});

it('should conform to interface', function() {
expect(obj.cpu.type).to.equal('ARM');
expect(obj.screen.resolution).to.equal('320x480');
});

it('should create unique instances', function() {
var obj2 = container.create('devices/tablet');
expect(obj).to.not.be.equal(obj2);
});

});

describe('creating phone', function() {
var obj = container.create('devices/phone');

Expand Down
16 changes: 16 additions & 0 deletions test/integration/node/objects/devices/tablet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

Object.defineProperty(exports, "__esModule", {
value: true
});

exports.default = function (cpu, screen) {
return new Tablet(cpu, screen);
};

function Tablet(cpu, screen) {
this.cpu = cpu;
this.screen = screen;
}

exports['@require'] = ['devices/cpu/arm', 'devices/screen/touch'];