From: nicolasconnault Date: Wed, 22 Jul 2009 04:21:13 +0000 (+0000) Subject: MDL-19840 Upgraded code of HTML-parsing assertions X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=6a92312848070a4cb9899450b08dbf653d17e8fa;p=moodle.git MDL-19840 Upgraded code of HTML-parsing assertions --- diff --git a/lib/simpletest/testsimpletestlib.php b/lib/simpletest/testsimpletestlib.php index 1f775e28b7..30408e7e45 100644 --- a/lib/simpletest/testsimpletestlib.php +++ b/lib/simpletest/testsimpletestlib.php @@ -45,7 +45,7 @@ class ContainsTagWithAttribute_test extends UnitTestCase { function test_other_attrs() { $expectation = new ContainsTagWithAttribute('span', 'class', 'error'); - $this->assertTrue($expectation->test('message')); + $this->assertTrue($expectation->test('message')); } function test_fails() { @@ -54,8 +54,21 @@ class ContainsTagWithAttribute_test extends UnitTestCase { } function test_link() { + $html = 'Click Here'; $expectation = new ContainsTagWithAttribute('a', 'href', 'http://www.test.com'); - $this->assertTrue($expectation->test('Click Here')); + $this->assertTrue($expectation->test($html)); + $this->assert(new ContainsTagWithContents('a', 'Click Here'), $html); + } + + function test_garbage() { + $expectation = new ContainsTagWithAttribute('a', 'href', '!#@*%@_-)(*#0-735\\fdf//fdfg235-0970}$@}{#:~'); + $this->assertTrue($expectation->test('Click Here')); + + } + + function test_inline_js() { + $html = 'Click here'; + $this->assert(new ContainsTagWithAttribute('a', 'href', 'http://otheraddress.com'), $html); } } diff --git a/lib/simpletestlib.php b/lib/simpletestlib.php index af83fb9b5e..adefa18bf9 100644 --- a/lib/simpletestlib.php +++ b/lib/simpletestlib.php @@ -195,8 +195,6 @@ class CheckSpecifiedFieldsExpectation extends SimpleExpectation { * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class ContainsTagWithAttribute extends SimpleExpectation { - const ATTRSREGEX = '(?:\s+\w+\s*=\s*["\'][^"\'>]*["\'])*'; - protected $tag; protected $attribute; protected $value; @@ -209,10 +207,17 @@ class ContainsTagWithAttribute extends SimpleExpectation { } function test($html) { - $regex = '/<' . preg_quote($this->tag, '/') . self::ATTRSREGEX . - '(?:\s+' . preg_quote($this->attribute, '/') . '\s*=\s*["\']' . preg_quote($this->value, '/') . '["\'])' . - self::ATTRSREGEX . '\s*>/'; - return preg_match($regex, $html); + $parser = new DOMDocument(); + $parser->validateOnParse = true; + $parser->loadHTML($html); + $list = $parser->getElementsByTagName($this->tag); + + foreach ($list as $node) { + if ($node->attributes->getNamedItem($this->attribute)->nodeValue == $this->value) { + return true; + } + } + return false; } function testMessage($html) { @@ -221,6 +226,65 @@ class ContainsTagWithAttribute extends SimpleExpectation { } } +/** + * An Expectation that looks to see whether some HMTL contains a tag with an array of attributes. + * All attributes must be present and their values must match the expected values. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class ContainsTagWithAttributes extends SimpleExpectation { + protected $tag; + protected $attributes = array(); + + function __construct($tag, $attributes, $message = '%s') { + $this->SimpleExpectation($message); + $this->tag = $tag; + $this->attributes = $attributes; + } + + function test($html) { + $parser = new DOMDocument(); + $parser->validateOnParse = true; + $parser->loadHTML($html); + $list = $parser->getElementsByTagName($this->tag); + + // Iterating through inputs + foreach ($list as $node) { + if (empty($node->attributes) || !is_a($node->attributes, 'DOMNamedNodeMap')) { + continue; + } + + $result = true; + + foreach ($this->attributes as $attribute => $expectedvalue) { + if (!$node->attributes->getNamedItem($attribute)) { + break 2; + } + + if ($node->attributes->getNamedItem($attribute)->value != $expectedvalue) { + $result = false; + } + } + + if ($result) { + return true; + } + + } + return false; + } + + function testMessage($html) { + $output = 'Content [' . $html . '] does not contain the tag [' . $this->tag . '] with attributes ['; + foreach ($this->attributes as $var => $val) { + $output .= "$var=\"$val\" "; + } + $output = rtrim($output); + $output .= ']'; + return $output; + } +} /** * An Expectation that looks to see whether some HMTL contains a tag with a certain text inside it. @@ -229,8 +293,6 @@ class ContainsTagWithAttribute extends SimpleExpectation { * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class ContainsTagWithContents extends SimpleExpectation { - const ATTRSREGEX = '(?:\s+\w+\s*=\s*["\'][^"\'>]*["\'])*'; - protected $tag; protected $content; @@ -241,9 +303,17 @@ class ContainsTagWithContents extends SimpleExpectation { } function test($html) { - $regex = '/<' . preg_quote($this->tag, '/') . self::ATTRSREGEX . '\s*>' . preg_quote($this->content, '/') . - '<\/' . preg_quote($this->tag, '/') . '>/'; - return preg_match($regex, $html); + $parser = new DOMDocument(); + $parser->loadHTML($html); + $list = $parser->getElementsByTagName($this->tag); + + foreach ($list as $node) { + if ($node->textContent == $this->content) { + return true; + } + } + + return false; } function testMessage($html) { @@ -252,6 +322,39 @@ class ContainsTagWithContents extends SimpleExpectation { } } +/** + * An Expectation that looks to see whether some HMTL contains an empty tag of a specific type. + * + * @copyright 2009 Nicolas Connault + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class ContainsEmptyTag extends SimpleExpectation { + protected $tag; + + function __construct($tag, $message = '%s') { + $this->SimpleExpectation($message); + $this->tag = $tag; + } + + function test($html) { + $parser = new DOMDocument(); + $parser->loadHTML($html); + $list = $parser->getElementsByTagName($this->tag); + + foreach ($list as $node) { + if (!$node->hasAttributes() && !$node->hasChildNodes()) { + return true; + } + } + + return false; + } + + function testMessage($html) { + return 'Content ['.$html.'] does not contain the empty tag ['.$this->tag.'].'; + } +} + /** * This class lets you write unit tests that access a separate set of test