• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3var define = require('../');
4var test = require('tape');
5var keys = require('object-keys');
6
7var arePropertyDescriptorsSupported = function () {
8	var obj = { a: 1 };
9	try {
10		Object.defineProperty(obj, 'x', { value: obj });
11		return obj.x === obj;
12	} catch (e) { /* this is IE 8. */
13		return false;
14	}
15};
16var descriptorsSupported = !!Object.defineProperty && arePropertyDescriptorsSupported();
17
18var hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';
19
20test('defineProperties', function (dt) {
21	dt.test('with descriptor support', { skip: !descriptorsSupported }, function (t) {
22		var getDescriptor = function (value) {
23			return {
24				configurable: true,
25				enumerable: false,
26				value: value,
27				writable: true
28			};
29		};
30
31		var obj = {
32			a: 1,
33			b: 2,
34			c: 3
35		};
36		t.deepEqual(keys(obj), ['a', 'b', 'c'], 'all literal-set keys start enumerable');
37		define(obj, {
38			b: 3,
39			c: 4,
40			d: 5
41		});
42		t.deepEqual(obj, {
43			a: 1,
44			b: 2,
45			c: 3
46		}, 'existing properties were not overridden');
47		t.deepEqual(Object.getOwnPropertyDescriptor(obj, 'd'), getDescriptor(5), 'new property "d" was added and is not enumerable');
48		t.deepEqual(['a', 'b', 'c'], keys(obj), 'new keys are not enumerable');
49
50		define(obj, {
51			a: 2,
52			b: 3,
53			c: 4
54		}, {
55			a: function () { return true; },
56			b: function () { return false; }
57		});
58		t.deepEqual(obj, {
59			b: 2,
60			c: 3
61		}, 'properties only overriden when predicate exists and returns true');
62		t.deepEqual(Object.getOwnPropertyDescriptor(obj, 'd'), getDescriptor(5), 'existing property "d" remained and is not enumerable');
63		t.deepEqual(Object.getOwnPropertyDescriptor(obj, 'a'), getDescriptor(2), 'existing property "a" was overridden and is not enumerable');
64		t.deepEqual(['b', 'c'], keys(obj), 'overridden keys are not enumerable');
65
66		t.end();
67	});
68
69	dt.test('without descriptor support', { skip: descriptorsSupported }, function (t) {
70		var obj = {
71			a: 1,
72			b: 2,
73			c: 3
74		};
75		define(obj, {
76			b: 3,
77			c: 4,
78			d: 5
79		});
80		t.deepEqual(obj, {
81			a: 1,
82			b: 2,
83			c: 3,
84			d: 5
85		}, 'existing properties were not overridden, new properties were added');
86
87		define(obj, {
88			a: 2,
89			b: 3,
90			c: 4
91		}, {
92			a: function () { return true; },
93			b: function () { return false; }
94		});
95		t.deepEqual(obj, {
96			a: 2,
97			b: 2,
98			c: 3,
99			d: 5
100		}, 'properties only overriden when predicate exists and returns true');
101
102		t.end();
103	});
104
105	dt.end();
106});
107
108test('symbols', { skip: !hasSymbols }, function (t) {
109	var sym = Symbol('foo');
110	var obj = {};
111	var aValue = {};
112	var bValue = {};
113	var properties = { a: aValue };
114	properties[sym] = bValue;
115
116	define(obj, properties);
117
118	t.deepEqual(Object.keys(obj), [], 'object has no enumerable keys');
119	t.deepEqual(Object.getOwnPropertyNames(obj), ['a'], 'object has non-enumerable "a" key');
120	t.deepEqual(Object.getOwnPropertySymbols(obj), [sym], 'object has non-enumerable symbol key');
121	t.equal(obj.a, aValue, 'string keyed value is defined');
122	t.equal(obj[sym], bValue, 'symbol keyed value is defined');
123
124	t.end();
125});
126