... | ... |
@@ -1,5 +1,6 @@ |
1 | 1 |
* 0.9.6-DEV |
2 | 2 |
|
3 |
+ * unit tests are now powered by PHPUnit |
|
3 | 4 |
* added support for gettext via the `i18n` extension |
4 | 5 |
* fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values |
5 | 6 |
* added a more useful exception if an if tag is not closed properly |
6 | 7 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,24 @@ |
1 |
+<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
+ |
|
3 |
+<phpunit backupGlobals="false" |
|
4 |
+ backupStaticAttributes="false" |
|
5 |
+ colors="false" |
|
6 |
+ convertErrorsToExceptions="true" |
|
7 |
+ convertNoticesToExceptions="true" |
|
8 |
+ convertWarningsToExceptions="true" |
|
9 |
+ processIsolation="false" |
|
10 |
+ stopOnFailure="false" |
|
11 |
+ syntaxCheck="false" |
|
12 |
+> |
|
13 |
+ <testsuites> |
|
14 |
+ <testsuite name="Twig Test Suite"> |
|
15 |
+ <directory>./test/Twig/</directory> |
|
16 |
+ </testsuite> |
|
17 |
+ </testsuites> |
|
18 |
+ |
|
19 |
+ <filter> |
|
20 |
+ <whitelist> |
|
21 |
+ <directory suffix=".php">./lib/Twig/</directory> |
|
22 |
+ </whitelist> |
|
23 |
+ </filter> |
|
24 |
+</phpunit> |
0 | 25 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,24 @@ |
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 |
+ |
|
12 |
+require_once dirname(__FILE__).'/bootstrap.php'; |
|
13 |
+ |
|
14 |
+class Twig_Tests_AutoloaderTest extends \PHPUnit_Framework_TestCase |
|
15 |
+{ |
|
16 |
+ public function testAutoload() |
|
17 |
+ { |
|
18 |
+ $this->assertFalse(class_exists('FooBarFoo'), '->autoload() does not try to load classes that does not begin with Twig'); |
|
19 |
+ |
|
20 |
+ $autoloader = new Twig_Autoloader(); |
|
21 |
+ $this->assertTrue($autoloader->autoload('Twig_Parser'), '->autoload() returns true if it is able to load a class'); |
|
22 |
+ $this->assertFalse($autoloader->autoload('Foo'), '->autoload() returns false if it is not able to load a class'); |
|
23 |
+ } |
|
24 |
+} |
0 | 25 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,138 @@ |
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 |
+ |
|
12 |
+require_once dirname(__FILE__).'/../bootstrap.php'; |
|
13 |
+ |
|
14 |
+class Twig_Tests_Extension_SandboxTest extends \PHPUnit_Framework_TestCase |
|
15 |
+{ |
|
16 |
+ static protected $params, $templates; |
|
17 |
+ |
|
18 |
+ static public function setUpBeforeClass() |
|
19 |
+ { |
|
20 |
+ self::$params = array( |
|
21 |
+ 'name' => 'Fabien', |
|
22 |
+ 'obj' => new Object(), |
|
23 |
+ ); |
|
24 |
+ |
|
25 |
+ self::$templates = array( |
|
26 |
+ '1_basic1' => '{{ obj.foo }}', |
|
27 |
+ '1_basic2' => '{{ name|upper }}', |
|
28 |
+ '1_basic3' => '{% if name %}foo{% endif %}', |
|
29 |
+ '1_basic4' => '{{ obj.bar }}', |
|
30 |
+ '1_basic' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', |
|
31 |
+ ); |
|
32 |
+ } |
|
33 |
+ |
|
34 |
+ public function testSandboxGloballySet() |
|
35 |
+ { |
|
36 |
+ $twig = $this->getEnvironment(false, self::$templates); |
|
37 |
+ $this->assertEquals('FOO', $twig->loadTemplate('1_basic')->render(self::$params), 'Sandbox does nothing if it is disabled globally'); |
|
38 |
+ |
|
39 |
+ $twig = $this->getEnvironment(true, self::$templates); |
|
40 |
+ try |
|
41 |
+ { |
|
42 |
+ $twig->loadTemplate('1_basic1')->render(self::$params); |
|
43 |
+ $this->fail('Sandbox throws a SecurityError exception if an unallowed method is called'); |
|
44 |
+ } |
|
45 |
+ catch (Twig_Sandbox_SecurityError $e) |
|
46 |
+ { |
|
47 |
+ } |
|
48 |
+ |
|
49 |
+ $twig = $this->getEnvironment(true, self::$templates); |
|
50 |
+ try |
|
51 |
+ { |
|
52 |
+ $twig->loadTemplate('1_basic2')->render(self::$params); |
|
53 |
+ $this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called'); |
|
54 |
+ } |
|
55 |
+ catch (Twig_Sandbox_SecurityError $e) |
|
56 |
+ { |
|
57 |
+ } |
|
58 |
+ |
|
59 |
+ $twig = $this->getEnvironment(true, self::$templates); |
|
60 |
+ try |
|
61 |
+ { |
|
62 |
+ $twig->loadTemplate('1_basic3')->render(self::$params); |
|
63 |
+ $this->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template'); |
|
64 |
+ } |
|
65 |
+ catch (Twig_Sandbox_SecurityError $e) |
|
66 |
+ { |
|
67 |
+ } |
|
68 |
+ |
|
69 |
+ $twig = $this->getEnvironment(true, self::$templates); |
|
70 |
+ try |
|
71 |
+ { |
|
72 |
+ $twig->loadTemplate('1_basic4')->render(self::$params); |
|
73 |
+ $this->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template'); |
|
74 |
+ } |
|
75 |
+ catch (Twig_Sandbox_SecurityError $e) |
|
76 |
+ { |
|
77 |
+ } |
|
78 |
+ |
|
79 |
+ $twig = $this->getEnvironment(true, self::$templates, array(), array(), array('Object' => 'foo')); |
|
80 |
+ $this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods'); |
|
81 |
+ |
|
82 |
+ $twig = $this->getEnvironment(true, self::$templates, array(), array('upper')); |
|
83 |
+ $this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters'); |
|
84 |
+ |
|
85 |
+ $twig = $this->getEnvironment(true, self::$templates, array('if')); |
|
86 |
+ $this->assertEquals('foo', $twig->loadTemplate('1_basic3')->render(self::$params), 'Sandbox allow some tags'); |
|
87 |
+ |
|
88 |
+ $twig = $this->getEnvironment(true, self::$templates, array(), array(), array(), array('Object' => 'bar')); |
|
89 |
+ $this->assertEquals('bar', $twig->loadTemplate('1_basic4')->render(self::$params), 'Sandbox allow some properties'); |
|
90 |
+ } |
|
91 |
+ |
|
92 |
+ public function testSandboxLocallySetForAnInclude() |
|
93 |
+ { |
|
94 |
+ self::$templates = array( |
|
95 |
+ '2_basic' => '{{ obj.foo }}{% include "2_included" %}{{ obj.foo }}', |
|
96 |
+ '2_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', |
|
97 |
+ ); |
|
98 |
+ |
|
99 |
+ $twig = $this->getEnvironment(false, self::$templates); |
|
100 |
+ $this->assertEquals('fooFOOfoo', $twig->loadTemplate('2_basic')->render(self::$params), 'Sandbox does nothing if disabled globally and sandboxed not used for the include'); |
|
101 |
+ |
|
102 |
+ self::$templates = array( |
|
103 |
+ '3_basic' => '{{ obj.foo }}{% include "3_included" sandboxed %}{{ obj.foo }}', |
|
104 |
+ '3_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', |
|
105 |
+ ); |
|
106 |
+ |
|
107 |
+ $twig = $this->getEnvironment(false, self::$templates); |
|
108 |
+ $twig = $this->getEnvironment(true, self::$templates); |
|
109 |
+ try |
|
110 |
+ { |
|
111 |
+ $twig->loadTemplate('3_basic')->render(self::$params); |
|
112 |
+ $this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed'); |
|
113 |
+ } |
|
114 |
+ catch (Twig_Sandbox_SecurityError $e) |
|
115 |
+ { |
|
116 |
+ } |
|
117 |
+ } |
|
118 |
+ |
|
119 |
+ protected function getEnvironment($sandboxed, $templates, $tags = array(), $filters = array(), $methods = array(), $properties = array()) |
|
120 |
+ { |
|
121 |
+ $loader = new Twig_Loader_Array($templates); |
|
122 |
+ $twig = new Twig_Environment($loader, array('trim_blocks' => true, 'debug' => true)); |
|
123 |
+ $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties); |
|
124 |
+ $twig->addExtension(new Twig_Extension_Sandbox($policy, $sandboxed)); |
|
125 |
+ |
|
126 |
+ return $twig; |
|
127 |
+ } |
|
128 |
+} |
|
129 |
+ |
|
130 |
+class Object |
|
131 |
+{ |
|
132 |
+ public $bar = 'bar'; |
|
133 |
+ |
|
134 |
+ public function foo() |
|
135 |
+ { |
|
136 |
+ return 'foo'; |
|
137 |
+ } |
|
138 |
+} |
0 | 139 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,90 @@ |
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 |
+ |
|
12 |
+require_once dirname(__FILE__).'/bootstrap.php'; |
|
13 |
+ |
|
14 |
+class Twig_Tests_TokenStreamTest extends \PHPUnit_Framework_TestCase |
|
15 |
+{ |
|
16 |
+ static protected $tokens; |
|
17 |
+ |
|
18 |
+ static public function setupBeforeClass() |
|
19 |
+ { |
|
20 |
+ self::$tokens = array( |
|
21 |
+ new Twig_Token(Twig_Token::TEXT_TYPE, 1, 0), |
|
22 |
+ new Twig_Token(Twig_Token::TEXT_TYPE, 2, 0), |
|
23 |
+ new Twig_Token(Twig_Token::TEXT_TYPE, 3, 0), |
|
24 |
+ new Twig_Token(Twig_Token::TEXT_TYPE, 4, 0), |
|
25 |
+ new Twig_Token(Twig_Token::TEXT_TYPE, 5, 0), |
|
26 |
+ new Twig_Token(Twig_Token::TEXT_TYPE, 6, 0), |
|
27 |
+ new Twig_Token(Twig_Token::TEXT_TYPE, 7, 0), |
|
28 |
+ new Twig_Token(Twig_Token::EOF_TYPE, 0, 0), |
|
29 |
+ ); |
|
30 |
+ } |
|
31 |
+ |
|
32 |
+ public function testNext() |
|
33 |
+ { |
|
34 |
+ $stream = new Twig_TokenStream(self::$tokens, '', false); |
|
35 |
+ $repr = array(); |
|
36 |
+ while (!$stream->isEOF()) |
|
37 |
+ { |
|
38 |
+ $token = $stream->next(); |
|
39 |
+ |
|
40 |
+ $repr[] = $token->getValue(); |
|
41 |
+ } |
|
42 |
+ $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->next() returns the next token in the stream'); |
|
43 |
+ } |
|
44 |
+ |
|
45 |
+ public function testLook() |
|
46 |
+ { |
|
47 |
+ $stream = new Twig_TokenStream(self::$tokens, '', false); |
|
48 |
+ $this->assertEquals(2, $stream->look()->getValue(), '->look() returns the next token'); |
|
49 |
+ $repr = array(); |
|
50 |
+ while (!$stream->isEOF()) |
|
51 |
+ { |
|
52 |
+ $token = $stream->next(); |
|
53 |
+ |
|
54 |
+ $repr[] = $token->getValue(); |
|
55 |
+ } |
|
56 |
+ $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->look() pushes the token to the stack'); |
|
57 |
+ |
|
58 |
+ $stream = new Twig_TokenStream(self::$tokens, '', false); |
|
59 |
+ $this->assertEquals(2, $stream->look()->getValue(), '->look() returns the next token'); |
|
60 |
+ $this->assertEquals(3, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token'); |
|
61 |
+ $this->assertEquals(4, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token'); |
|
62 |
+ $this->assertEquals(5, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token'); |
|
63 |
+ $repr = array(); |
|
64 |
+ while (!$stream->isEOF()) |
|
65 |
+ { |
|
66 |
+ $token = $stream->next(); |
|
67 |
+ |
|
68 |
+ $repr[] = $token->getValue(); |
|
69 |
+ } |
|
70 |
+ $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->look() pushes the token to the stack'); |
|
71 |
+ } |
|
72 |
+ |
|
73 |
+ public function testRewind() |
|
74 |
+ { |
|
75 |
+ $stream = new Twig_TokenStream(self::$tokens, '', false); |
|
76 |
+ $this->assertEquals(2, $stream->look()->getValue(), '->look() returns the next token'); |
|
77 |
+ $this->assertEquals(3, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token'); |
|
78 |
+ $this->assertEquals(4, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token'); |
|
79 |
+ $this->assertEquals(5, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token'); |
|
80 |
+ $stream->rewind(); |
|
81 |
+ $repr = array(); |
|
82 |
+ while (!$stream->isEOF()) |
|
83 |
+ { |
|
84 |
+ $token = $stream->next(false); |
|
85 |
+ |
|
86 |
+ $repr[] = $token->getValue(); |
|
87 |
+ } |
|
88 |
+ $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->rewind() pushes all pushed tokens to the token array'); |
|
89 |
+ } |
|
90 |
+} |
0 | 91 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,13 @@ |
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 |
+ |
|
12 |
+require_once dirname(__FILE__).'/../../../lib/Twig/Autoloader.php'; |
|
13 |
+Twig_Autoloader::register(); |
0 | 14 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,110 @@ |
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 |
+ |
|
12 |
+require_once dirname(__FILE__).'/bootstrap.php'; |
|
13 |
+ |
|
14 |
+class Twig_Tests_IntegrationTest extends \PHPUnit_Framework_TestCase |
|
15 |
+{ |
|
16 |
+ static protected $fixturesDir; |
|
17 |
+ |
|
18 |
+ static public function setUpBeforeClass() |
|
19 |
+ { |
|
20 |
+ self::$fixturesDir = realpath(dirname(__FILE__).'/../../fixtures/'); |
|
21 |
+ } |
|
22 |
+ |
|
23 |
+ public function testIntegration() |
|
24 |
+ { |
|
25 |
+ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(self::$fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) |
|
26 |
+ { |
|
27 |
+ if (!preg_match('/\.test$/', $file)) |
|
28 |
+ { |
|
29 |
+ continue; |
|
30 |
+ } |
|
31 |
+ |
|
32 |
+ $test = file_get_contents($file->getRealpath()); |
|
33 |
+ |
|
34 |
+ if (!preg_match('/--TEST--\s*(.*?)\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) |
|
35 |
+ { |
|
36 |
+ throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace(self::$fixturesDir.'/', '', $file))); |
|
37 |
+ } |
|
38 |
+ |
|
39 |
+ $message = $match[1]; |
|
40 |
+ $templates = array(); |
|
41 |
+ preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $match[2], $matches, PREG_SET_ORDER); |
|
42 |
+ foreach ($matches as $match) |
|
43 |
+ { |
|
44 |
+ $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2]; |
|
45 |
+ } |
|
46 |
+ |
|
47 |
+ $loader = new Twig_Loader_Array($templates); |
|
48 |
+ $twig = new Twig_Environment($loader, array('trim_blocks' => true, 'cache' => false)); |
|
49 |
+ $twig->addExtension(new Twig_Extension_Escaper()); |
|
50 |
+ $twig->addExtension(new TestExtension()); |
|
51 |
+ |
|
52 |
+ $template = $twig->loadTemplate('index.twig'); |
|
53 |
+ |
|
54 |
+ preg_match_all('/--DATA--(.*?)--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $matches, PREG_SET_ORDER); |
|
55 |
+ foreach ($matches as $match) |
|
56 |
+ { |
|
57 |
+ $output = trim($template->render(eval($match[1].';')), "\n "); |
|
58 |
+ $expected = trim($match[2], "\n "); |
|
59 |
+ |
|
60 |
+ $this->assertEquals($expected, $output, $message); |
|
61 |
+ if ($output != $expected) |
|
62 |
+ { |
|
63 |
+ echo 'Compiled template that failed:'; |
|
64 |
+ |
|
65 |
+ foreach (array_keys($templates) as $name) |
|
66 |
+ { |
|
67 |
+ $source = $loader->getSource($name); |
|
68 |
+ echo $twig->compile($twig->parse($twig->tokenize($source, $name))); |
|
69 |
+ } |
|
70 |
+ } |
|
71 |
+ } |
|
72 |
+ } |
|
73 |
+ } |
|
74 |
+} |
|
75 |
+ |
|
76 |
+class Foo |
|
77 |
+{ |
|
78 |
+ public function bar($param1 = null, $param2 = null) |
|
79 |
+ { |
|
80 |
+ return 'bar'.($param1 ? '_'.$param1 : '').($param2 ? '-'.$param2 : ''); |
|
81 |
+ } |
|
82 |
+ |
|
83 |
+ public function getFoo() |
|
84 |
+ { |
|
85 |
+ return 'foo'; |
|
86 |
+ } |
|
87 |
+ |
|
88 |
+ public function getSelf() |
|
89 |
+ { |
|
90 |
+ return $this; |
|
91 |
+ } |
|
92 |
+} |
|
93 |
+ |
|
94 |
+class TestExtension extends Twig_Extension |
|
95 |
+{ |
|
96 |
+ public function getFilters() |
|
97 |
+ { |
|
98 |
+ return array('nl2br' => new Twig_Filter_Method($this, 'nl2br')); |
|
99 |
+ } |
|
100 |
+ |
|
101 |
+ public function nl2br($value, $sep = '<br />') |
|
102 |
+ { |
|
103 |
+ return str_replace("\n", $sep."\n", $value); |
|
104 |
+ } |
|
105 |
+ |
|
106 |
+ public function getName() |
|
107 |
+ { |
|
108 |
+ return 'test'; |
|
109 |
+ } |
|
110 |
+} |
0 | 111 |
deleted file mode 100644 |
... | ... |
@@ -1,44 +0,0 @@ |
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 |
- |
|
12 |
-require_once(dirname(__FILE__).'/../lib/lime/LimeAutoloader.php'); |
|
13 |
-LimeAutoloader::register(); |
|
14 |
- |
|
15 |
-$suite = new LimeTestSuite(array( |
|
16 |
- 'force_colors' => isset($argv) && in_array('--color', $argv), |
|
17 |
- 'base_dir' => realpath(dirname(__FILE__).'/..'), |
|
18 |
-)); |
|
19 |
- |
|
20 |
-foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(dirname(__FILE__).'/../unit'), RecursiveIteratorIterator::LEAVES_ONLY) as $file) |
|
21 |
-{ |
|
22 |
- if (preg_match('/Test\.php$/', $file)) |
|
23 |
- { |
|
24 |
- $suite->register($file->getRealPath()); |
|
25 |
- } |
|
26 |
-} |
|
27 |
- |
|
28 |
-$coverage = new LimeCoverage($suite, array( |
|
29 |
- 'base_dir' => realpath(dirname(__FILE__).'/../../lib'), |
|
30 |
- 'extension' => '.php', |
|
31 |
- 'verbose' => true, |
|
32 |
-)); |
|
33 |
- |
|
34 |
-$files = array(); |
|
35 |
-foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(dirname(__FILE__).'/../../lib'), RecursiveIteratorIterator::LEAVES_ONLY) as $file) |
|
36 |
-{ |
|
37 |
- if (preg_match('/\.php$/', $file)) |
|
38 |
- { |
|
39 |
- $files[] = $file->getRealPath(); |
|
40 |
- } |
|
41 |
-} |
|
42 |
-$coverage->setFiles($files); |
|
43 |
- |
|
44 |
-$coverage->run(); |
45 | 0 |
deleted file mode 100644 |
... | ... |
@@ -1,28 +0,0 @@ |
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 |
- |
|
12 |
-require_once(dirname(__FILE__).'/../lib/lime/LimeAutoloader.php'); |
|
13 |
-LimeAutoloader::register(); |
|
14 |
- |
|
15 |
-$suite = new LimeTestSuite(array( |
|
16 |
- 'force_colors' => isset($argv) && in_array('--color', $argv), |
|
17 |
- 'base_dir' => realpath(dirname(__FILE__).'/..'), |
|
18 |
-)); |
|
19 |
- |
|
20 |
-foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(dirname(__FILE__).'/../unit'), RecursiveIteratorIterator::LEAVES_ONLY) as $file) |
|
21 |
-{ |
|
22 |
- if (preg_match('/Test\.php$/', $file)) |
|
23 |
- { |
|
24 |
- $suite->register($file->getRealPath()); |
|
25 |
- } |
|
26 |
-} |
|
27 |
- |
|
28 |
-exit($suite->run() ? 0 : 1); |
29 | 0 |
deleted file mode 100644 |
... | ... |
@@ -1,27 +0,0 @@ |
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 |
- |
|
12 |
-require_once(dirname(__FILE__).'/../../lib/lime/LimeAutoloader.php'); |
|
13 |
-LimeAutoloader::register(); |
|
14 |
- |
|
15 |
-require_once dirname(__FILE__).'/../../../lib/Twig/Autoloader.php'; |
|
16 |
-Twig_Autoloader::register(); |
|
17 |
- |
|
18 |
-$t = new LimeTest(3); |
|
19 |
- |
|
20 |
-// ->autoload() |
|
21 |
-$t->diag('->autoload()'); |
|
22 |
- |
|
23 |
-$t->ok(!class_exists('Foo'), '->autoload() does not try to load classes that does not begin with Twig'); |
|
24 |
- |
|
25 |
-$autoloader = new Twig_Autoloader(); |
|
26 |
-$t->is($autoloader->autoload('Twig_Parser'), true, '->autoload() returns true if it is able to load a class'); |
|
27 |
-$t->is($autoloader->autoload('Foo'), false, '->autoload() returns false if it is not able to load a class'); |
28 | 0 |
deleted file mode 100644 |
... | ... |
@@ -1,138 +0,0 @@ |
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 |
- |
|
12 |
-require_once(dirname(__FILE__).'/../../../lib/lime/LimeAutoloader.php'); |
|
13 |
-LimeAutoloader::register(); |
|
14 |
- |
|
15 |
-require_once dirname(__FILE__).'/../../../../lib/Twig/Autoloader.php'; |
|
16 |
-Twig_Autoloader::register(); |
|
17 |
- |
|
18 |
-class Object |
|
19 |
-{ |
|
20 |
- public $bar = 'bar'; |
|
21 |
- |
|
22 |
- public function foo() |
|
23 |
- { |
|
24 |
- return 'foo'; |
|
25 |
- } |
|
26 |
-} |
|
27 |
- |
|
28 |
-$params = array( |
|
29 |
- 'name' => 'Fabien', |
|
30 |
- 'obj' => new Object(), |
|
31 |
-); |
|
32 |
-$templates = array( |
|
33 |
- '1_basic1' => '{{ obj.foo }}', |
|
34 |
- '1_basic2' => '{{ name|upper }}', |
|
35 |
- '1_basic3' => '{% if name %}foo{% endif %}', |
|
36 |
- '1_basic4' => '{{ obj.bar }}', |
|
37 |
- '1_basic' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', |
|
38 |
-); |
|
39 |
- |
|
40 |
-$t = new LimeTest(11); |
|
41 |
- |
|
42 |
-$t->diag('Sandbox globally set'); |
|
43 |
-$twig = get_environment(false, $templates); |
|
44 |
-$t->is($twig->loadTemplate('1_basic')->render($params), 'FOO', 'Sandbox does nothing if it is disabled globally'); |
|
45 |
- |
|
46 |
-$twig = get_environment(true, $templates); |
|
47 |
-try |
|
48 |
-{ |
|
49 |
- $twig->loadTemplate('1_basic1')->render($params); |
|
50 |
- $t->fail('Sandbox throws a SecurityError exception if an unallowed method is called'); |
|
51 |
-} |
|
52 |
-catch (Twig_Sandbox_SecurityError $e) |
|
53 |
-{ |
|
54 |
- $t->pass('Sandbox throws a SecurityError exception if an unallowed method is called'); |
|
55 |
-} |
|
56 |
- |
|
57 |
-$twig = get_environment(true, $templates); |
|
58 |
-try |
|
59 |
-{ |
|
60 |
- $twig->loadTemplate('1_basic2')->render($params); |
|
61 |
- $t->fail('Sandbox throws a SecurityError exception if an unallowed filter is called'); |
|
62 |
-} |
|
63 |
-catch (Twig_Sandbox_SecurityError $e) |
|
64 |
-{ |
|
65 |
- $t->pass('Sandbox throws a SecurityError exception if an unallowed filter is called'); |
|
66 |
-} |
|
67 |
- |
|
68 |
-$twig = get_environment(true, $templates); |
|
69 |
-try |
|
70 |
-{ |
|
71 |
- $twig->loadTemplate('1_basic3')->render($params); |
|
72 |
- $t->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template'); |
|
73 |
-} |
|
74 |
-catch (Twig_Sandbox_SecurityError $e) |
|
75 |
-{ |
|
76 |
- $t->pass('Sandbox throws a SecurityError exception if an unallowed tag is used in the template'); |
|
77 |
-} |
|
78 |
- |
|
79 |
-$twig = get_environment(true, $templates); |
|
80 |
-try |
|
81 |
-{ |
|
82 |
- $twig->loadTemplate('1_basic4')->render($params); |
|
83 |
- $t->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template'); |
|
84 |
-} |
|
85 |
-catch (Twig_Sandbox_SecurityError $e) |
|
86 |
-{ |
|
87 |
- $t->pass('Sandbox throws a SecurityError exception if an unallowed property is called in the template'); |
|
88 |
-} |
|
89 |
- |
|
90 |
-$twig = get_environment(true, $templates, array(), array(), array('Object' => 'foo')); |
|
91 |
-$t->is($twig->loadTemplate('1_basic1')->render($params), 'foo', 'Sandbox allow some methods'); |
|
92 |
- |
|
93 |
-$twig = get_environment(true, $templates, array(), array('upper')); |
|
94 |
-$t->is($twig->loadTemplate('1_basic2')->render($params), 'FABIEN', 'Sandbox allow some filters'); |
|
95 |
- |
|
96 |
-$twig = get_environment(true, $templates, array('if')); |
|
97 |
-$t->is($twig->loadTemplate('1_basic3')->render($params), 'foo', 'Sandbox allow some tags'); |
|
98 |
- |
|
99 |
-$twig = get_environment(true, $templates, array(), array(), array(), array('Object' => 'bar')); |
|
100 |
-$t->is($twig->loadTemplate('1_basic4')->render($params), 'bar', 'Sandbox allow some properties'); |
|
101 |
- |
|
102 |
-$t->diag('Sandbox locally set for an include'); |
|
103 |
- |
|
104 |
-$templates = array( |
|
105 |
- '2_basic' => '{{ obj.foo }}{% include "2_included" %}{{ obj.foo }}', |
|
106 |
- '2_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', |
|
107 |
-); |
|
108 |
- |
|
109 |
-$twig = get_environment(false, $templates); |
|
110 |
-$t->is($twig->loadTemplate('2_basic')->render($params), 'fooFOOfoo', 'Sandbox does nothing if disabled globally and sandboxed not used for the include'); |
|
111 |
- |
|
112 |
-$templates = array( |
|
113 |
- '3_basic' => '{{ obj.foo }}{% include "3_included" sandboxed %}{{ obj.foo }}', |
|
114 |
- '3_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', |
|
115 |
-); |
|
116 |
- |
|
117 |
-$twig = get_environment(false, $templates); |
|
118 |
-$twig = get_environment(true, $templates); |
|
119 |
-try |
|
120 |
-{ |
|
121 |
- $twig->loadTemplate('3_basic')->render($params); |
|
122 |
- $t->fail('Sandbox throws a SecurityError exception when the included file is sandboxed'); |
|
123 |
-} |
|
124 |
-catch (Twig_Sandbox_SecurityError $e) |
|
125 |
-{ |
|
126 |
- $t->pass('Sandbox throws a SecurityError exception when the included file is sandboxed'); |
|
127 |
-} |
|
128 |
- |
|
129 |
- |
|
130 |
-function get_environment($sandboxed, $templates, $tags = array(), $filters = array(), $methods = array(), $properties = array()) |
|
131 |
-{ |
|
132 |
- $loader = new Twig_Loader_Array($templates); |
|
133 |
- $twig = new Twig_Environment($loader, array('trim_blocks' => true, 'debug' => true)); |
|
134 |
- $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties); |
|
135 |
- $twig->addExtension(new Twig_Extension_Sandbox($policy, $sandboxed)); |
|
136 |
- |
|
137 |
- return $twig; |
|
138 |
-} |
139 | 0 |
deleted file mode 100644 |
... | ... |
@@ -1,85 +0,0 @@ |
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 |
- |
|
12 |
-require_once(dirname(__FILE__).'/../../lib/lime/LimeAutoloader.php'); |
|
13 |
-LimeAutoloader::register(); |
|
14 |
- |
|
15 |
-require_once dirname(__FILE__).'/../../../lib/Twig/Autoloader.php'; |
|
16 |
-Twig_Autoloader::register(); |
|
17 |
- |
|
18 |
-$t = new LimeTest(13); |
|
19 |
- |
|
20 |
-$tokens = array( |
|
21 |
- new Twig_Token(Twig_Token::TEXT_TYPE, 1, 0), |
|
22 |
- new Twig_Token(Twig_Token::TEXT_TYPE, 2, 0), |
|
23 |
- new Twig_Token(Twig_Token::TEXT_TYPE, 3, 0), |
|
24 |
- new Twig_Token(Twig_Token::TEXT_TYPE, 4, 0), |
|
25 |
- new Twig_Token(Twig_Token::TEXT_TYPE, 5, 0), |
|
26 |
- new Twig_Token(Twig_Token::TEXT_TYPE, 6, 0), |
|
27 |
- new Twig_Token(Twig_Token::TEXT_TYPE, 7, 0), |
|
28 |
- new Twig_Token(Twig_Token::EOF_TYPE, 0, 0), |
|
29 |
-); |
|
30 |
- |
|
31 |
-// ->next() |
|
32 |
-$t->diag('->next()'); |
|
33 |
-$stream = new Twig_TokenStream($tokens, '', false); |
|
34 |
-$repr = array(); |
|
35 |
-while (!$stream->isEOF()) |
|
36 |
-{ |
|
37 |
- $token = $stream->next(); |
|
38 |
- |
|
39 |
- $repr[] = $token->getValue(); |
|
40 |
-} |
|
41 |
-$t->is(implode(', ', $repr), '1, 2, 3, 4, 5, 6, 7', '->next() returns the next token in the stream'); |
|
42 |
- |
|
43 |
-// ->look() |
|
44 |
-$t->diag('->look()'); |
|
45 |
-$stream = new Twig_TokenStream($tokens, '', false); |
|
46 |
-$t->is($stream->look()->getValue(), 2, '->look() returns the next token'); |
|
47 |
-$repr = array(); |
|
48 |
-while (!$stream->isEOF()) |
|
49 |
-{ |
|
50 |
- $token = $stream->next(); |
|
51 |
- |
|
52 |
- $repr[] = $token->getValue(); |
|
53 |
-} |
|
54 |
-$t->is(implode(', ', $repr), '1, 2, 3, 4, 5, 6, 7', '->look() pushes the token to the stack'); |
|
55 |
- |
|
56 |
-$stream = new Twig_TokenStream($tokens, '', false); |
|
57 |
-$t->is($stream->look()->getValue(), 2, '->look() returns the next token'); |
|
58 |
-$t->is($stream->look()->getValue(), 3, '->look() can be called several times to look more than one upcoming token'); |
|
59 |
-$t->is($stream->look()->getValue(), 4, '->look() can be called several times to look more than one upcoming token'); |
|
60 |
-$t->is($stream->look()->getValue(), 5, '->look() can be called several times to look more than one upcoming token'); |
|
61 |
-$repr = array(); |
|
62 |
-while (!$stream->isEOF()) |
|
63 |
-{ |
|
64 |
- $token = $stream->next(); |
|
65 |
- |
|
66 |
- $repr[] = $token->getValue(); |
|
67 |
-} |
|
68 |
-$t->is(implode(', ', $repr), '1, 2, 3, 4, 5, 6, 7', '->look() pushes the token to the stack'); |
|
69 |
- |
|
70 |
-// ->rewind() |
|
71 |
-$t->diag('->rewind()'); |
|
72 |
-$stream = new Twig_TokenStream($tokens, '', false); |
|
73 |
-$t->is($stream->look()->getValue(), 2, '->look() returns the next token'); |
|
74 |
-$t->is($stream->look()->getValue(), 3, '->look() can be called several times to look more than one upcoming token'); |
|
75 |
-$t->is($stream->look()->getValue(), 4, '->look() can be called several times to look more than one upcoming token'); |
|
76 |
-$t->is($stream->look()->getValue(), 5, '->look() can be called several times to look more than one upcoming token'); |
|
77 |
-$stream->rewind(); |
|
78 |
-$repr = array(); |
|
79 |
-while (!$stream->isEOF()) |
|
80 |
-{ |
|
81 |
- $token = $stream->next(false); |
|
82 |
- |
|
83 |
- $repr[] = $token->getValue(); |
|
84 |
-} |
|
85 |
-$t->is(implode(', ', $repr), '1, 2, 3, 4, 5, 6, 7', '->rewind() pushes all pushed tokens to the token array'); |
86 | 0 |
deleted file mode 100644 |
... | ... |
@@ -1,104 +0,0 @@ |
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 |
- |
|
12 |
-require_once(dirname(__FILE__).'/../lib/lime/LimeAutoloader.php'); |
|
13 |
-LimeAutoloader::register(); |
|
14 |
- |
|
15 |
-require_once dirname(__FILE__).'/../../lib/Twig/Autoloader.php'; |
|
16 |
-Twig_Autoloader::register(); |
|
17 |
- |
|
18 |
-class Foo |
|
19 |
-{ |
|
20 |
- public function bar($param1 = null, $param2 = null) |
|
21 |
- { |
|
22 |
- return 'bar'.($param1 ? '_'.$param1 : '').($param2 ? '-'.$param2 : ''); |
|
23 |
- } |
|
24 |
- |
|
25 |
- public function getFoo() |
|
26 |
- { |
|
27 |
- return 'foo'; |
|
28 |
- } |
|
29 |
- |
|
30 |
- public function getSelf() |
|
31 |
- { |
|
32 |
- return $this; |
|
33 |
- } |
|
34 |
-} |
|
35 |
- |
|
36 |
-class TestExtension extends Twig_Extension |
|
37 |
-{ |
|
38 |
- public function getFilters() |
|
39 |
- { |
|
40 |
- return array('nl2br' => new Twig_Filter_Method($this, 'nl2br')); |
|
41 |
- } |
|
42 |
- |
|
43 |
- public function nl2br($value, $sep = '<br />') |
|
44 |
- { |
|
45 |
- return str_replace("\n", $sep."\n", $value); |
|
46 |
- } |
|
47 |
- |
|
48 |
- public function getName() |
|
49 |
- { |
|
50 |
- return 'test'; |
|
51 |
- } |
|
52 |
-} |
|
53 |
- |
|
54 |
-$t = new LimeTest(62); |
|
55 |
-$fixturesDir = realpath(dirname(__FILE__).'/../fixtures/'); |
|
56 |
- |
|
57 |
-foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) |
|
58 |
-{ |
|
59 |
- if (!preg_match('/\.test$/', $file)) |
|
60 |
- { |
|
61 |
- continue; |
|
62 |
- } |
|
63 |
- |
|
64 |
- $test = file_get_contents($file->getRealpath()); |
|
65 |
- |
|
66 |
- if (!preg_match('/--TEST--\s*(.*?)\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) |
|
67 |
- { |
|
68 |
- throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file))); |
|
69 |
- } |
|
70 |
- |
|
71 |
- $message = $match[1]; |
|
72 |
- $templates = array(); |
|
73 |
- preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $match[2], $matches, PREG_SET_ORDER); |
|
74 |
- foreach ($matches as $match) |
|
75 |
- { |
|
76 |
- $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2]; |
|
77 |
- } |
|
78 |
- |
|
79 |
- $loader = new Twig_Loader_Array($templates); |
|
80 |
- $twig = new Twig_Environment($loader, array('trim_blocks' => true, 'cache' => false)); |
|
81 |
- $twig->addExtension(new Twig_Extension_Escaper()); |
|
82 |
- $twig->addExtension(new TestExtension()); |
|
83 |
- |
|
84 |
- $template = $twig->loadTemplate('index.twig'); |
|
85 |
- |
|
86 |
- preg_match_all('/--DATA--(.*?)--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $matches, PREG_SET_ORDER); |
|
87 |
- foreach ($matches as $match) |
|
88 |
- { |
|
89 |
- $output = trim($template->render(eval($match[1].';')), "\n "); |
|
90 |
- $expected = trim($match[2], "\n "); |
|
91 |
- |
|
92 |
- $t->is($output, $expected, $message); |
|
93 |
- if ($output != $expected) |
|
94 |
- { |
|
95 |
- $t->comment('Compiled template that failed:'); |
|
96 |
- |
|
97 |
- foreach (array_keys($templates) as $name) |
|
98 |
- { |
|
99 |
- $source = $loader->getSource($name); |
|
100 |
- $t->comment($twig->compile($twig->parse($twig->tokenize($source, $name)))); |
|
101 |
- } |
|
102 |
- } |
|
103 |
- } |
|
104 |
-} |