Skip to content

Commit

Permalink
Merge pull request #964 from zetamorph/assert-nestedInclude-ownInclude
Browse files Browse the repository at this point in the history
assert: add nestedInclude, deepNestedInclude, ownInclude and deepOwnInclude
  • Loading branch information
keithamus committed May 9, 2017
2 parents f3adfd9 + b744130 commit 0825826
Show file tree
Hide file tree
Showing 4 changed files with 329 additions and 24 deletions.
191 changes: 191 additions & 0 deletions lib/chai/interface/assert.js
Expand Up @@ -1012,6 +1012,197 @@ module.exports = function (chai, util) {
new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc);
};

/**
* ### .nestedInclude(haystack, needle, [message])
*
* Asserts that 'haystack' includes 'needle'.
* Can be used to assert the inclusion of a subset of properties in an
* object.
* Enables the use of dot- and bracket-notation for referencing nested
* properties.
* '[]' and '.' in property names can be escaped using double backslashes.
*
* assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'});
* assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'});
*
* @name nestedInclude
* @param {Object} haystack
* @param {Object} needle
* @param {String} message
* @namespace Assert
* @api public
*/

assert.nestedInclude = function (exp, inc, msg) {
new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc);
};

/**
* ### .notNestedInclude(haystack, needle, [message])
*
* Asserts that 'haystack' does not include 'needle'.
* Can be used to assert the absence of a subset of properties in an
* object.
* Enables the use of dot- and bracket-notation for referencing nested
* properties.
* '[]' and '.' in property names can be escaped using double backslashes.
*
* assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'});
* assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'});
*
* @name notNestedInclude
* @param {Object} haystack
* @param {Object} needle
* @param {String} message
* @namespace Assert
* @api public
*/

assert.notNestedInclude = function (exp, inc, msg) {
new Assertion(exp, msg, assert.notNestedInclude, true)
.not.nested.include(inc);
};

/**
* ### .deepNestedInclude(haystack, needle, [message])
*
* Asserts that 'haystack' includes 'needle'.
* Can be used to assert the inclusion of a subset of properties in an
* object while checking for deep equality.
* Enables the use of dot- and bracket-notation for referencing nested
* properties.
* '[]' and '.' in property names can be escaped using double backslashes.
*
* assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}});
* assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}});
*
* @name deepNestedInclude
* @param {Object} haystack
* @param {Object} needle
* @param {String} message
* @namespace Assert
* @api public
*/

assert.deepNestedInclude = function(exp, inc, msg) {
new Assertion(exp, msg, assert.deepNestedInclude, true)
.deep.nested.include(inc);
};

/**
* ### .notDeepNestedInclude(haystack, needle, [message])
*
* Asserts that 'haystack' does not include 'needle'.
* Can be used to assert the absence of a subset of properties in an
* object while checking for deep equality.
* Enables the use of dot- and bracket-notation for referencing nested
* properties.
* '[]' and '.' in property names can be escaped using double backslashes.
*
* assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}})
* assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}});
*
* @name notDeepNestedInclude
* @param {Object} haystack
* @param {Object} needle
* @param {String} message
* @namespace Assert
* @api public
*/

assert.notDeepNestedInclude = function(exp, inc, msg) {
new Assertion(exp, msg, assert.notDeepNestedInclude, true)
.not.deep.nested.include(inc);
};

/**
* ### .ownInclude(haystack, needle, [message])
*
* Asserts that 'haystack' includes 'needle'.
* Can be used to assert the inclusion of a subset of properties in an
* object while ignoring inherited properties.
*
* assert.ownInclude({ a: 1 }, { a: 1 });
*
* @name ownInclude
* @param {Object} haystack
* @param {Object} needle
* @param {String} message
* @namespace Assert
* @api public
*/

assert.ownInclude = function(exp, inc, msg) {
new Assertion(exp, msg, assert.ownInclude, true).own.include(inc);
};

/**
* ### .notOwnInclude(haystack, needle, [message])
*
* Asserts that 'haystack' includes 'needle'.
* Can be used to assert the absence of a subset of properties in an
* object while ignoring inherited properties.
*
* Object.prototype.b = 2;
*
* assert.notOwnInclude({ a: 1 }, { b: 2 });
*
* @name notOwnInclude
* @param {Object} haystack
* @param {Object} needle
* @param {String} message
* @namespace Assert
* @api public
*/

assert.notOwnInclude = function(exp, inc, msg) {
new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc);
};

/**
* ### .deepOwnInclude(haystack, needle, [message])
*
* Asserts that 'haystack' includes 'needle'.
* Can be used to assert the inclusion of a subset of properties in an
* object while ignoring inherited properties and checking for deep equality.
*
* assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}});
*
* @name deepOwnInclude
* @param {Object} haystack
* @param {Object} needle
* @param {String} message
* @namespace Assert
* @api public
*/

assert.deepOwnInclude = function(exp, inc, msg) {
new Assertion(exp, msg, assert.deepOwnInclude, true)
.deep.own.include(inc);
};

