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

Configurable proxy blacklist #774

Merged
merged 3 commits into from
Sep 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 22 additions & 2 deletions lib/chai/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,31 @@ module.exports = {
* chai.config.useProxy = false; // disable use of Proxy
*
* This feature is automatically disabled regardless of this config value
* in environments that don`t support proxies.
* in environments that don't support proxies.
*
* @param {Boolean}
* @api public
*/

useProxy: true
useProxy: true,

/**
* ### config.proxyExcludedKeys
*
* User configurable property, defines which properties should be ignored
* instead of throwing an error if they do not exist on the assertion.
* This is only applied if the environment Chai is running in supports proxies and
* if the `useProxy` configuration setting is enabled.
Copy link
Contributor

Choose a reason for hiding this comment

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

Couple nits:

  • Line 78: Can remove "non-existing" since it's redundant with "if they do not exist on the assertion" later on in the same sentence.
  • Line 80: "running in" instead of "running into".

* By default, `then` and `inspect` will not throw an error if they do not exist on the
* assertion object because the `.inspect` property is read by `util.inspect` (for example, when
* using `console.log` on the assertion object) and `.then` is necessary for promise type-checking.
*
* // By default these keys will not throw an error if they do not exist on the assertion object
* chai.config.proxyExcludedKeys = ['then', 'inspect'];
Copy link
Contributor

Choose a reason for hiding this comment

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

This is probably the best place to add a small note explaining why these two are ignored by default (instead of in proxify.js).

*
* @param {Array}
* @api public
*/

proxyExcludedKeys: ['then', 'inspect']
};
2 changes: 1 addition & 1 deletion lib/chai/utils/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var getEnumerableProperties = require('./getEnumerableProperties');
module.exports = inspect;

/**
* Echos the value of a value. Trys to print the value out
* Echoes the value of a value. Tries to print the value out
* in the best way possible given the different types.
*
* @param {Object} obj The object to print out.
Expand Down
8 changes: 5 additions & 3 deletions lib/chai/utils/proxify.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ module.exports = function proxify (obj) {

return new Proxy(obj, {
get: function getProperty (target, property) {
// Don't throw error on Symbol properties such as Symbol.toStringTag, nor
// on .then because it's necessary for promise type-checking.
// This check is here because we should not throw errors on Symbol properties
// such as `Symbol.toStringTag`.
// The values for which an error should be thrown can be configured using
// the `config.proxyExcludedKeys` setting.
if (typeof property === 'string' &&
property !== 'then' &&
config.proxyExcludedKeys.indexOf(property) === -1 &&
!Reflect.has(target, property))
throw Error('Invalid Chai property: ' + property);

Expand Down
33 changes: 33 additions & 0 deletions test/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,37 @@ describe('configuration', function () {
});
});
});

describe('proxyExcludedKeys', function() {
var readNoExistentProperty = function(prop) {
return function() {
var assertion = expect(false);
expect(assertion).to.not.have.key(prop);
assertion[prop];
}
};

it('should have default value equal to `[\'then\', \'inspect\']`', function() {
expect(chai.config.proxyExcludedKeys).to.be.deep.equal(['then', 'inspect']);
});

it('should not throw when accessing non-existing `then` and `inspect` in an environment with proxy support', function() {
// Since these will not throw if the environment does not support proxies we don't need any `if` clause here
expect(readNoExistentProperty('then')).to.not.throw();
expect(readNoExistentProperty('inspect')).to.not.throw();
});

it('should throw for properties which are not on the `proxyExcludedKeys` Array in an environment with proxy support', function() {
chai.config.proxyExcludedKeys = [];

if (typeof Proxy !== 'undefined' && typeof Reflect !== 'undefined') {
expect(readNoExistentProperty('then')).to.throw('Invalid Chai property: then');
expect(readNoExistentProperty('inspect')).to.throw('Invalid Chai property: inspect');
} else {
expect(readNoExistentProperty('then')).to.not.throw();
expect(readNoExistentProperty('inspect')).to.not.throw();
}
});
});

});