ArrayNodeTest.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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\Exception\InvalidConfigurationException;
  14. use Symfony\Component\Config\Definition\ScalarNode;
  15. class ArrayNodeTest extends TestCase
  16. {
  17. /**
  18. * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidTypeException
  19. */
  20. public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed()
  21. {
  22. $node = new ArrayNode('root');
  23. $node->normalize(false);
  24. }
  25. /**
  26. * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
  27. * @expectedExceptionMessage Unrecognized option "foo" under "root"
  28. */
  29. public function testExceptionThrownOnUnrecognizedChild()
  30. {
  31. $node = new ArrayNode('root');
  32. $node->normalize(array('foo' => 'bar'));
  33. }
  34. public function ignoreAndRemoveMatrixProvider()
  35. {
  36. $unrecognizedOptionException = new InvalidConfigurationException('Unrecognized option "foo" under "root"');
  37. return array(
  38. array(true, true, array(), 'no exception is thrown for an unrecognized child if the ignoreExtraKeys option is set to true'),
  39. array(true, false, array('foo' => 'bar'), 'extra keys are not removed when ignoreExtraKeys second option is set to false'),
  40. array(false, true, $unrecognizedOptionException),
  41. array(false, false, $unrecognizedOptionException),
  42. );
  43. }
  44. /**
  45. * @dataProvider ignoreAndRemoveMatrixProvider
  46. */
  47. public function testIgnoreAndRemoveBehaviors($ignore, $remove, $expected, $message = '')
  48. {
  49. if ($expected instanceof \Exception) {
  50. if (method_exists($this, 'expectException')) {
  51. $this->expectException(\get_class($expected));
  52. $this->expectExceptionMessage($expected->getMessage());
  53. } else {
  54. $this->setExpectedException(\get_class($expected), $expected->getMessage());
  55. }
  56. }
  57. $node = new ArrayNode('root');
  58. $node->setIgnoreExtraKeys($ignore, $remove);
  59. $result = $node->normalize(array('foo' => 'bar'));
  60. $this->assertSame($expected, $result, $message);
  61. }
  62. /**
  63. * @dataProvider getPreNormalizationTests
  64. */
  65. public function testPreNormalize($denormalized, $normalized)
  66. {
  67. $node = new ArrayNode('foo');
  68. $r = new \ReflectionMethod($node, 'preNormalize');
  69. $r->setAccessible(true);
  70. $this->assertSame($normalized, $r->invoke($node, $denormalized));
  71. }
  72. public function getPreNormalizationTests()
  73. {
  74. return array(
  75. array(
  76. array('foo-bar' => 'foo'),
  77. array('foo_bar' => 'foo'),
  78. ),
  79. array(
  80. array('foo-bar_moo' => 'foo'),
  81. array('foo-bar_moo' => 'foo'),
  82. ),
  83. array(
  84. array('anything-with-dash-and-no-underscore' => 'first', 'no_dash' => 'second'),
  85. array('anything_with_dash_and_no_underscore' => 'first', 'no_dash' => 'second'),
  86. ),
  87. array(
  88. array('foo-bar' => null, 'foo_bar' => 'foo'),
  89. array('foo-bar' => null, 'foo_bar' => 'foo'),
  90. ),
  91. );
  92. }
  93. /**
  94. * @dataProvider getZeroNamedNodeExamplesData
  95. */
  96. public function testNodeNameCanBeZero($denormalized, $normalized)
  97. {
  98. $zeroNode = new ArrayNode(0);
  99. $zeroNode->addChild(new ScalarNode('name'));
  100. $fiveNode = new ArrayNode(5);
  101. $fiveNode->addChild(new ScalarNode(0));
  102. $fiveNode->addChild(new ScalarNode('new_key'));
  103. $rootNode = new ArrayNode('root');
  104. $rootNode->addChild($zeroNode);
  105. $rootNode->addChild($fiveNode);
  106. $rootNode->addChild(new ScalarNode('string_key'));
  107. $r = new \ReflectionMethod($rootNode, 'normalizeValue');
  108. $r->setAccessible(true);
  109. $this->assertSame($normalized, $r->invoke($rootNode, $denormalized));
  110. }
  111. public function getZeroNamedNodeExamplesData()
  112. {
  113. return array(
  114. array(
  115. array(
  116. 0 => array(
  117. 'name' => 'something',
  118. ),
  119. 5 => array(
  120. 0 => 'this won\'t work too',
  121. 'new_key' => 'some other value',
  122. ),
  123. 'string_key' => 'just value',
  124. ),
  125. array(
  126. 0 => array(
  127. 'name' => 'something',
  128. ),
  129. 5 => array(
  130. 0 => 'this won\'t work too',
  131. 'new_key' => 'some other value',
  132. ),
  133. 'string_key' => 'just value',
  134. ),
  135. ),
  136. );
  137. }
  138. /**
  139. * @dataProvider getPreNormalizedNormalizedOrderedData
  140. */
  141. public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized)
  142. {
  143. $scalar1 = new ScalarNode('1');
  144. $scalar2 = new ScalarNode('2');
  145. $scalar3 = new ScalarNode('3');
  146. $node = new ArrayNode('foo');
  147. $node->addChild($scalar1);
  148. $node->addChild($scalar3);
  149. $node->addChild($scalar2);
  150. $r = new \ReflectionMethod($node, 'normalizeValue');
  151. $r->setAccessible(true);
  152. $this->assertSame($normalized, $r->invoke($node, $prenormalized));
  153. }
  154. public function getPreNormalizedNormalizedOrderedData()
  155. {
  156. return array(
  157. array(
  158. array('2' => 'two', '1' => 'one', '3' => 'three'),
  159. array('2' => 'two', '1' => 'one', '3' => 'three'),
  160. ),
  161. );
  162. }
  163. /**
  164. * @expectedException \InvalidArgumentException
  165. * @expectedExceptionMessage Child nodes must be named.
  166. */
  167. public function testAddChildEmptyName()
  168. {
  169. $node = new ArrayNode('root');
  170. $childNode = new ArrayNode('');
  171. $node->addChild($childNode);
  172. }
  173. /**
  174. * @expectedException \InvalidArgumentException
  175. * @expectedExceptionMessage A child node named "foo" already exists.
  176. */
  177. public function testAddChildNameAlreadyExists()
  178. {
  179. $node = new ArrayNode('root');
  180. $childNode = new ArrayNode('foo');
  181. $node->addChild($childNode);
  182. $childNodeWithSameName = new ArrayNode('foo');
  183. $node->addChild($childNodeWithSameName);
  184. }
  185. /**
  186. * @expectedException \RuntimeException
  187. * @expectedExceptionMessage The node at path "foo" has no default value.
  188. */
  189. public function testGetDefaultValueWithoutDefaultValue()
  190. {
  191. $node = new ArrayNode('foo');
  192. $node->getDefaultValue();
  193. }
  194. }