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) {
|
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 | });
|