Skip to content
This repository has been archived by the owner on Mar 25, 2022. It is now read-only.

Commit

Permalink
Add proclaim.isEnumerable and proclaim.isNotEnumerable (#59)
Browse files Browse the repository at this point in the history
* Add proclaim.isEnumerable and proclaim.isNotEnumerable

* Ignore lines which are only hit for really old JS engines
  • Loading branch information
JakeChampion committed Nov 28, 2018
1 parent 7bfd8b4 commit 10bcd8d
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,15 @@ Assert that `actual > expected`.
Assert that `actual >= expected`.


### proclaim.isNotEnumerable( obj, property, [message] )

Assert that `obj[property]` is not enumerable.


### proclaim.isEnumerable( obj, property, [message] )

Assert that `obj[property]` is enumerable.

Why?
----

Expand Down
58 changes: 58 additions & 0 deletions lib/proclaim.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,26 @@
}
};

// Assert that a property on an object is not enumerable
proclaim.isNotEnumerable = function(obj, property, msg) {
if (arePropertyDescriptorsSupported()) {
if (hasWorkingGetOwnPropertyDescriptor()) {
proclaim.isFalse(Object.getOwnPropertyDescriptor(obj, property).enumerable, msg);
}
proclaim.isFalse(Object.prototype.propertyIsEnumerable.call(obj, property), msg);
}
};

// Assert that a property on an object is enumerable
proclaim.isEnumerable = function(obj, property, msg) {
if (arePropertyDescriptorsSupported()) {
if (hasWorkingGetOwnPropertyDescriptor()) {
proclaim.isTrue(Object.getOwnPropertyDescriptor(obj, property).enumerable, msg);
}
proclaim.isTrue(Object.prototype.propertyIsEnumerable.call(obj, property), msg);
}
};


// Aliases
// -------
Expand Down Expand Up @@ -359,6 +379,44 @@
// Utilities
// ---------

// Utility for checking whether property descriptors are supported
function arePropertyDescriptorsSupported() {
var obj = {};
try {
Object.defineProperty(obj, 'x', {
enumerable: false,
value: obj
});
/* eslint-disable no-unused-vars, no-restricted-syntax, guard-for-in */
for (var _ in obj) {
/* istanbul ignore next */
return false;
}
/* eslint-enable no-unused-vars, no-restricted-syntax, guard-for-in */
return true;
} catch (error) { // this is IE 8.
/* istanbul ignore next */
return false;
}
}

// Utility for checking whether Object.getOwnPropertyDescriptor works correctly
function hasWorkingGetOwnPropertyDescriptor() {
return 'getOwnPropertyDescriptor' in Object && typeof Object.getOwnPropertyDescriptor === 'function' && (function() {
try {
var object = {};
object.test = 0;
return Object.getOwnPropertyDescriptor(
object,
'test'
).value === 0;
} catch (exception) {
/* istanbul ignore next */
return false;
}
}());
}

// Utility for checking whether a value is undefined or null
function isUndefinedOrNull(val) {
return (val === null || typeof val === 'undefined');
Expand Down
57 changes: 57 additions & 0 deletions test/unit/lib/proclaim.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint strict: ['error', 'function'] */

(function() {
'use strict';

Expand Down Expand Up @@ -1114,6 +1115,62 @@

});

describe('.isEnumerable()', function() {

it('should be a function', function() {
assert.isFunction(proclaim.isEnumerable);
});

it('should not throw when called with an object whose property is enumerable', function() {
var property = 'a';
var obj = {};
Object.defineProperty(obj, property, {
enumerable: true,
value: 1
});
assert.doesNotThrow(callFn(proclaim.isEnumerable, obj, property));
});

it('should throw when called with an object whose property is not enumerable', function() {
var property = 'a';
var obj = {};
Object.defineProperty(obj, property, {
enumerable: false,
value: 1
});
assert.throws(callFn(proclaim.isEnumerable, obj, property));
});

});

describe('.isNotEnumerable()', function() {

it('should be a function', function() {
assert.isFunction(proclaim.isNotEnumerable);
});

it('should not throw when called with an object whose property is not enumerable', function() {
var property = 'a';
var obj = {};
Object.defineProperty(obj, property, {
enumerable: false,
value: 1
});
assert.doesNotThrow(callFn(proclaim.isNotEnumerable, obj, property));
});

it('should throw when called with an object whose property is enumerable', function() {
var property = 'a';
var obj = {};
Object.defineProperty(obj, property, {
enumerable: true,
value: 1
});
assert.throws(callFn(proclaim.isNotEnumerable, obj, property));
});

});

});

}());

0 comments on commit 10bcd8d

Please sign in to comment.