*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require_once(dirname(__FILE__).'/../../bootstrap/unit.php');
$t = new lime_test(95);
$w1 = new sfWidgetFormInputText(array(), array('class' => 'foo1'));
$w2 = new sfWidgetFormInputText();
// __construct()
$t->diag('__construct()');
$w = new sfWidgetFormSchema();
$t->is($w->getFields(), array(), '__construct() can take no argument');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2));
$w1->setParent($w); $w2->setParent($w);
$t->ok($w->getFields() == array('w1' => $w1, 'w2' => $w2), '__construct() can take an array of named sfWidget objects');
try
{
$w = new sfWidgetFormSchema('string');
$t->fail('__construct() throws a exception when passing a non supported first argument');
}
catch (InvalidArgumentException $e)
{
$t->pass('__construct() throws an exception when passing a non supported first argument');
}
$t->is($w->getFormFormatterName(), 'table', '__construct() sets "form_formatter" option to "table" by default');
$w = new sfWidgetFormSchema(array(), array('form_formatter' => 'list'));
$t->is($w->getFormFormatterName(), 'list', '__construct() can override the default value for the "form_formatter" option');
$t->is($w->getNameFormat(), '%s', '__construct() sets "name_format" option to "table" by default');
$w = new sfWidgetFormSchema(array(), array('name_format' => 'name_%s'));
$t->is($w->getNameFormat(), 'name_%s', '__construct() can override the default value for the "name_format" option');
// implements ArrayAccess
$t->diag('implements ArrayAccess');
$w = new sfWidgetFormSchema();
$w['w1'] = $w1;
$w['w2'] = $w2;
$w1->setParent($w); $w2->setParent($w);
$t->ok($w->getFields() == array('w1' => $w1, 'w2' => $w2), 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
$t->is($w1->getParent(), $w, 'The widget schema is associated with the fields');
$t->is($w2->getParent(), $w, 'The widget schema is associated with the fields');
try
{
$w['w1'] = 'string';
$t->fail('sfWidgetFormSchema implements the ArrayAccess interface for the fields');
}
catch (LogicException $e)
{
$t->pass('sfWidgetFormSchema implements the ArrayAccess interface for the fields');
}
$w = new sfWidgetFormSchema(array('w1' => $w1));
$t->is(isset($w['w1']), true, 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
$t->is(isset($w['w2']), false, 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
$w = new sfWidgetFormSchema(array('w1' => $w1));
$w1->setParent($w); $w2->setParent($w);
$t->ok($w['w1'] == $w1, 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
$t->is($w['w2'], null, 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2));
unset($w['w1']);
$t->is($w['w1'], null, 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
$t->is($w->getPositions(), array('w2'), 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
// unset with numeric keys
$w = new sfWidgetFormSchema(array('0' => $w1, 'w2' => $w2));
unset($w['w2']);
$t->is($w['w2'], null, 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
$t->is($w->getPositions(), array('0'), 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
$w = new sfWidgetFormSchema(array('w1' => $w1, '0' => $w2));
unset($w[0]);
$t->is($w[0], null, 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
$t->is($w->getPositions(), array('w1'), 'sfWidgetFormSchema implements the ArrayAccess interface for the fields');
// ->addFormFormatter() ->setFormFormatterName() ->getFormFormatterName() ->getFormFormatter() ->getFormFormatters()
$t->diag('->addFormFormatter() ->setFormFormatterName() ->getFormFormatterName() ->getFormFormatter() ->getFormFormatters()');
$w = new sfWidgetFormSchema(array('w1' => $w1));
$t->is(get_class($w->getFormFormatter()), 'sfWidgetFormSchemaFormatterTable', '->getFormFormatter() returns a sfWidgetSchemaFormatter object');
$w->addFormFormatter('custom', $customFormatter = new sfWidgetFormSchemaFormatterList($w));
$w->setFormFormatterName('custom');
$t->is(get_class($w->getFormFormatter()), 'sfWidgetFormSchemaFormatterList', '->addFormFormatter() associates a name with a sfWidgetSchemaFormatter object');
$w->setFormFormatterName('list');
$t->is(get_class($w->getFormFormatter()), 'sfWidgetFormSchemaFormatterList', '->setFormFormatterName() set the names of the formatter to use when rendering');
$w->setFormFormatterName('nonexistant');
try
{
$w->getFormFormatter();
$t->fail('->setFormFormatterName() throws a InvalidArgumentException when the form format name is not associated with a formatter');
}
catch (InvalidArgumentException $e)
{
$t->pass('->setFormFormatterName() throws a InvalidArgumentException when the form format name is not associated with a formatter');
}
$formatterNames = array_keys($w->getFormFormatters());
sort($formatterNames);
$t->is($formatterNames, array('custom', 'list', 'table'), '->getFormFormatters() returns an array of all formatter for this widget schema');
// ->setNameFormat() ->getNameFormat() ->generateName()
$t->diag('->setNameFormat() ->getNameFormat() ->generateName()');
$w = new sfWidgetFormSchema();
$t->is($w->generateName('foo'), 'foo', '->generateName() returns a HTML name attribute value for a given field name');
$w->setNameFormat('article[%s]');
$t->is($w->generateName('foo'), 'article[foo]', '->setNameFormat() changes the name format');
$t->is($w->getNameFormat(), 'article[%s]', '->getNameFormat() returns the name format');
$w->setNameFormat(false);
$t->is($w->generateName('foo'), 'foo', '->generateName() returns the name unchanged if the format is false');
try
{
$w->setNameFormat('foo');
$t->fail('->setNameFormat() throws an InvalidArgumentException if the format does not contain %s');
}
catch (InvalidArgumentException $e)
{
$t->pass('->setNameFormat() throws an InvalidArgumentException if the format does not contain %s');
}
$w = new sfWidgetFormSchema(array(
'author' => new sfWidgetFormSchema(array(
'first_name' => new sfWidgetFormInputText(),
'company' => new sfWidgetFormSchema(array(
'name' => new sfWidgetFormInputText(),
)),
)),
));
$w->setNameFormat('article[%s]');
$t->is($w['author']->generateName('first_name'), 'article[author][first_name]', '->generateName() returns a HTML name attribute value for a given field name');
$t->is($w['author']['company']->generateName('name'), 'article[author][company][name]', '->generateName() returns a HTML name attribute value for a given field name');
// ->getParent() ->setParent()
$t->diag('->getParent() ->setParent()');
$author = new sfWidgetFormSchema(array('first_name' => new sfWidgetFormInputText()));
$company = new sfWidgetFormSchema(array('name' => new sfWidgetFormInputText()));
$t->is($company->getParent(), null, '->getParent() returns null if there is no parent widget schema');
$company->setParent($author);
$t->is($company->getParent(), $author, '->getParent() returns the parent widget schema');
// ->setLabels() ->setLabel() ->getLabels() ->getLabel() ->generateLabelName()
$t->diag('->setLabels() ->setLabel() ->getLabels() ->getLabel() ->generateLabelName()');
$w = new sfWidgetFormSchema(array('first_name' => new sfWidgetFormInputText()));
$w->setLabel('first_name', 'A first name');
$t->is($w->getLabels(), array('first_name' => 'A first name'), '->getLabels() returns all current labels');
$w->setLabels(array('first_name' => 'The first name'));
$t->is($w->getFormFormatter()->generateLabelName('first_name'), 'The first name', '->setLabels() changes all current labels');
$w->setLabel('first_name', 'A first name');
$t->is($w->getFormFormatter()->generateLabelName('first_name'), 'A first name', '->setLabel() sets a label value');
// ->setHelps() ->getHelps() ->setHelp() ->getHelp()
$t->diag('->setHelps() ->getHelps() ->setHelp() ->getHelp()');
$w = new sfWidgetFormSchema();
$w->setHelps(array('first_name', 'Please, provide your first name'));
$t->is($w->getHelps(), array('first_name', 'Please, provide your first name'), '->setHelps() changes all help messages');
$w->setHelp('last_name', 'Please, provide your last name');
$t->is($w->getHelp('last_name'), 'Please, provide your last name', '->setHelp() changes one help message');
// ->getLabel() ->setLabel() ->getLabels() ->setLabels()
$t->diag('->getLabel() ->setLabel() ->getLabels() ->setLabels()');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2));
$w->setLabels(array('w1' => 'foo'));
$t->is($w->getLabels(), array('w1' => 'foo', 'w2' => null), '->getLabels() returns the labels');
$t->is($w->getLabel('w1'), 'foo', '->getLabel() returns the label for a given field');
$w->setLabel('w2', 'foo');
$t->is($w->getLabels(), array('w1' => 'foo', 'w2' => 'foo'), '->setLabel() sets a label for a given field');
$w->setLabel('foo');
$t->is($w->getLabel(), 'foo', '->setLabel() can also set the label for the widget schema');
// ->getDefault() ->setDefault() ->getDefaults() ->setDefaults()
$t->diag('->getDefault() ->setDefault() ->getDefaults() ->setDefaults()');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2));
$w->setDefaults(array('w1' => 'foo'));
$t->is($w->getDefaults(), array('w1' => 'foo', 'w2' => null), '->getDefaults() returns the default values');
$t->is($w->getDefault('w1'), 'foo', '->getDefault() returns the default value for a given field');
$w->setDefault('w2', 'foo');
$t->is($w->getDefaults(), array('w1' => 'foo', 'w2' => 'foo'), '->setDefault() sets a default value for a given field');
// ->needsMultipartForm()
$t->diag('->needsMultipartForm()');
$w = new sfWidgetFormSchema(array('w1' => $w1));
$t->is($w->needsMultipartForm(), false, '->needsMultipartForm() returns false if the form schema does not have a widget that needs a multipart form');
$w['w2'] = new sfWidgetFormInputFile();
$t->is($w->needsMultipartForm(), true, '->needsMultipartForm() returns true if the form schema does not have a widget that needs a multipart form');
// ->renderField()
$t->diag('->renderField()');
$w = new sfWidgetFormSchema(array('first_name' => $w1));
$t->is($w->renderField('first_name', 'Fabien'), '', '->renderField() renders a field to HTML');
$ww = clone $w1;
$ww->setAttribute('id', 'foo');
$ww->setAttribute('style', 'color: blue');
$w = new sfWidgetFormSchema(array('first_name' => $ww));
$t->is($w->renderField('first_name', 'Fabien'), '', '->renderField() renders a field to HTML');
try
{
$w->renderField('last_name', 'Potencier');
$t->fail('->renderField() throws an InvalidArgumentException if the field does not exist');
}
catch (InvalidArgumentException $e)
{
$t->pass('->renderField() throws an InvalidArgumentException if the field does not exist');
}
// ->setPositions() ->getPositions()
$t->diag('->setPositions() ->getPositions()');
$w = new sfWidgetFormSchema();
$w['w1'] = $w1;
$w['w2'] = $w2;
$w->setPositions(array('w2', 'w1'));
$t->is($w->getPositions(), array('w2', 'w1'), '->setPositions() changes all field positions');
$w->setPositions(array('w1', 'w2'));
$t->is($w->getPositions(), array('w1', 'w2'), '->setPositions() changes all field positions');
$w = new sfWidgetFormSchema();
$w['w1'] = $w1;
$w['w2'] = $w2;
$w['w1'] = $w1;
$t->is($w->getPositions(), array('w1', 'w2'), '->setPositions() changes all field positions');
$w = new sfWidgetFormSchema();
$w['w1'] = $w1;
$w['w2'] = $w2;
$w->setPositions(array('w1', 'w2', 'w1'));
$t->is($w->getPositions(), array('w1', 'w2'), '->setPositions() does not repeat the fields');
try
{
$w->setPositions(array('w1', 'w2', 'w3'));
$t->fail('->setPositions() throws an InvalidArgumentException if you give it a non existant field name');
}
catch (InvalidArgumentException $e)
{
$t->pass('->setPositions() throws an InvalidArgumentException if you give it a non existant field name');
}
try
{
$w->setPositions(array('w1'));
$t->fail('->setPositions() throws an InvalidArgumentException if you miss a field name');
}
catch (InvalidArgumentException $e)
{
$t->pass('->setPositions() throws an InvalidArgumentException if you miss a field name');
}
// ->moveField()
$t->diag('->moveField()');
$w = new sfWidgetFormSchema();
$w['w1'] = $w1;
$w['w2'] = $w2;
$w['w3'] = $w1;
$w['w4'] = $w2;
$w->moveField('w1', sfWidgetFormSchema::BEFORE, 'w3');
$t->is($w->getPositions(), array('w2', 'w1', 'w3', 'w4'), '->moveField() can move a field before another one');
$w->moveField('w1', sfWidgetFormSchema::LAST);
$t->is($w->getPositions(), array('w2', 'w3', 'w4', 'w1'), '->moveField() can move a field to the end');
$w->moveField('w1', sfWidgetFormSchema::FIRST);
$t->is($w->getPositions(), array('w1', 'w2', 'w3', 'w4'), '->moveField() can move a field to the beginning');
$w->moveField('w1', sfWidgetFormSchema::AFTER, 'w3');
$t->is($w->getPositions(), array('w2', 'w3', 'w1', 'w4'), '->moveField() can move a field before another one');
try
{
$w->moveField('w1', sfWidgetFormSchema::AFTER);
$t->fail('->moveField() throws an LogicException if you don\'t pass a relative field name with AFTER');
}
catch (LogicException $e)
{
$t->pass('->moveField() throws an LogicException if you don\'t pass a relative field name with AFTER');
}
try
{
$w->moveField('w1', sfWidgetFormSchema::BEFORE);
$t->fail('->moveField() throws an LogicException if you don\'t pass a relative field name with BEFORE');
}
catch (LogicException $e)
{
$t->pass('->moveField() throws an LogicException if you don\'t pass a relative field name with BEFORE');
}
// this case is especially interesting because the numeric array keys are always
// converted to integers by array
// furthermore, (int)0 == (string)'w1' succeeds
$w = new sfWidgetFormSchema(array('w1' => $w1, '0' => $w2));
$w->moveField(0, sfWidgetFormSchema::FIRST);
$t->is($w->getPositions(), array('0', 'w1'), '->moveField() compares field names as strings');
$w = new sfWidgetFormSchema(array('w1' => $w1, '0' => $w2));
$w->moveField('0', sfWidgetFormSchema::FIRST);
$t->is($w->getPositions(), array('0', 'w1'), '->moveField() compares field names as strings');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2, '0' => $w1));
$w->moveField('w1', sfWidgetFormSchema::BEFORE, '0');
$t->is($w->getPositions(), array('w2', 'w1', '0'), '->moveField() compares field names as strings');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2, '0' => $w1));
$w->moveField('w1', sfWidgetFormSchema::BEFORE, 0);
$t->is($w->getPositions(), array('w2', 'w1', '0'), '->moveField() compares field names as strings');
// ->getGlobalErrors()
$t->diag('->getGlobalErrors()');
$w = new sfWidgetFormSchema();
$w['w1'] = $w1;
$w['w2'] = new sfWidgetFormInputHidden();
$w['w3'] = new sfWidgetFormSchema();
$w['w3']['w1'] = $w1;
$w['w3']['w2'] = new sfWidgetFormInputHidden();
$errors = array(
'global error',
'w1' => 'error for w1',
'w2' => 'error for w2',
'w4' => array(
'w1' => 'error for w4/w1',
'w2' => 'error for w4/w2',
'w3' => 'error for w4/w3',
),
'w4' => 'error for w4',
);
$t->is($w->getGlobalErrors($errors), array('global error', 'error for w4', 'W2' => 'error for w2'), '->getGlobalErrors() returns an array of global errors, errors for hidden fields, and errors for non existent fields');
// ->render()
$t->diag('->render()');
$w = new sfWidgetFormSchema();
try
{
$w->render(null, 'string');
$t->fail('->render() throws an InvalidArgumentException if the second argument is not an array');
}
catch (InvalidArgumentException $e)
{
$t->pass('->render() throws an InvalidArgumentException if the second argument is not an array');
}
$w['first_name'] = $w1;
$w['last_name'] = $w2;
$w['id'] = new sfWidgetFormInputHidden();
$w->setAttribute('style', 'padding: 5px');
$w->setNameFormat('article[%s]');
$w->setIdFormat('id_%s');
$expected = <<
Global error message
Id: Required
Too short
EOF;
$rendered = $w->render(null, array('first_name' => 'Fabien', 'last_name' => 'Potencier'), array('first_name' => array('class' => 'foo'), 'last_name' => array('class' => 'bar')), array('first_name' => 'Too short', 'Global error message', 'id' => 'Required'));
$t->is($rendered, fix_linebreaks($expected), '->render() renders a schema to HTML');
$t->diag('Widget schema with only hidden fields');
$w = new sfWidgetFormSchema(array('w1' => new sfWidgetFormInputHidden()));
$t->is($w->render(null), '', '->render() is able to render widget schema that only contains hidden fields');
$t->diag('Widget schema with an embed form as the last field and hidden fields');
$w = new sfWidgetFormSchema();
$w['w1'] = new sfWidgetFormInputHidden();
$ew = new sfWidgetFormSchema(array('w3' => new sfWidgetFormInputText()));
$w['w4'] = new sfWidgetFormSchemaDecorator($ew, $w->getFormFormatter()->getDecoratorFormat());
$expected = <<
W4
EOF;
$t->is(str_replace("\n", '', preg_replace('/^ +/m', '', $w->render(null))), str_replace("\n", '', preg_replace('/^ +/m', '', fix_linebreaks($expected))), '->render() is able to render widget schema that only contains hidden fields when the last field is a form');
// __clone()
$t->diag('__clone()');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2));
$w1->setParent($w); $w2->setParent($w);
$format1 = new sfWidgetFormSchemaFormatterList($w);
$format1->setTranslationCatalogue('english');
$w->addFormFormatter('testFormatter', $format1);
$w1 = clone $w;
$f1 = $w1->getFields();
$f = $w->getFields();
$t->is(array_keys($f1), array_keys($f), '__clone() clones embedded widgets');
foreach ($f1 as $name => $widget)
{
$t->ok($widget !== $f[$name], '__clone() clones embedded widgets');
$t->ok($widget->getParent() === $w1, 'The parents hafe been changed');
// avoid recursive dependencies at comparing
$widget->setParent(null); $f[$name]->setParent(null);
$t->ok($widget == $f[$name], '__clone() clones embedded widgets');
}
$format1->setTranslationCatalogue('french');
$formatters = $w1->getFormFormatters();
$t->is(count($formatters), 1 , '__clone() returns a sfWidgetFormSchema that has the Formatters attached');
$t->is($formatters['testFormatter']->getTranslationCatalogue(), 'english', '__clone() clones formatters, so that changes to the original one have no effect to the cloned formatter.');
$w = new sfWidgetFormSchema();
$w->addFormFormatter('table', new sfWidgetFormSchemaFormatterTable($w));
$w->addFormFormatter('list', new sfWidgetFormSchemaFormatterList($w));
$w1 = clone $w;
$f1 = $w1->getFormFormatters();
$f = $w->getFormFormatters();
$t->is(array_keys($f1), array_keys($f), '__clone() clones form formatters');
foreach ($f1 as $key => $formFormatter)
{
$t->ok($formFormatter !== $f[$key], '__clone() clones form formatters');
$t->is(get_class($formFormatter), get_class($f[$key]), '__clone() clones form formatters');
$t->ok($formFormatter->getWidgetSchema() !== $f[$key]->getWidgetSchema(), '__clone() clones form formatters');
$t->is(get_class($formFormatter->getWidgetSchema()), get_class($f[$key]->getWidgetSchema()), '__clone() clones form formatters');
}
// setDefaultFormFormatterName()
$t->diag('setDefaultFormFormatterName()');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2));
$t->isa_ok($w->getFormFormatter(), 'sfWidgetFormSchemaFormatterTable', 'setDefaultFormFormatterName() has the "sfWidgetFormSchemaFormatterTable" form formatter by default');
sfWidgetFormSchema::setDefaultFormFormatterName('list');
$w = new sfWidgetFormSchema(array('w1' => $w1, 'w2' => $w2));
$t->isa_ok($w->getFormFormatter(), 'sfWidgetFormSchemaFormatterList', 'setDefaultFormFormatterName() changes the default form formatter name correctly');
class MyWidget extends sfWidgetForm
{
protected function configure($options = array(), $attributes = array())
{
$this->addRequiredOption('name');
}
public function render($name, $value = null, $attributes = array(), $errors = array())
{
return null;
}
public function getJavaScripts()
{
return array('/path/to/a/'.$this->getOption('name').'.js', '/path/to/foo.js');
}
public function getStylesheets()
{
return array('/path/to/a/'.$this->getOption('name').'.css' => 'all', '/path/to/foo.css' => 'all');
}
}
// ->getJavaScripts() ->getStylesheets()
$t->diag('->getJavaScripts() ->getStylesheets()');
$w = new sfWidgetFormSchema(array(
'foo' => new MyWidget(array('name' => 'foo')),
'bar' => new MyWidget(array('name' => 'bar')),
));
$t->is($w->getJavaScripts(), array('/path/to/a/foo.js', '/path/to/foo.js', '/path/to/a/bar.js'), '->getJavaScripts() returns an array of stylesheets');
$t->is($w->getStylesheets(), array('/path/to/a/foo.css' => 'all', '/path/to/foo.css' => 'all', '/path/to/a/bar.css' => 'all'), '->getStylesheets() returns an array of JavaScripts');