Test empty filename and invalid handle
[phpbb.git] / tests / template / template.php
blobb315b20c5380892970fac506a078880ceb3455b9
1 <?php
2 /**
4 * @package testing
5 * @version $Id$
6 * @copyright (c) 2008 phpBB Group
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
9 */
11 define('IN_PHPBB', true);
12 define('PHP_EXT', 'php');
13 define('PHPBB_ROOT_PATH', '../phpBB/');
15 require_once 'test_framework/framework.php';
17 require_once '../phpBB/includes/constants.php';
18 require_once '../phpBB/includes/functions.php';
19 require_once '../phpBB/includes/template.php';
21 class phpbb_template_template_test extends phpbb_test_case
23 private $template;
24 private $template_path;
26 // Keep the contents of the cache for debugging?
27 const PRESERVE_CACHE = false;
29 private function display($handle)
31 ob_start();
32 $this->assertTrue($this->template->display($handle, false));
33 return self::trim_template_result(ob_get_clean());
36 private static function trim_template_result($result)
38 return str_replace("\n\n", "\n", implode("\n", array_map('trim', explode("\n", trim($result)))));
41 private function setup_engine()
43 $this->template_path = dirname(__FILE__) . '/templates';
44 $this->template = new template;
45 $this->template->set_custom_template($this->template_path, 'tests');
48 protected function setUp()
50 // Test the engine can be used
51 $this->setup_engine();
53 if (!is_writable(dirname($this->template->cachepath)))
55 $this->markTestSkipped("Template cache directory is not writable.");
58 foreach (glob($this->template->cachepath . '*') as $file)
60 unlink($file);
63 $GLOBALS['config'] = array(
64 'load_tplcompile' => true
68 /**
69 * @todo put test data into templates/xyz.test
71 public static function template_data()
73 return array(
75 array(
76 '', // File
77 array(), // vars
78 array(), // block vars
79 array(), // destroy
80 '', // Expected result
83 array(
84 'basic.html',
85 array(),
86 array(),
87 array(),
88 "pass\npass\n<!-- DUMMY var -->",
90 array(
91 'variable.html',
92 array('VARIABLE' => 'value'),
93 array(),
94 array(),
95 'value',
97 array(
98 'if.html',
99 array(),
100 array(),
101 array(),
102 '0',
104 array(
105 'if.html',
106 array('S_VALUE' => true),
107 array(),
108 array(),
109 '1',
111 array(
112 'if.html',
113 array('S_VALUE' => true, 'S_OTHER_VALUE' => true),
114 array(),
115 array(),
116 '1',
118 array(
119 'if.html',
120 array('S_VALUE' => false, 'S_OTHER_VALUE' => true),
121 array(),
122 array(),
123 '2',
125 array(
126 'loop.html',
127 array(),
128 array(),
129 array(),
130 "noloop\nnoloop",
132 array(
133 'loop.html',
134 array(),
135 array('loop' => array(array())),
136 array(),
137 "loop\nloop",
139 array(
140 'loop.html',
141 array(),
142 array('loop' => array(array(), array()), 'loop.block' => array(array())),
143 array(),
144 "loop\nloop\nloop\nloop",
146 array(
147 'loop.html',
148 array(),
149 array('loop' => array(array(), array()), 'loop.block' => array(array()), 'block' => array(array(), array())),
150 array(),
151 "loop\nloop\nloop\nloop\n\nloop#0-block#0\nloop#0-block#1\nloop#1-block#0\nloop#1-block#1",
153 array(
154 'loop_vars.html',
155 array(),
156 array('loop' => array(array('VARIABLE' => 'x'))),
157 array(),
158 "first\n0\n0\n1\nx\nset\nlast",
160 array(
161 'loop_vars.html',
162 array(),
163 array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y'))),
164 array(),
165 "first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast",
167 array(
168 'loop_vars.html',
169 array(),
170 array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())),
171 array(),
172 "first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast\n0\n\n1\nlast inner\ninner loop",
174 array(
175 'loop_advanced.html',
176 array(),
177 array('loop' => array(array(), array(), array(), array(), array(), array(), array())),
178 array(),
179 "101234561\n101234561\n101234561\n1234561\n1\n101\n234\n10\n561\n561",
181 array(
182 'define.html',
183 array(),
184 array('loop' => array(array(), array(), array(), array(), array(), array(), array())),
185 array(),
186 "xyz\nabc\n\n00\n11\n22\n33\n44\n55\n66\n\n144\n144",
188 array(
189 'expressions.html',
190 array(),
191 array(),
192 array(),
193 trim(str_repeat("pass\n", 40)),
195 array(
196 'php.html',
197 array(),
198 array(),
199 array(),
200 '<!-- echo "test"; -->',
202 array(
203 'include.html',
204 array('VARIABLE' => 'value'),
205 array(),
206 array(),
207 'value',
209 array(
210 'loop_vars.html',
211 array(),
212 array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())),
213 array('loop'),
216 array(
217 'loop_vars.html',
218 array(),
219 array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())),
220 array('loop.inner'),
221 "first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast",
223 array(
224 'loop_expressions.html',
225 array(),
226 array('loop' => array(array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array(), array())),
227 array(),
228 "on\non\non\non\noff\noff\noff\noff\non\non\non\non\n\noff\noff\noff\non\non\non\noff\noff\noff\non\non\non",
230 array(
231 'lang.html',
232 array(),
233 array(),
234 array(),
235 "{ VARIABLE }\n{ VARIABLE }",
237 array(
238 'lang.html',
239 array('L_VARIABLE' => "Value'"),
240 array(),
241 array(),
242 "Value'\nValue\'",
244 array(
245 'lang.html',
246 array('LA_VARIABLE' => "Value'"),
247 array(),
248 array(),
249 "{ VARIABLE }\nValue'",
254 public function test_missing_file()
256 $filename = 'file_not_found.html';
258 $this->template->set_filenames(array('test' => $filename));
259 $this->assertFileNotExists($this->template_path . '/' . $filename, 'Testing missing file, file cannot exist');
261 $this->setExpectedTriggerError(E_USER_ERROR, sprintf('template->_tpl_load_file(): File %s does not exist or is empty', realpath($this->template_path) . '/' . $filename));
262 $this->display('test');
265 public function test_empty_file()
267 $this->setExpectedTriggerError(E_USER_ERROR, sprintf("template->set_filenames: Empty filename specified for test"));
268 $this->template->set_filenames(array('test' => ''));
271 public function test_invalid_handle()
273 $this->setExpectedTriggerError(E_USER_ERROR, sprintf("template->_tpl_load(): No file specified for handle test"));
274 $this->display('test');
278 private function run_template($file, array $vars, array $block_vars, array $destroy, $expected, $cache_file)
280 $this->template->set_filenames(array('test' => $file));
281 $this->template->assign_vars($vars);
283 foreach ($block_vars as $block => $loops)
285 foreach ($loops as $_vars)
287 $this->template->assign_block_vars($block, $_vars);
291 foreach ($destroy as $block)
293 $this->template->destroy_block_vars($block);
296 $this->assertEquals($expected, $this->display('test'), "Testing $file");
297 $this->assertFileExists($cache_file);
299 // For debugging
300 if (self::PRESERVE_CACHE)
302 copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file));
307 * @dataProvider template_data
309 public function test_template($file, array $vars, array $block_vars, array $destroy, $expected)
311 $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.' . PHP_EXT;
313 $this->assertFileNotExists($cache_file);
315 $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file);
317 // Reset the engine state
318 $this->setup_engine();
320 $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file);
324 * @dataProvider template_data
326 public function test_assign_display($file, array $vars, array $block_vars, array $destroy, $expected)
328 $this->template->set_filenames(array(
329 'test' => $file,
330 'container' => 'variable.html',
332 $this->template->assign_vars($vars);
334 foreach ($block_vars as $block => $loops)
336 foreach ($loops as $_vars)
338 $this->template->assign_block_vars($block, $_vars);
342 foreach ($destroy as $block)
344 $this->template->destroy_block_vars($block);
347 $this->assertEquals($expected, self::trim_template_result($this->template->assign_display('test')), "Testing assign_display($file)");
349 $this->template->assign_display('test', 'VARIABLE', false);
350 $this->assertEquals($expected, $this->display('container'), "Testing assign_display($file)");
353 public function test_php()
355 global $config;
357 $config['tpl_allow_php'] = 1;
359 $cache_file = $this->template->cachepath . 'php.html.' . PHP_EXT;
361 $this->assertFileNotExists($cache_file);
363 $this->run_template('php.html', array(), array(), array(), 'test', $cache_file);
365 unset($config['tpl_allow_php']);
368 public function test_includephp()
370 global $config;
372 $config['tpl_allow_php'] = 1;
374 $cwd = getcwd();
375 chdir(dirname(__FILE__) . '/templates');
377 //$this->run_template('includephp.html', array(), array(), array(), 'testing included php', $cache_file);
379 $this->template->set_filenames(array('test' => 'includephp.html'));
380 $this->assertEquals('testing included php', $this->display('test'), "Testing $file");
382 chdir($cwd);
384 unset($config['tpl_allow_php']);
387 public static function alter_block_array_data()
389 return array(
390 array(
391 'outer',
392 array('VARIABLE' => 'before'),
393 false,
394 'insert',
395 <<<EOT
396 outer - 0/4 - before
397 outer - 1/4
398 middle - 0/2
399 middle - 1/2
400 outer - 2/4
401 middle - 0/3
402 middle - 1/3
403 middle - 2/3
404 outer - 3/4
405 middle - 0/2
406 middle - 1/2
409 'Test inserting before on top level block',
411 array(
412 'outer',
413 array('VARIABLE' => 'after'),
414 true,
415 'insert',
416 <<<EOT
417 outer - 0/4
418 middle - 0/2
419 middle - 1/2
420 outer - 1/4
421 middle - 0/3
422 middle - 1/3
423 middle - 2/3
424 outer - 2/4
425 middle - 0/2
426 middle - 1/2
427 outer - 3/4 - after
430 'Test inserting after on top level block',
432 array(
433 'outer',
434 array('VARIABLE' => 'pos #1'),
436 'insert',
437 <<<EOT
438 outer - 0/4
439 middle - 0/2
440 middle - 1/2
441 outer - 1/4 - pos #1
442 outer - 2/4
443 middle - 0/3
444 middle - 1/3
445 middle - 2/3
446 outer - 3/4
447 middle - 0/2
448 middle - 1/2
451 'Test inserting at 1 on top level block',
453 array(
454 'outer',
455 array('VARIABLE' => 'pos #1'),
457 'change',
458 <<<EOT
459 outer - 0/3 - pos #1
460 middle - 0/2
461 middle - 1/2
462 outer - 1/3
463 middle - 0/3
464 middle - 1/3
465 middle - 2/3
466 outer - 2/3
467 middle - 0/2
468 middle - 1/2
471 'Test inserting at 1 on top level block',
473 array(
474 'outer[0].middle',
475 array('VARIABLE' => 'before'),
476 false,
477 'insert',
478 <<<EOT
479 outer - 0/3
480 middle - 0/3 - before
481 middle - 1/3
482 middle - 2/3
483 outer - 1/3
484 middle - 0/3
485 middle - 1/3
486 middle - 2/3
487 outer - 2/3
488 middle - 0/2
489 middle - 1/2
492 'Test inserting before on nested block',
494 array(
495 'outer[0].middle',
496 array('VARIABLE' => 'after'),
497 true,
498 'insert',
499 <<<EOT
500 outer - 0/3
501 middle - 0/3
502 middle - 1/3
503 middle - 2/3 - after
504 outer - 1/3
505 middle - 0/3
506 middle - 1/3
507 middle - 2/3
508 outer - 2/3
509 middle - 0/2
510 middle - 1/2
513 'Test inserting after on nested block',
515 array(
516 'outer[0].middle',
517 array('VARIABLE' => 'pos #1'),
519 'insert',
520 <<<EOT
521 outer - 0/3
522 middle - 0/3
523 middle - 1/3 - pos #1
524 middle - 2/3
525 outer - 1/3
526 middle - 0/3
527 middle - 1/3
528 middle - 2/3
529 outer - 2/3
530 middle - 0/2
531 middle - 1/2
534 'Test inserting at pos 1 on nested block',
536 array(
537 'outer[1].middle',
538 array('VARIABLE' => 'before'),
539 false,
540 'insert',
541 <<<EOT
542 outer - 0/3
543 middle - 0/2
544 middle - 1/2
545 outer - 1/3
546 middle - 0/4 - before
547 middle - 1/4
548 middle - 2/4
549 middle - 3/4
550 outer - 2/3
551 middle - 0/2
552 middle - 1/2
555 'Test inserting before on nested block (pos 1)',
557 array(
558 'outer[].middle',
559 array('VARIABLE' => 'before'),
560 false,
561 'insert',
562 <<<EOT
563 outer - 0/3
564 middle - 0/2
565 middle - 1/2
566 outer - 1/3
567 middle - 0/3
568 middle - 1/3
569 middle - 2/3
570 outer - 2/3
571 middle - 0/3 - before
572 middle - 1/3
573 middle - 2/3
576 'Test inserting before on nested block (end)',
578 array(
579 'outer.middle',
580 array('VARIABLE' => 'before'),
581 false,
582 'insert',
583 <<<EOT
584 outer - 0/3
585 middle - 0/2
586 middle - 1/2
587 outer - 1/3
588 middle - 0/3
589 middle - 1/3
590 middle - 2/3
591 outer - 2/3
592 middle - 0/3 - before
593 middle - 1/3
594 middle - 2/3
597 'Test inserting before on nested block (end)',
603 <<<EOT
604 outer - 0/3
605 middle - 0/2
606 middle - 1/2
607 outer - 1/3
608 middle - 0/3
609 middle - 1/3
610 middle - 2/3
611 outer - 2/3
612 middle - 0/2
613 middle - 1/2
619 * @dataProvider alter_block_array_data
621 public function test_alter_block_array($alter_block, array $vararray, $key, $mode, $expect, $description)
623 $this->template->set_filenames(array('test' => 'loop_nested.html'));
625 // @todo Change this
626 $this->template->assign_block_vars('outer', array());
627 $this->template->assign_block_vars('outer.middle', array());
628 $this->template->assign_block_vars('outer.middle', array());
629 $this->template->assign_block_vars('outer', array());
630 $this->template->assign_block_vars('outer.middle', array());
631 $this->template->assign_block_vars('outer.middle', array());
632 $this->template->assign_block_vars('outer.middle', array());
633 $this->template->assign_block_vars('outer', array());
634 $this->template->assign_block_vars('outer.middle', array());
635 $this->template->assign_block_vars('outer.middle', array());
637 $this->assertEquals("outer - 0/3\nmiddle - 0/2\nmiddle - 1/2\nouter - 1/3\nmiddle - 0/3\nmiddle - 1/3\nmiddle - 2/3\nouter - 2/3\nmiddle - 0/2\nmiddle - 1/2", $this->display('test'), 'Ensuring template is built correctly before modification');
639 $this->template->alter_block_array($alter_block, $vararray, $key, $mode);
640 $this->assertEquals($expect, $this->display('test'), $description);