source: imaps-frontend/node_modules/flat/test/test.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 14.8 KB
Line 
1/* globals suite test */
2
3const assert = require('assert')
4const path = require('path')
5const { exec } = require('child_process')
6const pkg = require('../package.json')
7const flat = require('../index')
8
9const flatten = flat.flatten
10const unflatten = flat.unflatten
11
12const primitives = {
13 String: 'good morning',
14 Number: 1234.99,
15 Boolean: true,
16 Date: new Date(),
17 null: null,
18 undefined: undefined
19}
20
21suite('Flatten Primitives', function () {
22 Object.keys(primitives).forEach(function (key) {
23 const value = primitives[key]
24
25 test(key, function () {
26 assert.deepStrictEqual(flatten({
27 hello: {
28 world: value
29 }
30 }), {
31 'hello.world': value
32 })
33 })
34 })
35})
36
37suite('Unflatten Primitives', function () {
38 Object.keys(primitives).forEach(function (key) {
39 const value = primitives[key]
40
41 test(key, function () {
42 assert.deepStrictEqual(unflatten({
43 'hello.world': value
44 }), {
45 hello: {
46 world: value
47 }
48 })
49 })
50 })
51})
52
53suite('Flatten', function () {
54 test('Nested once', function () {
55 assert.deepStrictEqual(flatten({
56 hello: {
57 world: 'good morning'
58 }
59 }), {
60 'hello.world': 'good morning'
61 })
62 })
63
64 test('Nested twice', function () {
65 assert.deepStrictEqual(flatten({
66 hello: {
67 world: {
68 again: 'good morning'
69 }
70 }
71 }), {
72 'hello.world.again': 'good morning'
73 })
74 })
75
76 test('Multiple Keys', function () {
77 assert.deepStrictEqual(flatten({
78 hello: {
79 lorem: {
80 ipsum: 'again',
81 dolor: 'sit'
82 }
83 },
84 world: {
85 lorem: {
86 ipsum: 'again',
87 dolor: 'sit'
88 }
89 }
90 }), {
91 'hello.lorem.ipsum': 'again',
92 'hello.lorem.dolor': 'sit',
93 'world.lorem.ipsum': 'again',
94 'world.lorem.dolor': 'sit'
95 })
96 })
97
98 test('Custom Delimiter', function () {
99 assert.deepStrictEqual(flatten({
100 hello: {
101 world: {
102 again: 'good morning'
103 }
104 }
105 }, {
106 delimiter: ':'
107 }), {
108 'hello:world:again': 'good morning'
109 })
110 })
111
112 test('Empty Objects', function () {
113 assert.deepStrictEqual(flatten({
114 hello: {
115 empty: {
116 nested: {}
117 }
118 }
119 }), {
120 'hello.empty.nested': {}
121 })
122 })
123
124 if (typeof Buffer !== 'undefined') {
125 test('Buffer', function () {
126 assert.deepStrictEqual(flatten({
127 hello: {
128 empty: {
129 nested: Buffer.from('test')
130 }
131 }
132 }), {
133 'hello.empty.nested': Buffer.from('test')
134 })
135 })
136 }
137
138 if (typeof Uint8Array !== 'undefined') {
139 test('typed arrays', function () {
140 assert.deepStrictEqual(flatten({
141 hello: {
142 empty: {
143 nested: new Uint8Array([1, 2, 3, 4])
144 }
145 }
146 }), {
147 'hello.empty.nested': new Uint8Array([1, 2, 3, 4])
148 })
149 })
150 }
151
152 test('Custom Depth', function () {
153 assert.deepStrictEqual(flatten({
154 hello: {
155 world: {
156 again: 'good morning'
157 }
158 },
159 lorem: {
160 ipsum: {
161 dolor: 'good evening'
162 }
163 }
164 }, {
165 maxDepth: 2
166 }), {
167 'hello.world': {
168 again: 'good morning'
169 },
170 'lorem.ipsum': {
171 dolor: 'good evening'
172 }
173 })
174 })
175
176 test('Transformed Keys', function () {
177 assert.deepStrictEqual(flatten({
178 hello: {
179 world: {
180 again: 'good morning'
181 }
182 },
183 lorem: {
184 ipsum: {
185 dolor: 'good evening'
186 }
187 }
188 }, {
189 transformKey: function (key) {
190 return '__' + key + '__'
191 }
192 }), {
193 '__hello__.__world__.__again__': 'good morning',
194 '__lorem__.__ipsum__.__dolor__': 'good evening'
195 })
196 })
197
198 test('Should keep number in the left when object', function () {
199 assert.deepStrictEqual(flatten({
200 hello: {
201 '0200': 'world',
202 '0500': 'darkness my old friend'
203 }
204 }), {
205 'hello.0200': 'world',
206 'hello.0500': 'darkness my old friend'
207 })
208 })
209})
210
211suite('Unflatten', function () {
212 test('Nested once', function () {
213 assert.deepStrictEqual({
214 hello: {
215 world: 'good morning'
216 }
217 }, unflatten({
218 'hello.world': 'good morning'
219 }))
220 })
221
222 test('Nested twice', function () {
223 assert.deepStrictEqual({
224 hello: {
225 world: {
226 again: 'good morning'
227 }
228 }
229 }, unflatten({
230 'hello.world.again': 'good morning'
231 }))
232 })
233
234 test('Multiple Keys', function () {
235 assert.deepStrictEqual({
236 hello: {
237 lorem: {
238 ipsum: 'again',
239 dolor: 'sit'
240 }
241 },
242 world: {
243 greet: 'hello',
244 lorem: {
245 ipsum: 'again',
246 dolor: 'sit'
247 }
248 }
249 }, unflatten({
250 'hello.lorem.ipsum': 'again',
251 'hello.lorem.dolor': 'sit',
252 'world.lorem.ipsum': 'again',
253 'world.lorem.dolor': 'sit',
254 world: { greet: 'hello' }
255 }))
256 })
257
258 test('nested objects do not clobber each other when a.b inserted before a', function () {
259 const x = {}
260 x['foo.bar'] = { t: 123 }
261 x.foo = { p: 333 }
262 assert.deepStrictEqual(unflatten(x), {
263 foo: {
264 bar: {
265 t: 123
266 },
267 p: 333
268 }
269 })
270 })
271
272 test('Custom Delimiter', function () {
273 assert.deepStrictEqual({
274 hello: {
275 world: {
276 again: 'good morning'
277 }
278 }
279 }, unflatten({
280 'hello world again': 'good morning'
281 }, {
282 delimiter: ' '
283 }))
284 })
285
286 test('Overwrite', function () {
287 assert.deepStrictEqual({
288 travis: {
289 build: {
290 dir: '/home/travis/build/kvz/environmental'
291 }
292 }
293 }, unflatten({
294 travis: 'true',
295 travis_build_dir: '/home/travis/build/kvz/environmental'
296 }, {
297 delimiter: '_',
298 overwrite: true
299 }))
300 })
301
302 test('Transformed Keys', function () {
303 assert.deepStrictEqual(unflatten({
304 '__hello__.__world__.__again__': 'good morning',
305 '__lorem__.__ipsum__.__dolor__': 'good evening'
306 }, {
307 transformKey: function (key) {
308 return key.substring(2, key.length - 2)
309 }
310 }), {
311 hello: {
312 world: {
313 again: 'good morning'
314 }
315 },
316 lorem: {
317 ipsum: {
318 dolor: 'good evening'
319 }
320 }
321 })
322 })
323
324 test('Messy', function () {
325 assert.deepStrictEqual({
326 hello: { world: 'again' },
327 lorem: { ipsum: 'another' },
328 good: {
329 morning: {
330 hash: {
331 key: {
332 nested: {
333 deep: {
334 and: {
335 even: {
336 deeper: { still: 'hello' }
337 }
338 }
339 }
340 }
341 }
342 },
343 again: { testing: { this: 'out' } }
344 }
345 }
346 }, unflatten({
347 'hello.world': 'again',
348 'lorem.ipsum': 'another',
349 'good.morning': {
350 'hash.key': {
351 'nested.deep': {
352 'and.even.deeper.still': 'hello'
353 }
354 }
355 },
356 'good.morning.again': {
357 'testing.this': 'out'
358 }
359 }))
360 })
361
362 suite('Overwrite + non-object values in key positions', function () {
363 test('non-object keys + overwrite should be overwritten', function () {
364 assert.deepStrictEqual(flat.unflatten({ a: null, 'a.b': 'c' }, { overwrite: true }), { a: { b: 'c' } })
365 assert.deepStrictEqual(flat.unflatten({ a: 0, 'a.b': 'c' }, { overwrite: true }), { a: { b: 'c' } })
366 assert.deepStrictEqual(flat.unflatten({ a: 1, 'a.b': 'c' }, { overwrite: true }), { a: { b: 'c' } })
367 assert.deepStrictEqual(flat.unflatten({ a: '', 'a.b': 'c' }, { overwrite: true }), { a: { b: 'c' } })
368 })
369
370 test('overwrite value should not affect undefined keys', function () {
371 assert.deepStrictEqual(flat.unflatten({ a: undefined, 'a.b': 'c' }, { overwrite: true }), { a: { b: 'c' } })
372 assert.deepStrictEqual(flat.unflatten({ a: undefined, 'a.b': 'c' }, { overwrite: false }), { a: { b: 'c' } })
373 })
374
375 test('if no overwrite, should ignore nested values under non-object key', function () {
376 assert.deepStrictEqual(flat.unflatten({ a: null, 'a.b': 'c' }), { a: null })
377 assert.deepStrictEqual(flat.unflatten({ a: 0, 'a.b': 'c' }), { a: 0 })
378 assert.deepStrictEqual(flat.unflatten({ a: 1, 'a.b': 'c' }), { a: 1 })
379 assert.deepStrictEqual(flat.unflatten({ a: '', 'a.b': 'c' }), { a: '' })
380 })
381 })
382
383 suite('.safe', function () {
384 test('Should protect arrays when true', function () {
385 assert.deepStrictEqual(flatten({
386 hello: [
387 { world: { again: 'foo' } },
388 { lorem: 'ipsum' }
389 ],
390 another: {
391 nested: [{ array: { too: 'deep' } }]
392 },
393 lorem: {
394 ipsum: 'whoop'
395 }
396 }, {
397 safe: true
398 }), {
399 hello: [
400 { world: { again: 'foo' } },
401 { lorem: 'ipsum' }
402 ],
403 'lorem.ipsum': 'whoop',
404 'another.nested': [{ array: { too: 'deep' } }]
405 })
406 })
407
408 test('Should not protect arrays when false', function () {
409 assert.deepStrictEqual(flatten({
410 hello: [
411 { world: { again: 'foo' } },
412 { lorem: 'ipsum' }
413 ]
414 }, {
415 safe: false
416 }), {
417 'hello.0.world.again': 'foo',
418 'hello.1.lorem': 'ipsum'
419 })
420 })
421
422 test('Empty objects should not be removed', function () {
423 assert.deepStrictEqual(unflatten({
424 foo: [],
425 bar: {}
426 }), { foo: [], bar: {} })
427 })
428 })
429
430 suite('.object', function () {
431 test('Should create object instead of array when true', function () {
432 const unflattened = unflatten({
433 'hello.you.0': 'ipsum',
434 'hello.you.1': 'lorem',
435 'hello.other.world': 'foo'
436 }, {
437 object: true
438 })
439 assert.deepStrictEqual({
440 hello: {
441 you: {
442 0: 'ipsum',
443 1: 'lorem'
444 },
445 other: { world: 'foo' }
446 }
447 }, unflattened)
448 assert(!Array.isArray(unflattened.hello.you))
449 })
450
451 test('Should create object instead of array when nested', function () {
452 const unflattened = unflatten({
453 hello: {
454 'you.0': 'ipsum',
455 'you.1': 'lorem',
456 'other.world': 'foo'
457 }
458 }, {
459 object: true
460 })
461 assert.deepStrictEqual({
462 hello: {
463 you: {
464 0: 'ipsum',
465 1: 'lorem'
466 },
467 other: { world: 'foo' }
468 }
469 }, unflattened)
470 assert(!Array.isArray(unflattened.hello.you))
471 })
472
473 test('Should keep the zero in the left when object is true', function () {
474 const unflattened = unflatten({
475 'hello.0200': 'world',
476 'hello.0500': 'darkness my old friend'
477 }, {
478 object: true
479 })
480
481 assert.deepStrictEqual({
482 hello: {
483 '0200': 'world',
484 '0500': 'darkness my old friend'
485 }
486 }, unflattened)
487 })
488
489 test('Should not create object when false', function () {
490 const unflattened = unflatten({
491 'hello.you.0': 'ipsum',
492 'hello.you.1': 'lorem',
493 'hello.other.world': 'foo'
494 }, {
495 object: false
496 })
497 assert.deepStrictEqual({
498 hello: {
499 you: ['ipsum', 'lorem'],
500 other: { world: 'foo' }
501 }
502 }, unflattened)
503 assert(Array.isArray(unflattened.hello.you))
504 })
505 })
506
507 if (typeof Buffer !== 'undefined') {
508 test('Buffer', function () {
509 assert.deepStrictEqual(unflatten({
510 'hello.empty.nested': Buffer.from('test')
511 }), {
512 hello: {
513 empty: {
514 nested: Buffer.from('test')
515 }
516 }
517 })
518 })
519 }
520
521 if (typeof Uint8Array !== 'undefined') {
522 test('typed arrays', function () {
523 assert.deepStrictEqual(unflatten({
524 'hello.empty.nested': new Uint8Array([1, 2, 3, 4])
525 }), {
526 hello: {
527 empty: {
528 nested: new Uint8Array([1, 2, 3, 4])
529 }
530 }
531 })
532 })
533 }
534
535 test('should not pollute prototype', function () {
536 unflatten({
537 '__proto__.polluted': true
538 })
539 unflatten({
540 'prefix.__proto__.polluted': true
541 })
542 unflatten({
543 'prefix.0.__proto__.polluted': true
544 })
545
546 assert.notStrictEqual({}.polluted, true)
547 })
548})
549
550suite('Arrays', function () {
551 test('Should be able to flatten arrays properly', function () {
552 assert.deepStrictEqual({
553 'a.0': 'foo',
554 'a.1': 'bar'
555 }, flatten({
556 a: ['foo', 'bar']
557 }))
558 })
559
560 test('Should be able to revert and reverse array serialization via unflatten', function () {
561 assert.deepStrictEqual({
562 a: ['foo', 'bar']
563 }, unflatten({
564 'a.0': 'foo',
565 'a.1': 'bar'
566 }))
567 })
568
569 test('Array typed objects should be restored by unflatten', function () {
570 assert.strictEqual(
571 Object.prototype.toString.call(['foo', 'bar'])
572 , Object.prototype.toString.call(unflatten({
573 'a.0': 'foo',
574 'a.1': 'bar'
575 }).a)
576 )
577 })
578
579 test('Do not include keys with numbers inside them', function () {
580 assert.deepStrictEqual(unflatten({
581 '1key.2_key': 'ok'
582 }), {
583 '1key': {
584 '2_key': 'ok'
585 }
586 })
587 })
588})
589
590suite('Order of Keys', function () {
591 test('Order of keys should not be changed after round trip flatten/unflatten', function () {
592 const obj = {
593 b: 1,
594 abc: {
595 c: [{
596 d: 1,
597 bca: 1,
598 a: 1
599 }]
600 },
601 a: 1
602 }
603 const result = unflatten(
604 flatten(obj)
605 )
606
607 assert.deepStrictEqual(Object.keys(obj), Object.keys(result))
608 assert.deepStrictEqual(Object.keys(obj.abc), Object.keys(result.abc))
609 assert.deepStrictEqual(Object.keys(obj.abc.c[0]), Object.keys(result.abc.c[0]))
610 })
611})
612
613suite('CLI', function () {
614 test('can take filename', function (done) {
615 const cli = path.resolve(__dirname, '..', pkg.bin)
616 const pkgJSON = path.resolve(__dirname, '..', 'package.json')
617 exec(`${cli} ${pkgJSON}`, (err, stdout, stderr) => {
618 assert.ifError(err)
619 assert.strictEqual(stdout.trim(), JSON.stringify(flatten(pkg), null, 2))
620 done()
621 })
622 })
623
624 test('exits with usage if no file', function (done) {
625 const cli = path.resolve(__dirname, '..', pkg.bin)
626 const pkgJSON = path.resolve(__dirname, '..', 'package.json')
627 exec(`${cli} ${pkgJSON}`, (err, stdout, stderr) => {
628 assert.ifError(err)
629 assert.strictEqual(stdout.trim(), JSON.stringify(flatten(pkg), null, 2))
630 done()
631 })
632 })
633
634 test('can take piped file', function (done) {
635 const cli = path.resolve(__dirname, '..', pkg.bin)
636 const pkgJSON = path.resolve(__dirname, '..', 'package.json')
637 exec(`cat ${pkgJSON} | ${cli}`, (err, stdout, stderr) => {
638 assert.ifError(err)
639 assert.strictEqual(stdout.trim(), JSON.stringify(flatten(pkg), null, 2))
640 done()
641 })
642 })
643})
Note: See TracBrowser for help on using the repository browser.