This commit is contained in:
parent
fbbea2f369
commit
43e0db5f75
@ -139,6 +139,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
|
||||
|
||||
### DomCrawler
|
||||
|
||||
* refactor the Form class internals to support multi-dimensional fields (the public API is backward compatible)
|
||||
* added a way to get parsing errors for Crawler::addHtmlContent() and Crawler::addXmlContent() via libxml functions
|
||||
* added support for submitting a form without a submit button
|
||||
|
||||
@ -212,7 +213,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
|
||||
### Serializer
|
||||
|
||||
* [BC BREAK] changed `GetSetMethodNormalizer`'s key names from all lowercased to camelCased (e.g. `mypropertyvalue` to `myPropertyValue`)
|
||||
* [BC BREAK] convert the `item` XML tag to an array
|
||||
* [BC BREAK] convert the `item` XML tag to an array
|
||||
|
||||
``` xml
|
||||
<?xml version="1.0"?>
|
||||
|
@ -63,7 +63,7 @@ class Form extends Link implements \ArrayAccess
|
||||
public function setValues(array $values)
|
||||
{
|
||||
foreach ($values as $name => $value) {
|
||||
$this[$name] = $value;
|
||||
$this->fields->set($name, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@ -81,7 +81,7 @@ class Form extends Link implements \ArrayAccess
|
||||
public function getValues()
|
||||
{
|
||||
$values = array();
|
||||
foreach ($this->fields as $name => $field) {
|
||||
foreach ($this->fields->all() as $name => $field) {
|
||||
if ($field->isDisabled()) {
|
||||
continue;
|
||||
}
|
||||
@ -108,7 +108,8 @@ class Form extends Link implements \ArrayAccess
|
||||
}
|
||||
|
||||
$files = array();
|
||||
foreach ($this->fields as $name => $field) {
|
||||
|
||||
foreach ($this->fields->all() as $name => $field) {
|
||||
if ($field->isDisabled()) {
|
||||
continue;
|
||||
}
|
||||
@ -124,7 +125,7 @@ class Form extends Link implements \ArrayAccess
|
||||
/**
|
||||
* Gets the field values as PHP.
|
||||
*
|
||||
* This method converts fields with th array notation
|
||||
* This method converts fields with the array notation
|
||||
* (like foo[bar] to arrays) like PHP does.
|
||||
*
|
||||
* @return array An array of field values.
|
||||
@ -142,7 +143,7 @@ class Form extends Link implements \ArrayAccess
|
||||
/**
|
||||
* Gets the file field values as PHP.
|
||||
*
|
||||
* This method converts fields with th array notation
|
||||
* This method converts fields with the array notation
|
||||
* (like foo[bar] to arrays) like PHP does.
|
||||
*
|
||||
* @return array An array of field values.
|
||||
@ -214,7 +215,7 @@ class Form extends Link implements \ArrayAccess
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return isset($this->fields[$name]);
|
||||
return $this->fields->has($name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -222,11 +223,13 @@ class Form extends Link implements \ArrayAccess
|
||||
*
|
||||
* @param string $name The field name
|
||||
*
|
||||
* @throws \InvalidArgumentException when the name is malformed
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function remove($name)
|
||||
{
|
||||
unset($this->fields[$name]);
|
||||
$this->fields->remove($name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,25 +245,21 @@ class Form extends Link implements \ArrayAccess
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new \InvalidArgumentException(sprintf('The form has no "%s" field', $name));
|
||||
}
|
||||
|
||||
return $this->fields[$name];
|
||||
return $this->fields->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a named field.
|
||||
*
|
||||
* @param Field\FormField $field The field
|
||||
* @param FormField $field The field
|
||||
*
|
||||
* @return FormField The field instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function set(Field\FormField $field)
|
||||
public function set(FormField $field)
|
||||
{
|
||||
$this->fields[$field->getName()] = $field;
|
||||
$this->fields->add($field);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -272,12 +271,78 @@ class Form extends Link implements \ArrayAccess
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->fields;
|
||||
return $this->fields->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the named field exists.
|
||||
*
|
||||
* @param string $name The field name
|
||||
*
|
||||
* @return Boolean true if the field exists, false otherwise
|
||||
*/
|
||||
public function offsetExists($name)
|
||||
{
|
||||
return $this->has($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a field.
|
||||
*
|
||||
* @param string $name The field name
|
||||
*
|
||||
* @return FormField The associated Field instance
|
||||
*
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
public function offsetGet($name)
|
||||
{
|
||||
return $this->fields->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a field.
|
||||
*
|
||||
* @param string $name The field name
|
||||
* @param string|array $value The value of the field
|
||||
*
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
public function offsetSet($name, $value)
|
||||
{
|
||||
$this->fields->set($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a field from the form.
|
||||
*
|
||||
* @param string $name The field name
|
||||
*/
|
||||
public function offsetUnset($name)
|
||||
{
|
||||
$this->fields->remove($name);
|
||||
}
|
||||
|
||||
protected function setNode(\DOMNode $node)
|
||||
{
|
||||
$this->button = $node;
|
||||
if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) {
|
||||
do {
|
||||
// use the ancestor form element
|
||||
if (null === $node = $node->parentNode) {
|
||||
throw new \LogicException('The selected node does not have a form ancestor.');
|
||||
}
|
||||
} while ('form' != $node->nodeName);
|
||||
} elseif('form' != $node->nodeName) {
|
||||
throw new \LogicException(sprintf('Unable to submit on a "%s" tag.', $node->nodeName));
|
||||
}
|
||||
|
||||
$this->node = $node;
|
||||
}
|
||||
|
||||
private function initialize()
|
||||
{
|
||||
$this->fields = array();
|
||||
$this->fields = new FormFieldRegistry();
|
||||
|
||||
$document = new \DOMDocument('1.0', 'UTF-8');
|
||||
$node = $document->importNode($this->node, true);
|
||||
@ -313,78 +378,202 @@ class Form extends Link implements \ArrayAccess
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the named field exists.
|
||||
*
|
||||
* @param string $name The field name
|
||||
*
|
||||
* @return Boolean true if the field exists, false otherwise
|
||||
*/
|
||||
public function offsetExists($name)
|
||||
{
|
||||
return $this->has($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a field.
|
||||
*
|
||||
* @param string $name The field name
|
||||
*
|
||||
* @return FormField The associated Field instance
|
||||
*
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
public function offsetGet($name)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new \InvalidArgumentException(sprintf('The form field "%s" does not exist', $name));
|
||||
}
|
||||
|
||||
return $this->fields[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a field.
|
||||
*
|
||||
* @param string $name The field name
|
||||
* @param string|array $value The value of the field
|
||||
*
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
public function offsetSet($name, $value)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new \InvalidArgumentException(sprintf('The form field "%s" does not exist', $name));
|
||||
}
|
||||
|
||||
$this->fields[$name]->setValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a field from the form.
|
||||
*
|
||||
* @param string $name The field name
|
||||
*/
|
||||
public function offsetUnset($name)
|
||||
{
|
||||
$this->remove($name);
|
||||
}
|
||||
|
||||
protected function setNode(\DOMNode $node)
|
||||
{
|
||||
$this->button = $node;
|
||||
if ('button' == $node->nodeName || ('input' == $node->nodeName && in_array($node->getAttribute('type'), array('submit', 'button', 'image')))) {
|
||||
do {
|
||||
// use the ancestor form element
|
||||
if (null === $node = $node->parentNode) {
|
||||
throw new \LogicException('The selected node does not have a form ancestor.');
|
||||
}
|
||||
} while ('form' != $node->nodeName);
|
||||
} elseif('form' != $node->nodeName) {
|
||||
throw new \LogicException(sprintf('Unable to submit on a "%s" tag.', $node->nodeName));
|
||||
}
|
||||
|
||||
$this->node = $node;
|
||||
}
|
||||
}
|
||||
|
||||
class FormFieldRegistry
|
||||
{
|
||||
private $fields = array();
|
||||
|
||||
private $base;
|
||||
|
||||
/**
|
||||
* Adds a field to the registry.
|
||||
*
|
||||
* @param FormField $field The field
|
||||
*
|
||||
* @throws \InvalidArgumentException when the name is malformed
|
||||
*/
|
||||
public function add(FormField $field)
|
||||
{
|
||||
$segments = $this->getSegments($field->getName());
|
||||
|
||||
$target =& $this->fields;
|
||||
while ($segments) {
|
||||
if (!is_array($target)) {
|
||||
$target = array();
|
||||
}
|
||||
$path = array_shift($segments);
|
||||
if ('' === $path) {
|
||||
$target =& $target[];
|
||||
} else {
|
||||
$target =& $target[$path];
|
||||
}
|
||||
}
|
||||
$target = $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a field and its children from the registry.
|
||||
*
|
||||
* @param string $name The fully qualified name of the base field
|
||||
*
|
||||
* @throws \InvalidArgumentException when the name is malformed
|
||||
*/
|
||||
public function remove($name)
|
||||
{
|
||||
$segments = $this->getSegments($name);
|
||||
$target =& $this->fields;
|
||||
while (count($segments) > 1) {
|
||||
$path = array_shift($segments);
|
||||
if (!array_key_exists($path, $target)) {
|
||||
return;
|
||||
}
|
||||
$target =& $target[$path];
|
||||
}
|
||||
unset($target[array_shift($segments)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the field and its children.
|
||||
*
|
||||
* @param string $name The fully qualified name of the field
|
||||
*
|
||||
* @return mixed The value of the field
|
||||
*
|
||||
* @throws \InvalidArgumentException when the name is malformed
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
public function &get($name)
|
||||
{
|
||||
$segments = $this->getSegments($name);
|
||||
$target =& $this->fields;
|
||||
while ($segments) {
|
||||
$path = array_shift($segments);
|
||||
if (!array_key_exists($path, $target)) {
|
||||
throw new \InvalidArgumentException(sprintf('Unreachable field "%s"', $path));
|
||||
}
|
||||
$target =& $target[$path];
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the form has the given field.
|
||||
*
|
||||
* @param string $name The fully qualified name of the field
|
||||
*
|
||||
* @return Boolean Whether the form has the given field
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
try {
|
||||
$this->get($name);
|
||||
return true;
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a field and its children.
|
||||
*
|
||||
* @param string $name The fully qualified name of the field
|
||||
* @param mixed $value The value
|
||||
*
|
||||
* @throws \InvalidArgumentException when the name is malformed
|
||||
* @throws \InvalidArgumentException if the field does not exist
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
$target =& $this->get($name);
|
||||
if (is_array($value)) {
|
||||
$fields = self::create($name, $value);
|
||||
foreach ($fields->all() as $k => $v) {
|
||||
$this->set($k, $v);
|
||||
}
|
||||
} else {
|
||||
$target->setValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of field with their value.
|
||||
*
|
||||
* @return array The list of fields as array((string) Fully qualified name => (mixed) value)
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->walk($this->fields, $this->base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of the class.
|
||||
*
|
||||
* This function is made private because it allows overriding the $base and
|
||||
* the $values properties without any type checking.
|
||||
*
|
||||
* @param string $base The fully qualified name of the base field
|
||||
* @param array $values The values of the fields
|
||||
*
|
||||
* @return FormFieldRegistry
|
||||
*/
|
||||
static private function create($base, array $values)
|
||||
{
|
||||
$registry = new static();
|
||||
$registry->base = $base;
|
||||
$registry->fields = $values;
|
||||
|
||||
return $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a PHP array in a list of fully qualified name / value.
|
||||
*
|
||||
* @param array $array The PHP array
|
||||
* @param string $base The name of the base field
|
||||
* @param array $output The initial values
|
||||
*
|
||||
* @return array The list of fields as array((string) Fully qualified name => (mixed) value)
|
||||
*/
|
||||
private function walk(array $array, $base = '', array &$output = array())
|
||||
{
|
||||
foreach ($array as $k => $v) {
|
||||
$path = empty($base) ? $k : sprintf("%s[%s]", $base, $k);
|
||||
if (is_array($v)) {
|
||||
$this->walk($v, $path, $output);
|
||||
} else {
|
||||
$output[$path] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a field name into segments as a web browser would do.
|
||||
*
|
||||
* <code>
|
||||
* getSegments('base[foo][3][]') = array('base', 'foo, '3', '');
|
||||
* </code>
|
||||
*
|
||||
* @param string $name The name of the field
|
||||
*
|
||||
* @return array The list of segments
|
||||
*
|
||||
* @throws \InvalidArgumentException when the name is malformed
|
||||
*/
|
||||
private function getSegments($name)
|
||||
{
|
||||
if (preg_match('/^(?P<base>[^[]+)(?P<extra>(\[.*)|$)/', $name, $m)) {
|
||||
$segments = array($m['base']);
|
||||
while (preg_match('/^\[(?P<segment>.*?)\](?P<extra>.*)$/', $m['extra'], $m)) {
|
||||
$segments[] = $m['segment'];
|
||||
}
|
||||
|
||||
return $segments;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('Malformed field path "%s"', $name));
|
||||
}
|
||||
}
|
@ -12,9 +12,17 @@
|
||||
namespace Symfony\Tests\Component\DomCrawler;
|
||||
|
||||
use Symfony\Component\DomCrawler\Form;
|
||||
use Symfony\Component\DomCrawler\FormFieldRegistry;
|
||||
use Symfony\Component\DomCrawler\Field;
|
||||
|
||||
class FormTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
// Ensure that the private helper class FormFieldRegistry is loaded
|
||||
class_exists('Symfony\\Component\\DomCrawler\\Form');
|
||||
}
|
||||
|
||||
public function testConstructorThrowsExceptionIfTheNodeHasNoFormAncestor()
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
@ -48,19 +56,64 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
try {
|
||||
$form = new Form($nodes->item(0), 'http://example.com');
|
||||
$this->fail('__construct() throws a \\LogicException if the input type is not submit, button, or image');
|
||||
$this->fail('__construct() throws a \\LogicException if the node has no form ancestor');
|
||||
} catch (\LogicException $e) {
|
||||
$this->assertTrue(true, '__construct() throws a \\LogicException if the input type is not submit, button, or image');
|
||||
$this->assertTrue(true, '__construct() throws a \\LogicException if the node has no form ancestor');
|
||||
}
|
||||
}
|
||||
|
||||
public function testMultiValuedFields()
|
||||
{
|
||||
$form = $this->createForm('<form>
|
||||
<input type="text" name="foo[4]" value="foo" disabled="disabled" />
|
||||
<input type="text" name="foo" value="foo" disabled="disabled" />
|
||||
<input type="text" name="foo[2]" value="foo" disabled="disabled" />
|
||||
<input type="text" name="foo[]" value="foo" disabled="disabled" />
|
||||
<input type="text" name="bar[foo][]" value="foo" disabled="disabled" />
|
||||
<input type="text" name="bar[foo][foobar]" value="foo" disabled="disabled" />
|
||||
<input type="submit" />
|
||||
</form>
|
||||
');
|
||||
|
||||
$this->assertEquals(
|
||||
array_keys($form->all()),
|
||||
array('foo[2]', 'foo[3]', 'bar[foo][0]', 'bar[foo][foobar]')
|
||||
);
|
||||
|
||||
$this->assertEquals($form->get('foo[2]')->getValue(), 'foo');
|
||||
$this->assertEquals($form->get('foo[3]')->getValue(), 'foo');
|
||||
$this->assertEquals($form->get('bar[foo][0]')->getValue(), 'foo');
|
||||
$this->assertEquals($form->get('bar[foo][foobar]')->getValue(), 'foo');
|
||||
|
||||
$form['foo[2]'] = 'bar';
|
||||
$form['foo[3]'] = 'bar';
|
||||
|
||||
$this->assertEquals($form->get('foo[2]')->getValue(), 'bar');
|
||||
$this->assertEquals($form->get('foo[3]')->getValue(), 'bar');
|
||||
|
||||
$form['bar'] = array('foo' => array('0' => 'bar', 'foobar' => 'foobar'));
|
||||
|
||||
$this->assertEquals($form->get('bar[foo][0]')->getValue(), 'bar');
|
||||
$this->assertEquals($form->get('bar[foo][foobar]')->getValue(), 'foobar');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideInitializeValues
|
||||
*/
|
||||
public function testConstructor($message, $form, $values)
|
||||
{
|
||||
$form = $this->createForm('<form>'.$form.'</form>');
|
||||
$this->assertEquals($values, array_map(function ($field) { return array(get_class($field), $field->getValue()); }, $form->all()), '->getDefaultValues() '.$message);
|
||||
$this->assertEquals(
|
||||
$values,
|
||||
array_map(function ($field) {
|
||||
$class = get_class($field);
|
||||
return array(substr($class, strrpos($class, '\\') + 1), $field->getValue());
|
||||
},
|
||||
$form->all()
|
||||
),
|
||||
'->getDefaultValues() '.$message
|
||||
);
|
||||
}
|
||||
|
||||
public function provideInitializeValues()
|
||||
@ -76,55 +129,55 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
'takes into account disabled input fields',
|
||||
'<input type="text" name="foo" value="foo" disabled="disabled" />
|
||||
<input type="submit" />',
|
||||
array('foo' => array('Symfony\\Component\\DomCrawler\\Field\\InputFormField', 'foo')),
|
||||
array('foo' => array('InputFormField', 'foo')),
|
||||
),
|
||||
array(
|
||||
'appends the submitted button value',
|
||||
'<input type="submit" name="bar" value="bar" />',
|
||||
array('bar' => array('Symfony\\Component\\DomCrawler\\Field\\InputFormField', 'bar')),
|
||||
array('bar' => array('InputFormField', 'bar')),
|
||||
),
|
||||
array(
|
||||
'appends the submitted button value but not other submit buttons',
|
||||
'<input type="submit" name="bar" value="bar" />
|
||||
<input type="submit" name="foobar" value="foobar" />',
|
||||
array('foobar' => array('Symfony\\Component\\DomCrawler\\Field\\InputFormField', 'foobar')),
|
||||
array('foobar' => array('InputFormField', 'foobar')),
|
||||
),
|
||||
array(
|
||||
'returns textareas',
|
||||
'<textarea name="foo">foo</textarea>
|
||||
<input type="submit" />',
|
||||
array('foo' => array('Symfony\\Component\\DomCrawler\\Field\\TextareaFormField', 'foo')),
|
||||
array('foo' => array('TextareaFormField', 'foo')),
|
||||
),
|
||||
array(
|
||||
'returns inputs',
|
||||
'<input type="text" name="foo" value="foo" />
|
||||
<input type="submit" />',
|
||||
array('foo' => array('Symfony\\Component\\DomCrawler\\Field\\InputFormField', 'foo')),
|
||||
array('foo' => array('InputFormField', 'foo')),
|
||||
),
|
||||
array(
|
||||
'returns checkboxes',
|
||||
'<input type="checkbox" name="foo" value="foo" checked="checked" />
|
||||
<input type="submit" />',
|
||||
array('foo' => array('Symfony\\Component\\DomCrawler\\Field\\ChoiceFormField', 'foo')),
|
||||
array('foo' => array('ChoiceFormField', 'foo')),
|
||||
),
|
||||
array(
|
||||
'returns not-checked checkboxes',
|
||||
'<input type="checkbox" name="foo" value="foo" />
|
||||
<input type="submit" />',
|
||||
array('foo' => array('Symfony\\Component\\DomCrawler\\Field\\ChoiceFormField', false)),
|
||||
array('foo' => array('ChoiceFormField', false)),
|
||||
),
|
||||
array(
|
||||
'returns radio buttons',
|
||||
'<input type="radio" name="foo" value="foo" />
|
||||
<input type="radio" name="foo" value="bar" checked="bar" />
|
||||
<input type="submit" />',
|
||||
array('foo' => array('Symfony\\Component\\DomCrawler\\Field\\ChoiceFormField', 'bar')),
|
||||
array('foo' => array('ChoiceFormField', 'bar')),
|
||||
),
|
||||
array(
|
||||
'returns file inputs',
|
||||
'<input type="file" name="foo" />
|
||||
<input type="submit" />',
|
||||
array('foo' => array('Symfony\\Component\\DomCrawler\\Field\\FileFormField', array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => 4, 'size' => 0))),
|
||||
array('foo' => array('FileFormField', array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => 4, 'size' => 0))),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -248,6 +301,23 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('http://example.com'.$uri, $form->getUri(), '->getUri() '.$message);
|
||||
}
|
||||
|
||||
public function testGetBaseUri()
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
$dom->loadHTML('<form method="post" action="foo.php"><input type="text" name="bar" value="bar" /><input type="submit" /></form>');
|
||||
|
||||
$nodes = $dom->getElementsByTagName('input');
|
||||
$form = new Form($nodes->item($nodes->length - 1), 'http://www.foo.com/');
|
||||
$this->assertEquals('http://www.foo.com/foo.php', $form->getUri());
|
||||
}
|
||||
|
||||
public function testGetUriWithAnchor()
|
||||
{
|
||||
$form = $this->createForm('<form action="#foo"><input type="submit" /></form>', null, 'http://example.com/id/123');
|
||||
|
||||
$this->assertEquals('http://example.com/id/123#foo', $form->getUri());
|
||||
}
|
||||
|
||||
public function testGetUriActionAbsolute()
|
||||
{
|
||||
$formHtml='<form id="login_form" action="https://login.foo.com/login.php?login_attempt=1" method="POST"><input type="text" name="foo" value="foo" /><input type="submit" /></form>';
|
||||
@ -382,23 +452,6 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('Symfony\\Component\\DomCrawler\\Field\\InputFormField', get_class($fields['bar']), '->all() return an array of form field objects');
|
||||
}
|
||||
|
||||
public function testBase()
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
$dom->loadHTML('<form method="post" action="foo.php"><input type="text" name="bar" value="bar" /><input type="submit" /></form>');
|
||||
|
||||
$nodes = $dom->getElementsByTagName('input');
|
||||
$form = new Form($nodes->item($nodes->length - 1), 'http://www.foo.com/');
|
||||
$this->assertEquals('http://www.foo.com/foo.php', $form->getUri());
|
||||
}
|
||||
|
||||
public function testUriWithAnchor()
|
||||
{
|
||||
$form = $this->createForm('<form action="#foo"><input type="submit" /></form>', null, 'http://example.com/id/123');
|
||||
|
||||
$this->assertEquals('http://example.com/id/123#foo', $form->getUri());
|
||||
}
|
||||
|
||||
public function testSubmitWithoutAFormButton()
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
@ -415,6 +468,156 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame($nodes->item(0), $form->getFormNode(), '->getFormNode() returns the form node associated with this form');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testFormFieldRegistryAddThrowAnExceptionWhenTheNameIsMalformed()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->add($this->getFormFieldMock('[foo]'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testFormFieldRegistryRemoveThrowAnExceptionWhenTheNameIsMalformed()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->remove('[foo]');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testFormFieldRegistryGetThrowAnExceptionWhenTheNameIsMalformed()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->get('[foo]');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testFormFieldRegistryGetThrowAnExceptionWhenTheFieldDoesNotExist()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->get('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testFormFieldRegistrySetThrowAnExceptionWhenTheNameIsMalformed()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->set('[foo]', null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testFormFieldRegistrySetThrowAnExceptionWhenTheFieldDoesNotExist()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->set('foo', null);
|
||||
}
|
||||
|
||||
public function testFormFieldRegistryHasReturnsTrueWhenTheFQNExists()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->add($this->getFormFieldMock('foo[bar]'));
|
||||
|
||||
$this->assertTrue($registry->has('foo'));
|
||||
$this->assertTrue($registry->has('foo[bar]'));
|
||||
$this->assertFalse($registry->has('bar'));
|
||||
$this->assertFalse($registry->has('foo[foo]'));
|
||||
}
|
||||
|
||||
public function testFormRegistryFieldsCanBeRemoved()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->add($this->getFormFieldMock('foo'));
|
||||
$registry->remove('foo');
|
||||
$this->assertFalse($registry->has('foo'));
|
||||
}
|
||||
|
||||
public function testFormRegistrySupportsMultivaluedFields()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->add($this->getFormFieldMock('foo[]'));
|
||||
$registry->add($this->getFormFieldMock('foo[]'));
|
||||
$registry->add($this->getFormFieldMock('bar[5]'));
|
||||
$registry->add($this->getFormFieldMock('bar[]'));
|
||||
$registry->add($this->getFormFieldMock('bar[baz]'));
|
||||
|
||||
$this->assertEquals(
|
||||
array('foo[0]', 'foo[1]', 'bar[5]', 'bar[6]', 'bar[baz]'),
|
||||
array_keys($registry->all())
|
||||
);
|
||||
}
|
||||
|
||||
public function testFormRegistrySetValues()
|
||||
{
|
||||
$registry = new FormFieldRegistry();
|
||||
$registry->add($f2 = $this->getFormFieldMock('foo[2]'));
|
||||
$registry->add($f3 = $this->getFormFieldMock('foo[3]'));
|
||||
$registry->add($fbb = $this->getFormFieldMock('foo[bar][baz]'));
|
||||
|
||||
$f2
|
||||
->expects($this->exactly(2))
|
||||
->method('setValue')
|
||||
->with(2)
|
||||
;
|
||||
|
||||
$f3
|
||||
->expects($this->exactly(2))
|
||||
->method('setValue')
|
||||
->with(3)
|
||||
;
|
||||
|
||||
$fbb
|
||||
->expects($this->exactly(2))
|
||||
->method('setValue')
|
||||
->with('fbb')
|
||||
;
|
||||
|
||||
$registry->set('foo[2]', 2);
|
||||
$registry->set('foo[3]', 3);
|
||||
$registry->set('foo[bar][baz]', 'fbb');
|
||||
|
||||
$registry->set('foo', array(
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
'bar' => array(
|
||||
'baz' => 'fbb'
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
protected function getFormFieldMock($name, $value = null)
|
||||
{
|
||||
$field = $this
|
||||
->getMockBuilder('Symfony\\Component\\DomCrawler\\Field\\FormField')
|
||||
->setMethods(array('getName', 'getValue', 'setValue', 'initialize'))
|
||||
->disableOriginalConstructor()
|
||||
->getMock()
|
||||
;
|
||||
|
||||
$field
|
||||
->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue($name))
|
||||
;
|
||||
|
||||
$field
|
||||
->expects($this->any())
|
||||
->method('getValue')
|
||||
->will($this->returnValue($value))
|
||||
;
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
protected function createForm($form, $method = null, $currentUri = null)
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
|
Reference in New Issue
Block a user