You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

593 lines
12KB

  1. test("Parser", function() {
  2. expect(3);
  3. // matches whitespace_partial.html
  4. equals(
  5. Mustache.to_html(
  6. '<h1>{{ greeting }}</h1>\n{{> partial }}\n<h3>{{ farewell }}</h3>',
  7. {
  8. greeting: function() {
  9. return "Welcome";
  10. },
  11. farewell: function() {
  12. return "Fair enough, right?";
  13. },
  14. partial: {
  15. name: "Chris",
  16. value: 10000,
  17. taxed_value: function() {
  18. return this.value - (this.value * 0.4);
  19. },
  20. in_ca: true
  21. }
  22. },
  23. {partial:'Hello {{ name}}\nYou have just won ${{value }}!\n{{# in_ca }}\nWell, ${{ taxed_value }}, after taxes.\n{{/ in_ca }}\n'}
  24. ),
  25. '<h1>Welcome</h1>\nHello Chris\nYou have just won $10000!\n\nWell, $6000, after taxes.\n\n\n<h3>Fair enough, right?</h3>',
  26. 'Whitespace in Tag names'
  27. );
  28. equals(
  29. Mustache.to_html(
  30. '{{tag1}}\n\n\n{{tag2}}\n',
  31. { tag1: 'Hello', tag2: 'World' },
  32. {}
  33. ),
  34. 'Hello\n\n\nWorld\n',
  35. 'Preservation of white space'
  36. );
  37. try {
  38. Mustache.to_html(
  39. '{{=tag1}}',
  40. { tag1: 'Hello' },
  41. {}
  42. );
  43. ok(false);
  44. } catch (e) {
  45. equals(e.message, 'Unexpected end of document.');
  46. }
  47. });
  48. test("Compiler", function() {
  49. expect(3);
  50. var template = Mustache.compile('the grand poobah says: {{variable}}.', {});
  51. equals(template({variable: 'hello'}), 'the grand poobah says: hello.');
  52. template = Mustache.compile('the grand poobah says: {{>partial}}.', {partial: 'i love {{sugar}}'});
  53. equals(template({sugar: 'chocolate'}), 'the grand poobah says: i love chocolate.');
  54. template = Mustache.compile('the grand poobah says: {{#hos}}i love chocolate{{/hos}}.', {});
  55. equals(template({hos:function() { return function(text, renderer) { return '<b>' + text + '</b>'; } }}), 'the grand poobah says: <b>i love chocolate</b>.');
  56. });
  57. test("Basic Variables", function() {
  58. expect(3);
  59. // matches escaped.html
  60. equals(
  61. Mustache.to_html(
  62. '<h1>{{title}}</h1>\nBut not {{entities}}.\n',
  63. {
  64. title: function() {
  65. return "Bear > Shark";
  66. },
  67. entities: "&quot;"
  68. },
  69. {}
  70. ),
  71. '<h1>Bear &gt; Shark</h1>\nBut not &amp;quot;.\n',
  72. 'HTML Escaping'
  73. );
  74. // matches null_string.html
  75. equals(
  76. Mustache.to_html(
  77. 'Hello {{name}}\nglytch {{glytch}}\nbinary {{binary}}\nvalue {{value}}\nnumeric {{numeric}}',
  78. {
  79. name: "Elise",
  80. glytch: true,
  81. binary: false,
  82. value: null,
  83. numeric: function() {
  84. return NaN;
  85. }
  86. },
  87. {}
  88. ),
  89. 'Hello Elise\nglytch true\nbinary false\nvalue \nnumeric NaN',
  90. 'Different variable types'
  91. );
  92. // matches two_in_a_row.html
  93. equals(
  94. Mustache.to_html(
  95. '{{greeting}}, {{name}}!',
  96. {
  97. name: "Joe",
  98. greeting: "Welcome"
  99. },
  100. {}
  101. ),
  102. 'Welcome, Joe!'
  103. );
  104. });
  105. test("'{' or '&' (Unescaped Variable)", function() {
  106. expect(2);
  107. // matches unescaped.html
  108. equals(
  109. Mustache.to_html(
  110. '<h1>{{{title}}}</h1>',
  111. {
  112. title: function() {
  113. return "Bear > Shark";
  114. }
  115. },
  116. {}
  117. ),
  118. '<h1>Bear > Shark</h1>',
  119. '{ character'
  120. );
  121. equals(
  122. Mustache.to_html(
  123. '<h1>{{&title}}</h1>',
  124. {
  125. title: function() {
  126. return "Bear > Shark";
  127. }
  128. },
  129. {}
  130. ),
  131. '<h1>Bear > Shark</h1>',
  132. '& character'
  133. );
  134. });
  135. test("'#' (Sections)", function() {
  136. expect(7);
  137. // matches array_of_partials_implicit_partial.html
  138. equals(
  139. Mustache.to_html(
  140. 'Here is some stuff!\n{{#numbers}}\n{{>partial}}\n{{/numbers}}',
  141. { numbers: ['1', '2', '3', '4'] },
  142. { partial: '{{.}}' }
  143. ),
  144. 'Here is some stuff!\n\n1\n\n2\n\n3\n\n4\n',
  145. 'Array of Partials (Implicit)'
  146. );
  147. // matches array_of_partials_partial.html
  148. equals(
  149. Mustache.to_html(
  150. 'Here is some stuff!\n{{#numbers}}\n{{>partial}}\n{{/numbers}}',
  151. { numbers: [{i: '1'}, {i: '2'}, {i: '3'}, {i: '4'}] },
  152. { partial: '{{i}}' }
  153. ),
  154. 'Here is some stuff!\n\n1\n\n2\n\n3\n\n4\n',
  155. 'Array of Partials (Explicit)'
  156. );
  157. // matches array_of_strings.html
  158. equals(
  159. Mustache.to_html(
  160. '{{#array_of_strings}}{{.}} {{/array_of_strings}}',
  161. {array_of_strings: ['hello', 'world']},
  162. {}
  163. ),
  164. 'hello world ',
  165. 'Array of Strings'
  166. );
  167. // mathces higher_order_sections.html
  168. equals(
  169. Mustache.to_html(
  170. '{{#bolder}}Hi {{name}}.{{/bolder}}\n',
  171. {
  172. "name": "Tater",
  173. "helper": "To tinker?",
  174. "bolder": function() {
  175. return function(text, render) {
  176. return "<b>" + render(text) + '</b> ' + this.helper;
  177. }
  178. }
  179. },
  180. {}
  181. ),
  182. '<b>Hi Tater.</b> To tinker?\n'
  183. );
  184. // matches recursion_with_same_names.html
  185. equals(
  186. Mustache.to_html(
  187. '{{ name }}\n{{ description }}\n\n{{#terms}}\n {{name}}\n {{index}}\n{{/terms}}\n',
  188. {
  189. name: 'name',
  190. description: 'desc',
  191. terms: [
  192. {name: 't1', index: 0},
  193. {name: 't2', index: 1},
  194. ]
  195. },
  196. {}
  197. ),
  198. 'name\ndesc\n\n\n t1\n 0\n\n t2\n 1\n\n'
  199. );
  200. // matches reuse_of_enumerables.html
  201. equals(
  202. Mustache.to_html(
  203. '{{#terms}}\n {{name}}\n {{index}}\n{{/terms}}\n{{#terms}}\n {{name}}\n {{index}}\n{{/terms}}\n',
  204. {
  205. terms: [
  206. {name: 't1', index: 0},
  207. {name: 't2', index: 1},
  208. ]
  209. },
  210. {}
  211. ),
  212. '\n t1\n 0\n t2\n 1\n\n t1\n 0\n t2\n 1\n\n',
  213. 'Lazy match of Section and Inverted Section'
  214. );
  215. // matches section_as_context.html
  216. equals(
  217. Mustache.to_html(
  218. '{{#a_object}}\n <h1>{{title}}</h1>\n <p>{{description}}</p>\n <ul>\n {{#a_list}}\n <li>{{label}}</li>\n {{/a_list}}\n </ul>\n{{/a_object}}\n',
  219. {
  220. a_object: {
  221. title: 'this is an object',
  222. description: 'one of its attributes is a list',
  223. a_list: [{label: 'listitem1'}, {label: 'listitem2'}]
  224. }
  225. },
  226. {}
  227. ),
  228. '\n <h1>this is an object</h1>\n <p>one of its attributes is a list</p>\n <ul>\n <li>listitem1</li>\n <li>listitem2</li>\n </ul>\n',
  229. 'Lazy match of Section and Inverted Section'
  230. );
  231. });
  232. test("'^' (Inverted Section)", function() {
  233. expect(1);
  234. // matches inverted_section.html
  235. equals(
  236. Mustache.to_html(
  237. '{{#repo}}<b>{{name}}</b>{{/repo}}\n{{^repo}}No repos :({{/repo}}\n',
  238. {
  239. "repo": []
  240. },
  241. {}
  242. ),
  243. '\nNo repos :(\n'
  244. );
  245. });
  246. test("'>' (Partials)", function() {
  247. expect(5);
  248. // matches view_partial.html
  249. equals(
  250. Mustache.to_html(
  251. '<h1>{{greeting}}</h1>\n{{>partial}}\n<h3>{{farewell}}</h3>',
  252. {
  253. greeting: function() {
  254. return "Welcome";
  255. },
  256. farewell: function() {
  257. return "Fair enough, right?";
  258. },
  259. partial: {
  260. name: "Chris",
  261. value: 10000,
  262. taxed_value: function() {
  263. return this.value - (this.value * 0.4);
  264. },
  265. in_ca: true
  266. }
  267. },
  268. {partial: 'Hello {{name}}\nYou have just won ${{value}}!\n{{#in_ca}}\nWell, ${{ taxed_value }}, after taxes.\n{{/in_ca}}\n'}
  269. ),
  270. '<h1>Welcome</h1>\nHello Chris\nYou have just won $10000!\n\nWell, $6000, after taxes.\n\n\n<h3>Fair enough, right?</h3>'
  271. );
  272. // matches array_partial.html
  273. equals(
  274. Mustache.to_html(
  275. '{{>partial}}',
  276. {
  277. partial: {
  278. array: ['1', '2', '3', '4']
  279. }
  280. },
  281. { partial: 'Here\'s a non-sense array of values\n{{#array}}\n {{.}}\n{{/array}}' }
  282. ),
  283. 'Here\'s a non-sense array of values\n\n 1\n\n 2\n\n 3\n\n 4\n'
  284. );
  285. // matches template_partial.html
  286. equals(
  287. Mustache.to_html(
  288. '<h1>{{title}}</h1>\n{{>partial}}',
  289. {
  290. title: function() {
  291. return "Welcome";
  292. },
  293. partial: {
  294. again: "Goodbye"
  295. }
  296. },
  297. {partial:'Again, {{again}}!'}
  298. ),
  299. '<h1>Welcome</h1>\nAgain, Goodbye!'
  300. );
  301. // matches partial_recursion.html
  302. equals(
  303. Mustache.to_html(
  304. '{{name}}\n{{#kids}}\n{{>partial}}\n{{/kids}}',
  305. {
  306. name: '1',
  307. kids: [
  308. {
  309. name: '1.1',
  310. children: [
  311. {name: '1.1.1'}
  312. ]
  313. }
  314. ]
  315. },
  316. {partial:'{{name}}\n{{#children}}\n{{>partial}}\n{{/children}}'}
  317. ),
  318. '1\n\n1.1\n\n1.1.1\n\n\n'
  319. );
  320. try {
  321. Mustache.to_html(
  322. '{{>partial}}',
  323. {},
  324. {partal: ''}
  325. );
  326. ok(false);
  327. } catch(e) {
  328. equals(e.message, "Unknown partial 'partial'");
  329. }
  330. });
  331. test("'=' (Set Delimiter)", function() {
  332. expect(1);
  333. // matches delimiter.html
  334. equals(
  335. Mustache.to_html(
  336. '{{=<% %>=}}*\n<% first %>\n* <% second %>\n<%=| |=%>\n* | third |\n|={{ }}=|\n* {{ fourth }}',
  337. {
  338. first: "It worked the first time.",
  339. second: "And it worked the second time.",
  340. third: "Then, surprisingly, it worked the third time.",
  341. fourth: "Fourth time also fine!."
  342. },
  343. {}
  344. ),
  345. '*\nIt worked the first time.\n* And it worked the second time.\n\n* Then, surprisingly, it worked the third time.\n\n* Fourth time also fine!.',
  346. 'Simple Set Delimiter'
  347. );
  348. });
  349. test("'!' (Comments)", function() {
  350. expect(1);
  351. // matches comments.html
  352. equals(
  353. Mustache.to_html(
  354. '<h1>{{title}}{{! just something interesting... or not... }}</h1>\n',
  355. {
  356. title: function() {
  357. return "A Comedy of Errors";
  358. }
  359. },
  360. {}
  361. ),
  362. '<h1>A Comedy of Errors</h1>\n'
  363. );
  364. });
  365. test("'%' (Pragmas)", function() {
  366. expect(3);
  367. // matches array_of_strings_options.html
  368. equals(
  369. Mustache.to_html(
  370. '{{%IMPLICIT-ITERATOR iterator=rob}}\n{{#array_of_strings_options}}{{rob}} {{/array_of_strings_options}}',
  371. {array_of_strings_options: ['hello', 'world']},
  372. {}
  373. ),
  374. '\nhello world ',
  375. 'IMPLICIT-ITERATOR pragma'
  376. );
  377. // matches unknown_pragma.txt
  378. try {
  379. equals(
  380. Mustache.to_html(
  381. '{{%I-HAVE-THE-GREATEST-MUSTACHE}}\n',
  382. {},
  383. {}
  384. ),
  385. 'hello world ',
  386. 'IMPLICIT-ITERATOR pragma'
  387. );
  388. ok(false);
  389. } catch (e) {
  390. equals(e.message, 'This implementation of mustache doesn\'t understand the \'I-HAVE-THE-GREATEST-MUSTACHE\' pragma');
  391. }
  392. equals(
  393. Mustache.to_html(
  394. '{{%IMPLICIT-ITERATOR}}{{#dataSet}}{{.}}:{{/dataSet}}',
  395. { dataSet: [ 'Object 1', 'Object 2', 'Object 3' ] },
  396. {}
  397. ),
  398. "Object 1:Object 2:Object 3:"
  399. );
  400. });
  401. test("Empty", function() {
  402. expect(2);
  403. // matches empty_template.html
  404. equals(
  405. Mustache.to_html(
  406. '<html><head></head><body><h1>Test</h1></body></html>',
  407. {},
  408. {}
  409. ),
  410. '<html><head></head><body><h1>Test</h1></body></html>',
  411. 'Empty Template'
  412. );
  413. // matches empty_partial.html
  414. equals(
  415. Mustache.to_html(
  416. 'hey {{foo}}\n{{>partial}}\n',
  417. {
  418. foo: 1
  419. },
  420. {partial: 'yo'}
  421. ),
  422. 'hey 1\nyo\n',
  423. 'Empty Partial'
  424. );
  425. });
  426. test("Demo", function() {
  427. expect(2);
  428. // matches simple.html
  429. equals(
  430. Mustache.to_html(
  431. 'Hello {{name}}\nYou have just won ${{value}}!\n{{#in_ca}}\nWell, ${{ taxed_value }}, after taxes.\n{{/in_ca}}',
  432. {
  433. name: "Chris",
  434. value: 10000,
  435. taxed_value: function() {
  436. return this.value - (this.value * 0.4);
  437. },
  438. in_ca: true
  439. },
  440. {}
  441. ),
  442. 'Hello Chris\nYou have just won $10000!\n\nWell, $6000, after taxes.\n',
  443. 'A simple template'
  444. );
  445. // matches complex.html
  446. var template = [
  447. '<h1>{{header}}</h1>',
  448. '{{#list}}',
  449. ' <ul>',
  450. ' {{#item}}',
  451. ' {{#current}}',
  452. ' <li><strong>{{name}}</strong></li>',
  453. ' {{/current}}',
  454. ' {{#link}}',
  455. ' <li><a href="{{url}}">{{name}}</a></li>',
  456. ' {{/link}}',
  457. ' {{/item}}',
  458. ' </ul>',
  459. '{{/list}}',
  460. '{{#empty}}',
  461. ' <p>The list is empty.</p>',
  462. '{{/empty}}',
  463. ].join('\n');
  464. var view = {
  465. header: function() {
  466. return "Colors";
  467. },
  468. item: [
  469. {name: "red", current: true, url: "#Red"},
  470. {name: "green", current: false, url: "#Green"},
  471. {name: "blue", current: false, url: "#Blue"}
  472. ],
  473. link: function() {
  474. return this["current"] !== true;
  475. },
  476. list: function() {
  477. return this.item.length !== 0;
  478. },
  479. empty: function() {
  480. return this.item.length === 0;
  481. }
  482. };
  483. var expected_result = [
  484. '<h1>Colors</h1>',
  485. ' <ul>',
  486. ' <li><strong>red</strong></li>',
  487. ' <li><a href="#Green">green</a></li>',
  488. ' <li><a href="#Blue">blue</a></li>',
  489. ' </ul>',
  490. ''
  491. ].join('\n');
  492. equals(
  493. Mustache.to_html(
  494. template,
  495. view,
  496. {}
  497. ),
  498. expected_result,
  499. 'A complex template'
  500. );
  501. });
  502. test("Regression Suite", function() {
  503. expect(3);
  504. // matches bug_11_eating_whitespace.html
  505. equals(
  506. Mustache.to_html(
  507. '{{tag}} foo',
  508. { tag: "yo" },
  509. {}
  510. ),
  511. 'yo foo',
  512. 'Issue 11'
  513. );
  514. // matches delimiters_partial.html
  515. equals(
  516. Mustache.to_html(
  517. '{{#enumerate}}\n{{>partial}}\n{{/enumerate}}',
  518. { enumerate: [ { text: 'A' }, { text: 'B' } ] },
  519. { partial: '{{=[[ ]]=}}\n{{text}}\n[[={{ }}=]]' }
  520. ),
  521. '\n\n{{text}}\n\n\n\n{{text}}\n\n',
  522. 'Issue 44'
  523. );
  524. // matches bug_46_set_delimiter.html
  525. equals(
  526. Mustache.to_html(
  527. '{{=[[ ]]=}}[[#IsMustacheAwesome]]mustache is awesome![[/IsMustacheAwesome]]',
  528. {IsMustacheAwesome: true},
  529. {}
  530. ),
  531. 'mustache is awesome!',
  532. 'Issue 46'
  533. );
  534. });