Skip to content

Commit

Permalink
Merge pull request #496 from astorije/astorije/frozen-errors
Browse files Browse the repository at this point in the history
Make sure TypeErrors thrown by frozen are caught
  • Loading branch information
keithamus committed Aug 10, 2015
2 parents 7d36b5a + 1cc56c8 commit a42ac43
Show file tree
Hide file tree
Showing 4 changed files with 276 additions and 8 deletions.
53 changes: 47 additions & 6 deletions lib/chai/core/assertions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1429,7 +1429,7 @@ module.exports = function (chai, _) {
, result
);
}

Assertion.addMethod('satisfy', satisfy);
Assertion.addMethod('satisfies', satisfy);

Expand Down Expand Up @@ -1639,7 +1639,7 @@ module.exports = function (chai, _) {
/**
* ### .extensible
*
* Asserts that the target is extensible (can have new properties added to
* Asserts that the target is extensible (can have new properties added to
* it).
*
* var nonExtensibleObject = Object.preventExtensions({});
Expand All @@ -1658,8 +1658,22 @@ module.exports = function (chai, _) {
Assertion.addProperty('extensible', function() {
var obj = flag(this, 'object');

// In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.
// In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
// The following provides ES6 behavior when a TypeError is thrown under ES5.

var isExtensible;

try {
isExtensible = Object.isExtensible(obj);
} catch (err) {
if (err instanceof TypeError) isExtensible = false;
else throw err;
}

this.assert(
Object.isExtensible(obj)
isExtensible
, 'expected #{this} to be extensible'
, 'expected #{this} to not be extensible'
);
Expand All @@ -1685,8 +1699,22 @@ module.exports = function (chai, _) {
Assertion.addProperty('sealed', function() {
var obj = flag(this, 'object');

// In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.
// In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed
// The following provides ES6 behavior when a TypeError is thrown under ES5.

var isSealed;

try {
isSealed = Object.isSealed(obj);
} catch (err) {
if (err instanceof TypeError) isSealed = true;
else throw err;
}

this.assert(
Object.isSealed(obj)
isSealed
, 'expected #{this} to be sealed'
, 'expected #{this} to not be sealed'
);
Expand All @@ -1710,11 +1738,24 @@ module.exports = function (chai, _) {
Assertion.addProperty('frozen', function() {
var obj = flag(this, 'object');

// In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.
// In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen
// The following provides ES6 behavior when a TypeError is thrown under ES5.

var isFrozen;

try {
isFrozen = Object.isFrozen(obj);
} catch (err) {
if (err instanceof TypeError) isFrozen = true;
else throw err;
}

this.assert(
Object.isFrozen(obj)
isFrozen
, 'expected #{this} to be frozen'
, 'expected #{this} to not be frozen'
);
});

};
90 changes: 90 additions & 0 deletions test/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,28 @@ describe('assert', function () {
err(function() {
assert[isExtensible](nonExtensibleObject);
}, 'expected {} to be extensible');

// Making sure ES6-like Object.isExtensible response is respected for all primitive types

err(function() {
assert[isExtensible](42);
}, 'expected 42 to be extensible');

err(function() {
assert[isExtensible](null);
}, 'expected null to be extensible');

err(function() {
assert[isExtensible]('foo');
}, 'expected \'foo\' to be extensible');

err(function() {
assert[isExtensible](false);
}, 'expected false to be extensible');

err(function() {
assert[isExtensible](undefined);
}, 'expected undefined to be extensible');
});
});

Expand All @@ -815,6 +837,14 @@ describe('assert', function () {
err(function() {
assert[isNotExtensible]({});
}, 'expected {} to not be extensible');

// Making sure ES6-like Object.isExtensible response is respected for all primitive types

assert[isNotExtensible](42);
assert[isNotExtensible](null);
assert[isNotExtensible]('foo');
assert[isNotExtensible](false);
assert[isNotExtensible](undefined);
});
});

Expand All @@ -827,6 +857,14 @@ describe('assert', function () {
err(function() {
assert[isSealed]({});
}, 'expected {} to be sealed');

// Making sure ES6-like Object.isSealed response is respected for all primitive types

assert[isSealed](42);
assert[isSealed](null);
assert[isSealed]('foo');
assert[isSealed](false);
assert[isSealed](undefined);
});
});

Expand All @@ -839,6 +877,28 @@ describe('assert', function () {
err(function() {
assert[isNotSealed](sealedObject);
}, 'expected {} to not be sealed');

// Making sure ES6-like Object.isSealed response is respected for all primitive types

err(function() {
assert[isNotSealed](42);
}, 'expected 42 to not be sealed');

err(function() {
assert[isNotSealed](null);
}, 'expected null to not be sealed');

err(function() {
assert[isNotSealed]('foo');
}, 'expected \'foo\' to not be sealed');

err(function() {
assert[isNotSealed](false);
}, 'expected false to not be sealed');

err(function() {
assert[isNotSealed](undefined);
}, 'expected undefined to not be sealed');
});
});

Expand All @@ -851,6 +911,14 @@ describe('assert', function () {
err(function() {
assert[isFrozen]({});
}, 'expected {} to be frozen');

// Making sure ES6-like Object.isFrozen response is respected for all primitive types

assert[isFrozen](42);
assert[isFrozen](null);
assert[isFrozen]('foo');
assert[isFrozen](false);
assert[isFrozen](undefined);
});
});

Expand All @@ -863,6 +931,28 @@ describe('assert', function () {
err(function() {
assert[isNotFrozen](frozenObject);
}, 'expected {} to not be frozen');

// Making sure ES6-like Object.isFrozen response is respected for all primitive types

err(function() {
assert[isNotFrozen](42);
}, 'expected 42 to not be frozen');

err(function() {
assert[isNotFrozen](null);
}, 'expected null to not be frozen');

err(function() {
assert[isNotFrozen]('foo');
}, 'expected \'foo\' to not be frozen');

err(function() {
assert[isNotFrozen](false);
}, 'expected false to not be frozen');

err(function() {
assert[isNotFrozen](undefined);
}, 'expected undefined to not be frozen');
});
});
});
85 changes: 84 additions & 1 deletion test/expect.js
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,34 @@ describe('expect', function () {
err(function() {
expect({}).to.not.be.extensible;
}, 'expected {} to not be extensible');

// Making sure ES6-like Object.isExtensible response is respected for all primitive types

expect(42).to.not.be.extensible;
expect(null).to.not.be.extensible;
expect('foo').to.not.be.extensible;
expect(false).to.not.be.extensible;
expect(undefined).to.not.be.extensible;

err(function() {
expect(42).to.be.extensible;
}, 'expected 42 to be extensible');

err(function() {
expect(null).to.be.extensible;
}, 'expected null to be extensible');

err(function() {
expect('foo').to.be.extensible;
}, 'expected \'foo\' to be extensible');

err(function() {
expect(false).to.be.extensible;
}, 'expected false to be extensible');

err(function() {
expect(undefined).to.be.extensible;
}, 'expected undefined to be extensible');
});

it('sealed', function() {
Expand All @@ -1108,6 +1136,34 @@ describe('expect', function () {
err(function() {
expect(sealedObject).to.not.be.sealed;
}, 'expected {} to not be sealed');

// Making sure ES6-like Object.isSealed response is respected for all primitive types

expect(42).to.be.sealed;
expect(null).to.be.sealed;
expect('foo').to.be.sealed;
expect(false).to.be.sealed;
expect(undefined).to.be.sealed;

err(function() {
expect(42).to.not.be.sealed;
}, 'expected 42 to not be sealed');

err(function() {
expect(null).to.not.be.sealed;
}, 'expected null to not be sealed');

err(function() {
expect('foo').to.not.be.sealed;
}, 'expected \'foo\' to not be sealed');

err(function() {
expect(false).to.not.be.sealed;
}, 'expected false to not be sealed');

err(function() {
expect(undefined).to.not.be.sealed;
}, 'expected undefined to not be sealed');
});

it('frozen', function() {
Expand All @@ -1123,6 +1179,33 @@ describe('expect', function () {
err(function() {
expect(frozenObject).to.not.be.frozen;
}, 'expected {} to not be frozen');
});

// Making sure ES6-like Object.isFrozen response is respected for all primitive types

expect(42).to.be.frozen;
expect(null).to.be.frozen;
expect('foo').to.be.frozen;
expect(false).to.be.frozen;
expect(undefined).to.be.frozen;

err(function() {
expect(42).to.not.be.frozen;
}, 'expected 42 to not be frozen');

err(function() {
expect(null).to.not.be.frozen;
}, 'expected null to not be frozen');

err(function() {
expect('foo').to.not.be.frozen;
}, 'expected \'foo\' to not be frozen');

err(function() {
expect(false).to.not.be.frozen;
}, 'expected false to not be frozen');

err(function() {
expect(undefined).to.not.be.frozen;
}, 'expected undefined to not be frozen');
});
});

0 comments on commit a42ac43

Please sign in to comment.