tests.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. 'use strict';
  2. var mockProperty = require('mock-property');
  3. module.exports = function (getDescriptors, t) {
  4. var enumDescriptor = {
  5. configurable: true,
  6. enumerable: false,
  7. value: true,
  8. writable: false
  9. };
  10. var writableDescriptor = {
  11. configurable: true,
  12. enumerable: true,
  13. value: 42,
  14. writable: true
  15. };
  16. t.test('works with Object.prototype poisoned setter', { skip: !Object.defineProperty }, function (st) {
  17. var key = 'foo';
  18. var obj = {};
  19. obj[key] = 42;
  20. var expected = {};
  21. expected[key] = {
  22. configurable: true,
  23. enumerable: true,
  24. value: 42,
  25. writable: true
  26. };
  27. st.teardown(mockProperty(Object.prototype, key, { set: function (v) { throw new Error(v); } }));
  28. var hasOwnNamesBug = false;
  29. try {
  30. Object.getOwnPropertyNames(obj);
  31. } catch (e) {
  32. // v8 in node 0.6 - 0.12 has a bug :-(
  33. hasOwnNamesBug = true;
  34. st.comment('SKIP: this engine has a bug with Object.getOwnPropertyNames: it can not handle a throwing setter on Object.prototype.');
  35. }
  36. if (!hasOwnNamesBug) {
  37. st.doesNotThrow(function () {
  38. var result = getDescriptors(obj);
  39. st.deepEqual(result, expected, 'got expected descriptors');
  40. });
  41. }
  42. delete Object.prototype[key];
  43. st.end();
  44. });
  45. t.test('gets all expected non-Symbol descriptors', function (st) {
  46. var obj = { normal: Infinity };
  47. Object.defineProperty(obj, 'enumerable', enumDescriptor);
  48. Object.defineProperty(obj, 'writable', writableDescriptor);
  49. var descriptors = getDescriptors(obj);
  50. st.deepEqual(descriptors, {
  51. enumerable: enumDescriptor,
  52. normal: {
  53. configurable: true,
  54. enumerable: true,
  55. value: Infinity,
  56. writable: true
  57. },
  58. writable: writableDescriptor
  59. });
  60. st.end();
  61. });
  62. var supportsSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';
  63. t.test('gets Symbol descriptors too', { skip: !supportsSymbols }, function (st) {
  64. var symbol = Symbol('sym');
  65. var symDescriptor = {
  66. configurable: false,
  67. enumerable: true,
  68. value: [symbol],
  69. writable: true
  70. };
  71. var obj = { normal: Infinity };
  72. Object.defineProperty(obj, 'enumerable', enumDescriptor);
  73. Object.defineProperty(obj, 'writable', writableDescriptor);
  74. Object.defineProperty(obj, 'symbol', symDescriptor);
  75. var descriptors = getDescriptors(obj);
  76. st.deepEqual(descriptors, {
  77. enumerable: enumDescriptor,
  78. normal: {
  79. configurable: true,
  80. enumerable: true,
  81. value: Infinity,
  82. writable: true
  83. },
  84. symbol: symDescriptor,
  85. writable: writableDescriptor
  86. });
  87. st.end();
  88. });
  89. var supportsProxy = typeof Proxy === 'function';
  90. t.test('Proxies that return an undefined descriptor', { skip: !supportsProxy }, function (st) {
  91. var obj = { foo: true };
  92. var fooDescriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
  93. var proxy = new Proxy(obj, {
  94. getOwnPropertyDescriptor: function (target, key) {
  95. return Object.getOwnPropertyDescriptor(target, key);
  96. },
  97. ownKeys: function () {
  98. return ['foo', 'bar'];
  99. }
  100. });
  101. st.deepEqual(getDescriptors(proxy), { foo: fooDescriptor }, 'object has no descriptors');
  102. st.end();
  103. });
  104. };