TokenizerTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <?php
  2. /*
  3. * This file is part of Mustache.php.
  4. *
  5. * (c) 2010-2017 Justin Hileman
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. /**
  11. * @group unit
  12. */
  13. class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
  14. {
  15. /**
  16. * @dataProvider getTokens
  17. */
  18. public function testScan($text, $delimiters, $expected)
  19. {
  20. $tokenizer = new Mustache_Tokenizer();
  21. $this->assertSame($expected, $tokenizer->scan($text, $delimiters));
  22. }
  23. /**
  24. * @expectedException Mustache_Exception_SyntaxException
  25. */
  26. public function testUnevenBracesThrowExceptions()
  27. {
  28. $tokenizer = new Mustache_Tokenizer();
  29. $text = '{{{ name }}';
  30. $tokenizer->scan($text, null);
  31. }
  32. /**
  33. * @expectedException Mustache_Exception_SyntaxException
  34. */
  35. public function testUnevenBracesWithCustomDelimiterThrowExceptions()
  36. {
  37. $tokenizer = new Mustache_Tokenizer();
  38. $text = '<%{ name %>';
  39. $tokenizer->scan($text, '<% %>');
  40. }
  41. public function getTokens()
  42. {
  43. return array(
  44. array(
  45. 'text',
  46. null,
  47. array(
  48. array(
  49. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  50. Mustache_Tokenizer::LINE => 0,
  51. Mustache_Tokenizer::VALUE => 'text',
  52. ),
  53. ),
  54. ),
  55. array(
  56. 'text',
  57. '<<< >>>',
  58. array(
  59. array(
  60. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  61. Mustache_Tokenizer::LINE => 0,
  62. Mustache_Tokenizer::VALUE => 'text',
  63. ),
  64. ),
  65. ),
  66. array(
  67. '{{ name }}',
  68. null,
  69. array(
  70. array(
  71. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
  72. Mustache_Tokenizer::NAME => 'name',
  73. Mustache_Tokenizer::OTAG => '{{',
  74. Mustache_Tokenizer::CTAG => '}}',
  75. Mustache_Tokenizer::LINE => 0,
  76. Mustache_Tokenizer::INDEX => 10,
  77. ),
  78. ),
  79. ),
  80. array(
  81. '{{ name }}',
  82. '<<< >>>',
  83. array(
  84. array(
  85. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  86. Mustache_Tokenizer::LINE => 0,
  87. Mustache_Tokenizer::VALUE => '{{ name }}',
  88. ),
  89. ),
  90. ),
  91. array(
  92. '<<< name >>>',
  93. '<<< >>>',
  94. array(
  95. array(
  96. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
  97. Mustache_Tokenizer::NAME => 'name',
  98. Mustache_Tokenizer::OTAG => '<<<',
  99. Mustache_Tokenizer::CTAG => '>>>',
  100. Mustache_Tokenizer::LINE => 0,
  101. Mustache_Tokenizer::INDEX => 12,
  102. ),
  103. ),
  104. ),
  105. array(
  106. "{{{ a }}}\n{{# b }} \n{{= | | =}}| c ||/ b |\n|{ d }|",
  107. null,
  108. array(
  109. array(
  110. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
  111. Mustache_Tokenizer::NAME => 'a',
  112. Mustache_Tokenizer::OTAG => '{{',
  113. Mustache_Tokenizer::CTAG => '}}',
  114. Mustache_Tokenizer::LINE => 0,
  115. Mustache_Tokenizer::INDEX => 8,
  116. ),
  117. array(
  118. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  119. Mustache_Tokenizer::LINE => 0,
  120. Mustache_Tokenizer::VALUE => "\n",
  121. ),
  122. array(
  123. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
  124. Mustache_Tokenizer::NAME => 'b',
  125. Mustache_Tokenizer::OTAG => '{{',
  126. Mustache_Tokenizer::CTAG => '}}',
  127. Mustache_Tokenizer::LINE => 1,
  128. Mustache_Tokenizer::INDEX => 18,
  129. ),
  130. array(
  131. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  132. Mustache_Tokenizer::LINE => 1,
  133. Mustache_Tokenizer::VALUE => " \n",
  134. ),
  135. array(
  136. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_DELIM_CHANGE,
  137. Mustache_Tokenizer::LINE => 2,
  138. ),
  139. array(
  140. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
  141. Mustache_Tokenizer::NAME => 'c',
  142. Mustache_Tokenizer::OTAG => '|',
  143. Mustache_Tokenizer::CTAG => '|',
  144. Mustache_Tokenizer::LINE => 2,
  145. Mustache_Tokenizer::INDEX => 37,
  146. ),
  147. array(
  148. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
  149. Mustache_Tokenizer::NAME => 'b',
  150. Mustache_Tokenizer::OTAG => '|',
  151. Mustache_Tokenizer::CTAG => '|',
  152. Mustache_Tokenizer::LINE => 2,
  153. Mustache_Tokenizer::INDEX => 37,
  154. ),
  155. array(
  156. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  157. Mustache_Tokenizer::LINE => 2,
  158. Mustache_Tokenizer::VALUE => "\n",
  159. ),
  160. array(
  161. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
  162. Mustache_Tokenizer::NAME => 'd',
  163. Mustache_Tokenizer::OTAG => '|',
  164. Mustache_Tokenizer::CTAG => '|',
  165. Mustache_Tokenizer::LINE => 3,
  166. Mustache_Tokenizer::INDEX => 51,
  167. ),
  168. ),
  169. ),
  170. // See https://github.com/bobthecow/mustache.php/issues/183
  171. array(
  172. '{{# a }}0{{/ a }}',
  173. null,
  174. array(
  175. array(
  176. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
  177. Mustache_Tokenizer::NAME => 'a',
  178. Mustache_Tokenizer::OTAG => '{{',
  179. Mustache_Tokenizer::CTAG => '}}',
  180. Mustache_Tokenizer::LINE => 0,
  181. Mustache_Tokenizer::INDEX => 8,
  182. ),
  183. array(
  184. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  185. Mustache_Tokenizer::LINE => 0,
  186. Mustache_Tokenizer::VALUE => '0',
  187. ),
  188. array(
  189. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
  190. Mustache_Tokenizer::NAME => 'a',
  191. Mustache_Tokenizer::OTAG => '{{',
  192. Mustache_Tokenizer::CTAG => '}}',
  193. Mustache_Tokenizer::LINE => 0,
  194. Mustache_Tokenizer::INDEX => 9,
  195. ),
  196. ),
  197. ),
  198. // custom delimiters don't swallow the next character, even if it is a }, }}}, or the same delimiter
  199. array(
  200. '<% a %>} <% b %>%> <% c %>}}}',
  201. '<% %>',
  202. array(
  203. array(
  204. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
  205. Mustache_Tokenizer::NAME => 'a',
  206. Mustache_Tokenizer::OTAG => '<%',
  207. Mustache_Tokenizer::CTAG => '%>',
  208. Mustache_Tokenizer::LINE => 0,
  209. Mustache_Tokenizer::INDEX => 7,
  210. ),
  211. array(
  212. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  213. Mustache_Tokenizer::LINE => 0,
  214. Mustache_Tokenizer::VALUE => '} ',
  215. ),
  216. array(
  217. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
  218. Mustache_Tokenizer::NAME => 'b',
  219. Mustache_Tokenizer::OTAG => '<%',
  220. Mustache_Tokenizer::CTAG => '%>',
  221. Mustache_Tokenizer::LINE => 0,
  222. Mustache_Tokenizer::INDEX => 16,
  223. ),
  224. array(
  225. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  226. Mustache_Tokenizer::LINE => 0,
  227. Mustache_Tokenizer::VALUE => '%> ',
  228. ),
  229. array(
  230. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
  231. Mustache_Tokenizer::NAME => 'c',
  232. Mustache_Tokenizer::OTAG => '<%',
  233. Mustache_Tokenizer::CTAG => '%>',
  234. Mustache_Tokenizer::LINE => 0,
  235. Mustache_Tokenizer::INDEX => 26,
  236. ),
  237. array(
  238. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  239. Mustache_Tokenizer::LINE => 0,
  240. Mustache_Tokenizer::VALUE => '}}}',
  241. ),
  242. ),
  243. ),
  244. // unescaped custom delimiters are properly parsed
  245. array(
  246. '<%{ a }%>',
  247. '<% %>',
  248. array(
  249. array(
  250. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
  251. Mustache_Tokenizer::NAME => 'a',
  252. Mustache_Tokenizer::OTAG => '<%',
  253. Mustache_Tokenizer::CTAG => '%>',
  254. Mustache_Tokenizer::LINE => 0,
  255. Mustache_Tokenizer::INDEX => 9,
  256. ),
  257. ),
  258. ),
  259. // Ensure that $arg token is not picked up during tokenization
  260. array(
  261. '{{$arg}}default{{/arg}}',
  262. null,
  263. array(
  264. array(
  265. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_BLOCK_VAR,
  266. Mustache_Tokenizer::NAME => 'arg',
  267. Mustache_Tokenizer::OTAG => '{{',
  268. Mustache_Tokenizer::CTAG => '}}',
  269. Mustache_Tokenizer::LINE => 0,
  270. Mustache_Tokenizer::INDEX => 8,
  271. ),
  272. array(
  273. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
  274. Mustache_Tokenizer::LINE => 0,
  275. Mustache_Tokenizer::VALUE => 'default',
  276. ),
  277. array(
  278. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
  279. Mustache_Tokenizer::NAME => 'arg',
  280. Mustache_Tokenizer::OTAG => '{{',
  281. Mustache_Tokenizer::CTAG => '}}',
  282. Mustache_Tokenizer::LINE => 0,
  283. Mustache_Tokenizer::INDEX => 15,
  284. ),
  285. ),
  286. ),
  287. // Delimiters are trimmed
  288. array(
  289. '<% name %>',
  290. ' <% %> ',
  291. array(
  292. array(
  293. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
  294. Mustache_Tokenizer::NAME => 'name',
  295. Mustache_Tokenizer::OTAG => '<%',
  296. Mustache_Tokenizer::CTAG => '%>',
  297. Mustache_Tokenizer::LINE => 0,
  298. Mustache_Tokenizer::INDEX => 10,
  299. ),
  300. ),
  301. ),
  302. // An empty string makes delimiters fall back to default
  303. array(
  304. '{{ name }}',
  305. '',
  306. array(
  307. array(
  308. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
  309. Mustache_Tokenizer::NAME => 'name',
  310. Mustache_Tokenizer::OTAG => '{{',
  311. Mustache_Tokenizer::CTAG => '}}',
  312. Mustache_Tokenizer::LINE => 0,
  313. Mustache_Tokenizer::INDEX => 10,
  314. ),
  315. ),
  316. ),
  317. // A bad delimiter type makes delimiters fall back to default
  318. array(
  319. '{{ name }}',
  320. 42,
  321. array(
  322. array(
  323. Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
  324. Mustache_Tokenizer::NAME => 'name',
  325. Mustache_Tokenizer::OTAG => '{{',
  326. Mustache_Tokenizer::CTAG => '}}',
  327. Mustache_Tokenizer::LINE => 0,
  328. Mustache_Tokenizer::INDEX => 10,
  329. ),
  330. ),
  331. ),
  332. );
  333. }
  334. }