PropertyAccessorCollectionTest.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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\PropertyAccess\Tests;
  11. class PropertyAccessorCollectionTest_Car
  12. {
  13. private $axes;
  14. public function __construct($axes = null)
  15. {
  16. $this->axes = $axes;
  17. }
  18. // In the test, use a name that StringUtil can't uniquely singularify
  19. public function addAxis($axis)
  20. {
  21. $this->axes[] = $axis;
  22. }
  23. public function removeAxis($axis)
  24. {
  25. foreach ($this->axes as $key => $value) {
  26. if ($value === $axis) {
  27. unset($this->axes[$key]);
  28. return;
  29. }
  30. }
  31. }
  32. public function getAxes()
  33. {
  34. return $this->axes;
  35. }
  36. }
  37. class PropertyAccessorCollectionTest_CarOnlyAdder
  38. {
  39. public function addAxis($axis)
  40. {
  41. }
  42. public function getAxes()
  43. {
  44. }
  45. }
  46. class PropertyAccessorCollectionTest_CarOnlyRemover
  47. {
  48. public function removeAxis($axis)
  49. {
  50. }
  51. public function getAxes()
  52. {
  53. }
  54. }
  55. class PropertyAccessorCollectionTest_CarNoAdderAndRemover
  56. {
  57. public function getAxes()
  58. {
  59. }
  60. }
  61. class PropertyAccessorCollectionTest_CompositeCar
  62. {
  63. public function getStructure()
  64. {
  65. }
  66. public function setStructure($structure)
  67. {
  68. }
  69. }
  70. class PropertyAccessorCollectionTest_CarStructure
  71. {
  72. public function addAxis($axis)
  73. {
  74. }
  75. public function removeAxis($axis)
  76. {
  77. }
  78. public function getAxes()
  79. {
  80. }
  81. }
  82. abstract class PropertyAccessorCollectionTest extends PropertyAccessorArrayAccessTest
  83. {
  84. public function testSetValueCallsAdderAndRemoverForCollections()
  85. {
  86. $axesBefore = $this->getContainer(array(1 => 'second', 3 => 'fourth', 4 => 'fifth'));
  87. $axesMerged = $this->getContainer(array(1 => 'first', 2 => 'second', 3 => 'third'));
  88. $axesAfter = $this->getContainer(array(1 => 'second', 5 => 'first', 6 => 'third'));
  89. $axesMergedCopy = is_object($axesMerged) ? clone $axesMerged : $axesMerged;
  90. // Don't use a mock in order to test whether the collections are
  91. // modified while iterating them
  92. $car = new PropertyAccessorCollectionTest_Car($axesBefore);
  93. $this->propertyAccessor->setValue($car, 'axes', $axesMerged);
  94. $this->assertEquals($axesAfter, $car->getAxes());
  95. // The passed collection was not modified
  96. $this->assertEquals($axesMergedCopy, $axesMerged);
  97. }
  98. public function testSetValueCallsAdderAndRemoverForNestedCollections()
  99. {
  100. $car = $this->getMock(__CLASS__.'_CompositeCar');
  101. $structure = $this->getMock(__CLASS__.'_CarStructure');
  102. $axesBefore = $this->getContainer(array(1 => 'second', 3 => 'fourth'));
  103. $axesAfter = $this->getContainer(array(0 => 'first', 1 => 'second', 2 => 'third'));
  104. $car->expects($this->any())
  105. ->method('getStructure')
  106. ->will($this->returnValue($structure));
  107. $structure->expects($this->at(0))
  108. ->method('getAxes')
  109. ->will($this->returnValue($axesBefore));
  110. $structure->expects($this->at(1))
  111. ->method('removeAxis')
  112. ->with('fourth');
  113. $structure->expects($this->at(2))
  114. ->method('addAxis')
  115. ->with('first');
  116. $structure->expects($this->at(3))
  117. ->method('addAxis')
  118. ->with('third');
  119. $this->propertyAccessor->setValue($car, 'structure.axes', $axesAfter);
  120. }
  121. /**
  122. * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException
  123. * @expectedExceptionMessage Neither the property "axes" nor one of the methods "addAx()"/"removeAx()", "addAxe()"/"removeAxe()", "addAxis()"/"removeAxis()", "setAxes()", "axes()", "__set()" or "__call()" exist and have public access in class "Mock_PropertyAccessorCollectionTest_CarNoAdderAndRemover
  124. */
  125. public function testSetValueFailsIfNoAdderNorRemoverFound()
  126. {
  127. $car = $this->getMock(__CLASS__.'_CarNoAdderAndRemover');
  128. $axesBefore = $this->getContainer(array(1 => 'second', 3 => 'fourth'));
  129. $axesAfter = $this->getContainer(array(0 => 'first', 1 => 'second', 2 => 'third'));
  130. $car->expects($this->any())
  131. ->method('getAxes')
  132. ->will($this->returnValue($axesBefore));
  133. $this->propertyAccessor->setValue($car, 'axes', $axesAfter);
  134. }
  135. public function testIsWritableReturnsTrueIfAdderAndRemoverExists()
  136. {
  137. $car = $this->getMock(__CLASS__.'_Car');
  138. $this->assertTrue($this->propertyAccessor->isWritable($car, 'axes'));
  139. }
  140. public function testIsWritableReturnsFalseIfOnlyAdderExists()
  141. {
  142. $car = $this->getMock(__CLASS__.'_CarOnlyAdder');
  143. $this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
  144. }
  145. public function testIsWritableReturnsFalseIfOnlyRemoverExists()
  146. {
  147. $car = $this->getMock(__CLASS__.'_CarOnlyRemover');
  148. $this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
  149. }
  150. public function testIsWritableReturnsFalseIfNoAdderNorRemoverExists()
  151. {
  152. $car = $this->getMock(__CLASS__.'_CarNoAdderAndRemover');
  153. $this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
  154. }
  155. /**
  156. * @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException
  157. * expectedExceptionMessageRegExp /The property "axes" in class "Mock_PropertyAccessorCollectionTest_Car[^"]*" can be defined with the methods "addAxis()", "removeAxis()" but the new value must be an array or an instance of \Traversable, "string" given./
  158. */
  159. public function testSetValueFailsIfAdderAndRemoverExistButValueIsNotTraversable()
  160. {
  161. $car = $this->getMock(__CLASS__.'_Car');
  162. $this->propertyAccessor->setValue($car, 'axes', 'Not an array or Traversable');
  163. }
  164. }