/**
* ### .notDeepOwnInclude(haystack, needle, [message])
*
* Asserts that 'haystack' includes 'needle'.
* Can be used to assert the absence of a subset of properties in an
* object while ignoring inherited properties and checking for deep equality.
*
* assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}});
*
* @name notDeepOwnInclude
* @param {Object} haystack
* @param {Object} needle
* @param {String} message
* @namespace Assert
* @api public
*/

assert.notDeepOwnInclude = function(exp, inc, msg) {
new Assertion(exp, msg, assert.notDeepOwnInclude, true)
.not.deep.own.include(inc);
};

/**
* ### .match(value, regexp, [message])
*
Expand Down
102 changes: 100 additions & 2 deletions test/assert.js
Expand Up @@ -744,8 +744,106 @@ describe('assert', function () {
}, "blah: expected { foo: { a: 1 }, bar: { b: 2 } } to have deep property 'bar' of { b: 9 }, but got { b: 2 }");

err(function () {
assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}});
}, "expected { foo: { a: 1 }, bar: { b: 2 } } to not have deep property 'foo' of { a: 1 }");
assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}, 'blah');
}, "blah: expected { foo: { a: 1 }, bar: { b: 2 } } to not have deep property 'foo' of { a: 1 }");
});

it('nestedInclude and notNestedInclude', function() {
assert.nestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'y'});
assert.notNestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'x'});
assert.notNestedInclude({a: {b: ['x', 'y']}}, {'a.c': 'y'});

assert.notNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}});

assert.nestedInclude({'.a': {'[b]': 'x'}}, {'\\.a.\\[b\\]': 'x'});
assert.notNestedInclude({'.a': {'[b]': 'x'}}, {'\\.a.\\[b\\]': 'y'});

err(function () {
assert.nestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'x'}, 'blah');
}, "blah: expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.b[1]' of 'x', but got 'y'");

err(function () {
assert.nestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'x'}, 'blah');
}, "blah: expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.b[1]' of 'x', but got 'y'");

err(function () {
assert.nestedInclude({a: {b: ['x', 'y']}}, {'a.c': 'y'});
}, "expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.c'");

err(function () {
assert.notNestedInclude({a: {b: ['x', 'y']}}, {'a.b[1]': 'y'}, 'blah');
}, "blah: expected { a: { b: [ 'x', 'y' ] } } to not have nested property 'a.b[1]' of 'y'");
});

it('deepNestedInclude and notDeepNestedInclude', function() {
assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}});
assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 2}});
assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.c': {x: 1}});

assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}});
assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}});

err(function () {
assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 2}}, 'blah');
}, "blah: expected { a: { b: [ [Object] ] } } to have deep nested property 'a.b[0]' of { y: 2 }, but got { x: 1 }");

err(function () {
assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 2}}, 'blah');
}, "blah: expected { a: { b: [ [Object] ] } } to have deep nested property 'a.b[0]' of { y: 2 }, but got { x: 1 }");

err(function () {
assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.c': {x: 1}});
}, "expected { a: { b: [ [Object] ] } } to have deep nested property 'a.c'");

err(function () {
assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}, 'blah');
}, "blah: expected { a: { b: [ [Object] ] } } to not have deep nested property 'a.b[0]' of { x: 1 }");
});

it('ownInclude and notOwnInclude', function() {
assert.ownInclude({a: 1}, {a: 1});
assert.notOwnInclude({a: 1}, {a: 3});
assert.notOwnInclude({a: 1}, {'toString': Object.prototype.toString});

assert.notOwnInclude({a: {b: 2}}, {a: {b: 2}});

err(function () {
assert.ownInclude({a: 1}, {a: 3}, 'blah');
}, "blah: expected { a: 1 } to have own property 'a' of 3, but got 1");

err(function () {
assert.ownInclude({a: 1}, {a: 3}, 'blah');
}, "blah: expected { a: 1 } to have own property 'a' of 3, but got 1");

err(function () {
assert.ownInclude({a: 1}, {'toString': Object.prototype.toString});
}, "expected { a: 1 } to have own property 'toString'");

err(function () {
assert.notOwnInclude({a: 1}, {a: 1}, 'blah');
}, "blah: expected { a: 1 } to not have own property 'a' of 1");
});

it('deepOwnInclude and notDeepOwnInclude', function() {
assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}});
assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}});
assert.notDeepOwnInclude({a: {b: 2}}, {'toString': Object.prototype.toString});

err(function () {
assert.deepOwnInclude({a: {b: 2}}, {a: {c: 3}}, 'blah');
}, "blah: expected { a: { b: 2 } } to have deep own property 'a' of { c: 3 }, but got { b: 2 }");

err(function () {
assert.deepOwnInclude({a: {b: 2}}, {a: {c: 3}}, 'blah');
}, "blah: expected { a: { b: 2 } } to have deep own property 'a' of { c: 3 }, but got { b: 2 }");

err(function () {
assert.deepOwnInclude({a: {b: 2}}, {'toString': Object.prototype.toString});
}, "expected { a: { b: 2 } } to have deep own property 'toString'");

err(function () {
assert.notDeepOwnInclude({a: {b: 2}}, {a: {b: 2}}, 'blah');
}, "blah: expected { a: { b: 2 } } to not have deep own property 'a' of { b: 2 }");
});

it('keys(array|Object|arguments)', function(){
Expand Down
40 changes: 28 additions & 12 deletions test/expect.js
Expand Up @@ -1797,16 +1797,16 @@ describe('expect', function () {
}, "blah: expected [ { a: 1 }, { b: 2 } ] to deep include { a: 9 }");

err(function () {
expect([obj1, obj2]).to.not.deep.include({a: 1});
}, "expected [ { a: 1 }, { b: 2 } ] to not deep include { a: 1 }");
expect([obj1, obj2], 'blah').to.not.deep.include({a: 1});
}, "blah: expected [ { a: 1 }, { b: 2 } ] to not deep include { a: 1 }");

err(function () {
expect({foo: obj1, bar: obj2}).to.deep.include({foo: {a: 1}, bar: {b: 9}});
}, "expected { foo: { a: 1 }, bar: { b: 2 } } to have deep property 'bar' of { b: 9 }, but got { b: 2 }");

err(function () {
expect({foo: obj1, bar: obj2}).to.not.deep.include({foo: {a: 1}, bar: {b: 2}});
}, "expected { foo: { a: 1 }, bar: { b: 2 } } to not have deep property 'foo' of { a: 1 }");
expect({foo: obj1, bar: obj2}).to.not.deep.include({foo: {a: 1}, bar: {b: 2}}, 'blah');
}, "blah: expected { foo: { a: 1 }, bar: { b: 2 } } to not have deep property 'foo' of { a: 1 }");
});

it('nested.include()', function () {
Expand All @@ -1832,8 +1832,12 @@ describe('expect', function () {
}, "expected { a: { b: [ 'x', 'y' ] } } to have nested property 'a.c'");

err(function () {
expect({a: {b: ['x', 'y']}}).to.not.nested.include({'a.b[1]': 'y'});
}, "expected { a: { b: [ 'x', 'y' ] } } to not have nested property 'a.b[1]' of 'y'");
expect({a: {b: ['x', 'y']}}).to.not.nested.include({'a.b[1]': 'y'}, 'blah');
}, "blah: expected { a: { b: [ 'x', 'y' ] } } to not have nested property 'a.b[1]' of 'y'");

err(function () {
expect({a: {b: ['x', 'y']}}, 'blah').to.not.nested.include({'a.b[1]': 'y'});
}, "blah: expected { a: { b: [ 'x', 'y' ] } } to not have nested property 'a.b[1]' of 'y'");
});

it('deep.nested.include()', function () {
Expand All @@ -1859,8 +1863,12 @@ describe('expect', function () {
}, "expected { a: { b: [ [Object] ] } } to have deep nested property 'a.c'");

err(function () {
expect({a: {b: [{x: 1}]}}).to.not.deep.nested.include({'a.b[0]': {x: 1}});
}, "expected { a: { b: [ [Object] ] } } to not have deep nested property 'a.b[0]' of { x: 1 }");
expect({a: {b: [{x: 1}]}}).to.not.deep.nested.include({'a.b[0]': {x: 1}}, 'blah');
}, "blah: expected { a: { b: [ [Object] ] } } to not have deep nested property 'a.b[0]' of { x: 1 }");

err(function () {
expect({a: {b: [{x: 1}]}}, 'blah').to.not.deep.nested.include({'a.b[0]': {x: 1}});
}, "blah: expected { a: { b: [ [Object] ] } } to not have deep nested property 'a.b[0]' of { x: 1 }");
});

it('own.include()', function () {
Expand All @@ -1883,8 +1891,12 @@ describe('expect', function () {
}, "expected { a: 1 } to have own property 'toString'");

err(function () {
expect({a: 1}).to.not.own.include({a: 1});
}, "expected { a: 1 } to not have own property 'a' of 1");
expect({a: 1}).to.not.own.include({a: 1}, 'blah');
}, "blah: expected { a: 1 } to not have own property 'a' of 1");

err(function () {
expect({a: 1}, 'blah').to.not.own.include({a: 1});
}, "blah: expected { a: 1 } to not have own property 'a' of 1");
});

it('deep.own.include()', function () {
Expand All @@ -1906,8 +1918,12 @@ describe('expect', function () {
}, "expected { a: { b: 2 } } to have deep own property 'toString'");

err(function () {
expect({a: {b: 2}}).to.not.deep.own.include({a: {b: 2}});
}, "expected { a: { b: 2 } } to not have deep own property 'a' of { b: 2 }");
expect({a: {b: 2}}).to.not.deep.own.include({a: {b: 2}}, 'blah');
}, "blah: expected { a: { b: 2 } } to not have deep own property 'a' of { b: 2 }");

err(function () {
expect({a: {b: 2}}, 'blah').to.not.deep.own.include({a: {b: 2}});
}, "blah: expected { a: { b: 2 } } to not have deep own property 'a' of { b: 2 }");
});

it('keys(array|Object|arguments)', function(){
Expand Down

0 comments on commit 0825826

Please sign in to comment.