Permalink
Browse files

added assert support for different input format

  • Loading branch information...
james-huston committed Dec 2, 2012
1 parent 3714d15 commit bf47dcb8416033f5fda5bcb93b67df10a5ab50bf
Showing with 167 additions and 4 deletions.
  1. +1 −0 .gitignore
  2. +37 −2 lib/ruler.js
  3. +129 −2 test/test.js
View
@@ -1,3 +1,4 @@
node_modules
components
build
+nbproject
View
@@ -25,18 +25,48 @@ function Ruler(rules){
else this[obj.cmp](obj.path, obj.value)
}, this);
}
+
+ this.path = null;
+ this.parent = null;
+ this.assertStack = [];
}
/**
* Tests the `obj` against the "rule" `stack`.
*/
Ruler.prototype.test = function(obj){
+ this.flattenStacks();
+
return this.stack.every(function(fn){
return fn(obj);
});
};
+Ruler.prototype.flattenStacks = function() {
+ if (this.assertStack.length) {
+ var self = this;
+ this.assertStack.forEach(function(assertObj) {
+ self.stack = self.stack.concat(assertObj.stack);
+ });
+ }
+};
+
+Ruler.prototype.assert = function(path){
+ var assertRuler = new Ruler();
+ assertRuler.path = path;
+
+ if (this.parent) {
+ assertRuler.parent = this.parent;
+ this.parent.assertStack.push(assertRuler);
+ } else {
+ assertRuler.parent = this;
+ this.assertStack.push(assertRuler);
+ }
+
+ return assertRuler;
+};
+
/**
* Pushes a "rule" function onto the `stack`.
*/
@@ -65,7 +95,12 @@ Object
.keys(comparators)
.forEach(function(key){
Ruler.prototype[key] = function(path, value){
- this.use(comparators[key], path, value);
- return this;
+ if (this.path) {
+ this.use(comparators[key], this.path, path);
+ return this;
+ } else {
+ this.use(comparators[key], path, value);
+ return this;
+ }
};
});
View
@@ -1,5 +1,7 @@
-var ruler = require('..');
+var ruler = require('..')
+ , assert = require('assert');
+;
describe('.ruler(arr)', function(){
describe('when initialized with key/val rules', function(){
@@ -39,4 +41,129 @@ describe('.ruler()', function(){
result.should.equal(true);
});
});
-});
+});
+
+describe('.ruler().assert(path)', function(){
+ describe('on first assert chain', function(){
+ var engine = ruler();
+ engine.assert('name');
+
+ it('should have an assertStack of length 1', function() {
+ engine.assertStack.should.have.length(1);
+ });
+
+ it('should have the first element of type ruler', function() {
+ engine.assertStack[0].should.be.an.instanceof(ruler);
+ });
+
+ it('should have the path of "name" on the first stack element', function() {
+ engine.assertStack[0].path.should.equal('name');
+ });
+ });
+
+ describe('on second assert chain', function(){
+ var engine = ruler();
+ engine
+ .assert('name')
+ .assert('age');
+
+ it('should have an assertStack with 2 rulers', function(){
+ engine.assertStack.should.have.length(2);
+ });
+
+ it('should have a path of "name" on the first stack element', function() {
+ engine.assertStack[0].should.be.an.instanceof(ruler);
+ engine.assertStack[0].path.should.equal('name');
+ });
+
+ it('should have a path of "age" on the second stack element', function() {
+ engine.assertStack[1].should.be.an.instanceof(ruler);
+ engine.assertStack[1].path.should.equal('age');
+ });
+ });
+
+ describe('when initialized', function() {
+ var engine = ruler();
+ assert.equal(null, engine.parent);
+
+ it('should have its parent set to ruler', function() {
+ engine.assert('name');
+ engine.assertStack[0].parent.should.equal(engine);
+ });
+ });
+
+ describe('when chained with 2 simple passing tests', function() {
+ var engine = ruler();
+ engine
+ .assert('name').is('jane')
+ .assert('age').gt(10);
+
+ var result = engine.test({
+ name: 'jane'
+ , age: 21
+ , sex: 'yes please'
+ });
+
+ it('shoud return true', function() {
+ result.should.equal(true);
+ });
+ });
+});
+
+describe('.ruler().assert(path).is()', function(){
+ describe('when called', function(){
+ var engine = ruler();
+ engine.assert('name').is('bob');
+
+ it('should attach to rulers first assertStack.stack', function() {
+ engine.assertStack[0].stack.should.have.length(1);
+ engine.assertStack[0].stack[0].should.be.a('function');
+ });
+ });
+});
+
+describe('.ruler().flattenStacks', function() {
+ describe('when called with a single assert', function() {
+ var engine = ruler();
+ engine.assert('name').is('bob');
+
+ it('properly attached the action to the child', function() {
+ engine.stack.should.have.length(0);
+ engine.assertStack[0].stack.should.have.length(1);
+
+ engine.flattenStacks();
+ });
+
+ it('maintained the stack on the child', function() {
+ engine.assertStack[0].stack.should.have.length(1);
+ engine.assertStack[0].stack[0].should.be.a('function');
+ engine.stack.should.have.length(1);
+ });
+
+ it('copied the function to the main stack', function() {
+ engine.stack[0].should.be.a('function');
+ engine.stack[0].should.equal(engine.assertStack[0].stack[0]);
+ });
+
+ });
+});
+
+describe('.ruler().assert(path).is(value)', function() {
+ describe('when called with passing test', function() {
+ var engine = ruler();
+ engine.assert('name').is('bob');
+
+ var result = engine.test({
+ name: "bob"
+ });
+
+ it('will return true', function() {
+ result.should.equal(true);
+ });
+
+ it('will still have the stack on all assert objects', function() {
+ engine.assertStack[0].stack[0].should.be.a('function');
+ });
+ });
+});
+

0 comments on commit bf47dcb

Please sign in to comment.