Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

583 Zeilen
12KB

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