minor #32329 [DomCrawler] [5.0] add type-hint whenever possible (Simperfit)

This PR was merged into the 5.0-dev branch.

Discussion
----------

[DomCrawler] [5.0] add type-hint whenever possible

| Q             | A
| ------------- | ---
| Branch?       | 5.0
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | Contribute to #32179   <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | none <!-- required for new features -->

<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.

Additionally (see https://symfony.com/roadmap):
 - Bug fixes must be submitted against the lowest maintained branch where they apply
   (lowest branches are regularly merged to upper ones so they get the fixes too).
 - Features and deprecations must be submitted against branch 4.4.
 - Legacy code removals go to the master branch.
-->

Add type hint to DomCrawler

Commits
-------

580b126a35 [DomCrawler] [5.0] add type-hint whenever possible
This commit is contained in:
Fabien Potencier 2019-07-08 08:46:22 +02:00
commit faf5e8bdf8
9 changed files with 52 additions and 135 deletions

View File

@ -136,7 +136,7 @@ abstract class AbstractUriElement
* *
* @return string * @return string
*/ */
protected function canonicalizePath($path) protected function canonicalizePath(string $path)
{ {
if ('' === $path || '/' === $path) { if ('' === $path || '/' === $path) {
return $path; return $path;

View File

@ -61,9 +61,7 @@ class Crawler implements \Countable, \IteratorAggregate
private $html5Parser; private $html5Parser;
/** /**
* @param mixed $node A Node to use as the base for the crawling * @param mixed $node A Node to use as the base for the crawling
* @param string $uri The current URI
* @param string $baseHref The base href value
*/ */
public function __construct($node = null, string $uri = null, string $baseHref = null) public function __construct($node = null, string $uri = null, string $baseHref = null)
{ {
@ -134,11 +132,8 @@ class Crawler implements \Countable, \IteratorAggregate
* If the charset is not set via the content type, it is assumed to be UTF-8, * If the charset is not set via the content type, it is assumed to be UTF-8,
* or ISO-8859-1 as a fallback, which is the default charset defined by the * or ISO-8859-1 as a fallback, which is the default charset defined by the
* HTTP 1.1 specification. * HTTP 1.1 specification.
*
* @param string $content A string to parse as HTML/XML
* @param string|null $type The content type of the string
*/ */
public function addContent($content, $type = null) public function addContent(string $content, string $type = null)
{ {
if (empty($type)) { if (empty($type)) {
$type = 0 === strpos($content, '<?xml') ? 'application/xml' : 'text/html'; $type = 0 === strpos($content, '<?xml') ? 'application/xml' : 'text/html';
@ -184,11 +179,8 @@ class Crawler implements \Countable, \IteratorAggregate
* internal errors via libxml_use_internal_errors(true) * internal errors via libxml_use_internal_errors(true)
* and then, get the errors via libxml_get_errors(). Be * and then, get the errors via libxml_get_errors(). Be
* sure to clear errors with libxml_clear_errors() afterward. * sure to clear errors with libxml_clear_errors() afterward.
*
* @param string $content The HTML content
* @param string $charset The charset
*/ */
public function addHtmlContent($content, $charset = 'UTF-8') public function addHtmlContent(string $content, string $charset = 'UTF-8')
{ {
// Use HTML5 parser if the content is HTML5 and the library is available // Use HTML5 parser if the content is HTML5 and the library is available
$dom = null !== $this->html5Parser && strspn($content, " \t\r\n") === stripos($content, '<!doctype html>') ? $this->parseHtml5($content, $charset) : $this->parseXhtml($content, $charset); $dom = null !== $this->html5Parser && strspn($content, " \t\r\n") === stripos($content, '<!doctype html>') ? $this->parseHtml5($content, $charset) : $this->parseXhtml($content, $charset);
@ -219,13 +211,11 @@ class Crawler implements \Countable, \IteratorAggregate
* and then, get the errors via libxml_get_errors(). Be * and then, get the errors via libxml_get_errors(). Be
* sure to clear errors with libxml_clear_errors() afterward. * sure to clear errors with libxml_clear_errors() afterward.
* *
* @param string $content The XML content * @param int $options Bitwise OR of the libxml option constants
* @param string $charset The charset * LIBXML_PARSEHUGE is dangerous, see
* @param int $options Bitwise OR of the libxml option constants * http://symfony.com/blog/security-release-symfony-2-0-17-released
* LIBXML_PARSEHUGE is dangerous, see
* http://symfony.com/blog/security-release-symfony-2-0-17-released
*/ */
public function addXmlContent($content, $charset = 'UTF-8', $options = LIBXML_NONET) public function addXmlContent(string $content, string $charset = 'UTF-8', int $options = LIBXML_NONET)
{ {
// remove the default namespace if it's the only namespace to make XPath expressions simpler // remove the default namespace if it's the only namespace to make XPath expressions simpler
if (!preg_match('/xmlns:/', $content)) { if (!preg_match('/xmlns:/', $content)) {
@ -318,11 +308,9 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Returns a node given its position in the node list. * Returns a node given its position in the node list.
* *
* @param int $position The position
*
* @return self * @return self
*/ */
public function eq($position) public function eq(int $position)
{ {
if (isset($this->nodes[$position])) { if (isset($this->nodes[$position])) {
return $this->createSubCrawler($this->nodes[$position]); return $this->createSubCrawler($this->nodes[$position]);
@ -360,12 +348,9 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Slices the list of nodes by $offset and $length. * Slices the list of nodes by $offset and $length.
* *
* @param int $offset
* @param int $length
*
* @return self * @return self
*/ */
public function slice($offset = 0, $length = null) public function slice(int $offset = 0, int $length = null)
{ {
return $this->createSubCrawler(\array_slice($this->nodes, $offset, $length)); return $this->createSubCrawler(\array_slice($this->nodes, $offset, $length));
} }
@ -487,8 +472,6 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Returns the children nodes of the current selection. * Returns the children nodes of the current selection.
* *
* @param string|null $selector An optional CSS selector to filter children
*
* @return self * @return self
* *
* @throws \InvalidArgumentException When current node is empty * @throws \InvalidArgumentException When current node is empty
@ -515,13 +498,11 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Returns the attribute value of the first node of the list. * Returns the attribute value of the first node of the list.
* *
* @param string $attribute The attribute name
*
* @return string|null The attribute value or null if the attribute does not exist * @return string|null The attribute value or null if the attribute does not exist
* *
* @throws \InvalidArgumentException When current node is empty * @throws \InvalidArgumentException When current node is empty
*/ */
public function attr($attribute) public function attr(string $attribute)
{ {
if (!$this->nodes) { if (!$this->nodes) {
throw new \InvalidArgumentException('The current node list is empty.'); throw new \InvalidArgumentException('The current node list is empty.');
@ -610,11 +591,9 @@ class Crawler implements \Countable, \IteratorAggregate
* Since an XPath expression might evaluate to either a simple type or a \DOMNodeList, * Since an XPath expression might evaluate to either a simple type or a \DOMNodeList,
* this method will return either an array of simple types or a new Crawler instance. * this method will return either an array of simple types or a new Crawler instance.
* *
* @param string $xpath An XPath expression
*
* @return array|Crawler An array of evaluation results or a new Crawler instance * @return array|Crawler An array of evaluation results or a new Crawler instance
*/ */
public function evaluate($xpath) public function evaluate(string $xpath)
{ {
if (null === $this->document) { if (null === $this->document) {
throw new \LogicException('Cannot evaluate the expression on an uninitialized crawler.'); throw new \LogicException('Cannot evaluate the expression on an uninitialized crawler.');
@ -643,13 +622,10 @@ class Crawler implements \Countable, \IteratorAggregate
* *
* $crawler->filter('h1 a')->extract(['_text', 'href']); * $crawler->filter('h1 a')->extract(['_text', 'href']);
* *
* @param array $attributes An array of attributes
*
* @return array An array of extracted values * @return array An array of extracted values
*/ */
public function extract($attributes) public function extract(array $attributes)
{ {
$attributes = (array) $attributes;
$count = \count($attributes); $count = \count($attributes);
$data = []; $data = [];
@ -679,11 +655,9 @@ class Crawler implements \Countable, \IteratorAggregate
* This means that a child selector "div" or "./div" will match only * This means that a child selector "div" or "./div" will match only
* the div elements of the current crawler, not their children. * the div elements of the current crawler, not their children.
* *
* @param string $xpath An XPath expression
*
* @return self * @return self
*/ */
public function filterXPath($xpath) public function filterXPath(string $xpath)
{ {
$xpath = $this->relativize($xpath); $xpath = $this->relativize($xpath);
@ -700,13 +674,11 @@ class Crawler implements \Countable, \IteratorAggregate
* *
* This method only works if you have installed the CssSelector Symfony Component. * This method only works if you have installed the CssSelector Symfony Component.
* *
* @param string $selector A CSS selector
*
* @return self * @return self
* *
* @throws \RuntimeException if the CssSelector Component is not available * @throws \RuntimeException if the CssSelector Component is not available
*/ */
public function filter($selector) public function filter(string $selector)
{ {
$converter = $this->createCssSelectorConverter(); $converter = $this->createCssSelectorConverter();
@ -717,11 +689,9 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Selects links by name or alt value for clickable images. * Selects links by name or alt value for clickable images.
* *
* @param string $value The link text
*
* @return self * @return self
*/ */
public function selectLink($value) public function selectLink(string $value)
{ {
return $this->filterRelativeXPath( return $this->filterRelativeXPath(
sprintf('descendant-or-self::a[contains(concat(\' \', normalize-space(string(.)), \' \'), %1$s) or ./img[contains(concat(\' \', normalize-space(string(@alt)), \' \'), %1$s)]]', static::xpathLiteral(' '.$value.' ')) sprintf('descendant-or-self::a[contains(concat(\' \', normalize-space(string(.)), \' \'), %1$s) or ./img[contains(concat(\' \', normalize-space(string(@alt)), \' \'), %1$s)]]', static::xpathLiteral(' '.$value.' '))
@ -731,11 +701,9 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Selects images by alt value. * Selects images by alt value.
* *
* @param string $value The image alt
*
* @return self A new instance of Crawler with the filtered list of nodes * @return self A new instance of Crawler with the filtered list of nodes
*/ */
public function selectImage($value) public function selectImage(string $value)
{ {
$xpath = sprintf('descendant-or-self::img[contains(normalize-space(string(@alt)), %s)]', static::xpathLiteral($value)); $xpath = sprintf('descendant-or-self::img[contains(normalize-space(string(@alt)), %s)]', static::xpathLiteral($value));
@ -745,11 +713,9 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Selects a button by name or alt value for images. * Selects a button by name or alt value for images.
* *
* @param string $value The button text
*
* @return self * @return self
*/ */
public function selectButton($value) public function selectButton(string $value)
{ {
return $this->filterRelativeXPath( return $this->filterRelativeXPath(
sprintf('descendant-or-self::input[((contains(%1$s, "submit") or contains(%1$s, "button")) and contains(concat(\' \', normalize-space(string(@value)), \' \'), %2$s)) or (contains(%1$s, "image") and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %2$s)) or @id=%3$s or @name=%3$s] | descendant-or-self::button[contains(concat(\' \', normalize-space(string(.)), \' \'), %2$s) or @id=%3$s or @name=%3$s]', 'translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")', static::xpathLiteral(' '.$value.' '), static::xpathLiteral($value)) sprintf('descendant-or-self::input[((contains(%1$s, "submit") or contains(%1$s, "button")) and contains(concat(\' \', normalize-space(string(@value)), \' \'), %2$s)) or (contains(%1$s, "image") and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %2$s)) or @id=%3$s or @name=%3$s] | descendant-or-self::button[contains(concat(\' \', normalize-space(string(.)), \' \'), %2$s) or @id=%3$s or @name=%3$s]', 'translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")', static::xpathLiteral(' '.$value.' '), static::xpathLiteral($value))
@ -759,13 +725,11 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Returns a Link object for the first node in the list. * Returns a Link object for the first node in the list.
* *
* @param string $method The method for the link (get by default)
*
* @return Link A Link instance * @return Link A Link instance
* *
* @throws \InvalidArgumentException If the current node list is empty or the selected node is not instance of DOMElement * @throws \InvalidArgumentException If the current node list is empty or the selected node is not instance of DOMElement
*/ */
public function link($method = 'get') public function link(string $method = 'get')
{ {
if (!$this->nodes) { if (!$this->nodes) {
throw new \InvalidArgumentException('The current node list is empty.'); throw new \InvalidArgumentException('The current node list is empty.');
@ -845,14 +809,11 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Returns a Form object for the first node in the list. * Returns a Form object for the first node in the list.
* *
* @param array $values An array of values for the form fields
* @param string $method The method for the form
*
* @return Form A Form instance * @return Form A Form instance
* *
* @throws \InvalidArgumentException If the current node list is empty or the selected node is not instance of DOMElement * @throws \InvalidArgumentException If the current node list is empty or the selected node is not instance of DOMElement
*/ */
public function form(array $values = null, $method = null) public function form(array $values = null, string $method = null)
{ {
if (!$this->nodes) { if (!$this->nodes) {
throw new \InvalidArgumentException('The current node list is empty.'); throw new \InvalidArgumentException('The current node list is empty.');
@ -875,19 +836,13 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* Overloads a default namespace prefix to be used with XPath and CSS expressions. * Overloads a default namespace prefix to be used with XPath and CSS expressions.
*
* @param string $prefix
*/ */
public function setDefaultNamespacePrefix($prefix) public function setDefaultNamespacePrefix(string $prefix)
{ {
$this->defaultNamespacePrefix = $prefix; $this->defaultNamespacePrefix = $prefix;
} }
/** public function registerNamespace(string $prefix, string $namespace)
* @param string $prefix
* @param string $namespace
*/
public function registerNamespace($prefix, $namespace)
{ {
$this->namespaces[$prefix] = $namespace; $this->namespaces[$prefix] = $namespace;
} }
@ -909,11 +864,9 @@ class Crawler implements \Countable, \IteratorAggregate
* //prints concat('a', "'", 'b"c') * //prints concat('a', "'", 'b"c')
* *
* *
* @param string $s String to be escaped
*
* @return string Converted string * @return string Converted string
*/ */
public static function xpathLiteral($s) public static function xpathLiteral(string $s)
{ {
if (false === strpos($s, "'")) { if (false === strpos($s, "'")) {
return sprintf("'%s'", $s); return sprintf("'%s'", $s);
@ -944,11 +897,9 @@ class Crawler implements \Countable, \IteratorAggregate
* *
* The XPath expression should already be processed to apply it in the context of each node. * The XPath expression should already be processed to apply it in the context of each node.
* *
* @param string $xpath
*
* @return self * @return self
*/ */
private function filterRelativeXPath($xpath) private function filterRelativeXPath(string $xpath)
{ {
$prefixes = $this->findNamespacePrefixes($xpath); $prefixes = $this->findNamespacePrefixes($xpath);
@ -1053,11 +1004,9 @@ class Crawler implements \Countable, \IteratorAggregate
} }
/** /**
* @param int $position
*
* @return \DOMElement|null * @return \DOMElement|null
*/ */
public function getNode($position) public function getNode(int $position)
{ {
if (isset($this->nodes[$position])) { if (isset($this->nodes[$position])) {
return $this->nodes[$position]; return $this->nodes[$position];
@ -1082,11 +1031,10 @@ class Crawler implements \Countable, \IteratorAggregate
/** /**
* @param \DOMElement $node * @param \DOMElement $node
* @param string $siblingDir
* *
* @return array * @return array
*/ */
protected function sibling($node, $siblingDir = 'nextSibling') protected function sibling($node, string $siblingDir = 'nextSibling')
{ {
$nodes = []; $nodes = [];

View File

@ -270,12 +270,9 @@ class ChoiceFormField extends FormField
/** /**
* Checks whether given value is in the existing options. * Checks whether given value is in the existing options.
* *
* @param string $optionValue
* @param array $options
*
* @return bool * @return bool
*/ */
public function containsOption($optionValue, $options) public function containsOption(string $optionValue, array $options)
{ {
if ($this->validationDisabled) { if ($this->validationDisabled) {
return true; return true;

View File

@ -25,7 +25,7 @@ class FileFormField extends FormField
* *
* @throws \InvalidArgumentException When error code doesn't exist * @throws \InvalidArgumentException When error code doesn't exist
*/ */
public function setErrorCode($error) public function setErrorCode(int $error)
{ {
$codes = [UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE, UPLOAD_ERR_EXTENSION]; $codes = [UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE, UPLOAD_ERR_EXTENSION];
if (!\in_array($error, $codes)) { if (!\in_array($error, $codes)) {
@ -37,20 +37,16 @@ class FileFormField extends FormField
/** /**
* Sets the value of the field. * Sets the value of the field.
*
* @param string $value The value of the field
*/ */
public function upload($value) public function upload(?string $value)
{ {
$this->setValue($value); $this->setValue($value);
} }
/** /**
* Sets the value of the field. * Sets the value of the field.
*
* @param string $value The value of the field
*/ */
public function setValue($value) public function setValue(?string $value)
{ {
if (null !== $value && is_readable($value)) { if (null !== $value && is_readable($value)) {
$error = UPLOAD_ERR_OK; $error = UPLOAD_ERR_OK;
@ -80,10 +76,8 @@ class FileFormField extends FormField
/** /**
* Sets path to the file as string for simulating HTTP request. * Sets path to the file as string for simulating HTTP request.
*
* @param string $path The path to the file
*/ */
public function setFilePath($path) public function setFilePath(string $path)
{ {
parent::setValue($path); parent::setValue($path);
} }

View File

@ -99,10 +99,8 @@ abstract class FormField
/** /**
* Sets the value of the field. * Sets the value of the field.
*
* @param string $value The value of the field
*/ */
public function setValue($value) public function setValue(?string $value)
{ {
$this->value = (string) $value; $this->value = (string) $value;
} }

View File

@ -263,21 +263,17 @@ class Form extends Link implements \ArrayAccess
/** /**
* Returns true if the named field exists. * Returns true if the named field exists.
* *
* @param string $name The field name
*
* @return bool true if the field exists, false otherwise * @return bool true if the field exists, false otherwise
*/ */
public function has($name) public function has(string $name)
{ {
return $this->fields->has($name); return $this->fields->has($name);
} }
/** /**
* Removes a field from the form. * Removes a field from the form.
*
* @param string $name The field name
*/ */
public function remove($name) public function remove(string $name)
{ {
$this->fields->remove($name); $this->fields->remove($name);
} }
@ -285,13 +281,11 @@ class Form extends Link implements \ArrayAccess
/** /**
* Gets a named field. * Gets a named field.
* *
* @param string $name The field name
*
* @return FormField The field instance * @return FormField The field instance
* *
* @throws \InvalidArgumentException When field is not present in this form * @throws \InvalidArgumentException When field is not present in this form
*/ */
public function get($name) public function get(string $name)
{ {
return $this->fields->get($name); return $this->fields->get($name);
} }

View File

@ -22,7 +22,7 @@ class FormFieldRegistry
{ {
private $fields = []; private $fields = [];
private $base; private $base = '';
/** /**
* Adds a field to the registry. * Adds a field to the registry.
@ -47,11 +47,9 @@ class FormFieldRegistry
} }
/** /**
* Removes a field and its children from the registry. * Removes a field based on the fully qualifed name and its children from the registry.
*
* @param string $name The fully qualified name of the base field
*/ */
public function remove($name) public function remove(string $name)
{ {
$segments = $this->getSegments($name); $segments = $this->getSegments($name);
$target = &$this->fields; $target = &$this->fields;
@ -66,15 +64,13 @@ class FormFieldRegistry
} }
/** /**
* Returns the value of the field and its children. * Returns the value of the field based on the fully qualifed name and its children.
*
* @param string $name The fully qualified name of the field
* *
* @return mixed The value of the field * @return mixed The value of the field
* *
* @throws \InvalidArgumentException if the field does not exist * @throws \InvalidArgumentException if the field does not exist
*/ */
public function &get($name) public function &get(string $name)
{ {
$segments = $this->getSegments($name); $segments = $this->getSegments($name);
$target = &$this->fields; $target = &$this->fields;
@ -90,13 +86,11 @@ class FormFieldRegistry
} }
/** /**
* Tests whether the form has the given field. * Tests whether the form has the given field based on the fully qualified name.
*
* @param string $name The fully qualified name of the field
* *
* @return bool Whether the form has the given field * @return bool Whether the form has the given field
*/ */
public function has($name) public function has(string $name)
{ {
try { try {
$this->get($name); $this->get($name);
@ -108,14 +102,13 @@ class FormFieldRegistry
} }
/** /**
* Set the value of a field and its children. * Set the value of a field based on the fully qualified name and its children.
* *
* @param string $name The fully qualified name of the field * @param mixed $value The value
* @param mixed $value The value
* *
* @throws \InvalidArgumentException if the field does not exist * @throws \InvalidArgumentException if the field does not exist
*/ */
public function set($name, $value) public function set(string $name, $value)
{ {
$target = &$this->get($name); $target = &$this->get($name);
if ((!\is_array($value) && $target instanceof Field\FormField) || $target instanceof Field\ChoiceFormField) { if ((!\is_array($value) && $target instanceof Field\FormField) || $target instanceof Field\ChoiceFormField) {
@ -146,12 +139,11 @@ class FormFieldRegistry
* This function is made private because it allows overriding the $base and * This function is made private because it allows overriding the $base and
* the $values properties without any type checking. * 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
* @param array $values The values of the fields
* *
* @return static * @return static
*/ */
private static function create($base, array $values) private static function create(string $base, array $values)
{ {
$registry = new static(); $registry = new static();
$registry->base = $base; $registry->base = $base;
@ -163,13 +155,9 @@ class FormFieldRegistry
/** /**
* Transforms a PHP array in a list of fully qualified name / value. * 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 [string] Fully qualified name => (mixed) value) * @return array The list of fields as [string] Fully qualified name => (mixed) value)
*/ */
private function walk(array $array, $base = '', array &$output = []) private function walk(array $array, string $base = '', array &$output = [])
{ {
foreach ($array as $k => $v) { foreach ($array as $k => $v) {
$path = empty($base) ? $k : sprintf('%s[%s]', $base, $k); $path = empty($base) ? $k : sprintf('%s[%s]', $base, $k);
@ -188,11 +176,9 @@ class FormFieldRegistry
* *
* getSegments('base[foo][3][]') = ['base', 'foo, '3', '']; * getSegments('base[foo][3][]') = ['base', 'foo, '3', ''];
* *
* @param string $name The name of the field
*
* @return string[] The list of segments * @return string[] The list of segments
*/ */
private function getSegments($name) private function getSegments(string $name)
{ {
if (preg_match('/^(?P<base>[^[]+)(?P<extra>(\[.*)|$)/', $name, $m)) { if (preg_match('/^(?P<base>[^[]+)(?P<extra>(\[.*)|$)/', $name, $m)) {
$segments = [$m['base']]; $segments = [$m['base']];

View File

@ -364,11 +364,11 @@ abstract class AbstractCrawlerTest extends TestCase
{ {
$crawler = $this->createTestCrawler()->filterXPath('//ul[1]/li'); $crawler = $this->createTestCrawler()->filterXPath('//ul[1]/li');
$this->assertEquals(['One', 'Two', 'Three'], $crawler->extract('_text'), '->extract() returns an array of extracted data from the node list'); $this->assertEquals(['One', 'Two', 'Three'], $crawler->extract(['_text']), '->extract() returns an array of extracted data from the node list');
$this->assertEquals([['One', 'first'], ['Two', ''], ['Three', '']], $crawler->extract(['_text', 'class']), '->extract() returns an array of extracted data from the node list'); $this->assertEquals([['One', 'first'], ['Two', ''], ['Three', '']], $crawler->extract(['_text', 'class']), '->extract() returns an array of extracted data from the node list');
$this->assertEquals([[], [], []], $crawler->extract([]), '->extract() returns empty arrays if the attribute list is empty'); $this->assertEquals([[], [], []], $crawler->extract([]), '->extract() returns empty arrays if the attribute list is empty');
$this->assertEquals([], $this->createTestCrawler()->filterXPath('//ol')->extract('_text'), '->extract() returns an empty array if the node list is empty'); $this->assertEquals([], $this->createTestCrawler()->filterXPath('//ol')->extract(['_text']), '->extract() returns an empty array if the node list is empty');
$this->assertEquals([['One', 'li'], ['Two', 'li'], ['Three', 'li']], $crawler->extract(['_text', '_name']), '->extract() returns an array of extracted data from the node list'); $this->assertEquals([['One', 'li'], ['Two', 'li'], ['Three', 'li']], $crawler->extract(['_text', '_name']), '->extract() returns an array of extracted data from the node list');
} }

View File

@ -96,7 +96,7 @@ class FileFormFieldTest extends FormFieldTestCase
$this->assertEquals(UPLOAD_ERR_FORM_SIZE, $value['error'], '->setErrorCode() sets the file input field error code'); $this->assertEquals(UPLOAD_ERR_FORM_SIZE, $value['error'], '->setErrorCode() sets the file input field error code');
try { try {
$field->setErrorCode('foobar'); $field->setErrorCode(12345);
$this->fail('->setErrorCode() throws a \InvalidArgumentException if the error code is not valid'); $this->fail('->setErrorCode() throws a \InvalidArgumentException if the error code is not valid');
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
$this->assertTrue(true, '->setErrorCode() throws a \InvalidArgumentException if the error code is not valid'); $this->assertTrue(true, '->setErrorCode() throws a \InvalidArgumentException if the error code is not valid');