Skip to content

Commit

Permalink
[Form] Added option 'value_transformer' and 'normalization_transforme…
Browse files Browse the repository at this point in the history
…r' to Field class
  • Loading branch information
Bernhard Schussek authored and fabpot committed Nov 16, 2010
1 parent ece9691 commit 3127312
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 65 deletions.
10 changes: 10 additions & 0 deletions src/Symfony/Component/Form/Field.php
Expand Up @@ -69,6 +69,8 @@ public function __construct($key, array $options = array())
$this->addOption('required', true);
$this->addOption('disabled', false);
$this->addOption('property_path', (string)$key);
$this->addOption('value_transformer');
$this->addOption('normalization_transformer');

$this->key = (string)$key;

Expand All @@ -78,6 +80,14 @@ public function __construct($key, array $options = array())

parent::__construct($options);

if ($this->getOption('value_transformer')) {
$this->setValueTransformer($this->getOption('value_transformer'));
}

if ($this->getOption('normalization_transformer')) {
$this->setNormalizationTransformer($this->getOption('normalization_transformer'));
}

$this->normalizedData = $this->normalize($this->data);
$this->transformedData = $this->transform($this->normalizedData);
$this->required = $this->getOption('required');
Expand Down
118 changes: 69 additions & 49 deletions tests/Symfony/Tests/Component/Form/FieldTest.php
Expand Up @@ -133,25 +133,28 @@ public function testGetIdIncludesParent()
$this->assertEquals('news_article_title', $this->field->getId());
}

public function testLocaleIsPassedToLocalizableValueTransformer_setLocaleCalledBefore()
{
$transformer = $this->getMock('Symfony\Component\Form\ValueTransformer\ValueTransformerInterface');
$transformer->expects($this->once())
->method('setLocale')
->with($this->equalTo('de_DE'));

$this->field->setLocale('de_DE');
$this->field->setValueTransformer($transformer);
}
// public function testLocaleIsPassedToLocalizableValueTransformer_setLocaleCalledBefore()
// {
// $transformer = $this->getMock('Symfony\Component\Form\ValueTransformer\ValueTransformerInterface');
// $transformer->expects($this->once())
// ->method('setLocale')
// ->with($this->equalTo('de_DE'));
//
// $this->field->setLocale('de_DE');
// $this->field->setValueTransformer($transformer);
// }

public function testLocaleIsPassedToValueTransformer_setLocaleCalledAfter()
{
$transformer = $this->getMock('Symfony\Component\Form\ValueTransformer\ValueTransformerInterface');
$transformer->expects($this->exactly(2))
->method('setLocale'); // we can't test the params cause they differ :(

$this->field->setValueTransformer($transformer);
$this->field->setLocale('de_DE');
$field = new TestField('title', array(
'value_transformer' => $transformer,
));

$field->setLocale('de_DE');
}

public function testIsRequiredReturnsOwnValueIfNoParent()
Expand Down Expand Up @@ -231,21 +234,24 @@ public function testValuesAreTransformedCorrectlyIfNull_noValueTransformer()

