PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php

http://github.com/fabpot/symfony
PHP | 341 lines | 185 code | 37 blank | 119 comment | 0 complexity | e3318e91888effd6f62f5312cca645f0 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Config\Tests\Definition;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\Config\Definition\ArrayNode;
  13. use Symfony\Component\Config\Definition\PrototypedArrayNode;
  14. use Symfony\Component\Config\Definition\ScalarNode;
  15. use Symfony\Component\Config\Definition\VariableNode;
  16. class PrototypedArrayNodeTest extends TestCase
  17. {
  18. public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes()
  19. {
  20. $node = new PrototypedArrayNode('root');
  21. $prototype = new ArrayNode(null, $node);
  22. $node->setPrototype($prototype);
  23. $this->assertEmpty($node->getDefaultValue());
  24. }
  25. public function testGetDefaultValueReturnsDefaultValueForPrototypes()
  26. {
  27. $node = new PrototypedArrayNode('root');
  28. $prototype = new ArrayNode(null, $node);
  29. $node->setPrototype($prototype);
  30. $node->setDefaultValue(['test']);
  31. $this->assertEquals(['test'], $node->getDefaultValue());
  32. }
  33. // a remapped key (e.g. "mapping" -> "mappings") should be unset after being used
  34. public function testRemappedKeysAreUnset()
  35. {
  36. $node = new ArrayNode('root');
  37. $mappingsNode = new PrototypedArrayNode('mappings');
  38. $node->addChild($mappingsNode);
  39. // each item under mappings is just a scalar
  40. $prototype = new ScalarNode(null, $mappingsNode);
  41. $mappingsNode->setPrototype($prototype);
  42. $remappings = [];
  43. $remappings[] = ['mapping', 'mappings'];
  44. $node->setXmlRemappings($remappings);
  45. $normalized = $node->normalize(['mapping' => ['foo', 'bar']]);
  46. $this->assertEquals(['mappings' => ['foo', 'bar']], $normalized);
  47. }
  48. /**
  49. * Tests that when a key attribute is mapped, that key is removed from the array.
  50. *
  51. * <things>
  52. * <option id="option1" value="foo">
  53. * <option id="option2" value="bar">
  54. * </things>
  55. *
  56. * The above should finally be mapped to an array that looks like this
  57. * (because "id" is the key attribute).
  58. *
  59. * [
  60. * 'things' => [
  61. * 'option1' => 'foo',
  62. * 'option2' => 'bar',
  63. * ]
  64. * ]
  65. */
  66. public function testMappedAttributeKeyIsRemoved()
  67. {
  68. $node = new PrototypedArrayNode('root');
  69. $node->setKeyAttribute('id', true);
  70. // each item under the root is an array, with one scalar item
  71. $prototype = new ArrayNode(null, $node);
  72. $prototype->addChild(new ScalarNode('foo'));
  73. $node->setPrototype($prototype);
  74. $children = [];
  75. $children[] = ['id' => 'item_name', 'foo' => 'bar'];
  76. $normalized = $node->normalize($children);
  77. $expected = [];
  78. $expected['item_name'] = ['foo' => 'bar'];
  79. $this->assertEquals($expected, $normalized);
  80. }
  81. /**
  82. * Tests the opposite of the testMappedAttributeKeyIsRemoved because
  83. * the removal can be toggled with an option.
  84. */
  85. public function testMappedAttributeKeyNotRemoved()
  86. {
  87. $node = new PrototypedArrayNode('root');
  88. $node->setKeyAttribute('id', false);
  89. // each item under the root is an array, with two scalar items
  90. $prototype = new ArrayNode(null, $node);
  91. $prototype->addChild(new ScalarNode('foo'));
  92. $prototype->addChild(new ScalarNode('id')); // the key attribute will remain
  93. $node->setPrototype($prototype);
  94. $children = [];
  95. $children[] = ['id' => 'item_name', 'foo' => 'bar'];
  96. $normalized = $node->normalize($children);
  97. $expected = [];
  98. $expected['item_name'] = ['id' => 'item_name', 'foo' => 'bar'];
  99. $this->assertEquals($expected, $normalized);
  100. }
  101. public function testAddDefaultChildren()
  102. {
  103. $node = $this->getPrototypeNodeWithDefaultChildren();
  104. $node->setAddChildrenIfNoneSet();
  105. $this->assertTrue($node->hasDefaultValue());
  106. $this->assertEquals([['foo' => 'bar']], $node->getDefaultValue());
  107. $node = $this->getPrototypeNodeWithDefaultChildren();
  108. $node->setKeyAttribute('foobar');
  109. $node->setAddChildrenIfNoneSet();
  110. $this->assertTrue($node->hasDefaultValue());
  111. $this->assertEquals(['defaults' => ['foo' => 'bar']], $node->getDefaultValue());
  112. $node = $this->getPrototypeNodeWithDefaultChildren();
  113. $node->setKeyAttribute('foobar');
  114. $node->setAddChildrenIfNoneSet('defaultkey');
  115. $this->assertTrue($node->hasDefaultValue());
  116. $this->assertEquals(['defaultkey' => ['foo' => 'bar']], $node->getDefaultValue());
  117. $node = $this->getPrototypeNodeWithDefaultChildren();
  118. $node->setKeyAttribute('foobar');
  119. $node->setAddChildrenIfNoneSet(['defaultkey']);
  120. $this->assertTrue($node->hasDefaultValue());
  121. $this->assertEquals(['defaultkey' => ['foo' => 'bar']], $node->getDefaultValue());
  122. $node = $this->getPrototypeNodeWithDefaultChildren();
  123. $node->setKeyAttribute('foobar');
  124. $node->setAddChildrenIfNoneSet(['dk1', 'dk2']);
  125. $this->assertTrue($node->hasDefaultValue());
  126. $this->assertEquals(['dk1' => ['foo' => 'bar'], 'dk2' => ['foo' => 'bar']], $node->getDefaultValue());
  127. $node = $this->getPrototypeNodeWithDefaultChildren();
  128. $node->setAddChildrenIfNoneSet([5, 6]);
  129. $this->assertTrue($node->hasDefaultValue());
  130. $this->assertEquals([0 => ['foo' => 'bar'], 1 => ['foo' => 'bar']], $node->getDefaultValue());
  131. $node = $this->getPrototypeNodeWithDefaultChildren();
  132. $node->setAddChildrenIfNoneSet(2);
  133. $this->assertTrue($node->hasDefaultValue());
  134. $this->assertEquals([['foo' => 'bar'], ['foo' => 'bar']], $node->getDefaultValue());
  135. }
  136. public function testDefaultChildrenWinsOverDefaultValue()
  137. {
  138. $node = $this->getPrototypeNodeWithDefaultChildren();
  139. $node->setAddChildrenIfNoneSet();
  140. $node->setDefaultValue(['bar' => 'foo']);
  141. $this->assertTrue($node->hasDefaultValue());
  142. $this->assertEquals([['foo' => 'bar']], $node->getDefaultValue());
  143. }
  144. protected function getPrototypeNodeWithDefaultChildren()
  145. {
  146. $node = new PrototypedArrayNode('root');
  147. $prototype = new ArrayNode(null, $node);
  148. $child = new ScalarNode('foo');
  149. $child->setDefaultValue('bar');
  150. $prototype->addChild($child);
  151. $prototype->setAddIfNotSet(true);
  152. $node->setPrototype($prototype);
  153. return $node;
  154. }
  155. /**
  156. * Tests that when a key attribute is mapped, that key is removed from the array.
  157. * And if only 'value' element is left in the array, it will replace its wrapper array.
  158. *
  159. * <things>
  160. * <option id="option1" value="value1">
  161. * </things>
  162. *
  163. * The above should finally be mapped to an array that looks like this
  164. * (because "id" is the key attribute).
  165. *
  166. * [
  167. * 'things' => [
  168. * 'option1' => 'value1'
  169. * ]
  170. * ]
  171. *
  172. * It's also possible to mix 'value-only' and 'non-value-only' elements in the array.
  173. *
  174. * <things>
  175. * <option id="option1" value="value1">
  176. * <option id="option2" value="value2" foo="foo2">
  177. * </things>
  178. *
  179. * The above should finally be mapped to an array as follows
  180. *
  181. * [
  182. * 'things' => [
  183. * 'option1' => 'value1',
  184. * 'option2' => [
  185. * 'value' => 'value2',
  186. * 'foo' => 'foo2'
  187. * ]
  188. * ]
  189. * ]
  190. *
  191. * The 'value' element can also be ArrayNode:
  192. *
  193. * <things>
  194. * <option id="option1">
  195. * <value>
  196. * <foo>foo1</foo>
  197. * <bar>bar1</bar>
  198. * </value>
  199. * </option>
  200. * </things>
  201. *
  202. * The above should be finally be mapped to an array as follows
  203. *
  204. * [
  205. * 'things' => [
  206. * 'option1' => [
  207. * 'foo' => 'foo1',
  208. * 'bar' => 'bar1'
  209. * ]
  210. * ]
  211. * ]
  212. *
  213. * If using VariableNode for value node, it's also possible to mix different types of value nodes:
  214. *
  215. * <things>
  216. * <option id="option1">
  217. * <value>
  218. * <foo>foo1</foo>
  219. * <bar>bar1</bar>
  220. * </value>
  221. * </option>
  222. * <option id="option2" value="value2">
  223. * </things>
  224. *
  225. * The above should be finally mapped to an array as follows
  226. *
  227. * [
  228. * 'things' => [
  229. * 'option1' => [
  230. * 'foo' => 'foo1',
  231. * 'bar' => 'bar1'
  232. * ],
  233. * 'option2' => 'value2'
  234. * ]
  235. * ]
  236. *
  237. * @dataProvider getDataForKeyRemovedLeftValueOnly
  238. */
  239. public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $expected)
  240. {
  241. $node = new PrototypedArrayNode('root');
  242. $node->setKeyAttribute('id', true);
  243. // each item under the root is an array, with one scalar item
  244. $prototype = new ArrayNode(null, $node);
  245. $prototype->addChild(new ScalarNode('id'));
  246. $prototype->addChild(new ScalarNode('foo'));
  247. $prototype->addChild($value);
  248. $node->setPrototype($prototype);
  249. $normalized = $node->normalize($children);
  250. $this->assertEquals($expected, $normalized);
  251. }
  252. public function getDataForKeyRemovedLeftValueOnly()
  253. {
  254. $scalarValue = new ScalarNode('value');
  255. $arrayValue = new ArrayNode('value');
  256. $arrayValue->addChild(new ScalarNode('foo'));
  257. $arrayValue->addChild(new ScalarNode('bar'));
  258. $variableValue = new VariableNode('value');
  259. return [
  260. [
  261. $scalarValue,
  262. [
  263. ['id' => 'option1', 'value' => 'value1'],
  264. ],
  265. ['option1' => 'value1'],
  266. ],
  267. [
  268. $scalarValue,
  269. [
  270. ['id' => 'option1', 'value' => 'value1'],
  271. ['id' => 'option2', 'value' => 'value2', 'foo' => 'foo2'],
  272. ],
  273. [
  274. 'option1' => 'value1',
  275. 'option2' => ['value' => 'value2', 'foo' => 'foo2'],
  276. ],
  277. ],
  278. [
  279. $arrayValue,
  280. [
  281. [
  282. 'id' => 'option1',
  283. 'value' => ['foo' => 'foo1', 'bar' => 'bar1'],
  284. ],
  285. ],
  286. [
  287. 'option1' => ['foo' => 'foo1', 'bar' => 'bar1'],
  288. ],
  289. ],
  290. [$variableValue,
  291. [
  292. [
  293. 'id' => 'option1', 'value' => ['foo' => 'foo1', 'bar' => 'bar1'],
  294. ],
  295. ['id' => 'option2', 'value' => 'value2'],
  296. ],
  297. [
  298. 'option1' => ['foo' => 'foo1', 'bar' => 'bar1'],
  299. 'option2' => 'value2',
  300. ],
  301. ],
  302. ];
  303. }
  304. }