TemplateTest.php 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <?php
  2. /*
  3. * This file is part of Twig.
  4. *
  5. * (c) Fabien Potencier
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. class Twig_Tests_TemplateTest extends PHPUnit_Framework_TestCase
  11. {
  12. /**
  13. * @dataProvider getGetAttributeTests
  14. */
  15. public function testGetAttribute($defined, $value, $object, $item, $arguments, $type, $useExt = false)
  16. {
  17. $template = new Twig_TemplateTest(
  18. new Twig_Environment(),
  19. $useExt
  20. );
  21. $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type));
  22. }
  23. /**
  24. * @dataProvider getGetAttributeTests
  25. */
  26. public function testGetAttributeStrict($defined, $value, $object, $item, $arguments, $type, $useExt = false, $exceptionMessage = null)
  27. {
  28. $template = new Twig_TemplateTest(
  29. new Twig_Environment(null, array('strict_variables' => true)),
  30. $useExt
  31. );
  32. if ($defined) {
  33. $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type));
  34. } else {
  35. try {
  36. $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type));
  37. throw new Exception('Expected Twig_Error_Runtime exception.');
  38. } catch (Twig_Error_Runtime $e) {
  39. if (null !== $exceptionMessage) {
  40. $this->assertSame($exceptionMessage, $e->getMessage());
  41. }
  42. }
  43. }
  44. }
  45. /**
  46. * @dataProvider getGetAttributeTests
  47. */
  48. public function testGetAttributeDefined($defined, $value, $object, $item, $arguments, $type, $useExt = false)
  49. {
  50. $template = new Twig_TemplateTest(
  51. new Twig_Environment(),
  52. $useExt
  53. );
  54. $this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true));
  55. }
  56. /**
  57. * @dataProvider getGetAttributeTests
  58. */
  59. public function testGetAttributeDefinedStrict($defined, $value, $object, $item, $arguments, $type, $useExt = false)
  60. {
  61. $template = new Twig_TemplateTest(
  62. new Twig_Environment(null, array('strict_variables' => true)),
  63. $useExt
  64. );
  65. $this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true));
  66. }
  67. public function getGetAttributeTests()
  68. {
  69. $array = array(
  70. 'defined' => 'defined',
  71. 'zero' => 0,
  72. 'null' => null,
  73. '1' => 1,
  74. );
  75. $objectArray = new Twig_TemplateArrayAccessObject();
  76. $stdObject = (object) $array;
  77. $magicPropertyObject = new Twig_TemplateMagicPropertyObject();
  78. $propertyObject = new Twig_TemplatePropertyObject();
  79. $propertyObject1 = new Twig_TemplatePropertyObjectAndIterator();
  80. $methodObject = new Twig_TemplateMethodObject();
  81. $magicMethodObject = new Twig_TemplateMagicMethodObject();
  82. $anyType = Twig_TemplateInterface::ANY_CALL;
  83. $methodType = Twig_TemplateInterface::METHOD_CALL;
  84. $arrayType = Twig_TemplateInterface::ARRAY_CALL;
  85. $basicTests = array(
  86. // array(defined, value, property to fetch)
  87. array(true, 'defined', 'defined'),
  88. array(false, null, 'undefined'),
  89. array(false, null, 'protected'),
  90. array(true, 0, 'zero'),
  91. array(true, 1, 1),
  92. array(true, 1, 1.0),
  93. array(true, null, 'null'),
  94. );
  95. $testObjects = array(
  96. // array(object, type of fetch)
  97. array($array, $arrayType),
  98. array($objectArray, $arrayType),
  99. array($stdObject, $anyType),
  100. array($magicPropertyObject, $anyType),
  101. array($methodObject, $methodType),
  102. array($methodObject, $anyType),
  103. array($propertyObject, $anyType),
  104. array($propertyObject1, $anyType),
  105. );
  106. $tests = array();
  107. foreach ($testObjects as $testObject) {
  108. foreach ($basicTests as $test) {
  109. // properties cannot be numbers
  110. if (($testObject[0] instanceof stdClass || $testObject[0] instanceof Twig_TemplatePropertyObject) && is_numeric($test[2])) {
  111. continue;
  112. }
  113. $tests[] = array($test[0], $test[1], $testObject[0], $test[2], array(), $testObject[1]);
  114. }
  115. }
  116. // additional method tests
  117. $tests = array_merge($tests, array(
  118. array(true, 'defined', $methodObject, 'defined', array(), $methodType),
  119. array(true, 'defined', $methodObject, 'DEFINED', array(), $methodType),
  120. array(true, 'defined', $methodObject, 'getDefined', array(), $methodType),
  121. array(true, 'defined', $methodObject, 'GETDEFINED', array(), $methodType),
  122. array(true, 'static', $methodObject, 'static', array(), $methodType),
  123. array(true, 'static', $methodObject, 'getStatic', array(), $methodType),
  124. array(true, '__call_undefined', $magicMethodObject, 'undefined', array(), $methodType),
  125. array(true, '__call_UNDEFINED', $magicMethodObject, 'UNDEFINED', array(), $methodType),
  126. ));
  127. // add the same tests for the any type
  128. foreach ($tests as $test) {
  129. if ($anyType !== $test[5]) {
  130. $test[5] = $anyType;
  131. $tests[] = $test;
  132. }
  133. }
  134. $methodAndPropObject = new Twig_TemplateMethodAndPropObject;
  135. // additional method tests
  136. $tests = array_merge($tests, array(
  137. array(true, 'a', $methodAndPropObject, 'a', array(), $anyType),
  138. array(true, 'a', $methodAndPropObject, 'a', array(), $methodType),
  139. array(false, null, $methodAndPropObject, 'a', array(), $arrayType),
  140. array(true, 'b_prop', $methodAndPropObject, 'b', array(), $anyType),
  141. array(true, 'b', $methodAndPropObject, 'B', array(), $anyType),
  142. array(true, 'b', $methodAndPropObject, 'b', array(), $methodType),
  143. array(true, 'b', $methodAndPropObject, 'B', array(), $methodType),
  144. array(false, null, $methodAndPropObject, 'b', array(), $arrayType),
  145. array(false, null, $methodAndPropObject, 'c', array(), $anyType),
  146. array(false, null, $methodAndPropObject, 'c', array(), $methodType),
  147. array(false, null, $methodAndPropObject, 'c', array(), $arrayType),
  148. ));
  149. // tests when input is not an array or object
  150. $tests = array_merge($tests, array(
  151. array(false, null, 42, 'a', array(), $anyType, false, 'Item "a" for "42" does not exist'),
  152. array(false, null, "string", 'a', array(), $anyType, false, 'Item "a" for "string" does not exist'),
  153. array(false, null, array(), 'a', array(), $anyType, false, 'Item "a" for "Array" does not exist'),
  154. ));
  155. // add twig_template_get_attributes tests
  156. if (function_exists('twig_template_get_attributes')) {
  157. foreach(array_slice($tests, 0) as $test) {
  158. $test = array_pad($test, 7, null);
  159. $test[6] = true;
  160. $tests[] = $test;
  161. }
  162. }
  163. return $tests;
  164. }
  165. public function useExtGetAttribute()
  166. {
  167. return false;
  168. }
  169. }
  170. class Twig_TemplateTest extends Twig_Template
  171. {
  172. protected $useExtGetAttribute = false;
  173. public function __construct(Twig_Environment $env, $useExtGetAttribute = false)
  174. {
  175. parent::__construct($env);
  176. $this->useExtGetAttribute = $useExtGetAttribute;
  177. Twig_Template::clearCache();
  178. }
  179. public function getTemplateName()
  180. {
  181. }
  182. protected function doGetParent(array $context)
  183. {
  184. }
  185. protected function doDisplay(array $context, array $blocks = array())
  186. {
  187. }
  188. public function getAttribute($object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
  189. {
  190. if ($this->useExtGetAttribute) {
  191. return twig_template_get_attributes($this, $object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck);
  192. } else {
  193. return parent::getAttribute($object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck);
  194. }
  195. }
  196. }
  197. class Twig_TemplateArrayAccessObject implements ArrayAccess
  198. {
  199. protected $protected = 'protected';
  200. public $attributes = array(
  201. 'defined' => 'defined',
  202. 'zero' => 0,
  203. 'null' => null,
  204. '1' => 1,
  205. );
  206. public function offsetExists($name)
  207. {
  208. return array_key_exists($name, $this->attributes);
  209. }
  210. public function offsetGet($name)
  211. {
  212. return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : null;
  213. }
  214. public function offsetSet($name, $value)
  215. {
  216. }
  217. public function offsetUnset($name)
  218. {
  219. }
  220. }
  221. class Twig_TemplateMagicPropertyObject
  222. {
  223. public $defined = 'defined';
  224. public $attributes = array(
  225. 'zero' => 0,
  226. 'null' => null,
  227. '1' => 1,
  228. );
  229. protected $protected = 'protected';
  230. public function __isset($name)
  231. {
  232. return array_key_exists($name, $this->attributes);
  233. }
  234. public function __get($name)
  235. {
  236. return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : null;
  237. }
  238. }
  239. class Twig_TemplatePropertyObject
  240. {
  241. public $defined = 'defined';
  242. public $zero = 0;
  243. public $null = null;
  244. protected $protected = 'protected';
  245. }
  246. class Twig_TemplatePropertyObjectAndIterator extends Twig_TemplatePropertyObject implements IteratorAggregate
  247. {
  248. public function getIterator()
  249. {
  250. return new ArrayIterator(array('foo', 'bar'));
  251. }
  252. }
  253. class Twig_TemplateMethodObject
  254. {
  255. public function getDefined()
  256. {
  257. return 'defined';
  258. }
  259. public function get1()
  260. {
  261. return 1;
  262. }
  263. public function getZero()
  264. {
  265. return 0;
  266. }
  267. public function getNull()
  268. {
  269. return null;
  270. }
  271. protected function getProtected()
  272. {
  273. return 'protected';
  274. }
  275. static public function getStatic()
  276. {
  277. return 'static';
  278. }
  279. }
  280. class Twig_TemplateMethodAndPropObject
  281. {
  282. private $a = 'a_prop';
  283. public function getA() {
  284. return 'a';
  285. }
  286. public $b = 'b_prop';
  287. public function getB() {
  288. return 'b';
  289. }
  290. private $c = 'c_prop';
  291. private function getC() {
  292. return 'c';
  293. }
  294. }
  295. class Twig_TemplateMagicMethodObject
  296. {
  297. public function __call($method, $arguments) {
  298. return '__call_'.$method;
  299. }
  300. }