1
|
'use strict';
|
2
|
|
3
|
var define = require('../');
|
4
|
var test = require('tape');
|
5
|
var keys = require('object-keys');
|
6
|
|
7
|
var 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
|
};
|
16
|
var descriptorsSupported = !!Object.defineProperty && arePropertyDescriptorsSupported();
|
17
|
|
18
|
var hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';
|
19
|
|
20
|
test('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
|
|
108
|
test('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
|
});
|