25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

596 satır
12KB

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