object-keys
Advanced tools
Comparing version 0.2.0 to 0.3.0
{ | ||
"name": "object-keys", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"author": "Jordan Harband", | ||
@@ -22,8 +22,8 @@ "description": "An Object.keys replacement, in case Object.keys is not available. From https://github.com/kriskowal/es5-shim", | ||
"dependencies": { | ||
"foreach": "~2.0.1", | ||
"indexof": "~0.0.1", | ||
"foreach": "~2.0.3", | ||
"is": "~0.2.6" | ||
}, | ||
"devDependencies": { | ||
"tape": "~1.0.2" | ||
"tape": "~1.0.2", | ||
"indexof": "~0.0.1" | ||
}, | ||
@@ -30,0 +30,0 @@ "testling": { |
@@ -24,6 +24,6 @@ #object-keys <sup>[![Version Badge][2]][1]</sup> | ||
## Source | ||
Implementation taken directly from [9] | ||
Implementation taken directly from [es5-shim]([9]), with modifications, including from [lodash]([10]). | ||
## Tests | ||
Tests currently use tape - which doesn't work in node 0.10, but works in browserify. Rest assured, they pass. | ||
Simply clone the repo, `npm install`, and run `npm test` | ||
@@ -39,2 +39,3 @@ [1]: https://npmjs.org/package/object-keys | ||
[9]: https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L542-589 | ||
[10]: https://github.com/bestiejs/lodash | ||
29
shim.js
@@ -9,2 +9,3 @@ (function () { | ||
hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), | ||
hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), | ||
dontEnums = [ | ||
@@ -22,10 +23,23 @@ "toString", | ||
keysShim = function keys(object) { | ||
if (!is.object(object) && !is.array(object)) { | ||
var isObject = object !== null && typeof object === 'object', | ||
isFunction = is.fn(object), | ||
isArguments = is.arguments(object), | ||
theKeys = []; | ||
if (!isObject && !isFunction && !isArguments) { | ||
throw new TypeError("Object.keys called on a non-object"); | ||
} | ||
var name, theKeys = []; | ||
for (name in object) { | ||
if (has.call(object, name)) { | ||
theKeys.push(name); | ||
if (isArguments) { | ||
forEach(object, function (value) { | ||
theKeys.push(value); | ||
}); | ||
} else { | ||
var name, | ||
skipProto = hasProtoEnumBug && isFunction; | ||
for (name in object) { | ||
if (!(skipProto && name === 'prototype') && has.call(object, name)) { | ||
theKeys.push(name); | ||
} | ||
} | ||
@@ -35,4 +49,7 @@ } | ||
if (hasDontEnumBug) { | ||
var ctor = object.constructor, | ||
skipConstructor = ctor && ctor.prototype === object; | ||
forEach(dontEnums, function (dontEnum) { | ||
if (has.call(object, dontEnum)) { | ||
if (!(skipConstructor && dontEnum === 'constructor') && has.call(object, dontEnum)) { | ||
theKeys.push(dontEnum); | ||
@@ -39,0 +56,0 @@ } |
162
test.js
@@ -8,68 +8,65 @@ var test = require('tape'); | ||
test('works', function (t) { | ||
var obj = { | ||
"str": "boz", | ||
"obj": {}, | ||
"arr": [], | ||
"bool": true, | ||
"num": 42, | ||
"aNull": null, | ||
"undef": undefined | ||
}; | ||
var objKeys = ['str', 'obj', 'arr', 'bool', 'num', 'aNull', 'undef']; | ||
var obj = { | ||
"str": "boz", | ||
"obj": {}, | ||
"arr": [], | ||
"bool": true, | ||
"num": 42, | ||
"aNull": null, | ||
"undef": undefined | ||
}; | ||
var objKeys = ['str', 'obj', 'arr', 'bool', 'num', 'aNull', 'undef']; | ||
t.test('exports a function', function (st) { | ||
if (Object.keys) { | ||
st.equal(Object.keys, shimmedKeys, 'Object.keys is supported and exported'); | ||
} else { | ||
st.equal(keys, shimmedKeys, 'Object.keys is not supported; shim is exported'); | ||
} | ||
st.end(); | ||
}); | ||
test('exports a function', function (t) { | ||
if (Object.keys) { | ||
t.equal(Object.keys, shimmedKeys, 'Object.keys is supported and exported'); | ||
} else { | ||
t.equal(keys, shimmedKeys, 'Object.keys is not supported; shim is exported'); | ||
} | ||
t.end(); | ||
}); | ||
t.test('working with actual shim', function (st) { | ||
st.notEqual(Object.keys, keys, 'keys shim is not native Object.keys'); | ||
st.end(); | ||
}); | ||
test('working with actual shim', function (t) { | ||
t.notEqual(Object.keys, keys, 'keys shim is not native Object.keys'); | ||
t.end(); | ||
}); | ||
t.test('works with an object literal', function (st) { | ||
var theKeys = keys(obj); | ||
st.equal(is.array(theKeys), true, 'returns an array'); | ||
st.deepEqual(theKeys, objKeys, 'Object has expected keys'); | ||
st.end(); | ||
}); | ||
test('works with an object literal', function (t) { | ||
var theKeys = keys(obj); | ||
t.equal(is.array(theKeys), true, 'returns an array'); | ||
t.deepEqual(theKeys, objKeys, 'Object has expected keys'); | ||
t.end(); | ||
}); | ||
t.test('works with an array', function (st) { | ||
var arr = [1, 2, 3]; | ||
var theKeys = keys(arr); | ||
st.equal(is.array(theKeys), true, 'returns an array'); | ||
st.deepEqual(theKeys, ['0', '1', '2'], 'Array has expected keys'); | ||
st.end(); | ||
}); | ||
test('works with an array', function (t) { | ||
var arr = [1, 2, 3]; | ||
var theKeys = keys(arr); | ||
t.equal(is.array(theKeys), true, 'returns an array'); | ||
t.deepEqual(theKeys, ['0', '1', '2'], 'Array has expected keys'); | ||
t.end(); | ||
}); | ||
t.test('returns names which are own properties', function (st) { | ||
forEach(keys(obj), function (name) { | ||
st.equal(obj.hasOwnProperty(name), true, name + ' should be returned'); | ||
}); | ||
st.end(); | ||
}); | ||
test('works with a function', function (t) { | ||
var foo = function () {}; | ||
foo.a = true; | ||
t.test('returns names which are enumerable', function (st) { | ||
var k, loopedValues = []; | ||
for (k in obj) { | ||
loopedValues.push(k); | ||
} | ||
forEach(keys(obj), function (name) { | ||
st.notEqual(indexOf(loopedValues, name), -1, name + ' is not enumerable'); | ||
}); | ||
st.end(); | ||
t.doesNotThrow(function () { return keys(foo); }, 'does not throw an error'); | ||
t.deepEqual(keys(foo), ['a'], 'returns expected keys'); | ||
t.end(); | ||
}); | ||
test('returns names which are own properties', function (t) { | ||
forEach(keys(obj), function (name) { | ||
t.equal(obj.hasOwnProperty(name), true, name + ' should be returned'); | ||
}); | ||
t.end(); | ||
}); | ||
t.test('throws an error for a non-object', function (st) { | ||
st.throws( | ||
function () { return keys(42); }, | ||
new TypeError('Object.keys called on a non-object'), | ||
'throws on a non-object' | ||
); | ||
st.end(); | ||
test('returns names which are enumerable', function (t) { | ||
var k, loopedValues = []; | ||
for (k in obj) { | ||
loopedValues.push(k); | ||
} | ||
forEach(keys(obj), function (name) { | ||
t.notEqual(indexOf(loopedValues, name), -1, name + ' is not enumerable'); | ||
}); | ||
@@ -79,2 +76,11 @@ t.end(); | ||
test('throws an error for a non-object', function (t) { | ||
t.throws( | ||
function () { return keys(42); }, | ||
new TypeError('Object.keys called on a non-object'), | ||
'throws on a non-object' | ||
); | ||
t.end(); | ||
}); | ||
test('works with an object instance', function (t) { | ||
@@ -91,1 +97,41 @@ var Prototype = function () {}; | ||
test('works in iOS 5 mobile Safari', function (t) { | ||
var Foo = function () {}; | ||
Foo.a = function () {}; | ||
// the bug is keys(Foo) => ['a', 'prototype'] instead of ['a'] | ||
t.deepEqual(keys(Foo), ['a'], 'has expected keys'); | ||
t.end(); | ||
}); | ||
test('works in environments with the dontEnum bug (IE < 9)', function (t) { | ||
var Foo = function () {}; | ||
Foo.prototype.a = function () {}; | ||
// the bug is keys(Foo.prototype) => ['a', 'constructor'] instead of ['a'] | ||
t.deepEqual(keys(Foo.prototype), ['a'], 'has expected keys'); | ||
t.end(); | ||
}); | ||
test('shadowed properties', function (t) { | ||
var shadowedProps = [ | ||
'dummyControlProp', /* just to be sure */ | ||
'constructor', | ||
'hasOwnProperty', | ||
'isPrototypeOf', | ||
'propertyIsEnumerable', | ||
'toLocaleString', | ||
'toString', | ||
'valueOf' | ||
]; | ||
shadowedProps.sort(); | ||
var shadowedObject = {}; | ||
forEach(shadowedProps, function (value, index) { | ||
shadowedObject[value] = index; | ||
}); | ||
var shadowedObjectKeys = keys(shadowedObject); | ||
shadowedObjectKeys.sort(); | ||
t.deepEqual(shadowedObjectKeys, shadowedProps, 'troublesome shadowed properties are keys of object literals'); | ||
t.end(); | ||
}); | ||
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7087
2
170
40
2
- Removedindexof@~0.0.1
- Removedindexof@0.0.1(transitive)
Updatedforeach@~2.0.3