Skip to content

Commit

Permalink
Make .containDeep more strict to avoid potential misunderstanding.
Browse files Browse the repository at this point in the history
  • Loading branch information
btd committed Jan 14, 2014
1 parent 2f301cd commit 068f57d
Show file tree
Hide file tree
Showing 15 changed files with 368 additions and 347 deletions.
1 change: 1 addition & 0 deletions History.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Breaking change: .keys now check as is - no keys in args means no keys in object
* Deprecated: assert extension
* Deprecated: .include and .includeEql
* Now all assertions define only positive cases, should.js take care about negations and chains

2.1.1 / 2013-12-05
==================
Expand Down
26 changes: 17 additions & 9 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ should.be.exactly(window);
```

*should.js* uses EcmaScript 5 very extensively so any browser that support ES5 is supported. (IE <=8 not supported).
See [kangax's compat table](http://kangax.github.io/es5-compat-table) to know which exactly.

You can easy install it with again npm or bower:
```
Expand Down Expand Up @@ -370,7 +371,6 @@ Assert given value to contain something *.eql* to otherValue. See examples to un
[[1],[2],[3, 4]].should.not.containEql([3]);

({ b: 10 }).should.containEql({ b: 10 });
[1, 2, 3].should.containEql(1);
([1, 2, { a: 10 }]).should.containEql({ a: 10 });
[1, 2, 3].should.not.containEql({ a: 1 });

Expand All @@ -380,24 +380,32 @@ Assert given value to contain something *.eql* to otherValue. See examples to un

## .containDeep(otherValue)

Assert given value to contain something *.eql* to otherValue within depth. Again see examples:
Assert given value to contain something *.eql* to otherValue within depth.
Again see examples:

```javascript
'hello boy'.should.containDeep('boy');
[1,2,3].should.containDeep(3);
[1,2,3].should.containDeep([3]);
[1,2,3].should.containDeep([1, 3]);
//but not
[1,2,3].should.containDeep([3, 1]);

({ a: { b: 10 }, b: { c: 10, d: 11, a: { b: 10, c: 11} }}).should
.containDeep({ a: { b: 10 }, b: { c: 10, a: { c: 11 }}});

[1, 2, 3, { a: { b: { d: 12 }}}].should.containDeep({ a: { b: {d: 12}}});
[1, 2, 3, { a: { b: { d: 12 }}}].should.containDeep([{ a: { b: {d: 12}}}]);

[[1],[2],[3]].should.containDeep([3]);
[[1],[2],[3, 4]].should.containDeep([3]);
[{a: 'a'}, {b: 'b', c: 'c'}].should.containDeep({a: 'a'});
[{a: 'a'}, {b: 'b', c: 'c'}].should.containDeep({b: 'b'});
[[1],[2],[3]].should.containDeep([[3]]);
[[1],[2],[3, 4]].should.containDeep([[3]]);
[{a: 'a'}, {b: 'b', c: 'c'}].should.containDeep([{a: 'a'}]);
[{a: 'a'}, {b: 'b', c: 'c'}].should.containDeep([{b: 'b'}]);
```

It does not search somewhere in depth it check all pattern in depth. It is important meaning.
It does not search somewhere in depth it check all pattern in depth. Object checked
by properties key and value, arrays checked like sub sequences. Everyting compared using .eql.
Main difference with `.containEql` is that this assertion require full type chain -
if asserted value is an object, otherValue should be also an object (which is sub object of given).
The same true for arrays, otherValue should be an array which compared to be subsequence of given object.

## .match(otherValue)

