• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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