From ccdd15962a13a9467febaa3c2b0b71c58b554201 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 16 Dec 2010 16:29:14 +0000 Subject: [PATCH] MDL-25715 simpletestlib new expectations for testing renderer output. With unit tests. --- lib/simpletest/testsimpletestlib.php | 145 +++++++++++++++++++++++++ lib/simpletestlib.php | 153 ++++++++++++++++++++++++++- 2 files changed, 295 insertions(+), 3 deletions(-) diff --git a/lib/simpletest/testsimpletestlib.php b/lib/simpletest/testsimpletestlib.php index c87d2155da2..9f36c35c9d8 100644 --- a/lib/simpletest/testsimpletestlib.php +++ b/lib/simpletest/testsimpletestlib.php @@ -176,3 +176,148 @@ class ContainsTagWithContents_test extends UnitTestCase { } +/** + * Unit tests for the {@link ContainsSelectExpectation} class. + * + * @copyright 2010 The Open University. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class ContainsSelectExpectation_test extends UnitTestCase { + function test_matching_select_passes() { + $expectation = new ContainsSelectExpectation('selectname', array('Choice1', 'Choice2')); + $this->assertTrue($expectation->test(' + ')); + } + + function test_fails_if_no_select() { + $expectation = new ContainsSelectExpectation('selectname', array('Choice1', 'Choice2')); + $this->assertFalse($expectation->test('should not match')); + } + + function test_select_with_missing_choices_fails() { + $expectation = new ContainsSelectExpectation('selectname', array('Choice1', 'Choice2')); + $this->assertFalse($expectation->test(' + ')); + } + + function test_select_with_extra_choices_fails() { + $expectation = new ContainsSelectExpectation('selectname', array('Choice1')); + $this->assertFalse($expectation->test(' + ')); + } + + function test_select_with_wrong_order_choices_fails() { + $expectation = new ContainsSelectExpectation('selectname', array('Choice1')); + $this->assertFalse($expectation->test(' + ')); + } + + function test_select_check_selected_pass() { + $expectation = new ContainsSelectExpectation('selectname', + array('key1' => 'Choice1', 'key2' => 'Choice2'), 'key2'); + $this->assertTrue($expectation->test(' + ')); + } + + function test_select_check_wrong_one_selected_fail() { + $expectation = new ContainsSelectExpectation('selectname', + array('key1' => 'Choice1', 'key2' => 'Choice2'), 'key2'); + $this->assertFalse($expectation->test(' + ')); + } + + function test_select_check_nothing_selected_fail() { + $expectation = new ContainsSelectExpectation('selectname', + array('key1' => 'Choice1', 'key2' => 'Choice2'), 'key2'); + $this->assertFalse($expectation->test(' + ')); + } + + function test_select_disabled_pass() { + $expectation = new ContainsSelectExpectation('selectname', + array('key1' => 'Choice1', 'key2' => 'Choice2'), null, false); + $this->assertTrue($expectation->test(' + ')); + } + + function test_select_disabled_fail1() { + $expectation = new ContainsSelectExpectation('selectname', + array('key1' => 'Choice1', 'key2' => 'Choice2'), null, true); + $this->assertFalse($expectation->test(' + ')); + } + + function test_select_disabled_fail2() { + $expectation = new ContainsSelectExpectation('selectname', + array('key1' => 'Choice1', 'key2' => 'Choice2'), null, false); + $this->assertFalse($expectation->test(' + ')); + } +} + + +/** + * Unit tests for the {@link DoesNotContainTagWithAttributes} class. + * + * @copyright 2010 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class DoesNotContainTagWithAttributes_test extends UnitTestCase { + function test_simple() { + $content = << +END; + $expectation = new DoesNotContainTagWithAttributes('input', + array('type' => 'submit', 'name' => 'qIhr6wWLTt3,1_omact_gen_14', 'value' => 'Check')); + $this->assertFalse($expectation->test($content)); + } + + function test_zero_attr() { + $expectation = new DoesNotContainTagWithAttributes('span', array('class' => 0)); + $this->assertFalse($expectation->test('message')); + } + + function test_zero_different_attr_ok() { + $expectation = new DoesNotContainTagWithAttributes('span', array('class' => 'shrub')); + $this->assertTrue($expectation->test('message')); + } + + function test_blank_attr() { + $expectation = new DoesNotContainTagWithAttributes('span', array('class' => '')); + $this->assertFalse($expectation->test('message')); + } + + function test_blank_attr_does_not_match_zero() { + $expectation = new ContainsTagWithAttributes('span', array('class' => '')); + $this->assertFalse($expectation->test('message')); + } +} diff --git a/lib/simpletestlib.php b/lib/simpletestlib.php index 33a1975d76f..7ae77669d6c 100644 --- a/lib/simpletestlib.php +++ b/lib/simpletestlib.php @@ -205,6 +205,18 @@ abstract class XMLStructureExpectation extends SimpleExpectation { libxml_use_internal_errors($prevsetting); return $parser; } + + function testMessage($html) { + $parsererrors = $this->load_xml($html); + if (is_array($parsererrors)) { + foreach ($parsererrors as $key => $message) { + $parsererrors[$key] = $message->message; + } + return 'Could not parse XML [' . $html . '] errors were [' . + implode('], [', $parsererrors) . ']'; + } + return $this->customMessage($html); + } } /** * An Expectation that looks to see whether some HMTL contains a tag with a certain attribute. @@ -226,6 +238,9 @@ class ContainsTagWithAttribute extends XMLStructureExpectation { function test($html) { $parser = $this->load_xml($html); + if (is_array($parser)) { + return false; + } $list = $parser->getElementsByTagName($this->tag); foreach ($list as $node) { @@ -236,7 +251,7 @@ class ContainsTagWithAttribute extends XMLStructureExpectation { return false; } - function testMessage($html) { + function customMessage($html) { return 'Content [' . $html . '] does not contain the tag [' . $this->tag . '] with attribute [' . $this->attribute . '="' . $this->value . '"].'; } @@ -277,8 +292,11 @@ class ContainsTagWithAttributes extends XMLStructureExpectation { function test($html) { $parser = $this->load_xml($html); - $list = $parser->getElementsByTagName($this->tag); + if (is_array($parser)) { + return false; + } + $list = $parser->getElementsByTagName($this->tag); $foundamatch = false; // Iterating through inputs @@ -319,7 +337,7 @@ class ContainsTagWithAttributes extends XMLStructureExpectation { return $foundamatch; } - function testMessage($html) { + function customMessage($html) { $output = 'Content [' . $html . '] '; if (preg_match('/forbiddenmatch:(.*):(.*)/', $this->failurereason, $matches)) { @@ -337,6 +355,135 @@ class ContainsTagWithAttributes extends XMLStructureExpectation { } } +/** + * 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. + * A third parameter can be used to specify attribute=>value pairs which must not be present in a positive match. + * + * @copyright 2010 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class ContainsSelectExpectation extends XMLStructureExpectation { + /** + * @var string $tag The name of the Tag to search + */ + protected $name; + /** + * @var array $expectedvalues An associative array of parameters, all of which must be matched + */ + protected $choices; + /** + * @var array $forbiddenvalues An associative array of parameters, none of which must be matched + */ + protected $selected; + /** + * @var string $failurereason The reason why the test failed: nomatch or forbiddenmatch + */ + protected $enabled; + + function __construct($name, $choices, $selected = null, $enabled = null, $message = '%s') { + parent::__construct($message); + $this->name = $name; + $this->choices = $choices; + $this->selected = $selected; + $this->enabled = $enabled; + } + + function test($html) { + $parser = $this->load_xml($html); + if (is_array($parser)) { + return false; + } + + $list = $parser->getElementsByTagName('select'); + + // Iterating through inputs + foreach ($list as $node) { + if (empty($node->attributes) || !is_a($node->attributes, 'DOMNamedNodeMap')) { + continue; + } + + if ($node->getAttribute('name') != $this->name) { + continue; + } + + if ($this->enabled === true && $node->getAttribute('disabled')) { + continue; + } else if ($this->enabled === false && $node->getAttribute('disabled') != 'disabled') { + continue; + } + + $options = $node->getElementsByTagName('option'); + reset($this->choices); + foreach ($options as $option) { + if ($option->getAttribute('value') != key($this->choices)) { + continue 2; + } + if ($option->firstChild->wholeText != current($this->choices)) { + continue 2; + } + if ($option->getAttribute('value') === $this->selected && + !$option->hasAttribute('selected')) { + continue 2; + } + next($this->choices); + } + if (current($this->choices) !== false) { + // The HTML did not contain all the choices. + return false; + } + return true; + } + return false; + } + + function customMessage($html) { + if ($this->enabled === true) { + $state = 'an enabled'; + } else if ($this->enabled === false) { + $state = 'a disabled'; + } else { + $state = 'a'; + } + $output = 'Content [' . $html . '] does not contain ' . $state . + '