| 'use strict'; | 
|   | 
| var mockProperty = require('mock-property'); | 
|   | 
| module.exports = function (getDescriptors, t) { | 
|     var enumDescriptor = { | 
|         configurable: true, | 
|         enumerable: false, | 
|         value: true, | 
|         writable: false | 
|     }; | 
|     var writableDescriptor = { | 
|         configurable: true, | 
|         enumerable: true, | 
|         value: 42, | 
|         writable: true | 
|     }; | 
|   | 
|     t.test('works with Object.prototype poisoned setter', { skip: !Object.defineProperty }, function (st) { | 
|         var key = 'foo'; | 
|   | 
|         var obj = {}; | 
|         obj[key] = 42; | 
|   | 
|         var expected = {}; | 
|         expected[key] = { | 
|             configurable: true, | 
|             enumerable: true, | 
|             value: 42, | 
|             writable: true | 
|         }; | 
|   | 
|         st.teardown(mockProperty(Object.prototype, key, { set: function (v) { throw new Error(v); } })); | 
|   | 
|         var hasOwnNamesBug = false; | 
|         try { | 
|             Object.getOwnPropertyNames(obj); | 
|         } catch (e) { | 
|             // v8 in node 0.6 - 0.12 has a bug :-( | 
|             hasOwnNamesBug = true; | 
|             st.comment('SKIP: this engine has a bug with Object.getOwnPropertyNames: it can not handle a throwing setter on Object.prototype.'); | 
|         } | 
|   | 
|         if (!hasOwnNamesBug) { | 
|             st.doesNotThrow(function () { | 
|                 var result = getDescriptors(obj); | 
|                 st.deepEqual(result, expected, 'got expected descriptors'); | 
|             }); | 
|         } | 
|   | 
|         delete Object.prototype[key]; | 
|         st.end(); | 
|     }); | 
|   | 
|     t.test('gets all expected non-Symbol descriptors', function (st) { | 
|         var obj = { normal: Infinity }; | 
|         Object.defineProperty(obj, 'enumerable', enumDescriptor); | 
|         Object.defineProperty(obj, 'writable', writableDescriptor); | 
|   | 
|         var descriptors = getDescriptors(obj); | 
|   | 
|         st.deepEqual(descriptors, { | 
|             enumerable: enumDescriptor, | 
|             normal: { | 
|                 configurable: true, | 
|                 enumerable: true, | 
|                 value: Infinity, | 
|                 writable: true | 
|             }, | 
|             writable: writableDescriptor | 
|         }); | 
|         st.end(); | 
|     }); | 
|   | 
|     var supportsSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol'; | 
|     t.test('gets Symbol descriptors too', { skip: !supportsSymbols }, function (st) { | 
|         var symbol = Symbol('sym'); | 
|         var symDescriptor = { | 
|             configurable: false, | 
|             enumerable: true, | 
|             value: [symbol], | 
|             writable: true | 
|         }; | 
|         var obj = { normal: Infinity }; | 
|         Object.defineProperty(obj, 'enumerable', enumDescriptor); | 
|         Object.defineProperty(obj, 'writable', writableDescriptor); | 
|         Object.defineProperty(obj, 'symbol', symDescriptor); | 
|   | 
|         var descriptors = getDescriptors(obj); | 
|   | 
|         st.deepEqual(descriptors, { | 
|             enumerable: enumDescriptor, | 
|             normal: { | 
|                 configurable: true, | 
|                 enumerable: true, | 
|                 value: Infinity, | 
|                 writable: true | 
|             }, | 
|             symbol: symDescriptor, | 
|             writable: writableDescriptor | 
|         }); | 
|         st.end(); | 
|     }); | 
|   | 
|     var supportsProxy = typeof Proxy === 'function'; | 
|     t.test('Proxies that return an undefined descriptor', { skip: !supportsProxy }, function (st) { | 
|         var obj = { foo: true }; | 
|         var fooDescriptor = Object.getOwnPropertyDescriptor(obj, 'foo'); | 
|   | 
|         var proxy = new Proxy(obj, { | 
|             getOwnPropertyDescriptor: function (target, key) { | 
|                 return Object.getOwnPropertyDescriptor(target, key); | 
|             }, | 
|             ownKeys: function () { | 
|                 return ['foo', 'bar']; | 
|             } | 
|         }); | 
|         st.deepEqual(getDescriptors(proxy), { foo: fooDescriptor }, 'object has no descriptors'); | 
|         st.end(); | 
|     }); | 
| }; |