Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

property assertion should only accept strings if nested, fixes #1043 #1044

Merged
merged 10 commits into from Oct 2, 2017
25 changes: 22 additions & 3 deletions lib/chai/core/assertions.js
Expand Up @@ -1763,10 +1763,30 @@ module.exports = function (chai, _) {
, isOwn = flag(this, 'own')
, flagMsg = flag(this, 'message')
, obj = flag(this, 'object')
, ssfi = flag(this, 'ssfi');
, ssfi = flag(this, 'ssfi')
, nameType = typeof name;

flagMsg = flagMsg ? flagMsg + ': ' : '';

if (isNested) {
if (nameType !== 'string') {
throw new AssertionError(
flagMsg + 'the argument to property must be a string when using nested syntax',
undefined,
ssfi
);
}
} else {
if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') {
throw new AssertionError(
flagMsg + 'the argument to property must be a string, number, or symbol',
undefined,
ssfi
);
}
}

if (isNested && isOwn) {
flagMsg = flagMsg ? flagMsg + ': ' : '';
throw new AssertionError(
flagMsg + 'The "nested" and "own" flags cannot be combined.',
undefined,
Expand All @@ -1775,7 +1795,6 @@ module.exports = function (chai, _) {
}

if (obj === null || obj === undefined) {
flagMsg = flagMsg ? flagMsg + ': ' : '';
throw new AssertionError(
flagMsg + 'Target cannot be null or undefined.',
undefined,
Expand Down
13 changes: 13 additions & 0 deletions test/assert.js
Expand Up @@ -1395,6 +1395,7 @@ describe('assert', function () {
var obj = { foo: { bar: 'baz' } };
var simpleObj = { foo: 'bar' };
var undefinedKeyObj = { foo: undefined };
var dummyObj = { a: '1' };
assert.property(obj, 'foo');
assert.property(obj, 'toString');
assert.propertyVal(obj, 'toString', Object.prototype.toString);
Expand Down Expand Up @@ -1454,6 +1455,18 @@ describe('assert', function () {
err(function () {
assert.property(undefined, 'a', 'blah');
}, "blah: Target cannot be null or undefined.");

err(function () {
assert.property({a:1}, {'a':'1'}, 'blah');
}, 'blah: the argument to property must be a string, number, or symbol');

err(function () {
assert.propertyVal(dummyObj, 'a', '2', 'blah');
}, "blah: expected { a: '1' } to have property 'a' of '2', but got '1'");

err(function () {
assert.nestedProperty({a:1}, {'a':'1'}, 'blah');
}, 'blah: the argument to property must be a string when using nested syntax');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more test should be added here to the assert interface tests in order to verify the error message "the argument to property must be a string, number, or symbol". This test can closely resemble the expect({a:1}).to.have.property(null); test that you added on the expect interface, except using the assert interface instead of expect. (And using the err helper function, just like you've done in the previous two tests on the assert interface).

});

it('deepPropertyVal', function () {
Expand Down
8 changes: 8 additions & 0 deletions test/expect.js
Expand Up @@ -1462,6 +1462,10 @@ describe('expect', function () {
err(function () {
expect(undefined, 'blah').to.have.property("a");
}, "blah: Target cannot be null or undefined.");

err(function () {
expect({a:1}, 'blah').to.have.property(null)
}, "blah: the argument to property must be a string, number, or symbol");
});

it('property(name, val)', function(){
Expand Down Expand Up @@ -1755,6 +1759,10 @@ describe('expect', function () {
expect({ 'foo.bar': 'baz' })
.to.have.nested.property('foo.bar');
}, "expected { 'foo.bar': 'baz' } to have nested property 'foo.bar'");

err(function () {
expect({a:1}, 'blah').to.have.nested.property({'a':'1'});
}, "blah: the argument to property must be a string when using nested syntax");
});

it('nested.property(name, val)', function(){
Expand Down
10 changes: 10 additions & 0 deletions test/should.js
Expand Up @@ -1182,6 +1182,10 @@ describe('should', function() {
err(function() {
({a: {b: 1}}).should.have.own.nested.property("a.b");
}, "The \"nested\" and \"own\" flags cannot be combined.");

err(function () {
({a:1}).should.have.property(undefined);
}, "the argument to property must be a string, number, or symbol");
});

it('property(name, val)', function(){
Expand Down Expand Up @@ -1407,6 +1411,12 @@ describe('should', function() {

({ 'foo.bar[]': 'baz'}).should.have.nested.property('foo\\.bar\\[\\]');

({a:1}).should.have.nested.property('a');

err(function(){
({a:1}).should.have.nested.property({'a':'1'});
}, "the argument to property must be a string when using nested syntax");

err(function(){
({ 'foo.bar': 'baz' }).should.have.nested.property('foo.bar');
}, "expected { 'foo.bar': 'baz' } to have nested property 'foo.bar'");
Expand Down