Expand Down
10 changes: 4 additions & 6 deletions lib/ext/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ module.exports = function(should) {
should.exist = should.exists = function(obj, msg) {
if(null == obj) {
throw new AssertionError({
message: msg || ('expected ' + i(obj) + ' to exist')
, stackStartFunction: should.exist
message: msg || ('expected ' + i(obj) + ' to exist'), stackStartFunction: should.exist
});
}
};
Expand All @@ -48,11 +47,10 @@ module.exports = function(should) {
*/

should.not = {};
should.not.exist = should.not.exists = function(obj, msg){
if (null != obj) {
should.not.exist = should.not.exists = function(obj, msg) {
if(null != obj) {
throw new AssertionError({
message: msg || ('expected ' + i(obj) + ' to not exist')
, stackStartFunction: should.not.exist
message: msg || ('expected ' + i(obj) + ' to not exist'), stackStartFunction: should.not.exist
});
}
};
Expand Down
2 changes: 1 addition & 1 deletion lib/ext/bool.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports = function(should, Assertion) {
}, true);

Assertion.add('ok', function() {
this.params = { operator: 'to be truthy' };
this.params = { operator: 'to be truthy' };

this.assert(this.obj);
}, true);
Expand Down
28 changes: 15 additions & 13 deletions lib/ext/deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,29 @@
*/

var util = require('../util'),
eql = require('../eql');
eql = require('../eql');

module.exports = function (should, Assertion) {
var i = should.format;
Assertion.add('include', function(obj, description){
if (!Array.isArray(this.obj) && !util.isString(this.obj)){
this.params = { operator: 'to include an object equal to ' + i(obj), message: description };
module.exports = function(should, Assertion) {
var i = should.format;

Assertion.add('include', function(obj, description) {
if(!Array.isArray(this.obj) && !util.isString(this.obj)) {
this.params = { operator: 'to include an object equal to ' + i(obj), message: description };
var cmp = {};
for (var key in obj) cmp[key] = this.obj[key];
for(var key in obj) cmp[key] = this.obj[key];
this.assert(eql(cmp, obj));
} else {
this.params = { operator: 'to include ' + i(obj), message: description };
this.params = { operator: 'to include ' + i(obj), message: description };

this.assert(~this.obj.indexOf(obj));
}
})
});

Assertion.add('includeEql', function(obj, description) {
this.params = { operator: 'to include an object equal to ' + i(obj), message: description };
this.params = { operator: 'to include an object equal to ' + i(obj), message: description };

this.assert(this.obj.some(function(item) { return eql(obj, item); }));
this.assert(this.obj.some(function(item) {
return eql(obj, item);
}));
});
}
};
30 changes: 15 additions & 15 deletions lib/ext/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
*/

module.exports = function(should, Assertion) {
var i = should.format;
var i = should.format;

Assertion.add('throw', function(message) {
Assertion.add('throw', function(message) {
var fn = this.obj
, err = {}
, errorInfo = ''
Expand All @@ -16,36 +16,36 @@ module.exports = function(should, Assertion) {
try {
fn();
ok = false;
} catch (e) {
} catch(e) {
err = e;
}

if (ok) {
if ('string' == typeof message) {
if(ok) {
if('string' == typeof message) {
ok = message == err.message;
} else if (message instanceof RegExp) {
} else if(message instanceof RegExp) {
ok = message.test(err.message);
} else if ('function' == typeof message) {
} else if('function' == typeof message) {
ok = err instanceof message;
}

if (message && !ok) {
if ('string' == typeof message) {
if(message && !ok) {
if('string' == typeof message) {
errorInfo = " with a message matching '" + message + "', but got '" + err.message + "'";
} else if (message instanceof RegExp) {
} else if(message instanceof RegExp) {
errorInfo = " with a message matching " + message + ", but got '" + err.message + "'";
} else if ('function' == typeof message) {
} else if('function' == typeof message) {
errorInfo = " of type " + message.name + ", but got " + err.constructor.name;
}
} else {
errorInfo = " (got "+i(err)+")";
}
errorInfo = " (got " + i(err) + ")";
}
}

this.params = { operator: 'to throw exception' + errorInfo };

this.assert(ok);
});

Assertion.alias('throw', 'throwError');
}
Assertion.alias('throw', 'throwError');
};
17 changes: 8 additions & 9 deletions lib/ext/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,27 @@
//var statusCodes = require('http').STATUS_CODES;

module.exports = function(should, Assertion) {
var i = should.format;

Assertion.add('header', function(field, val){
Assertion.add('header', function(field, val) {
this
.have.property('headers')
.and.have.property(field.toLowerCase(), val);
});

Assertion.add('status', function(code) {
//this.params = { operator: 'to have response code ' + code + ' ' + i(statusCodes[code])
//this.params = { operator: 'to have response code ' + code + ' ' + i(statusCodes[code])
// + ', but got ' + this.obj.statusCode + ' ' + i(statusCodes[this.obj.statusCode]) }

this.have.property('statusCode', code);
})
});

Assertion.add('json', function() {
this.have.property('headers')
.and.have.property('content-type').include('application/json');
}, true)
.and.have.property('content-type').include('application/json');
}, true);

Assertion.add('html', function() {
this.have.property('headers')
.and.have.property('content-type').include('text/html');
}, true)
}
.and.have.property('content-type').include('text/html');
}, true);
};
Loading

0 comments on commit 068f57d

Please sign in to comment.