Skip to content

Commit

Permalink
Merge pull request #503 from astorije/astorije/expected-types
Browse files Browse the repository at this point in the history
Checking that argument given to expect is of the right type when using with include
  • Loading branch information
keithamus committed Sep 21, 2015
2 parents df954cc + 1f8c651 commit d7d9420
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 4 deletions.
3 changes: 3 additions & 0 deletions lib/chai/core/assertions.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,12 @@ module.exports = function (chai, _) {
}

function include (val, msg) {
_.expectTypes(this, ['array', 'object', 'string']);

if (msg) flag(this, 'message', msg);
var obj = flag(this, 'object');
var expected = false;

if (_.type(obj) === 'array' && _.type(val) === 'object') {
for (var i in obj) {
if (_.eql(obj[i], val)) {
Expand Down
41 changes: 41 additions & 0 deletions lib/chai/utils/expectTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*!
* Chai - expectTypes utility
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
* MIT Licensed
*/

/**
* ### expectTypes(obj, types)
*
* Ensures that the object being tested against is of a valid type.
*
* utils.expectTypes(this, ['array', 'object', 'string']);
*
* @param {Mixed} obj constructed Assertion
* @param {Array} type A list of allowed types for this assertion
* @name expectTypes
* @api public
*/

var AssertionError = require('assertion-error');
var flag = require('./flag');
var type = require('type-detect');

module.exports = function (obj, types) {
var obj = flag(obj, 'object');
types = types.map(function (t) { return t.toLowerCase(); });
types.sort();

// Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'
var str = types.map(function (t, index) {
var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
return or + art + ' ' + t;
}).join(', ');

if (!types.some(function (expected) { return type(obj) === expected; })) {
throw new AssertionError(
'object tested must be ' + str + ', but ' + type(obj) + ' given'
);
}
};
6 changes: 5 additions & 1 deletion lib/chai/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ exports.test = require('./test');

exports.type = require('type-detect');

/*!
* expectTypes utility
*/
exports.expectTypes = require('./expectTypes');

/*!
* message utility
*/
Expand Down Expand Up @@ -123,4 +128,3 @@ exports.addChainableMethod = require('./addChainableMethod');
*/

exports.overwriteChainableMethod = require('./overwriteChainableMethod');

31 changes: 29 additions & 2 deletions test/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -438,15 +438,42 @@ describe('assert', function () {
assert.include('foobar', 'baz');
}, "expected \'foobar\' to include \'baz\'");

err(function(){
assert.include(true, true);
}, "object tested must be an array, an object, or a string, but boolean given");

err(function () {
assert.include(42, 'bar');
}, "object tested must be an array, an object, or a string, but number given");

err(function(){
assert.include(null, 42);
}, "object tested must be an array, an object, or a string, but null given");

err(function () {
assert.include(undefined, 'bar');
}, "expected undefined to include 'bar'");
}, "object tested must be an array, an object, or a string, but undefined given");
});

it('notInclude', function () {
assert.notInclude('foobar', 'baz');
assert.notInclude([ 1, 2, 3 ], 4);
assert.notInclude(undefined, 'bar');

err(function(){
assert.notInclude(true, true);
}, "object tested must be an array, an object, or a string, but boolean given");

err(function () {
assert.notInclude(42, 'bar');
}, "object tested must be an array, an object, or a string, but number given");

err(function(){
assert.notInclude(null, 42);
}, "object tested must be an array, an object, or a string, but null given");

err(function () {
assert.notInclude(undefined, 'bar');
}, "object tested must be an array, an object, or a string, but undefined given");

err(function () {
assert.notInclude('foobar', 'bar');
Expand Down
32 changes: 32 additions & 0 deletions test/expect.js
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,38 @@ describe('expect', function () {
err(function(){
expect([{a:1},{b:2}]).to.not.include({b:2});
}, "expected [ { a: 1 }, { b: 2 } ] to not include { b: 2 }");

err(function(){
expect(true).to.include(true);
}, "object tested must be an array, an object, or a string, but boolean given");

err(function(){
expect(42.0).to.include(42);
}, "object tested must be an array, an object, or a string, but number given");

err(function(){
expect(null).to.include(42);
}, "object tested must be an array, an object, or a string, but null given");

err(function(){
expect(undefined).to.include(42);
}, "object tested must be an array, an object, or a string, but undefined given");

err(function(){
expect(true).to.not.include(true);
}, "object tested must be an array, an object, or a string, but boolean given");

err(function(){
expect(42.0).to.not.include(42);
}, "object tested must be an array, an object, or a string, but number given");

err(function(){
expect(null).to.not.include(42);
}, "object tested must be an array, an object, or a string, but null given");

err(function(){
expect(undefined).to.not.include(42);
}, "object tested must be an array, an object, or a string, but undefined given");
});

it('keys(array|Object|arguments)', function(){
Expand Down
18 changes: 17 additions & 1 deletion test/should.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,23 @@ describe('should', function() {

err(function(){
({a:1}).should.include({b:2});
}, "expected { a: 1 } to have a property 'b'")
}, "expected { a: 1 } to have a property 'b'");

err(function(){
(true).should.include(true);
}, "object tested must be an array, an object, or a string, but boolean given");

err(function(){
(42).should.include(4);
}, "object tested must be an array, an object, or a string, but number given");

err(function(){
(true).should.not.include(true);
}, "object tested must be an array, an object, or a string, but boolean given");

err(function(){
(42).should.not.include(4);
}, "object tested must be an array, an object, or a string, but number given");
});

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

0 comments on commit d7d9420

Please sign in to comment.