4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Form\Tests
;
14 use Symfony\Component\Form\FormTypeGuesserChain
;
15 use Symfony\Component\Form\FormFactory
;
16 use Symfony\Component\Form\Guess\Guess
;
17 use Symfony\Component\Form\Guess\ValueGuess
;
18 use Symfony\Component\Form\Guess\TypeGuess
;
19 use Symfony\Component\Form\Tests\Fixtures\Author
;
20 use Symfony\Component\Form\Tests\Fixtures\FooType
;
21 use Symfony\Component\Form\Tests\Fixtures\FooSubType
;
22 use Symfony\Component\Form\Tests\Fixtures\FooSubTypeWithParentInstance
;
25 * @author Bernhard Schussek <bschussek@gmail.com>
27 class FormFactoryTest
extends \PHPUnit_Framework_TestCase
30 * @var \PHPUnit_Framework_MockObject_MockObject
35 * @var \PHPUnit_Framework_MockObject_MockObject
40 * @var \PHPUnit_Framework_MockObject_MockObject
45 * @var \PHPUnit_Framework_MockObject_MockObject
47 private $resolvedTypeFactory;
54 protected function setUp()
56 if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) {
57 $this->markTestSkipped('The "EventDispatcher" component is not available');
60 $this->resolvedTypeFactory
= $this->getMock('Symfony\Component\Form\ResolvedFormTypeFactoryInterface');
61 $this->guesser1
= $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
62 $this->guesser2
= $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
63 $this->registry
= $this->getMock('Symfony\Component\Form\FormRegistryInterface');
64 $this->factory
= new FormFactory($this->registry
, $this->resolvedTypeFactory
);
66 $this->registry
->expects($this->any())
67 ->method('getTypeGuesser')
68 ->will($this->returnValue(new FormTypeGuesserChain(array(
74 public function testCreateNamedBuilderWithTypeName()
76 $options = array('a' => '1', 'b' => '2');
77 $resolvedType = $this->getMockResolvedType();
79 $this->registry
->expects($this->once())
82 ->will($this->returnValue($resolvedType));
84 $resolvedType->expects($this->once())
85 ->method('createBuilder')
86 ->with($this->factory
, 'name', $options)
87 ->will($this->returnValue('BUILDER'));
89 $this->assertSame('BUILDER', $this->factory
->createNamedBuilder('name', 'type', null, $options));
92 public function testCreateNamedBuilderWithTypeInstance()
94 $options = array('a' => '1', 'b' => '2');
95 $type = new FooType();
96 $resolvedType = $this->getMockResolvedType();
98 $this->resolvedTypeFactory
->expects($this->once())
99 ->method('createResolvedType')
101 ->will($this->returnValue($resolvedType));
103 $resolvedType->expects($this->once())
104 ->method('createBuilder')
105 ->with($this->factory
, 'name', $options)
106 ->will($this->returnValue('BUILDER'));
108 $this->assertSame('BUILDER', $this->factory
->createNamedBuilder('name', $type, null, $options));
111 public function testCreateNamedBuilderWithTypeInstanceWithParentType()
113 $options = array('a' => '1', 'b' => '2');
114 $type = new FooSubType();
115 $resolvedType = $this->getMockResolvedType();
116 $parentResolvedType = $this->getMockResolvedType();
118 $this->registry
->expects($this->once())
121 ->will($this->returnValue($parentResolvedType));
123 $this->resolvedTypeFactory
->expects($this->once())
124 ->method('createResolvedType')
125 ->with($type, array(), $parentResolvedType)
126 ->will($this->returnValue($resolvedType));
128 $resolvedType->expects($this->once())
129 ->method('createBuilder')
130 ->with($this->factory
, 'name', $options)
131 ->will($this->returnValue('BUILDER'));
133 $this->assertSame('BUILDER', $this->factory
->createNamedBuilder('name', $type, null, $options));
136 public function testCreateNamedBuilderWithTypeInstanceWithParentTypeInstance()
138 $options = array('a' => '1', 'b' => '2');
139 $type = new FooSubTypeWithParentInstance();
140 $resolvedType = $this->getMockResolvedType();
141 $parentResolvedType = $this->getMockResolvedType();
143 $this->resolvedTypeFactory
->expects($this->at(0))
144 ->method('createResolvedType')
145 ->with($type->getParent())
146 ->will($this->returnValue($parentResolvedType));
148 $this->resolvedTypeFactory
->expects($this->at(1))
149 ->method('createResolvedType')
150 ->with($type, array(), $parentResolvedType)
151 ->will($this->returnValue($resolvedType));
153 $resolvedType->expects($this->once())
154 ->method('createBuilder')
155 ->with($this->factory
, 'name', $options)
156 ->will($this->returnValue('BUILDER'));
158 $this->assertSame('BUILDER', $this->factory
->createNamedBuilder('name', $type, null, $options));
161 public function testCreateNamedBuilderWithResolvedTypeInstance()
163 $options = array('a' => '1', 'b' => '2');
164 $resolvedType = $this->getMockResolvedType();
166 $resolvedType->expects($this->once())
167 ->method('createBuilder')
168 ->with($this->factory
, 'name', $options)
169 ->will($this->returnValue('BUILDER'));
171 $this->assertSame('BUILDER', $this->factory
->createNamedBuilder('name', $resolvedType, null, $options));
174 public function testCreateNamedBuilderFillsDataOption()
176 $givenOptions = array('a' => '1', 'b' => '2');
177 $expectedOptions = array_merge($givenOptions, array('data' => 'DATA'));
178 $resolvedType = $this->getMockResolvedType();
180 $this->registry
->expects($this->once())
183 ->will($this->returnValue($resolvedType));
185 $resolvedType->expects($this->once())
186 ->method('createBuilder')
187 ->with($this->factory
, 'name', $expectedOptions)
188 ->will($this->returnValue('BUILDER'));
190 $this->assertSame('BUILDER', $this->factory
->createNamedBuilder('name', 'type', 'DATA', $givenOptions));
193 public function testCreateNamedBuilderDoesNotOverrideExistingDataOption()
195 $options = array('a' => '1', 'b' => '2', 'data' => 'CUSTOM');
196 $resolvedType = $this->getMockResolvedType();
198 $this->registry
->expects($this->once())
201 ->will($this->returnValue($resolvedType));
203 $resolvedType->expects($this->once())
204 ->method('createBuilder')
205 ->with($this->factory
, 'name', $options)
206 ->will($this->returnValue('BUILDER'));
208 $this->assertSame('BUILDER', $this->factory
->createNamedBuilder('name', 'type', 'DATA', $options));
212 * @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
213 * @expectedExceptionMessage Expected argument of type "string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface", "stdClass" given
215 public function testCreateNamedBuilderThrowsUnderstandableException()
217 $this->factory
->createNamedBuilder('name', new \
stdClass());
220 public function testCreateUsesTypeNameIfTypeGivenAsString()
222 $options = array('a' => '1', 'b' => '2');
223 $resolvedType = $this->getMockResolvedType();
224 $builder = $this->getMockFormBuilder();
226 $this->registry
->expects($this->once())
229 ->will($this->returnValue($resolvedType));
231 $resolvedType->expects($this->once())
232 ->method('createBuilder')
233 ->with($this->factory
, 'TYPE', $options)
234 ->will($this->returnValue($builder));
236 $builder->expects($this->once())
238 ->will($this->returnValue('FORM'));
240 $this->assertSame('FORM', $this->factory
->create('TYPE', null, $options));
243 public function testCreateUsesTypeNameIfTypeGivenAsObject()
245 $options = array('a' => '1', 'b' => '2');
246 $resolvedType = $this->getMockResolvedType();
247 $builder = $this->getMockFormBuilder();
249 $resolvedType->expects($this->once())
251 ->will($this->returnValue('TYPE'));
253 $resolvedType->expects($this->once())
254 ->method('createBuilder')
255 ->with($this->factory
, 'TYPE', $options)
256 ->will($this->returnValue($builder));
258 $builder->expects($this->once())
260 ->will($this->returnValue('FORM'));
262 $this->assertSame('FORM', $this->factory
->create($resolvedType, null, $options));
265 public function testCreateNamed()
267 $options = array('a' => '1', 'b' => '2');
268 $resolvedType = $this->getMockResolvedType();
269 $builder = $this->getMockFormBuilder();
271 $this->registry
->expects($this->once())
274 ->will($this->returnValue($resolvedType));
276 $resolvedType->expects($this->once())
277 ->method('createBuilder')
278 ->with($this->factory
, 'name', $options)
279 ->will($this->returnValue($builder));
281 $builder->expects($this->once())
283 ->will($this->returnValue('FORM'));
285 $this->assertSame('FORM', $this->factory
->createNamed('name', 'type', null, $options));
288 public function testCreateBuilderForPropertyWithoutTypeGuesser()
290 $registry = $this->getMock('Symfony\Component\Form\FormRegistryInterface');
291 $factory = $this->getMockBuilder('Symfony\Component\Form\FormFactory')
292 ->setMethods(array('createNamedBuilder'))
293 ->setConstructorArgs(array($registry, $this->resolvedTypeFactory
))
296 $factory->expects($this->once())
297 ->method('createNamedBuilder')
298 ->with('firstName', 'text', null, array())
299 ->will($this->returnValue('builderInstance'));
301 $builder = $factory->createBuilderForProperty('Application\Author', 'firstName');
303 $this->assertEquals('builderInstance', $builder);
306 public function testCreateBuilderForPropertyCreatesFormWithHighestConfidence()
308 $this->guesser1
->expects($this->once())
309 ->method('guessType')
310 ->with('Application\Author', 'firstName')
311 ->will($this->returnValue(new TypeGuess(
313 array('max_length' => 10),
314 Guess
::MEDIUM_CONFIDENCE
317 $this->guesser2
->expects($this->once())
318 ->method('guessType')
319 ->with('Application\Author', 'firstName')
320 ->will($this->returnValue(new TypeGuess(
322 array('max_length' => 7),
323 Guess
::HIGH_CONFIDENCE
326 $factory = $this->getMockFactory(array('createNamedBuilder'));
328 $factory->expects($this->once())
329 ->method('createNamedBuilder')
330 ->with('firstName', 'password', null, array('max_length' => 7))
331 ->will($this->returnValue('builderInstance'));
333 $builder = $factory->createBuilderForProperty('Application\Author', 'firstName');
335 $this->assertEquals('builderInstance', $builder);
338 public function testCreateBuilderCreatesTextFormIfNoGuess()
340 $this->guesser1
->expects($this->once())
341 ->method('guessType')
342 ->with('Application\Author', 'firstName')
343 ->will($this->returnValue(null));
345 $factory = $this->getMockFactory(array('createNamedBuilder'));
347 $factory->expects($this->once())
348 ->method('createNamedBuilder')
349 ->with('firstName', 'text')
350 ->will($this->returnValue('builderInstance'));
352 $builder = $factory->createBuilderForProperty('Application\Author', 'firstName');
354 $this->assertEquals('builderInstance', $builder);
357 public function testOptionsCanBeOverridden()
359 $this->guesser1
->expects($this->once())
360 ->method('guessType')
361 ->with('Application\Author', 'firstName')
362 ->will($this->returnValue(new TypeGuess(
364 array('max_length' => 10),
365 Guess
::MEDIUM_CONFIDENCE
368 $factory = $this->getMockFactory(array('createNamedBuilder'));
370 $factory->expects($this->once())
371 ->method('createNamedBuilder')
372 ->with('firstName', 'text', null, array('max_length' => 11))
373 ->will($this->returnValue('builderInstance'));
375 $builder = $factory->createBuilderForProperty(
376 'Application\Author',
379 array('max_length' => 11)
382 $this->assertEquals('builderInstance', $builder);
385 public function testCreateBuilderUsesMaxLengthIfFound()
387 $this->guesser1
->expects($this->once())
388 ->method('guessMaxLength')
389 ->with('Application\Author', 'firstName')
390 ->will($this->returnValue(new ValueGuess(
392 Guess
::MEDIUM_CONFIDENCE
395 $this->guesser2
->expects($this->once())
396 ->method('guessMaxLength')
397 ->with('Application\Author', 'firstName')
398 ->will($this->returnValue(new ValueGuess(
400 Guess
::HIGH_CONFIDENCE
403 $factory = $this->getMockFactory(array('createNamedBuilder'));
405 $factory->expects($this->once())
406 ->method('createNamedBuilder')
407 ->with('firstName', 'text', null, array('max_length' => 20))
408 ->will($this->returnValue('builderInstance'));
410 $builder = $factory->createBuilderForProperty(
411 'Application\Author',
415 $this->assertEquals('builderInstance', $builder);
418 public function testCreateBuilderUsesRequiredSettingWithHighestConfidence()
420 $this->guesser1
->expects($this->once())
421 ->method('guessRequired')
422 ->with('Application\Author', 'firstName')
423 ->will($this->returnValue(new ValueGuess(
425 Guess
::MEDIUM_CONFIDENCE
428 $this->guesser2
->expects($this->once())
429 ->method('guessRequired')
430 ->with('Application\Author', 'firstName')
431 ->will($this->returnValue(new ValueGuess(
433 Guess
::HIGH_CONFIDENCE
436 $factory = $this->getMockFactory(array('createNamedBuilder'));
438 $factory->expects($this->once())
439 ->method('createNamedBuilder')
440 ->with('firstName', 'text', null, array('required' => false))
441 ->will($this->returnValue('builderInstance'));
443 $builder = $factory->createBuilderForProperty(
444 'Application\Author',
448 $this->assertEquals('builderInstance', $builder);
451 public function testCreateBuilderUsesPatternIfFound()
453 $this->guesser1
->expects($this->once())
454 ->method('guessPattern')
455 ->with('Application\Author', 'firstName')
456 ->will($this->returnValue(new ValueGuess(
458 Guess
::MEDIUM_CONFIDENCE
461 $this->guesser2
->expects($this->once())
462 ->method('guessPattern')
463 ->with('Application\Author', 'firstName')
464 ->will($this->returnValue(new ValueGuess(
466 Guess
::HIGH_CONFIDENCE
469 $factory = $this->getMockFactory(array('createNamedBuilder'));
471 $factory->expects($this->once())
472 ->method('createNamedBuilder')
473 ->with('firstName', 'text', null, array('pattern' => '[a-zA-Z]'))
474 ->will($this->returnValue('builderInstance'));
476 $builder = $factory->createBuilderForProperty(
477 'Application\Author',
481 $this->assertEquals('builderInstance', $builder);
484 private function getMockFactory(array $methods = array())
486 return $this->getMockBuilder('Symfony\Component\Form\FormFactory')
487 ->setMethods($methods)
488 ->setConstructorArgs(array($this->registry
, $this->resolvedTypeFactory
))
492 private function getMockResolvedType()
494 return $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
497 private function getMockType()
499 return $this->getMock('Symfony\Component\Form\FormTypeInterface');
502 private function getMockFormBuilder()
504 return $this->getMock('Symfony\Component\Form\Test\FormBuilderInterface');