public function testBoundValuesAreTransformedCorrectly()
{
$valueTransformer = $this->createMockTransformer();
$normTransformer = $this->createMockTransformer();

$field = $this->getMock(
'Symfony\Tests\Component\Form\Fixtures\TestField',
array('processData'), // only mock processData()
array('title')
array('title', array(
'value_transformer' => $valueTransformer,
'normalization_transformer' => $normTransformer,
))
);

// 1a. The value is converted to a string and passed to the value transformer
$valueTransformer = $this->createMockTransformer();
$valueTransformer->expects($this->once())
->method('reverseTransform')
->with($this->identicalTo('0'))
->will($this->returnValue('reverse[0]'));

$field->setValueTransformer($valueTransformer);

// 2. The output of the reverse transformation is passed to processData()
// The processed data is accessible through getNormalizedData()
$field->expects($this->once())
Expand All @@ -255,14 +261,11 @@ public function testBoundValuesAreTransformedCorrectly()

// 3. The processed data is denormalized and then accessible through
// getData()
$normTransformer = $this->createMockTransformer();
$normTransformer->expects($this->once())
->method('reverseTransform')
->with($this->identicalTo('processed[reverse[0]]'))
->will($this->returnValue('denorm[processed[reverse[0]]]'));

$field->setNormalizationTransformer($normTransformer);

// 4. The processed data is transformed again and then accessible
// through getDisplayedData()
$valueTransformer->expects($this->once())
Expand All @@ -279,21 +282,22 @@ public function testBoundValuesAreTransformedCorrectly()

public function testBoundValuesAreTransformedCorrectlyIfEmpty_processDataReturnsValue()
{
$transformer = $this->createMockTransformer();

$field = $this->getMock(
'Symfony\Tests\Component\Form\Fixtures\TestField',
array('processData'), // only mock processData()
array('title')
array('title', array(
'value_transformer' => $transformer,
))
);

// 1. Empty values are converted to NULL by convention
$transformer = $this->createMockTransformer();
$transformer->expects($this->once())
->method('reverseTransform')
->with($this->identicalTo(''))
->will($this->returnValue(null));

$field->setValueTransformer($transformer);

// 2. NULL is passed to processData()
$field->expects($this->once())
->method('processData')
Expand All @@ -314,26 +318,29 @@ public function testBoundValuesAreTransformedCorrectlyIfEmpty_processDataReturns

public function testBoundValuesAreTransformedCorrectlyIfEmpty_processDataReturnsNull()
{
// 1. Empty values are converted to NULL by convention
$transformer = $this->createMockTransformer();

$field = new TestField('title', array(
'value_transformer' => $transformer,
));

// 1. Empty values are converted to NULL by convention
$transformer->expects($this->once())
->method('reverseTransform')
->with($this->identicalTo(''))
->will($this->returnValue(null));

$this->field->setValueTransformer($transformer);

// 2. The processed data is NULL and therefore transformed to an empty
// string by convention
$transformer->expects($this->once())
->method('transform')
->with($this->identicalTo(null))
->will($this->returnValue(''));

$this->field->bind('');
$field->bind('');

$this->assertSame(null, $this->field->getData());
$this->assertEquals('', $this->field->getDisplayedData());
$this->assertSame(null, $field->getData());
$this->assertEquals('', $field->getDisplayedData());
}

public function testBoundValuesAreTransformedCorrectlyIfEmpty_processDataReturnsNull_noValueTransformer()
Expand All @@ -348,25 +355,30 @@ public function testValuesAreTransformedCorrectly()
{
// The value is first passed to the normalization transformer...
$normTransformer = $this->createMockTransformer();
$normTransformer->expects($this->once())
$normTransformer->expects($this->exactly(2))
->method('transform')
->with($this->identicalTo(0))
// Impossible to test with PHPUnit because called twice
// ->with($this->identicalTo(0))
->will($this->returnValue('norm[0]'));

// ...and then to the value transformer
$valueTransformer = $this->createMockTransformer();
$valueTransformer->expects($this->once())
$valueTransformer->expects($this->exactly(2))
->method('transform')
->with($this->identicalTo('norm[0]'))
// Impossible to test with PHPUnit because called twice
// ->with($this->identicalTo('norm[0]'))
->will($this->returnValue('transform[norm[0]]'));

$this->field->setNormalizationTransformer($normTransformer);
$this->field->setValueTransformer($valueTransformer);
$this->field->setData(0);
$field = new TestField('title', array(
'value_transformer' => $valueTransformer,
'normalization_transformer' => $normTransformer,
));

$field->setData(0);

$this->assertEquals(0, $this->field->getData());
$this->assertEquals('norm[0]', $this->field->getNormalizedData());
$this->assertEquals('transform[norm[0]]', $this->field->getDisplayedData());
$this->assertEquals(0, $field->getData());
$this->assertEquals('norm[0]', $field->getNormalizedData());
$this->assertEquals('transform[norm[0]]', $field->getDisplayedData());
}

public function testBoundValuesAreTrimmedBeforeTransforming()
Expand All @@ -378,16 +390,20 @@ public function testBoundValuesAreTrimmedBeforeTransforming()
->with($this->identicalTo('a'))
->will($this->returnValue('reverse[a]'));

$transformer->expects($this->once())
$transformer->expects($this->exactly(2))
->method('transform')
->with($this->identicalTo('reverse[a]'))
// Impossible to test with PHPUnit because called twice
// ->with($this->identicalTo('reverse[a]'))
->will($this->returnValue('a'));

$this->field->setValueTransformer($transformer);
$this->field->bind(' a ');
$field = new TestField('title', array(
'value_transformer' => $transformer,
));

$this->assertEquals('a', $this->field->getDisplayedData());
$this->assertEquals('reverse[a]', $this->field->getData());
$field->bind(' a ');

$this->assertEquals('a', $field->getDisplayedData());
$this->assertEquals('reverse[a]', $field->getData());
}

public function testBoundValuesAreNotTrimmedBeforeTransformingIfDisabled()
Expand All @@ -399,13 +415,17 @@ public function testBoundValuesAreNotTrimmedBeforeTransformingIfDisabled()
->with($this->identicalTo(' a '))
->will($this->returnValue('reverse[ a ]'));

$transformer->expects($this->once())
$transformer->expects($this->exactly(2))
->method('transform')
->with($this->identicalTo('reverse[ a ]'))
// Impossible to test with PHPUnit because called twice
// ->with($this->identicalTo('reverse[ a ]'))
->will($this->returnValue(' a '));

$field = new TestField('title', array('trim' => false));
$field->setValueTransformer($transformer);
$field = new TestField('title', array(
'trim' => false,
'value_transformer' => $transformer,
));

$field->bind(' a ');

$this->assertEquals(' a ', $field->getDisplayedData());
Expand Down
16 changes: 0 additions & 16 deletions tests/Symfony/Tests/Component/Form/Fixtures/TestField.php
Expand Up @@ -11,22 +11,6 @@ public function render(array $attributes = array())
{
}

/**
* Expose method for testing purposes
*/
public function setNormalizationTransformer(ValueTransformerInterface $normalizationTransformer)
{
parent::setNormalizationTransformer($normalizationTransformer);
}

/**
* Expose method for testing purposes
*/
public function setValueTransformer(ValueTransformerInterface $valueTransformer)
{
parent::setValueTransformer($valueTransformer);
}

/**
* Expose method for testing purposes
*/
Expand Down

0 comments on commit 3127312

Please sign in to comment.