Skip to content

Commit

Permalink
Merge pull request #140 from RubenVerborgh/function-prototype
Browse files Browse the repository at this point in the history
Restore the `call` and `apply` methods when adding a chainable method
  • Loading branch information
logicalparadox committed Feb 15, 2013
2 parents baf576d + caf2a15 commit 039d8c6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
10 changes: 9 additions & 1 deletion lib/chai/utils/addChainableMethod.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ var hasProtoSupport = '__proto__' in Object;
// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).
var excludeNames = /^(?:length|name|arguments|caller)$/;

// Cache `Function` properties
var call = Function.prototype.call,
apply = Function.prototype.apply;

/**
* ### addChainableMethod (ctx, name, method, chainingBehavior)
*
Expand Down Expand Up @@ -65,7 +69,11 @@ module.exports = function (ctx, name, method, chainingBehavior) {

// Use `__proto__` if available
if (hasProtoSupport) {
assert.__proto__ = this;
// Inherit all properties from the object by replacing the `Function` prototype
var prototype = assert.__proto__ = Object.create(this);
// Restore the `call` and `apply` methods from `Function`
prototype.call = call;
prototype.apply = apply;
}
// Otherwise, redefine all properties (slow!)
else {
Expand Down
9 changes: 9 additions & 0 deletions test/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ suite('utilities', function () {
new chai.Assertion(this._obj).to.be.equal('x');
}
, function () {
this._obj = this._obj || {};
this._obj.__x = 'X!'
}
);
Expand All @@ -228,6 +229,14 @@ suite('utilities', function () {
expect("foo").x();
}).to.throw(_chai.AssertionError);

// Verify whether the original Function properties are present.
// see https://github.com/chaijs/chai/commit/514dd6ce4#commitcomment-2593383
var propertyDescriptor = Object.getOwnPropertyDescriptor(chai.Assertion.prototype, "x");
expect(propertyDescriptor.get).to.have.property("call", Function.prototype.call);
expect(propertyDescriptor.get).to.have.property("apply", Function.prototype.apply);
expect(propertyDescriptor.get()).to.have.property("call", Function.prototype.call);
expect(propertyDescriptor.get()).to.have.property("apply", Function.prototype.apply);

var obj = {};
expect(obj).x.to.be.ok;
expect(obj).to.have.property('__x', 'X!');
Expand Down

0 comments on commit 039d8c6

Please sign in to comment.