UNPKG

27.4 kBJavaScriptView Raw
1const { toXML } = require('./dist/jstoxml');
2const assert = require('assert');
3
4describe('toXML', () => {
5 describe('primitives', () => {
6 const vals = [
7 'foo',
8 false,
9 true,
10 4,
11 4.56
12 ];
13
14 vals.forEach(val => {
15 it(`outputs ${val}`, () => {
16 const result = toXML(val);
17 const expectedResult = `${val}`;
18 assert.equal(result, expectedResult);
19 });
20 });
21 });
22
23 describe('functions', () => {
24 describe('primitive outputs', () => {
25 const vals = [
26 999,
27 'foo',
28 false,
29 true
30 ];
31
32 vals.forEach((val) => {
33 it(`${val}`, () => {
34 const result = toXML(() => val);
35 const expectedResult = `${val}`;
36 assert.equal(result, expectedResult);
37 });
38 });
39 });
40
41 it('fat arrow', () => {
42 const val = 888;
43 const result = toXML(() => val);
44 const expectedResult = val;
45 assert.equal(result, expectedResult);
46 });
47
48 it('accessing config within function', () => {
49 const val = {
50 foo: {
51 depth: config => config.depth
52 }
53 };
54 const result = toXML(val);
55 const expectedResult = '<foo><depth>2</depth></foo>';
56 assert.equal(result, expectedResult);
57 });
58
59 it('converts nonprimitive output', () => {
60 const val = { foo: 'bar' };
61 const result = toXML(() => val);
62 const expectedResult = '<foo>bar</foo>';
63 assert.equal(result, expectedResult);
64 });
65
66 it('converts nested nonprimitive output', () => {
67 const val = { foo: { bar: { baz: 2 } } };
68 const result = toXML(() => val);
69 const expectedResult = '<foo><bar><baz>2</baz></bar></foo>';
70 assert.equal(result, expectedResult);
71 });
72
73 it('converts nested nonprimitive output with indent', () => {
74 const val = { foo: { bar: { baz: 2 } } };
75 const config = { indent: ' ' };
76 const result = toXML(() => val, config);
77 const expectedResult = '<foo>\n <bar>\n <baz>2</baz>\n </bar>\n</foo>';
78 assert.equal(result, expectedResult);
79 });
80 });
81
82 describe('github issues', () => {
83 it('issue 3', () => {
84 const val = {
85 foo: true,
86 bar: '',
87 foo2: false,
88 ok: 'This is ok',
89 ok2: 'false',
90 ok3: 'true'
91 };
92 const result = toXML(val);
93 const expectedResult = '<foo>true</foo><bar/><foo2>false</foo2><ok>This is ok</ok><ok2>false</ok2><ok3>true</ok3>';
94 assert.equal(result, expectedResult);
95 });
96
97 it('issue 4a', () => {
98 const val = {
99 foo: 4,
100 bar: '&'
101 };
102 const result = toXML(val);
103 const expectedResult = '<foo>4</foo><bar>&</bar>';
104 assert.equal(result, expectedResult);
105 });
106
107 it('issue 4b', () => {
108 const val = {
109 foo: '&'
110 };
111 const config = {
112 filter: {
113 '&': '&amp;'
114 }
115 };
116 const result = toXML(val, config);
117 const expectedResult = '<foo>&amp;</foo>';
118 assert.equal(result, expectedResult);
119 });
120 });
121
122 describe('arrays', () => {
123 it('1', () => {
124 const val = [
125 { foo: 'bar' },
126 { foo: 'baz' },
127 { foo2: 'bar2' }
128 ];
129 const result = toXML(val);
130 const expectedResult = '<foo>bar</foo><foo>baz</foo><foo2>bar2</foo2>';
131 assert.equal(result, expectedResult);
132 });
133
134 it('attributes in subobject', () => {
135 const val = [
136 { foo: 'bar' },
137 { foo: 'baz' },
138 { foo: undefined },
139 { foo: '' },
140 { foo: null },
141 {
142 _name: 'foo',
143 _content: 'bar',
144 _attrs: {
145 a: 'b',
146 c: 'd'
147 }
148 }
149 ];
150 const result = toXML(val);
151 const expectedResult = '<foo>bar</foo><foo>baz</foo><foo/><foo/>foo<foo a="b" c="d">bar</foo>';
152 assert.equal(result, expectedResult);
153 });
154
155 it('nesting with indent', () => {
156 const val = {
157 foo: [
158 { foo: 'bar' },
159 { foo: 'baz' },
160 { foo2: 'bar2' }
161 ]
162 };
163 const config = { indent: ' ' };
164 const result = toXML(val, config);
165 const expectedResult = `<foo>
166 <foo>bar</foo>
167 <foo>baz</foo>
168 <foo2>bar2</foo2>
169</foo>`;
170 assert.equal(result, expectedResult);
171 });
172 });
173
174 describe('special-objects', () => {
175 it('1', () => {
176 const val = {
177 _name: 'foo',
178 _content: 'bar',
179 _attrs: {
180 a: 1,
181 b: 2
182 }
183 };
184 const result = toXML(val);
185 const expectedResult = '<foo a="1" b="2">bar</foo>';
186 assert.equal(result, expectedResult);
187 });
188
189 it('2', () => {
190 const val = {
191 _name: 'foo',
192 _content: {
193 foo: 'bar'
194 },
195 _attrs: {
196 a: 1,
197 b: 2
198 }
199 };
200 const result = toXML(val);
201 const expectedResult = '<foo a="1" b="2"><foo>bar</foo></foo>';
202 assert.equal(result, expectedResult);
203 });
204
205 it('3', () => {
206 const val = {
207 _name: 'foo',
208 _content: () => 1 + 2,
209 _attrs: {
210 a: 1,
211 b: 2
212 }
213 };
214 const result = toXML(val);
215 const expectedResult = '<foo a="1" b="2">3</foo>';
216 assert.equal(result, expectedResult);
217 });
218 });
219
220 describe('objects', () => {
221 it('1', () => {
222 const val = {
223 foo: 'bar',
224 foo2: 'bar2'
225 };
226 const result = toXML(val);
227 const expectedResult = '<foo>bar</foo><foo2>bar2</foo2>';
228 assert.equal(result, expectedResult);
229 });
230
231 it('attributes', () => {
232 const val = {
233 _name: 'a',
234 _attrs: {
235 foo: 'bar',
236 foo2: 'bar2'
237 }
238 };
239 const result = toXML(val);
240 const expectedResult = '<a foo="bar" foo2="bar2"/>';
241 assert.equal(result, expectedResult);
242 });
243
244 it('attributes 2', () => {
245 const val = {
246 _name: 'a',
247 _attrs: {
248 foo: 'bar',
249 foo2: 'bar2'
250 },
251 _content: 'la dee da'
252 };
253 const result = toXML(val);
254 const expectedResult = '<a foo="bar" foo2="bar2">la dee da</a>';
255 assert.equal(result, expectedResult);
256 });
257
258 it('attributes nesting', () => {
259 const val = {
260 _name: 'foo',
261 _attrs: {
262 a: 'b'
263 },
264 _content: {
265 _name: 'bar',
266 _attrs: {
267 c: 'd'
268 }
269 }
270 };
271 const result = toXML(val);
272 const expectedResult = '<foo a="b"><bar c="d"/></foo>';
273 assert.equal(result, expectedResult);
274 });
275 it('with mixed content', () => {
276 const val = {
277 blah: null,
278 foo: 'bar',
279 'more blah': null,
280 bar: 0,
281 'more more blah': null,
282 baz: false
283 };
284 const result = toXML(val);
285 const expectedResult =
286 'blah<foo>bar</foo>more blah<bar>0</bar>more more blah<baz>false</baz>';
287 assert.equal(result, expectedResult);
288 });
289
290 it('nesting with indent', () => {
291 const val = {
292 foo: {
293 foo: 'bar',
294 foo2: 'bar2'
295 }
296 };
297 const config = { indent: ' ' };
298 const result = toXML(val, config);
299 const expectedResult = `<foo>
300 <foo>bar</foo>
301 <foo2>bar2</foo2>
302</foo>`;
303 assert.equal(result, expectedResult);
304 });
305
306 it('deep nesting', () => {
307 const val = {
308 a: {
309 b: {
310 c: {
311 d: {
312 e: {
313 f: {
314 g: {
315 h: {
316 i: {
317 j: {
318 k: {
319 l: {
320 m: {
321 foo: 'bar'
322 }
323 }
324 }
325 }
326 }
327 }
328 }
329 }
330 }
331 }
332 }
333 }
334 }
335 };
336 const result = toXML(val);
337 const expectedResult = '<a><b><c><d><e><f><g><h><i><j><k><l><m><foo>bar</foo></m></l></k></j></i></h></g></f></e></d></c></b></a>';
338 assert.equal(result, expectedResult);
339 });
340 });
341
342 describe('header', () => {
343 it('default header', () => {
344 const val = {
345 foo: 'bar'
346 };
347 const config = {
348 header: true
349 };
350 const result = toXML(val, config);
351 const expectedResult = '<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>';
352 assert.equal(result, expectedResult);
353 });
354
355 it('no header', () => {
356 const val = {
357 foo: 'bar'
358 };
359 const config = {
360 header: false
361 };
362 const result = toXML(val, config);
363 const expectedResult = '<foo>bar</foo>';
364 assert.equal(result, expectedResult);
365 });
366
367 it('no header by default', () => {
368 const val = {
369 foo: 'bar'
370 };
371 const result = toXML(val);
372 const expectedResult = '<foo>bar</foo>';
373 assert.equal(result, expectedResult);
374 });
375
376 it('default header with indent', () => {
377 const val = {
378 foo: 'bar'
379 };
380 const config = {
381 header: true,
382 indent: ' '
383 };
384 const result = toXML(val, config);
385 const expectedResult = '<?xml version="1.0" encoding="UTF-8"?>\n<foo>bar</foo>';
386 assert.equal(result, expectedResult);
387 });
388
389 it('custom header', () => {
390 const val = {
391 foo: 'bar'
392 };
393 const config = {
394 header: '<?FOO BAR="123" BAZ="XX"?>'
395 };
396 const result = toXML(val, config);
397 const expectedResult = '<?FOO BAR="123" BAZ="XX"?><foo>bar</foo>';
398 assert.equal(result, expectedResult);
399 });
400 });
401
402 describe('filtering', () => {
403 it('values', () => {
404 const val = {
405 foo: '<a>',
406 bar: '"b"',
407 baz: '\'&whee\''
408 };
409 const config = {
410 filter: {
411 '<': '&lt;',
412 '>': '&gt;',
413 '"': '&quot;',
414 '\'': '&apos;',
415 '&': '&amp;'
416 }
417 };
418 const result = toXML(val, config);
419 const expectedResult =
420 '<foo>&lt;a&gt;</foo><bar>&quot;b&quot;</bar><baz>&apos;&amp;whee&apos;</baz>';
421 assert.equal(result, expectedResult);
422 });
423
424 it('attributes', () => {
425 const val = {
426 _name: 'foo',
427 _attrs: { a: '<"\'&"foo>' }
428 };
429 const config = {
430 attributesFilter: {
431 '<': '&lt;',
432 '>': '&gt;',
433 '"': '&quot;',
434 '\'': '&apos;',
435 '&': '&amp;'
436 }
437 };
438 const result = toXML(val, config);
439 const expectedResult = '<foo a="&lt;&quot;&apos;&amp;&quot;foo&gt;"/>';
440 assert.equal(result, expectedResult);
441 });
442 });
443
444 describe('misc', () => {
445 it('outputs <_content> if it has no tag name', () => {
446 const val = {
447 _content: 'foo'
448 };
449 const result = toXML(val);
450 const expectedResult = '<_content>foo</_content>';
451 assert.equal(result, expectedResult);
452 });
453
454 it('outputs emoji attributes', () => {
455 const val = {
456 html: {
457 _attrs: [
458 { '⚡': true },
459 { lang: 'en' },
460 { lang: 'klingon' }
461 ]
462 }
463 };
464 const result = toXML(val);
465 const expectedResult = '<html ⚡ lang="en" lang="klingon"/>';
466 assert.equal(result, expectedResult);
467 });
468
469 it('does not force self close if tag has content', () => {
470 const val = {
471 _name: 'foo',
472 _selfCloseTag: true,
473 _content: 'bar'
474 };
475 const result = toXML(val);
476 const expectedResult = '<foo>bar</foo>';
477 assert.equal(result, expectedResult);
478 });
479
480 it('nested elements with self-closing sibling', () => {
481 const val = {
482 people: {
483 students: [
484 {
485 student: { name: 'Joe' }
486 },
487 {
488 student: { name: 'Jane' }
489 }
490 ],
491 teacher: {
492 _selfCloseTag: true,
493 _attrs: {
494 name: 'Yoda'
495 }
496 }
497 }
498 };
499 const result = toXML(val);
500 const expectedResult = '<people><students><student><name>Joe</name></student><student><name>Jane</name></student></students><teacher name="Yoda"/></people>';
501 assert.equal(result, expectedResult);
502 });
503
504 it('sibling _content tag', () => {
505 const val = {
506 foo: {
507 bar: 'baz',
508 _content: {
509 bar2: 'baz2'
510 }
511 }
512 };
513 const result = toXML(val);
514 const expectedResult = '<foo><bar>baz</bar><bar2>baz2</bar2></foo>';
515 assert.equal(result, expectedResult);
516 });
517 });
518
519 describe('examples', () => {
520 it('1 simple object', () => {
521 const val = {
522 foo: 'bar',
523 foo2: 'bar2'
524 };
525 const result = toXML(val);
526 const expectedResult = '<foo>bar</foo><foo2>bar2</foo2>';
527 assert.equal(result, expectedResult);
528 });
529
530 it('2 simple array', () => {
531 const val = [
532 { foo: 'bar' },
533 { foo: 'bar2' }
534 ];
535 const result = toXML(val);
536 const expectedResult = '<foo>bar</foo><foo>bar2</foo>';
537 assert.equal(result, expectedResult);
538 });
539
540 it('3 simple function', () => {
541 const date = new Date();
542 const val = {
543 currentTime: () => date
544 };
545 const result = toXML(val);
546 const expectedResult = `<currentTime>${date}</currentTime>`;
547 assert.equal(result, expectedResult);
548 });
549
550 it('4 attributes', () => {
551 const val = {
552 _name: 'foo',
553 _content: 'bar',
554 _attrs: {
555 a: 'b',
556 c: 'd'
557 }
558 };
559 const result = toXML(val);
560 const expectedResult = '<foo a="b" c="d">bar</foo>';
561 assert.equal(result, expectedResult);
562 });
563
564 it('5 tags with mixed content', () => {
565 const val = {
566 text1: null,
567 foo: 'bar',
568 text2: null
569 };
570 const result = toXML(val);
571 const expectedResult = 'text1<foo>bar</foo>text2';
572 assert.equal(result, expectedResult);
573 });
574
575 it('6 nested tags with indent', () => {
576 const val = {
577 a: {
578 foo: 'bar',
579 foo2: 'bar2'
580 }
581 };
582 const config = {
583 header: false,
584 indent: ' '
585 };
586 const result = toXML(val, config);
587 const expectedResult = `<a>
588 <foo>bar</foo>
589 <foo2>bar2</foo2>
590</a>`;
591 assert.equal(result, expectedResult);
592 });
593
594 it('7 nested tags attributes', () => {
595 const val = {
596 ooo: {
597 _name: 'foo',
598 _attrs: {
599 a: 'b'
600 },
601 _content: {
602 _name: 'bar',
603 _attrs: {
604 c: 'd'
605 }
606 }
607 }
608 };
609 const config = {
610 header: false,
611 indent: ' '
612 };
613 const result = toXML(val, config);
614 const expectedResult = `<ooo>
615 <foo a="b">
616 <bar c="d"/>
617 </foo>
618</ooo>`;
619 assert.equal(result, expectedResult);
620 });
621
622 it('8 complex functions', () => {
623 const val = {
624 someNestedXML: () => ({ foo: 'bar' })
625 };
626 const result = toXML(val);
627 const expectedResult = '<someNestedXML><foo>bar</foo></someNestedXML>';
628 assert.equal(result, expectedResult);
629 });
630
631 it('9 RSS feed', () => {
632 const date = new Date();
633
634 const val = {
635 _name: 'rss',
636 _attrs: {
637 version: '2.0'
638 },
639 _content: {
640 channel: [
641 { title: 'RSS Example' },
642 { description: 'Description' },
643 { link: 'google.com' },
644 { lastBuildDate: () => date },
645 { pubDate: () => date },
646 { language: 'en' },
647 { item: {
648 title: 'Item title',
649 link: 'Item link',
650 description: 'Item Description',
651 pubDate: () => date
652 } },
653 { item: {
654 title: 'Item2 title',
655 link: 'Item2 link',
656 description: 'Item2 Description',
657 pubDate: () => date
658 } }
659 ]
660 }
661 };
662 const config = {
663 header: true,
664 indent: ' '
665 };
666 const result = toXML(val, config);
667 const expectedResult = `<?xml version="1.0" encoding="UTF-8"?>
668<rss version="2.0">
669 <channel>
670 <title>RSS Example</title>
671 <description>Description</description>
672 <link>google.com</link>
673 <lastBuildDate>${date}</lastBuildDate>
674 <pubDate>${date}</pubDate>
675 <language>en</language>
676 <item>
677 <title>Item title</title>
678 <link>Item link</link>
679 <description>Item Description</description>
680 <pubDate>${date}</pubDate>
681 </item>
682 <item>
683 <title>Item2 title</title>
684 <link>Item2 link</link>
685 <description>Item2 Description</description>
686 <pubDate>${date}</pubDate>
687 </item>
688 </channel>
689</rss>`;
690 assert.equal(result, expectedResult);
691 });
692
693 it('10 podcast RSS', () => {
694 const val = {
695 _name: 'rss',
696 _attrs: {
697 'xmlns:itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd',
698 version: '2.0'
699 },
700 _content: {
701 channel: [
702 { title: 'Title' },
703 { link: 'google.com' },
704 { language: 'en-us' },
705 { copyright: 'Copyright 2011' },
706 { 'itunes:subtitle': 'Subtitle' },
707 { 'itunes:author': 'Author' },
708 { 'itunes:summary': 'Summary' },
709 { description: 'Description' },
710 { 'itunes:owner': {
711 'itunes:name': 'Name',
712 'itunes:email': 'Email'
713 } },
714 {
715 _name: 'itunes:image',
716 _attrs: {
717 href: 'image.jpg'
718 }
719 },
720 {
721 _name: 'itunes:category',
722 _attrs: {
723 text: 'Technology'
724 },
725 _content: {
726 _name: 'itunes:category',
727 _attrs: {
728 text: 'Gadgets'
729 }
730 }
731 },
732 {
733 _name: 'itunes:category',
734 _attrs: {
735 text: 'TV &amp; Film'
736 }
737 },
738 {
739 item: [
740 { title: 'Podcast Title' },
741 { 'itunes:author': 'Author' },
742 { 'itunes:subtitle': 'Subtitle' },
743 { 'itunes:summary': 'Summary' },
744 { 'itunes:image': 'image.jpg' },
745 {
746 _name: 'enclosure',
747 _attrs: {
748 url: 'http://example.com/podcast.m4a',
749 length: '8727310',
750 type: 'audio/x-m4a'
751 }
752 },
753 { guid: 'http://example.com/archive/aae20050615.m4a' },
754 { pubDate: 'Wed, 15 Jun 2011 19:00:00 GMT' },
755 { 'itunes:duration': '7:04' },
756 { 'itunes:keywords': 'salt, pepper, shaker, exciting' }
757 ]
758 },
759 {
760 item: [
761 { title: 'Podcast2 Title' },
762 { 'itunes:author': 'Author2' },
763 { 'itunes:subtitle': 'Subtitle2' },
764 { 'itunes:summary': 'Summary2' },
765 { 'itunes:image': 'image2.jpg' },
766 {
767 _name: 'enclosure',
768 _attrs: {
769 url: 'http://example.com/podcast2.m4a',
770 length: '655555',
771 type: 'audio/x-m4a'
772 }
773 },
774 { guid: 'http://example.com/archive/aae2.m4a' },
775 { pubDate: 'Wed, 15 Jul 2011 19:00:00 GMT' },
776 { 'itunes:duration': '11:20' },
777 { 'itunes:keywords': 'foo, bar' }
778 ]
779 }
780 ]
781 }
782 };
783 const config = {
784 header: true,
785 indent: ' '
786 };
787
788 const result = toXML(val, config);
789 const expectedResult = `<?xml version="1.0" encoding="UTF-8"?>
790<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
791 <channel>
792 <title>Title</title>
793 <link>google.com</link>
794 <language>en-us</language>
795 <copyright>Copyright 2011</copyright>
796 <itunes:subtitle>Subtitle</itunes:subtitle>
797 <itunes:author>Author</itunes:author>
798 <itunes:summary>Summary</itunes:summary>
799 <description>Description</description>
800 <itunes:owner>
801 <itunes:name>Name</itunes:name>
802 <itunes:email>Email</itunes:email>
803 </itunes:owner>
804 <itunes:image href="image.jpg"/>
805 <itunes:category text="Technology">
806 <itunes:category text="Gadgets"/>
807 </itunes:category>
808 <itunes:category text="TV &amp; Film"/>
809 <item>
810 <title>Podcast Title</title>
811 <itunes:author>Author</itunes:author>
812 <itunes:subtitle>Subtitle</itunes:subtitle>
813 <itunes:summary>Summary</itunes:summary>
814 <itunes:image>image.jpg</itunes:image>
815 <enclosure url="http://example.com/podcast.m4a" length="8727310" type="audio/x-m4a"/>
816 <guid>http://example.com/archive/aae20050615.m4a</guid>
817 <pubDate>Wed, 15 Jun 2011 19:00:00 GMT</pubDate>
818 <itunes:duration>7:04</itunes:duration>
819 <itunes:keywords>salt, pepper, shaker, exciting</itunes:keywords>
820 </item>
821 <item>
822 <title>Podcast2 Title</title>
823 <itunes:author>Author2</itunes:author>
824 <itunes:subtitle>Subtitle2</itunes:subtitle>
825 <itunes:summary>Summary2</itunes:summary>
826 <itunes:image>image2.jpg</itunes:image>
827 <enclosure url="http://example.com/podcast2.m4a" length="655555" type="audio/x-m4a"/>
828 <guid>http://example.com/archive/aae2.m4a</guid>
829 <pubDate>Wed, 15 Jul 2011 19:00:00 GMT</pubDate>
830 <itunes:duration>11:20</itunes:duration>
831 <itunes:keywords>foo, bar</itunes:keywords>
832 </item>
833 </channel>
834</rss>`;
835 assert.equal(result, expectedResult);
836 });
837
838 it('11 filter', () => {
839 const val = {
840 foo: '<a>',
841 bar: '"b"',
842 baz: '\'&whee\''
843 };
844 const config = {
845 filter: {
846 '<': '&lt;',
847 '>': '&gt;',
848 '"': '&quot;',
849 '\'': '&apos;',
850 '&': '&amp;'
851 }
852 };
853 const result = toXML(val, config);
854 const expectedResult =
855 '<foo>&lt;a&gt;</foo><bar>&quot;b&quot;</bar><baz>&apos;&amp;whee&apos;</baz>';
856 assert.equal(result, expectedResult);
857 });
858
859 it('11b attributes filter', () => {
860 const val = {
861 _name: 'foo',
862 _content: 'bar',
863 _attrs: {
864 a: 'http://example.com/?test=\'1\'&foo=<bar>&whee="sha"',
865 b: 'http://example2.com/?test=\'2\'&md=<5>&sum="sha"'
866 }
867 };
868 const config = {
869 attributesFilter: {
870 '<': '&lt;',
871 '>': '&gt;',
872 '"': '&quot;',
873 '\'': '&apos;',
874 '&': '&amp;'
875 }
876 };
877 const result = toXML(val, config);
878 const expectedResult =
879 '<foo a="http://example.com/?test=&apos;1&apos;&amp;foo=&lt;bar&gt;&amp;whee=&quot;sha&quot;" b="http://example2.com/?test=&apos;2&apos;&amp;md=&lt;5&gt;&amp;sum=&quot;sha&quot;">bar</foo>';
880 assert.equal(result, expectedResult);
881 });
882
883 it('12 avoiding self closing tags', () => {
884 const val = [
885 {
886 _name: 'foo',
887 _content: '',
888 _selfCloseTag: false
889 },
890 {
891 _name: 'bar',
892 _content: undefined,
893 _selfCloseTag: false
894 }
895 ];
896 const result = toXML(val);
897 const expectedResult = '<foo></foo><bar></bar>';
898 assert.equal(result, expectedResult);
899 });
900
901 it('13 custom xml header', () => {
902 const val = {
903 foo: 'bar'
904 };
905 const config = {
906 header: '<?xml version="1.0" encoding="UTF-16" standalone="yes"?>'
907 };
908 const result = toXML(val, config);
909 const expectedResult =
910 '<?xml version="1.0" encoding="UTF-16" standalone="yes"?><foo>bar</foo>';
911 assert.equal(result, expectedResult);
912 });
913
914
915 it('14 emoji attributes', () => {
916 const val = {
917 html: {
918 _attrs: {
919 '⚡': true
920 }
921 }
922 };
923 const result = toXML(val);
924 const expectedResult = '<html ⚡/>';
925 assert.equal(result, expectedResult);
926 });
927
928 it('15 duplicate attribute keys', () => {
929 const val = {
930 html: {
931 _attrs: [
932 { lang: 'en' },
933 { lang: 'klingon' }
934 ]
935 }
936 };
937 const result = toXML(val);
938 const expectedResult = '<html lang="en" lang="klingon"/>';
939 assert.equal(result, expectedResult);
940 });
941
942 it('issue #33: array of primitives', () => {
943 const val = {
944 x: [1, 2, 3]
945 };
946 const result = toXML(val);
947 const expectedResult = '<x>1</x><x>2</x><x>3</x>';
948 assert.equal(result, expectedResult);
949 });
950
951 it('issue #33: array of primitives 2', () => {
952 const val = {
953 a: {
954 x: [1, 2, 3]
955 }
956 };
957 const result = toXML(val);
958 const expectedResult = '<a><x>1</x><x>2</x><x>3</x></a>';
959 assert.equal(result, expectedResult);
960 });
961
962 it('issue #33: array of primitives 2 with indent', () => {
963 const val = {
964 a: {
965 x: [1, 2, 3]
966 }
967 };
968 const config = { indent: ' ' };
969 const result = toXML(val, config);
970 const expectedResult = '<a>\n <x>1</x>\n <x>2</x>\n <x>3</x>\n</a>';
971 assert.equal(result, expectedResult);
972 });
973 it('issue #33: array of objects', ()=>{
974 const val = {
975 a: {
976 x: [{b:1,c:2},{d:3,e:4},{f:5,g:6}]
977 }
978 }
979 const result = toXML(val);
980 const expectedResult = '<a><x><b>1</b><c>2</c></x><x><d>3</d><e>4</e></x><x><f>5</f><g>6</g></x></a>'
981 });
982 it('issue #33: array of objects jstoxml format', () => {
983 const val = {
984 a: [
985 {
986 _name: 'foo',
987 _content: '1',
988 },
989 {
990 _name: 'foo',
991 _content: '2',
992 }
993 ]
994 };
995 const result = toXML(val);
996 const expectedResult = '<a><foo>1</foo><foo>2</foo></a>';
997 assert.equal(result, expectedResult);
998 });
999 it('issue #34: array of array', () => {
1000 const val = {
1001 Response: [
1002 [
1003 {
1004 _name: 'Play',
1005 _content: 'first sound'
1006 },
1007 {
1008 _name: 'Play',
1009 _content: 'second sound'
1010 }
1011 ]
1012 ]
1013 };
1014 const result = toXML(val);
1015 const expectedResult = '<Response><Play>first sound</Play><Play>second sound</Play></Response>';
1016 assert.equal(result, expectedResult);
1017 });
1018 it('issue #34', () => {
1019 const val = {t:[{foo: 'bar'},{foo: 'bar2'}]};
1020 const result = toXML(val);
1021 const expectedResult = '<t><foo>bar</foo><foo>bar2</foo></t>';
1022 assert.equal(result, expectedResult);
1023 });
1024 it('issue #34', () => {
1025 const val = {t:[{_name: "foo", _content: 'bar'},{_name: "foo", _content: 'bar2'}]};
1026 const result = toXML(val);
1027 const expectedResult = '<t><foo>bar</foo><foo>bar2</foo></t>';
1028 assert.equal(result, expectedResult);
1029 });
1030 });
1031});