1'use strict'; 2 3module.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 17 t.test('works with Object.prototype poisoned setter', { skip: !Object.defineProperty }, function (st) { 18 var key = 'foo'; 19 20 var obj = {}; 21 obj[key] = 42; 22 23 var expected = {}; 24 expected[key] = { 25 configurable: true, 26 enumerable: true, 27 value: 42, 28 writable: true 29 }; 30 31 /* eslint-disable no-extend-native, accessor-pairs */ 32 Object.defineProperty(Object.prototype, key, { configurable: true, set: function (v) { throw new Error(v); } }); 33 /* eslint-enable no-extend-native, accessor-pairs */ 34 35 var hasOwnNamesBug = false; 36 try { 37 Object.getOwnPropertyNames(obj); 38 } catch (e) { 39 // v8 in node 0.6 - 0.12 has a bug :-( 40 hasOwnNamesBug = true; 41 st.comment('SKIP: this engine has a bug with Object.getOwnPropertyNames: it can not handle a throwing setter on Object.prototype.'); 42 } 43 44 if (!hasOwnNamesBug) { 45 st.doesNotThrow(function () { 46 var result = getDescriptors(obj); 47 st.deepEqual(result, expected, 'got expected descriptors'); 48 }); 49 } 50 51 /* eslint-disable no-extend-native */ 52 delete Object.prototype[key]; 53 /* eslint-enable no-extend-native */ 54 st.end(); 55 }); 56 57 t.test('gets all expected non-Symbol descriptors', function (st) { 58 var obj = { normal: Infinity }; 59 Object.defineProperty(obj, 'enumerable', enumDescriptor); 60 Object.defineProperty(obj, 'writable', writableDescriptor); 61 62 var descriptors = getDescriptors(obj); 63 64 st.deepEqual(descriptors, { 65 enumerable: enumDescriptor, 66 normal: { 67 configurable: true, 68 enumerable: true, 69 value: Infinity, 70 writable: true 71 }, 72 writable: writableDescriptor 73 }); 74 st.end(); 75 }); 76 77 var supportsSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol'; 78 t.test('gets Symbol descriptors too', { skip: !supportsSymbols }, function (st) { 79 var symbol = Symbol(); 80 var symDescriptor = { 81 configurable: false, 82 enumerable: true, 83 value: [symbol], 84 writable: true 85 }; 86 var obj = { normal: Infinity }; 87 Object.defineProperty(obj, 'enumerable', enumDescriptor); 88 Object.defineProperty(obj, 'writable', writableDescriptor); 89 Object.defineProperty(obj, 'symbol', symDescriptor); 90 91 var descriptors = getDescriptors(obj); 92 93 st.deepEqual(descriptors, { 94 enumerable: enumDescriptor, 95 normal: { 96 configurable: true, 97 enumerable: true, 98 value: Infinity, 99 writable: true 100 }, 101 symbol: symDescriptor, 102 writable: writableDescriptor 103 }); 104 st.end(); 105 }); 106 107 /* global Proxy */ 108 var supportsProxy = typeof Proxy === 'function'; 109 t.test('Proxies that return an undefined descriptor', { skip: !supportsProxy }, function (st) { 110 var obj = { foo: true }; 111 var fooDescriptor = Object.getOwnPropertyDescriptor(obj, 'foo'); 112 113 var proxy = new Proxy(obj, { 114 getOwnPropertyDescriptor: function (target, key) { 115 return Object.getOwnPropertyDescriptor(target, key); 116 }, 117 ownKeys: function () { 118 return [ 119 'foo', 120 'bar' 121 ]; 122 } 123 }); 124 st.deepEqual(getDescriptors(proxy), { foo: fooDescriptor }, 'object has no descriptors'); 125 st.end(); 126 }); 127}; 128