shim.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. var test = require('tape');
  2. var shimmedKeys = require('../index.js');
  3. var is = require('is');
  4. var keys = require('../shim.js');
  5. var forEach = require('foreach');
  6. var indexOf = require('indexof');
  7. var obj = {
  8. "str": "boz",
  9. "obj": {},
  10. "arr": [],
  11. "bool": true,
  12. "num": 42,
  13. "aNull": null,
  14. "undef": undefined
  15. };
  16. var objKeys = ['str', 'obj', 'arr', 'bool', 'num', 'aNull', 'undef'];
  17. test('exports a function', function (t) {
  18. if (Object.keys) {
  19. t.equal(Object.keys, shimmedKeys, 'Object.keys is supported and exported');
  20. } else {
  21. t.equal(keys, shimmedKeys, 'Object.keys is not supported; shim is exported');
  22. }
  23. t.end();
  24. });
  25. test('working with actual shim', function (t) {
  26. t.notEqual(Object.keys, keys, 'keys shim is not native Object.keys');
  27. t.end();
  28. });
  29. test('works with an object literal', function (t) {
  30. var theKeys = keys(obj);
  31. t.equal(is.array(theKeys), true, 'returns an array');
  32. t.deepEqual(theKeys, objKeys, 'Object has expected keys');
  33. t.end();
  34. });
  35. test('works with an array', function (t) {
  36. var arr = [1, 2, 3];
  37. var theKeys = keys(arr);
  38. t.equal(is.array(theKeys), true, 'returns an array');
  39. t.deepEqual(theKeys, ['0', '1', '2'], 'Array has expected keys');
  40. t.end();
  41. });
  42. test('works with a function', function (t) {
  43. var foo = function () {};
  44. foo.a = true;
  45. t.doesNotThrow(function () { return keys(foo); }, 'does not throw an error');
  46. t.deepEqual(keys(foo), ['a'], 'returns expected keys');
  47. t.end();
  48. });
  49. test('returns names which are own properties', function (t) {
  50. forEach(keys(obj), function (name) {
  51. t.equal(obj.hasOwnProperty(name), true, name + ' should be returned');
  52. });
  53. t.end();
  54. });
  55. test('returns names which are enumerable', function (t) {
  56. var k, loopedValues = [];
  57. for (k in obj) {
  58. loopedValues.push(k);
  59. }
  60. forEach(keys(obj), function (name) {
  61. t.notEqual(indexOf(loopedValues, name), -1, name + ' is not enumerable');
  62. });
  63. t.end();
  64. });
  65. test('throws an error for a non-object', function (t) {
  66. t.throws(
  67. function () { return keys(42); },
  68. new TypeError('Object.keys called on a non-object'),
  69. 'throws on a non-object'
  70. );
  71. t.end();
  72. });
  73. test('works with an object instance', function (t) {
  74. var Prototype = function () {};
  75. Prototype.prototype.foo = true;
  76. var obj = new Prototype();
  77. obj.bar = true;
  78. var theKeys = keys(obj);
  79. t.equal(is.array(theKeys), true, 'returns an array');
  80. t.deepEqual(theKeys, ['bar'], 'Instance has expected keys');
  81. t.end();
  82. });
  83. test('works in iOS 5 mobile Safari', function (t) {
  84. var Foo = function () {};
  85. Foo.a = function () {};
  86. // the bug is keys(Foo) => ['a', 'prototype'] instead of ['a']
  87. t.deepEqual(keys(Foo), ['a'], 'has expected keys');
  88. t.end();
  89. });
  90. test('works in environments with the dontEnum bug (IE < 9)', function (t) {
  91. var Foo = function () {};
  92. Foo.prototype.a = function () {};
  93. // the bug is keys(Foo.prototype) => ['a', 'constructor'] instead of ['a']
  94. t.deepEqual(keys(Foo.prototype), ['a'], 'has expected keys');
  95. t.end();
  96. });
  97. test('shadowed properties', function (t) {
  98. var shadowedProps = [
  99. 'dummyControlProp', /* just to be sure */
  100. 'constructor',
  101. 'hasOwnProperty',
  102. 'isPrototypeOf',
  103. 'propertyIsEnumerable',
  104. 'toLocaleString',
  105. 'toString',
  106. 'valueOf'
  107. ];
  108. shadowedProps.sort();
  109. var shadowedObject = {};
  110. forEach(shadowedProps, function (value, index) {
  111. shadowedObject[value] = index;
  112. });
  113. var shadowedObjectKeys = keys(shadowedObject);
  114. shadowedObjectKeys.sort();
  115. t.deepEqual(shadowedObjectKeys, shadowedProps, 'troublesome shadowed properties are keys of object literals');
  116. t.end();
  117. });