source: imaps-frontend/node_modules/define-data-property/test/index.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 10.2 KB
RevLine 
[d565449]1'use strict';
2
3var test = require('tape');
4var v = require('es-value-fixtures');
5var forEach = require('for-each');
6var inspect = require('object-inspect');
7var hasOwn = require('hasown');
8var hasPropertyDescriptors = require('has-property-descriptors')();
9var getOwnPropertyDescriptors = require('object.getownpropertydescriptors');
10var ownKeys = require('reflect.ownkeys');
11
12var defineDataProperty = require('../');
13
14test('defineDataProperty', function (t) {
15 t.test('argument validation', function (st) {
16 forEach(v.primitives, function (nonObject) {
17 st['throws'](
18 // @ts-expect-error
19 function () { defineDataProperty(nonObject, 'key', 'value'); },
20 TypeError,
21 'throws on non-object input: ' + inspect(nonObject)
22 );
23 });
24
25 forEach(v.nonPropertyKeys, function (nonPropertyKey) {
26 st['throws'](
27 // @ts-expect-error
28 function () { defineDataProperty({}, nonPropertyKey, 'value'); },
29 TypeError,
30 'throws on non-PropertyKey input: ' + inspect(nonPropertyKey)
31 );
32 });
33
34 forEach(v.nonBooleans, function (nonBoolean) {
35 if (nonBoolean !== null) {
36 st['throws'](
37 // @ts-expect-error
38 function () { defineDataProperty({}, 'key', 'value', nonBoolean); },
39 TypeError,
40 'throws on non-boolean nonEnumerable: ' + inspect(nonBoolean)
41 );
42
43 st['throws'](
44 // @ts-expect-error
45 function () { defineDataProperty({}, 'key', 'value', false, nonBoolean); },
46 TypeError,
47 'throws on non-boolean nonWritable: ' + inspect(nonBoolean)
48 );
49
50 st['throws'](
51 // @ts-expect-error
52 function () { defineDataProperty({}, 'key', 'value', false, false, nonBoolean); },
53 TypeError,
54 'throws on non-boolean nonConfigurable: ' + inspect(nonBoolean)
55 );
56 }
57 });
58
59 st.end();
60 });
61
62 t.test('normal data property', function (st) {
63 /** @type {Record<PropertyKey, string>} */
64 var obj = { existing: 'existing property' };
65 st.ok(hasOwn(obj, 'existing'), 'has initial own property');
66 st.equal(obj.existing, 'existing property', 'has expected initial value');
67
68 var res = defineDataProperty(obj, 'added', 'added property');
69 st.equal(res, void undefined, 'returns `undefined`');
70 st.ok(hasOwn(obj, 'added'), 'has expected own property');
71 st.equal(obj.added, 'added property', 'has expected value');
72
73 defineDataProperty(obj, 'existing', 'new value');
74 st.ok(hasOwn(obj, 'existing'), 'still has expected own property');
75 st.equal(obj.existing, 'new value', 'has new expected value');
76
77 defineDataProperty(obj, 'explicit1', 'new value', false);
78 st.ok(hasOwn(obj, 'explicit1'), 'has expected own property (explicit enumerable)');
79 st.equal(obj.explicit1, 'new value', 'has new expected value (explicit enumerable)');
80
81 defineDataProperty(obj, 'explicit2', 'new value', false, false);
82 st.ok(hasOwn(obj, 'explicit2'), 'has expected own property (explicit writable)');
83 st.equal(obj.explicit2, 'new value', 'has new expected value (explicit writable)');
84
85 defineDataProperty(obj, 'explicit3', 'new value', false, false, false);
86 st.ok(hasOwn(obj, 'explicit3'), 'has expected own property (explicit configurable)');
87 st.equal(obj.explicit3, 'new value', 'has new expected value (explicit configurable)');
88
89 st.end();
90 });
91
92 t.test('loose mode', { skip: !hasPropertyDescriptors }, function (st) {
93 var obj = { existing: 'existing property' };
94
95 defineDataProperty(obj, 'added', 'added value 1', true, null, null, true);
96 st.deepEqual(
97 getOwnPropertyDescriptors(obj),
98 {
99 existing: {
100 configurable: true,
101 enumerable: true,
102 value: 'existing property',
103 writable: true
104 },
105 added: {
106 configurable: true,
107 enumerable: !hasPropertyDescriptors,
108 value: 'added value 1',
109 writable: true
110 }
111 },
112 'in loose mode, obj still adds property 1'
113 );
114
115 defineDataProperty(obj, 'added', 'added value 2', false, true, null, true);
116 st.deepEqual(
117 getOwnPropertyDescriptors(obj),
118 {
119 existing: {
120 configurable: true,
121 enumerable: true,
122 value: 'existing property',
123 writable: true
124 },
125 added: {
126 configurable: true,
127 enumerable: true,
128 value: 'added value 2',
129 writable: !hasPropertyDescriptors
130 }
131 },
132 'in loose mode, obj still adds property 2'
133 );
134
135 defineDataProperty(obj, 'added', 'added value 3', false, false, true, true);
136 st.deepEqual(
137 getOwnPropertyDescriptors(obj),
138 {
139 existing: {
140 configurable: true,
141 enumerable: true,
142 value: 'existing property',
143 writable: true
144 },
145 added: {
146 configurable: !hasPropertyDescriptors,
147 enumerable: true,
148 value: 'added value 3',
149 writable: true
150 }
151 },
152 'in loose mode, obj still adds property 3'
153 );
154
155 st.end();
156 });
157
158 t.test('non-normal data property, ES3', { skip: hasPropertyDescriptors }, function (st) {
159 /** @type {Record<PropertyKey, string>} */
160 var obj = { existing: 'existing property' };
161
162 st['throws'](
163 function () { defineDataProperty(obj, 'added', 'added value', true); },
164 SyntaxError,
165 'nonEnumerable throws a Syntax Error'
166 );
167
168 st['throws'](
169 function () { defineDataProperty(obj, 'added', 'added value', false, true); },
170 SyntaxError,
171 'nonWritable throws a Syntax Error'
172 );
173
174 st['throws'](
175 function () { defineDataProperty(obj, 'added', 'added value', false, false, true); },
176 SyntaxError,
177 'nonWritable throws a Syntax Error'
178 );
179
180 st.deepEqual(
181 ownKeys(obj),
182 ['existing'],
183 'obj still has expected keys'
184 );
185 st.equal(obj.existing, 'existing property', 'obj still has expected values');
186
187 st.end();
188 });
189
190 t.test('new non-normal data property, ES5+', { skip: !hasPropertyDescriptors }, function (st) {
191 /** @type {Record<PropertyKey, string>} */
192 var obj = { existing: 'existing property' };
193
194 defineDataProperty(obj, 'nonEnum', null, true);
195 defineDataProperty(obj, 'nonWrit', null, false, true);
196 defineDataProperty(obj, 'nonConf', null, false, false, true);
197
198 st.deepEqual(
199 getOwnPropertyDescriptors(obj),
200 {
201 existing: {
202 configurable: true,
203 enumerable: true,
204 value: 'existing property',
205 writable: true
206 },
207 nonEnum: {
208 configurable: true,
209 enumerable: false,
210 value: null,
211 writable: true
212 },
213 nonWrit: {
214 configurable: true,
215 enumerable: true,
216 value: null,
217 writable: false
218 },
219 nonConf: {
220 configurable: false,
221 enumerable: true,
222 value: null,
223 writable: true
224 }
225 },
226 'obj has expected property descriptors'
227 );
228
229 st.end();
230 });
231
232 t.test('existing non-normal data property, ES5+', { skip: !hasPropertyDescriptors }, function (st) {
233 // test case changing an existing non-normal property
234
235 /** @type {Record<string, null | string>} */
236 var obj = {};
237 Object.defineProperty(obj, 'nonEnum', { configurable: true, enumerable: false, value: null, writable: true });
238 Object.defineProperty(obj, 'nonWrit', { configurable: true, enumerable: true, value: null, writable: false });
239 Object.defineProperty(obj, 'nonConf', { configurable: false, enumerable: true, value: null, writable: true });
240
241 st.deepEqual(
242 getOwnPropertyDescriptors(obj),
243 {
244 nonEnum: {
245 configurable: true,
246 enumerable: false,
247 value: null,
248 writable: true
249 },
250 nonWrit: {
251 configurable: true,
252 enumerable: true,
253 value: null,
254 writable: false
255 },
256 nonConf: {
257 configurable: false,
258 enumerable: true,
259 value: null,
260 writable: true
261 }
262 },
263 'obj initially has expected property descriptors'
264 );
265
266 defineDataProperty(obj, 'nonEnum', 'new value', false);
267 defineDataProperty(obj, 'nonWrit', 'new value', false, false);
268 st['throws'](
269 function () { defineDataProperty(obj, 'nonConf', 'new value', false, false, false); },
270 TypeError,
271 'can not alter a nonconfigurable property'
272 );
273
274 st.deepEqual(
275 getOwnPropertyDescriptors(obj),
276 {
277 nonEnum: {
278 configurable: true,
279 enumerable: true,
280 value: 'new value',
281 writable: true
282 },
283 nonWrit: {
284 configurable: true,
285 enumerable: true,
286 value: 'new value',
287 writable: true
288 },
289 nonConf: {
290 configurable: false,
291 enumerable: true,
292 value: null,
293 writable: true
294 }
295 },
296 'obj ends up with expected property descriptors'
297 );
298
299 st.end();
300 });
301
302 t.test('frozen object, ES5+', { skip: !hasPropertyDescriptors }, function (st) {
303 var frozen = Object.freeze({ existing: true });
304
305 st['throws'](
306 function () { defineDataProperty(frozen, 'existing', 'new value'); },
307 TypeError,
308 'frozen object can not modify an existing property'
309 );
310
311 st['throws'](
312 function () { defineDataProperty(frozen, 'new', 'new property'); },
313 TypeError,
314 'frozen object can not add a new property'
315 );
316
317 st.end();
318 });
319
320 t.test('sealed object, ES5+', { skip: !hasPropertyDescriptors }, function (st) {
321 var sealed = Object.seal({ existing: true });
322 st.deepEqual(
323 Object.getOwnPropertyDescriptor(sealed, 'existing'),
324 {
325 configurable: false,
326 enumerable: true,
327 value: true,
328 writable: true
329 },
330 'existing value on sealed object has expected descriptor'
331 );
332
333 defineDataProperty(sealed, 'existing', 'new value');
334
335 st.deepEqual(
336 Object.getOwnPropertyDescriptor(sealed, 'existing'),
337 {
338 configurable: false,
339 enumerable: true,
340 value: 'new value',
341 writable: true
342 },
343 'existing value on sealed object has changed descriptor'
344 );
345
346 st['throws'](
347 function () { defineDataProperty(sealed, 'new', 'new property'); },
348 TypeError,
349 'sealed object can not add a new property'
350 );
351
352 st.end();
353 });
354
355 t.test('nonextensible object, ES5+', { skip: !hasPropertyDescriptors }, function (st) {
356 var nonExt = Object.preventExtensions({ existing: true });
357
358 st.deepEqual(
359 Object.getOwnPropertyDescriptor(nonExt, 'existing'),
360 {
361 configurable: true,
362 enumerable: true,
363 value: true,
364 writable: true
365 },
366 'existing value on non-extensible object has expected descriptor'
367 );
368
369 defineDataProperty(nonExt, 'existing', 'new value', true);
370
371 st.deepEqual(
372 Object.getOwnPropertyDescriptor(nonExt, 'existing'),
373 {
374 configurable: true,
375 enumerable: false,
376 value: 'new value',
377 writable: true
378 },
379 'existing value on non-extensible object has changed descriptor'
380 );
381
382 st['throws'](
383 function () { defineDataProperty(nonExt, 'new', 'new property'); },
384 TypeError,
385 'non-extensible object can not add a new property'
386 );
387
388 st.end();
389 });
390
391 t.end();
392});
Note: See TracBrowser for help on using the repository browser.