test.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. var jstoxml = require('./jstoxml.js');
  2. (function(){
  3. var tests = [];
  4. var results = {
  5. testsRun: 0,
  6. pass: 0,
  7. fail: 0
  8. };
  9. var addTest = function(obj){
  10. tests.push(obj);
  11. };
  12. var showReport = function(){
  13. console.log(results);
  14. };
  15. var passFail = function(test){
  16. var output;
  17. try {
  18. output = test.input();
  19. results.testsRun++;
  20. if(output !== test.expectedOutput){
  21. console.log('OUTPUT:\n' + output + '\n\nEXPECTED OUTPUT:\n' + test.expectedOutput);
  22. console.log(test.name + ' \033[1;31mFAILED\033[0m\n ' + results.testsRun + '/' + tests.length);
  23. results.fail++;
  24. } else {
  25. console.log(test.name + ' passed. ' + results.testsRun + '/' + tests.length);
  26. results.pass++;
  27. }
  28. } catch(e) {
  29. console.log(test.name + ' failed. ' + results.testsRun + '/' + tests.length);
  30. console.log(e);
  31. }
  32. };
  33. var runTests = function(){
  34. for(var i=0, len=tests.length; i<len; i++){
  35. passFail(tests[i]);
  36. }
  37. };
  38. addTest({
  39. name: 'string',
  40. input: function(){
  41. return jstoxml.toXML('foo');
  42. },
  43. expectedOutput: 'foo'
  44. });
  45. addTest({
  46. name: 'boolean',
  47. input: function(){
  48. return jstoxml.toXML(true);
  49. },
  50. expectedOutput: 'true'
  51. });
  52. addTest({
  53. name: 'number',
  54. input: function(){
  55. return jstoxml.toXML(5);
  56. },
  57. expectedOutput: '5'
  58. });
  59. addTest({
  60. name: 'function',
  61. input: function(){
  62. return jstoxml.toXML(function(){
  63. return 999;
  64. });
  65. },
  66. expectedOutput: '999'
  67. });
  68. addTest({
  69. name: 'array',
  70. input: function(){
  71. return jstoxml.toXML([
  72. {foo: 'bar'},
  73. {foo2: 'bar2'}
  74. ]);
  75. },
  76. expectedOutput: '<foo>bar</foo><foo2>bar2</foo2>'
  77. });
  78. addTest({
  79. name: 'array-advanced',
  80. input: function(){
  81. return jstoxml.toXML([
  82. {foo: 'bar'},
  83. {foo2: 'bar2'}
  84. ]);
  85. },
  86. expectedOutput: '<foo>bar</foo><foo2>bar2</foo2>'
  87. });
  88. addTest({
  89. name: 'object',
  90. input: function(){
  91. return jstoxml.toXML({
  92. foo: 'bar',
  93. foo2: 'bar2'
  94. });
  95. },
  96. expectedOutput: '<foo>bar</foo><foo2>bar2</foo2>'
  97. });
  98. addTest({
  99. name: 'object-xml-header',
  100. input: function(){
  101. return jstoxml.toXML({
  102. foo: 'bar',
  103. foo2: 'bar2'
  104. }, {header: true});
  105. },
  106. expectedOutput: '<?xml version="1.0" encoding="UTF-8"?>\n<foo>bar</foo><foo2>bar2</foo2>'
  107. });
  108. addTest({
  109. name: 'object-with-tabs',
  110. input: function(){
  111. return jstoxml.toXML({
  112. a: {
  113. foo: 'bar',
  114. foo2: 'bar2'
  115. }
  116. }, {header: false, indent: ' '});
  117. },
  118. expectedOutput: '<a>\n <foo>bar</foo>\n <foo2>bar2</foo2>\n</a>\n'
  119. });
  120. addTest({
  121. name: 'object-with-attributes',
  122. input: function(){
  123. return jstoxml.toXML({
  124. _name: 'a',
  125. _attrs: {
  126. foo: 'bar',
  127. foo2: 'bar2'
  128. }
  129. });
  130. },
  131. expectedOutput: '<a foo="bar" foo2="bar2"/>'
  132. });
  133. addTest({
  134. name: 'object-with-attributes2',
  135. input: function(){
  136. return jstoxml.toXML({
  137. _name: 'a',
  138. _attrs: {
  139. foo: 'bar',
  140. foo2: 'bar2'
  141. },
  142. _content: 'la dee da'
  143. });
  144. },
  145. expectedOutput: '<a foo="bar" foo2="bar2">la dee da</a>'
  146. });
  147. addTest({
  148. name: 'object-mixed',
  149. input: function(){
  150. return jstoxml.toXML({
  151. 'blah': null,
  152. foo: 'bar',
  153. 'more blah': null,
  154. bar: 0,
  155. 'more more blah': null,
  156. baz: false
  157. });
  158. },
  159. expectedOutput: 'blah<foo>bar</foo>more blah<bar>0</bar>more more blah<baz>false</baz>'
  160. });
  161. addTest({
  162. name: 'object-nested',
  163. input: function(){
  164. return jstoxml.toXML({
  165. a: {
  166. foo: 'bar',
  167. foo2: 'bar2'
  168. }
  169. });
  170. },
  171. expectedOutput: '<a><foo>bar</foo><foo2>bar2</foo2></a>'
  172. });
  173. addTest({
  174. name: 'object-deep-nesting',
  175. input: function(){
  176. return jstoxml.toXML({
  177. a: {
  178. b: {
  179. c: {
  180. d: {
  181. e: {
  182. f: {
  183. g: {
  184. h: {
  185. i: {
  186. j: {
  187. k: {
  188. l: {
  189. m: {
  190. foo: 'bar'
  191. }
  192. }
  193. }
  194. }
  195. }
  196. }
  197. }
  198. }
  199. }
  200. }
  201. }
  202. }
  203. }
  204. });
  205. },
  206. expectedOutput: '<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>'
  207. });
  208. addTest({
  209. name: 'entities',
  210. input: function(){
  211. return jstoxml.toXML({
  212. foo: '<a>',
  213. bar: '"b"',
  214. baz: '\'&whee\''
  215. },
  216. {
  217. filter: {
  218. '<': '&lt;',
  219. '>': '&gt;',
  220. '"': '&quot;',
  221. '\'': '&apos;',
  222. '&': '&amp;'
  223. }
  224. });
  225. },
  226. expectedOutput: '<foo>&lt;a&gt;</foo><bar>&quot;b&quot;</bar><baz>&apos;&amp;whee&apos;</baz>'
  227. });
  228. addTest({
  229. name: 'example1-simple-object',
  230. input: function(){
  231. return jstoxml.toXML({
  232. foo: 'bar',
  233. foo2: 'bar2'
  234. });
  235. },
  236. expectedOutput: '<foo>bar</foo><foo2>bar2</foo2>'
  237. });
  238. addTest({
  239. name: 'example2-simple-array',
  240. input: function(){
  241. return jstoxml.toXML([
  242. {foo: 'bar'},
  243. {foo2: 'bar2'}
  244. ]);
  245. },
  246. expectedOutput: '<foo>bar</foo><foo2>bar2</foo2>'
  247. });
  248. addTest({
  249. name: 'example3-duplicate-tag-names',
  250. input: function(){
  251. return jstoxml.toXML([
  252. {foo: 'bar'},
  253. {foo: 'bar2'}
  254. ]);
  255. },
  256. expectedOutput: '<foo>bar</foo><foo>bar2</foo>'
  257. });
  258. addTest({
  259. name: 'example4-attributes',
  260. input: function(){
  261. return jstoxml.toXML({
  262. _name: 'foo',
  263. _content: 'bar',
  264. _attrs: {
  265. a: 'b',
  266. c: 'd'
  267. }
  268. });
  269. },
  270. expectedOutput: '<foo a="b" c="d">bar</foo>'
  271. });
  272. addTest({
  273. name: 'example5-tags-with-text-nodes',
  274. input: function(){
  275. return jstoxml.toXML({
  276. 'text1': null,
  277. foo: 'bar',
  278. 'text2': null
  279. });
  280. },
  281. expectedOutput: 'text1<foo>bar</foo>text2'
  282. });
  283. addTest({
  284. name: 'example6-nested-tags-with-indenting',
  285. input: function(){
  286. return jstoxml.toXML({
  287. a: {
  288. foo: 'bar',
  289. foo2: 'bar2'
  290. }
  291. }, {header: false, indent: ' '});
  292. },
  293. expectedOutput: '<a>\n <foo>bar</foo>\n <foo2>bar2</foo2>\n</a>\n'
  294. });
  295. addTest({
  296. name: 'example7-nested-tags-with-attributes',
  297. input: function(){
  298. return jstoxml.toXML({
  299. ooo: {
  300. _name: 'foo',
  301. _attrs: {
  302. a: 'b'
  303. },
  304. _content: {
  305. _name: 'bar',
  306. _attrs: {
  307. c: 'd'
  308. }
  309. }
  310. }
  311. }, {header: false, indent: ' '});
  312. },
  313. expectedOutput: '<ooo>\n <foo a="b">\n <bar c="d"/>\n </foo>\n</ooo>\n'
  314. });
  315. addTest({
  316. name: 'example7b',
  317. input: function(){
  318. var bar = {
  319. _name: 'bar',
  320. _attrs: {
  321. c: 'd'
  322. }
  323. };
  324. var foo = {
  325. _name: 'foo',
  326. _attrs: {
  327. a: 'b'
  328. },
  329. _content: bar
  330. };
  331. return jstoxml.toXML({
  332. ooo: foo
  333. }, {header: false, indent: ' '});
  334. },
  335. expectedOutput: '<ooo>\n <foo a="b">\n <bar c="d"/>\n </foo>\n</ooo>\n'
  336. });
  337. addTest({
  338. name: 'example8-functions',
  339. input: function(){
  340. return jstoxml.toXML({
  341. onePlusTwo: function(){
  342. return 1 + 2;
  343. }
  344. });
  345. },
  346. expectedOutput: '<onePlusTwo>3</onePlusTwo>'
  347. });
  348. addTest({
  349. name: 'example9-rss-feed',
  350. input: function(){
  351. return jstoxml.toXML({
  352. _name: 'rss',
  353. _attrs: {
  354. version: '2.0'
  355. },
  356. _content: {
  357. channel: [
  358. {title: 'RSS Example'},
  359. {description: 'Description'},
  360. {link: 'google.com'},
  361. {lastBuildDate: function(){
  362. return 'Sat Jul 30 2011 18:14:25 GMT+0900 (JST)';
  363. }},
  364. {pubDate: function(){
  365. return 'Sat Jul 30 2011 18:14:25 GMT+0900 (JST)';
  366. }},
  367. {language: 'en'},
  368. {item: {
  369. title: 'Item title',
  370. link: 'Item link',
  371. description: 'Item Description',
  372. pubDate: function(){
  373. return 'Sat Jul 30 2011 18:33:47 GMT+0900 (JST)';
  374. }
  375. }},
  376. {item: {
  377. title: 'Item2 title',
  378. link: 'Item2 link',
  379. description: 'Item2 Description',
  380. pubDate: function(){
  381. return 'Sat Jul 30 2011 18:33:47 GMT+0900 (JST)';
  382. }
  383. }}
  384. ]
  385. }
  386. }, {header: true, indent: ' '});
  387. },
  388. expectedOutput: '<?xml version="1.0" encoding="UTF-8"?>\n<rss version="2.0">\n <channel>\n <title>RSS Example</title>\n <description>Description</description>\n <link>google.com</link>\n <lastBuildDate>Sat Jul 30 2011 18:14:25 GMT+0900 (JST)</lastBuildDate>\n <pubDate>Sat Jul 30 2011 18:14:25 GMT+0900 (JST)</pubDate>\n <language>en</language>\n <item>\n <title>Item title</title>\n <link>Item link</link>\n <description>Item Description</description>\n <pubDate>Sat Jul 30 2011 18:33:47 GMT+0900 (JST)</pubDate>\n </item>\n <item>\n <title>Item2 title</title>\n <link>Item2 link</link>\n <description>Item2 Description</description>\n <pubDate>Sat Jul 30 2011 18:33:47 GMT+0900 (JST)</pubDate>\n </item>\n </channel>\n</rss>\n'
  389. });
  390. addTest({
  391. name: 'example10-podcast',
  392. input: function(){
  393. return jstoxml.toXML({
  394. _name: 'rss',
  395. _attrs: {
  396. 'xmlns:itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd',
  397. version: '2.0'
  398. },
  399. _content: {
  400. channel: [
  401. {title: 'Title'},
  402. {link: 'google.com'},
  403. {language: 'en-us'},
  404. {copyright: 'Copyright 2011'},
  405. {'itunes:subtitle': 'Subtitle'},
  406. {'itunes:author': 'Author'},
  407. {'itunes:summary': 'Summary'},
  408. {description: 'Description'},
  409. {'itunes:owner': {
  410. 'itunes:name': 'Name',
  411. 'itunes:email': 'Email'
  412. }},
  413. {
  414. _name: 'itunes:image',
  415. _attrs: {
  416. href: 'image.jpg'
  417. }
  418. },
  419. {
  420. _name: 'itunes:category',
  421. _attrs: {
  422. text: 'Technology'
  423. },
  424. _content: {
  425. _name: 'itunes:category',
  426. _attrs: {
  427. text: 'Gadgets'
  428. }
  429. }
  430. },
  431. {
  432. _name: 'itunes:category',
  433. _attrs: {
  434. text: 'TV &amp; Film'
  435. }
  436. },
  437. {
  438. item: [
  439. {title: 'Podcast Title'},
  440. {'itunes:author': 'Author'},
  441. {'itunes:subtitle': 'Subtitle'},
  442. {'itunes:summary': 'Summary'},
  443. {'itunes:image': 'image.jpg'},
  444. {
  445. _name: 'enclosure',
  446. _attrs: {
  447. url: 'http://example.com/podcast.m4a',
  448. length: '8727310',
  449. type: 'audio/x-m4a'
  450. }
  451. },
  452. {guid: 'http://example.com/archive/aae20050615.m4a'},
  453. {pubDate: 'Wed, 15 Jun 2011 19:00:00 GMT'},
  454. {'itunes:duration': '7:04'},
  455. {'itunes:keywords': 'salt, pepper, shaker, exciting'}
  456. ]
  457. },
  458. {
  459. item: [
  460. {title: 'Podcast2 Title'},
  461. {'itunes:author': 'Author2'},
  462. {'itunes:subtitle': 'Subtitle2'},
  463. {'itunes:summary': 'Summary2'},
  464. {'itunes:image': 'image2.jpg'},
  465. {
  466. _name: 'enclosure',
  467. _attrs: {
  468. url: 'http://example.com/podcast2.m4a',
  469. length: '655555',
  470. type: 'audio/x-m4a'
  471. }
  472. },
  473. {guid: 'http://example.com/archive/aae2.m4a'},
  474. {pubDate: 'Wed, 15 Jul 2011 19:00:00 GMT'},
  475. {'itunes:duration': '11:20'},
  476. {'itunes:keywords': 'foo, bar'}
  477. ]
  478. }
  479. ]
  480. }
  481. }, {header: true, indent: ' '});
  482. },
  483. expectedOutput: '<?xml version="1.0" encoding="UTF-8"?>\n<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">\n <channel>\n <title>Title</title>\n <link>google.com</link>\n <language>en-us</language>\n <copyright>Copyright 2011</copyright>\n <itunes:subtitle>Subtitle</itunes:subtitle>\n <itunes:author>Author</itunes:author>\n <itunes:summary>Summary</itunes:summary>\n <description>Description</description>\n <itunes:owner>\n <itunes:name>Name</itunes:name>\n <itunes:email>Email</itunes:email>\n </itunes:owner>\n <itunes:image href="image.jpg"/>\n <itunes:category text="Technology">\n <itunes:category text="Gadgets"/>\n </itunes:category>\n <itunes:category text="TV &amp; Film"/>\n <item>\n <title>Podcast Title</title>\n <itunes:author>Author</itunes:author>\n <itunes:subtitle>Subtitle</itunes:subtitle>\n <itunes:summary>Summary</itunes:summary>\n <itunes:image>image.jpg</itunes:image>\n <enclosure url="http://example.com/podcast.m4a" length="8727310" type="audio/x-m4a"/>\n <guid>http://example.com/archive/aae20050615.m4a</guid>\n <pubDate>Wed, 15 Jun 2011 19:00:00 GMT</pubDate>\n <itunes:duration>7:04</itunes:duration>\n <itunes:keywords>salt, pepper, shaker, exciting</itunes:keywords>\n </item>\n <item>\n <title>Podcast2 Title</title>\n <itunes:author>Author2</itunes:author>\n <itunes:subtitle>Subtitle2</itunes:subtitle>\n <itunes:summary>Summary2</itunes:summary>\n <itunes:image>image2.jpg</itunes:image>\n <enclosure url="http://example.com/podcast2.m4a" length="655555" type="audio/x-m4a"/>\n <guid>http://example.com/archive/aae2.m4a</guid>\n <pubDate>Wed, 15 Jul 2011 19:00:00 GMT</pubDate>\n <itunes:duration>11:20</itunes:duration>\n <itunes:keywords>foo, bar</itunes:keywords>\n </item>\n </channel>\n</rss>\n'
  484. });
  485. addTest({
  486. name: 'bug3',
  487. input: function(){
  488. return jstoxml.toXML({
  489. foo: true,
  490. bar: '',
  491. foo2: false,
  492. ok: 'This is ok',
  493. ok2: 'false',
  494. ok3: 'true'
  495. });
  496. },
  497. expectedOutput: '<foo>true</foo><bar></bar><foo2>false</foo2><ok>This is ok</ok><ok2>false</ok2><ok3>true</ok3>'
  498. });
  499. addTest({
  500. name: 'bug4a',
  501. input: function(){
  502. return jstoxml.toXML({
  503. foo: 4,
  504. bar: '&'
  505. });
  506. },
  507. expectedOutput: '<foo>4</foo><bar>&</bar>'
  508. });
  509. addTest({
  510. name: 'bug4b',
  511. input: function(){
  512. return jstoxml.toXML({
  513. foo: '&'
  514. },
  515. {
  516. filter: {
  517. '&': '&amp;'
  518. }
  519. });
  520. },
  521. expectedOutput: '<foo>&amp;</foo>'
  522. });
  523. addTest({
  524. name: 'headerNone',
  525. input: function(){
  526. return jstoxml.toXML({
  527. foo: 4
  528. },
  529. {
  530. header: false
  531. });
  532. },
  533. expectedOutput: '<foo>4</foo>'
  534. });
  535. addTest({
  536. name: 'headerDefault',
  537. input: function(){
  538. return jstoxml.toXML({
  539. foo: 4
  540. },
  541. {
  542. header: true
  543. });
  544. },
  545. expectedOutput: '<?xml version="1.0" encoding="UTF-8"?>\n<foo>4</foo>'
  546. });
  547. addTest({
  548. name: 'headerCustom',
  549. input: function(){
  550. return jstoxml.toXML({
  551. foo: 4
  552. },
  553. {
  554. header: '<Hooray For Captain Spaulding, the African Explorer>\n'
  555. });
  556. },
  557. expectedOutput: '<Hooray For Captain Spaulding, the African Explorer>\n<foo>4</foo>'
  558. });
  559. addTest({
  560. name: 'nested-elements-with-self-closing-sibling',
  561. input: function(){
  562. return jstoxml.toXML({
  563. people: {
  564. students: [
  565. {
  566. student: { name: 'Joe' }
  567. },
  568. {
  569. student: { name: 'Jane' }
  570. }
  571. ],
  572. teacher: {
  573. _selfCloseTag: true,
  574. _attrs: {
  575. 'name': 'Yoda'
  576. }
  577. }
  578. }
  579. });
  580. },
  581. expectedOutput: [
  582. '<people>',
  583. '<students>',
  584. '<student><name>Joe</name></student>',
  585. '<student><name>Jane</name></student>',
  586. '</students>',
  587. '<teacher name="Yoda"/>',
  588. '</people>'
  589. ].join('')
  590. });
  591. runTests();
  592. showReport();
  593. // Exit with 1 to signal a failed build
  594. if(results.fail > 0) {
  595. process.exit(1);
  596. }
  597. })();