197 lines
5.8 KiB
PHP
Executable File
197 lines
5.8 KiB
PHP
Executable File
<?php
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Symfony\Component\PropertyAccess\Tests;
|
|
|
|
class PropertyAccessorCollectionTest_Car
|
|
{
|
|
private $axes;
|
|
|
|
public function __construct($axes = null)
|
|
{
|
|
$this->axes = $axes;
|
|
}
|
|
|
|
// In the test, use a name that StringUtil can't uniquely singularify
|
|
public function addAxis($axis)
|
|
{
|
|
$this->axes[] = $axis;
|
|
}
|
|
|
|
public function removeAxis($axis)
|
|
{
|
|
foreach ($this->axes as $key => $value) {
|
|
if ($value === $axis) {
|
|
unset($this->axes[$key]);
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function getAxes()
|
|
{
|
|
return $this->axes;
|
|
}
|
|
}
|
|
|
|
class PropertyAccessorCollectionTest_CarOnlyAdder
|
|
{
|
|
public function addAxis($axis)
|
|
{
|
|
}
|
|
|
|
public function getAxes()
|
|
{
|
|
}
|
|
}
|
|
|
|
class PropertyAccessorCollectionTest_CarOnlyRemover
|
|
{
|
|
public function removeAxis($axis)
|
|
{
|
|
}
|
|
|
|
public function getAxes()
|
|
{
|
|
}
|
|
}
|
|
|
|
class PropertyAccessorCollectionTest_CarNoAdderAndRemover
|
|
{
|
|
public function getAxes()
|
|
{
|
|
}
|
|
}
|
|
|
|
class PropertyAccessorCollectionTest_CompositeCar
|
|
{
|
|
public function getStructure()
|
|
{
|
|
}
|
|
|
|
public function setStructure($structure)
|
|
{
|
|
}
|
|
}
|
|
|
|
class PropertyAccessorCollectionTest_CarStructure
|
|
{
|
|
public function addAxis($axis)
|
|
{
|
|
}
|
|
|
|
public function removeAxis($axis)
|
|
{
|
|
}
|
|
|
|
public function getAxes()
|
|
{
|
|
}
|
|
}
|
|
|
|
abstract class PropertyAccessorCollectionTest extends PropertyAccessorArrayAccessTest
|
|
{
|
|
public function testSetValueCallsAdderAndRemoverForCollections()
|
|
{
|
|
$axesBefore = $this->getContainer([1 => 'second', 3 => 'fourth', 4 => 'fifth']);
|
|
$axesMerged = $this->getContainer([1 => 'first', 2 => 'second', 3 => 'third']);
|
|
$axesAfter = $this->getContainer([1 => 'second', 5 => 'first', 6 => 'third']);
|
|
$axesMergedCopy = \is_object($axesMerged) ? clone $axesMerged : $axesMerged;
|
|
|
|
// Don't use a mock in order to test whether the collections are
|
|
// modified while iterating them
|
|
$car = new PropertyAccessorCollectionTest_Car($axesBefore);
|
|
|
|
$this->propertyAccessor->setValue($car, 'axes', $axesMerged);
|
|
|
|
$this->assertEquals($axesAfter, $car->getAxes());
|
|
|
|
// The passed collection was not modified
|
|
$this->assertEquals($axesMergedCopy, $axesMerged);
|
|
}
|
|
|
|
public function testSetValueCallsAdderAndRemoverForNestedCollections()
|
|
{
|
|
$car = $this->getMockBuilder(__CLASS__.'_CompositeCar')->getMock();
|
|
$structure = $this->getMockBuilder(__CLASS__.'_CarStructure')->getMock();
|
|
$axesBefore = $this->getContainer([1 => 'second', 3 => 'fourth']);
|
|
$axesAfter = $this->getContainer([0 => 'first', 1 => 'second', 2 => 'third']);
|
|
|
|
$car->expects($this->any())
|
|
->method('getStructure')
|
|
->willReturn($structure);
|
|
|
|
$structure->expects($this->at(0))
|
|
->method('getAxes')
|
|
->willReturn($axesBefore);
|
|
$structure->expects($this->at(1))
|
|
->method('removeAxis')
|
|
->with('fourth');
|
|
$structure->expects($this->at(2))
|
|
->method('addAxis')
|
|
->with('first');
|
|
$structure->expects($this->at(3))
|
|
->method('addAxis')
|
|
->with('third');
|
|
|
|
$this->propertyAccessor->setValue($car, 'structure.axes', $axesAfter);
|
|
}
|
|
|
|
public function testSetValueFailsIfNoAdderNorRemoverFound()
|
|
{
|
|
$this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException');
|
|
$this->expectExceptionMessageRegExp('/Could not determine access type for property "axes" in class "Mock_PropertyAccessorCollectionTest_CarNoAdderAndRemover_[^"]*"./');
|
|
$car = $this->getMockBuilder(__CLASS__.'_CarNoAdderAndRemover')->getMock();
|
|
$axesBefore = $this->getContainer([1 => 'second', 3 => 'fourth']);
|
|
$axesAfter = $this->getContainer([0 => 'first', 1 => 'second', 2 => 'third']);
|
|
|
|
$car->expects($this->any())
|
|
->method('getAxes')
|
|
->willReturn($axesBefore);
|
|
|
|
$this->propertyAccessor->setValue($car, 'axes', $axesAfter);
|
|
}
|
|
|
|
public function testIsWritableReturnsTrueIfAdderAndRemoverExists()
|
|
{
|
|
$car = new PropertyAccessorCollectionTest_Car();
|
|
$this->assertTrue($this->propertyAccessor->isWritable($car, 'axes'));
|
|
}
|
|
|
|
public function testIsWritableReturnsFalseIfOnlyAdderExists()
|
|
{
|
|
$car = new PropertyAccessorCollectionTest_CarOnlyAdder();
|
|
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
|
}
|
|
|
|
public function testIsWritableReturnsFalseIfOnlyRemoverExists()
|
|
{
|
|
$car = new PropertyAccessorCollectionTest_CarOnlyRemover();
|
|
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
|
}
|
|
|
|
public function testIsWritableReturnsFalseIfNoAdderNorRemoverExists()
|
|
{
|
|
$car = new PropertyAccessorCollectionTest_CarNoAdderAndRemover();
|
|
$this->assertFalse($this->propertyAccessor->isWritable($car, 'axes'));
|
|
}
|
|
|
|
public function testSetValueFailsIfAdderAndRemoverExistButValueIsNotTraversable()
|
|
{
|
|
$this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException');
|
|
$this->expectExceptionMessage('The property "axes" in class "Symfony\Component\PropertyAccess\Tests\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.');
|
|
$car = new PropertyAccessorCollectionTest_Car();
|
|
|
|
$this->propertyAccessor->setValue($car, 'axes', 'Not an array or Traversable');
|
|
}
|
|
}
|