From 4f5b44bd3bd490309eb2ba7b44df4769816ba729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Sat, 3 Aug 2013 19:26:54 +0200 Subject: twig implementation --- .../Extension/Core/ChoiceList/ChoiceListTest.php | 200 +++ .../Core/ChoiceList/LazyChoiceListTest.php | 116 ++ .../Core/ChoiceList/ObjectChoiceListTest.php | 212 +++ .../Core/ChoiceList/SimpleChoiceListTest.php | 188 +++ .../Core/DataMapper/PropertyPathMapperTest.php | 319 +++++ .../ArrayToPartsTransformerTest.php | 149 ++ .../BooleanToStringTransformerTest.php | 60 + .../ChoiceToValueTransformerTest.php | 76 + .../ChoicesToValuesTransformerTest.php | 76 + .../DataTransformer/DataTransformerChainTest.php | 53 + .../Core/DataTransformer/DateTimeTestCase.php | 20 + .../DateTimeToArrayTransformerTest.php | 512 +++++++ .../DateTimeToLocalizedStringTransformerTest.php | 275 ++++ .../DateTimeToRfc3339TransformerTest.php | 132 ++ .../DateTimeToStringTransformerTest.php | 181 +++ .../DateTimeToTimestampTransformerTest.php | 104 ++ .../IntegerToLocalizedStringTransformerTest.php | 115 ++ .../MoneyToLocalizedStringTransformerTest.php | 74 + .../NumberToLocalizedStringTransformerTest.php | 393 ++++++ .../PercentToLocalizedStringTransformerTest.php | 114 ++ .../ValueToDuplicatesTransformerTest.php | 120 ++ .../EventListener/FixRadioInputListenerTest.php | 106 ++ .../EventListener/FixUrlProtocolListenerTest.php | 61 + .../Core/EventListener/Fixtures/randomhash | Bin 0 -> 35 bytes .../MergeCollectionListenerArrayObjectTest.php | 27 + .../MergeCollectionListenerArrayTest.php | 27 + ...ergeCollectionListenerCustomArrayObjectTest.php | 28 + .../EventListener/MergeCollectionListenerTest.php | 259 ++++ .../Core/EventListener/ResizeFormListenerTest.php | 255 ++++ .../Core/EventListener/TrimListenerTest.php | 79 ++ .../Tests/Extension/Core/Type/BaseTypeTest.php | 135 ++ .../Tests/Extension/Core/Type/ButtonTypeTest.php | 28 + .../Tests/Extension/Core/Type/CheckboxTypeTest.php | 162 +++ .../Core/Type/ChoiceTypePerformanceTest.php | 38 + .../Tests/Extension/Core/Type/ChoiceTypeTest.php | 949 +++++++++++++ .../Extension/Core/Type/CollectionTypeTest.php | 200 +++ .../Tests/Extension/Core/Type/CountryTypeTest.php | 52 + .../Tests/Extension/Core/Type/CurrencyTypeTest.php | 37 + .../Tests/Extension/Core/Type/DateTimeTypeTest.php | 477 +++++++ .../Tests/Extension/Core/Type/DateTypeTest.php | 781 +++++++++++ .../Tests/Extension/Core/Type/FileTypeTest.php | 83 ++ .../Tests/Extension/Core/Type/FormTypeTest.php | 578 ++++++++ .../Tests/Extension/Core/Type/IntegerTypeTest.php | 34 + .../Tests/Extension/Core/Type/LanguageTypeTest.php | 47 + .../Tests/Extension/Core/Type/LocaleTypeTest.php | 36 + .../Tests/Extension/Core/Type/MoneyTypeTest.php | 59 + .../Tests/Extension/Core/Type/NumberTypeTest.php | 63 + .../Tests/Extension/Core/Type/PasswordTypeTest.php | 51 + .../Tests/Extension/Core/Type/RepeatedTypeTest.php | 149 ++ .../Tests/Extension/Core/Type/SubmitTypeTest.php | 54 + .../Tests/Extension/Core/Type/TimeTypeTest.php | 649 +++++++++ .../Tests/Extension/Core/Type/TimezoneTypeTest.php | 30 + .../Tests/Extension/Core/Type/TypeTestCase.php | 21 + .../Form/Tests/Extension/Core/Type/UrlTypeTest.php | 61 + .../Csrf/CsrfProvider/DefaultCsrfProviderTest.php | 81 ++ .../Csrf/CsrfProvider/SessionCsrfProviderTest.php | 75 + .../EventListener/CsrfValidationListenerTest.php | 78 ++ .../Csrf/Type/FormTypeCsrfExtensionTest.php | 301 ++++ .../EventListener/BindRequestListenerTest.php | 286 ++++ .../HttpFoundationRequestHandlerTest.php | 54 + .../Validator/Constraints/FormValidatorTest.php | 748 ++++++++++ .../EventListener/ValidationListenerTest.php | 145 ++ .../Type/FormTypeValidatorExtensionTest.php | 85 ++ .../Extension/Validator/Type/TypeTestCase.php | 49 + .../Extension/Validator/Util/ServerParamsTest.php | 46 + .../ViolationMapper/ViolationMapperTest.php | 1481 ++++++++++++++++++++ .../ViolationMapper/ViolationPathTest.php | 245 ++++ 67 files changed, 12779 insertions(+) create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ChoiceListTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/LazyChoiceListTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleChoiceListTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ArrayToPartsTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoicesToValuesTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DataTransformerChainTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ValueToDuplicatesTransformerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/Fixtures/randomhash create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayObjectTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerCustomArrayObjectTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/BaseTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ButtonTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/PasswordTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/SubmitTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TimezoneTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TypeTestCase.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/DefaultCsrfProviderTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/SessionCsrfProviderTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/HttpFoundation/EventListener/BindRequestListenerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Type/TypeTestCase.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Util/ServerParamsTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php create mode 100644 vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationPathTest.php (limited to 'vendor/symfony/form/Symfony/Component/Form/Tests/Extension') diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ChoiceListTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ChoiceListTest.php new file mode 100644 index 00000000..63eae9bf --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ChoiceListTest.php @@ -0,0 +1,200 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\ChoiceList; + +use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; + +class ChoiceListTest extends \PHPUnit_Framework_TestCase +{ + private $obj1; + + private $obj2; + + private $obj3; + + private $obj4; + + private $list; + + protected function setUp() + { + parent::setUp(); + + $this->obj1 = new \stdClass(); + $this->obj2 = new \stdClass(); + $this->obj3 = new \stdClass(); + $this->obj4 = new \stdClass(); + + $this->list = new ChoiceList( + array( + 'Group 1' => array($this->obj1, $this->obj2), + 'Group 2' => array($this->obj3, $this->obj4), + ), + array( + 'Group 1' => array('A', 'B'), + 'Group 2' => array('C', 'D'), + ), + array($this->obj2, $this->obj3) + ); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->obj1 = null; + $this->obj2 = null; + $this->obj3 = null; + $this->obj4 = null; + $this->list = null; + } + + public function testInitArray() + { + $this->list = new ChoiceList( + array($this->obj1, $this->obj2, $this->obj3, $this->obj4), + array('A', 'B', 'C', 'D'), + array($this->obj2) + ); + + $this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices()); + $this->assertSame(array('0', '1', '2', '3'), $this->list->getValues()); + $this->assertEquals(array(1 => new ChoiceView($this->obj2, '1', 'B')), $this->list->getPreferredViews()); + $this->assertEquals(array(0 => new ChoiceView($this->obj1, '0', 'A'), 2 => new ChoiceView($this->obj3, '2', 'C'), 3 => new ChoiceView($this->obj4, '3', 'D')), $this->list->getRemainingViews()); + } + + /** + * Necessary for interoperability with MongoDB cursors or ORM relations as + * choices parameter. A choice itself that is an object implementing \Traversable + * is not treated as hierarchical structure, but as-is. + */ + public function testInitNestedTraversable() + { + $traversableChoice = new \ArrayIterator(array($this->obj3, $this->obj4)); + + $this->list = new ChoiceList( + new \ArrayIterator(array( + 'Group' => array($this->obj1, $this->obj2), + 'Not a Group' => $traversableChoice + )), + array( + 'Group' => array('A', 'B'), + 'Not a Group' => 'C', + ), + array($this->obj2) + ); + + $this->assertSame(array($this->obj1, $this->obj2, $traversableChoice), $this->list->getChoices()); + $this->assertSame(array('0', '1', '2'), $this->list->getValues()); + $this->assertEquals(array( + 'Group' => array(1 => new ChoiceView($this->obj2, '1', 'B')) + ), $this->list->getPreferredViews()); + $this->assertEquals(array( + 'Group' => array(0 => new ChoiceView($this->obj1, '0', 'A')), + 2 => new ChoiceView($traversableChoice, '2', 'C') + ), $this->list->getRemainingViews()); + } + + public function testInitNestedArray() + { + $this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices()); + $this->assertSame(array('0', '1', '2', '3'), $this->list->getValues()); + $this->assertEquals(array( + 'Group 1' => array(1 => new ChoiceView($this->obj2, '1', 'B')), + 'Group 2' => array(2 => new ChoiceView($this->obj3, '2', 'C')) + ), $this->list->getPreferredViews()); + $this->assertEquals(array( + 'Group 1' => array(0 => new ChoiceView($this->obj1, '0', 'A')), + 'Group 2' => array(3 => new ChoiceView($this->obj4, '3', 'D')) + ), $this->list->getRemainingViews()); + } + + public function testGetIndicesForChoices() + { + $choices = array($this->obj2, $this->obj3); + $this->assertSame(array(1, 2), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForChoicesIgnoresNonExistingChoices() + { + $choices = array($this->obj2, $this->obj3, 'foobar'); + $this->assertSame(array(1, 2), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForValues() + { + // values and indices are always the same + $values = array('1', '2'); + $this->assertSame(array(1, 2), $this->list->getIndicesForValues($values)); + } + + public function testGetIndicesForValuesIgnoresNonExistingValues() + { + $values = array('1', '2', '5'); + $this->assertSame(array(1, 2), $this->list->getIndicesForValues($values)); + } + + public function testGetChoicesForValues() + { + $values = array('1', '2'); + $this->assertSame(array($this->obj2, $this->obj3), $this->list->getChoicesForValues($values)); + } + + public function testGetChoicesForValuesCorrectOrderingOfResult() + { + $values = array('2', '1'); + $this->assertSame(array($this->obj3, $this->obj2), $this->list->getChoicesForValues($values)); + } + + public function testGetChoicesForValuesIgnoresNonExistingValues() + { + $values = array('1', '2', '5'); + $this->assertSame(array($this->obj2, $this->obj3), $this->list->getChoicesForValues($values)); + } + + public function testGetValuesForChoices() + { + $choices = array($this->obj2, $this->obj3); + $this->assertSame(array('1', '2'), $this->list->getValuesForChoices($choices)); + } + + public function testGetValuesForChoicesIgnoresNonExistingChoices() + { + $choices = array($this->obj2, $this->obj3, 'foobar'); + $this->assertSame(array('1', '2'), $this->list->getValuesForChoices($choices)); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testNonMatchingLabels() + { + $this->list = new ChoiceList( + array($this->obj1, $this->obj2), + array('A') + ); + } + + public function testLabelsContainingNull() + { + $this->list = new ChoiceList( + array($this->obj1, $this->obj2), + array('A', null) + ); + + $this->assertEquals( + array(0 => new ChoiceView($this->obj1, '0', 'A'), 1 => new ChoiceView($this->obj2, '1', null)), + $this->list->getRemainingViews() + ); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/LazyChoiceListTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/LazyChoiceListTest.php new file mode 100644 index 00000000..bcd309e0 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/LazyChoiceListTest.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\ChoiceList; + +use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; +use Symfony\Component\Form\Extension\Core\ChoiceList\LazyChoiceList; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; + +class LazyChoiceListTest extends \PHPUnit_Framework_TestCase +{ + private $list; + + protected function setUp() + { + parent::setUp(); + + $this->list = new LazyChoiceListTest_Impl(new SimpleChoiceList(array( + 'a' => 'A', + 'b' => 'B', + 'c' => 'C', + ), array('b'))); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->list = null; + } + + public function testGetChoices() + { + $this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c'), $this->list->getChoices()); + } + + public function testGetValues() + { + $this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c'), $this->list->getValues()); + } + + public function testGetPreferredViews() + { + $this->assertEquals(array(1 => new ChoiceView('b', 'b', 'B')), $this->list->getPreferredViews()); + } + + public function testGetRemainingViews() + { + $this->assertEquals(array(0 => new ChoiceView('a', 'a', 'A'), 2 => new ChoiceView('c', 'c', 'C')), $this->list->getRemainingViews()); + } + + public function testGetIndicesForChoices() + { + $choices = array('b', 'c'); + $this->assertSame(array(1, 2), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForValues() + { + $values = array('b', 'c'); + $this->assertSame(array(1, 2), $this->list->getIndicesForValues($values)); + } + + public function testGetChoicesForValues() + { + $values = array('b', 'c'); + $this->assertSame(array('b', 'c'), $this->list->getChoicesForValues($values)); + } + + public function testGetValuesForChoices() + { + $choices = array('b', 'c'); + $this->assertSame(array('b', 'c'), $this->list->getValuesForChoices($choices)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException + */ + public function testLoadChoiceListShouldReturnChoiceList() + { + $list = new LazyChoiceListTest_InvalidImpl(); + + $list->getChoices(); + } +} + +class LazyChoiceListTest_Impl extends LazyChoiceList +{ + private $choiceList; + + public function __construct($choiceList) + { + $this->choiceList = $choiceList; + } + + protected function loadChoiceList() + { + return $this->choiceList; + } +} + +class LazyChoiceListTest_InvalidImpl extends LazyChoiceList +{ + protected function loadChoiceList() + { + return new \stdClass(); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php new file mode 100644 index 00000000..69c5aa0f --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/ObjectChoiceListTest.php @@ -0,0 +1,212 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\ChoiceList; + +use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; + +class ObjectChoiceListTest_EntityWithToString +{ + private $property; + + public function __construct($property) + { + $this->property = $property; + } + + public function __toString() + { + return $this->property; + } +} + +class ObjectChoiceListTest extends \PHPUnit_Framework_TestCase +{ + private $obj1; + + private $obj2; + + private $obj3; + + private $obj4; + + /** + * @var ObjectChoiceList + */ + private $list; + + protected function setUp() + { + parent::setUp(); + + $this->obj1 = (object) array('name' => 'A'); + $this->obj2 = (object) array('name' => 'B'); + $this->obj3 = (object) array('name' => 'C'); + $this->obj4 = (object) array('name' => 'D'); + + $this->list = new ObjectChoiceList( + array( + 'Group 1' => array($this->obj1, $this->obj2), + 'Group 2' => array($this->obj3, $this->obj4), + ), + 'name', + array($this->obj2, $this->obj3) + ); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->obj1 = null; + $this->obj2 = null; + $this->obj3 = null; + $this->obj4 = null; + $this->list = null; + } + + public function testInitArray() + { + $this->list = new ObjectChoiceList( + array($this->obj1, $this->obj2, $this->obj3, $this->obj4), + 'name', + array($this->obj2) + ); + + $this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices()); + $this->assertSame(array('0', '1', '2', '3'), $this->list->getValues()); + $this->assertEquals(array(1 => new ChoiceView($this->obj2, '1', 'B')), $this->list->getPreferredViews()); + $this->assertEquals(array(0 => new ChoiceView($this->obj1, '0', 'A'), 2 => new ChoiceView($this->obj3, '2', 'C'), 3 => new ChoiceView($this->obj4, '3', 'D')), $this->list->getRemainingViews()); + } + + public function testInitNestedArray() + { + $this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices()); + $this->assertSame(array('0', '1', '2', '3'), $this->list->getValues()); + $this->assertEquals(array( + 'Group 1' => array(1 => new ChoiceView($this->obj2, '1', 'B')), + 'Group 2' => array(2 => new ChoiceView($this->obj3, '2', 'C')) + ), $this->list->getPreferredViews()); + $this->assertEquals(array( + 'Group 1' => array(0 => new ChoiceView($this->obj1, '0', 'A')), + 'Group 2' => array(3 => new ChoiceView($this->obj4, '3', 'D')) + ), $this->list->getRemainingViews()); + } + + public function testInitArrayWithGroupPath() + { + $this->obj1 = (object) array('name' => 'A', 'category' => 'Group 1'); + $this->obj2 = (object) array('name' => 'B', 'category' => 'Group 1'); + $this->obj3 = (object) array('name' => 'C', 'category' => 'Group 2'); + $this->obj4 = (object) array('name' => 'D', 'category' => 'Group 2'); + + // Objects with NULL groups are not grouped + $obj5 = (object) array('name' => 'E', 'category' => null); + + // Objects without the group property are not grouped either + // see https://github.com/symfony/symfony/commit/d9b7abb7c7a0f28e0ce970afc5e305dce5dccddf + $obj6 = (object) array('name' => 'F'); + + $this->list = new ObjectChoiceList( + array($this->obj1, $this->obj2, $this->obj3, $this->obj4, $obj5, $obj6), + 'name', + array($this->obj2, $this->obj3), + 'category' + ); + + $this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4, $obj5, $obj6), $this->list->getChoices()); + $this->assertSame(array('0', '1', '2', '3', '4', '5'), $this->list->getValues()); + $this->assertEquals(array( + 'Group 1' => array(1 => new ChoiceView($this->obj2, '1', 'B')), + 'Group 2' => array(2 => new ChoiceView($this->obj3, '2', 'C')) + ), $this->list->getPreferredViews()); + $this->assertEquals(array( + 'Group 1' => array(0 => new ChoiceView($this->obj1, '0', 'A')), + 'Group 2' => array(3 => new ChoiceView($this->obj4, '3', 'D')), + 4 => new ChoiceView($obj5, '4', 'E'), + 5 => new ChoiceView($obj6, '5', 'F'), + ), $this->list->getRemainingViews()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testInitArrayWithGroupPathThrowsExceptionIfNestedArray() + { + $this->obj1 = (object) array('name' => 'A', 'category' => 'Group 1'); + $this->obj2 = (object) array('name' => 'B', 'category' => 'Group 1'); + $this->obj3 = (object) array('name' => 'C', 'category' => 'Group 2'); + $this->obj4 = (object) array('name' => 'D', 'category' => 'Group 2'); + + new ObjectChoiceList( + array( + 'Group 1' => array($this->obj1, $this->obj2), + 'Group 2' => array($this->obj3, $this->obj4), + ), + 'name', + array($this->obj2, $this->obj3), + 'category' + ); + } + + public function testInitArrayWithValuePath() + { + $this->obj1 = (object) array('name' => 'A', 'id' => 10); + $this->obj2 = (object) array('name' => 'B', 'id' => 20); + $this->obj3 = (object) array('name' => 'C', 'id' => 30); + $this->obj4 = (object) array('name' => 'D', 'id' => 40); + + $this->list = new ObjectChoiceList( + array($this->obj1, $this->obj2, $this->obj3, $this->obj4), + 'name', + array($this->obj2, $this->obj3), + null, + 'id' + ); + + $this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices()); + $this->assertSame(array('10', '20', '30', '40'), $this->list->getValues()); + $this->assertEquals(array(1 => new ChoiceView($this->obj2, '20', 'B'), 2 => new ChoiceView($this->obj3, '30', 'C')), $this->list->getPreferredViews()); + $this->assertEquals(array(0 => new ChoiceView($this->obj1, '10', 'A'), 3 => new ChoiceView($this->obj4, '40', 'D')), $this->list->getRemainingViews()); + } + + public function testInitArrayUsesToString() + { + $this->obj1 = new ObjectChoiceListTest_EntityWithToString('A'); + $this->obj2 = new ObjectChoiceListTest_EntityWithToString('B'); + $this->obj3 = new ObjectChoiceListTest_EntityWithToString('C'); + $this->obj4 = new ObjectChoiceListTest_EntityWithToString('D'); + + $this->list = new ObjectChoiceList( + array($this->obj1, $this->obj2, $this->obj3, $this->obj4) + ); + + $this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices()); + $this->assertSame(array('0', '1', '2', '3'), $this->list->getValues()); + $this->assertEquals(array(0 => new ChoiceView($this->obj1, '0', 'A'), 1 => new ChoiceView($this->obj2, '1', 'B'), 2 => new ChoiceView($this->obj3, '2', 'C'), 3 => new ChoiceView($this->obj4, '3', 'D')), $this->list->getRemainingViews()); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\StringCastException + */ + public function testInitArrayThrowsExceptionIfToStringNotFound() + { + $this->obj1 = new ObjectChoiceListTest_EntityWithToString('A'); + $this->obj2 = new ObjectChoiceListTest_EntityWithToString('B'); + $this->obj3 = (object) array('name' => 'C'); + $this->obj4 = new ObjectChoiceListTest_EntityWithToString('D'); + + new ObjectChoiceList( + array($this->obj1, $this->obj2, $this->obj3, $this->obj4) + ); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleChoiceListTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleChoiceListTest.php new file mode 100644 index 00000000..69d27a18 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/ChoiceList/SimpleChoiceListTest.php @@ -0,0 +1,188 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\ChoiceList; + +use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; +use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; + +class SimpleChoiceListTest extends \PHPUnit_Framework_TestCase +{ + private $list; + + private $numericList; + + protected function setUp() + { + parent::setUp(); + + $choices = array( + 'Group 1' => array('a' => 'A', 'b' => 'B'), + 'Group 2' => array('c' => 'C', 'd' => 'D'), + ); + $numericChoices = array( + 'Group 1' => array(0 => 'A', 1 => 'B'), + 'Group 2' => array(2 => 'C', 3 => 'D'), + ); + + $this->list = new SimpleChoiceList($choices, array('b', 'c')); + + // Use COPY_CHOICE strategy to test for the various associated problems + $this->numericList = new SimpleChoiceList($numericChoices, array(1, 2)); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->list = null; + $this->numericList = null; + } + + public function testInitArray() + { + $choices = array('a' => 'A', 'b' => 'B', 'c' => 'C'); + $this->list = new SimpleChoiceList($choices, array('b')); + + $this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c'), $this->list->getChoices()); + $this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c'), $this->list->getValues()); + $this->assertEquals(array(1 => new ChoiceView('b', 'b', 'B')), $this->list->getPreferredViews()); + $this->assertEquals(array(0 => new ChoiceView('a', 'a', 'A'), 2 => new ChoiceView('c', 'c', 'C')), $this->list->getRemainingViews()); + } + + public function testInitNestedArray() + { + $this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd'), $this->list->getChoices()); + $this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd'), $this->list->getValues()); + $this->assertEquals(array( + 'Group 1' => array(1 => new ChoiceView('b', 'b', 'B')), + 'Group 2' => array(2 => new ChoiceView('c', 'c', 'C')) + ), $this->list->getPreferredViews()); + $this->assertEquals(array( + 'Group 1' => array(0 => new ChoiceView('a', 'a', 'A')), + 'Group 2' => array(3 => new ChoiceView('d', 'd', 'D')) + ), $this->list->getRemainingViews()); + } + + public function testGetIndicesForChoices() + { + $choices = array('b', 'c'); + $this->assertSame(array(1, 2), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForChoicesIgnoresNonExistingChoices() + { + $choices = array('b', 'c', 'foobar'); + $this->assertSame(array(1, 2), $this->list->getIndicesForChoices($choices)); + } + + public function testGetIndicesForChoicesDealsWithNumericChoices() + { + // Pass choices as strings although they are integers + $choices = array('0', '1'); + $this->assertSame(array(0, 1), $this->numericList->getIndicesForChoices($choices)); + } + + public function testGetIndicesForValues() + { + $values = array('b', 'c'); + $this->assertSame(array(1, 2), $this->list->getIndicesForValues($values)); + } + + public function testGetIndicesForValuesIgnoresNonExistingValues() + { + $values = array('b', 'c', '100'); + $this->assertSame(array(1, 2), $this->list->getIndicesForValues($values)); + } + + public function testGetIndicesForValuesDealsWithNumericValues() + { + // Pass values as strings although they are integers + $values = array('0', '1'); + $this->assertSame(array(0, 1), $this->numericList->getIndicesForValues($values)); + } + + public function testGetChoicesForValues() + { + $values = array('b', 'c'); + $this->assertSame(array('b', 'c'), $this->list->getChoicesForValues($values)); + } + + public function testGetChoicesForValuesIgnoresNonExistingValues() + { + $values = array('b', 'c', '100'); + $this->assertSame(array('b', 'c'), $this->list->getChoicesForValues($values)); + } + + public function testGetChoicesForValuesDealsWithNumericValues() + { + // Pass values as strings although they are integers + $values = array('0', '1'); + $this->assertSame(array(0, 1), $this->numericList->getChoicesForValues($values)); + } + + public function testGetValuesForChoices() + { + $choices = array('b', 'c'); + $this->assertSame(array('b', 'c'), $this->list->getValuesForChoices($choices)); + } + + public function testGetValuesForChoicesIgnoresNonExistingValues() + { + $choices = array('b', 'c', 'foobar'); + $this->assertSame(array('b', 'c'), $this->list->getValuesForChoices($choices)); + } + + public function testGetValuesForChoicesDealsWithNumericValues() + { + // Pass values as strings although they are integers + $values = array('0', '1'); + + $this->assertSame(array('0', '1'), $this->numericList->getValuesForChoices($values)); + } + + /** + * @dataProvider dirtyValuesProvider + */ + public function testGetValuesForChoicesDealsWithDirtyValues($choice, $value) + { + $choices = array( + '0' => 'Zero', + '1' => 'One', + '' => 'Empty', + '1.23' => 'Float', + 'foo' => 'Foo', + 'foo10' => 'Foo 10', + ); + + // use COPY_CHOICE strategy to test the problems + $this->list = new SimpleChoiceList($choices, array()); + + $this->assertSame(array($value), $this->list->getValuesForChoices(array($choice))); + } + + public function dirtyValuesProvider() + { + return array( + array(0, '0'), + array('0', '0'), + array('1', '1'), + array(false, '0'), + array(true, '1'), + array('', ''), + array(null, ''), + array('1.23', '1.23'), + array('foo', 'foo'), + array('foo10', 'foo10'), + ); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php new file mode 100644 index 00000000..ee2e3351 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataMapper/PropertyPathMapperTest.php @@ -0,0 +1,319 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataMapper; + +use Symfony\Component\Form\FormConfigBuilder; +use Symfony\Component\Form\FormConfigInterface; +use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; + +class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var PropertyPathMapper + */ + private $mapper; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $dispatcher; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $propertyAccessor; + + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\Event')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) { + $this->markTestSkipped('The "PropertyAccess" component is not available'); + } + + $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->propertyAccessor = $this->getMock('Symfony\Component\PropertyAccess\PropertyAccessorInterface'); + $this->mapper = new PropertyPathMapper($this->propertyAccessor); + } + + /** + * @param $path + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getPropertyPath($path) + { + return $this->getMockBuilder('Symfony\Component\PropertyAccess\PropertyPath') + ->setConstructorArgs(array($path)) + ->setMethods(array('getValue', 'setValue')) + ->getMock(); + } + + /** + * @param FormConfigInterface $config + * @param Boolean $synchronized + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getForm(FormConfigInterface $config, $synchronized = true) + { + $form = $this->getMockBuilder('Symfony\Component\Form\Form') + ->setConstructorArgs(array($config)) + ->setMethods(array('isSynchronized')) + ->getMock(); + + $form->expects($this->any()) + ->method('isSynchronized') + ->will($this->returnValue($synchronized)); + + return $form; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getDataMapper() + { + return $this->getMock('Symfony\Component\Form\DataMapperInterface'); + } + + public function testMapDataToFormsPassesObjectRefIfByReference() + { + $car = new \stdClass(); + $engine = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->once()) + ->method('getValue') + ->with($car, $propertyPath) + ->will($this->returnValue($engine)); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(true); + $config->setPropertyPath($propertyPath); + $form = $this->getForm($config); + + $this->mapper->mapDataToForms($car, array($form)); + + // Can't use isIdentical() above because mocks always clone their + // arguments which can't be disabled in PHPUnit 3.6 + $this->assertSame($engine, $form->getData()); + } + + public function testMapDataToFormsPassesObjectCloneIfNotByReference() + { + $car = new \stdClass(); + $engine = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->once()) + ->method('getValue') + ->with($car, $propertyPath) + ->will($this->returnValue($engine)); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(false); + $config->setPropertyPath($propertyPath); + $form = $this->getForm($config); + + $this->mapper->mapDataToForms($car, array($form)); + + $this->assertNotSame($engine, $form->getData()); + $this->assertEquals($engine, $form->getData()); + } + + public function testMapDataToFormsIgnoresEmptyPropertyPath() + { + $car = new \stdClass(); + + $config = new FormConfigBuilder(null, '\stdClass', $this->dispatcher); + $config->setByReference(true); + $form = $this->getForm($config); + + $this->assertNull($form->getPropertyPath()); + + $this->mapper->mapDataToForms($car, array($form)); + + $this->assertNull($form->getData()); + } + + public function testMapDataToFormsIgnoresUnmapped() + { + $car = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->never()) + ->method('getValue'); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(true); + $config->setMapped(false); + $config->setPropertyPath($propertyPath); + $form = $this->getForm($config); + + $this->mapper->mapDataToForms($car, array($form)); + + $this->assertNull($form->getData()); + } + + public function testMapDataToFormsIgnoresEmptyData() + { + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->never()) + ->method('getValue'); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(true); + $config->setPropertyPath($propertyPath); + $form = $this->getForm($config); + + $this->mapper->mapDataToForms(null, array($form)); + + $this->assertNull($form->getData()); + } + + public function testMapFormsToDataWritesBackIfNotByReference() + { + $car = new \stdClass(); + $engine = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->once()) + ->method('setValue') + ->with($car, $propertyPath, $engine); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(false); + $config->setPropertyPath($propertyPath); + $config->setData($engine); + $form = $this->getForm($config); + + $this->mapper->mapFormsToData(array($form), $car); + } + + public function testMapFormsToDataWritesBackIfByReferenceButNoReference() + { + $car = new \stdClass(); + $engine = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->once()) + ->method('setValue') + ->with($car, $propertyPath, $engine); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(true); + $config->setPropertyPath($propertyPath); + $config->setData($engine); + $form = $this->getForm($config); + + $this->mapper->mapFormsToData(array($form), $car); + } + + public function testMapFormsToDataWritesBackIfByReferenceAndReference() + { + $car = new \stdClass(); + $engine = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + // $car already contains the reference of $engine + $this->propertyAccessor->expects($this->once()) + ->method('getValue') + ->with($car, $propertyPath) + ->will($this->returnValue($engine)); + + $this->propertyAccessor->expects($this->never()) + ->method('setValue'); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(true); + $config->setPropertyPath($propertyPath); + $config->setData($engine); + $form = $this->getForm($config); + + $this->mapper->mapFormsToData(array($form), $car); + } + + public function testMapFormsToDataIgnoresUnmapped() + { + $car = new \stdClass(); + $engine = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->never()) + ->method('setValue'); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(true); + $config->setPropertyPath($propertyPath); + $config->setData($engine); + $config->setMapped(false); + $form = $this->getForm($config); + + $this->mapper->mapFormsToData(array($form), $car); + } + + public function testMapFormsToDataIgnoresEmptyData() + { + $car = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->never()) + ->method('setValue'); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(true); + $config->setPropertyPath($propertyPath); + $config->setData(null); + $form = $this->getForm($config); + + $this->mapper->mapFormsToData(array($form), $car); + } + + public function testMapFormsToDataIgnoresUnsynchronized() + { + $car = new \stdClass(); + $engine = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->never()) + ->method('setValue'); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(true); + $config->setPropertyPath($propertyPath); + $config->setData($engine); + $form = $this->getForm($config, false); + + $this->mapper->mapFormsToData(array($form), $car); + } + + public function testMapFormsToDataIgnoresDisabled() + { + $car = new \stdClass(); + $engine = new \stdClass(); + $propertyPath = $this->getPropertyPath('engine'); + + $this->propertyAccessor->expects($this->never()) + ->method('setValue'); + + $config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher); + $config->setByReference(true); + $config->setPropertyPath($propertyPath); + $config->setData($engine); + $config->setDisabled(true); + $form = $this->getForm($config); + + $this->mapper->mapFormsToData(array($form), $car); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ArrayToPartsTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ArrayToPartsTransformerTest.php new file mode 100644 index 00000000..bafe5c09 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ArrayToPartsTransformerTest.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\ArrayToPartsTransformer; + +class ArrayToPartsTransformerTest extends \PHPUnit_Framework_TestCase +{ + private $transformer; + + protected function setUp() + { + $this->transformer = new ArrayToPartsTransformer(array( + 'first' => array('a', 'b', 'c'), + 'second' => array('d', 'e', 'f'), + )); + } + + protected function tearDown() + { + $this->transformer = null; + } + + public function testTransform() + { + $input = array( + 'a' => '1', + 'b' => '2', + 'c' => '3', + 'd' => '4', + 'e' => '5', + 'f' => '6', + ); + + $output = array( + 'first' => array( + 'a' => '1', + 'b' => '2', + 'c' => '3', + ), + 'second' => array( + 'd' => '4', + 'e' => '5', + 'f' => '6', + ), + ); + + $this->assertSame($output, $this->transformer->transform($input)); + } + + public function testTransformEmpty() + { + $output = array( + 'first' => null, + 'second' => null, + ); + + $this->assertSame($output, $this->transformer->transform(null)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testTransformRequiresArray() + { + $this->transformer->transform('12345'); + } + + public function testReverseTransform() + { + $input = array( + 'first' => array( + 'a' => '1', + 'b' => '2', + 'c' => '3', + ), + 'second' => array( + 'd' => '4', + 'e' => '5', + 'f' => '6', + ), + ); + + $output = array( + 'a' => '1', + 'b' => '2', + 'c' => '3', + 'd' => '4', + 'e' => '5', + 'f' => '6', + ); + + $this->assertSame($output, $this->transformer->reverseTransform($input)); + } + + public function testReverseTransformCompletelyEmpty() + { + $input = array( + 'first' => '', + 'second' => '', + ); + + $this->assertNull($this->transformer->reverseTransform($input)); + } + + public function testReverseTransformCompletelyNull() + { + $input = array( + 'first' => null, + 'second' => null, + ); + + $this->assertNull($this->transformer->reverseTransform($input)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformPartiallyNull() + { + $input = array( + 'first' => array( + 'a' => '1', + 'b' => '2', + 'c' => '3', + ), + 'second' => null, + ); + + $this->transformer->reverseTransform($input); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformRequiresArray() + { + $this->transformer->reverseTransform('12345'); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php new file mode 100644 index 00000000..41f8f956 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/BooleanToStringTransformerTest.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\BooleanToStringTransformer; + +class BooleanToStringTransformerTest extends \PHPUnit_Framework_TestCase +{ + const TRUE_VALUE = '1'; + + protected $transformer; + + protected function setUp() + { + $this->transformer = new BooleanToStringTransformer(self::TRUE_VALUE); + } + + protected function tearDown() + { + $this->transformer = null; + } + + public function testTransform() + { + $this->assertEquals(self::TRUE_VALUE, $this->transformer->transform(true)); + $this->assertNull($this->transformer->transform(false)); + $this->assertNull($this->transformer->transform(null)); + } + + public function testTransformExpectsBoolean() + { + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $this->transformer->transform('1'); + } + + public function testReverseTransformExpectsString() + { + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $this->transformer->reverseTransform(1); + } + + public function testReverseTransform() + { + $this->assertTrue($this->transformer->reverseTransform(self::TRUE_VALUE)); + $this->assertTrue($this->transformer->reverseTransform('foobar')); + $this->assertTrue($this->transformer->reverseTransform('')); + $this->assertFalse($this->transformer->reverseTransform(null)); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php new file mode 100644 index 00000000..bbae0621 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoiceToValueTransformerTest.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; +use Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer; + +class ChoiceToValueTransformerTest extends \PHPUnit_Framework_TestCase +{ + protected $transformer; + + protected function setUp() + { + $list = new SimpleChoiceList(array('' => 'A', 0 => 'B', 1 => 'C')); + $this->transformer = new ChoiceToValueTransformer($list); + } + + protected function tearDown() + { + $this->transformer = null; + } + + public function transformProvider() + { + return array( + // more extensive test set can be found in FormUtilTest + array(0, '0'), + array(false, '0'), + array('', ''), + ); + } + + /** + * @dataProvider transformProvider + */ + public function testTransform($in, $out) + { + $this->assertSame($out, $this->transformer->transform($in)); + } + + public function reverseTransformProvider() + { + return array( + // values are expected to be valid choice keys already and stay + // the same + array('0', 0), + array('', null), + array(null, null), + ); + } + + /** + * @dataProvider reverseTransformProvider + */ + public function testReverseTransform($in, $out) + { + $this->assertSame($out, $this->transformer->reverseTransform($in)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformExpectsScalar() + { + $this->transformer->reverseTransform(array()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoicesToValuesTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoicesToValuesTransformerTest.php new file mode 100644 index 00000000..57297193 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ChoicesToValuesTransformerTest.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; + +use Symfony\Component\Form\Extension\Core\DataTransformer\ChoicesToValuesTransformer; + +class ChoicesToValuesTransformerTest extends \PHPUnit_Framework_TestCase +{ + protected $transformer; + + protected function setUp() + { + $list = new SimpleChoiceList(array(0 => 'A', 1 => 'B', 2 => 'C')); + $this->transformer = new ChoicesToValuesTransformer($list); + } + + protected function tearDown() + { + $this->transformer = null; + } + + public function testTransform() + { + // Value strategy in SimpleChoiceList is to copy and convert to string + $in = array(0, 1, 2); + $out = array('0', '1', '2'); + + $this->assertSame($out, $this->transformer->transform($in)); + } + + public function testTransformNull() + { + $this->assertSame(array(), $this->transformer->transform(null)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testTransformExpectsArray() + { + $this->transformer->transform('foobar'); + } + + public function testReverseTransform() + { + // values are expected to be valid choices and stay the same + $in = array('0', '1', '2'); + $out = array(0, 1, 2); + + $this->assertSame($out, $this->transformer->reverseTransform($in)); + } + + public function testReverseTransformNull() + { + $this->assertSame(array(), $this->transformer->reverseTransform(null)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformExpectsArray() + { + $this->transformer->reverseTransform('foobar'); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DataTransformerChainTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DataTransformerChainTest.php new file mode 100644 index 00000000..2ee2f22d --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DataTransformerChainTest.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain; + +class DataTransformerChainTest extends \PHPUnit_Framework_TestCase +{ + public function testTransform() + { + $transformer1 = $this->getMock('Symfony\Component\Form\DataTransformerInterface'); + $transformer1->expects($this->once()) + ->method('transform') + ->with($this->identicalTo('foo')) + ->will($this->returnValue('bar')); + $transformer2 = $this->getMock('Symfony\Component\Form\DataTransformerInterface'); + $transformer2->expects($this->once()) + ->method('transform') + ->with($this->identicalTo('bar')) + ->will($this->returnValue('baz')); + + $chain = new DataTransformerChain(array($transformer1, $transformer2)); + + $this->assertEquals('baz', $chain->transform('foo')); + } + + public function testReverseTransform() + { + $transformer2 = $this->getMock('Symfony\Component\Form\DataTransformerInterface'); + $transformer2->expects($this->once()) + ->method('reverseTransform') + ->with($this->identicalTo('foo')) + ->will($this->returnValue('bar')); + $transformer1 = $this->getMock('Symfony\Component\Form\DataTransformerInterface'); + $transformer1->expects($this->once()) + ->method('reverseTransform') + ->with($this->identicalTo('bar')) + ->will($this->returnValue('baz')); + + $chain = new DataTransformerChain(array($transformer1, $transformer2)); + + $this->assertEquals('baz', $chain->reverseTransform('foo')); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php new file mode 100644 index 00000000..f7722c49 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeTestCase.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +abstract class DateTimeTestCase extends \PHPUnit_Framework_TestCase +{ + public static function assertDateTimeEquals(\DateTime $expected, \DateTime $actual) + { + self::assertEquals($expected->format('c'), $actual->format('c')); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php new file mode 100644 index 00000000..4898b88d --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php @@ -0,0 +1,512 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer; + +class DateTimeToArrayTransformerTest extends DateTimeTestCase +{ + public function testTransform() + { + $transformer = new DateTimeToArrayTransformer('UTC', 'UTC'); + + $input = new \DateTime('2010-02-03 04:05:06 UTC'); + + $output = array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + ); + + $this->assertSame($output, $transformer->transform($input)); + } + + public function testTransformEmpty() + { + $transformer = new DateTimeToArrayTransformer(); + + $output = array( + 'year' => '', + 'month' => '', + 'day' => '', + 'hour' => '', + 'minute' => '', + 'second' => '', + ); + + $this->assertSame($output, $transformer->transform(null)); + } + + public function testTransformEmptyWithFields() + { + $transformer = new DateTimeToArrayTransformer(null, null, array('year', 'minute', 'second')); + + $output = array( + 'year' => '', + 'minute' => '', + 'second' => '', + ); + + $this->assertSame($output, $transformer->transform(null)); + } + + public function testTransformWithFields() + { + $transformer = new DateTimeToArrayTransformer('UTC', 'UTC', array('year', 'month', 'minute', 'second')); + + $input = new \DateTime('2010-02-03 04:05:06 UTC'); + + $output = array( + 'year' => '2010', + 'month' => '2', + 'minute' => '5', + 'second' => '6', + ); + + $this->assertSame($output, $transformer->transform($input)); + } + + public function testTransformWithPadding() + { + $transformer = new DateTimeToArrayTransformer('UTC', 'UTC', null, true); + + $input = new \DateTime('2010-02-03 04:05:06 UTC'); + + $output = array( + 'year' => '2010', + 'month' => '02', + 'day' => '03', + 'hour' => '04', + 'minute' => '05', + 'second' => '06', + ); + + $this->assertSame($output, $transformer->transform($input)); + } + + public function testTransformDifferentTimezones() + { + $transformer = new DateTimeToArrayTransformer('America/New_York', 'Asia/Hong_Kong'); + + $input = new \DateTime('2010-02-03 04:05:06 America/New_York'); + + $dateTime = new \DateTime('2010-02-03 04:05:06 America/New_York'); + $dateTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + $output = array( + 'year' => (string) (int) $dateTime->format('Y'), + 'month' => (string) (int) $dateTime->format('m'), + 'day' => (string) (int) $dateTime->format('d'), + 'hour' => (string) (int) $dateTime->format('H'), + 'minute' => (string) (int) $dateTime->format('i'), + 'second' => (string) (int) $dateTime->format('s'), + ); + + $this->assertSame($output, $transformer->transform($input)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testTransformRequiresDateTime() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform('12345'); + } + + public function testReverseTransform() + { + $transformer = new DateTimeToArrayTransformer('UTC', 'UTC'); + + $input = array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + ); + + $output = new \DateTime('2010-02-03 04:05:06 UTC'); + + $this->assertDateTimeEquals($output, $transformer->reverseTransform($input)); + } + + public function testReverseTransformWithSomeZero() + { + $transformer = new DateTimeToArrayTransformer('UTC', 'UTC'); + + $input = array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '0', + 'second' => '0', + ); + + $output = new \DateTime('2010-02-03 04:00:00 UTC'); + + $this->assertDateTimeEquals($output, $transformer->reverseTransform($input)); + } + + public function testReverseTransformCompletelyEmpty() + { + $transformer = new DateTimeToArrayTransformer(); + + $input = array( + 'year' => '', + 'month' => '', + 'day' => '', + 'hour' => '', + 'minute' => '', + 'second' => '', + ); + + $this->assertNull($transformer->reverseTransform($input)); + } + + public function testReverseTransformCompletelyEmptySubsetOfFields() + { + $transformer = new DateTimeToArrayTransformer(null, null, array('year', 'month', 'day')); + + $input = array( + 'year' => '', + 'month' => '', + 'day' => '', + ); + + $this->assertNull($transformer->reverseTransform($input)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformPartiallyEmptyYear() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformPartiallyEmptyMonth() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformPartiallyEmptyDay() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformPartiallyEmptyHour() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformPartiallyEmptyMinute() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformPartiallyEmptySecond() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + )); + } + + public function testReverseTransformNull() + { + $transformer = new DateTimeToArrayTransformer(); + + $this->assertNull($transformer->reverseTransform(null)); + } + + public function testReverseTransformDifferentTimezones() + { + $transformer = new DateTimeToArrayTransformer('America/New_York', 'Asia/Hong_Kong'); + + $input = array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + ); + + $output = new \DateTime('2010-02-03 04:05:06 Asia/Hong_Kong'); + $output->setTimezone(new \DateTimeZone('America/New_York')); + + $this->assertDateTimeEquals($output, $transformer->reverseTransform($input)); + } + + public function testReverseTransformToDifferentTimezone() + { + $transformer = new DateTimeToArrayTransformer('Asia/Hong_Kong', 'UTC'); + + $input = array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + ); + + $output = new \DateTime('2010-02-03 04:05:06 UTC'); + $output->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $this->assertDateTimeEquals($output, $transformer->reverseTransform($input)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformRequiresArray() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform('12345'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithNegativeYear() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '-1', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithNegativeMonth() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '-1', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithNegativeDay() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'day' => '-1', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithNegativeHour() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '-1', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithNegativeMinute() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '-1', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithNegativeSecond() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '-1', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithInvalidMonth() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '13', + 'day' => '3', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithInvalidDay() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'day' => '31', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithStringDay() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => '2', + 'day' => 'bazinga', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithStringMonth() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => '2010', + 'month' => 'bazinga', + 'day' => '31', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithStringYear() + { + $transformer = new DateTimeToArrayTransformer(); + $transformer->reverseTransform(array( + 'year' => 'bazinga', + 'month' => '2', + 'day' => '31', + 'hour' => '4', + 'minute' => '5', + 'second' => '6', + )); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php new file mode 100644 index 00000000..cb50fc36 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php @@ -0,0 +1,275 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToLocalizedStringTransformer; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class DateTimeToLocalizedStringTransformerTest extends DateTimeTestCase +{ + protected $dateTime; + protected $dateTimeWithoutSeconds; + + protected function setUp() + { + parent::setUp(); + + // Since we test against "de_AT", we need the full implementation + IntlTestHelper::requireFullIntl($this); + + \Locale::setDefault('de_AT'); + + $this->dateTime = new \DateTime('2010-02-03 04:05:06 UTC'); + $this->dateTimeWithoutSeconds = new \DateTime('2010-02-03 04:05:00 UTC'); + } + + protected function tearDown() + { + $this->dateTime = null; + $this->dateTimeWithoutSeconds = null; + } + + public static function assertEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) + { + if ($expected instanceof \DateTime && $actual instanceof \DateTime) { + $expected = $expected->format('c'); + $actual = $actual->format('c'); + } + + parent::assertEquals($expected, $actual, $message, $delta, $maxDepth, $canonicalize, $ignoreCase); + } + + public function dataProvider() + { + return array( + array(\IntlDateFormatter::SHORT, null, null, '03.02.10 04:05', '2010-02-03 04:05:00 UTC'), + array(\IntlDateFormatter::MEDIUM, null, null, '03.02.2010 04:05', '2010-02-03 04:05:00 UTC'), + array(\IntlDateFormatter::LONG, null, null, '03. Februar 2010 04:05', '2010-02-03 04:05:00 UTC'), + array(\IntlDateFormatter::FULL, null, null, 'Mittwoch, 03. Februar 2010 04:05', '2010-02-03 04:05:00 UTC'), + array(\IntlDateFormatter::SHORT, \IntlDateFormatter::NONE, null, '03.02.10', '2010-02-03 00:00:00 UTC'), + array(\IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE, null, '03.02.2010', '2010-02-03 00:00:00 UTC'), + array(\IntlDateFormatter::LONG, \IntlDateFormatter::NONE, null, '03. Februar 2010', '2010-02-03 00:00:00 UTC'), + array(\IntlDateFormatter::FULL, \IntlDateFormatter::NONE, null, 'Mittwoch, 03. Februar 2010', '2010-02-03 00:00:00 UTC'), + array(null, \IntlDateFormatter::SHORT, null, '03.02.2010 04:05', '2010-02-03 04:05:00 UTC'), + array(null, \IntlDateFormatter::MEDIUM, null, '03.02.2010 04:05:06', '2010-02-03 04:05:06 UTC'), + array(null, \IntlDateFormatter::LONG, null, '03.02.2010 04:05:06 GMT', '2010-02-03 04:05:06 UTC'), + // see below for extra test case for time format FULL + array(\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT, null, '04:05', '1970-01-01 04:05:00 UTC'), + array(\IntlDateFormatter::NONE, \IntlDateFormatter::MEDIUM, null, '04:05:06', '1970-01-01 04:05:06 UTC'), + array(\IntlDateFormatter::NONE, \IntlDateFormatter::LONG, null, '04:05:06 GMT', '1970-01-01 04:05:06 UTC'), + array(null, null, 'yyyy-MM-dd HH:mm:00', '2010-02-03 04:05:00', '2010-02-03 04:05:00 UTC'), + array(null, null, 'yyyy-MM-dd HH:mm', '2010-02-03 04:05', '2010-02-03 04:05:00 UTC'), + array(null, null, 'yyyy-MM-dd HH', '2010-02-03 04', '2010-02-03 04:00:00 UTC'), + array(null, null, 'yyyy-MM-dd', '2010-02-03', '2010-02-03 00:00:00 UTC'), + array(null, null, 'yyyy-MM', '2010-02', '2010-02-01 00:00:00 UTC'), + array(null, null, 'yyyy', '2010', '2010-01-01 00:00:00 UTC'), + array(null, null, 'dd-MM-yyyy', '03-02-2010', '2010-02-03 00:00:00 UTC'), + array(null, null, 'HH:mm:ss', '04:05:06', '1970-01-01 04:05:06 UTC'), + array(null, null, 'HH:mm:00', '04:05:00', '1970-01-01 04:05:00 UTC'), + array(null, null, 'HH:mm', '04:05', '1970-01-01 04:05:00 UTC'), + array(null, null, 'HH', '04', '1970-01-01 04:00:00 UTC'), + ); + } + + /** + * @dataProvider dataProvider + */ + public function testTransform($dateFormat, $timeFormat, $pattern, $output, $input) + { + $transformer = new DateTimeToLocalizedStringTransformer( + 'UTC', + 'UTC', + $dateFormat, + $timeFormat, + \IntlDateFormatter::GREGORIAN, + $pattern + ); + + $input = new \DateTime($input); + + $this->assertEquals($output, $transformer->transform($input)); + } + + public function testTransformFullTime() + { + $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', null, \IntlDateFormatter::FULL); + + $this->assertEquals('03.02.2010 04:05:06 GMT', $transformer->transform($this->dateTime)); + } + + public function testTransformToDifferentLocale() + { + \Locale::setDefault('en_US'); + + $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC'); + + $this->assertEquals('Feb 3, 2010, 4:05 AM', $transformer->transform($this->dateTime)); + } + + public function testTransformEmpty() + { + $transformer = new DateTimeToLocalizedStringTransformer(); + + $this->assertSame('', $transformer->transform(null)); + } + + public function testTransformWithDifferentTimezones() + { + $transformer = new DateTimeToLocalizedStringTransformer('America/New_York', 'Asia/Hong_Kong'); + + $input = new \DateTime('2010-02-03 04:05:06 America/New_York'); + + $dateTime = clone $input; + $dateTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $this->assertEquals($dateTime->format('d.m.Y H:i'), $transformer->transform($input)); + } + + public function testTransformWithDifferentPatterns() + { + $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, \IntlDateFormatter::GREGORIAN, 'MM*yyyy*dd HH|mm|ss'); + + $this->assertEquals('02*2010*03 04|05|06', $transformer->transform($this->dateTime)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testTransformRequiresValidDateTime() + { + $transformer = new DateTimeToLocalizedStringTransformer(); + $transformer->transform('2010-01-01'); + } + + public function testTransformWrapsIntlErrors() + { + $transformer = new DateTimeToLocalizedStringTransformer(); + + // HOW TO REPRODUCE? + + //$this->setExpectedException('Symfony\Component\Form\Extension\Core\DataTransformer\Transdate_formationFailedException'); + + //$transformer->transform(1.5); + } + + /** + * @dataProvider dataProvider + */ + public function testReverseTransform($dateFormat, $timeFormat, $pattern, $input, $output) + { + $transformer = new DateTimeToLocalizedStringTransformer( + 'UTC', + 'UTC', + $dateFormat, + $timeFormat, + \IntlDateFormatter::GREGORIAN, + $pattern + ); + + $output = new \DateTime($output); + + $this->assertEquals($output, $transformer->reverseTransform($input)); + } + + public function testReverseTransformFullTime() + { + $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', null, \IntlDateFormatter::FULL); + + $this->assertDateTimeEquals($this->dateTime, $transformer->reverseTransform('03.02.2010 04:05:06 GMT+00:00')); + } + + public function testReverseTransformFromDifferentLocale() + { + \Locale::setDefault('en_US'); + + $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC'); + + $this->assertDateTimeEquals($this->dateTimeWithoutSeconds, $transformer->reverseTransform('Feb 3, 2010, 04:05 AM')); + } + + public function testReverseTransformWithDifferentTimezones() + { + $transformer = new DateTimeToLocalizedStringTransformer('America/New_York', 'Asia/Hong_Kong'); + + $dateTime = new \DateTime('2010-02-03 04:05:00 Asia/Hong_Kong'); + $dateTime->setTimezone(new \DateTimeZone('America/New_York')); + + $this->assertDateTimeEquals($dateTime, $transformer->reverseTransform('03.02.2010 04:05')); + } + + public function testReverseTransformWithDifferentPatterns() + { + $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, \IntlDateFormatter::GREGORIAN, 'MM*yyyy*dd HH|mm|ss'); + + $this->assertDateTimeEquals($this->dateTime, $transformer->reverseTransform('02*2010*03 04|05|06')); + } + + public function testReverseTransformEmpty() + { + $transformer = new DateTimeToLocalizedStringTransformer(); + + $this->assertNull($transformer->reverseTransform('')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformRequiresString() + { + $transformer = new DateTimeToLocalizedStringTransformer(); + $transformer->reverseTransform(12345); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWrapsIntlErrors() + { + $transformer = new DateTimeToLocalizedStringTransformer(); + $transformer->reverseTransform('12345'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testValidateDateFormatOption() + { + new DateTimeToLocalizedStringTransformer(null, null, 'foobar'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testValidateTimeFormatOption() + { + new DateTimeToLocalizedStringTransformer(null, null, null, 'foobar'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithNonExistingDate() + { + $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', \IntlDateFormatter::SHORT); + + $this->assertDateTimeEquals($this->dateTimeWithoutSeconds, $transformer->reverseTransform('31.04.10 04:05')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformOutOfTimestampRange() + { + $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC'); + $transformer->reverseTransform('1789-07-14'); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php new file mode 100644 index 00000000..98aeb772 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php @@ -0,0 +1,132 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToRfc3339Transformer; + +class DateTimeToRfc3339TransformerTest extends DateTimeTestCase +{ + protected $dateTime; + protected $dateTimeWithoutSeconds; + + protected function setUp() + { + parent::setUp(); + + $this->dateTime = new \DateTime('2010-02-03 04:05:06 UTC'); + $this->dateTimeWithoutSeconds = new \DateTime('2010-02-03 04:05:00 UTC'); + } + + protected function tearDown() + { + $this->dateTime = null; + $this->dateTimeWithoutSeconds = null; + } + + public static function assertEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE) + { + if ($expected instanceof \DateTime && $actual instanceof \DateTime) { + $expected = $expected->format('c'); + $actual = $actual->format('c'); + } + + parent::assertEquals($expected, $actual, $message, $delta, $maxDepth, $canonicalize, $ignoreCase); + } + + public function allProvider() + { + return array( + array('UTC', 'UTC', '2010-02-03 04:05:06 UTC', '2010-02-03T04:05:06Z'), + array('UTC', 'UTC', null, ''), + array('America/New_York', 'Asia/Hong_Kong', '2010-02-03 04:05:06 America/New_York', '2010-02-03T17:05:06+08:00'), + array('America/New_York', 'Asia/Hong_Kong', null, ''), + array('UTC', 'Asia/Hong_Kong', '2010-02-03 04:05:06 UTC', '2010-02-03T12:05:06+08:00'), + array('America/New_York', 'UTC', '2010-02-03 04:05:06 America/New_York', '2010-02-03T09:05:06Z'), + ); + } + + public function transformProvider() + { + return $this->allProvider(); + } + + public function reverseTransformProvider() + { + return array_merge($this->allProvider(), array( + // format without seconds, as appears in some browsers + array('UTC', 'UTC', '2010-02-03 04:05:00 UTC', '2010-02-03T04:05Z'), + array('America/New_York', 'Asia/Hong_Kong', '2010-02-03 04:05:00 America/New_York', '2010-02-03T17:05+08:00'), + )); + } + + /** + * @dataProvider transformProvider + */ + public function testTransform($fromTz, $toTz, $from, $to) + { + $transformer = new DateTimeToRfc3339Transformer($fromTz, $toTz); + + $this->assertSame($to, $transformer->transform(null !== $from ? new \DateTime($from) : null)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testTransformRequiresValidDateTime() + { + $transformer = new DateTimeToRfc3339Transformer(); + $transformer->transform('2010-01-01'); + } + + /** + * @dataProvider reverseTransformProvider + */ + public function testReverseTransform($toTz, $fromTz, $to, $from) + { + $transformer = new DateTimeToRfc3339Transformer($toTz, $fromTz); + + if (null !== $to) { + $this->assertDateTimeEquals(new \DateTime($to), $transformer->reverseTransform($from)); + } else { + $this->assertSame($to, $transformer->reverseTransform($from)); + } + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformRequiresString() + { + $transformer = new DateTimeToRfc3339Transformer(); + $transformer->reverseTransform(12345); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformWithNonExistingDate() + { + $transformer = new DateTimeToRfc3339Transformer('UTC', 'UTC'); + + $transformer->reverseTransform('2010-04-31T04:05Z'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformExpectsValidDateString() + { + $transformer = new DateTimeToRfc3339Transformer('UTC', 'UTC'); + + $transformer->reverseTransform('2010-2010-2010'); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php new file mode 100644 index 00000000..987df1d8 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php @@ -0,0 +1,181 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer; + +class DateTimeToStringTransformerTest extends DateTimeTestCase +{ + public function dataProvider() + { + $data = array( + array('Y-m-d H:i:s', '2010-02-03 16:05:06', '2010-02-03 16:05:06 UTC'), + array('Y-m-d H:i:00', '2010-02-03 16:05:00', '2010-02-03 16:05:00 UTC'), + array('Y-m-d H:i', '2010-02-03 16:05', '2010-02-03 16:05:00 UTC'), + array('Y-m-d H', '2010-02-03 16', '2010-02-03 16:00:00 UTC'), + array('Y-m-d', '2010-02-03', '2010-02-03 00:00:00 UTC'), + array('Y-m', '2010-12', '2010-12-01 00:00:00 UTC'), + array('Y', '2010', '2010-01-01 00:00:00 UTC'), + array('d-m-Y', '03-02-2010', '2010-02-03 00:00:00 UTC'), + array('H:i:s', '16:05:06', '1970-01-01 16:05:06 UTC'), + array('H:i:00', '16:05:00', '1970-01-01 16:05:00 UTC'), + array('H:i', '16:05', '1970-01-01 16:05:00 UTC'), + array('H', '16', '1970-01-01 16:00:00 UTC'), + + // different day representations + array('Y-m-j', '2010-02-3', '2010-02-03 00:00:00 UTC'), + array('z', '33', '1970-02-03 00:00:00 UTC'), + + // not bijective + // this will not work as php will use actual date to replace missing info + // and after change of date will lookup for closest Wednesday + // i.e. value: 2010-02, php value: 2010-02-(today i.e. 20), parsed date: 2010-02-24 + //array('Y-m-D', '2010-02-Wed', '2010-02-03 00:00:00 UTC'), + //array('Y-m-l', '2010-02-Wednesday', '2010-02-03 00:00:00 UTC'), + + // different month representations + array('Y-n-d', '2010-2-03', '2010-02-03 00:00:00 UTC'), + array('Y-M-d', '2010-Feb-03', '2010-02-03 00:00:00 UTC'), + array('Y-F-d', '2010-February-03', '2010-02-03 00:00:00 UTC'), + + // different year representations + array('y-m-d', '10-02-03', '2010-02-03 00:00:00 UTC'), + + // different time representations + array('G:i:s', '16:05:06', '1970-01-01 16:05:06 UTC'), + array('g:i:s a', '4:05:06 pm', '1970-01-01 16:05:06 UTC'), + array('h:i:s a', '04:05:06 pm', '1970-01-01 16:05:06 UTC'), + + // seconds since unix + array('U', '1265213106', '2010-02-03 16:05:06 UTC'), + ); + + // This test will fail < 5.3.9 - see https://bugs.php.net/51994 + if (version_compare(phpversion(), '5.3.9', '>=')) { + $data[] = array('Y-z', '2010-33', '2010-02-03 00:00:00 UTC'); + } + + return $data; + } + + /** + * @dataProvider dataProvider + */ + public function testTransform($format, $output, $input) + { + $transformer = new DateTimeToStringTransformer('UTC', 'UTC', $format); + + $input = new \DateTime($input); + + $this->assertEquals($output, $transformer->transform($input)); + } + + public function testTransformEmpty() + { + $transformer = new DateTimeToStringTransformer(); + + $this->assertSame('', $transformer->transform(null)); + } + + public function testTransformWithDifferentTimezones() + { + $transformer = new DateTimeToStringTransformer('Asia/Hong_Kong', 'America/New_York', 'Y-m-d H:i:s'); + + $input = new \DateTime('2010-02-03 12:05:06 America/New_York'); + $output = $input->format('Y-m-d H:i:s'); + $input->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $this->assertEquals($output, $transformer->transform($input)); + } + + public function testTransformExpectsDateTime() + { + $transformer = new DateTimeToStringTransformer(); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $transformer->transform('1234'); + } + + /** + * @dataProvider dataProvider + */ + public function testReverseTransformUsingPipe($format, $input, $output) + { + if (version_compare(phpversion(), '5.3.7', '<')) { + $this->markTestSkipped('Pipe usage requires PHP 5.3.7 or newer.'); + } + + $reverseTransformer = new DateTimeToStringTransformer('UTC', 'UTC', $format, true); + + $output = new \DateTime($output); + + $this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input)); + } + + /** + * @dataProvider dataProvider + */ + public function testReverseTransformWithoutUsingPipe($format, $input, $output) + { + $reverseTransformer = new DateTimeToStringTransformer('UTC', 'UTC', $format, false); + + $output = new \DateTime($output); + + $this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input)); + } + + public function testReverseTransformEmpty() + { + $reverseTransformer = new DateTimeToStringTransformer(); + + $this->assertNull($reverseTransformer->reverseTransform('')); + } + + public function testReverseTransformWithDifferentTimezones() + { + $reverseTransformer = new DateTimeToStringTransformer('America/New_York', 'Asia/Hong_Kong', 'Y-m-d H:i:s'); + + $output = new \DateTime('2010-02-03 16:05:06 Asia/Hong_Kong'); + $input = $output->format('Y-m-d H:i:s'); + $output->setTimeZone(new \DateTimeZone('America/New_York')); + + $this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input)); + } + + public function testReverseTransformExpectsString() + { + $reverseTransformer = new DateTimeToStringTransformer(); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $reverseTransformer->reverseTransform(1234); + } + + public function testReverseTransformExpectsValidDateString() + { + $reverseTransformer = new DateTimeToStringTransformer(); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $reverseTransformer->reverseTransform('2010-2010-2010'); + } + + public function testReverseTransformWithNonExistingDate() + { + $reverseTransformer = new DateTimeToStringTransformer(); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $reverseTransformer->reverseTransform('2010-04-31'); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php new file mode 100644 index 00000000..b54f0c4c --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToTimestampTransformer; + +class DateTimeToTimestampTransformerTest extends DateTimeTestCase +{ + public function testTransform() + { + $transformer = new DateTimeToTimestampTransformer('UTC', 'UTC'); + + $input = new \DateTime('2010-02-03 04:05:06 UTC'); + $output = $input->format('U'); + + $this->assertEquals($output, $transformer->transform($input)); + } + + public function testTransformEmpty() + { + $transformer = new DateTimeToTimestampTransformer(); + + $this->assertNull($transformer->transform(null)); + } + + public function testTransformWithDifferentTimezones() + { + $transformer = new DateTimeToTimestampTransformer('Asia/Hong_Kong', 'America/New_York'); + + $input = new \DateTime('2010-02-03 04:05:06 America/New_York'); + $output = $input->format('U'); + $input->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $this->assertEquals($output, $transformer->transform($input)); + } + + public function testTransformFromDifferentTimezone() + { + $transformer = new DateTimeToTimestampTransformer('Asia/Hong_Kong', 'UTC'); + + $input = new \DateTime('2010-02-03 04:05:06 Asia/Hong_Kong'); + + $dateTime = clone $input; + $dateTime->setTimezone(new \DateTimeZone('UTC')); + $output = $dateTime->format('U'); + + $this->assertEquals($output, $transformer->transform($input)); + } + + public function testTransformExpectsDateTime() + { + $transformer = new DateTimeToTimestampTransformer(); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $transformer->transform('1234'); + } + + public function testReverseTransform() + { + $reverseTransformer = new DateTimeToTimestampTransformer('UTC', 'UTC'); + + $output = new \DateTime('2010-02-03 04:05:06 UTC'); + $input = $output->format('U'); + + $this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input)); + } + + public function testReverseTransformEmpty() + { + $reverseTransformer = new DateTimeToTimestampTransformer(); + + $this->assertNull($reverseTransformer->reverseTransform(null)); + } + + public function testReverseTransformWithDifferentTimezones() + { + $reverseTransformer = new DateTimeToTimestampTransformer('Asia/Hong_Kong', 'America/New_York'); + + $output = new \DateTime('2010-02-03 04:05:06 America/New_York'); + $input = $output->format('U'); + $output->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $this->assertDateTimeEquals($output, $reverseTransformer->reverseTransform($input)); + } + + public function testReverseTransformExpectsValidTimestamp() + { + $reverseTransformer = new DateTimeToTimestampTransformer(); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $reverseTransformer->reverseTransform('2010-2010-2010'); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php new file mode 100644 index 00000000..a90fa91b --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\IntegerToLocalizedStringTransformer; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class IntegerToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + parent::setUp(); + + // Since we test against "de_AT", we need the full implementation + IntlTestHelper::requireFullIntl($this); + + \Locale::setDefault('de_AT'); + } + + public function testReverseTransform() + { + $transformer = new IntegerToLocalizedStringTransformer(); + + $this->assertEquals(1, $transformer->reverseTransform('1')); + $this->assertEquals(1, $transformer->reverseTransform('1,5')); + $this->assertEquals(1234, $transformer->reverseTransform('1234,5')); + $this->assertEquals(12345, $transformer->reverseTransform('12345,912')); + } + + public function testReverseTransformEmpty() + { + $transformer = new IntegerToLocalizedStringTransformer(); + + $this->assertNull($transformer->reverseTransform('')); + } + + public function testReverseTransformWithGrouping() + { + $transformer = new IntegerToLocalizedStringTransformer(null, true); + + $this->assertEquals(1234, $transformer->reverseTransform('1.234,5')); + $this->assertEquals(12345, $transformer->reverseTransform('12.345,912')); + $this->assertEquals(1234, $transformer->reverseTransform('1234,5')); + $this->assertEquals(12345, $transformer->reverseTransform('12345,912')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformExpectsString() + { + $transformer = new IntegerToLocalizedStringTransformer(); + + $transformer->reverseTransform(1); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformExpectsValidNumber() + { + $transformer = new IntegerToLocalizedStringTransformer(); + + $transformer->reverseTransform('foo'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsNaN() + { + $transformer = new IntegerToLocalizedStringTransformer(); + + $transformer->reverseTransform('NaN'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsNaN2() + { + $transformer = new IntegerToLocalizedStringTransformer(); + + $transformer->reverseTransform('nan'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsInfinity() + { + $transformer = new IntegerToLocalizedStringTransformer(); + + $transformer->reverseTransform('∞'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsNegativeInfinity() + { + $transformer = new IntegerToLocalizedStringTransformer(); + + $transformer->reverseTransform('-∞'); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php new file mode 100644 index 00000000..8b91fe10 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\MoneyToLocalizedStringTransformer; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class MoneyToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + parent::setUp(); + + // Since we test against "de_AT", we need the full implementation + IntlTestHelper::requireFullIntl($this); + + \Locale::setDefault('de_AT'); + } + + public function testTransform() + { + $transformer = new MoneyToLocalizedStringTransformer(null, null, null, 100); + + $this->assertEquals('1,23', $transformer->transform(123)); + } + + public function testTransformExpectsNumeric() + { + $transformer = new MoneyToLocalizedStringTransformer(null, null, null, 100); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $transformer->transform('abcd'); + } + + public function testTransformEmpty() + { + $transformer = new MoneyToLocalizedStringTransformer(); + + $this->assertSame('', $transformer->transform(null)); + } + + public function testReverseTransform() + { + $transformer = new MoneyToLocalizedStringTransformer(null, null, null, 100); + + $this->assertEquals(123, $transformer->reverseTransform('1,23')); + } + + public function testReverseTransformExpectsString() + { + $transformer = new MoneyToLocalizedStringTransformer(null, null, null, 100); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $transformer->reverseTransform(12345); + } + + public function testReverseTransformEmpty() + { + $transformer = new MoneyToLocalizedStringTransformer(); + + $this->assertNull($transformer->reverseTransform('')); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php new file mode 100644 index 00000000..c58e3f60 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php @@ -0,0 +1,393 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + parent::setUp(); + + // Since we test against "de_AT", we need the full implementation + IntlTestHelper::requireFullIntl($this); + + \Locale::setDefault('de_AT'); + } + + public function provideTransformations() + { + return array( + array(null, '', 'de_AT'), + array(1, '1', 'de_AT'), + array(1.5, '1,5', 'de_AT'), + array(1234.5, '1234,5', 'de_AT'), + array(12345.912, '12345,912', 'de_AT'), + array(1234.5, '1234,5', 'ru'), + array(1234.5, '1234,5', 'fi'), + ); + } + + /** + * @dataProvider provideTransformations + */ + public function testTransform($from, $to, $locale) + { + \Locale::setDefault($locale); + + $transformer = new NumberToLocalizedStringTransformer(); + + $this->assertSame($to, $transformer->transform($from)); + } + + public function provideTransformationsWithGrouping() + { + return array( + array(1234.5, '1.234,5', 'de_AT'), + array(12345.912, '12.345,912', 'de_AT'), + array(1234.5, '1 234,5', 'fr'), + array(1234.5, '1 234,5', 'ru'), + array(1234.5, '1 234,5', 'fi'), + ); + } + + /** + * @dataProvider provideTransformationsWithGrouping + */ + public function testTransformWithGrouping($from, $to, $locale) + { + \Locale::setDefault($locale); + + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $this->assertSame($to, $transformer->transform($from)); + } + + public function testTransformWithPrecision() + { + $transformer = new NumberToLocalizedStringTransformer(2); + + $this->assertEquals('1234,50', $transformer->transform(1234.5)); + $this->assertEquals('678,92', $transformer->transform(678.916)); + } + + public function testTransformWithRoundingMode() + { + $transformer = new NumberToLocalizedStringTransformer(null, null, NumberToLocalizedStringTransformer::ROUND_DOWN); + $this->assertEquals('1234,547', $transformer->transform(1234.547), '->transform() only applies rounding mode if precision set'); + + $transformer = new NumberToLocalizedStringTransformer(2, null, NumberToLocalizedStringTransformer::ROUND_DOWN); + $this->assertEquals('1234,54', $transformer->transform(1234.547), '->transform() rounding-mode works'); + + } + + /** + * @dataProvider provideTransformations + */ + public function testReverseTransform($to, $from, $locale) + { + \Locale::setDefault($locale); + + $transformer = new NumberToLocalizedStringTransformer(); + + $this->assertEquals($to, $transformer->reverseTransform($from)); + } + + /** + * @dataProvider provideTransformationsWithGrouping + */ + public function testReverseTransformWithGrouping($to, $from, $locale) + { + \Locale::setDefault($locale); + + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $this->assertEquals($to, $transformer->reverseTransform($from)); + } + + // https://github.com/symfony/symfony/issues/7609 + public function testReverseTransformWithGroupingAndFixedSpaces() + { + if (!extension_loaded('mbstring')) { + $this->markTestSkipped('The "mbstring" extension is required for this test.'); + } + + \Locale::setDefault('ru'); + + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $this->assertEquals(1234.5, $transformer->reverseTransform("1\xc2\xa0234,5")); + } + + public function testReverseTransformWithGroupingButWithoutGroupSeparator() + { + $transformer = new NumberToLocalizedStringTransformer(null, true); + + // omit group separator + $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); + $this->assertEquals(12345.912, $transformer->reverseTransform('12345,912')); + } + + public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsNotDot() + { + \Locale::setDefault('fr'); + $transformer = new NumberToLocalizedStringTransformer(null, true); + + // completely valid format + $this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5')); + // accept dots + $this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5')); + // omit group separator + $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); + $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot() + { + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $transformer->reverseTransform('1.234.5'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDotWithNoGroupSep() + { + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $transformer->reverseTransform('1234.5'); + } + + public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsDotButNoGroupingUsed() + { + \Locale::setDefault('fr'); + $transformer = new NumberToLocalizedStringTransformer(); + + $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); + $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5')); + } + + public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsNotComma() + { + \Locale::setDefault('bg'); + $transformer = new NumberToLocalizedStringTransformer(null, true); + + // completely valid format + $this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5')); + // accept commas + $this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5')); + // omit group separator + $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5')); + $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsComma() + { + \Locale::setDefault('en'); + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $transformer->reverseTransform('1,234,5'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsCommaWithNoGroupSep() + { + \Locale::setDefault('en'); + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $transformer->reverseTransform('1234,5'); + } + + public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsCommaButNoGroupingUsed() + { + \Locale::setDefault('en'); + $transformer = new NumberToLocalizedStringTransformer(); + + $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); + $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testTransformExpectsNumeric() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->transform('foo'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformExpectsString() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform(1); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformExpectsValidNumber() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform('foo'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @link https://github.com/symfony/symfony/issues/3161 + */ + public function testReverseTransformDisallowsNaN() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform('NaN'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsNaN2() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform('nan'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsInfinity() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform('∞'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsInfinity2() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform('∞,123'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsNegativeInfinity() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform('-∞'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDisallowsLeadingExtraCharacters() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform('foo123'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage The number contains unrecognized characters: "foo3" + */ + public function testReverseTransformDisallowsCenteredExtraCharacters() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform('12foo3'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage The number contains unrecognized characters: "foo8" + */ + public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte() + { + if (!extension_loaded('mbstring')) { + $this->markTestSkipped('The "mbstring" extension is required for this test.'); + } + + \Locale::setDefault('ru'); + + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $transformer->reverseTransform("12\xc2\xa0345,67foo8"); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage The number contains unrecognized characters: "foo8" + */ + public function testReverseTransformIgnoresTrailingSpacesInExceptionMessage() + { + if (!extension_loaded('mbstring')) { + $this->markTestSkipped('The "mbstring" extension is required for this test.'); + } + + \Locale::setDefault('ru'); + + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $transformer->reverseTransform("12\xc2\xa0345,67foo8 \xc2\xa0\t"); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage The number contains unrecognized characters: "foo" + */ + public function testReverseTransformDisallowsTrailingExtraCharacters() + { + $transformer = new NumberToLocalizedStringTransformer(); + + $transformer->reverseTransform('123foo'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage The number contains unrecognized characters: "foo" + */ + public function testReverseTransformDisallowsTrailingExtraCharactersMultibyte() + { + if (!extension_loaded('mbstring')) { + $this->markTestSkipped('The "mbstring" extension is required for this test.'); + } + + \Locale::setDefault('ru'); + + $transformer = new NumberToLocalizedStringTransformer(null, true); + + $transformer->reverseTransform("12\xc2\xa0345,678foo"); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php new file mode 100644 index 00000000..104941c9 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php @@ -0,0 +1,114 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\PercentToLocalizedStringTransformer; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class PercentToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + parent::setUp(); + + // Since we test against "de_AT", we need the full implementation + IntlTestHelper::requireFullIntl($this); + + \Locale::setDefault('de_AT'); + } + + public function testTransform() + { + $transformer = new PercentToLocalizedStringTransformer(); + + $this->assertEquals('10', $transformer->transform(0.1)); + $this->assertEquals('15', $transformer->transform(0.15)); + $this->assertEquals('12', $transformer->transform(0.1234)); + $this->assertEquals('200', $transformer->transform(2)); + } + + public function testTransformEmpty() + { + $transformer = new PercentToLocalizedStringTransformer(); + + $this->assertEquals('', $transformer->transform(null)); + } + + public function testTransformWithInteger() + { + $transformer = new PercentToLocalizedStringTransformer(null, 'integer'); + + $this->assertEquals('0', $transformer->transform(0.1)); + $this->assertEquals('1', $transformer->transform(1)); + $this->assertEquals('15', $transformer->transform(15)); + $this->assertEquals('16', $transformer->transform(15.9)); + } + + public function testTransformWithPrecision() + { + $transformer = new PercentToLocalizedStringTransformer(2); + + $this->assertEquals('12,34', $transformer->transform(0.1234)); + } + + public function testReverseTransform() + { + $transformer = new PercentToLocalizedStringTransformer(); + + $this->assertEquals(0.1, $transformer->reverseTransform('10')); + $this->assertEquals(0.15, $transformer->reverseTransform('15')); + $this->assertEquals(0.12, $transformer->reverseTransform('12')); + $this->assertEquals(2, $transformer->reverseTransform('200')); + } + + public function testReverseTransformEmpty() + { + $transformer = new PercentToLocalizedStringTransformer(); + + $this->assertNull($transformer->reverseTransform('')); + } + + public function testReverseTransformWithInteger() + { + $transformer = new PercentToLocalizedStringTransformer(null, 'integer'); + + $this->assertEquals(10, $transformer->reverseTransform('10')); + $this->assertEquals(15, $transformer->reverseTransform('15')); + $this->assertEquals(12, $transformer->reverseTransform('12')); + $this->assertEquals(200, $transformer->reverseTransform('200')); + } + + public function testReverseTransformWithPrecision() + { + $transformer = new PercentToLocalizedStringTransformer(2); + + $this->assertEquals(0.1234, $transformer->reverseTransform('12,34')); + } + + public function testTransformExpectsNumeric() + { + $transformer = new PercentToLocalizedStringTransformer(); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $transformer->transform('foo'); + } + + public function testReverseTransformExpectsString() + { + $transformer = new PercentToLocalizedStringTransformer(); + + $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); + + $transformer->reverseTransform(1); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ValueToDuplicatesTransformerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ValueToDuplicatesTransformerTest.php new file mode 100644 index 00000000..2c5298da --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/ValueToDuplicatesTransformerTest.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\ValueToDuplicatesTransformer; + +class ValueToDuplicatesTransformerTest extends \PHPUnit_Framework_TestCase +{ + private $transformer; + + protected function setUp() + { + $this->transformer = new ValueToDuplicatesTransformer(array('a', 'b', 'c')); + } + + protected function tearDown() + { + $this->transformer = null; + } + + public function testTransform() + { + $output = array( + 'a' => 'Foo', + 'b' => 'Foo', + 'c' => 'Foo', + ); + + $this->assertSame($output, $this->transformer->transform('Foo')); + } + + public function testTransformEmpty() + { + $output = array( + 'a' => null, + 'b' => null, + 'c' => null, + ); + + $this->assertSame($output, $this->transformer->transform(null)); + } + + public function testReverseTransform() + { + $input = array( + 'a' => 'Foo', + 'b' => 'Foo', + 'c' => 'Foo', + ); + + $this->assertSame('Foo', $this->transformer->reverseTransform($input)); + } + + public function testReverseTransformCompletelyEmpty() + { + $input = array( + 'a' => '', + 'b' => '', + 'c' => '', + ); + + $this->assertNull($this->transformer->reverseTransform($input)); + } + + public function testReverseTransformCompletelyNull() + { + $input = array( + 'a' => null, + 'b' => null, + 'c' => null, + ); + + $this->assertNull($this->transformer->reverseTransform($input)); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformPartiallyNull() + { + $input = array( + 'a' => 'Foo', + 'b' => 'Foo', + 'c' => null, + ); + + $this->transformer->reverseTransform($input); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformDifferences() + { + $input = array( + 'a' => 'Foo', + 'b' => 'Bar', + 'c' => 'Foo', + ); + + $this->transformer->reverseTransform($input); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformRequiresArray() + { + $this->transformer->reverseTransform('12345'); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php new file mode 100644 index 00000000..a5d5c78a --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixRadioInputListenerTest.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; + +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\Extension\Core\EventListener\FixRadioInputListener; +use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; + +class FixRadioInputListenerTest extends \PHPUnit_Framework_TestCase +{ + private $choiceList; + + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + parent::setUp(); + + $this->choiceList = new SimpleChoiceList(array('' => 'Empty', 0 => 'A', 1 => 'B')); + } + + protected function tearDown() + { + parent::tearDown(); + + $listener = null; + } + + public function testFixRadio() + { + $data = '1'; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $listener = new FixRadioInputListener($this->choiceList, true); + $listener->preSubmit($event); + + // Indices in SimpleChoiceList are zero-based generated integers + $this->assertEquals(array(2 => '1'), $event->getData()); + } + + public function testFixZero() + { + $data = '0'; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $listener = new FixRadioInputListener($this->choiceList, true); + $listener->preSubmit($event); + + // Indices in SimpleChoiceList are zero-based generated integers + $this->assertEquals(array(1 => '0'), $event->getData()); + } + + public function testFixEmptyString() + { + $data = ''; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $listener = new FixRadioInputListener($this->choiceList, true); + $listener->preSubmit($event); + + // Indices in SimpleChoiceList are zero-based generated integers + $this->assertEquals(array(0 => ''), $event->getData()); + } + + public function testConvertEmptyStringToPlaceholderIfNotFound() + { + $list = new SimpleChoiceList(array(0 => 'A', 1 => 'B')); + + $data = ''; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $listener = new FixRadioInputListener($list, true); + $listener->preSubmit($event); + + $this->assertEquals(array('placeholder' => ''), $event->getData()); + } + + public function testDontConvertEmptyStringToPlaceholderIfNoPlaceholderUsed() + { + $list = new SimpleChoiceList(array(0 => 'A', 1 => 'B')); + + $data = ''; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $listener = new FixRadioInputListener($list, false); + $listener->preSubmit($event); + + $this->assertEquals(array(), $event->getData()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php new file mode 100644 index 00000000..2b84e4fd --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/FixUrlProtocolListenerTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; + +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\Extension\Core\EventListener\FixUrlProtocolListener; + +class FixUrlProtocolListenerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + } + + public function testFixHttpUrl() + { + $data = "www.symfony.com"; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $filter = new FixUrlProtocolListener('http'); + $filter->onSubmit($event); + + $this->assertEquals('http://www.symfony.com', $event->getData()); + } + + public function testSkipKnownUrl() + { + $data = "http://www.symfony.com"; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $filter = new FixUrlProtocolListener('http'); + $filter->onSubmit($event); + + $this->assertEquals('http://www.symfony.com', $event->getData()); + } + + public function testSkipOtherProtocol() + { + $data = "ftp://www.symfony.com"; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $filter = new FixUrlProtocolListener('http'); + $filter->onSubmit($event); + + $this->assertEquals('ftp://www.symfony.com', $event->getData()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/Fixtures/randomhash b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/Fixtures/randomhash new file mode 100644 index 00000000..b636f4b8 Binary files /dev/null and b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/Fixtures/randomhash differ diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayObjectTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayObjectTest.php new file mode 100644 index 00000000..6f46c9d7 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayObjectTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; + +use Symfony\Component\Form\FormBuilder; + +class MergeCollectionListenerArrayObjectTest extends MergeCollectionListenerTest +{ + protected function getData(array $data) + { + return new \ArrayObject($data); + } + + protected function getBuilder($name = 'name') + { + return new FormBuilder($name, '\ArrayObject', $this->dispatcher, $this->factory); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayTest.php new file mode 100644 index 00000000..c0f3d597 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerArrayTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; + +use Symfony\Component\Form\FormBuilder; + +class MergeCollectionListenerArrayTest extends MergeCollectionListenerTest +{ + protected function getData(array $data) + { + return $data; + } + + protected function getBuilder($name = 'name') + { + return new FormBuilder($name, null, $this->dispatcher, $this->factory); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerCustomArrayObjectTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerCustomArrayObjectTest.php new file mode 100644 index 00000000..5eb6c7b9 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerCustomArrayObjectTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; + +use Symfony\Component\Form\Tests\Fixtures\CustomArrayObject; +use Symfony\Component\Form\FormBuilder; + +class MergeCollectionListenerCustomArrayObjectTest extends MergeCollectionListenerTest +{ + protected function getData(array $data) + { + return new CustomArrayObject($data); + } + + protected function getBuilder($name = 'name') + { + return new FormBuilder($name, 'Symfony\Component\Form\Tests\Fixtures\CustomArrayObject', $this->dispatcher, $this->factory); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php new file mode 100644 index 00000000..dbd28c6b --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/MergeCollectionListenerTest.php @@ -0,0 +1,259 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; + +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\Extension\Core\EventListener\MergeCollectionListener; + +abstract class MergeCollectionListenerTest extends \PHPUnit_Framework_TestCase +{ + protected $dispatcher; + protected $factory; + protected $form; + + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->factory = $this->getMock('Symfony\Component\Form\FormFactoryInterface'); + $this->form = $this->getForm('axes'); + } + + protected function tearDown() + { + $this->dispatcher = null; + $this->factory = null; + $this->form = null; + } + + abstract protected function getBuilder($name = 'name'); + + protected function getForm($name = 'name', $propertyPath = null) + { + $propertyPath = $propertyPath ?: $name; + + return $this->getBuilder($name)->setAttribute('property_path', $propertyPath)->getForm(); + } + + protected function getMockForm() + { + return $this->getMock('Symfony\Component\Form\Test\FormInterface'); + } + + public function getBooleanMatrix1() + { + return array( + array(true), + array(false), + ); + } + + public function getBooleanMatrix2() + { + return array( + array(true, true), + array(true, false), + array(false, true), + array(false, false), + ); + } + + abstract protected function getData(array $data); + + /** + * @dataProvider getBooleanMatrix1 + */ + public function testAddExtraEntriesIfAllowAdd($allowDelete) + { + $originalData = $this->getData(array(1 => 'second')); + $newData = $this->getData(array(0 => 'first', 1 => 'second', 2 => 'third')); + + $listener = new MergeCollectionListener(true, $allowDelete); + + $this->form->setData($originalData); + + $event = new FormEvent($this->form, $newData); + $listener->onSubmit($event); + + // The original object was modified + if (is_object($originalData)) { + $this->assertSame($originalData, $event->getData()); + } + + // The original object matches the new object + $this->assertEquals($newData, $event->getData()); + } + + /** + * @dataProvider getBooleanMatrix1 + */ + public function testAddExtraEntriesIfAllowAddDontOverwriteExistingIndices($allowDelete) + { + $originalData = $this->getData(array(1 => 'first')); + $newData = $this->getData(array(0 => 'first', 1 => 'second')); + + $listener = new MergeCollectionListener(true, $allowDelete); + + $this->form->setData($originalData); + + $event = new FormEvent($this->form, $newData); + $listener->onSubmit($event); + + // The original object was modified + if (is_object($originalData)) { + $this->assertSame($originalData, $event->getData()); + } + + // The original object matches the new object + $this->assertEquals($this->getData(array(1 => 'first', 2 => 'second')), $event->getData()); + } + + /** + * @dataProvider getBooleanMatrix1 + */ + public function testDoNothingIfNotAllowAdd($allowDelete) + { + $originalDataArray = array(1 => 'second'); + $originalData = $this->getData($originalDataArray); + $newData = $this->getData(array(0 => 'first', 1 => 'second', 2 => 'third')); + + $listener = new MergeCollectionListener(false, $allowDelete); + + $this->form->setData($originalData); + + $event = new FormEvent($this->form, $newData); + $listener->onSubmit($event); + + // We still have the original object + if (is_object($originalData)) { + $this->assertSame($originalData, $event->getData()); + } + + // Nothing was removed + $this->assertEquals($this->getData($originalDataArray), $event->getData()); + } + + /** + * @dataProvider getBooleanMatrix1 + */ + public function testRemoveMissingEntriesIfAllowDelete($allowAdd) + { + $originalData = $this->getData(array(0 => 'first', 1 => 'second', 2 => 'third')); + $newData = $this->getData(array(1 => 'second')); + + $listener = new MergeCollectionListener($allowAdd, true); + + $this->form->setData($originalData); + + $event = new FormEvent($this->form, $newData); + $listener->onSubmit($event); + + // The original object was modified + if (is_object($originalData)) { + $this->assertSame($originalData, $event->getData()); + } + + // The original object matches the new object + $this->assertEquals($newData, $event->getData()); + } + + /** + * @dataProvider getBooleanMatrix1 + */ + public function testDoNothingIfNotAllowDelete($allowAdd) + { + $originalDataArray = array(0 => 'first', 1 => 'second', 2 => 'third'); + $originalData = $this->getData($originalDataArray); + $newData = $this->getData(array(1 => 'second')); + + $listener = new MergeCollectionListener($allowAdd, false); + + $this->form->setData($originalData); + + $event = new FormEvent($this->form, $newData); + $listener->onSubmit($event); + + // We still have the original object + if (is_object($originalData)) { + $this->assertSame($originalData, $event->getData()); + } + + // Nothing was removed + $this->assertEquals($this->getData($originalDataArray), $event->getData()); + } + + /** + * @dataProvider getBooleanMatrix2 + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testRequireArrayOrTraversable($allowAdd, $allowDelete) + { + $newData = 'no array or traversable'; + $event = new FormEvent($this->form, $newData); + $listener = new MergeCollectionListener($allowAdd, $allowDelete); + $listener->onSubmit($event); + } + + public function testDealWithNullData() + { + $originalData = $this->getData(array(0 => 'first', 1 => 'second', 2 => 'third')); + $newData = null; + + $listener = new MergeCollectionListener(false, false); + + $this->form->setData($originalData); + + $event = new FormEvent($this->form, $newData); + $listener->onSubmit($event); + + $this->assertSame($originalData, $event->getData()); + } + + /** + * @dataProvider getBooleanMatrix1 + */ + public function testDealWithNullOriginalDataIfAllowAdd($allowDelete) + { + $originalData = null; + $newData = $this->getData(array(0 => 'first', 1 => 'second', 2 => 'third')); + + $listener = new MergeCollectionListener(true, $allowDelete); + + $this->form->setData($originalData); + + $event = new FormEvent($this->form, $newData); + $listener->onSubmit($event); + + $this->assertSame($newData, $event->getData()); + } + + /** + * @dataProvider getBooleanMatrix1 + */ + public function testDontDealWithNullOriginalDataIfNotAllowAdd($allowDelete) + { + $originalData = null; + $newData = $this->getData(array(0 => 'first', 1 => 'second', 2 => 'third')); + + $listener = new MergeCollectionListener(false, $allowDelete); + + $this->form->setData($originalData); + + $event = new FormEvent($this->form, $newData); + $listener->onSubmit($event); + + $this->assertNull($event->getData()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php new file mode 100644 index 00000000..1367b3ef --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/ResizeFormListenerTest.php @@ -0,0 +1,255 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; + +use Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener; +use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormEvent; + +class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase +{ + private $dispatcher; + private $factory; + private $form; + + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->factory = $this->getMock('Symfony\Component\Form\FormFactoryInterface'); + $this->form = $this->getBuilder() + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->getForm(); + } + + protected function tearDown() + { + $this->dispatcher = null; + $this->factory = null; + $this->form = null; + } + + protected function getBuilder($name = 'name') + { + return new FormBuilder($name, null, $this->dispatcher, $this->factory); + } + + protected function getForm($name = 'name') + { + return $this->getBuilder($name)->getForm(); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getDataMapper() + { + return $this->getMock('Symfony\Component\Form\DataMapperInterface'); + } + + protected function getMockForm() + { + return $this->getMock('Symfony\Component\Form\Test\FormInterface'); + } + + public function testPreSetDataResizesForm() + { + $this->form->add($this->getForm('0')); + $this->form->add($this->getForm('1')); + + $this->factory->expects($this->at(0)) + ->method('createNamed') + ->with(1, 'text', null, array('property_path' => '[1]', 'max_length' => 10, 'auto_initialize' => false)) + ->will($this->returnValue($this->getForm('1'))); + $this->factory->expects($this->at(1)) + ->method('createNamed') + ->with(2, 'text', null, array('property_path' => '[2]', 'max_length' => 10, 'auto_initialize' => false)) + ->will($this->returnValue($this->getForm('2'))); + + $data = array(1 => 'string', 2 => 'string'); + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array('max_length' => '10'), false, false); + $listener->preSetData($event); + + $this->assertFalse($this->form->has('0')); + $this->assertTrue($this->form->has('1')); + $this->assertTrue($this->form->has('2')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testPreSetDataRequiresArrayOrTraversable() + { + $data = 'no array or traversable'; + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, false); + $listener->preSetData($event); + } + + public function testPreSetDataDealsWithNullData() + { + $this->factory->expects($this->never())->method('createNamed'); + + $data = null; + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, false); + $listener->preSetData($event); + } + + public function testPreSubmitResizesUpIfAllowAdd() + { + $this->form->add($this->getForm('0')); + + $this->factory->expects($this->once()) + ->method('createNamed') + ->with(1, 'text', null, array('property_path' => '[1]', 'max_length' => 10, 'auto_initialize' => false)) + ->will($this->returnValue($this->getForm('1'))); + + $data = array(0 => 'string', 1 => 'string'); + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array('max_length' => 10), true, false); + $listener->preSubmit($event); + + $this->assertTrue($this->form->has('0')); + $this->assertTrue($this->form->has('1')); + } + + public function testPreSubmitResizesDownIfAllowDelete() + { + $this->form->add($this->getForm('0')); + $this->form->add($this->getForm('1')); + + $data = array(0 => 'string'); + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, true); + $listener->preSubmit($event); + + $this->assertTrue($this->form->has('0')); + $this->assertFalse($this->form->has('1')); + } + + // fix for https://github.com/symfony/symfony/pull/493 + public function testPreSubmitRemovesZeroKeys() + { + $this->form->add($this->getForm('0')); + + $data = array(); + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, true); + $listener->preSubmit($event); + + $this->assertFalse($this->form->has('0')); + } + + public function testPreSubmitDoesNothingIfNotAllowAddNorAllowDelete() + { + $this->form->add($this->getForm('0')); + $this->form->add($this->getForm('1')); + + $data = array(0 => 'string', 2 => 'string'); + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, false); + $listener->preSubmit($event); + + $this->assertTrue($this->form->has('0')); + $this->assertTrue($this->form->has('1')); + $this->assertFalse($this->form->has('2')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testPreSubmitRequiresArrayOrTraversable() + { + $data = 'no array or traversable'; + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, false); + $listener->preSubmit($event); + } + + public function testPreSubmitDealsWithNullData() + { + $this->form->add($this->getForm('1')); + + $data = null; + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, true); + $listener->preSubmit($event); + + $this->assertFalse($this->form->has('1')); + } + + // fixes https://github.com/symfony/symfony/pull/40 + public function testPreSubmitDealsWithEmptyData() + { + $this->form->add($this->getForm('1')); + + $data = ''; + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, true); + $listener->preSubmit($event); + + $this->assertFalse($this->form->has('1')); + } + + public function testOnSubmitNormDataRemovesEntriesMissingInTheFormIfAllowDelete() + { + $this->form->add($this->getForm('1')); + + $data = array(0 => 'first', 1 => 'second', 2 => 'third'); + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, true); + $listener->onSubmit($event); + + $this->assertEquals(array(1 => 'second'), $event->getData()); + } + + public function testOnSubmitNormDataDoesNothingIfNotAllowDelete() + { + $this->form->add($this->getForm('1')); + + $data = array(0 => 'first', 1 => 'second', 2 => 'third'); + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, false); + $listener->onSubmit($event); + + $this->assertEquals($data, $event->getData()); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testOnSubmitNormDataRequiresArrayOrTraversable() + { + $data = 'no array or traversable'; + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, false); + $listener->onSubmit($event); + } + + public function testOnSubmitNormDataDealsWithNullData() + { + $this->form->add($this->getForm('1')); + + $data = null; + $event = new FormEvent($this->form, $data); + $listener = new ResizeFormListener('text', array(), false, true); + $listener->onSubmit($event); + + $this->assertEquals(array(), $event->getData()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php new file mode 100644 index 00000000..4e368933 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\EventListener; + +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\Extension\Core\EventListener\TrimListener; + +class TrimListenerTest extends \PHPUnit_Framework_TestCase +{ + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + } + + public function testTrim() + { + $data = " Foo! "; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $filter = new TrimListener(); + $filter->preSubmit($event); + + $this->assertEquals('Foo!', $event->getData()); + } + + public function testTrimSkipNonStrings() + { + $data = 1234; + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $filter = new TrimListener(); + $filter->preSubmit($event); + + $this->assertSame(1234, $event->getData()); + } + + /** + * @dataProvider codePointProvider + */ + public function testTrimUtf8($chars) + { + if (!function_exists('mb_check_encoding')) { + $this->markTestSkipped('The "mb_check_encoding" function is not available'); + } + + $data = mb_convert_encoding(pack('H*', implode('', $chars)), 'UTF-8', 'UCS-2BE'); + $data = $data."ab\ncd".$data; + + $form = $this->getMock('Symfony\Component\Form\Test\FormInterface'); + $event = new FormEvent($form, $data); + + $filter = new TrimListener(); + $filter->preSubmit($event); + + $this->assertSame("ab\ncd", $event->getData(), 'TrimListener should trim character(s): '.implode(', ', $chars)); + } + + public function codePointProvider() + { + return array( + 'General category: Separator' => array(array('0020', '00A0', '1680', '180E', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '200A', '2028', '2029', '202F', '205F', '3000')), + 'General category: Other, control' => array(array('0009', '000A', '000B', '000C', '000D', '0085')), + //'General category: Other, format. ZERO WIDTH SPACE' => array(array('200B')), + ); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/BaseTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/BaseTypeTest.php new file mode 100644 index 00000000..bfa1e218 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/BaseTypeTest.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +/** + * @author Bernhard Schussek + */ +abstract class BaseTypeTest extends \Symfony\Component\Form\Test\TypeTestCase +{ + public function testPassDisabledAsOption() + { + $form = $this->factory->create($this->getTestedType(), null, array('disabled' => true)); + + $this->assertTrue($form->isDisabled()); + } + + public function testPassIdAndNameToView() + { + $view = $this->factory->createNamed('name', $this->getTestedType()) + ->createView(); + + $this->assertEquals('name', $view->vars['id']); + $this->assertEquals('name', $view->vars['name']); + $this->assertEquals('name', $view->vars['full_name']); + } + + public function testStripLeadingUnderscoresAndDigitsFromId() + { + $view = $this->factory->createNamed('_09name', $this->getTestedType()) + ->createView(); + + $this->assertEquals('name', $view->vars['id']); + $this->assertEquals('_09name', $view->vars['name']); + $this->assertEquals('_09name', $view->vars['full_name']); + } + + public function testPassIdAndNameToViewWithParent() + { + $view = $this->factory->createNamedBuilder('parent', 'form') + ->add('child', $this->getTestedType()) + ->getForm() + ->createView(); + + $this->assertEquals('parent_child', $view['child']->vars['id']); + $this->assertEquals('child', $view['child']->vars['name']); + $this->assertEquals('parent[child]', $view['child']->vars['full_name']); + } + + public function testPassIdAndNameToViewWithGrandParent() + { + $builder = $this->factory->createNamedBuilder('parent', 'form') + ->add('child', 'form'); + $builder->get('child')->add('grand_child', $this->getTestedType()); + $view = $builder->getForm()->createView(); + + $this->assertEquals('parent_child_grand_child', $view['child']['grand_child']->vars['id']); + $this->assertEquals('grand_child', $view['child']['grand_child']->vars['name']); + $this->assertEquals('parent[child][grand_child]', $view['child']['grand_child']->vars['full_name']); + } + + public function testPassTranslationDomainToView() + { + $form = $this->factory->create($this->getTestedType(), null, array( + 'translation_domain' => 'domain', + )); + $view = $form->createView(); + + $this->assertSame('domain', $view->vars['translation_domain']); + } + + public function testInheritTranslationDomainFromParent() + { + $view = $this->factory + ->createNamedBuilder('parent', 'form', null, array( + 'translation_domain' => 'domain', + )) + ->add('child', $this->getTestedType()) + ->getForm() + ->createView(); + + $this->assertEquals('domain', $view['child']->vars['translation_domain']); + } + + public function testPreferOwnTranslationDomain() + { + $view = $this->factory + ->createNamedBuilder('parent', 'form', null, array( + 'translation_domain' => 'parent_domain', + )) + ->add('child', $this->getTestedType(), array( + 'translation_domain' => 'domain', + )) + ->getForm() + ->createView(); + + $this->assertEquals('domain', $view['child']->vars['translation_domain']); + } + + public function testDefaultTranslationDomain() + { + $view = $this->factory->createNamedBuilder('parent', 'form') + ->add('child', $this->getTestedType()) + ->getForm() + ->createView(); + + $this->assertEquals('messages', $view['child']->vars['translation_domain']); + } + + public function testPassLabelToView() + { + $form = $this->factory->createNamed('__test___field', $this->getTestedType(), null, array('label' => 'My label')); + $view = $form->createView(); + + $this->assertSame('My label', $view->vars['label']); + } + + public function testPassMultipartFalseToView() + { + $form = $this->factory->create($this->getTestedType()); + $view = $form->createView(); + + $this->assertFalse($view->vars['multipart']); + } + + abstract protected function getTestedType(); +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ButtonTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ButtonTypeTest.php new file mode 100644 index 00000000..55835e77 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ButtonTypeTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +/** + * @author Bernhard Schussek + */ +class ButtonTypeTest extends BaseTypeTest +{ + public function testCreateButtonInstances() + { + $this->assertInstanceOf('Symfony\Component\Form\Button', $this->factory->create('button')); + } + + protected function getTestedType() + { + return 'button'; + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php new file mode 100644 index 00000000..c782adab --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CheckboxTypeTest.php @@ -0,0 +1,162 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\CallbackTransformer; + +class CheckboxTypeTest extends \Symfony\Component\Form\Test\TypeTestCase +{ + public function testPassValueToView() + { + $form = $this->factory->create('checkbox', null, array('value' => 'foobar')); + $view = $form->createView(); + + $this->assertEquals('foobar', $view->vars['value']); + } + + public function testCheckedIfDataTrue() + { + $form = $this->factory->create('checkbox'); + $form->setData(true); + $view = $form->createView(); + + $this->assertTrue($view->vars['checked']); + } + + public function testCheckedIfDataTrueWithEmptyValue() + { + $form = $this->factory->create('checkbox', null, array('value' => '')); + $form->setData(true); + $view = $form->createView(); + + $this->assertTrue($view->vars['checked']); + } + + public function testNotCheckedIfDataFalse() + { + $form = $this->factory->create('checkbox'); + $form->setData(false); + $view = $form->createView(); + + $this->assertFalse($view->vars['checked']); + } + + public function testSubmitWithValueChecked() + { + $form = $this->factory->create('checkbox', null, array( + 'value' => 'foobar', + )); + $form->submit('foobar'); + + $this->assertTrue($form->getData()); + $this->assertEquals('foobar', $form->getViewData()); + } + + public function testSubmitWithRandomValueChecked() + { + $form = $this->factory->create('checkbox', null, array( + 'value' => 'foobar', + )); + $form->submit('krixikraxi'); + + $this->assertTrue($form->getData()); + $this->assertEquals('foobar', $form->getViewData()); + } + + public function testSubmitWithValueUnchecked() + { + $form = $this->factory->create('checkbox', null, array( + 'value' => 'foobar', + )); + $form->submit(null); + + $this->assertFalse($form->getData()); + $this->assertNull($form->getViewData()); + } + + public function testSubmitWithEmptyValueChecked() + { + $form = $this->factory->create('checkbox', null, array( + 'value' => '', + )); + $form->submit(''); + + $this->assertTrue($form->getData()); + $this->assertSame('', $form->getViewData()); + } + + public function testSubmitWithEmptyValueUnchecked() + { + $form = $this->factory->create('checkbox', null, array( + 'value' => '', + )); + $form->submit(null); + + $this->assertFalse($form->getData()); + $this->assertNull($form->getViewData()); + } + + public function testBindWithEmptyValueAndFalseUnchecked() + { + $form = $this->factory->create('checkbox', null, array( + 'value' => '', + )); + $form->bind(false); + + $this->assertFalse($form->getData()); + $this->assertNull($form->getViewData()); + } + + public function testBindWithEmptyValueAndTrueChecked() + { + $form = $this->factory->create('checkbox', null, array( + 'value' => '', + )); + $form->bind(true); + + $this->assertTrue($form->getData()); + $this->assertSame('', $form->getViewData()); + } + + /** + * @dataProvider provideTransformedData + */ + public function testTransformedData($data, $expected) + { + // present a binary status field as a checkbox + $transformer = new CallbackTransformer( + function ($value) { + return 'expedited' == $value; + }, + function ($value) { + return $value ? 'expedited' : 'standard'; + } + ); + + $form = $this->builder + ->create('expedited_shipping', 'checkbox') + ->addModelTransformer($transformer) + ->getForm(); + $form->setData($data); + $view = $form->createView(); + + $this->assertEquals($expected, $view->vars['checked']); + } + + public function provideTransformedData() + { + return array( + array('expedited', true), + array('standard', false), + ); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php new file mode 100644 index 00000000..0685946f --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypePerformanceTest.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Test\FormPerformanceTestCase; + +/** + * @author Bernhard Schussek + */ +class ChoiceTypePerformanceTest extends FormPerformanceTestCase +{ + /** + * This test case is realistic in collection forms where each + * row contains the same choice field. + * + * @group benchmark + */ + public function testSameChoiceFieldCreatedMultipleTimes() + { + $this->setMaxRunningTime(1); + $choices = range(1, 300); + + for ($i = 0; $i < 100; ++$i) { + $this->factory->create('choice', rand(1, 400), array( + 'choices' => $choices, + )); + } + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php new file mode 100644 index 00000000..219e8181 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -0,0 +1,949 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList; +use Symfony\Component\Form\Extension\Core\View\ChoiceView; + +class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase +{ + private $choices = array( + 'a' => 'Bernhard', + 'b' => 'Fabien', + 'c' => 'Kris', + 'd' => 'Jon', + 'e' => 'Roman', + ); + + private $numericChoices = array( + 0 => 'Bernhard', + 1 => 'Fabien', + 2 => 'Kris', + 3 => 'Jon', + 4 => 'Roman', + ); + + private $objectChoices; + + protected $groupedChoices = array( + 'Symfony' => array( + 'a' => 'Bernhard', + 'b' => 'Fabien', + 'c' => 'Kris', + ), + 'Doctrine' => array( + 'd' => 'Jon', + 'e' => 'Roman', + ) + ); + + protected function setUp() + { + parent::setUp(); + + $this->objectChoices = array( + (object) array('id' => 1, 'name' => 'Bernhard'), + (object) array('id' => 2, 'name' => 'Fabien'), + (object) array('id' => 3, 'name' => 'Kris'), + (object) array('id' => 4, 'name' => 'Jon'), + (object) array('id' => 5, 'name' => 'Roman'), + ); + } + + protected function tearDown() + { + parent::tearDown(); + + $this->objectChoices = null; + } + + /** + * @expectedException \PHPUnit_Framework_Error + */ + public function testChoicesOptionExpectsArray() + { + $this->factory->create('choice', null, array( + 'choices' => new \ArrayObject(), + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testChoiceListOptionExpectsChoiceListInterface() + { + $this->factory->create('choice', null, array( + 'choice_list' => array('foo' => 'foo'), + )); + } + + public function testChoiceListAndChoicesCanBeEmpty() + { + $this->factory->create('choice'); + } + + public function testExpandedChoicesOptionsTurnIntoChildren() + { + $form = $this->factory->create('choice', null, array( + 'expanded' => true, + 'choices' => $this->choices, + )); + + $this->assertCount(count($this->choices), $form, 'Each choice should become a new field'); + } + + public function testPlaceholderPresentOnNonRequiredExpandedSingleChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => false, + 'choices' => $this->choices, + )); + + $this->assertTrue(isset($form['placeholder'])); + $this->assertCount(count($this->choices) + 1, $form, 'Each choice should become a new field'); + } + + public function testPlaceholderNotPresentIfRequired() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => true, + 'choices' => $this->choices, + )); + + $this->assertFalse(isset($form['placeholder'])); + $this->assertCount(count($this->choices), $form, 'Each choice should become a new field'); + } + + public function testPlaceholderNotPresentIfMultiple() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => true, + 'required' => false, + 'choices' => $this->choices, + )); + + $this->assertFalse(isset($form['placeholder'])); + $this->assertCount(count($this->choices), $form, 'Each choice should become a new field'); + } + + public function testPlaceholderNotPresentIfEmptyChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => false, + 'choices' => array( + '' => 'Empty', + 1 => 'Not empty', + ), + )); + + $this->assertFalse(isset($form['placeholder'])); + $this->assertCount(2, $form, 'Each choice should become a new field'); + } + + public function testExpandedChoicesOptionsAreFlattened() + { + $form = $this->factory->create('choice', null, array( + 'expanded' => true, + 'choices' => $this->groupedChoices, + )); + + $flattened = array(); + foreach ($this->groupedChoices as $choices) { + $flattened = array_merge($flattened, array_keys($choices)); + } + + $this->assertCount($form->count(), $flattened, 'Each nested choice should become a new field, not the groups'); + + foreach ($flattened as $value => $choice) { + $this->assertTrue($form->has($value), 'Flattened choice is named after it\'s value'); + } + } + + public function testExpandedCheckboxesAreNeverRequired() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => true, + 'required' => true, + 'choices' => $this->choices, + )); + + foreach ($form as $child) { + $this->assertFalse($child->isRequired()); + } + } + + public function testExpandedRadiosAreRequiredIfChoiceChildIsRequired() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => true, + 'choices' => $this->choices, + )); + + foreach ($form as $child) { + $this->assertTrue($child->isRequired()); + } + } + + public function testExpandedRadiosAreNotRequiredIfChoiceChildIsNotRequired() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => false, + 'choices' => $this->choices, + )); + + foreach ($form as $child) { + $this->assertFalse($child->isRequired()); + } + } + + public function testSubmitSingleNonExpanded() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => false, + 'choices' => $this->choices, + )); + + $form->submit('b'); + + $this->assertEquals('b', $form->getData()); + $this->assertEquals('b', $form->getViewData()); + } + + public function testSubmitSingleNonExpandedObjectChoices() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => false, + 'choice_list' => new ObjectChoiceList( + $this->objectChoices, + // label path + 'name', + array(), + null, + // value path + 'id' + ), + )); + + // "id" value of the second entry + $form->submit('2'); + + $this->assertEquals($this->objectChoices[1], $form->getData()); + $this->assertEquals('2', $form->getViewData()); + } + + public function testSubmitMultipleNonExpanded() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => false, + 'choices' => $this->choices, + )); + + $form->submit(array('a', 'b')); + + $this->assertEquals(array('a', 'b'), $form->getData()); + $this->assertEquals(array('a', 'b'), $form->getViewData()); + } + + public function testSubmitMultipleNonExpandedObjectChoices() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => false, + 'choice_list' => new ObjectChoiceList( + $this->objectChoices, + // label path + 'name', + array(), + null, + // value path + 'id' + ), + )); + + $form->submit(array('2', '3')); + + $this->assertEquals(array($this->objectChoices[1], $this->objectChoices[2]), $form->getData()); + $this->assertEquals(array('2', '3'), $form->getViewData()); + } + + public function testSubmitSingleExpandedRequired() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => true, + 'choices' => $this->choices, + )); + + $form->submit('b'); + + $this->assertSame('b', $form->getData()); + $this->assertSame(array( + 0 => false, + 1 => true, + 2 => false, + 3 => false, + 4 => false, + ), $form->getViewData()); + + $this->assertFalse($form[0]->getData()); + $this->assertTrue($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertSame('b', $form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitSingleExpandedNonRequired() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => false, + 'choices' => $this->choices, + )); + + $form->submit('b'); + + $this->assertSame('b', $form->getData()); + $this->assertSame(array( + 0 => false, + 1 => true, + 2 => false, + 3 => false, + 4 => false, + 'placeholder' => false, + ), $form->getViewData()); + + $this->assertFalse($form['placeholder']->getData()); + $this->assertFalse($form[0]->getData()); + $this->assertTrue($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form['placeholder']->getViewData()); + $this->assertNull($form[0]->getViewData()); + $this->assertSame('b', $form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitSingleExpandedRequiredNothingChecked() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => true, + 'choices' => $this->choices, + )); + + $form->submit(null); + + $this->assertNull($form->getData()); + $this->assertSame(array( + 0 => false, + 1 => false, + 2 => false, + 3 => false, + 4 => false, + ), $form->getViewData()); + + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitSingleExpandedNonRequiredNothingChecked() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => false, + 'choices' => $this->choices, + )); + + $form->submit(null); + + $this->assertNull($form->getData()); + $this->assertSame(array( + 0 => false, + 1 => false, + 2 => false, + 3 => false, + 4 => false, + 'placeholder' => true, + ), $form->getViewData()); + + $this->assertTrue($form['placeholder']->getData()); + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertSame('', $form['placeholder']->getViewData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitFalseToSingleExpandedRequiredDoesNotProduceExtraChildrenError() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => true, + 'choices' => $this->choices, + )); + + $form->submit(false); + + $this->assertEmpty($form->getExtraData()); + $this->assertNull($form->getData()); + } + + public function testSubmitFalseToSingleExpandedNonRequiredDoesNotProduceExtraChildrenError() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'required' => false, + 'choices' => $this->choices, + )); + + $form->submit(false); + + $this->assertEmpty($form->getExtraData()); + $this->assertNull($form->getData()); + } + + public function testSubmitSingleExpandedWithEmptyChild() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'choices' => array( + '' => 'Empty', + 1 => 'Not empty', + ), + )); + + $form->submit(''); + + $this->assertNull($form->getData()); + $this->assertTrue($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertSame('', $form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + } + + public function testSubmitSingleExpandedObjectChoices() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'choice_list' => new ObjectChoiceList( + $this->objectChoices, + // label path + 'name', + array(), + null, + // value path + 'id' + ), + )); + + $form->submit('2'); + + $this->assertSame($this->objectChoices[1], $form->getData()); + $this->assertFalse($form[0]->getData()); + $this->assertTrue($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertSame('2', $form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitSingleExpandedNumericChoices() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => true, + 'choices' => $this->numericChoices, + )); + + $form->submit('1'); + + $this->assertSame(1, $form->getData()); + $this->assertFalse($form[0]->getData()); + $this->assertTrue($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertSame('1', $form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitMultipleExpanded() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => true, + 'choices' => $this->choices, + )); + + $form->submit(array('a', 'c')); + + $this->assertSame(array('a', 'c'), $form->getData()); + $this->assertTrue($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertTrue($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertSame('a', $form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertSame('c', $form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitMultipleExpandedEmpty() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => true, + 'choices' => $this->choices, + )); + + $form->submit(array()); + + $this->assertSame(array(), $form->getData()); + $this->assertFalse($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitMultipleExpandedWithEmptyChild() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => true, + 'choices' => array( + '' => 'Empty', + 1 => 'Not Empty', + 2 => 'Not Empty 2', + ) + )); + + $form->submit(array('', '2')); + + $this->assertSame(array('', 2), $form->getData()); + $this->assertTrue($form[0]->getData()); + $this->assertFalse($form[1]->getData()); + $this->assertTrue($form[2]->getData()); + $this->assertSame('', $form[0]->getViewData()); + $this->assertNull($form[1]->getViewData()); + $this->assertSame('2', $form[2]->getViewData()); + } + + public function testSubmitMultipleExpandedObjectChoices() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => true, + 'choice_list' => new ObjectChoiceList( + $this->objectChoices, + // label path + 'name', + array(), + null, + // value path + 'id' + ), + )); + + $form->submit(array('1', '2')); + + $this->assertSame(array($this->objectChoices[0], $this->objectChoices[1]), $form->getData()); + $this->assertTrue($form[0]->getData()); + $this->assertTrue($form[1]->getData()); + $this->assertFalse($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertSame('1', $form[0]->getViewData()); + $this->assertSame('2', $form[1]->getViewData()); + $this->assertNull($form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + public function testSubmitMultipleExpandedNumericChoices() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => true, + 'choices' => $this->numericChoices, + )); + + $form->submit(array('1', '2')); + + $this->assertSame(array(1, 2), $form->getData()); + $this->assertFalse($form[0]->getData()); + $this->assertTrue($form[1]->getData()); + $this->assertTrue($form[2]->getData()); + $this->assertFalse($form[3]->getData()); + $this->assertFalse($form[4]->getData()); + $this->assertNull($form[0]->getViewData()); + $this->assertSame('1', $form[1]->getViewData()); + $this->assertSame('2', $form[2]->getViewData()); + $this->assertNull($form[3]->getViewData()); + $this->assertNull($form[4]->getViewData()); + } + + /* + * We need this functionality to create choice fields for Boolean types, + * e.g. false => 'No', true => 'Yes' + */ + public function testSetDataSingleNonExpandedAcceptsBoolean() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => false, + 'choices' => $this->numericChoices, + )); + + $form->setData(false); + + $this->assertFalse($form->getData()); + $this->assertEquals('0', $form->getViewData()); + } + + public function testSetDataMultipleNonExpandedAcceptsBoolean() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'expanded' => false, + 'choices' => $this->numericChoices, + )); + + $form->setData(array(false, true)); + + $this->assertEquals(array(false, true), $form->getData()); + $this->assertEquals(array('0', '1'), $form->getViewData()); + } + + public function testPassRequiredToView() + { + $form = $this->factory->create('choice', null, array( + 'choices' => $this->choices, + )); + $view = $form->createView(); + + $this->assertTrue($view->vars['required']); + } + + public function testPassNonRequiredToView() + { + $form = $this->factory->create('choice', null, array( + 'required' => false, + 'choices' => $this->choices, + )); + $view = $form->createView(); + + $this->assertFalse($view->vars['required']); + } + + public function testPassMultipleToView() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => true, + 'choices' => $this->choices, + )); + $view = $form->createView(); + + $this->assertTrue($view->vars['multiple']); + } + + public function testPassExpandedToView() + { + $form = $this->factory->create('choice', null, array( + 'expanded' => true, + 'choices' => $this->choices, + )); + $view = $form->createView(); + + $this->assertTrue($view->vars['expanded']); + } + + public function testEmptyValueIsNullByDefaultIfRequired() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'required' => true, + 'choices' => $this->choices, + )); + $view = $form->createView(); + + $this->assertNull($view->vars['empty_value']); + } + + public function testEmptyValueIsEmptyStringByDefaultIfNotRequired() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'required' => false, + 'choices' => $this->choices, + )); + $view = $form->createView(); + + $this->assertSame('', $view->vars['empty_value']); + } + + /** + * @dataProvider getOptionsWithEmptyValue + */ + public function testPassEmptyValueToView($multiple, $expanded, $required, $emptyValue, $viewValue) + { + $form = $this->factory->create('choice', null, array( + 'multiple' => $multiple, + 'expanded' => $expanded, + 'required' => $required, + 'empty_value' => $emptyValue, + 'choices' => $this->choices, + )); + $view = $form->createView(); + + $this->assertEquals($viewValue, $view->vars['empty_value']); + } + + /** + * @dataProvider getOptionsWithEmptyValue + */ + public function testDontPassEmptyValueIfContainedInChoices($multiple, $expanded, $required, $emptyValue, $viewValue) + { + $form = $this->factory->create('choice', null, array( + 'multiple' => $multiple, + 'expanded' => $expanded, + 'required' => $required, + 'empty_value' => $emptyValue, + 'choices' => array('a' => 'A', '' => 'Empty'), + )); + $view = $form->createView(); + + $this->assertNull($view->vars['empty_value']); + } + + public function getOptionsWithEmptyValue() + { + return array( + // single non-expanded + array(false, false, false, 'foobar', 'foobar'), + array(false, false, false, '', ''), + array(false, false, false, null, null), + array(false, false, false, false, null), + array(false, false, true, 'foobar', 'foobar'), + array(false, false, true, '', ''), + array(false, false, true, null, null), + array(false, false, true, false, null), + // single expanded + array(false, true, false, 'foobar', 'foobar'), + // radios should never have an empty label + array(false, true, false, '', 'None'), + array(false, true, false, null, null), + array(false, true, false, false, null), + array(false, true, true, 'foobar', 'foobar'), + // radios should never have an empty label + array(false, true, true, '', 'None'), + array(false, true, true, null, null), + array(false, true, true, false, null), + // multiple non-expanded + array(true, false, false, 'foobar', null), + array(true, false, false, '', null), + array(true, false, false, null, null), + array(true, false, false, false, null), + array(true, false, true, 'foobar', null), + array(true, false, true, '', null), + array(true, false, true, null, null), + array(true, false, true, false, null), + // multiple expanded + array(true, true, false, 'foobar', null), + array(true, true, false, '', null), + array(true, true, false, null, null), + array(true, true, false, false, null), + array(true, true, true, 'foobar', null), + array(true, true, true, '', null), + array(true, true, true, null, null), + array(true, true, true, false, null), + ); + } + + public function testPassChoicesToView() + { + $choices = array('a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D'); + $form = $this->factory->create('choice', null, array( + 'choices' => $choices, + )); + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('a', 'a', 'A'), + new ChoiceView('b', 'b', 'B'), + new ChoiceView('c', 'c', 'C'), + new ChoiceView('d', 'd', 'D'), + ), $view->vars['choices']); + } + + public function testPassPreferredChoicesToView() + { + $choices = array('a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D'); + $form = $this->factory->create('choice', null, array( + 'choices' => $choices, + 'preferred_choices' => array('b', 'd'), + )); + $view = $form->createView(); + + $this->assertEquals(array( + 0 => new ChoiceView('a', 'a', 'A'), + 2 => new ChoiceView('c', 'c', 'C'), + ), $view->vars['choices']); + $this->assertEquals(array( + 1 => new ChoiceView('b', 'b', 'B'), + 3 => new ChoiceView('d', 'd', 'D'), + ), $view->vars['preferred_choices']); + } + + public function testPassHierarchicalChoicesToView() + { + $form = $this->factory->create('choice', null, array( + 'choices' => $this->groupedChoices, + 'preferred_choices' => array('b', 'd'), + )); + $view = $form->createView(); + + $this->assertEquals(array( + 'Symfony' => array( + 0 => new ChoiceView('a', 'a', 'Bernhard'), + 2 => new ChoiceView('c', 'c', 'Kris'), + ), + 'Doctrine' => array( + 4 => new ChoiceView('e', 'e', 'Roman'), + ), + ), $view->vars['choices']); + $this->assertEquals(array( + 'Symfony' => array( + 1 => new ChoiceView('b', 'b', 'Fabien'), + ), + 'Doctrine' => array( + 3 => new ChoiceView('d', 'd', 'Jon'), + ), + ), $view->vars['preferred_choices']); + } + + public function testPassChoiceDataToView() + { + $obj1 = (object) array('value' => 'a', 'label' => 'A'); + $obj2 = (object) array('value' => 'b', 'label' => 'B'); + $obj3 = (object) array('value' => 'c', 'label' => 'C'); + $obj4 = (object) array('value' => 'd', 'label' => 'D'); + $form = $this->factory->create('choice', null, array( + 'choice_list' => new ObjectChoiceList(array($obj1, $obj2, $obj3, $obj4), 'label', array(), null, 'value'), + )); + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView($obj1, 'a', 'A'), + new ChoiceView($obj2, 'b', 'B'), + new ChoiceView($obj3, 'c', 'C'), + new ChoiceView($obj4, 'd', 'D'), + ), $view->vars['choices']); + } + + public function testAdjustFullNameForMultipleNonExpanded() + { + $form = $this->factory->createNamed('name', 'choice', null, array( + 'multiple' => true, + 'expanded' => false, + 'choices' => $this->choices, + )); + $view = $form->createView(); + + $this->assertSame('name[]', $view->vars['full_name']); + } + + // https://github.com/symfony/symfony/issues/3298 + public function testInitializeWithEmptyChoices() + { + $this->factory->createNamed('name', 'choice', null, array( + 'choices' => array(), + )); + } + + public function testInitializeWithDefaultObjectChoice() + { + $obj1 = (object) array('value' => 'a', 'label' => 'A'); + $obj2 = (object) array('value' => 'b', 'label' => 'B'); + $obj3 = (object) array('value' => 'c', 'label' => 'C'); + $obj4 = (object) array('value' => 'd', 'label' => 'D'); + + $form = $this->factory->create('choice', null, array( + 'choice_list' => new ObjectChoiceList(array($obj1, $obj2, $obj3, $obj4), 'label', array(), null, 'value'), + // Used to break because "data_class" was inferred, which needs to + // remain null in every case (because it refers to the view format) + 'data' => $obj3, + )); + + // Trigger data initialization + $form->getViewData(); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php new file mode 100644 index 00000000..be3ad9db --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CollectionTypeTest.php @@ -0,0 +1,200 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Form; + +class CollectionTypeTest extends \Symfony\Component\Form\Test\TypeTestCase +{ + public function testContainsNoChildByDefault() + { + $form = $this->factory->create('collection', null, array( + 'type' => 'text', + )); + + $this->assertCount(0, $form); + } + + public function testSetDataAdjustsSize() + { + $form = $this->factory->create('collection', null, array( + 'type' => 'text', + 'options' => array( + 'max_length' => 20, + ), + )); + $form->setData(array('foo@foo.com', 'foo@bar.com')); + + $this->assertInstanceOf('Symfony\Component\Form\Form', $form[0]); + $this->assertInstanceOf('Symfony\Component\Form\Form', $form[1]); + $this->assertCount(2, $form); + $this->assertEquals('foo@foo.com', $form[0]->getData()); + $this->assertEquals('foo@bar.com', $form[1]->getData()); + $this->assertEquals(20, $form[0]->getConfig()->getOption('max_length')); + $this->assertEquals(20, $form[1]->getConfig()->getOption('max_length')); + + $form->setData(array('foo@baz.com')); + $this->assertInstanceOf('Symfony\Component\Form\Form', $form[0]); + $this->assertFalse(isset($form[1])); + $this->assertCount(1, $form); + $this->assertEquals('foo@baz.com', $form[0]->getData()); + $this->assertEquals(20, $form[0]->getConfig()->getOption('max_length')); + } + + public function testThrowsExceptionIfObjectIsNotTraversable() + { + $form = $this->factory->create('collection', null, array( + 'type' => 'text', + )); + $this->setExpectedException('Symfony\Component\Form\Exception\UnexpectedTypeException'); + $form->setData(new \stdClass()); + } + + public function testNotResizedIfSubmittedWithMissingData() + { + $form = $this->factory->create('collection', null, array( + 'type' => 'text', + )); + $form->setData(array('foo@foo.com', 'bar@bar.com')); + $form->submit(array('foo@bar.com')); + + $this->assertTrue($form->has('0')); + $this->assertTrue($form->has('1')); + $this->assertEquals('foo@bar.com', $form[0]->getData()); + $this->assertEquals('', $form[1]->getData()); + } + + public function testResizedDownIfSubmittedWithMissingDataAndAllowDelete() + { + $form = $this->factory->create('collection', null, array( + 'type' => 'text', + 'allow_delete' => true, + )); + $form->setData(array('foo@foo.com', 'bar@bar.com')); + $form->submit(array('foo@foo.com')); + + $this->assertTrue($form->has('0')); + $this->assertFalse($form->has('1')); + $this->assertEquals('foo@foo.com', $form[0]->getData()); + $this->assertEquals(array('foo@foo.com'), $form->getData()); + } + + public function testNotResizedIfSubmittedWithExtraData() + { + $form = $this->factory->create('collection', null, array( + 'type' => 'text', + )); + $form->setData(array('foo@bar.com')); + $form->submit(array('foo@foo.com', 'bar@bar.com')); + + $this->assertTrue($form->has('0')); + $this->assertFalse($form->has('1')); + $this->assertEquals('foo@foo.com', $form[0]->getData()); + } + + public function testResizedUpIfSubmittedWithExtraDataAndAllowAdd() + { + $form = $this->factory->create('collection', null, array( + 'type' => 'text', + 'allow_add' => true, + )); + $form->setData(array('foo@bar.com')); + $form->submit(array('foo@bar.com', 'bar@bar.com')); + + $this->assertTrue($form->has('0')); + $this->assertTrue($form->has('1')); + $this->assertEquals('foo@bar.com', $form[0]->getData()); + $this->assertEquals('bar@bar.com', $form[1]->getData()); + $this->assertEquals(array('foo@bar.com', 'bar@bar.com'), $form->getData()); + } + + public function testAllowAddButNoPrototype() + { + $form = $this->factory->create('collection', null, array( + 'type' => 'form', + 'allow_add' => true, + 'prototype' => false, + )); + + $this->assertFalse($form->has('__name__')); + } + + public function testPrototypeMultipartPropagation() + { + $form = $this->factory + ->create('collection', null, array( + 'type' => 'file', + 'allow_add' => true, + 'prototype' => true, + )) + ; + + $this->assertTrue($form->createView()->vars['multipart']); + } + + public function testGetDataDoesNotContainsPrototypeNameBeforeDataAreSet() + { + $form = $this->factory->create('collection', array(), array( + 'type' => 'file', + 'prototype' => true, + 'allow_add' => true, + )); + + $data = $form->getData(); + $this->assertFalse(isset($data['__name__'])); + } + + public function testGetDataDoesNotContainsPrototypeNameAfterDataAreSet() + { + $form = $this->factory->create('collection', array(), array( + 'type' => 'file', + 'allow_add' => true, + 'prototype' => true, + )); + + $form->setData(array('foobar.png')); + $data = $form->getData(); + $this->assertFalse(isset($data['__name__'])); + } + + public function testPrototypeNameOption() + { + $form = $this->factory->create('collection', null, array( + 'type' => 'form', + 'prototype' => true, + 'allow_add' => true, + )); + + $this->assertSame('__name__', $form->getConfig()->getAttribute('prototype')->getName(), '__name__ is the default'); + + $form = $this->factory->create('collection', null, array( + 'type' => 'form', + 'prototype' => true, + 'allow_add' => true, + 'prototype_name' => '__test__', + )); + + $this->assertSame('__test__', $form->getConfig()->getAttribute('prototype')->getName()); + } + + public function testPrototypeDefaultLabel() + { + $form = $this->factory->create('collection', array(), array( + 'type' => 'file', + 'allow_add' => true, + 'prototype' => true, + 'prototype_name' => '__test__', + )); + + $this->assertSame('__test__label__', $form->createView()->vars['prototype']->vars['label']); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php new file mode 100644 index 00000000..1d56e2a0 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class CountryTypeTest extends TypeTestCase +{ + protected function setUp() + { + IntlTestHelper::requireIntl($this); + + parent::setUp(); + } + + public function testCountriesAreSelectable() + { + $form = $this->factory->create('country'); + $view = $form->createView(); + $choices = $view->vars['choices']; + + // Don't check objects for identity + $this->assertContains(new ChoiceView('DE', 'DE', 'Germany'), $choices, '', false, false); + $this->assertContains(new ChoiceView('GB', 'GB', 'United Kingdom'), $choices, '', false, false); + $this->assertContains(new ChoiceView('US', 'US', 'United States'), $choices, '', false, false); + $this->assertContains(new ChoiceView('FR', 'FR', 'France'), $choices, '', false, false); + $this->assertContains(new ChoiceView('MY', 'MY', 'Malaysia'), $choices, '', false, false); + } + + public function testUnknownCountryIsNotIncluded() + { + $form = $this->factory->create('country', 'country'); + $view = $form->createView(); + $choices = $view->vars['choices']; + + foreach ($choices as $choice) { + if ('ZZ' === $choice->value) { + $this->fail('Should not contain choice "ZZ"'); + } + } + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php new file mode 100644 index 00000000..b0eb6dc0 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class CurrencyTypeTest extends TypeTestCase +{ + protected function setUp() + { + IntlTestHelper::requireIntl($this); + + parent::setUp(); + } + + public function testCurrenciesAreSelectable() + { + $form = $this->factory->create('currency'); + $view = $form->createView(); + $choices = $view->vars['choices']; + + $this->assertContains(new ChoiceView('EUR', 'EUR', 'Euro'), $choices, '', false, false); + $this->assertContains(new ChoiceView('USD', 'USD', 'US Dollar'), $choices, '', false, false); + $this->assertContains(new ChoiceView('SIT', 'SIT', 'Slovenian Tolar'), $choices, '', false, false); + } + +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php new file mode 100644 index 00000000..b9c1ebad --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/DateTimeTypeTest.php @@ -0,0 +1,477 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\FormError; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class DateTimeTypeTest extends TypeTestCase +{ + protected function setUp() + { + IntlTestHelper::requireIntl($this); + + parent::setUp(); + } + + public function testSubmitDateTime() + { + $form = $this->factory->create('datetime', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'date_widget' => 'choice', + 'time_widget' => 'choice', + 'input' => 'datetime', + )); + + $form->submit(array( + 'date' => array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ), + 'time' => array( + 'hour' => '3', + 'minute' => '4', + ), + )); + + $dateTime = new \DateTime('2010-06-02 03:04:00 UTC'); + + $this->assertDateTimeEquals($dateTime, $form->getData()); + } + + public function testSubmitString() + { + $form = $this->factory->create('datetime', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + 'date_widget' => 'choice', + 'time_widget' => 'choice', + )); + + $form->submit(array( + 'date' => array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ), + 'time' => array( + 'hour' => '3', + 'minute' => '4', + ), + )); + + $this->assertEquals('2010-06-02 03:04:00', $form->getData()); + } + + public function testSubmitTimestamp() + { + $form = $this->factory->create('datetime', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'timestamp', + 'date_widget' => 'choice', + 'time_widget' => 'choice', + )); + + $form->submit(array( + 'date' => array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ), + 'time' => array( + 'hour' => '3', + 'minute' => '4', + ), + )); + + $dateTime = new \DateTime('2010-06-02 03:04:00 UTC'); + + $this->assertEquals($dateTime->format('U'), $form->getData()); + } + + public function testSubmitWithoutMinutes() + { + $form = $this->factory->create('datetime', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'date_widget' => 'choice', + 'time_widget' => 'choice', + 'input' => 'datetime', + 'with_minutes' => false, + )); + + $form->setData(new \DateTime('2010-06-02 03:04:05 UTC')); + + $input = array( + 'date' => array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ), + 'time' => array( + 'hour' => '3', + ), + ); + + $form->submit($input); + + $this->assertDateTimeEquals(new \DateTime('2010-06-02 03:00:00 UTC'), $form->getData()); + } + + public function testSubmitWithSeconds() + { + $form = $this->factory->create('datetime', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'date_widget' => 'choice', + 'time_widget' => 'choice', + 'input' => 'datetime', + 'with_seconds' => true, + )); + + $form->setData(new \DateTime('2010-06-02 03:04:05 UTC')); + + $input = array( + 'date' => array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ), + 'time' => array( + 'hour' => '3', + 'minute' => '4', + 'second' => '5', + ), + ); + + $form->submit($input); + + $this->assertDateTimeEquals(new \DateTime('2010-06-02 03:04:05 UTC'), $form->getData()); + } + + public function testSubmitDifferentTimezones() + { + $form = $this->factory->create('datetime', null, array( + 'model_timezone' => 'America/New_York', + 'view_timezone' => 'Pacific/Tahiti', + 'date_widget' => 'choice', + 'time_widget' => 'choice', + 'input' => 'string', + 'with_seconds' => true, + )); + + $dateTime = new \DateTime('2010-06-02 03:04:05 Pacific/Tahiti'); + + $form->submit(array( + 'date' => array( + 'day' => (int) $dateTime->format('d'), + 'month' => (int) $dateTime->format('m'), + 'year' => (int) $dateTime->format('Y'), + ), + 'time' => array( + 'hour' => (int) $dateTime->format('H'), + 'minute' => (int) $dateTime->format('i'), + 'second' => (int) $dateTime->format('s'), + ), + )); + + $dateTime->setTimezone(new \DateTimeZone('America/New_York')); + + $this->assertEquals($dateTime->format('Y-m-d H:i:s'), $form->getData()); + } + + public function testSubmitDifferentTimezonesDateTime() + { + $form = $this->factory->create('datetime', null, array( + 'model_timezone' => 'America/New_York', + 'view_timezone' => 'Pacific/Tahiti', + 'widget' => 'single_text', + 'input' => 'datetime', + )); + + $outputTime = new \DateTime('2010-06-02 03:04:00 Pacific/Tahiti'); + + $form->submit('2010-06-02T03:04:00-10:00'); + + $outputTime->setTimezone(new \DateTimeZone('America/New_York')); + + $this->assertDateTimeEquals($outputTime, $form->getData()); + $this->assertEquals('2010-06-02T03:04:00-10:00', $form->getViewData()); + } + + public function testSubmitStringSingleText() + { + $form = $this->factory->create('datetime', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + 'widget' => 'single_text', + )); + + $form->submit('2010-06-02T03:04:00Z'); + + $this->assertEquals('2010-06-02 03:04:00', $form->getData()); + $this->assertEquals('2010-06-02T03:04:00Z', $form->getViewData()); + } + + public function testSubmitStringSingleTextWithSeconds() + { + $form = $this->factory->create('datetime', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + 'widget' => 'single_text', + 'with_seconds' => true, + )); + + $form->submit('2010-06-02T03:04:05Z'); + + $this->assertEquals('2010-06-02 03:04:05', $form->getData()); + $this->assertEquals('2010-06-02T03:04:05Z', $form->getViewData()); + } + + public function testSubmitDifferentPattern() + { + $form = $this->factory->create('datetime', null, array( + 'date_format' => 'MM*yyyy*dd', + 'date_widget' => 'single_text', + 'time_widget' => 'single_text', + 'input' => 'datetime', + )); + + $dateTime = new \DateTime('2010-06-02 03:04'); + + $form->submit(array( + 'date' => '06*2010*02', + 'time' => '03:04', + )); + + $this->assertDateTimeEquals($dateTime, $form->getData()); + } + + // Bug fix + public function testInitializeWithDateTime() + { + // Throws an exception if "data_class" option is not explicitly set + // to null in the type + $this->factory->create('datetime', new \DateTime()); + } + + public function testSingleTextWidgetShouldUseTheRightInputType() + { + $form = $this->factory->create('datetime', null, array( + 'widget' => 'single_text', + )); + + $view = $form->createView(); + $this->assertEquals('datetime', $view->vars['type']); + } + + public function testPassDefaultEmptyValueToViewIfNotRequired() + { + $form = $this->factory->create('datetime', null, array( + 'required' => false, + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('', $view['date']['year']->vars['empty_value']); + $this->assertSame('', $view['date']['month']->vars['empty_value']); + $this->assertSame('', $view['date']['day']->vars['empty_value']); + $this->assertSame('', $view['time']['hour']->vars['empty_value']); + $this->assertSame('', $view['time']['minute']->vars['empty_value']); + $this->assertSame('', $view['time']['second']->vars['empty_value']); + } + + public function testPassNoEmptyValueToViewIfRequired() + { + $form = $this->factory->create('datetime', null, array( + 'required' => true, + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertNull($view['date']['year']->vars['empty_value']); + $this->assertNull($view['date']['month']->vars['empty_value']); + $this->assertNull($view['date']['day']->vars['empty_value']); + $this->assertNull($view['time']['hour']->vars['empty_value']); + $this->assertNull($view['time']['minute']->vars['empty_value']); + $this->assertNull($view['time']['second']->vars['empty_value']); + } + + public function testPassEmptyValueAsString() + { + $form = $this->factory->create('datetime', null, array( + 'empty_value' => 'Empty', + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty', $view['date']['year']->vars['empty_value']); + $this->assertSame('Empty', $view['date']['month']->vars['empty_value']); + $this->assertSame('Empty', $view['date']['day']->vars['empty_value']); + $this->assertSame('Empty', $view['time']['hour']->vars['empty_value']); + $this->assertSame('Empty', $view['time']['minute']->vars['empty_value']); + $this->assertSame('Empty', $view['time']['second']->vars['empty_value']); + } + + public function testPassEmptyValueAsArray() + { + $form = $this->factory->create('datetime', null, array( + 'empty_value' => array( + 'year' => 'Empty year', + 'month' => 'Empty month', + 'day' => 'Empty day', + 'hour' => 'Empty hour', + 'minute' => 'Empty minute', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view['date']['year']->vars['empty_value']); + $this->assertSame('Empty month', $view['date']['month']->vars['empty_value']); + $this->assertSame('Empty day', $view['date']['day']->vars['empty_value']); + $this->assertSame('Empty hour', $view['time']['hour']->vars['empty_value']); + $this->assertSame('Empty minute', $view['time']['minute']->vars['empty_value']); + $this->assertSame('Empty second', $view['time']['second']->vars['empty_value']); + } + + public function testPassEmptyValueAsPartialArrayAddEmptyIfNotRequired() + { + $form = $this->factory->create('datetime', null, array( + 'required' => false, + 'empty_value' => array( + 'year' => 'Empty year', + 'day' => 'Empty day', + 'hour' => 'Empty hour', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view['date']['year']->vars['empty_value']); + $this->assertSame('', $view['date']['month']->vars['empty_value']); + $this->assertSame('Empty day', $view['date']['day']->vars['empty_value']); + $this->assertSame('Empty hour', $view['time']['hour']->vars['empty_value']); + $this->assertSame('', $view['time']['minute']->vars['empty_value']); + $this->assertSame('Empty second', $view['time']['second']->vars['empty_value']); + } + + public function testPassEmptyValueAsPartialArrayAddNullIfRequired() + { + $form = $this->factory->create('datetime', null, array( + 'required' => true, + 'empty_value' => array( + 'year' => 'Empty year', + 'day' => 'Empty day', + 'hour' => 'Empty hour', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view['date']['year']->vars['empty_value']); + $this->assertNull($view['date']['month']->vars['empty_value']); + $this->assertSame('Empty day', $view['date']['day']->vars['empty_value']); + $this->assertSame('Empty hour', $view['time']['hour']->vars['empty_value']); + $this->assertNull($view['time']['minute']->vars['empty_value']); + $this->assertSame('Empty second', $view['time']['second']->vars['empty_value']); + } + + public function testPassHtml5TypeIfSingleTextAndHtml5Format() + { + $form = $this->factory->create('datetime', null, array( + 'widget' => 'single_text', + )); + + $view = $form->createView(); + $this->assertSame('datetime', $view->vars['type']); + } + + public function testDontPassHtml5TypeIfNotHtml5Format() + { + $form = $this->factory->create('datetime', null, array( + 'widget' => 'single_text', + 'format' => 'yyyy-MM-dd HH:mm', + )); + + $view = $form->createView(); + $this->assertFalse(isset($view->vars['type'])); + } + + public function testDontPassHtml5TypeIfNotSingleText() + { + $form = $this->factory->create('datetime', null, array( + 'widget' => 'text', + )); + + $view = $form->createView(); + $this->assertFalse(isset($view->vars['type'])); + } + + public function testDateTypeChoiceErrorsBubbleUp() + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('datetime', null); + + $form['date']->addError($error); + + $this->assertSame(array(), $form['date']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + public function testDateTypeSingleTextErrorsBubbleUp() + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('datetime', null, array( + 'date_widget' => 'single_text' + )); + + $form['date']->addError($error); + + $this->assertSame(array(), $form['date']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + public function testTimeTypeChoiceErrorsBubbleUp() + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('datetime', null); + + $form['time']->addError($error); + + $this->assertSame(array(), $form['time']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + public function testTimeTypeSingleTextErrorsBubbleUp() + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('datetime', null, array( + 'time_widget' => 'single_text' + )); + + $form['time']->addError($error); + + $this->assertSame(array(), $form['time']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php new file mode 100644 index 00000000..2aa155e7 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php @@ -0,0 +1,781 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Form\FormError; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class DateTypeTest extends TypeTestCase +{ + protected function setUp() + { + parent::setUp(); + + // we test against "de_AT", so we need the full implementation + IntlTestHelper::requireFullIntl($this); + + \Locale::setDefault('de_AT'); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testInvalidWidgetOption() + { + $this->factory->create('date', null, array( + 'widget' => 'fake_widget', + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testInvalidInputOption() + { + $this->factory->create('date', null, array( + 'input' => 'fake_input', + )); + } + + public function testSubmitFromSingleTextDateTimeWithDefaultFormat() + { + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'single_text', + 'input' => 'datetime', + )); + + $form->submit('2010-06-02'); + + $this->assertDateTimeEquals(new \DateTime('2010-06-02 UTC'), $form->getData()); + $this->assertEquals('2010-06-02', $form->getViewData()); + } + + public function testSubmitFromSingleTextDateTime() + { + $form = $this->factory->create('date', null, array( + 'format' => \IntlDateFormatter::MEDIUM, + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'single_text', + 'input' => 'datetime', + )); + + $form->submit('2.6.2010'); + + $this->assertDateTimeEquals(new \DateTime('2010-06-02 UTC'), $form->getData()); + $this->assertEquals('02.06.2010', $form->getViewData()); + } + + public function testSubmitFromSingleTextString() + { + $form = $this->factory->create('date', null, array( + 'format' => \IntlDateFormatter::MEDIUM, + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'single_text', + 'input' => 'string', + )); + + $form->submit('2.6.2010'); + + $this->assertEquals('2010-06-02', $form->getData()); + $this->assertEquals('02.06.2010', $form->getViewData()); + } + + public function testSubmitFromSingleTextTimestamp() + { + $form = $this->factory->create('date', null, array( + 'format' => \IntlDateFormatter::MEDIUM, + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'single_text', + 'input' => 'timestamp', + )); + + $form->submit('2.6.2010'); + + $dateTime = new \DateTime('2010-06-02 UTC'); + + $this->assertEquals($dateTime->format('U'), $form->getData()); + $this->assertEquals('02.06.2010', $form->getViewData()); + } + + public function testSubmitFromSingleTextRaw() + { + $form = $this->factory->create('date', null, array( + 'format' => \IntlDateFormatter::MEDIUM, + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'single_text', + 'input' => 'array', + )); + + $form->submit('2.6.2010'); + + $output = array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ); + + $this->assertEquals($output, $form->getData()); + $this->assertEquals('02.06.2010', $form->getViewData()); + } + + public function testSubmitFromText() + { + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'text', + )); + + $text = array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ); + + $form->submit($text); + + $dateTime = new \DateTime('2010-06-02 UTC'); + + $this->assertDateTimeEquals($dateTime, $form->getData()); + $this->assertEquals($text, $form->getViewData()); + } + + public function testSubmitFromChoice() + { + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'choice', + )); + + $text = array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ); + + $form->submit($text); + + $dateTime = new \DateTime('2010-06-02 UTC'); + + $this->assertDateTimeEquals($dateTime, $form->getData()); + $this->assertEquals($text, $form->getViewData()); + } + + public function testSubmitFromChoiceEmpty() + { + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'choice', + 'required' => false, + )); + + $text = array( + 'day' => '', + 'month' => '', + 'year' => '', + ); + + $form->submit($text); + + $this->assertNull($form->getData()); + $this->assertEquals($text, $form->getViewData()); + } + + public function testSubmitFromInputDateTimeDifferentPattern() + { + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'format' => 'MM*yyyy*dd', + 'widget' => 'single_text', + 'input' => 'datetime', + )); + + $form->submit('06*2010*02'); + + $this->assertDateTimeEquals(new \DateTime('2010-06-02 UTC'), $form->getData()); + $this->assertEquals('06*2010*02', $form->getViewData()); + } + + public function testSubmitFromInputStringDifferentPattern() + { + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'format' => 'MM*yyyy*dd', + 'widget' => 'single_text', + 'input' => 'string', + )); + + $form->submit('06*2010*02'); + + $this->assertEquals('2010-06-02', $form->getData()); + $this->assertEquals('06*2010*02', $form->getViewData()); + } + + public function testSubmitFromInputTimestampDifferentPattern() + { + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'format' => 'MM*yyyy*dd', + 'widget' => 'single_text', + 'input' => 'timestamp', + )); + + $form->submit('06*2010*02'); + + $dateTime = new \DateTime('2010-06-02 UTC'); + + $this->assertEquals($dateTime->format('U'), $form->getData()); + $this->assertEquals('06*2010*02', $form->getViewData()); + } + + public function testSubmitFromInputRawDifferentPattern() + { + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'format' => 'MM*yyyy*dd', + 'widget' => 'single_text', + 'input' => 'array', + )); + + $form->submit('06*2010*02'); + + $output = array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + ); + + $this->assertEquals($output, $form->getData()); + $this->assertEquals('06*2010*02', $form->getViewData()); + } + + /** + * @dataProvider provideDateFormats + */ + public function testDatePatternWithFormatOption($format, $pattern) + { + $form = $this->factory->create('date', null, array( + 'format' => $format, + )); + + $view = $form->createView(); + + $this->assertEquals($pattern, $view->vars['date_pattern']); + } + + public function provideDateFormats() + { + return array( + array('dMy', '{{ day }}{{ month }}{{ year }}'), + array('d-M-yyyy', '{{ day }}-{{ month }}-{{ year }}'), + array('M d y', '{{ month }} {{ day }} {{ year }}'), + ); + } + + /** + * This test is to check that the strings '0', '1', '2', '3' are no accepted + * as valid IntlDateFormatter constants for FULL, LONG, MEDIUM or SHORT respectively. + * + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testThrowExceptionIfFormatIsNoPattern() + { + $this->factory->create('date', null, array( + 'format' => '0', + 'widget' => 'single_text', + 'input' => 'string', + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testThrowExceptionIfFormatDoesNotContainYearMonthAndDay() + { + $this->factory->create('date', null, array( + 'months' => array(6, 7), + 'format' => 'yy', + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testThrowExceptionIfFormatIsNoConstant() + { + $this->factory->create('date', null, array( + 'format' => 105, + )); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testThrowExceptionIfFormatIsInvalid() + { + $this->factory->create('date', null, array( + 'format' => array(), + )); + } + + public function testSetDataWithDifferentTimezones() + { + $form = $this->factory->create('date', null, array( + 'format' => \IntlDateFormatter::MEDIUM, + 'model_timezone' => 'America/New_York', + 'view_timezone' => 'Pacific/Tahiti', + 'input' => 'string', + 'widget' => 'single_text', + )); + + $form->setData('2010-06-02'); + + $this->assertEquals('01.06.2010', $form->getViewData()); + } + + public function testSetDataWithDifferentTimezonesDateTime() + { + $form = $this->factory->create('date', null, array( + 'format' => \IntlDateFormatter::MEDIUM, + 'model_timezone' => 'America/New_York', + 'view_timezone' => 'Pacific/Tahiti', + 'input' => 'datetime', + 'widget' => 'single_text', + )); + + $dateTime = new \DateTime('2010-06-02 America/New_York'); + + $form->setData($dateTime); + + $this->assertDateTimeEquals($dateTime, $form->getData()); + $this->assertEquals('01.06.2010', $form->getViewData()); + } + + public function testYearsOption() + { + $form = $this->factory->create('date', null, array( + 'years' => array(2010, 2011), + )); + + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('2010', '2010', '2010'), + new ChoiceView('2011', '2011', '2011'), + ), $view['year']->vars['choices']); + } + + public function testMonthsOption() + { + $form = $this->factory->create('date', null, array( + 'months' => array(6, 7), + )); + + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('6', '6', '06'), + new ChoiceView('7', '7', '07'), + ), $view['month']->vars['choices']); + } + + public function testMonthsOptionShortFormat() + { + $form = $this->factory->create('date', null, array( + 'months' => array(1, 4), + 'format' => 'dd.MMM.yy', + )); + + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('1', '1', 'Jän'), + new ChoiceView('4', '4', 'Apr.') + ), $view['month']->vars['choices']); + } + + public function testMonthsOptionLongFormat() + { + $form = $this->factory->create('date', null, array( + 'months' => array(1, 4), + 'format' => 'dd.MMMM.yy', + )); + + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('1', '1', 'Jänner'), + new ChoiceView('4', '4', 'April'), + ), $view['month']->vars['choices']); + } + + public function testMonthsOptionLongFormatWithDifferentTimezone() + { + $form = $this->factory->create('date', null, array( + 'months' => array(1, 4), + 'format' => 'dd.MMMM.yy', + )); + + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('1', '1', 'Jänner'), + new ChoiceView('4', '4', 'April'), + ), $view['month']->vars['choices']); + } + + public function testIsDayWithinRangeReturnsTrueIfWithin() + { + $form = $this->factory->create('date', null, array( + 'days' => array(6, 7), + )); + + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('6', '6', '06'), + new ChoiceView('7', '7', '07'), + ), $view['day']->vars['choices']); + } + + public function testIsPartiallyFilledReturnsFalseIfSingleText() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'single_text', + )); + + $form->submit('7.6.2010'); + + $this->assertFalse($form->isPartiallyFilled()); + } + + public function testIsPartiallyFilledReturnsFalseIfChoiceAndCompletelyEmpty() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'choice', + )); + + $form->submit(array( + 'day' => '', + 'month' => '', + 'year' => '', + )); + + $this->assertFalse($form->isPartiallyFilled()); + } + + public function testIsPartiallyFilledReturnsFalseIfChoiceAndCompletelyFilled() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'choice', + )); + + $form->submit(array( + 'day' => '2', + 'month' => '6', + 'year' => '2010', + )); + + $this->assertFalse($form->isPartiallyFilled()); + } + + public function testIsPartiallyFilledReturnsTrueIfChoiceAndDayEmpty() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('date', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'widget' => 'choice', + )); + + $form->submit(array( + 'day' => '', + 'month' => '6', + 'year' => '2010', + )); + + $this->assertTrue($form->isPartiallyFilled()); + } + + public function testPassDatePatternToView() + { + $form = $this->factory->create('date'); + $view = $form->createView(); + + $this->assertSame('{{ day }}{{ month }}{{ year }}', $view->vars['date_pattern']); + } + + public function testPassDatePatternToViewDifferentFormat() + { + $form = $this->factory->create('date', null, array( + 'format' => \IntlDateFormatter::LONG, + )); + + $view = $form->createView(); + + $this->assertSame('{{ day }}{{ month }}{{ year }}', $view->vars['date_pattern']); + } + + public function testPassDatePatternToViewDifferentPattern() + { + $form = $this->factory->create('date', null, array( + 'format' => 'MMyyyydd' + )); + + $view = $form->createView(); + + $this->assertSame('{{ month }}{{ year }}{{ day }}', $view->vars['date_pattern']); + } + + public function testPassDatePatternToViewDifferentPatternWithSeparators() + { + $form = $this->factory->create('date', null, array( + 'format' => 'MM*yyyy*dd' + )); + + $view = $form->createView(); + + $this->assertSame('{{ month }}*{{ year }}*{{ day }}', $view->vars['date_pattern']); + } + + public function testDontPassDatePatternIfText() + { + $form = $this->factory->create('date', null, array( + 'widget' => 'single_text', + )); + $view = $form->createView(); + + $this->assertFalse(isset($view->vars['date_pattern'])); + } + + public function testPassWidgetToView() + { + $form = $this->factory->create('date', null, array( + 'widget' => 'single_text', + )); + $view = $form->createView(); + + $this->assertSame('single_text', $view->vars['widget']); + } + + // Bug fix + public function testInitializeWithDateTime() + { + // Throws an exception if "data_class" option is not explicitly set + // to null in the type + $this->factory->create('date', new \DateTime()); + } + + public function testSingleTextWidgetShouldUseTheRightInputType() + { + $form = $this->factory->create('date', null, array( + 'widget' => 'single_text', + )); + + $view = $form->createView(); + $this->assertEquals('date', $view->vars['type']); + } + + public function testPassDefaultEmptyValueToViewIfNotRequired() + { + $form = $this->factory->create('date', null, array( + 'required' => false, + )); + + $view = $form->createView(); + $this->assertSame('', $view['year']->vars['empty_value']); + $this->assertSame('', $view['month']->vars['empty_value']); + $this->assertSame('', $view['day']->vars['empty_value']); + } + + public function testPassNoEmptyValueToViewIfRequired() + { + $form = $this->factory->create('date', null, array( + 'required' => true, + )); + + $view = $form->createView(); + $this->assertNull($view['year']->vars['empty_value']); + $this->assertNull($view['month']->vars['empty_value']); + $this->assertNull($view['day']->vars['empty_value']); + } + + public function testPassEmptyValueAsString() + { + $form = $this->factory->create('date', null, array( + 'empty_value' => 'Empty', + )); + + $view = $form->createView(); + $this->assertSame('Empty', $view['year']->vars['empty_value']); + $this->assertSame('Empty', $view['month']->vars['empty_value']); + $this->assertSame('Empty', $view['day']->vars['empty_value']); + } + + public function testPassEmptyValueAsArray() + { + $form = $this->factory->create('date', null, array( + 'empty_value' => array( + 'year' => 'Empty year', + 'month' => 'Empty month', + 'day' => 'Empty day', + ), + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view['year']->vars['empty_value']); + $this->assertSame('Empty month', $view['month']->vars['empty_value']); + $this->assertSame('Empty day', $view['day']->vars['empty_value']); + } + + public function testPassEmptyValueAsPartialArrayAddEmptyIfNotRequired() + { + $form = $this->factory->create('date', null, array( + 'required' => false, + 'empty_value' => array( + 'year' => 'Empty year', + 'day' => 'Empty day', + ), + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view['year']->vars['empty_value']); + $this->assertSame('', $view['month']->vars['empty_value']); + $this->assertSame('Empty day', $view['day']->vars['empty_value']); + } + + public function testPassEmptyValueAsPartialArrayAddNullIfRequired() + { + $form = $this->factory->create('date', null, array( + 'required' => true, + 'empty_value' => array( + 'year' => 'Empty year', + 'day' => 'Empty day', + ), + )); + + $view = $form->createView(); + $this->assertSame('Empty year', $view['year']->vars['empty_value']); + $this->assertNull($view['month']->vars['empty_value']); + $this->assertSame('Empty day', $view['day']->vars['empty_value']); + } + + public function testPassHtml5TypeIfSingleTextAndHtml5Format() + { + $form = $this->factory->create('date', null, array( + 'widget' => 'single_text', + )); + + $view = $form->createView(); + $this->assertSame('date', $view->vars['type']); + } + + public function testDontPassHtml5TypeIfNotHtml5Format() + { + $form = $this->factory->create('date', null, array( + 'widget' => 'single_text', + 'format' => \IntlDateFormatter::MEDIUM, + )); + + $view = $form->createView(); + $this->assertFalse(isset($view->vars['type'])); + } + + public function testDontPassHtml5TypeIfNotSingleText() + { + $form = $this->factory->create('date', null, array( + 'widget' => 'text', + )); + + $view = $form->createView(); + $this->assertFalse(isset($view->vars['type'])); + } + + public function provideCompoundWidgets() + { + return array( + array('text'), + array('choice'), + ); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testYearErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('date', null, array( + 'widget' => $widget, + )); + $form['year']->addError($error); + + $this->assertSame(array(), $form['year']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testMonthErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('date', null, array( + 'widget' => $widget, + )); + $form['month']->addError($error); + + $this->assertSame(array(), $form['month']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testDayErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('date', null, array( + 'widget' => $widget, + )); + $form['day']->addError($error); + + $this->assertSame(array(), $form['day']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php new file mode 100644 index 00000000..63556eb5 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +class FileTypeTest extends \Symfony\Component\Form\Test\TypeTestCase +{ + // https://github.com/symfony/symfony/pull/5028 + public function testSetData() + { + $form = $this->factory->createBuilder('file')->getForm(); + $data = $this->createUploadedFileMock('abcdef', 'original.jpg', true); + + $form->setData($data); + + $this->assertSame($data, $form->getData()); + } + + public function testSubmit() + { + $form = $this->factory->createBuilder('file')->getForm(); + $data = $this->createUploadedFileMock('abcdef', 'original.jpg', true); + + $form->submit($data); + + $this->assertSame($data, $form->getData()); + } + + // https://github.com/symfony/symfony/issues/6134 + public function testSubmitEmpty() + { + $form = $this->factory->createBuilder('file')->getForm(); + + $form->submit(null); + + $this->assertNull($form->getData()); + } + + public function testDontPassValueToView() + { + $form = $this->factory->create('file'); + $form->submit(array( + 'file' => $this->createUploadedFileMock('abcdef', 'original.jpg', true), + )); + $view = $form->createView(); + + $this->assertEquals('', $view->vars['value']); + } + + private function createUploadedFileMock($name, $originalName, $valid) + { + $file = $this + ->getMockBuilder('Symfony\Component\HttpFoundation\File\UploadedFile') + ->disableOriginalConstructor() + ->getMock() + ; + $file + ->expects($this->any()) + ->method('getBasename') + ->will($this->returnValue($name)) + ; + $file + ->expects($this->any()) + ->method('getClientOriginalName') + ->will($this->returnValue($originalName)) + ; + $file + ->expects($this->any()) + ->method('isValid') + ->will($this->returnValue($valid)) + ; + + return $file; + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php new file mode 100644 index 00000000..cced82f4 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php @@ -0,0 +1,578 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\PropertyAccess\PropertyPath; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\CallbackTransformer; +use Symfony\Component\Form\Tests\Fixtures\Author; +use Symfony\Component\Form\Tests\Fixtures\FixedDataTransformer; +use Symfony\Component\Form\FormError; + +class FormTest_AuthorWithoutRefSetter +{ + protected $reference; + + protected $referenceCopy; + + public function __construct($reference) + { + $this->reference = $reference; + $this->referenceCopy = $reference; + } + + // The returned object should be modified by reference without having + // to provide a setReference() method + public function getReference() + { + return $this->reference; + } + + // The returned object is a copy, so setReferenceCopy() must be used + // to update it + public function getReferenceCopy() + { + return is_object($this->referenceCopy) ? clone $this->referenceCopy : $this->referenceCopy; + } + + public function setReferenceCopy($reference) + { + $this->referenceCopy = $reference; + } +} + +class FormTypeTest extends BaseTypeTest +{ + public function testCreateFormInstances() + { + $this->assertInstanceOf('Symfony\Component\Form\Form', $this->factory->create('form')); + } + + public function testPassRequiredAsOption() + { + $form = $this->factory->create('form', null, array('required' => false)); + + $this->assertFalse($form->isRequired()); + + $form = $this->factory->create('form', null, array('required' => true)); + + $this->assertTrue($form->isRequired()); + } + + public function testSubmittedDataIsTrimmedBeforeTransforming() + { + $form = $this->factory->createBuilder('form') + ->addViewTransformer(new FixedDataTransformer(array( + null => '', + 'reverse[a]' => 'a', + ))) + ->setCompound(false) + ->getForm(); + + $form->submit(' a '); + + $this->assertEquals('a', $form->getViewData()); + $this->assertEquals('reverse[a]', $form->getData()); + } + + public function testSubmittedDataIsNotTrimmedBeforeTransformingIfNoTrimming() + { + $form = $this->factory->createBuilder('form', null, array('trim' => false)) + ->addViewTransformer(new FixedDataTransformer(array( + null => '', + 'reverse[ a ]' => ' a ', + ))) + ->setCompound(false) + ->getForm(); + + $form->submit(' a '); + + $this->assertEquals(' a ', $form->getViewData()); + $this->assertEquals('reverse[ a ]', $form->getData()); + } + + public function testNonReadOnlyFormWithReadOnlyParentIsReadOnly() + { + $view = $this->factory->createNamedBuilder('parent', 'form', null, array('read_only' => true)) + ->add('child', 'form') + ->getForm() + ->createView(); + + $this->assertTrue($view['child']->vars['read_only']); + } + + public function testReadOnlyFormWithNonReadOnlyParentIsReadOnly() + { + $view = $this->factory->createNamedBuilder('parent', 'form') + ->add('child', 'form', array('read_only' => true)) + ->getForm() + ->createView(); + + $this->assertTrue($view['child']->vars['read_only']); + } + + public function testNonReadOnlyFormWithNonReadOnlyParentIsNotReadOnly() + { + $view = $this->factory->createNamedBuilder('parent', 'form') + ->add('child', 'form') + ->getForm() + ->createView(); + + $this->assertFalse($view['child']->vars['read_only']); + } + + public function testPassMaxLengthToView() + { + $form = $this->factory->create('form', null, array('max_length' => 10)); + $view = $form->createView(); + + $this->assertSame(10, $view->vars['max_length']); + } + + public function testSubmitWithEmptyDataCreatesObjectIfClassAvailable() + { + $builder = $this->factory->createBuilder('form', null, array( + 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', + 'required' => false, + )); + $builder->add('firstName', 'text'); + $builder->add('lastName', 'text'); + $form = $builder->getForm(); + + $form->setData(null); + // partially empty, still an object is created + $form->submit(array('firstName' => 'Bernhard', 'lastName' => '')); + + $author = new Author(); + $author->firstName = 'Bernhard'; + $author->setLastName(''); + + $this->assertEquals($author, $form->getData()); + } + + public function testSubmitWithEmptyDataCreatesObjectIfInitiallySubmittedWithObject() + { + $builder = $this->factory->createBuilder('form', null, array( + // data class is inferred from the passed object + 'data' => new Author(), + 'required' => false, + )); + $builder->add('firstName', 'text'); + $builder->add('lastName', 'text'); + $form = $builder->getForm(); + + $form->setData(null); + // partially empty, still an object is created + $form->submit(array('firstName' => 'Bernhard', 'lastName' => '')); + + $author = new Author(); + $author->firstName = 'Bernhard'; + $author->setLastName(''); + + $this->assertEquals($author, $form->getData()); + } + + public function testSubmitWithEmptyDataCreatesArrayIfDataClassIsNull() + { + $builder = $this->factory->createBuilder('form', null, array( + 'data_class' => null, + 'required' => false, + )); + $builder->add('firstName', 'text'); + $form = $builder->getForm(); + + $form->setData(null); + $form->submit(array('firstName' => 'Bernhard')); + + $this->assertSame(array('firstName' => 'Bernhard'), $form->getData()); + } + + public function testSubmitEmptyWithEmptyDataCreatesNoObjectIfNotRequired() + { + $builder = $this->factory->createBuilder('form', null, array( + 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', + 'required' => false, + )); + $builder->add('firstName', 'text'); + $builder->add('lastName', 'text'); + $form = $builder->getForm(); + + $form->setData(null); + $form->submit(array('firstName' => '', 'lastName' => '')); + + $this->assertNull($form->getData()); + } + + public function testSubmitEmptyWithEmptyDataCreatesObjectIfRequired() + { + $builder = $this->factory->createBuilder('form', null, array( + 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', + 'required' => true, + )); + $builder->add('firstName', 'text'); + $builder->add('lastName', 'text'); + $form = $builder->getForm(); + + $form->setData(null); + $form->submit(array('firstName' => '', 'lastName' => '')); + + $this->assertEquals(new Author(), $form->getData()); + } + + /* + * We need something to write the field values into + */ + public function testSubmitWithEmptyDataStoresArrayIfNoClassAvailable() + { + $form = $this->factory->createBuilder('form') + ->add('firstName', 'text') + ->getForm(); + + $form->setData(null); + $form->submit(array('firstName' => 'Bernhard')); + + $this->assertSame(array('firstName' => 'Bernhard'), $form->getData()); + } + + public function testSubmitWithEmptyDataPassesEmptyStringToTransformerIfNotCompound() + { + $form = $this->factory->createBuilder('form') + ->addViewTransformer(new FixedDataTransformer(array( + // required for the initial, internal setData(null) + null => 'null', + // required to test that submit(null) is converted to '' + 'empty' => '', + ))) + ->setCompound(false) + ->getForm(); + + $form->submit(null); + + $this->assertSame('empty', $form->getData()); + } + + public function testSubmitWithEmptyDataUsesEmptyDataOption() + { + $author = new Author(); + + $builder = $this->factory->createBuilder('form', null, array( + 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', + 'empty_data' => $author, + )); + $builder->add('firstName', 'text'); + $form = $builder->getForm(); + + $form->submit(array('firstName' => 'Bernhard')); + + $this->assertSame($author, $form->getData()); + $this->assertEquals('Bernhard', $author->firstName); + } + + public function provideZeros() + { + return array( + array(0, '0'), + array('0', '0'), + array('00000', '00000'), + ); + } + + /** + * @dataProvider provideZeros + * @see https://github.com/symfony/symfony/issues/1986 + */ + public function testSetDataThroughParamsWithZero($data, $dataAsString) + { + $form = $this->factory->create('form', null, array( + 'data' => $data, + 'compound' => false, + )); + $view = $form->createView(); + + $this->assertFalse($form->isEmpty()); + + $this->assertSame($dataAsString, $view->vars['value']); + $this->assertSame($dataAsString, $form->getData()); + } + + /** + * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException + */ + public function testAttributesException() + { + $this->factory->create('form', null, array('attr' => '')); + } + + public function testNameCanBeEmptyString() + { + $form = $this->factory->createNamed('', 'form'); + + $this->assertEquals('', $form->getName()); + } + + public function testSubformDoesntCallSetters() + { + $author = new FormTest_AuthorWithoutRefSetter(new Author()); + + $builder = $this->factory->createBuilder('form', $author); + $builder->add('reference', 'form', array( + 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', + )); + $builder->get('reference')->add('firstName', 'text'); + $form = $builder->getForm(); + + $form->submit(array( + // reference has a getter, but not setter + 'reference' => array( + 'firstName' => 'Foo', + ) + )); + + $this->assertEquals('Foo', $author->getReference()->firstName); + } + + public function testSubformCallsSettersIfTheObjectChanged() + { + // no reference + $author = new FormTest_AuthorWithoutRefSetter(null); + $newReference = new Author(); + + $builder = $this->factory->createBuilder('form', $author); + $builder->add('referenceCopy', 'form', array( + 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', + )); + $builder->get('referenceCopy')->add('firstName', 'text'); + $form = $builder->getForm(); + + $form['referenceCopy']->setData($newReference); // new author object + + $form->submit(array( + // referenceCopy has a getter that returns a copy + 'referenceCopy' => array( + 'firstName' => 'Foo', + ) + )); + + $this->assertEquals('Foo', $author->getReferenceCopy()->firstName); + } + + public function testSubformCallsSettersIfByReferenceIsFalse() + { + $author = new FormTest_AuthorWithoutRefSetter(new Author()); + + $builder = $this->factory->createBuilder('form', $author); + $builder->add('referenceCopy', 'form', array( + 'data_class' => 'Symfony\Component\Form\Tests\Fixtures\Author', + 'by_reference' => false + )); + $builder->get('referenceCopy')->add('firstName', 'text'); + $form = $builder->getForm(); + + $form->submit(array( + // referenceCopy has a getter that returns a copy + 'referenceCopy' => array( + 'firstName' => 'Foo', + ) + )); + + // firstName can only be updated if setReferenceCopy() was called + $this->assertEquals('Foo', $author->getReferenceCopy()->firstName); + } + + public function testSubformCallsSettersIfReferenceIsScalar() + { + $author = new FormTest_AuthorWithoutRefSetter('scalar'); + + $builder = $this->factory->createBuilder('form', $author); + $builder->add('referenceCopy', 'form'); + $builder->get('referenceCopy')->addViewTransformer(new CallbackTransformer( + function () {}, + function ($value) { // reverseTransform + + return 'foobar'; + } + )); + $form = $builder->getForm(); + + $form->submit(array( + 'referenceCopy' => array(), // doesn't matter actually + )); + + // firstName can only be updated if setReferenceCopy() was called + $this->assertEquals('foobar', $author->getReferenceCopy()); + } + + public function testSubformAlwaysInsertsIntoArrays() + { + $ref1 = new Author(); + $ref2 = new Author(); + $author = array('referenceCopy' => $ref1); + + $builder = $this->factory->createBuilder('form'); + $builder->setData($author); + $builder->add('referenceCopy', 'form'); + $builder->get('referenceCopy')->addViewTransformer(new CallbackTransformer( + function () {}, + function ($value) use ($ref2) { // reverseTransform + + return $ref2; + } + )); + $form = $builder->getForm(); + + $form->submit(array( + 'referenceCopy' => array('a' => 'b'), // doesn't matter actually + )); + + // the new reference was inserted into the array + $author = $form->getData(); + $this->assertSame($ref2, $author['referenceCopy']); + } + + public function testPassMultipartTrueIfAnyChildIsMultipartToView() + { + $view = $this->factory->createBuilder('form') + ->add('foo', 'text') + ->add('bar', 'file') + ->getForm() + ->createView(); + + $this->assertTrue($view->vars['multipart']); + } + + public function testViewIsNotRenderedByDefault() + { + $view = $this->factory->createBuilder('form') + ->add('foo', 'form') + ->getForm() + ->createView(); + + $this->assertFalse($view->isRendered()); + } + + public function testErrorBubblingIfCompound() + { + $form = $this->factory->create('form', null, array( + 'compound' => true, + )); + + $this->assertTrue($form->getConfig()->getErrorBubbling()); + } + + public function testNoErrorBubblingIfNotCompound() + { + $form = $this->factory->create('form', null, array( + 'compound' => false, + )); + + $this->assertFalse($form->getConfig()->getErrorBubbling()); + } + + public function testOverrideErrorBubbling() + { + $form = $this->factory->create('form', null, array( + 'compound' => false, + 'error_bubbling' => true, + )); + + $this->assertTrue($form->getConfig()->getErrorBubbling()); + } + + public function testPropertyPath() + { + $form = $this->factory->create('form', null, array( + 'property_path' => 'foo', + )); + + $this->assertEquals(new PropertyPath('foo'), $form->getPropertyPath()); + $this->assertTrue($form->getConfig()->getMapped()); + } + + public function testPropertyPathNullImpliesDefault() + { + $form = $this->factory->createNamed('name', 'form', null, array( + 'property_path' => null, + )); + + $this->assertEquals(new PropertyPath('name'), $form->getPropertyPath()); + $this->assertTrue($form->getConfig()->getMapped()); + } + + public function testNotMapped() + { + $form = $this->factory->create('form', null, array( + 'property_path' => 'foo', + 'mapped' => false, + )); + + $this->assertEquals(new PropertyPath('foo'), $form->getPropertyPath()); + $this->assertFalse($form->getConfig()->getMapped()); + } + + public function testViewValidNotSubmitted() + { + $form = $this->factory->create('form'); + $view = $form->createView(); + $this->assertTrue($view->vars['valid']); + } + + public function testViewNotValidSubmitted() + { + $form = $this->factory->create('form'); + $form->submit(array()); + $form->addError(new FormError('An error')); + $view = $form->createView(); + $this->assertFalse($view->vars['valid']); + } + + public function testDataOptionSupersedesSetDataCalls() + { + $form = $this->factory->create('form', null, array( + 'data' => 'default', + 'compound' => false, + )); + + $form->setData('foobar'); + + $this->assertSame('default', $form->getData()); + } + + public function testNormDataIsPassedToView() + { + $view = $this->factory->createBuilder('form') + ->addViewTransformer(new FixedDataTransformer(array( + 'foo' => 'bar', + ))) + ->setData('foo') + ->getForm() + ->createView(); + + $this->assertSame('foo', $view->vars['data']); + $this->assertSame('bar', $view->vars['value']); + } + + // https://github.com/symfony/symfony/issues/6862 + public function testPassZeroLabelToView() + { + $view = $this->factory->create('form', null, array( + 'label' => '0' + )) + ->createView(); + + $this->assertSame('0', $view->vars['label']); + } + + protected function getTestedType() + { + return 'form'; + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php new file mode 100644 index 00000000..998bbe01 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Intl\Util\IntlTestHelper; + +class IntegerTypeTest extends TypeTestCase +{ + protected function setUp() + { + IntlTestHelper::requireIntl($this); + + parent::setUp(); + } + + public function testSubmitCastsToInteger() + { + $form = $this->factory->create('integer'); + + $form->submit('1.678'); + + $this->assertSame(1, $form->getData()); + $this->assertSame('1', $form->getViewData()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php new file mode 100644 index 00000000..24434b21 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class LanguageTypeTest extends TypeTestCase +{ + protected function setUp() + { + IntlTestHelper::requireIntl($this); + + parent::setUp(); + } + + public function testCountriesAreSelectable() + { + $form = $this->factory->create('language'); + $view = $form->createView(); + $choices = $view->vars['choices']; + + $this->assertContains(new ChoiceView('en', 'en', 'English'), $choices, '', false, false); + $this->assertContains(new ChoiceView('en_GB', 'en_GB', 'British English'), $choices, '', false, false); + $this->assertContains(new ChoiceView('en_US', 'en_US', 'U.S. English'), $choices, '', false, false); + $this->assertContains(new ChoiceView('fr', 'fr', 'French'), $choices, '', false, false); + $this->assertContains(new ChoiceView('my', 'my', 'Burmese'), $choices, '', false, false); + } + + public function testMultipleLanguagesIsNotIncluded() + { + $form = $this->factory->create('language', 'language'); + $view = $form->createView(); + $choices = $view->vars['choices']; + + $this->assertNotContains(new ChoiceView('mul', 'mul', 'Mehrsprachig'), $choices, '', false, false); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php new file mode 100644 index 00000000..e402cb4b --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class LocaleTypeTest extends TypeTestCase +{ + protected function setUp() + { + IntlTestHelper::requireIntl($this); + + parent::setUp(); + } + + public function testLocalesAreSelectable() + { + $form = $this->factory->create('locale'); + $view = $form->createView(); + $choices = $view->vars['choices']; + + $this->assertContains(new ChoiceView('en', 'en', 'English'), $choices, '', false, false); + $this->assertContains(new ChoiceView('en_GB', 'en_GB', 'English (United Kingdom)'), $choices, '', false, false); + $this->assertContains(new ChoiceView('zh_Hant_MO', 'zh_Hant_MO', 'Chinese (Traditional, Macau SAR China)'), $choices, '', false, false); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php new file mode 100644 index 00000000..97fc37fa --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Intl\Util\IntlTestHelper; + +class MoneyTypeTest extends TypeTestCase +{ + protected function setUp() + { + // we test against different locales, so we need the full + // implementation + IntlTestHelper::requireFullIntl($this); + + parent::setUp(); + } + + public function testPassMoneyPatternToView() + { + \Locale::setDefault('de_DE'); + + $form = $this->factory->create('money'); + $view = $form->createView(); + + $this->assertSame('{{ widget }} €', $view->vars['money_pattern']); + } + + public function testMoneyPatternWorksForYen() + { + \Locale::setDefault('en_US'); + + $form = $this->factory->create('money', null, array('currency' => 'JPY')); + $view = $form->createView(); + $this->assertTrue((Boolean) strstr($view->vars['money_pattern'], '¥')); + } + + // https://github.com/symfony/symfony/issues/5458 + public function testPassDifferentPatternsForDifferentCurrencies() + { + \Locale::setDefault('de_DE'); + + $form1 = $this->factory->create('money', null, array('currency' => 'GBP')); + $form2 = $this->factory->create('money', null, array('currency' => 'EUR')); + $view1 = $form1->createView(); + $view2 = $form2->createView(); + + $this->assertSame('{{ widget }} £', $view1->vars['money_pattern']); + $this->assertSame('{{ widget }} €', $view2->vars['money_pattern']); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php new file mode 100644 index 00000000..e5b3dd74 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Intl\Util\IntlTestHelper; + +class NumberTypeTest extends TypeTestCase +{ + protected function setUp() + { + parent::setUp(); + + // we test against "de_DE", so we need the full implementation + IntlTestHelper::requireFullIntl($this); + + \Locale::setDefault('de_DE'); + } + + public function testDefaultFormatting() + { + $form = $this->factory->create('number'); + $form->setData('12345.67890'); + $view = $form->createView(); + + $this->assertSame('12345,679', $view->vars['value']); + } + + public function testDefaultFormattingWithGrouping() + { + $form = $this->factory->create('number', null, array('grouping' => true)); + $form->setData('12345.67890'); + $view = $form->createView(); + + $this->assertSame('12.345,679', $view->vars['value']); + } + + public function testDefaultFormattingWithPrecision() + { + $form = $this->factory->create('number', null, array('precision' => 2)); + $form->setData('12345.67890'); + $view = $form->createView(); + + $this->assertSame('12345,68', $view->vars['value']); + } + + public function testDefaultFormattingWithRounding() + { + $form = $this->factory->create('number', null, array('precision' => 0, 'rounding_mode' => \NumberFormatter::ROUND_UP)); + $form->setData('12345.54321'); + $view = $form->createView(); + + $this->assertSame('12346', $view->vars['value']); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/PasswordTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/PasswordTypeTest.php new file mode 100644 index 00000000..bccb6f7b --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/PasswordTypeTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +class PasswordTypeTest extends \Symfony\Component\Form\Test\TypeTestCase +{ + public function testEmptyIfNotSubmitted() + { + $form = $this->factory->create('password'); + $form->setData('pAs5w0rd'); + $view = $form->createView(); + + $this->assertSame('', $view->vars['value']); + } + + public function testEmptyIfSubmitted() + { + $form = $this->factory->create('password'); + $form->submit('pAs5w0rd'); + $view = $form->createView(); + + $this->assertSame('', $view->vars['value']); + } + + public function testNotEmptyIfSubmittedAndNotAlwaysEmpty() + { + $form = $this->factory->create('password', null, array('always_empty' => false)); + $form->submit('pAs5w0rd'); + $view = $form->createView(); + + $this->assertSame('pAs5w0rd', $view->vars['value']); + } + + public function testNotTrimmed() + { + $form = $this->factory->create('password', null); + $form->submit(' pAs5w0rd '); + $data = $form->getData(); + + $this->assertSame(' pAs5w0rd ', $data); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php new file mode 100644 index 00000000..9e125d78 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/RepeatedTypeTest.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +class RepeatedTypeTest extends \Symfony\Component\Form\Test\TypeTestCase +{ + protected $form; + + protected function setUp() + { + parent::setUp(); + + $this->form = $this->factory->create('repeated', null, array( + 'type' => 'text', + )); + $this->form->setData(null); + } + + public function testSetData() + { + $this->form->setData('foobar'); + + $this->assertEquals('foobar', $this->form['first']->getData()); + $this->assertEquals('foobar', $this->form['second']->getData()); + } + + public function testSetOptions() + { + $form = $this->factory->create('repeated', null, array( + 'type' => 'text', + 'options' => array('label' => 'Global'), + )); + + $this->assertEquals('Global', $form['first']->getConfig()->getOption('label')); + $this->assertEquals('Global', $form['second']->getConfig()->getOption('label')); + $this->assertTrue($form['first']->isRequired()); + $this->assertTrue($form['second']->isRequired()); + } + + public function testSetOptionsPerChild() + { + $form = $this->factory->create('repeated', null, array( + // the global required value cannot be overridden + 'type' => 'text', + 'first_options' => array('label' => 'Test', 'required' => false), + 'second_options' => array('label' => 'Test2') + )); + + $this->assertEquals('Test', $form['first']->getConfig()->getOption('label')); + $this->assertEquals('Test2', $form['second']->getConfig()->getOption('label')); + $this->assertTrue($form['first']->isRequired()); + $this->assertTrue($form['second']->isRequired()); + } + + public function testSetRequired() + { + $form = $this->factory->create('repeated', null, array( + 'required' => false, + 'type' => 'text', + )); + + $this->assertFalse($form['first']->isRequired()); + $this->assertFalse($form['second']->isRequired()); + } + + public function testSetErrorBubblingToTrue() + { + $form = $this->factory->create('repeated', null, array( + 'error_bubbling' => true, + )); + + $this->assertTrue($form->getConfig()->getOption('error_bubbling')); + $this->assertTrue($form['first']->getConfig()->getOption('error_bubbling')); + $this->assertTrue($form['second']->getConfig()->getOption('error_bubbling')); + } + + public function testSetErrorBubblingToFalse() + { + $form = $this->factory->create('repeated', null, array( + 'error_bubbling' => false, + )); + + $this->assertFalse($form->getConfig()->getOption('error_bubbling')); + $this->assertFalse($form['first']->getConfig()->getOption('error_bubbling')); + $this->assertFalse($form['second']->getConfig()->getOption('error_bubbling')); + } + + public function testSetErrorBubblingIndividually() + { + $form = $this->factory->create('repeated', null, array( + 'error_bubbling' => true, + 'options' => array('error_bubbling' => false), + 'second_options' => array('error_bubbling' => true), + )); + + $this->assertTrue($form->getConfig()->getOption('error_bubbling')); + $this->assertFalse($form['first']->getConfig()->getOption('error_bubbling')); + $this->assertTrue($form['second']->getConfig()->getOption('error_bubbling')); + } + + public function testSetOptionsPerChildAndOverwrite() + { + $form = $this->factory->create('repeated', null, array( + 'type' => 'text', + 'options' => array('label' => 'Label'), + 'second_options' => array('label' => 'Second label') + )); + + $this->assertEquals('Label', $form['first']->getConfig()->getOption('label')); + $this->assertEquals('Second label', $form['second']->getConfig()->getOption('label')); + $this->assertTrue($form['first']->isRequired()); + $this->assertTrue($form['second']->isRequired()); + } + + public function testSubmitUnequal() + { + $input = array('first' => 'foo', 'second' => 'bar'); + + $this->form->submit($input); + + $this->assertEquals('foo', $this->form['first']->getViewData()); + $this->assertEquals('bar', $this->form['second']->getViewData()); + $this->assertFalse($this->form->isSynchronized()); + $this->assertEquals($input, $this->form->getViewData()); + $this->assertNull($this->form->getData()); + } + + public function testSubmitEqual() + { + $input = array('first' => 'foo', 'second' => 'foo'); + + $this->form->submit($input); + + $this->assertEquals('foo', $this->form['first']->getViewData()); + $this->assertEquals('foo', $this->form['second']->getViewData()); + $this->assertTrue($this->form->isSynchronized()); + $this->assertEquals($input, $this->form->getViewData()); + $this->assertEquals('foo', $this->form->getData()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/SubmitTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/SubmitTypeTest.php new file mode 100644 index 00000000..8cc72281 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/SubmitTypeTest.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +/** + * @author Bernhard Schussek + */ +class SubmitTypeTest extends TypeTestCase +{ + public function testCreateSubmitButtonInstances() + { + $this->assertInstanceOf('Symfony\Component\Form\SubmitButton', $this->factory->create('submit')); + } + + public function testNotClickedByDefault() + { + $button = $this->factory->create('submit'); + + $this->assertFalse($button->isClicked()); + } + + public function testNotClickedIfSubmittedWithNull() + { + $button = $this->factory->create('submit'); + $button->submit(null); + + $this->assertFalse($button->isClicked()); + } + + public function testClickedIfSubmittedWithEmptyString() + { + $button = $this->factory->create('submit'); + $button->submit(''); + + $this->assertTrue($button->isClicked()); + } + + public function testClickedIfSubmittedWithUnemptyString() + { + $button = $this->factory->create('submit'); + $button->submit('foo'); + + $this->assertTrue($button->isClicked()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php new file mode 100644 index 00000000..9bdfe156 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TimeTypeTest.php @@ -0,0 +1,649 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Extension\Core\View\ChoiceView; +use Symfony\Component\Form\FormError; +use Symfony\Component\Intl\Util\IntlTestHelper; + +class TimeTypeTest extends TypeTestCase +{ + protected function setUp() + { + IntlTestHelper::requireIntl($this); + + parent::setUp(); + } + + public function testSubmitDateTime() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'datetime', + )); + + $input = array( + 'hour' => '3', + 'minute' => '4', + ); + + $form->submit($input); + + $dateTime = new \DateTime('1970-01-01 03:04:00 UTC'); + + $this->assertEquals($dateTime, $form->getData()); + $this->assertEquals($input, $form->getViewData()); + } + + public function testSubmitString() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + )); + + $input = array( + 'hour' => '3', + 'minute' => '4', + ); + + $form->submit($input); + + $this->assertEquals('03:04:00', $form->getData()); + $this->assertEquals($input, $form->getViewData()); + } + + public function testSubmitTimestamp() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'timestamp', + )); + + $input = array( + 'hour' => '3', + 'minute' => '4', + ); + + $form->submit($input); + + $dateTime = new \DateTime('1970-01-01 03:04:00 UTC'); + + $this->assertEquals($dateTime->format('U'), $form->getData()); + $this->assertEquals($input, $form->getViewData()); + } + + public function testSubmitArray() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'array', + )); + + $input = array( + 'hour' => '3', + 'minute' => '4', + ); + + $form->submit($input); + + $this->assertEquals($input, $form->getData()); + $this->assertEquals($input, $form->getViewData()); + } + + public function testSubmitDatetimeSingleText() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'datetime', + 'widget' => 'single_text', + )); + + $form->submit('03:04'); + + $this->assertEquals(new \DateTime('1970-01-01 03:04:00 UTC'), $form->getData()); + $this->assertEquals('03:04', $form->getViewData()); + } + + public function testSubmitDatetimeSingleTextWithoutMinutes() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'datetime', + 'widget' => 'single_text', + 'with_minutes' => false, + )); + + $form->submit('03'); + + $this->assertEquals(new \DateTime('1970-01-01 03:00:00 UTC'), $form->getData()); + $this->assertEquals('03', $form->getViewData()); + } + + public function testSubmitArraySingleText() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'array', + 'widget' => 'single_text', + )); + + $data = array( + 'hour' => '3', + 'minute' => '4', + ); + + $form->submit('03:04'); + + $this->assertEquals($data, $form->getData()); + $this->assertEquals('03:04', $form->getViewData()); + } + + public function testSubmitArraySingleTextWithoutMinutes() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'array', + 'widget' => 'single_text', + 'with_minutes' => false, + )); + + $data = array( + 'hour' => '3', + ); + + $form->submit('03'); + + $this->assertEquals($data, $form->getData()); + $this->assertEquals('03', $form->getViewData()); + } + + public function testSubmitArraySingleTextWithSeconds() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'array', + 'widget' => 'single_text', + 'with_seconds' => true, + )); + + $data = array( + 'hour' => '3', + 'minute' => '4', + 'second' => '5', + ); + + $form->submit('03:04:05'); + + $this->assertEquals($data, $form->getData()); + $this->assertEquals('03:04:05', $form->getViewData()); + } + + public function testSubmitStringSingleText() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + 'widget' => 'single_text', + )); + + $form->submit('03:04'); + + $this->assertEquals('03:04:00', $form->getData()); + $this->assertEquals('03:04', $form->getViewData()); + } + + public function testSubmitStringSingleTextWithoutMinutes() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'string', + 'widget' => 'single_text', + 'with_minutes' => false, + )); + + $form->submit('03'); + + $this->assertEquals('03:00:00', $form->getData()); + $this->assertEquals('03', $form->getViewData()); + } + + public function testSetDataWithoutMinutes() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'datetime', + 'with_minutes' => false, + )); + + $form->setData(new \DateTime('03:04:05 UTC')); + + $this->assertEquals(array('hour' => 3), $form->getViewData()); + } + + public function testSetDataWithSeconds() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'UTC', + 'view_timezone' => 'UTC', + 'input' => 'datetime', + 'with_seconds' => true, + )); + + $form->setData(new \DateTime('03:04:05 UTC')); + + $this->assertEquals(array('hour' => 3, 'minute' => 4, 'second' => 5), $form->getViewData()); + } + + public function testSetDataDifferentTimezones() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'America/New_York', + 'view_timezone' => 'Asia/Hong_Kong', + 'input' => 'string', + 'with_seconds' => true, + )); + + $dateTime = new \DateTime('2013-01-01 12:04:05'); + $dateTime->setTimezone(new \DateTimeZone('America/New_York')); + + $form->setData($dateTime->format('H:i:s')); + + $outputTime = clone $dateTime; + $outputTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $displayedData = array( + 'hour' => (int) $outputTime->format('H'), + 'minute' => (int) $outputTime->format('i'), + 'second' => (int) $outputTime->format('s') + ); + + $this->assertEquals($displayedData, $form->getViewData()); + } + + public function testSetDataDifferentTimezonesDateTime() + { + $form = $this->factory->create('time', null, array( + 'model_timezone' => 'America/New_York', + 'view_timezone' => 'Asia/Hong_Kong', + 'input' => 'datetime', + 'with_seconds' => true, + )); + + $dateTime = new \DateTime('12:04:05'); + $dateTime->setTimezone(new \DateTimeZone('America/New_York')); + + $form->setData($dateTime); + + $outputTime = clone $dateTime; + $outputTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $displayedData = array( + 'hour' => (int) $outputTime->format('H'), + 'minute' => (int) $outputTime->format('i'), + 'second' => (int) $outputTime->format('s') + ); + + $this->assertDateTimeEquals($dateTime, $form->getData()); + $this->assertEquals($displayedData, $form->getViewData()); + } + + public function testHoursOption() + { + $form = $this->factory->create('time', null, array( + 'hours' => array(6, 7), + )); + + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('6', '6', '06'), + new ChoiceView('7', '7', '07'), + ), $view['hour']->vars['choices']); + } + + public function testIsMinuteWithinRangeReturnsTrueIfWithin() + { + $form = $this->factory->create('time', null, array( + 'minutes' => array(6, 7), + )); + + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('6', '6', '06'), + new ChoiceView('7', '7', '07'), + ), $view['minute']->vars['choices']); + } + + public function testIsSecondWithinRangeReturnsTrueIfWithin() + { + $form = $this->factory->create('time', null, array( + 'seconds' => array(6, 7), + 'with_seconds' => true, + )); + + $view = $form->createView(); + + $this->assertEquals(array( + new ChoiceView('6', '6', '06'), + new ChoiceView('7', '7', '07'), + ), $view['second']->vars['choices']); + } + + public function testIsPartiallyFilledReturnsFalseIfCompletelyEmpty() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('time', null, array( + 'widget' => 'choice', + )); + + $form->submit(array( + 'hour' => '', + 'minute' => '', + )); + + $this->assertFalse($form->isPartiallyFilled()); + } + + public function testIsPartiallyFilledReturnsFalseIfCompletelyEmptyWithSeconds() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('time', null, array( + 'widget' => 'choice', + 'with_seconds' => true, + )); + + $form->submit(array( + 'hour' => '', + 'minute' => '', + 'second' => '', + )); + + $this->assertFalse($form->isPartiallyFilled()); + } + + public function testIsPartiallyFilledReturnsFalseIfCompletelyFilled() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('time', null, array( + 'widget' => 'choice', + )); + + $form->submit(array( + 'hour' => '0', + 'minute' => '0', + )); + + $this->assertFalse($form->isPartiallyFilled()); + } + + public function testIsPartiallyFilledReturnsFalseIfCompletelyFilledWithSeconds() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('time', null, array( + 'widget' => 'choice', + 'with_seconds' => true, + )); + + $form->submit(array( + 'hour' => '0', + 'minute' => '0', + 'second' => '0', + )); + + $this->assertFalse($form->isPartiallyFilled()); + } + + public function testIsPartiallyFilledReturnsTrueIfChoiceAndHourEmpty() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('time', null, array( + 'widget' => 'choice', + 'with_seconds' => true, + )); + + $form->submit(array( + 'hour' => '', + 'minute' => '0', + 'second' => '0', + )); + + $this->assertTrue($form->isPartiallyFilled()); + } + + public function testIsPartiallyFilledReturnsTrueIfChoiceAndMinuteEmpty() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('time', null, array( + 'widget' => 'choice', + 'with_seconds' => true, + )); + + $form->submit(array( + 'hour' => '0', + 'minute' => '', + 'second' => '0', + )); + + $this->assertTrue($form->isPartiallyFilled()); + } + + public function testIsPartiallyFilledReturnsTrueIfChoiceAndSecondsEmpty() + { + $this->markTestIncomplete('Needs to be reimplemented using validators'); + + $form = $this->factory->create('time', null, array( + 'widget' => 'choice', + 'with_seconds' => true, + )); + + $form->submit(array( + 'hour' => '0', + 'minute' => '0', + 'second' => '', + )); + + $this->assertTrue($form->isPartiallyFilled()); + } + + // Bug fix + public function testInitializeWithDateTime() + { + // Throws an exception if "data_class" option is not explicitly set + // to null in the type + $this->factory->create('time', new \DateTime()); + } + + public function testSingleTextWidgetShouldUseTheRightInputType() + { + $form = $this->factory->create('time', null, array( + 'widget' => 'single_text', + )); + + $view = $form->createView(); + $this->assertEquals('time', $view->vars['type']); + } + + public function testPassDefaultEmptyValueToViewIfNotRequired() + { + $form = $this->factory->create('time', null, array( + 'required' => false, + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('', $view['hour']->vars['empty_value']); + $this->assertSame('', $view['minute']->vars['empty_value']); + $this->assertSame('', $view['second']->vars['empty_value']); + } + + public function testPassNoEmptyValueToViewIfRequired() + { + $form = $this->factory->create('time', null, array( + 'required' => true, + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertNull($view['hour']->vars['empty_value']); + $this->assertNull($view['minute']->vars['empty_value']); + $this->assertNull($view['second']->vars['empty_value']); + } + + public function testPassEmptyValueAsString() + { + $form = $this->factory->create('time', null, array( + 'empty_value' => 'Empty', + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty', $view['hour']->vars['empty_value']); + $this->assertSame('Empty', $view['minute']->vars['empty_value']); + $this->assertSame('Empty', $view['second']->vars['empty_value']); + } + + public function testPassEmptyValueAsArray() + { + $form = $this->factory->create('time', null, array( + 'empty_value' => array( + 'hour' => 'Empty hour', + 'minute' => 'Empty minute', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty hour', $view['hour']->vars['empty_value']); + $this->assertSame('Empty minute', $view['minute']->vars['empty_value']); + $this->assertSame('Empty second', $view['second']->vars['empty_value']); + } + + public function testPassEmptyValueAsPartialArrayAddEmptyIfNotRequired() + { + $form = $this->factory->create('time', null, array( + 'required' => false, + 'empty_value' => array( + 'hour' => 'Empty hour', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty hour', $view['hour']->vars['empty_value']); + $this->assertSame('', $view['minute']->vars['empty_value']); + $this->assertSame('Empty second', $view['second']->vars['empty_value']); + } + + public function testPassEmptyValueAsPartialArrayAddNullIfRequired() + { + $form = $this->factory->create('time', null, array( + 'required' => true, + 'empty_value' => array( + 'hour' => 'Empty hour', + 'second' => 'Empty second', + ), + 'with_seconds' => true, + )); + + $view = $form->createView(); + $this->assertSame('Empty hour', $view['hour']->vars['empty_value']); + $this->assertNull($view['minute']->vars['empty_value']); + $this->assertSame('Empty second', $view['second']->vars['empty_value']); + } + + public function provideCompoundWidgets() + { + return array( + array('text'), + array('choice'), + ); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testHourErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('time', null, array( + 'widget' => $widget, + )); + $form['hour']->addError($error); + + $this->assertSame(array(), $form['hour']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testMinuteErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('time', null, array( + 'widget' => $widget, + )); + $form['minute']->addError($error); + + $this->assertSame(array(), $form['minute']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + /** + * @dataProvider provideCompoundWidgets + */ + public function testSecondErrorsBubbleUp($widget) + { + $error = new FormError('Invalid!'); + $form = $this->factory->create('time', null, array( + 'widget' => $widget, + 'with_seconds' => true, + )); + $form['second']->addError($error); + + $this->assertSame(array(), $form['second']->getErrors()); + $this->assertSame(array($error), $form->getErrors()); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\InvalidConfigurationException + */ + public function testInitializeWithSecondsAndWithoutMinutes() + { + $this->factory->create('time', null, array( + 'with_minutes' => false, + 'with_seconds' => true, + )); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TimezoneTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TimezoneTypeTest.php new file mode 100644 index 00000000..81df20cb --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TimezoneTypeTest.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Extension\Core\View\ChoiceView; + +class TimezoneTypeTest extends \Symfony\Component\Form\Test\TypeTestCase +{ + public function testTimezonesAreSelectable() + { + $form = $this->factory->create('timezone'); + $view = $form->createView(); + $choices = $view->vars['choices']; + + $this->assertArrayHasKey('Africa', $choices); + $this->assertContains(new ChoiceView('Africa/Kinshasa', 'Africa/Kinshasa', 'Kinshasa'), $choices['Africa'], '', false, false); + + $this->assertArrayHasKey('America', $choices); + $this->assertContains(new ChoiceView('America/New_York', 'America/New_York', 'New York'), $choices['America'], '', false, false); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TypeTestCase.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TypeTestCase.php new file mode 100644 index 00000000..733546e3 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/TypeTestCase.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Test\TypeTestCase as BaseTypeTestCase; + +/** + * @deprecated Deprecated since version 2.3, to be removed in 3.0. Use Symfony\Component\Form\Test\TypeTestCase instead. + */ +abstract class TypeTestCase extends BaseTypeTestCase +{ +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php new file mode 100644 index 00000000..254b2a8e --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Core/Type/UrlTypeTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +class UrlTypeTest extends TypeTestCase +{ + public function testSubmitAddsDefaultProtocolIfNoneIsIncluded() + { + $form = $this->factory->create('url', 'name'); + + $form->submit('www.domain.com'); + + $this->assertSame('http://www.domain.com', $form->getData()); + $this->assertSame('http://www.domain.com', $form->getViewData()); + } + + public function testSubmitAddsNoDefaultProtocolIfAlreadyIncluded() + { + $form = $this->factory->create('url', null, array( + 'default_protocol' => 'http', + )); + + $form->submit('ftp://www.domain.com'); + + $this->assertSame('ftp://www.domain.com', $form->getData()); + $this->assertSame('ftp://www.domain.com', $form->getViewData()); + } + + public function testSubmitAddsNoDefaultProtocolIfEmpty() + { + $form = $this->factory->create('url', null, array( + 'default_protocol' => 'http', + )); + + $form->submit(''); + + $this->assertNull($form->getData()); + $this->assertSame('', $form->getViewData()); + } + + public function testSubmitAddsNoDefaultProtocolIfSetToNull() + { + $form = $this->factory->create('url', null, array( + 'default_protocol' => null, + )); + + $form->submit('www.domain.com'); + + $this->assertSame('www.domain.com', $form->getData()); + $this->assertSame('www.domain.com', $form->getViewData()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/DefaultCsrfProviderTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/DefaultCsrfProviderTest.php new file mode 100644 index 00000000..a99b5444 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/DefaultCsrfProviderTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Csrf\CsrfProvider; + +use Symfony\Component\Form\Extension\Csrf\CsrfProvider\DefaultCsrfProvider; + +/** + * @runTestsInSeparateProcesses + */ +class DefaultCsrfProviderTest extends \PHPUnit_Framework_TestCase +{ + protected $provider; + + public static function setUpBeforeClass() + { + ini_set('session.save_handler', 'files'); + ini_set('session.save_path', sys_get_temp_dir()); + } + + protected function setUp() + { + $this->provider = new DefaultCsrfProvider('SECRET'); + } + + protected function tearDown() + { + $this->provider = null; + } + + public function testGenerateCsrfToken() + { + session_start(); + + $token = $this->provider->generateCsrfToken('foo'); + + $this->assertEquals(sha1('SECRET'.'foo'.session_id()), $token); + } + + public function testGenerateCsrfTokenOnUnstartedSession() + { + session_id('touti'); + + if (!version_compare(PHP_VERSION, '5.4', '>=')) { + $this->markTestSkipped('This test requires PHP >= 5.4'); + } + + $this->assertSame(PHP_SESSION_NONE, session_status()); + + $token = $this->provider->generateCsrfToken('foo'); + + $this->assertEquals(sha1('SECRET'.'foo'.session_id()), $token); + $this->assertSame(PHP_SESSION_ACTIVE, session_status()); + } + + public function testIsCsrfTokenValidSucceeds() + { + session_start(); + + $token = sha1('SECRET'.'foo'.session_id()); + + $this->assertTrue($this->provider->isCsrfTokenValid('foo', $token)); + } + + public function testIsCsrfTokenValidFails() + { + session_start(); + + $token = sha1('SECRET'.'bar'.session_id()); + + $this->assertFalse($this->provider->isCsrfTokenValid('foo', $token)); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/SessionCsrfProviderTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/SessionCsrfProviderTest.php new file mode 100644 index 00000000..1dcc6b4c --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/SessionCsrfProviderTest.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Csrf\CsrfProvider; + +use Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider; + +class SessionCsrfProviderTest extends \PHPUnit_Framework_TestCase +{ + protected $provider; + protected $session; + + protected function setUp() + { + if (!class_exists('Symfony\Component\HttpFoundation\Session\Session')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $this->session = $this->getMock( + 'Symfony\Component\HttpFoundation\Session\Session', + array(), + array(), + '', + false // don't call constructor + ); + $this->provider = new SessionCsrfProvider($this->session, 'SECRET'); + } + + protected function tearDown() + { + $this->provider = null; + $this->session = null; + } + + public function testGenerateCsrfToken() + { + $this->session->expects($this->once()) + ->method('getId') + ->will($this->returnValue('ABCDEF')); + + $token = $this->provider->generateCsrfToken('foo'); + + $this->assertEquals(sha1('SECRET'.'foo'.'ABCDEF'), $token); + } + + public function testIsCsrfTokenValidSucceeds() + { + $this->session->expects($this->once()) + ->method('getId') + ->will($this->returnValue('ABCDEF')); + + $token = sha1('SECRET'.'foo'.'ABCDEF'); + + $this->assertTrue($this->provider->isCsrfTokenValid('foo', $token)); + } + + public function testIsCsrfTokenValidFails() + { + $this->session->expects($this->once()) + ->method('getId') + ->will($this->returnValue('ABCDEF')); + + $token = sha1('SECRET'.'bar'.'ABCDEF'); + + $this->assertFalse($this->provider->isCsrfTokenValid('foo', $token)); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php new file mode 100644 index 00000000..0bcfe74e --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/EventListener/CsrfValidationListenerTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Csrf\EventListener; + +use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener; + +class CsrfValidationListenerTest extends \PHPUnit_Framework_TestCase +{ + protected $dispatcher; + protected $factory; + protected $csrfProvider; + + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->factory = $this->getMock('Symfony\Component\Form\FormFactoryInterface'); + $this->csrfProvider = $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'); + $this->form = $this->getBuilder('post') + ->setDataMapper($this->getDataMapper()) + ->getForm(); + } + + protected function tearDown() + { + $this->dispatcher = null; + $this->factory = null; + $this->csrfProvider = null; + $this->form = null; + } + + protected function getBuilder($name = 'name') + { + return new FormBuilder($name, null, $this->dispatcher, $this->factory, array('compound' => true)); + } + + protected function getForm($name = 'name') + { + return $this->getBuilder($name)->getForm(); + } + + protected function getDataMapper() + { + return $this->getMock('Symfony\Component\Form\DataMapperInterface'); + } + + protected function getMockForm() + { + return $this->getMock('Symfony\Component\Form\Test\FormInterface'); + } + + // https://github.com/symfony/symfony/pull/5838 + public function testStringFormData() + { + $data = "XP4HUzmHPi"; + $event = new FormEvent($this->form, $data); + + $validation = new CsrfValidationListener('csrf', $this->csrfProvider, 'unknown', 'Invalid.'); + $validation->preSubmit($event); + + // Validate accordingly + $this->assertSame($data, $event->getData()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php new file mode 100644 index 00000000..0a1f0dc4 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Csrf/Type/FormTypeCsrfExtensionTest.php @@ -0,0 +1,301 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Csrf\Type; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormError; +use Symfony\Component\Form\Test\TypeTestCase; +use Symfony\Component\Form\Extension\Csrf\CsrfExtension; + +class FormTypeCsrfExtensionTest_ChildType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + // The form needs a child in order to trigger CSRF protection by + // default + $builder->add('name', 'text'); + } + + public function getName() + { + return 'csrf_collection_test'; + } +} + +class FormTypeCsrfExtensionTest extends TypeTestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $csrfProvider; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $translator; + + protected function setUp() + { + $this->csrfProvider = $this->getMock('Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface'); + $this->translator = $this->getMock('Symfony\Component\Translation\TranslatorInterface'); + + parent::setUp(); + } + + protected function tearDown() + { + $this->csrfProvider = null; + $this->translator = null; + + parent::tearDown(); + } + + protected function getExtensions() + { + return array_merge(parent::getExtensions(), array( + new CsrfExtension($this->csrfProvider, $this->translator), + )); + } + + public function testCsrfProtectionByDefaultIfRootAndCompound() + { + $view = $this->factory + ->create('form', null, array( + 'csrf_field_name' => 'csrf', + 'compound' => true, + )) + ->createView(); + + $this->assertTrue(isset($view['csrf'])); + } + + public function testNoCsrfProtectionByDefaultIfCompoundButNotRoot() + { + $view = $this->factory + ->createNamedBuilder('root', 'form') + ->add($this->factory + ->createNamedBuilder('form', 'form', null, array( + 'csrf_field_name' => 'csrf', + 'compound' => true, + )) + ) + ->getForm() + ->get('form') + ->createView(); + + $this->assertFalse(isset($view['csrf'])); + } + + public function testNoCsrfProtectionByDefaultIfRootButNotCompound() + { + $view = $this->factory + ->create('form', null, array( + 'csrf_field_name' => 'csrf', + 'compound' => false, + )) + ->createView(); + + $this->assertFalse(isset($view['csrf'])); + } + + public function testCsrfProtectionCanBeDisabled() + { + $view = $this->factory + ->create('form', null, array( + 'csrf_field_name' => 'csrf', + 'csrf_protection' => false, + 'compound' => true, + )) + ->createView(); + + $this->assertFalse(isset($view['csrf'])); + } + + public function testGenerateCsrfToken() + { + $this->csrfProvider->expects($this->once()) + ->method('generateCsrfToken') + ->with('%INTENTION%') + ->will($this->returnValue('token')); + + $view = $this->factory + ->create('form', null, array( + 'csrf_field_name' => 'csrf', + 'csrf_provider' => $this->csrfProvider, + 'intention' => '%INTENTION%', + 'compound' => true, + )) + ->createView(); + + $this->assertEquals('token', $view['csrf']->vars['value']); + } + + public function provideBoolean() + { + return array( + array(true), + array(false), + ); + } + + /** + * @dataProvider provideBoolean + */ + public function testValidateTokenOnSubmitIfRootAndCompound($valid) + { + $this->csrfProvider->expects($this->once()) + ->method('isCsrfTokenValid') + ->with('%INTENTION%', 'token') + ->will($this->returnValue($valid)); + + $form = $this->factory + ->createBuilder('form', null, array( + 'csrf_field_name' => 'csrf', + 'csrf_provider' => $this->csrfProvider, + 'intention' => '%INTENTION%', + 'compound' => true, + )) + ->add('child', 'text') + ->getForm(); + + $form->submit(array( + 'child' => 'foobar', + 'csrf' => 'token', + )); + + // Remove token from data + $this->assertSame(array('child' => 'foobar'), $form->getData()); + + // Validate accordingly + $this->assertSame($valid, $form->isValid()); + } + + public function testFailIfRootAndCompoundAndTokenMissing() + { + $this->csrfProvider->expects($this->never()) + ->method('isCsrfTokenValid'); + + $form = $this->factory + ->createBuilder('form', null, array( + 'csrf_field_name' => 'csrf', + 'csrf_provider' => $this->csrfProvider, + 'intention' => '%INTENTION%', + 'compound' => true, + )) + ->add('child', 'text') + ->getForm(); + + $form->submit(array( + 'child' => 'foobar', + // token is missing + )); + + // Remove token from data + $this->assertSame(array('child' => 'foobar'), $form->getData()); + + // Validate accordingly + $this->assertFalse($form->isValid()); + } + + public function testDontValidateTokenIfCompoundButNoRoot() + { + $this->csrfProvider->expects($this->never()) + ->method('isCsrfTokenValid'); + + $form = $this->factory + ->createNamedBuilder('root', 'form') + ->add($this->factory + ->createNamedBuilder('form', 'form', null, array( + 'csrf_field_name' => 'csrf', + 'csrf_provider' => $this->csrfProvider, + 'intention' => '%INTENTION%', + 'compound' => true, + )) + ) + ->getForm() + ->get('form'); + + $form->submit(array( + 'child' => 'foobar', + 'csrf' => 'token', + )); + } + + public function testDontValidateTokenIfRootButNotCompound() + { + $this->csrfProvider->expects($this->never()) + ->method('isCsrfTokenValid'); + + $form = $this->factory + ->create('form', null, array( + 'csrf_field_name' => 'csrf', + 'csrf_provider' => $this->csrfProvider, + 'intention' => '%INTENTION%', + 'compound' => false, + )); + + $form->submit(array( + 'csrf' => 'token', + )); + } + + public function testNoCsrfProtectionOnPrototype() + { + $prototypeView = $this->factory + ->create('collection', null, array( + 'type' => new FormTypeCsrfExtensionTest_ChildType(), + 'options' => array( + 'csrf_field_name' => 'csrf', + ), + 'prototype' => true, + 'allow_add' => true, + )) + ->createView() + ->vars['prototype']; + + $this->assertFalse(isset($prototypeView['csrf'])); + $this->assertCount(1, $prototypeView); + } + + public function testsTranslateCustomErrorMessage() + { + $this->csrfProvider->expects($this->once()) + ->method('isCsrfTokenValid') + ->with('%INTENTION%', 'token') + ->will($this->returnValue(false)); + + $this->translator->expects($this->once()) + ->method('trans') + ->with('Foobar') + ->will($this->returnValue('[trans]Foobar[/trans]')); + + $form = $this->factory + ->createBuilder('form', null, array( + 'csrf_field_name' => 'csrf', + 'csrf_provider' => $this->csrfProvider, + 'csrf_message' => 'Foobar', + 'intention' => '%INTENTION%', + 'compound' => true, + )) + ->getForm(); + + $form->submit(array( + 'csrf' => 'token', + )); + + $errors = $form->getErrors(); + + $this->assertGreaterThan(0, count($errors)); + $this->assertEquals(new FormError('[trans]Foobar[/trans]'), $errors[0]); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/HttpFoundation/EventListener/BindRequestListenerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/HttpFoundation/EventListener/BindRequestListenerTest.php new file mode 100644 index 00000000..2ff072b2 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/HttpFoundation/EventListener/BindRequestListenerTest.php @@ -0,0 +1,286 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\HttpFoundation\EventListener; + +use Symfony\Component\Form\Extension\HttpFoundation\EventListener\BindRequestListener; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormConfigBuilder; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\Test\DeprecationErrorHandler; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\File\UploadedFile; + +/** + * @author Bernhard Schussek + */ +class BindRequestListenerTest extends \PHPUnit_Framework_TestCase +{ + private $values; + + private $filesPlain; + + private $filesNested; + + /** + * @var UploadedFile + */ + private $uploadedFile; + + protected function setUp() + { + $path = tempnam(sys_get_temp_dir(), 'sf2'); + touch($path); + + $this->values = array( + 'name' => 'Bernhard', + 'image' => array('filename' => 'foobar.png'), + ); + + $this->filesPlain = array( + 'image' => array( + 'error' => UPLOAD_ERR_OK, + 'name' => 'upload.png', + 'size' => 123, + 'tmp_name' => $path, + 'type' => 'image/png' + ), + ); + + $this->filesNested = array( + 'error' => array('image' => UPLOAD_ERR_OK), + 'name' => array('image' => 'upload.png'), + 'size' => array('image' => 123), + 'tmp_name' => array('image' => $path), + 'type' => array('image' => 'image/png'), + ); + + $this->uploadedFile = new UploadedFile($path, 'upload.png', 'image/png', 123, UPLOAD_ERR_OK); + } + + protected function tearDown() + { + unlink($this->uploadedFile->getRealPath()); + } + + public function requestMethodProvider() + { + return array( + array('POST'), + array('PUT'), + array('DELETE'), + array('PATCH'), + ); + } + + /** + * @dataProvider requestMethodProvider + */ + public function testSubmitRequest($method) + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $values = array('author' => $this->values); + $files = array('author' => $this->filesNested); + $request = new Request(array(), $values, array(), array(), $files, array( + 'REQUEST_METHOD' => $method, + )); + + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $config = new FormConfigBuilder('author', null, $dispatcher); + $form = new Form($config); + $event = new FormEvent($form, $request); + + $listener = new BindRequestListener(); + DeprecationErrorHandler::preBind($listener, $event); + + $this->assertEquals(array( + 'name' => 'Bernhard', + 'image' => $this->uploadedFile, + ), $event->getData()); + } + + /** + * @dataProvider requestMethodProvider + */ + public function testSubmitRequestWithEmptyName($method) + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $request = new Request(array(), $this->values, array(), array(), $this->filesPlain, array( + 'REQUEST_METHOD' => $method, + )); + + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $config = new FormConfigBuilder('', null, $dispatcher); + $form = new Form($config); + $event = new FormEvent($form, $request); + + $listener = new BindRequestListener(); + DeprecationErrorHandler::preBind($listener, $event); + + $this->assertEquals(array( + 'name' => 'Bernhard', + 'image' => $this->uploadedFile, + ), $event->getData()); + } + + /** + * @dataProvider requestMethodProvider + */ + public function testSubmitEmptyRequestToCompoundForm($method) + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $request = new Request(array(), array(), array(), array(), array(), array( + 'REQUEST_METHOD' => $method, + )); + + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $config = new FormConfigBuilder('author', null, $dispatcher); + $config->setCompound(true); + $config->setDataMapper($this->getMock('Symfony\Component\Form\DataMapperInterface')); + $form = new Form($config); + $event = new FormEvent($form, $request); + + $listener = new BindRequestListener(); + DeprecationErrorHandler::preBind($listener, $event); + + // Default to empty array + $this->assertEquals(array(), $event->getData()); + } + + /** + * @dataProvider requestMethodProvider + */ + public function testSubmitEmptyRequestToSimpleForm($method) + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $request = new Request(array(), array(), array(), array(), array(), array( + 'REQUEST_METHOD' => $method, + )); + + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $config = new FormConfigBuilder('author', null, $dispatcher); + $config->setCompound(false); + $form = new Form($config); + $event = new FormEvent($form, $request); + + $listener = new BindRequestListener(); + DeprecationErrorHandler::preBind($listener, $event); + + // Default to null + $this->assertNull($event->getData()); + } + + public function testSubmitGetRequest() + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $values = array('author' => $this->values); + $request = new Request($values, array(), array(), array(), array(), array( + 'REQUEST_METHOD' => 'GET', + )); + + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $config = new FormConfigBuilder('author', null, $dispatcher); + $form = new Form($config); + $event = new FormEvent($form, $request); + + $listener = new BindRequestListener(); + DeprecationErrorHandler::preBind($listener, $event); + + $this->assertEquals(array( + 'name' => 'Bernhard', + 'image' => array('filename' => 'foobar.png'), + ), $event->getData()); + } + + public function testSubmitGetRequestWithEmptyName() + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $request = new Request($this->values, array(), array(), array(), array(), array( + 'REQUEST_METHOD' => 'GET', + )); + + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $config = new FormConfigBuilder('', null, $dispatcher); + $form = new Form($config); + $event = new FormEvent($form, $request); + + $listener = new BindRequestListener(); + DeprecationErrorHandler::preBind($listener, $event); + + $this->assertEquals(array( + 'name' => 'Bernhard', + 'image' => array('filename' => 'foobar.png'), + ), $event->getData()); + } + + public function testSubmitEmptyGetRequestToCompoundForm() + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $request = new Request(array(), array(), array(), array(), array(), array( + 'REQUEST_METHOD' => 'GET', + )); + + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $config = new FormConfigBuilder('author', null, $dispatcher); + $config->setCompound(true); + $config->setDataMapper($this->getMock('Symfony\Component\Form\DataMapperInterface')); + $form = new Form($config); + $event = new FormEvent($form, $request); + + $listener = new BindRequestListener(); + DeprecationErrorHandler::preBind($listener, $event); + + $this->assertEquals(array(), $event->getData()); + } + + public function testSubmitEmptyGetRequestToSimpleForm() + { + if (!class_exists('Symfony\Component\HttpFoundation\Request')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $request = new Request(array(), array(), array(), array(), array(), array( + 'REQUEST_METHOD' => 'GET', + )); + + $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $config = new FormConfigBuilder('author', null, $dispatcher); + $config->setCompound(false); + $form = new Form($config); + $event = new FormEvent($form, $request); + + $listener = new BindRequestListener(); + DeprecationErrorHandler::preBind($listener, $event); + + $this->assertNull($event->getData()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php new file mode 100644 index 00000000..2d5cf776 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\HttpFoundation; + +use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler; +use Symfony\Component\Form\Tests\AbstractRequestHandlerTest; +use Symfony\Component\HttpFoundation\Request; + +/** + * @author Bernhard Schussek + */ +class HttpFoundationRequestHandlerTest extends AbstractRequestHandlerTest +{ + /** + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testRequestShouldNotBeNull() + { + $this->requestHandler->handleRequest($this->getMockForm('name', 'GET')); + } + /** + * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testRequestShouldBeInstanceOfRequest() + { + $this->requestHandler->handleRequest($this->getMockForm('name', 'GET'), new \stdClass()); + } + + protected function setRequestData($method, $data, $files = array()) + { + $this->request = Request::create('http://localhost', $method, $data, array(), $files); + } + + protected function getRequestHandler() + { + return new HttpFoundationRequestHandler(); + } + + protected function getMockFile() + { + return $this->getMockBuilder('Symfony\Component\HttpFoundation\File\UploadedFile') + ->disableOriginalConstructor() + ->getMock(); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php new file mode 100644 index 00000000..a8bdde8a --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -0,0 +1,748 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Validator\Constraints; + +use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\Exception\TransformationFailedException; +use Symfony\Component\Form\CallbackTransformer; +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\Extension\Validator\Constraints\Form; +use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator; +use Symfony\Component\Form\SubmitButtonBuilder; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\NotNull; +use Symfony\Component\Validator\Constraints\NotBlank; + +/** + * @author Bernhard Schussek + */ +class FormValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $dispatcher; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $factory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $serverParams; + + /** + * @var FormValidator + */ + private $validator; + + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\Event')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->factory = $this->getMock('Symfony\Component\Form\FormFactoryInterface'); + $this->serverParams = $this->getMock( + 'Symfony\Component\Form\Extension\Validator\Util\ServerParams', + array('getNormalizedIniPostMaxSize', 'getContentLength') + ); + $this->validator = new FormValidator($this->serverParams); + } + + public function testValidate() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + $options = array('validation_groups' => array('group1', 'group2')); + $form = $this->getBuilder('name', '\stdClass', $options) + ->setData($object) + ->getForm(); + + $context->expects($this->at(0)) + ->method('validate') + ->with($object, 'data', 'group1', true); + $context->expects($this->at(1)) + ->method('validate') + ->with($object, 'data', 'group2', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testValidateConstraints() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + $constraint1 = new NotNull(array('groups' => array('group1', 'group2'))); + $constraint2 = new NotBlank(array('groups' => 'group2')); + + $options = array( + 'validation_groups' => array('group1', 'group2'), + 'constraints' => array($constraint1, $constraint2), + ); + $form = $this->getBuilder('name', '\stdClass', $options) + ->setData($object) + ->getForm(); + + // First default constraints + $context->expects($this->at(0)) + ->method('validate') + ->with($object, 'data', 'group1', true); + $context->expects($this->at(1)) + ->method('validate') + ->with($object, 'data', 'group2', true); + + // Then custom constraints + $context->expects($this->at(2)) + ->method('validateValue') + ->with($object, $constraint1, 'data', 'group1'); + $context->expects($this->at(3)) + ->method('validateValue') + ->with($object, $constraint2, 'data', 'group2'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testDontValidateIfParentWithoutCascadeValidation() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $parent = $this->getBuilder('parent', null, array('cascade_validation' => false)) + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->getForm(); + $options = array('validation_groups' => array('group1', 'group2')); + $form = $this->getBuilder('name', '\stdClass', $options)->getForm(); + $parent->add($form); + + $form->setData($object); + + $context->expects($this->never()) + ->method('validate'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testValidateConstraintsEvenIfNoCascadeValidation() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + $constraint1 = new NotNull(array('groups' => array('group1', 'group2'))); + $constraint2 = new NotBlank(array('groups' => 'group2')); + + $parent = $this->getBuilder('parent', null, array('cascade_validation' => false)) + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->getForm(); + $options = array( + 'validation_groups' => array('group1', 'group2'), + 'constraints' => array($constraint1, $constraint2), + ); + $form = $this->getBuilder('name', '\stdClass', $options) + ->setData($object) + ->getForm(); + $parent->add($form); + + $context->expects($this->at(0)) + ->method('validateValue') + ->with($object, $constraint1, 'data', 'group1'); + $context->expects($this->at(1)) + ->method('validateValue') + ->with($object, $constraint2, 'data', 'group2'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testDontValidateIfNoValidationGroups() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $form = $this->getBuilder('name', '\stdClass', array( + 'validation_groups' => array(), + )) + ->setData($object) + ->getForm(); + + $form->setData($object); + + $context->expects($this->never()) + ->method('validate'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testDontValidateConstraintsIfNoValidationGroups() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + $constraint1 = $this->getMock('Symfony\Component\Validator\Constraint'); + $constraint2 = $this->getMock('Symfony\Component\Validator\Constraint'); + + $options = array( + 'validation_groups' => array(), + 'constraints' => array($constraint1, $constraint2), + ); + $form = $this->getBuilder('name', '\stdClass', $options) + ->setData($object) + ->getForm(); + + // Launch transformer + $form->submit(array()); + + $context->expects($this->never()) + ->method('validate'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testDontValidateIfNotSynchronized() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $form = $this->getBuilder('name', '\stdClass', array( + 'invalid_message' => 'invalid_message_key', + // Invalid message parameters must be supported, because the + // invalid message can be a translation key + // see https://github.com/symfony/symfony/issues/5144 + 'invalid_message_parameters' => array('{{ foo }}' => 'bar'), + )) + ->setData($object) + ->addViewTransformer(new CallbackTransformer( + function ($data) { return $data; }, + function () { throw new TransformationFailedException(); } + )) + ->getForm(); + + // Launch transformer + $form->submit('foo'); + + $context->expects($this->never()) + ->method('validate'); + + $context->expects($this->once()) + ->method('addViolation') + ->with( + 'invalid_message_key', + array('{{ value }}' => 'foo', '{{ foo }}' => 'bar'), + 'foo' + ); + $context->expects($this->never()) + ->method('addViolationAt'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testAddInvalidErrorEvenIfNoValidationGroups() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $form = $this->getBuilder('name', '\stdClass', array( + 'invalid_message' => 'invalid_message_key', + // Invalid message parameters must be supported, because the + // invalid message can be a translation key + // see https://github.com/symfony/symfony/issues/5144 + 'invalid_message_parameters' => array('{{ foo }}' => 'bar'), + 'validation_groups' => array(), + )) + ->setData($object) + ->addViewTransformer(new CallbackTransformer( + function ($data) { return $data; }, + function () { throw new TransformationFailedException(); } + )) + ->getForm(); + + // Launch transformer + $form->submit('foo'); + + $context->expects($this->never()) + ->method('validate'); + + $context->expects($this->once()) + ->method('addViolation') + ->with( + 'invalid_message_key', + array('{{ value }}' => 'foo', '{{ foo }}' => 'bar'), + 'foo' + ); + $context->expects($this->never()) + ->method('addViolationAt'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testDontValidateConstraintsIfNotSynchronized() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + $constraint1 = $this->getMock('Symfony\Component\Validator\Constraint'); + $constraint2 = $this->getMock('Symfony\Component\Validator\Constraint'); + + $options = array( + 'validation_groups' => array('group1', 'group2'), + 'constraints' => array($constraint1, $constraint2), + ); + $form = $this->getBuilder('name', '\stdClass', $options) + ->setData($object) + ->addViewTransformer(new CallbackTransformer( + function ($data) { return $data; }, + function () { throw new TransformationFailedException(); } + )) + ->getForm(); + + // Launch transformer + $form->submit(array()); + + $context->expects($this->never()) + ->method('validate'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + // https://github.com/symfony/symfony/issues/4359 + public function testDontMarkInvalidIfAnyChildIsNotSynchronized() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $failingTransformer = new CallbackTransformer( + function ($data) { return $data; }, + function () { throw new TransformationFailedException(); } + ); + + $form = $this->getBuilder('name', '\stdClass') + ->setData($object) + ->addViewTransformer($failingTransformer) + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->add( + $this->getBuilder('child') + ->addViewTransformer($failingTransformer) + ) + ->getForm(); + + // Launch transformer + $form->submit(array('child' => 'foo')); + + $context->expects($this->never()) + ->method('addViolation'); + $context->expects($this->never()) + ->method('addViolationAt'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testHandleCallbackValidationGroups() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + $options = array('validation_groups' => array($this, 'getValidationGroups')); + $form = $this->getBuilder('name', '\stdClass', $options) + ->setData($object) + ->getForm(); + + $context->expects($this->at(0)) + ->method('validate') + ->with($object, 'data', 'group1', true); + $context->expects($this->at(1)) + ->method('validate') + ->with($object, 'data', 'group2', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testDontExecuteFunctionNames() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + $options = array('validation_groups' => 'header'); + $form = $this->getBuilder('name', '\stdClass', $options) + ->setData($object) + ->getForm(); + + $context->expects($this->once()) + ->method('validate') + ->with($object, 'data', 'header', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testHandleClosureValidationGroups() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + $options = array('validation_groups' => function(FormInterface $form){ + return array('group1', 'group2'); + }); + $form = $this->getBuilder('name', '\stdClass', $options) + ->setData($object) + ->getForm(); + + $context->expects($this->at(0)) + ->method('validate') + ->with($object, 'data', 'group1', true); + $context->expects($this->at(1)) + ->method('validate') + ->with($object, 'data', 'group2', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testUseValidationGroupOfClickedButton() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $parent = $this->getBuilder('parent', null, array('cascade_validation' => true)) + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->getForm(); + $form = $this->getForm('name', '\stdClass', array( + 'validation_groups' => 'form_group', + )); + + $parent->add($form); + $parent->add($this->getClickedSubmitButton('submit', array( + 'validation_groups' => 'button_group', + ))); + + $form->setData($object); + + $context->expects($this->once()) + ->method('validate') + ->with($object, 'data', 'button_group', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testDontUseValidationGroupOfUnclickedButton() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $parent = $this->getBuilder('parent', null, array('cascade_validation' => true)) + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->getForm(); + $form = $this->getForm('name', '\stdClass', array( + 'validation_groups' => 'form_group', + )); + + $parent->add($form); + $parent->add($this->getSubmitButton('submit', array( + 'validation_groups' => 'button_group', + ))); + + $form->setData($object); + + $context->expects($this->once()) + ->method('validate') + ->with($object, 'data', 'form_group', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testUseInheritedValidationGroup() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $parentOptions = array( + 'validation_groups' => 'group', + 'cascade_validation' => true, + ); + $parent = $this->getBuilder('parent', null, $parentOptions) + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->getForm(); + $form = $this->getBuilder('name', '\stdClass')->getForm(); + $parent->add($form); + + $form->setData($object); + + $context->expects($this->once()) + ->method('validate') + ->with($object, 'data', 'group', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testUseInheritedCallbackValidationGroup() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $parentOptions = array( + 'validation_groups' => array($this, 'getValidationGroups'), + 'cascade_validation' => true, + ); + $parent = $this->getBuilder('parent', null, $parentOptions) + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->getForm(); + $form = $this->getBuilder('name', '\stdClass')->getForm(); + $parent->add($form); + + $form->setData($object); + + $context->expects($this->at(0)) + ->method('validate') + ->with($object, 'data', 'group1', true); + $context->expects($this->at(1)) + ->method('validate') + ->with($object, 'data', 'group2', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testUseInheritedClosureValidationGroup() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + + $parentOptions = array( + 'validation_groups' => function(FormInterface $form){ + return array('group1', 'group2'); + }, + 'cascade_validation' => true, + ); + $parent = $this->getBuilder('parent', null, $parentOptions) + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->getForm(); + $form = $this->getBuilder('name', '\stdClass')->getForm(); + $parent->add($form); + + $form->setData($object); + + $context->expects($this->at(0)) + ->method('validate') + ->with($object, 'data', 'group1', true); + $context->expects($this->at(1)) + ->method('validate') + ->with($object, 'data', 'group2', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testAppendPropertyPath() + { + $context = $this->getMockExecutionContext(); + $object = $this->getMock('\stdClass'); + $form = $this->getBuilder('name', '\stdClass') + ->setData($object) + ->getForm(); + + $context->expects($this->once()) + ->method('validate') + ->with($object, 'data', 'Default', true); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testDontWalkScalars() + { + $context = $this->getMockExecutionContext(); + + $form = $this->getBuilder() + ->setData('scalar') + ->getForm(); + + $context->expects($this->never()) + ->method('validate'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function testViolationIfExtraData() + { + $context = $this->getMockExecutionContext(); + + $form = $this->getBuilder('parent', null, array('extra_fields_message' => 'Extra!')) + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->add($this->getBuilder('child')) + ->getForm(); + + $form->submit(array('foo' => 'bar')); + + $context->expects($this->once()) + ->method('addViolation') + ->with( + 'Extra!', + array('{{ extra_fields }}' => 'foo'), + array('foo' => 'bar') + ); + $context->expects($this->never()) + ->method('addViolationAt'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + /** + * @dataProvider getPostMaxSizeFixtures + */ + public function testPostMaxSizeViolation($contentLength, $iniMax, $nbViolation, array $params = array()) + { + $this->serverParams->expects($this->once()) + ->method('getContentLength') + ->will($this->returnValue($contentLength)); + $this->serverParams->expects($this->any()) + ->method('getNormalizedIniPostMaxSize') + ->will($this->returnValue($iniMax)); + + $context = $this->getMockExecutionContext(); + $options = array('post_max_size_message' => 'Max {{ max }}!'); + $form = $this->getBuilder('name', null, $options)->getForm(); + + for ($i = 0; $i < $nbViolation; ++$i) { + if (0 === $i && count($params) > 0) { + $context->expects($this->at($i)) + ->method('addViolation') + ->with($options['post_max_size_message'], $params); + } else { + $context->expects($this->at($i)) + ->method('addViolation'); + } + } + + $context->expects($this->never()) + ->method('addViolationAt'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + public function getPostMaxSizeFixtures() + { + return array( + array(pow(1024, 3) + 1, '1G', 1, array('{{ max }}' => '1G')), + array(pow(1024, 3), '1G', 0), + array(pow(1024, 2) + 1, '1M', 1, array('{{ max }}' => '1M')), + array(pow(1024, 2), '1M', 0), + array(1024 + 1, '1K', 1, array('{{ max }}' => '1K')), + array(1024, '1K', 0), + array(null, '1K', 0), + array(1024, '', 0), + array(1024, 0, 0), + ); + } + + public function testNoViolationIfNotRoot() + { + $this->serverParams->expects($this->once()) + ->method('getContentLength') + ->will($this->returnValue(1025)); + $this->serverParams->expects($this->never()) + ->method('getNormalizedIniPostMaxSize'); + + $context = $this->getMockExecutionContext(); + $parent = $this->getBuilder() + ->setCompound(true) + ->setDataMapper($this->getDataMapper()) + ->getForm(); + $form = $this->getForm(); + $parent->add($form); + + $context->expects($this->never()) + ->method('addViolation'); + $context->expects($this->never()) + ->method('addViolationAt'); + + $this->validator->initialize($context); + $this->validator->validate($form, new Form()); + } + + /** + * Access has to be public, as this method is called via callback array + * in {@link testValidateFormDataCanHandleCallbackValidationGroups()} + * and {@link testValidateFormDataUsesInheritedCallbackValidationGroup()} + */ + public function getValidationGroups(FormInterface $form) + { + return array('group1', 'group2'); + } + + private function getMockExecutionContext() + { + return $this->getMock('Symfony\Component\Validator\ExecutionContextInterface'); + } + + /** + * @param string $name + * @param string $dataClass + * @param array $options + * + * @return FormBuilder + */ + private function getBuilder($name = 'name', $dataClass = null, array $options = array()) + { + $options = array_replace(array( + 'constraints' => array(), + 'invalid_message_parameters' => array(), + ), $options); + + return new FormBuilder($name, $dataClass, $this->dispatcher, $this->factory, $options); + } + + private function getForm($name = 'name', $dataClass = null, array $options = array()) + { + return $this->getBuilder($name, $dataClass, $options)->getForm(); + } + + private function getSubmitButton($name = 'name', array $options = array()) + { + $builder = new SubmitButtonBuilder($name, $options); + + return $builder->getForm(); + } + + private function getClickedSubmitButton($name = 'name', array $options = array()) + { + return $this->getSubmitButton($name, $options)->submit(''); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getDataMapper() + { + return $this->getMock('Symfony\Component\Form\DataMapperInterface'); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php new file mode 100644 index 00000000..528f9463 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/EventListener/ValidationListenerTest.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Validator\EventListener; + +use Symfony\Component\Form\FormBuilder; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\Extension\Validator\Constraints\Form; +use Symfony\Component\Form\Extension\Validator\EventListener\ValidationListener; +use Symfony\Component\PropertyAccess\PropertyPath; +use Symfony\Component\Validator\ConstraintViolation; + +class ValidationListenerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $dispatcher; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $factory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $validator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $violationMapper; + + /** + * @var ValidationListener + */ + private $listener; + + private $message; + + private $messageTemplate; + + private $params; + + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\Event')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->factory = $this->getMock('Symfony\Component\Form\FormFactoryInterface'); + $this->validator = $this->getMock('Symfony\Component\Validator\ValidatorInterface'); + $this->violationMapper = $this->getMock('Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapperInterface'); + $this->listener = new ValidationListener($this->validator, $this->violationMapper); + $this->message = 'Message'; + $this->messageTemplate = 'Message template'; + $this->params = array('foo' => 'bar'); + } + + private function getConstraintViolation($code = null) + { + return new ConstraintViolation($this->message, $this->messageTemplate, $this->params, null, 'prop.path', null, null, $code); + } + + private function getBuilder($name = 'name', $propertyPath = null, $dataClass = null) + { + $builder = new FormBuilder($name, $dataClass, $this->dispatcher, $this->factory); + $builder->setPropertyPath(new PropertyPath($propertyPath ?: $name)); + $builder->setAttribute('error_mapping', array()); + $builder->setErrorBubbling(false); + $builder->setMapped(true); + + return $builder; + } + + private function getForm($name = 'name', $propertyPath = null, $dataClass = null) + { + return $this->getBuilder($name, $propertyPath, $dataClass)->getForm(); + } + + private function getMockForm() + { + return $this->getMock('Symfony\Component\Form\Test\FormInterface'); + } + + // More specific mapping tests can be found in ViolationMapperTest + public function testMapViolation() + { + $violation = $this->getConstraintViolation(); + $form = $this->getForm('street'); + + $this->validator->expects($this->once()) + ->method('validate') + ->will($this->returnValue(array($violation))); + + $this->violationMapper->expects($this->once()) + ->method('mapViolation') + ->with($violation, $form, false); + + $this->listener->validateForm(new FormEvent($form, null)); + } + + public function testMapViolationAllowsNonSyncIfInvalid() + { + $violation = $this->getConstraintViolation(Form::ERR_INVALID); + $form = $this->getForm('street'); + + $this->validator->expects($this->once()) + ->method('validate') + ->will($this->returnValue(array($violation))); + + $this->violationMapper->expects($this->once()) + ->method('mapViolation') + // pass true now + ->with($violation, $form, true); + + $this->listener->validateForm(new FormEvent($form, null)); + } + + public function testValidateIgnoresNonRoot() + { + $form = $this->getMockForm(); + $form->expects($this->once()) + ->method('isRoot') + ->will($this->returnValue(false)); + + $this->validator->expects($this->never()) + ->method('validate'); + + $this->violationMapper->expects($this->never()) + ->method('mapViolation'); + + $this->listener->validateForm(new FormEvent($form, null)); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php new file mode 100644 index 00000000..66194105 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Validator\Type; + +use Symfony\Component\Form\FormInterface; + +class FormTypeValidatorExtensionTest extends TypeTestCase +{ + public function testValidationGroupNullByDefault() + { + $form = $this->factory->create('form'); + + $this->assertNull($form->getConfig()->getOption('validation_groups')); + } + + public function testValidationGroupsTransformedToArray() + { + $form = $this->factory->create('form', null, array( + 'validation_groups' => 'group', + )); + + $this->assertEquals(array('group'), $form->getConfig()->getOption('validation_groups')); + } + + public function testValidationGroupsCanBeSetToArray() + { + $form = $this->factory->create('form', null, array( + 'validation_groups' => array('group1', 'group2'), + )); + + $this->assertEquals(array('group1', 'group2'), $form->getConfig()->getOption('validation_groups')); + } + + public function testValidationGroupsCanBeSetToFalse() + { + $form = $this->factory->create('form', null, array( + 'validation_groups' => false, + )); + + $this->assertEquals(array(), $form->getConfig()->getOption('validation_groups')); + } + + public function testValidationGroupsCanBeSetToCallback() + { + $form = $this->factory->create('form', null, array( + 'validation_groups' => array($this, 'testValidationGroupsCanBeSetToCallback'), + )); + + $this->assertTrue(is_callable($form->getConfig()->getOption('validation_groups'))); + } + + public function testValidationGroupsCanBeSetToClosure() + { + $form = $this->factory->create('form', null, array( + 'validation_groups' => function(FormInterface $form){ return null; }, + )); + + $this->assertTrue(is_callable($form->getConfig()->getOption('validation_groups'))); + } + + public function testSubmitValidatesData() + { + $builder = $this->factory->createBuilder('form', null, array( + 'validation_groups' => 'group', + )); + $builder->add('firstName', 'form'); + $form = $builder->getForm(); + + $this->validator->expects($this->once()) + ->method('validate') + ->with($this->equalTo($form)); + + // specific data is irrelevant + $form->submit(array()); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Type/TypeTestCase.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Type/TypeTestCase.php new file mode 100644 index 00000000..d94d896a --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Type/TypeTestCase.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Validator\Type; + +use Symfony\Component\Form\Test\TypeTestCase as BaseTypeTestCase; +use Symfony\Component\Form\Extension\Validator\ValidatorExtension; + +abstract class TypeTestCase extends BaseTypeTestCase +{ + protected $validator; + + protected function setUp() + { + if (!class_exists('Symfony\Component\Validator\Constraint')) { + $this->markTestSkipped('The "Validator" component is not available'); + } + + $this->validator = $this->getMock('Symfony\Component\Validator\ValidatorInterface'); + $metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface'); + $this->validator->expects($this->once())->method('getMetadataFactory')->will($this->returnValue($metadataFactory)); + $metadata = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata')->disableOriginalConstructor()->getMock(); + $metadataFactory->expects($this->once())->method('getMetadataFor')->will($this->returnValue($metadata)); + + parent::setUp(); + } + + protected function tearDown() + { + $this->validator = null; + + parent::tearDown(); + } + + protected function getExtensions() + { + return array_merge(parent::getExtensions(), array( + new ValidatorExtension($this->validator), + )); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Util/ServerParamsTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Util/ServerParamsTest.php new file mode 100644 index 00000000..7ad5b771 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/Util/ServerParamsTest.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Validator\Util; + +class ServerParamsTest extends \PHPUnit_Framework_TestCase +{ + /** @dataProvider getGetPostMaxSizeTestData */ + public function testGetPostMaxSize($size, $bytes) + { + $serverParams = $this->getMock('Symfony\Component\Form\Extension\Validator\Util\ServerParams', array('getNormalizedIniPostMaxSize')); + $serverParams + ->expects($this->any()) + ->method('getNormalizedIniPostMaxSize') + ->will($this->returnValue(strtoupper($size))); + + $this->assertEquals($bytes, $serverParams->getPostMaxSize()); + } + + public function getGetPostMaxSizeTestData() + { + return array( + array('2k', 2048), + array('2 k', 2048), + array('8m', 8 * 1024 * 1024), + array('+2 k', 2048), + array('+2???k', 2048), + array('0x10', 16), + array('0xf', 15), + array('010', 8), + array('+0x10 k', 16 * 1024), + array('1g', 1024 * 1024 * 1024), + array('-1', -1), + array('0', 0), + array('2mk', 2048), // the unit must be the last char, so in this case 'k', not 'm' + ); + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php new file mode 100644 index 00000000..c802ea7e --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php @@ -0,0 +1,1481 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Validator\ViolationMapper; + +use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper; +use Symfony\Component\Form\Exception\TransformationFailedException; +use Symfony\Component\Form\CallbackTransformer; +use Symfony\Component\Form\Form; +use Symfony\Component\Form\FormConfigBuilder; +use Symfony\Component\Form\FormError; +use Symfony\Component\PropertyAccess\PropertyPath; +use Symfony\Component\Validator\ConstraintViolation; + +/** + * @author Bernhard Schussek + */ +class ViolationMapperTest extends \PHPUnit_Framework_TestCase +{ + const LEVEL_0 = 0; + + const LEVEL_1 = 1; + + const LEVEL_1B = 2; + + const LEVEL_2 = 3; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $dispatcher; + + /** + * @var ViolationMapper + */ + private $mapper; + + /** + * @var string + */ + private $message; + + /** + * @var string + */ + private $messageTemplate; + + /** + * @var array + */ + private $params; + + protected function setUp() + { + if (!class_exists('Symfony\Component\EventDispatcher\Event')) { + $this->markTestSkipped('The "EventDispatcher" component is not available'); + } + + $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->mapper = new ViolationMapper(); + $this->message = 'Message'; + $this->messageTemplate = 'Message template'; + $this->params = array('foo' => 'bar'); + } + + protected function getForm($name = 'name', $propertyPath = null, $dataClass = null, $errorMapping = array(), $inheritData = false, $synchronized = true) + { + $config = new FormConfigBuilder($name, $dataClass, $this->dispatcher, array( + 'error_mapping' => $errorMapping, + )); + $config->setMapped(true); + $config->setInheritData($inheritData); + $config->setPropertyPath($propertyPath); + $config->setCompound(true); + $config->setDataMapper($this->getDataMapper()); + + if (!$synchronized) { + $config->addViewTransformer(new CallbackTransformer( + function ($normData) { return $normData; }, + function () { throw new TransformationFailedException(); } + )); + } + + return new Form($config); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getDataMapper() + { + return $this->getMock('Symfony\Component\Form\DataMapperInterface'); + } + + /** + * @param $propertyPath + * + * @return ConstraintViolation + */ + protected function getConstraintViolation($propertyPath) + { + return new ConstraintViolation($this->message, $this->messageTemplate, $this->params, null, $propertyPath, null); + } + + /** + * @return FormError + */ + protected function getFormError() + { + return new FormError($this->message, $this->messageTemplate, $this->params); + } + + public function testMapToFormInheritingParentDataIfDataDoesNotMatch() + { + $violation = $this->getConstraintViolation('children[address].data.foo'); + $parent = $this->getForm('parent'); + $child = $this->getForm('address', 'address', null, array(), true); + $grandChild = $this->getForm('street'); + + $parent->add($child); + $child->add($grandChild); + + $this->mapper->mapViolation($violation, $parent); + + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $child->getErrors(), $child->getName().' should have an error, but has none'); + $this->assertCount(0, $grandChild->getErrors(), $grandChild->getName().' should not have an error, but has one'); + } + + public function testFollowDotRules() + { + $violation = $this->getConstraintViolation('data.foo'); + $parent = $this->getForm('parent', null, null, array( + 'foo' => 'address', + )); + $child = $this->getForm('address', null, null, array( + '.' => 'street', + )); + $grandChild = $this->getForm('street', null, null, array( + '.' => 'name', + )); + $grandGrandChild = $this->getForm('name'); + + $parent->add($child); + $child->add($grandChild); + $grandChild->add($grandGrandChild); + + $this->mapper->mapViolation($violation, $parent); + + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertCount(0, $child->getErrors(), $child->getName().' should not have an error, but has one'); + $this->assertCount(0, $grandChild->getErrors(), $grandChild->getName().' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $grandGrandChild->getErrors(), $grandGrandChild->getName().' should have an error, but has none'); + } + + public function testAbortMappingIfNotSynchronized() + { + $violation = $this->getConstraintViolation('children[address].data.street'); + $parent = $this->getForm('parent'); + $child = $this->getForm('address', 'address', null, array(), false, false); + // even though "street" is synchronized, it should not have any errors + // due to its parent not being synchronized + $grandChild = $this->getForm('street' , 'street'); + + $parent->add($child); + $child->add($grandChild); + + // submit to invoke the transformer and mark the form unsynchronized + $parent->submit(array()); + + $this->mapper->mapViolation($violation, $parent); + + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertCount(0, $child->getErrors(), $child->getName().' should not have an error, but has one'); + $this->assertCount(0, $grandChild->getErrors(), $grandChild->getName().' should not have an error, but has one'); + } + + public function testAbortDotRuleMappingIfNotSynchronized() + { + $violation = $this->getConstraintViolation('data.address'); + $parent = $this->getForm('parent'); + $child = $this->getForm('address', 'address', null, array( + '.' => 'street', + ), false, false); + // even though "street" is synchronized, it should not have any errors + // due to its parent not being synchronized + $grandChild = $this->getForm('street'); + + $parent->add($child); + $child->add($grandChild); + + // submit to invoke the transformer and mark the form unsynchronized + $parent->submit(array()); + + $this->mapper->mapViolation($violation, $parent); + + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertCount(0, $child->getErrors(), $child->getName().' should not have an error, but has one'); + $this->assertCount(0, $grandChild->getErrors(), $grandChild->getName().' should not have an error, but has one'); + } + + public function provideDefaultTests() + { + // The mapping must be deterministic! If a child has the property path "[street]", + // "data[street]" should be mapped, but "data.street" should not! + return array( + // mapping target, child name, its property path, grand child name, its property path, violation path + array(self::LEVEL_0, 'address', 'address', 'street', 'street', ''), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data'), + + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'children[address].data'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address].data.street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'children[address].data[street].prop'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'data.address.street'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'data.address.street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'data.address[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'data.address[street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[address].street'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[address].street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[address][street]'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[address][street].prop'), + + array(self::LEVEL_2, 'address', 'address', 'street', '[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'address', 'street', '[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[street]', 'children[address].data'), + array(self::LEVEL_1, 'address', 'address', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1, 'address', 'address', 'street', '[street]', 'children[address].data.street.prop'), + array(self::LEVEL_2, 'address', 'address', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'address', 'address', 'street', '[street]', 'children[address].data[street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[street]', 'data.address.street'), + array(self::LEVEL_1, 'address', 'address', 'street', '[street]', 'data.address.street.prop'), + array(self::LEVEL_2, 'address', 'address', 'street', '[street]', 'data.address[street]'), + array(self::LEVEL_2, 'address', 'address', 'street', '[street]', 'data.address[street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[street]', 'data[address].street'), + array(self::LEVEL_0, 'address', 'address', 'street', '[street]', 'data[address].street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[street]', 'data[address][street]'), + array(self::LEVEL_0, 'address', 'address', 'street', '[street]', 'data[address][street].prop'), + + array(self::LEVEL_2, 'address', '[address]', 'street', 'street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'street', 'children[address].data'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'street', 'children[address].data.street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'street', 'children[address].data[street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'street', 'data.address.street'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'street', 'data.address.street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'street', 'data.address[street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'street', 'data.address[street].prop'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'street', 'data[address].street'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'street', 'data[address].street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'street', 'data[address][street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'street', 'data[address][street].prop'), + + array(self::LEVEL_2, 'address', '[address]', 'street', '[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[street]', 'children[address].data'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[street]', 'children[address].data.street.prop'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[street]', 'children[address].data[street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[street]', 'data.address.street'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[street]', 'data.address.street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[street]', 'data.address[street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[street]', 'data.address[street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[street]', 'data[address].street'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[street]', 'data[address].street.prop'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[street]', 'data[address][street]'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[street]', 'data[address][street].prop'), + + array(self::LEVEL_2, 'address', 'person.address', 'street', 'street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'person.address', 'street', 'street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'person.address', 'street', 'street', 'children[address].data'), + array(self::LEVEL_2, 'address', 'person.address', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_2, 'address', 'person.address', 'street', 'street', 'children[address].data.street.prop'), + array(self::LEVEL_1, 'address', 'person.address', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1, 'address', 'person.address', 'street', 'street', 'children[address].data[street].prop'), + array(self::LEVEL_2, 'address', 'person.address', 'street', 'street', 'data.person.address.street'), + array(self::LEVEL_2, 'address', 'person.address', 'street', 'street', 'data.person.address.street.prop'), + array(self::LEVEL_1, 'address', 'person.address', 'street', 'street', 'data.person.address[street]'), + array(self::LEVEL_1, 'address', 'person.address', 'street', 'street', 'data.person.address[street].prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data.person[address].street'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data.person[address].street.prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data.person[address][street]'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data.person[address][street].prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data[person].address.street'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data[person].address.street.prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data[person].address[street]'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data[person].address[street].prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data[person][address].street'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data[person][address].street.prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data[person][address][street]'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data[person][address][street].prop'), + + array(self::LEVEL_2, 'address', 'person.address', 'street', '[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'person.address', 'street', '[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'person.address', 'street', '[street]', 'children[address].data'), + array(self::LEVEL_1, 'address', 'person.address', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1, 'address', 'person.address', 'street', '[street]', 'children[address].data.street.prop'), + array(self::LEVEL_2, 'address', 'person.address', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'address', 'person.address', 'street', '[street]', 'children[address].data[street].prop'), + array(self::LEVEL_1, 'address', 'person.address', 'street', '[street]', 'data.person.address.street'), + array(self::LEVEL_1, 'address', 'person.address', 'street', '[street]', 'data.person.address.street.prop'), + array(self::LEVEL_2, 'address', 'person.address', 'street', '[street]', 'data.person.address[street]'), + array(self::LEVEL_2, 'address', 'person.address', 'street', '[street]', 'data.person.address[street].prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data.person[address].street'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data.person[address].street.prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data.person[address][street]'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data.person[address][street].prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data[person].address.street'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data[person].address.street.prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data[person].address[street]'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data[person].address[street].prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data[person][address].street'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data[person][address].street.prop'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data[person][address][street]'), + array(self::LEVEL_0, 'address', 'person.address', 'street', '[street]', 'data[person][address][street].prop'), + + array(self::LEVEL_2, 'address', 'person[address]', 'street', 'street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', 'street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', 'street', 'children[address].data'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', 'street', 'children[address].data.street.prop'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', 'street', 'children[address].data[street].prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data.person.address.street'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data.person.address.street.prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data.person.address[street]'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data.person.address[street].prop'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', 'street', 'data.person[address].street'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', 'street', 'data.person[address].street.prop'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', 'street', 'data.person[address][street]'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', 'street', 'data.person[address][street].prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data[person].address.street'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data[person].address.street.prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data[person].address[street]'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data[person].address[street].prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data[person][address].street'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data[person][address].street.prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data[person][address][street]'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', 'street', 'data[person][address][street].prop'), + + array(self::LEVEL_2, 'address', 'person[address]', 'street', '[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', '[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', '[street]', 'children[address].data'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', '[street]', 'children[address].data.street.prop'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', '[street]', 'children[address].data[street].prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data.person.address.street'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data.person.address.street.prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data.person.address[street]'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data.person.address[street].prop'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', '[street]', 'data.person[address].street'), + array(self::LEVEL_1, 'address', 'person[address]', 'street', '[street]', 'data.person[address].street.prop'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', '[street]', 'data.person[address][street]'), + array(self::LEVEL_2, 'address', 'person[address]', 'street', '[street]', 'data.person[address][street].prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data[person].address.street'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data[person].address.street.prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data[person].address[street]'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data[person].address[street].prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data[person][address].street'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data[person][address].street.prop'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data[person][address][street]'), + array(self::LEVEL_0, 'address', 'person[address]', 'street', '[street]', 'data[person][address][street].prop'), + + array(self::LEVEL_2, 'address', '[person].address', 'street', 'street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[person].address', 'street', 'street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[person].address', 'street', 'street', 'children[address].data'), + array(self::LEVEL_2, 'address', '[person].address', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_2, 'address', '[person].address', 'street', 'street', 'children[address].data.street.prop'), + array(self::LEVEL_1, 'address', '[person].address', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1, 'address', '[person].address', 'street', 'street', 'children[address].data[street].prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data.person.address.street'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data.person.address.street.prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data.person.address[street]'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data.person.address[street].prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data.person[address].street'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data.person[address].street.prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data.person[address][street]'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data.person[address][street].prop'), + array(self::LEVEL_2, 'address', '[person].address', 'street', 'street', 'data[person].address.street'), + array(self::LEVEL_2, 'address', '[person].address', 'street', 'street', 'data[person].address.street.prop'), + array(self::LEVEL_1, 'address', '[person].address', 'street', 'street', 'data[person].address[street]'), + array(self::LEVEL_1, 'address', '[person].address', 'street', 'street', 'data[person].address[street].prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data[person][address].street'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data[person][address].street.prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data[person][address][street]'), + array(self::LEVEL_0, 'address', '[person].address', 'street', 'street', 'data[person][address][street].prop'), + + array(self::LEVEL_2, 'address', '[person].address', 'street', '[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[person].address', 'street', '[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[person].address', 'street', '[street]', 'children[address].data'), + array(self::LEVEL_1, 'address', '[person].address', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1, 'address', '[person].address', 'street', '[street]', 'children[address].data.street.prop'), + array(self::LEVEL_2, 'address', '[person].address', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'address', '[person].address', 'street', '[street]', 'children[address].data[street].prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data.person.address.street'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data.person.address.street.prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data.person.address[street]'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data.person.address[street].prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data.person[address].street'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data.person[address].street.prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data.person[address][street]'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data.person[address][street].prop'), + array(self::LEVEL_1, 'address', '[person].address', 'street', '[street]', 'data[person].address.street'), + array(self::LEVEL_1, 'address', '[person].address', 'street', '[street]', 'data[person].address.street.prop'), + array(self::LEVEL_2, 'address', '[person].address', 'street', '[street]', 'data[person].address[street]'), + array(self::LEVEL_2, 'address', '[person].address', 'street', '[street]', 'data[person].address[street].prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data[person][address].street'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data[person][address].street.prop'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data[person][address][street]'), + array(self::LEVEL_0, 'address', '[person].address', 'street', '[street]', 'data[person][address][street].prop'), + + array(self::LEVEL_2, 'address', '[person][address]', 'street', 'street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', 'street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', 'street', 'children[address]'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', 'street', 'children[address].data'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', 'street', 'children[address].data.street.prop'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', 'street', 'children[address].data[street].prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data.person.address.street'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data.person.address.street.prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data.person.address[street]'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data.person.address[street].prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data.person[address].street'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data.person[address].street.prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data.person[address][street]'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data.person[address][street].prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data[person].address.street'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data[person].address.street.prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data[person].address[street]'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', 'street', 'data[person].address[street].prop'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', 'street', 'data[person][address].street'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', 'street', 'data[person][address].street.prop'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', 'street', 'data[person][address][street]'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', 'street', 'data[person][address][street].prop'), + + array(self::LEVEL_2, 'address', '[person][address]', 'street', '[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', '[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', '[street]', 'children[address].data'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', '[street]', 'children[address].data.street.prop'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', '[street]', 'children[address].data[street].prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data.person.address.street'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data.person.address.street.prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data.person.address[street]'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data.person.address[street].prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data.person[address].street'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data.person[address].street.prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data.person[address][street]'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data.person[address][street].prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data[person].address.street'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data[person].address.street.prop'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data[person].address[street]'), + array(self::LEVEL_0, 'address', '[person][address]', 'street', '[street]', 'data[person].address[street].prop'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', '[street]', 'data[person][address].street'), + array(self::LEVEL_1, 'address', '[person][address]', 'street', '[street]', 'data[person][address].street.prop'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', '[street]', 'data[person][address][street]'), + array(self::LEVEL_2, 'address', '[person][address]', 'street', '[street]', 'data[person][address][street].prop'), + + array(self::LEVEL_2, 'address', 'address', 'street', 'office.street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office.street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data.office'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office.street', 'children[address].data.office.street'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office.street', 'children[address].data.office.street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data.office[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data.office[street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data[office]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data[office].street'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data[office].street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data[office][street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data[office][street].prop'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office.street', 'data.address.office.street'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office.street', 'data.address.office.street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'data.address.office[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'data.address.office[street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'data.address[office].street'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'data.address[office].street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'data.address[office][street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'data.address[office][street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office.street', 'data[address].office.street'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office.street', 'data[address].office.street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office.street', 'data[address].office[street]'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office.street', 'data[address].office[street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office.street', 'data[address][office].street'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office.street', 'data[address][office].street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office.street', 'data[address][office][street]'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office.street', 'data[address][office][street].prop'), + + array(self::LEVEL_2, 'address', '[address]', 'street', 'office.street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office.street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'children[address].data'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'children[address].data.office'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office.street', 'children[address].data.office.street'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office.street', 'children[address].data.office.street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'children[address].data.office[street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'children[address].data.office[street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'children[address].data[office]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'children[address].data[office].street'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'children[address].data[office].street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'children[address].data[office][street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'children[address].data[office][street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office.street', 'data.address.office.street'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office.street', 'data.address.office.street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office.street', 'data.address.office[street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office.street', 'data.address.office[street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office.street', 'data.address[office].street'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office.street', 'data.address[office].street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office.street', 'data.address[office][street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office.street', 'data.address[office][street].prop'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office.street', 'data[address].office.street'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office.street', 'data[address].office.street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'data[address].office[street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'data[address].office[street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'data[address][office].street'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'data[address][office].street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'data[address][office][street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office.street', 'data[address][office][street].prop'), + + array(self::LEVEL_2, 'address', 'address', 'street', 'office[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'children[address].data'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'children[address].data.office'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'children[address].data.office.street'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'children[address].data.office.street.prop'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office[street]', 'children[address].data.office[street]'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office[street]', 'children[address].data.office[street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'children[address].data[office]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'children[address].data[office].street'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'children[address].data[office].street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'children[address].data[office][street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'children[address].data[office][street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'data.address.office.street'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'data.address.office.street.prop'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office[street]', 'data.address.office[street]'), + array(self::LEVEL_2, 'address', 'address', 'street', 'office[street]', 'data.address.office[street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'data.address[office].street'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'data.address[office].street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'data.address[office][street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office[street]', 'data.address[office][street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office[street]', 'data[address].office.street'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office[street]', 'data[address].office.street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office[street]', 'data[address].office[street]'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office[street]', 'data[address].office[street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office[street]', 'data[address][office].street'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office[street]', 'data[address][office].street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office[street]', 'data[address][office][street]'), + array(self::LEVEL_0, 'address', 'address', 'street', 'office[street]', 'data[address][office][street].prop'), + + array(self::LEVEL_2, 'address', '[address]', 'street', 'office[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'children[address].data.office.street'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'children[address].data.office.street.prop'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office[street]', 'children[address].data.office[street]'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office[street]', 'children[address].data.office[street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'children[address].data[office]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'children[address].data[office].street'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'children[address].data[office].street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'children[address].data[office][street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'children[address].data[office][street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office[street]', 'data.address.office.street'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office[street]', 'data.address.office.street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office[street]', 'data.address.office[street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office[street]', 'data.address.office[street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office[street]', 'data.address[office].street'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office[street]', 'data.address[office].street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office[street]', 'data.address[office][street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', 'office[street]', 'data.address[office][street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'data[address].office.street'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'data[address].office.street.prop'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office[street]', 'data[address].office[street]'), + array(self::LEVEL_2, 'address', '[address]', 'street', 'office[street]', 'data[address].office[street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'data[address][office].street'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'data[address][office].street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'data[address][office][street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'office[street]', 'data[address][office][street].prop'), + + array(self::LEVEL_2, 'address', 'address', 'street', '[office].street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office].street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'children[address].data'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'children[address].data.office'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'children[address].data.office.street'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'children[address].data.office.street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'children[address].data.office[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'children[address].data.office[street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'children[address].data[office]'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office].street', 'children[address].data[office].street'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office].street', 'children[address].data[office].street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'children[address].data[office][street]'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'children[address].data[office][street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'data.address.office.street'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'data.address.office.street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'data.address.office[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'data.address.office[street].prop'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office].street', 'data.address[office].street'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office].street', 'data.address[office].street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'data.address[office][street]'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office].street', 'data.address[office][street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office].street', 'data[address].office.street'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office].street', 'data[address].office.street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office].street', 'data[address].office[street]'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office].street', 'data[address].office[street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office].street', 'data[address][office].street'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office].street', 'data[address][office].street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office].street', 'data[address][office][street]'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office].street', 'data[address][office][street].prop'), + + array(self::LEVEL_2, 'address', '[address]', 'street', '[office].street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office].street', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'children[address].data'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'children[address].data.office'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'children[address].data.office.street'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'children[address].data.office.street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'children[address].data.office[street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'children[address].data.office[street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'children[address].data[office]'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office].street', 'children[address].data[office].street'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office].street', 'children[address].data[office].street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'children[address].data[office][street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'children[address].data[office][street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office].street', 'data.address.office.street'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office].street', 'data.address.office.street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office].street', 'data.address.office[street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office].street', 'data.address.office[street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office].street', 'data.address[office].street'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office].street', 'data.address[office].street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office].street', 'data.address[office][street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office].street', 'data.address[office][street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'data[address].office.street'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'data[address].office.street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'data[address].office[street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'data[address].office[street].prop'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office].street', 'data[address][office].street'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office].street', 'data[address][office].street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'data[address][office][street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office].street', 'data[address][office][street].prop'), + + array(self::LEVEL_2, 'address', 'address', 'street', '[office][street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office][street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'children[address].data'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'children[address].data.office'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'children[address].data.office.street'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'children[address].data.office.street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'children[address].data.office[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'children[address].data.office[street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'children[address].data[office]'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'children[address].data[office].street'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'children[address].data[office].street.prop'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office][street]', 'children[address].data[office][street]'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office][street]', 'children[address].data[office][street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'data.address.office.street'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'data.address.office.street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'data.address.office[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'data.address.office[street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'data.address[office].street'), + array(self::LEVEL_1, 'address', 'address', 'street', '[office][street]', 'data.address[office].street.prop'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office][street]', 'data.address[office][street]'), + array(self::LEVEL_2, 'address', 'address', 'street', '[office][street]', 'data.address[office][street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office][street]', 'data[address].office.street'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office][street]', 'data[address].office.street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office][street]', 'data[address].office[street]'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office][street]', 'data[address].office[street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office][street]', 'data[address][office].street'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office][street]', 'data[address][office].street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office][street]', 'data[address][office][street]'), + array(self::LEVEL_0, 'address', 'address', 'street', '[office][street]', 'data[address][office][street].prop'), + + array(self::LEVEL_2, 'address', '[address]', 'street', '[office][street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office][street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'children[address].data'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'children[address].data.office'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'children[address].data.office.street'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'children[address].data.office.street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'children[address].data.office[street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'children[address].data.office[street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'children[address].data[office]'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'children[address].data[office].street'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'children[address].data[office].street.prop'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office][street]', 'children[address].data[office][street]'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office][street]', 'children[address].data[office][street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office][street]', 'data.address.office.street'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office][street]', 'data.address.office.street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office][street]', 'data.address.office[street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office][street]', 'data.address.office[street].prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office][street]', 'data.address[office].street'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office][street]', 'data.address[office].street.prop'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office][street]', 'data.address[office][street]'), + array(self::LEVEL_0, 'address', '[address]', 'street', '[office][street]', 'data.address[office][street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'data[address].office.street'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'data[address].office.street.prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'data[address].office[street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'data[address].office[street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'data[address][office].street'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[office][street]', 'data[address][office].street.prop'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office][street]', 'data[address][office][street]'), + array(self::LEVEL_2, 'address', '[address]', 'street', '[office][street]', 'data[address][office][street].prop'), + + // Edge cases which must not occur + array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'children[address][street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'children[address][street].prop'), + array(self::LEVEL_1, 'address', 'address', 'street', '[street]', 'children[address][street]'), + array(self::LEVEL_1, 'address', 'address', 'street', '[street]', 'children[address][street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'street', 'children[address][street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', 'street', 'children[address][street].prop'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[street]', 'children[address][street]'), + array(self::LEVEL_1, 'address', '[address]', 'street', '[street]', 'children[address][street].prop'), + + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'children[person].children[address].children[street]'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'children[person].children[address].data.street'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'children[person].data.address.street'), + array(self::LEVEL_0, 'address', 'person.address', 'street', 'street', 'data.address.street'), + + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].children[office].children[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].children[office].data.street'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'children[address].data.street'), + array(self::LEVEL_1, 'address', 'address', 'street', 'office.street', 'data.address.street'), + ); + } + + /** + * @dataProvider provideDefaultTests + */ + public function testDefaultErrorMapping($target, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath) + { + $violation = $this->getConstraintViolation($violationPath); + $parent = $this->getForm('parent'); + $child = $this->getForm($childName, $childPath); + $grandChild = $this->getForm($grandChildName, $grandChildPath); + + $parent->add($child); + $child->add($grandChild); + + $this->mapper->mapViolation($violation, $parent); + + if (self::LEVEL_0 === $target) { + $this->assertEquals(array($this->getFormError()), $parent->getErrors(), $parent->getName().' should have an error, but has none'); + $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); + $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); + } elseif (self::LEVEL_1 === $target) { + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $child->getErrors(), $childName.' should have an error, but has none'); + $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); + } else { + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); + } + } + + public function provideCustomDataErrorTests() + { + return array( + // mapping target, error mapping, child name, its property path, grand child name, its property path, violation path + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.foo'), + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.foo.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[foo]'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[foo].prop'), + + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.address'), + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.address.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[address]'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[address].prop'), + + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo]'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo].prop'), + + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.address'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.address.prop'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[address]'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[address].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo.prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo]'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo].prop'), + + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.address'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.address.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[address]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[address].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.foo'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.foo.prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[foo]'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[foo].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.address'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.address.prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[address]'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[address].prop'), + + array(self::LEVEL_2, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.foo.street'), + array(self::LEVEL_2, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.foo.street.prop'), + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.foo[street]'), + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.foo[street].prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[foo].street'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[foo].street.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[foo][street]'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[foo][street].prop'), + + array(self::LEVEL_2, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.address.street'), + array(self::LEVEL_2, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.address.street.prop'), + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.address[street]'), + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', 'street', 'data.address[street].prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[address].street'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[address].street.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[address][street]'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', 'street', 'data[address][street].prop'), + + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data.foo.street'), + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data.foo.street.prop'), + array(self::LEVEL_2, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data.foo[street]'), + array(self::LEVEL_2, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data.foo[street].prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data[foo].street'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data[foo].street.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data[foo][street]'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data[foo][street].prop'), + + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data.address.street'), + array(self::LEVEL_1, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data.address.street.prop'), + array(self::LEVEL_2, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data.address[street]'), + array(self::LEVEL_2, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data.address[street].prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data[address].street'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data[address].street.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data[address][street]'), + array(self::LEVEL_0, 'foo', 'address', 'address', 'address', 'street', '[street]', 'data[address][street].prop'), + + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo.street'), + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo.street.prop'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo[street]'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo[street].prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo].street'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo].street.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo][street]'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo][street].prop'), + + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.address.street'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.address.street.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.address[street]'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.address[street].prop'), + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[address].street'), + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[address].street.prop'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[address][street]'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[address][street].prop'), + + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data.foo.street'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data.foo.street.prop'), + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data.foo[street]'), + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data.foo[street].prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data[foo].street'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data[foo].street.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data[foo][street]'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data[foo][street].prop'), + + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data.address.street'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data.address.street.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data.address[street]'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data.address[street].prop'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data[address].street'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data[address].street.prop'), + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data[address][street]'), + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', '[street]', 'data[address][street].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo.street'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo.street.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo[street]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo[street].prop'), + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo].street'), + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo].street.prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo][street]'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo][street].prop'), + + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.address.street'), + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.address.street.prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.address[street]'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.address[street].prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[address].street'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[address].street.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[address][street]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[address][street].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.street'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.street.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[street]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[street].prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].street'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].street.prop'), + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][street]'), + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][street].prop'), + + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data.address.street'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data.address.street.prop'), + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data.address[street]'), + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data.address[street].prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data[address].street'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data[address].street.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data[address][street]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', '[street]', 'data[address][street].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.foo.street'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.foo.street.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.foo[street]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.foo[street].prop'), + array(self::LEVEL_2, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[foo].street'), + array(self::LEVEL_2, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[foo].street.prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[foo][street]'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[foo][street].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.address.street'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.address.street.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.address[street]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data.address[street].prop'), + array(self::LEVEL_2, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[address].street'), + array(self::LEVEL_2, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[address].street.prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[address][street]'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', 'street', 'data[address][street].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data.foo.street'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data.foo.street.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data.foo[street]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data.foo[street].prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data[foo].street'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data[foo].street.prop'), + array(self::LEVEL_2, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data[foo][street]'), + array(self::LEVEL_2, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data[foo][street].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data.address.street'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data.address.street.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data.address[street]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data.address[street].prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data[address].street'), + array(self::LEVEL_1, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data[address].street.prop'), + array(self::LEVEL_2, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data[address][street]'), + array(self::LEVEL_2, '[foo]', 'address', 'address', '[address]', 'street', '[street]', 'data[address][street].prop'), + + array(self::LEVEL_1, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar'), + array(self::LEVEL_1, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar]'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar]'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].prop'), + + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.prop'), + array(self::LEVEL_1, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar]'), + array(self::LEVEL_1, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar]'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].prop'), + + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar]'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].prop'), + array(self::LEVEL_1, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar'), + array(self::LEVEL_1, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar]'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].prop'), + + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar]'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.prop'), + array(self::LEVEL_1, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar]'), + array(self::LEVEL_1, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].prop'), + + array(self::LEVEL_2, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.street'), + array(self::LEVEL_2, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.street.prop'), + array(self::LEVEL_1, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar[street]'), + array(self::LEVEL_1, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar[street].prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].street'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].street.prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar][street]'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar][street].prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.street'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.street.prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar[street]'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar[street].prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].street'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].street.prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar][street]'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar][street].prop'), + + array(self::LEVEL_1, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar.street'), + array(self::LEVEL_1, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar.street.prop'), + array(self::LEVEL_2, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar[street]'), + array(self::LEVEL_2, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar[street].prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar].street'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar].street.prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar][street]'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar][street].prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar.street'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar.street.prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar[street]'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar[street].prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar].street'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar].street.prop'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar][street]'), + array(self::LEVEL_0, 'foo.bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar][street].prop'), + + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.street'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.street.prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar[street]'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar[street].prop'), + array(self::LEVEL_2, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].street'), + array(self::LEVEL_2, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].street.prop'), + array(self::LEVEL_1, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar][street]'), + array(self::LEVEL_1, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar][street].prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.street'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.street.prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar[street]'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar[street].prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].street'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].street.prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar][street]'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar][street].prop'), + + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar.street'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar.street.prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar[street]'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar[street].prop'), + array(self::LEVEL_1, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar].street'), + array(self::LEVEL_1, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar].street.prop'), + array(self::LEVEL_2, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar][street]'), + array(self::LEVEL_2, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar][street].prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar.street'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar.street.prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar[street]'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar[street].prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar].street'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar].street.prop'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar][street]'), + array(self::LEVEL_0, 'foo[bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar][street].prop'), + + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.street'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.street.prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar[street]'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar[street].prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].street'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].street.prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar][street]'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar][street].prop'), + array(self::LEVEL_2, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.street'), + array(self::LEVEL_2, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.street.prop'), + array(self::LEVEL_1, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar[street]'), + array(self::LEVEL_1, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar[street].prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].street'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].street.prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar][street]'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar][street].prop'), + + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar.street'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar.street.prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar[street]'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar[street].prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar].street'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar].street.prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar][street]'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar][street].prop'), + array(self::LEVEL_1, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar.street'), + array(self::LEVEL_1, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar.street.prop'), + array(self::LEVEL_2, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar[street]'), + array(self::LEVEL_2, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar[street].prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar].street'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar].street.prop'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar][street]'), + array(self::LEVEL_0, '[foo].bar', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar][street].prop'), + + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.street'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar.street.prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar[street]'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo.bar[street].prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].street'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar].street.prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar][street]'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data.foo[bar][street].prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.street'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar.street.prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar[street]'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo].bar[street].prop'), + array(self::LEVEL_2, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].street'), + array(self::LEVEL_2, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar].street.prop'), + array(self::LEVEL_1, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar][street]'), + array(self::LEVEL_1, '[foo][bar]', 'address', 'address', 'address', 'street', 'street', 'data[foo][bar][street].prop'), + + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar.street'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar.street.prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar[street]'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo.bar[street].prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar].street'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar].street.prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar][street]'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data.foo[bar][street].prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar.street'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar.street.prop'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar[street]'), + array(self::LEVEL_0, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo].bar[street].prop'), + array(self::LEVEL_1, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar].street'), + array(self::LEVEL_1, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar].street.prop'), + array(self::LEVEL_2, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar][street]'), + array(self::LEVEL_2, '[foo][bar]', 'address', 'address', 'address', 'street', '[street]', 'data[foo][bar][street].prop'), + + array(self::LEVEL_2, 'foo', 'address.street', 'address', 'address', 'street', 'street', 'data.foo'), + array(self::LEVEL_2, 'foo', 'address.street', 'address', 'address', 'street', 'street', 'data.foo.prop'), + array(self::LEVEL_2, '[foo]', 'address.street', 'address', 'address', 'street', 'street', 'data[foo]'), + array(self::LEVEL_2, '[foo]', 'address.street', 'address', 'address', 'street', 'street', 'data[foo].prop'), + + array(self::LEVEL_2, 'foo', 'address.street', 'address', 'address', 'street', '[street]', 'data.foo'), + array(self::LEVEL_2, 'foo', 'address.street', 'address', 'address', 'street', '[street]', 'data.foo.prop'), + array(self::LEVEL_2, '[foo]', 'address.street', 'address', 'address', 'street', '[street]', 'data[foo]'), + array(self::LEVEL_2, '[foo]', 'address.street', 'address', 'address', 'street', '[street]', 'data[foo].prop'), + + array(self::LEVEL_2, 'foo', 'address.street', 'address', '[address]', 'street', 'street', 'data.foo'), + array(self::LEVEL_2, 'foo', 'address.street', 'address', '[address]', 'street', 'street', 'data.foo.prop'), + array(self::LEVEL_2, '[foo]', 'address.street', 'address', '[address]', 'street', 'street', 'data[foo]'), + array(self::LEVEL_2, '[foo]', 'address.street', 'address', '[address]', 'street', 'street', 'data[foo].prop'), + + array(self::LEVEL_2, 'foo.bar', 'address.street', 'address', 'address', 'street', 'street', 'data.foo.bar'), + array(self::LEVEL_2, 'foo.bar', 'address.street', 'address', 'address', 'street', 'street', 'data.foo.bar.prop'), + array(self::LEVEL_2, 'foo[bar]', 'address.street', 'address', 'address', 'street', 'street', 'data.foo[bar]'), + array(self::LEVEL_2, 'foo[bar]', 'address.street', 'address', 'address', 'street', 'street', 'data.foo[bar].prop'), + array(self::LEVEL_2, '[foo].bar', 'address.street', 'address', 'address', 'street', 'street', 'data[foo].bar'), + array(self::LEVEL_2, '[foo].bar', 'address.street', 'address', 'address', 'street', 'street', 'data[foo].bar.prop'), + array(self::LEVEL_2, '[foo][bar]', 'address.street', 'address', 'address', 'street', 'street', 'data[foo][bar]'), + array(self::LEVEL_2, '[foo][bar]', 'address.street', 'address', 'address', 'street', 'street', 'data[foo][bar].prop'), + + array(self::LEVEL_2, 'foo.bar', 'address.street', 'address', 'address', 'street', '[street]', 'data.foo.bar'), + array(self::LEVEL_2, 'foo.bar', 'address.street', 'address', 'address', 'street', '[street]', 'data.foo.bar.prop'), + array(self::LEVEL_2, 'foo[bar]', 'address.street', 'address', 'address', 'street', '[street]', 'data.foo[bar]'), + array(self::LEVEL_2, 'foo[bar]', 'address.street', 'address', 'address', 'street', '[street]', 'data.foo[bar].prop'), + array(self::LEVEL_2, '[foo].bar', 'address.street', 'address', 'address', 'street', '[street]', 'data[foo].bar'), + array(self::LEVEL_2, '[foo].bar', 'address.street', 'address', 'address', 'street', '[street]', 'data[foo].bar.prop'), + array(self::LEVEL_2, '[foo][bar]', 'address.street', 'address', 'address', 'street', '[street]', 'data[foo][bar]'), + array(self::LEVEL_2, '[foo][bar]', 'address.street', 'address', 'address', 'street', '[street]', 'data[foo][bar].prop'), + + array(self::LEVEL_2, 'foo.bar', 'address.street', 'address', '[address]', 'street', 'street', 'data.foo.bar'), + array(self::LEVEL_2, 'foo.bar', 'address.street', 'address', '[address]', 'street', 'street', 'data.foo.bar.prop'), + array(self::LEVEL_2, 'foo[bar]', 'address.street', 'address', '[address]', 'street', 'street', 'data.foo[bar]'), + array(self::LEVEL_2, 'foo[bar]', 'address.street', 'address', '[address]', 'street', 'street', 'data.foo[bar].prop'), + array(self::LEVEL_2, '[foo].bar', 'address.street', 'address', '[address]', 'street', 'street', 'data[foo].bar'), + array(self::LEVEL_2, '[foo].bar', 'address.street', 'address', '[address]', 'street', 'street', 'data[foo].bar.prop'), + array(self::LEVEL_2, '[foo][bar]', 'address.street', 'address', '[address]', 'street', 'street', 'data[foo][bar]'), + array(self::LEVEL_2, '[foo][bar]', 'address.street', 'address', '[address]', 'street', 'street', 'data[foo][bar].prop'), + + // Edge cases + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo.street'), + array(self::LEVEL_2, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo.street.prop'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo[street]'), + array(self::LEVEL_1, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data.foo[street].prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo].street'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo].street.prop'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo][street]'), + array(self::LEVEL_0, 'foo', 'address', 'address', '[address]', 'street', 'street', 'data[foo][street].prop'), + + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo.street'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo.street.prop'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo[street]'), + array(self::LEVEL_0, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data.foo[street].prop'), + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo].street'), + array(self::LEVEL_2, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo].street.prop'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo][street]'), + array(self::LEVEL_1, '[foo]', 'address', 'address', 'address', 'street', 'street', 'data[foo][street].prop'), + ); + } + + /** + * @dataProvider provideCustomDataErrorTests + */ + public function testCustomDataErrorMapping($target, $mapFrom, $mapTo, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath) + { + $violation = $this->getConstraintViolation($violationPath); + $parent = $this->getForm('parent', null, null, array($mapFrom => $mapTo)); + $child = $this->getForm($childName, $childPath); + $grandChild = $this->getForm($grandChildName, $grandChildPath); + + $parent->add($child); + $child->add($grandChild); + + // Add a field mapped to the first element of $mapFrom + // to try to distract the algorithm + // Only add it if we expect the error to come up on a different + // level than LEVEL_0, because in this case the error would + // (correctly) be mapped to the distraction field + if ($target !== self::LEVEL_0) { + $mapFromPath = new PropertyPath($mapFrom); + $mapFromPrefix = $mapFromPath->isIndex(0) + ? '['.$mapFromPath->getElement(0).']' + : $mapFromPath->getElement(0); + $distraction = $this->getForm('distraction', $mapFromPrefix); + + $parent->add($distraction); + } + + $this->mapper->mapViolation($violation, $parent); + + if ($target !== self::LEVEL_0) { + $this->assertCount(0, $distraction->getErrors(), 'distraction should not have an error, but has one'); + } + + if (self::LEVEL_0 === $target) { + $this->assertEquals(array($this->getFormError()), $parent->getErrors(), $parent->getName().' should have an error, but has none'); + $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); + $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); + } elseif (self::LEVEL_1 === $target) { + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $child->getErrors(), $childName.' should have an error, but has none'); + $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); + } else { + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); + } + } + + public function provideCustomFormErrorTests() + { + // This case is different than the data errors, because here the + // left side of the mapping refers to the property path of the actual + // children. In other words, a child error only works if + // 1) the error actually maps to an existing child and + // 2) the property path of that child (relative to the form providing + // the mapping) matches the left side of the mapping + return array( + // mapping target, map from, map to, child name, its property path, grand child name, its property path, violation path + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].children[street].data'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].children[street].data.prop'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].data.street'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].data.street.prop'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].data[street]'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].data[street].prop'), + + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].children[street].data.prop'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data.street.prop'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data[street].prop'), + + // Property path of the erroneous field and mapping must match exactly + array(self::LEVEL_1B, 'foo', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].children[street].data'), + array(self::LEVEL_1B, 'foo', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].children[street].data.prop'), + array(self::LEVEL_1B, 'foo', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].data.street'), + array(self::LEVEL_1B, 'foo', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].data.street.prop'), + array(self::LEVEL_1B, 'foo', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].data[street]'), + array(self::LEVEL_1B, 'foo', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].data[street].prop'), + + array(self::LEVEL_1B, '[foo]', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].children[street].data'), + array(self::LEVEL_1B, '[foo]', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].children[street].data.prop'), + array(self::LEVEL_1B, '[foo]', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].data.street'), + array(self::LEVEL_1B, '[foo]', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].data.street.prop'), + array(self::LEVEL_1B, '[foo]', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].data[street]'), + array(self::LEVEL_1B, '[foo]', 'address', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo].data[street].prop'), + + array(self::LEVEL_1, '[foo]', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].children[street].data'), + array(self::LEVEL_1, '[foo]', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].children[street].data.prop'), + array(self::LEVEL_2, '[foo]', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].data.street'), + array(self::LEVEL_2, '[foo]', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].data.street.prop'), + array(self::LEVEL_1, '[foo]', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].data[street]'), + array(self::LEVEL_1, '[foo]', 'address', 'foo', '[foo]', 'address', 'address', 'street', 'street', 'children[foo].data[street].prop'), + + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[foo].children[street].data'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[foo].children[street].data.prop'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[foo].data.street'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[foo].data.street.prop'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[foo].data[street]'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[foo].data[street].prop'), + + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data.street.prop'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data[street].prop'), + + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[foo].children[street].data'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[foo].children[street].data.prop'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[foo].data.street'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[foo].data.street.prop'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[foo].data[street]'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[foo].data[street].prop'), + + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].children[street].data.prop'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data.street.prop'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data[street].prop'), + + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[foo].children[street].data'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[foo].children[street].data.prop'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[foo].data.street'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[foo].data.street.prop'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[foo].data[street]'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[foo].data[street].prop'), + + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].children[street].data'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].children[street].data.prop'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data.street.prop'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'foo', 'address', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data[street].prop'), + + // Map to a nested child + array(self::LEVEL_2, 'foo', 'address.street', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[foo]'), + array(self::LEVEL_2, 'foo', 'address.street', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[foo]'), + array(self::LEVEL_2, 'foo', 'address.street', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[foo]'), + array(self::LEVEL_2, 'foo', 'address.street', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[foo]'), + + // Map from a nested child + array(self::LEVEL_1B, 'address.street', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].children[street]'), + array(self::LEVEL_1B, 'address.street', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_1, 'address.street', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_2, 'address.street', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].children[street]'), + array(self::LEVEL_1B, 'address.street', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_2, 'address.street', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'address.street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].children[street]'), + array(self::LEVEL_2, 'address.street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_1, 'address.street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_2, 'address.street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].children[street]'), + array(self::LEVEL_1, 'address.street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_2, 'address.street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data[street]'), + + array(self::LEVEL_2, 'address[street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].children[street]'), + array(self::LEVEL_2, 'address[street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_1B, 'address[street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1B, 'address[street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].children[street]'), + array(self::LEVEL_1, 'address[street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1B, 'address[street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, 'address[street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].children[street]'), + array(self::LEVEL_2, 'address[street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_1, 'address[street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_2, 'address[street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].children[street]'), + array(self::LEVEL_1, 'address[street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_2, 'address[street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data[street]'), + + array(self::LEVEL_2, '[address].street', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].children[street]'), + array(self::LEVEL_2, '[address].street', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_1, '[address].street', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_2, '[address].street', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].children[street]'), + array(self::LEVEL_1, '[address].street', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_2, '[address].street', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_1B, '[address].street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].children[street]'), + array(self::LEVEL_1B, '[address].street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_1, '[address].street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_2, '[address].street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].children[street]'), + array(self::LEVEL_1B, '[address].street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_2, '[address].street', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data[street]'), + + array(self::LEVEL_2, '[address][street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].children[street]'), + array(self::LEVEL_2, '[address][street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_1, '[address][street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_2, '[address][street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].children[street]'), + array(self::LEVEL_1, '[address][street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_2, '[address][street]', 'foo', 'foo', 'foo', 'address', 'address', 'street', '[street]', 'children[address].data[street]'), + array(self::LEVEL_2, '[address][street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].children[street]'), + array(self::LEVEL_2, '[address][street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_1B, '[address][street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1B, '[address][street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].children[street]'), + array(self::LEVEL_1, '[address][street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data.street'), + array(self::LEVEL_1B, '[address][street]', 'foo', 'foo', 'foo', 'address', '[address]', 'street', '[street]', 'children[address].data[street]'), + ); + } + + /** + * @dataProvider provideCustomFormErrorTests + */ + public function testCustomFormErrorMapping($target, $mapFrom, $mapTo, $errorName, $errorPath, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath) + { + $violation = $this->getConstraintViolation($violationPath); + $parent = $this->getForm('parent', null, null, array($mapFrom => $mapTo)); + $child = $this->getForm($childName, $childPath); + $grandChild = $this->getForm($grandChildName, $grandChildPath); + $errorChild = $this->getForm($errorName, $errorPath); + + $parent->add($child); + $parent->add($errorChild); + $child->add($grandChild); + + $this->mapper->mapViolation($violation, $parent); + + if (self::LEVEL_0 === $target) { + $this->assertCount(0, $errorChild->getErrors(), $errorName.' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $parent->getErrors(), $parent->getName().' should have an error, but has none'); + $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); + $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); + } elseif (self::LEVEL_1 === $target) { + $this->assertCount(0, $errorChild->getErrors(), $errorName.' should not have an error, but has one'); + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $child->getErrors(), $childName.' should have an error, but has none'); + $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); + } elseif (self::LEVEL_1B === $target) { + $this->assertEquals(array($this->getFormError()), $errorChild->getErrors(), $errorName.' should have an error, but has none'); + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); + $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); + } else { + $this->assertCount(0, $errorChild->getErrors(), $errorName.' should not have an error, but has one'); + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); + } + } + + public function provideErrorTestsForFormInheritingParentData() + { + return array( + // mapping target, child name, its property path, grand child name, its property path, violation path + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address].children[street].data'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address].children[street].data.prop'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address].data.street'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'children[address].data.street.prop'), + array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'children[address].data[street]'), + array(self::LEVEL_1, 'address', 'address', 'street', 'street', 'children[address].data[street].prop'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'data.street'), + array(self::LEVEL_2, 'address', 'address', 'street', 'street', 'data.street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[street]'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data.address.street'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data.address.street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data.address[street]'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data.address[street].prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[address].street'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[address].street.prop'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[address][street]'), + array(self::LEVEL_0, 'address', 'address', 'street', 'street', 'data[address][street].prop'), + ); + } + + /** + * @dataProvider provideErrorTestsForFormInheritingParentData + */ + public function testErrorMappingForFormInheritingParentData($target, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath) + { + $violation = $this->getConstraintViolation($violationPath); + $parent = $this->getForm('parent'); + $child = $this->getForm($childName, $childPath, null, array(), true); + $grandChild = $this->getForm($grandChildName, $grandChildPath); + + $parent->add($child); + $child->add($grandChild); + + $this->mapper->mapViolation($violation, $parent); + + if (self::LEVEL_0 === $target) { + $this->assertEquals(array($this->getFormError()), $parent->getErrors(), $parent->getName().' should have an error, but has none'); + $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); + $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); + } elseif (self::LEVEL_1 === $target) { + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $child->getErrors(), $childName.' should have an error, but has none'); + $this->assertCount(0, $grandChild->getErrors(), $grandChildName.' should not have an error, but has one'); + } else { + $this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one'); + $this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one'); + $this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none'); + } + } +} diff --git a/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationPathTest.php b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationPathTest.php new file mode 100644 index 00000000..02df8f43 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationPathTest.php @@ -0,0 +1,245 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Validator\ViolationMapper; + +use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationPath; + +/** + * @author Bernhard Schussek + */ +class ViolationPathTest extends \PHPUnit_Framework_TestCase +{ + public function providePaths() + { + return array( + array('children[address]', array( + array('address', true, true), + )), + array('children[address].children[street]', array( + array('address', true, true), + array('street', true, true), + )), + array('children[address][street]', array( + array('address', true, true), + ), 'children[address]'), + array('children[address].data', array( + array('address', true, true), + ), 'children[address]'), + array('children[address].data.street', array( + array('address', true, true), + array('street', false, false), + )), + array('children[address].data[street]', array( + array('address', true, true), + array('street', false, true), + )), + array('children[address].children[street].data.name', array( + array('address', true, true), + array('street', true, true), + array('name', false, false), + )), + array('children[address].children[street].data[name]', array( + array('address', true, true), + array('street', true, true), + array('name', false, true), + )), + array('data.address', array( + array('address', false, false), + )), + array('data[address]', array( + array('address', false, true), + )), + array('data.address.street', array( + array('address', false, false), + array('street', false, false), + )), + array('data[address].street', array( + array('address', false, true), + array('street', false, false), + )), + array('data.address[street]', array( + array('address', false, false), + array('street', false, true), + )), + array('data[address][street]', array( + array('address', false, true), + array('street', false, true), + )), + // A few invalid examples + array('data', array(), ''), + array('children', array(), ''), + array('children.address', array(), ''), + array('children.address[street]', array(), ''), + ); + } + + /** + * @dataProvider providePaths + */ + public function testCreatePath($string, $entries, $slicedPath = null) + { + if (null === $slicedPath) { + $slicedPath = $string; + } + + $path = new ViolationPath($string); + + $this->assertSame($slicedPath, $path->__toString()); + $this->assertSame(count($entries), count($path->getElements())); + $this->assertSame(count($entries), $path->getLength()); + + foreach ($entries as $index => $entry) { + $this->assertEquals($entry[0], $path->getElement($index)); + $this->assertSame($entry[1], $path->mapsForm($index)); + $this->assertSame($entry[2], $path->isIndex($index)); + $this->assertSame(!$entry[2], $path->isProperty($index)); + } + } + + public function provideParents() + { + return array( + array('children[address]', null), + array('children[address].children[street]', 'children[address]'), + array('children[address].data.street', 'children[address]'), + array('children[address].data[street]', 'children[address]'), + array('data.address', null), + array('data.address.street', 'data.address'), + array('data.address[street]', 'data.address'), + array('data[address].street', 'data[address]'), + array('data[address][street]', 'data[address]'), + ); + } + + /** + * @dataProvider provideParents + */ + public function testGetParent($violationPath, $parentPath) + { + $path = new ViolationPath($violationPath); + $parent = $parentPath === null ? null : new ViolationPath($parentPath); + + $this->assertEquals($parent, $path->getParent()); + } + + public function testGetElement() + { + $path = new ViolationPath('children[address].data[street].name'); + + $this->assertEquals('street', $path->getElement(1)); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testGetElementDoesNotAcceptInvalidIndices() + { + $path = new ViolationPath('children[address].data[street].name'); + + $path->getElement(3); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testGetElementDoesNotAcceptNegativeIndices() + { + $path = new ViolationPath('children[address].data[street].name'); + + $path->getElement(-1); + } + + public function testIsProperty() + { + $path = new ViolationPath('children[address].data[street].name'); + + $this->assertFalse($path->isProperty(1)); + $this->assertTrue($path->isProperty(2)); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testIsPropertyDoesNotAcceptInvalidIndices() + { + $path = new ViolationPath('children[address].data[street].name'); + + $path->isProperty(3); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testIsPropertyDoesNotAcceptNegativeIndices() + { + $path = new ViolationPath('children[address].data[street].name'); + + $path->isProperty(-1); + } + + public function testIsIndex() + { + $path = new ViolationPath('children[address].data[street].name'); + + $this->assertTrue($path->isIndex(1)); + $this->assertFalse($path->isIndex(2)); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testIsIndexDoesNotAcceptInvalidIndices() + { + $path = new ViolationPath('children[address].data[street].name'); + + $path->isIndex(3); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testIsIndexDoesNotAcceptNegativeIndices() + { + $path = new ViolationPath('children[address].data[street].name'); + + $path->isIndex(-1); + } + + public function testMapsForm() + { + $path = new ViolationPath('children[address].data[street].name'); + + $this->assertTrue($path->mapsForm(0)); + $this->assertFalse($path->mapsForm(1)); + $this->assertFalse($path->mapsForm(2)); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testMapsFormDoesNotAcceptInvalidIndices() + { + $path = new ViolationPath('children[address].data[street].name'); + + $path->mapsForm(3); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testMapsFormDoesNotAcceptNegativeIndices() + { + $path = new ViolationPath('children[address].data[street].name'); + + $path->mapsForm(-1); + } +} -- cgit v1.2.3