Skip to content

Commit

Permalink
Add ownPropertyDescriptor assertion.
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Mar 30, 2015
1 parent 57df388 commit 5e1e680
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
49 changes: 49 additions & 0 deletions lib/chai/core/assertions.js
Expand Up @@ -888,6 +888,55 @@ module.exports = function (chai, _) {
Assertion.addMethod('ownProperty', assertOwnProperty);
Assertion.addMethod('haveOwnProperty', assertOwnProperty);

/**
* ### .ownPropertyDescriptor(name[, descriptor[, message]])
*
* Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.
*
* expect('test').to.have.ownPropertyDescriptor('length');
* expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });
* expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });
* expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);
* expect('test').ownPropertyDescriptor('length').to.have.keys('value');
*
* @name ownPropertyDescriptor
* @alias haveOwnPropertyDescriptor
* @param {String} name
* @param {Object} descriptor _optional_
* @param {String} message _optional_
* @api public
*/

function assertOwnPropertyDescriptor (name, descriptor, msg) {
if (typeof descriptor === 'string') {
msg = descriptor;
descriptor = null;
}
if (msg) flag(this, 'message', msg);
var obj = flag(this, 'object');
var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);
if (actualDescriptor && descriptor) {
this.assert(
_.eql(descriptor, actualDescriptor)
, 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)
, 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)
, descriptor
, actualDescriptor
, true
);
} else {
this.assert(
actualDescriptor
, 'expected #{this} to have an own property descriptor for ' + _.inspect(name)
, 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)
);
}
flag(this, 'object', actualDescriptor);
}

Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);
Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);

/**
* ### .length(value)
*
Expand Down
36 changes: 35 additions & 1 deletion test/expect.js
Expand Up @@ -467,7 +467,7 @@ describe('expect', function () {
err(function(){
expect(deepObj).to.have.deep.property('teas[3].tea', 'bar');
}, "expected { Object (green, teas) } to have a deep property 'teas[3].tea'");

var arr = [
[ 'chai', 'matcha', 'konacha' ]
, [ { tea: 'chai' }
Expand Down Expand Up @@ -531,6 +531,40 @@ describe('expect', function () {
}, "blah: expected { length: 12 } to not have own property 'length'");
});

it('ownPropertyDescriptor(name)', function(){
expect('test').to.have.ownPropertyDescriptor('length');
expect('test').to.haveOwnPropertyDescriptor('length');
expect('test').not.to.have.ownPropertyDescriptor('foo');

var obj = {};
var descriptor = {
configurable: false,
enumerable: true,
writable: true,
value: NaN
};
Object.defineProperty(obj, 'test', descriptor);
expect(obj).to.have.ownPropertyDescriptor('test', descriptor);
err(function(){
expect(obj).not.to.have.ownPropertyDescriptor('test', descriptor, 'blah');
}, "blah: expected the own property descriptor for 'test' on { test: NaN } to not match { configurable: false,\n enumerable: true,\n writable: true,\n value: NaN }");
err(function(){
var wrongDescriptor = {
configurable: false,
enumerable: true,
writable: false,
value: NaN
};
expect(obj).to.have.ownPropertyDescriptor('test', wrongDescriptor, 'blah');
}, "blah: expected the own property descriptor for 'test' on { test: NaN } to match { configurable: false,\n enumerable: true,\n writable: false,\n value: NaN }, got { value: NaN,\n writable: true,\n enumerable: true,\n configurable: false }");

err(function(){
expect(obj).to.have.ownPropertyDescriptor('test2', 'blah');
}, "blah: expected { test: NaN } to have an own property descriptor for 'test2'");

expect(obj).to.have.ownPropertyDescriptor('test').and.have.property('enumerable', true);
});

it('string()', function(){
expect('foobar').to.have.string('bar');
expect('foobar').to.have.string('foo');
Expand Down
34 changes: 34 additions & 0 deletions test/should.js
Expand Up @@ -396,6 +396,40 @@ describe('should', function() {
}, "blah: expected { length: 12 } to not have own property 'length'");
});

it('ownPropertyDescriptor(name)', function(){
'test'.should.haveOwnPropertyDescriptor('length');
'test'.should.have.ownPropertyDescriptor('length');
'test'.should.not.have.ownPropertyDescriptor('foo');

var obj = { };
var descriptor = {
configurable: false,
enumerable: true,
writable: true,
value: NaN
};
Object.defineProperty(obj, 'test', descriptor);
obj.should.haveOwnPropertyDescriptor('test', descriptor);
err(function(){
obj.should.not.haveOwnPropertyDescriptor('test', descriptor, 'blah');
}, "blah: expected the own property descriptor for 'test' on { test: NaN } to not match { configurable: false,\n enumerable: true,\n writable: true,\n value: NaN }");
err(function(){
var wrongDescriptor = {
configurable: false,
enumerable: true,
writable: false,
value: NaN
};
obj.should.haveOwnPropertyDescriptor('test', wrongDescriptor, 'blah');
}, "blah: expected the own property descriptor for 'test' on { test: NaN } to match { configurable: false,\n enumerable: true,\n writable: false,\n value: NaN }, got { value: NaN,\n writable: true,\n enumerable: true,\n configurable: false }");

err(function(){
obj.should.haveOwnPropertyDescriptor('test2', 'blah');
}, "blah: expected { test: NaN } to have an own property descriptor for 'test2'");

obj.should.have.ownPropertyDescriptor('test').and.have.property('enumerable', true);
});

it('string()', function(){
'foobar'.should.contain.string('bar');
'foobar'.should.contain.string('foo');
Expand Down

0 comments on commit 5e1e680

Please sign in to comment.