freight.js
Version:
An simple CommonJS dependency injection container for both node.js and the browser (using browserify)
268 lines (182 loc) • 6.89 kB
JavaScript
var Freight = require('./../src/freight.js');
var Definition = require('./../src/definition.js');
var carsConfig = require('./examples/cars.json');
var invalidConfig = require('./examples/invalid.json');
var castleConfig = require('./examples/castle.json');
describe('Freight', function(){
var f;
beforeEach(function(){
f = new Freight();
});
describe('#construct()', function(){
it('should initialize members', function(){
var def = new Definition('car', carsConfig.car, f);
def.id.should.equal('car');
def.shared.should.equal(false);
(typeof def.fn).should.equal('function');
var def2 = new Definition('engine', carsConfig.engine, f);
def2.shared.should.equal(true);
var def3 = new Definition('engine', {
"shared": "false",
"factoryFn": ":engine_factory"
}, f);
def3.shared.should.equal(false);
});
it('callable should create valid instances as constructor', function(){
var Car = function(a, b){
a.should.equal('a');
b.should.equal('b');
};
f.setParameter('car_class', 'a');
var def = new Definition('car', carsConfig.car, f);
def.args = ['a', 'b'];
(function(){
var car = def.fn(); //parameter is a string instead of a function
}).should.throw();
f.setParameter('car_class', Car);
var car = def.fn();
car.should.be.an.instanceOf(Car);
});
it('callable should create valid instances as factory', function(){
var Engine = function(){};
f.setParameter('engine_factory', 'a');
var def = new Definition('engine', carsConfig.engine, f);
(function(){
var engine = def.fn(); //parameter is a string instead of a function
}).should.throw();
f.setParameter('engine_factory', function(){ return new Engine(); });
var engine = def.fn();
engine.should.be.an.instanceOf(Engine);
});
});
describe('#configure()', function(){
it('Should throw on invalid configuration', function(){
(function(){
new Definition('invalid1', invalidConfig.invalid1, f); //no factory or constructor
}).should.throw();
(function(){
new Definition('invalid2', invalidConfig.invalid2, f); //factory/cls must be a string
}).should.throw();
(function(){
new Definition('invalid3', invalidConfig.invalid3, f); //factory/cls should not be both defined
}).should.throw();
(function(){
new Definition('invalid4', invalidConfig.invalid4, f); //arguments not as array
}).should.throw();
(function(){
new Definition('invalid5', invalidConfig.invalid5, f); //arguments not as array
}).should.throw();
(function(){
new Definition('invalid6', invalidConfig.invalid6, f); //tags not as array
}).should.throw();
});
it('Should add arguments from configuration', function(){
var def = new Definition('car', carsConfig.car, f);
Array.isArray(def.args).should.equal(true);
def.args.length.should.equal(2);
def.args[0].should.equal(':engine');
def.args[1].should.equal(':wheels');
});
});
describe('#addTag()', function(){
it("should increase length and return definition", function(){
var def = new Definition('engine', carsConfig.engine, f);
def.tags.length.should.equal(1);
def.addTag('part');
def.addTag('part');
def.addTag('metal');
def.tags.length.should.equal(3);
});
});
describe('#addArgument()', function(){
it("should increase length and return definition", function(){
var def = new Definition('engine', carsConfig.engine, f);
var def2 = def.addArgument('arg1');
def2.should.equal(def);
def.args.length.should.equal(1);
def.addArgument('arg2');
def.args.length.should.equal(2);
def.args[1].should.equal('arg2');
});
});
describe('#resolveArguments()', function(){
var Engine = function(){};
var engineFactory = function(){
this.should.equal(f);
return new Engine();
};
var Car = function(){};
var Wheels = function(){};
var Castle = function(knight, towers) {
this.knight = knight;
this.towers = towers;
};
var Tower = function(height) {
this.height = height;
return {
height: height,
};
};
var Knight = function(name, sword, attributes) {
this.name = name;
this.sword = sword;
this.attributes = attributes;
};
var Sword = function(name) {
this.name = name;
this.fastenGrip = function() {
this.fastened = true;
};
this.sharpenBlade = function() {
this.sharpened = true;
};
};
it("should increase length and return definition", function(){
var defs = f.registerAll(carsConfig);
f.setParameter('engine_factory', engineFactory);
f.setParameter('wheels_class', Wheels);
var args = defs[0].resolveArguments();
args[0].should.be.an.instanceOf(Engine);
args[1].should.be.an.instanceOf(Wheels);
args = defs[0].resolveArguments(); //doub resolve should not have any consequences
args[0].should.be.an.instanceOf(Engine);
args[1].should.be.an.instanceOf(Wheels);
});
it("should also resolve array arguments", function(){
var defs = f.registerAll(castleConfig);
f.setParameter('castle.class', Castle)
.setParameter('tower.class', Tower)
.setParameter('tower.height', 30)
.setParameter('knight.class', Knight)
.setParameter('knight.quest', 'The holy DI grail')
.setParameter('sword.factory', function(){
var sword = new Sword('Excalibur');
sword.fastenGrip();
sword.sharpenBlade();
return sword;
});
var args = defs[0].resolveArguments();
args[1].length.should.equal(3);
args[1][0].height.should.equal(30);
args[1][1].height.should.equal(30);
args[1][2][1].height.should.equal(30); //test nested
});
it("should also resolve hash arguments", function(){
var defs = f.registerAll(castleConfig);
f.setParameter('castle.class', Castle)
.setParameter('tower.class', Tower)
.setParameter('tower.height', 30)
.setParameter('knight.class', Knight)
.setParameter('knight.quest', 'The holy DI grail')
.setParameter('sword.factory', function(){
var sword = new Sword('Excalibur');
sword.fastenGrip();
sword.sharpenBlade();
return sword;
});
var args = defs[1].resolveArguments();
args[2].quest.should.equal('The holy DI grail');
args[2].tower.height.should.equal(30);
});
});
});