ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
EnvironmentTest.php
Go to the documentation of this file.
1<?php
2
3/*
4 * This file is part of Twig.
5 *
6 * (c) Fabien Potencier
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12require_once dirname(__FILE__).'/FilesystemHelper.php';
13
14class Twig_Tests_EnvironmentTest extends \PHPUnit\Framework\TestCase
15{
16 private $deprecations = array();
17
22 {
23 $env = new Twig_Environment();
24 $stream = $env->tokenize('{{ foo }}', 'foo');
25 $this->assertEquals('{{ foo }}', $stream->getSource());
26 $this->assertEquals('foo', $stream->getFilename());
27 }
28
33 {
34 $loader = new Twig_Loader_Array(array('foo' => '{{ foo }}'));
36 $this->assertContains('getTemplateName', $env->compileSource('{{ foo }}', 'foo'));
37 }
38
44 public function testRenderNoLoader()
45 {
46 $env = new Twig_Environment();
47 $env->render('test');
48 }
49
50 public function testAutoescapeOption()
51 {
52 $loader = new Twig_Loader_Array(array(
53 'html' => '{{ foo }} {{ foo }}',
54 'js' => '{{ bar }} {{ bar }}',
55 ));
56
57 $twig = new Twig_Environment($loader, array(
58 'debug' => true,
59 'cache' => false,
60 'autoescape' => array($this, 'escapingStrategyCallback'),
61 ));
62
63 $this->assertEquals('foo&lt;br/ &gt; foo&lt;br/ &gt;', $twig->render('html', array('foo' => 'foo<br/ >')));
64 $this->assertEquals('foo\x3Cbr\x2F\x20\x3E foo\x3Cbr\x2F\x20\x3E', $twig->render('js', array('bar' => 'foo<br/ >')));
65 }
66
68 {
69 return $name;
70 }
71
72 public function testGlobals()
73 {
74 // to be removed in 2.0
75 $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
76 //$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
77 $loader->expects($this->any())->method('getSourceContext')->will($this->returnValue(new Twig_Source('', '')));
78
79 // globals can be added after calling getGlobals
80
81 $twig = new Twig_Environment($loader);
82 $twig->addGlobal('foo', 'foo');
83 $twig->getGlobals();
84 $twig->addGlobal('foo', 'bar');
85 $globals = $twig->getGlobals();
86 $this->assertEquals('bar', $globals['foo']);
87
88 // globals can be modified after a template has been loaded
89 $twig = new Twig_Environment($loader);
90 $twig->addGlobal('foo', 'foo');
91 $twig->getGlobals();
92 $twig->loadTemplate('index');
93 $twig->addGlobal('foo', 'bar');
94 $globals = $twig->getGlobals();
95 $this->assertEquals('bar', $globals['foo']);
96
97 // globals can be modified after extensions init
98 $twig = new Twig_Environment($loader);
99 $twig->addGlobal('foo', 'foo');
100 $twig->getGlobals();
101 $twig->getFunctions();
102 $twig->addGlobal('foo', 'bar');
103 $globals = $twig->getGlobals();
104 $this->assertEquals('bar', $globals['foo']);
105
106 // globals can be modified after extensions and a template has been loaded
107 $arrayLoader = new Twig_Loader_Array(array('index' => '{{foo}}'));
108 $twig = new Twig_Environment($arrayLoader);
109 $twig->addGlobal('foo', 'foo');
110 $twig->getGlobals();
111 $twig->getFunctions();
112 $twig->loadTemplate('index');
113 $twig->addGlobal('foo', 'bar');
114 $globals = $twig->getGlobals();
115 $this->assertEquals('bar', $globals['foo']);
116
117 $twig = new Twig_Environment($arrayLoader);
118 $twig->getGlobals();
119 $twig->addGlobal('foo', 'bar');
120 $template = $twig->loadTemplate('index');
121 $this->assertEquals('bar', $template->render(array()));
122
123 /* to be uncomment in Twig 2.0
124 // globals cannot be added after a template has been loaded
125 $twig = new Twig_Environment($loader);
126 $twig->addGlobal('foo', 'foo');
127 $twig->getGlobals();
128 $twig->loadTemplate('index');
129 try {
130 $twig->addGlobal('bar', 'bar');
131 $this->fail();
132 } catch (LogicException $e) {
133 $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
134 }
135
136 // globals cannot be added after extensions init
137 $twig = new Twig_Environment($loader);
138 $twig->addGlobal('foo', 'foo');
139 $twig->getGlobals();
140 $twig->getFunctions();
141 try {
142 $twig->addGlobal('bar', 'bar');
143 $this->fail();
144 } catch (LogicException $e) {
145 $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
146 }
147
148 // globals cannot be added after extensions and a template has been loaded
149 $twig = new Twig_Environment($loader);
150 $twig->addGlobal('foo', 'foo');
151 $twig->getGlobals();
152 $twig->getFunctions();
153 $twig->loadTemplate('index');
154 try {
155 $twig->addGlobal('bar', 'bar');
156 $this->fail();
157 } catch (LogicException $e) {
158 $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
159 }
160
161 // test adding globals after a template has been loaded without call to getGlobals
162 $twig = new Twig_Environment($loader);
163 $twig->loadTemplate('index');
164 try {
165 $twig->addGlobal('bar', 'bar');
166 $this->fail();
167 } catch (LogicException $e) {
168 $this->assertFalse(array_key_exists('bar', $twig->getGlobals()));
169 }
170 */
171 }
172
174 {
175 $cache = new Twig_Cache_Filesystem($dir = sys_get_temp_dir().'/twig');
176 $options = array('cache' => $cache, 'auto_reload' => false, 'debug' => false);
177
178 // force compilation
179 $twig = new Twig_Environment($loader = new Twig_Loader_Array(array('index' => '{{ foo }}')), $options);
180
181 $key = $cache->generateKey('index', $twig->getTemplateClass('index'));
182 $cache->write($key, $twig->compileSource(new Twig_Source('{{ foo }}', 'index')));
183
184 // check that extensions won't be initialized when rendering a template that is already in the cache
185 $twig = $this
186 ->getMockBuilder('Twig_Environment')
187 ->setConstructorArgs(array($loader, $options))
188 ->setMethods(array('initExtensions'))
189 ->getMock()
190 ;
191
192 $twig->expects($this->never())->method('initExtensions');
193
194 // render template
195 $output = $twig->render('index', array('foo' => 'bar'));
196 $this->assertEquals('bar', $output);
197
199 }
200
201 public function testAutoReloadCacheMiss()
202 {
203 $templateName = __FUNCTION__;
204 $templateContent = __FUNCTION__;
205
206 $cache = $this->getMockBuilder('Twig_CacheInterface')->getMock();
207 $loader = $this->getMockLoader($templateName, $templateContent);
208 $twig = new Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => true, 'debug' => false));
209
210 // Cache miss: getTimestamp returns 0 and as a result the load() is
211 // skipped.
212 $cache->expects($this->once())
213 ->method('generateKey')
214 ->will($this->returnValue('key'));
215 $cache->expects($this->once())
216 ->method('getTimestamp')
217 ->will($this->returnValue(0));
218 $loader->expects($this->never())
219 ->method('isFresh');
220 $cache->expects($this->once())
221 ->method('write');
222 $cache->expects($this->once())
223 ->method('load');
224
225 $twig->loadTemplate($templateName);
226 }
227
228 public function testAutoReloadCacheHit()
229 {
230 $templateName = __FUNCTION__;
231 $templateContent = __FUNCTION__;
232
233 $cache = $this->getMockBuilder('Twig_CacheInterface')->getMock();
234 $loader = $this->getMockLoader($templateName, $templateContent);
235 $twig = new Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => true, 'debug' => false));
236
237 $now = time();
238
239 // Cache hit: getTimestamp returns something > extension timestamps and
240 // the loader returns true for isFresh().
241 $cache->expects($this->once())
242 ->method('generateKey')
243 ->will($this->returnValue('key'));
244 $cache->expects($this->once())
245 ->method('getTimestamp')
246 ->will($this->returnValue($now));
247 $loader->expects($this->once())
248 ->method('isFresh')
249 ->will($this->returnValue(true));
250 $cache->expects($this->atLeastOnce())
251 ->method('load');
252
253 $twig->loadTemplate($templateName);
254 }
255
257 {
258 $templateName = __FUNCTION__;
259 $templateContent = __FUNCTION__;
260
261 $cache = $this->getMockBuilder('Twig_CacheInterface')->getMock();
262 $loader = $this->getMockLoader($templateName, $templateContent);
263 $twig = new Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => true, 'debug' => false));
264
265 $now = time();
266
267 $cache->expects($this->once())
268 ->method('generateKey')
269 ->will($this->returnValue('key'));
270 $cache->expects($this->once())
271 ->method('getTimestamp')
272 ->will($this->returnValue($now));
273 $loader->expects($this->once())
274 ->method('isFresh')
275 ->will($this->returnValue(false));
276 $cache->expects($this->once())
277 ->method('write');
278 $cache->expects($this->once())
279 ->method('load');
280
281 $twig->loadTemplate($templateName);
282 }
283
288 {
289 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
290
293 $twig->addExtension($ext1);
294 $twig->addExtension($ext2);
295
296 $this->assertTrue($twig->hasExtension('ext1'));
297 $this->assertTrue($twig->hasExtension('ext2'));
298
299 $this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension_DynamicWithDeprecatedName'));
300
301 $this->assertSame($ext1, $twig->getExtension('ext1'));
302 $this->assertSame($ext2, $twig->getExtension('ext2'));
303 }
304
306 {
307 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
308 $twig->addExtension($ext = new Twig_Tests_EnvironmentTest_Extension());
309 $this->assertTrue($twig->hasExtension('Twig_Tests_EnvironmentTest_Extension'));
310 $this->assertTrue($twig->hasExtension('\Twig_Tests_EnvironmentTest_Extension'));
311
312 $this->assertSame($ext, $twig->getExtension('Twig_Tests_EnvironmentTest_Extension'));
313 $this->assertSame($ext, $twig->getExtension('\Twig_Tests_EnvironmentTest_Extension'));
314
315 $this->assertTrue($twig->hasExtension('Twig\Tests\EnvironmentTest\Extension'));
316 $this->assertSame($ext, $twig->getExtension('Twig\Tests\EnvironmentTest\Extension'));
317 }
318
319 public function testAddExtension()
320 {
321 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
322 $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension());
323
324 $this->assertArrayHasKey('test', $twig->getTags());
325 $this->assertArrayHasKey('foo_filter', $twig->getFilters());
326 $this->assertArrayHasKey('foo_function', $twig->getFunctions());
327 $this->assertArrayHasKey('foo_test', $twig->getTests());
328 $this->assertArrayHasKey('foo_unary', $twig->getUnaryOperators());
329 $this->assertArrayHasKey('foo_binary', $twig->getBinaryOperators());
330 $this->assertArrayHasKey('foo_global', $twig->getGlobals());
331 $visitors = $twig->getNodeVisitors();
332 $found = false;
333 foreach ($visitors as $visitor) {
334 if ($visitor instanceof Twig_Tests_EnvironmentTest_NodeVisitor) {
335 $found = true;
336 }
337 }
338 $this->assertTrue($found);
339 }
340
345 {
346 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
347 $twig->addExtension(new Twig_Tests_EnvironmentTest_Extension_WithGlobals());
348
349 $this->deprecations = array();
350 set_error_handler(array($this, 'handleError'));
351
352 $this->assertArrayHasKey('foo_global', $twig->getGlobals());
353
354 $this->assertCount(1, $this->deprecations);
355 $this->assertContains('Defining the getGlobals() method in the "Twig_Tests_EnvironmentTest_Extension_WithGlobals" extension ', $this->deprecations[0]);
356
357 restore_error_handler();
358 }
359
363 public function testRemoveExtension()
364 {
365 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
367 $twig->removeExtension('environment_test');
368
369 $this->assertArrayNotHasKey('test', $twig->getTags());
370 $this->assertArrayNotHasKey('foo_filter', $twig->getFilters());
371 $this->assertArrayNotHasKey('foo_function', $twig->getFunctions());
372 $this->assertArrayNotHasKey('foo_test', $twig->getTests());
373 $this->assertArrayNotHasKey('foo_unary', $twig->getUnaryOperators());
374 $this->assertArrayNotHasKey('foo_binary', $twig->getBinaryOperators());
375 $this->assertArrayNotHasKey('foo_global', $twig->getGlobals());
376 $this->assertCount(2, $twig->getNodeVisitors());
377 }
378
379 public function testAddMockExtension()
380 {
381 // should be replaced by the following in 2.0 (this current code is just to avoid a dep notice)
382 // $extension = $this->getMockBuilder('Twig_Extension')->getMock();
383 $extension = eval(<<<EOF
384class Twig_Tests_EnvironmentTest_ExtensionInEval extends Twig_Extension
385{
386}
387EOF
388 );
389 $extension = new Twig_Tests_EnvironmentTest_ExtensionInEval();
390
391 $loader = new Twig_Loader_Array(array('page' => 'hey'));
392
393 $twig = new Twig_Environment($loader);
394 $twig->addExtension($extension);
395
396 $this->assertInstanceOf('Twig_ExtensionInterface', $twig->getExtension(get_class($extension)));
397 $this->assertTrue($twig->isTemplateFresh('page', time()));
398 }
399
401 {
402 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
404 $twig->initRuntime();
405
406 // add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
407 // can be executed without throwing any deprecations
408 $this->addToAssertionCount(1);
409 }
410
415 {
416 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
418
419 $this->deprecations = array();
420 set_error_handler(array($this, 'handleError'));
421
422 $twig->initRuntime();
423
424 $this->assertCount(1, $this->deprecations);
425 $this->assertContains('Defining the initRuntime() method in the "Twig_Tests_EnvironmentTest_ExtensionWithDeprecationInitRuntime" extension is deprecated since version 1.23.', $this->deprecations[0]);
426
427 restore_error_handler();
428 }
429
430 public function handleError($type, $msg)
431 {
432 if (E_USER_DEPRECATED === $type) {
433 $this->deprecations[] = $msg;
434 }
435 }
436
440 public function testOverrideExtension()
441 {
442 $twig = new Twig_Environment($this->getMockBuilder('Twig_LoaderInterface')->getMock());
444
445 $this->deprecations = array();
446 set_error_handler(array($this, 'handleError'));
447
450
451 $this->assertCount(1, $this->deprecations);
452 $this->assertContains('The possibility to register the same extension twice', $this->deprecations[0]);
453
454 restore_error_handler();
455 }
456
457 public function testAddRuntimeLoader()
458 {
459 $runtimeLoader = $this->getMockBuilder('Twig_RuntimeLoaderInterface')->getMock();
460 $runtimeLoader->expects($this->any())->method('load')->will($this->returnValue(new Twig_Tests_EnvironmentTest_Runtime()));
461
462 $loader = new Twig_Loader_Array(array(
463 'func_array' => '{{ from_runtime_array("foo") }}',
464 'func_array_default' => '{{ from_runtime_array() }}',
465 'func_array_named_args' => '{{ from_runtime_array(name="foo") }}',
466 'func_string' => '{{ from_runtime_string("foo") }}',
467 'func_string_default' => '{{ from_runtime_string() }}',
468 'func_string_named_args' => '{{ from_runtime_string(name="foo") }}',
469 ));
470
471 $twig = new Twig_Environment($loader);
473 $twig->addRuntimeLoader($runtimeLoader);
474
475 $this->assertEquals('foo', $twig->render('func_array'));
476 $this->assertEquals('bar', $twig->render('func_array_default'));
477 $this->assertEquals('foo', $twig->render('func_array_named_args'));
478 $this->assertEquals('foo', $twig->render('func_string'));
479 $this->assertEquals('bar', $twig->render('func_string_default'));
480 $this->assertEquals('foo', $twig->render('func_string_named_args'));
481 }
482
488 {
489 $twig = new Twig_Environment(new Twig_Loader_Array(array(
490 'base.html.twig' => '{% extends "base.html.twig" %}',
491 )));
492
493 $twig->loadTemplate('base.html.twig');
494 }
495
501 {
502 $twig = new Twig_Environment(new Twig_Loader_Array(array(
503 'base1.html.twig' => '{% extends "base2.html.twig" %}',
504 'base2.html.twig' => '{% extends "base1.html.twig" %}',
505 )));
506
507 $twig->loadTemplate('base1.html.twig');
508 }
509
510 protected function getMockLoader($templateName, $templateContent)
511 {
512 // to be removed in 2.0
513 $loader = $this->getMockBuilder('Twig_EnvironmentTestLoaderInterface')->getMock();
514 //$loader = $this->getMockBuilder(array('Twig_LoaderInterface', 'Twig_SourceContextLoaderInterface'))->getMock();
515 $loader->expects($this->any())
516 ->method('getSourceContext')
517 ->with($templateName)
518 ->will($this->returnValue(new Twig_Source($templateContent, $templateName)));
519 $loader->expects($this->any())
520 ->method('getCacheKey')
521 ->with($templateName)
522 ->will($this->returnValue($templateName));
523
524 return $loader;
525 }
526}
527
529{
530 public function getGlobals()
531 {
532 return array(
533 'foo_global' => 'foo_global',
534 );
535 }
536}
537
539{
540 public function getTokenParsers()
541 {
542 return array(
544 );
545 }
546
547 public function getNodeVisitors()
548 {
549 return array(
551 );
552 }
553
554 public function getFilters()
555 {
556 return array(
557 new Twig_SimpleFilter('foo_filter', 'foo_filter'),
558 );
559 }
560
561 public function getTests()
562 {
563 return array(
564 new Twig_SimpleTest('foo_test', 'foo_test'),
565 );
566 }
567
568 public function getFunctions()
569 {
570 return array(
571 new Twig_SimpleFunction('foo_function', 'foo_function'),
572 );
573 }
574
575 public function getOperators()
576 {
577 return array(
578 array('foo_unary' => array()),
579 array('foo_binary' => array()),
580 );
581 }
582
583 public function getGlobals()
584 {
585 return array(
586 'foo_global' => 'foo_global',
587 );
588 }
589}
590class_alias('Twig_Tests_EnvironmentTest_Extension', 'Twig\Tests\EnvironmentTest\Extension', false);
591
593{
594 public function getName()
595 {
596 return 'environment_test';
597 }
598}
599
601{
602 private $name;
603
604 public function __construct($name)
605 {
606 $this->name = $name;
607 }
608
609 public function getName()
610 {
611 return $this->name;
612 }
613}
614
616{
617 public function parse(Twig_Token $token)
618 {
619 }
620
621 public function getTag()
622 {
623 return 'test';
624 }
625}
626
628{
630 {
631 return $node;
632 }
633
635 {
636 return $node;
637 }
638
639 public function getPriority()
640 {
641 return 0;
642 }
643}
644
646{
648 {
649 }
650}
651
653{
655 {
656 }
657}
658
660{
661 public function getFunctions()
662 {
663 return array(
664 new Twig_SimpleFunction('from_runtime_array', array('Twig_Tests_EnvironmentTest_Runtime', 'fromRuntime')),
665 new Twig_SimpleFunction('from_runtime_string', 'Twig_Tests_EnvironmentTest_Runtime::fromRuntime'),
666 );
667 }
668
669 public function getName()
670 {
671 return 'from_runtime';
672 }
673}
674
676{
677 public function fromRuntime($name = 'bar')
678 {
679 return $name;
680 }
681}
682
683// to be removed in 2.0
685{
686}
$env
const EOF
How fgetc() reports an End Of File.
Definition: JSMin_lib.php:92
if(!isset( $_REQUEST[ 'ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20
An exception for terminatinating execution or to throw for unit testing.
Implements a cache on the filesystem.
Definition: Filesystem.php:18
Stores the Twig configuration.
Definition: Environment.php:18
Loads a template from an array.
Definition: Array.php:27
Represents a template filter.
Represents a template function.
Represents a template test.
Definition: SimpleTest.php:20
Holds information about a non-compiled Twig template.
Definition: Source.php:20
getFunctions()
Returns a list of functions to add to the existing list.
getOperators()
Returns a list of operators to add to the existing list.
getTokenParsers()
Returns the token parser instances to add to the existing list.
getFunctions()
Returns a list of functions to add to the existing list.
getNodeVisitors()
Returns the node visitor instances to add to the existing list.
getTests()
Returns a list of tests to add to the existing list.
getFilters()
Returns a list of filters to add to the existing list.
enterNode(Twig_NodeInterface $node, Twig_Environment $env)
Called before child nodes are visited.
leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
Called after child nodes are visited.
getPriority()
Returns the priority for this visitor.
parse(Twig_Token $token)
Parses a token and returns a node.
getTag()
Gets the tag name associated with this token parser.
testOverrideExtension()
@requires PHP 5.3
testLegacyTokenizeSignature()
@group legacy
testRenderNoLoader()
@expectedException LogicException @expectedExceptionMessage You must set a loader first.
testInitRuntimeWithAnExtensionUsingInitRuntimeDeprecation()
@requires PHP 5.3
testFailLoadTemplateOnComplexCircularReference()
@expectedException Twig_Error_Runtime @expectedExceptionMessage Circular reference detected for Twig ...
testFailLoadTemplateOnCircularReference()
@expectedException Twig_Error_Runtime @expectedExceptionMessage Circular reference detected for Twig ...
testRemoveExtension()
@group legacy
testLegacyCompileSourceSignature()
@group legacy
testInitRuntimeWithAnExtensionUsingInitRuntimeNoDeprecation()
testHasGetExtensionWithDynamicName()
@group legacy
testAddExtensionWithDeprecatedGetGlobals()
@requires PHP 5.3
getMockLoader($templateName, $templateContent)
testExtensionsAreNotInitializedWhenRenderingACompiledTemplate()
Base class for all token parsers.
Definition: TokenParser.php:18
Represents a Token.
Definition: Token.php:21
$template
$key
Definition: croninfo.php:18
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
Enables usage of the deprecated Twig_Extension::getGlobals() method.
Enables usage of the deprecated Twig_Extension::initRuntime() method.
Interface all loaders must implement.
Represents a node in the AST.
Twig_NodeVisitorInterface is the interface the all node visitor classes must implement.
Adds a getSourceContext() method for loaders.
if($format !==null) $name
Definition: metadata.php:146
$stream
PHP stream implementation.
$type