|
1 | 1 | <?php |
2 | 2 |
|
| 3 | +// Declare strict is necessary here to provoke type errors |
| 4 | +declare(strict_types = 1); |
| 5 | + |
3 | 6 | /* |
4 | 7 | * This file is part of the Symfony package. |
5 | 8 | * |
|
17 | 20 | use Symfony\Component\EventDispatcher\EventDispatcher; |
18 | 21 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
19 | 22 | use Symfony\Component\Form\DataMapperInterface; |
| 23 | +use Symfony\Component\Form\Exception\RuntimeException; |
20 | 24 | use Symfony\Component\Form\Extension\Core\DataMapper\AccessorMapper; |
21 | 25 | use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; |
22 | 26 | use Symfony\Component\Form\Form; |
@@ -236,6 +240,63 @@ public function getEngineClosure() |
236 | 240 | $this->assertSame('petrol', $data->getEngineClosure()); |
237 | 241 | } |
238 | 242 |
|
| 243 | + public static function invalidValueProvider(): \Generator |
| 244 | + { |
| 245 | + yield 'validation error' => ['#Corn is not a valid engine type#', 'corn']; |
| 246 | + yield 'type error' => ['#Argument 1 passed to class@anonymous::setEngineClosure\(\) must be of the type string, object given#', new stdClass()]; |
| 247 | + } |
| 248 | + |
| 249 | + /** |
| 250 | + * @dataProvider InvalidValueProvider |
| 251 | + */ |
| 252 | + public function testSetAccessorCatchesExceptions(string $errorMessagePattern, $value) |
| 253 | + { |
| 254 | + $this->setupPropertyPathMapper($this->any(), $this->any()); |
| 255 | + |
| 256 | + $data = new class('petrol') { |
| 257 | + private $engine; |
| 258 | + |
| 259 | + public function __construct(string $engine) |
| 260 | + { |
| 261 | + $this->engine = $engine; |
| 262 | + } |
| 263 | + |
| 264 | + public function setEngineClosure(string $data) |
| 265 | + { |
| 266 | + if ($data === 'corn') { |
| 267 | + throw new class extends RuntimeException |
| 268 | + { |
| 269 | + public function __construct() |
| 270 | + { |
| 271 | + parent::__construct('Corn is not a valid engine type'); |
| 272 | + } |
| 273 | + }; |
| 274 | + } |
| 275 | + |
| 276 | + $this->engine = $data; |
| 277 | + } |
| 278 | + |
| 279 | + public function getEngineClosure() |
| 280 | + { |
| 281 | + return $this->engine; |
| 282 | + } |
| 283 | + }; |
| 284 | + |
| 285 | + $config = new FormConfigBuilder('car', null, $this->dispatcher); |
| 286 | + $config->setCompound(true); |
| 287 | + $config->setDataMapper($this->createMapper(true, true)); |
| 288 | + $config->setData($data); |
| 289 | + $form = new Form($config); |
| 290 | + $form |
| 291 | + ->add(new Form(new FormConfigBuilder('engine', null, $this->dispatcher))); |
| 292 | + |
| 293 | + $form->submit(['engine' => $value]); |
| 294 | + $this->assertFalse($form->isValid()); |
| 295 | + $this->assertSame('petrol', $data->getEngineClosure()); |
| 296 | + |
| 297 | + $this->assertMatchesRegularExpression($errorMessagePattern, (string) $form->get('engine')->getErrors()); |
| 298 | + } |
| 299 | + |
239 | 300 | private function setupPropertyPathMapper(Invocation $dataToFormsMatcher, Invocation $formsToDataMatcher): void |
240 | 301 | { |
241 | 302 | $propertyPathMapper = new PropertyPathMapper($this->propertyAccessor); |
|
0 commit comments