MDL-25715 simpletestlib new expectations for testing renderer output.
authorTim Hunt <T.J.Hunt@open.ac.uk>
Thu, 16 Dec 2010 16:29:14 +0000 (16:29 +0000)
committerPetr Skoda <commits@skodak.org>
Mon, 20 Dec 2010 15:24:23 +0000 (16:24 +0100)
With unit tests.

lib/simpletest/testsimpletestlib.php
lib/simpletestlib.php

index c87d215..9f36c35 100644 (file)
@@ -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('
+                <select name="selectname">
+                    <option value="0">Choice1</option>
+                    <option value="1">Choice2</option>
+                </select>'));
+    }
+
+    function test_fails_if_no_select() {
+        $expectation = new ContainsSelectExpectation('selectname', array('Choice1', 'Choice2'));
+        $this->assertFalse($expectation->test('<span>should not match</span>'));
+    }
+
+    function test_select_with_missing_choices_fails() {
+        $expectation = new ContainsSelectExpectation('selectname', array('Choice1', 'Choice2'));
+        $this->assertFalse($expectation->test('
+                <select name="selectname">
+                    <option value="0">Choice1</option>
+                </select>'));
+    }
+
+    function test_select_with_extra_choices_fails() {
+        $expectation = new ContainsSelectExpectation('selectname', array('Choice1'));
+        $this->assertFalse($expectation->test('
+                <select name="selectname">
+                    <option value="0">Choice1</option>
+                    <option value="1">Choice2</option>
+                </select>'));
+    }
+
+    function test_select_with_wrong_order_choices_fails() {
+        $expectation = new ContainsSelectExpectation('selectname', array('Choice1'));
+        $this->assertFalse($expectation->test('
+                <select name="selectname">
+                    <option value="1">Choice2</option>
+                    <option value="0">Choice1</option>
+                </select>'));
+    }
+
+    function test_select_check_selected_pass() {
+        $expectation = new ContainsSelectExpectation('selectname',
+                array('key1' => 'Choice1', 'key2' => 'Choice2'), 'key2');
+        $this->assertTrue($expectation->test('
+                <select name="selectname">
+                    <option value="key1">Choice1</option>
+                    <option value="key2" selected="selected">Choice2</option>
+                </select>'));
+    }
+
+    function test_select_check_wrong_one_selected_fail() {
+        $expectation = new ContainsSelectExpectation('selectname',
+                array('key1' => 'Choice1', 'key2' => 'Choice2'), 'key2');
+        $this->assertFalse($expectation->test('
+                <select name="selectname">
+                    <option value="key1" selected="selected">Choice1</option>
+                    <option value="key2">Choice2</option>
+                </select>'));
+    }
+
+    function test_select_check_nothing_selected_fail() {
+        $expectation = new ContainsSelectExpectation('selectname',
+                array('key1' => 'Choice1', 'key2' => 'Choice2'), 'key2');
+        $this->assertFalse($expectation->test('
+                <select name="selectname">
+                    <option value="key1">Choice1</option>
+                    <option value="key2">Choice2</option>
+                </select>'));
+    }
+
+    function test_select_disabled_pass() {
+        $expectation = new ContainsSelectExpectation('selectname',
+                array('key1' => 'Choice1', 'key2' => 'Choice2'), null, false);
+        $this->assertTrue($expectation->test('
+                <select name="selectname" disabled="disabled">
+                    <option value="key1">Choice1</option>
+                    <option value="key2">Choice2</option>
+                </select>'));
+    }
+
+    function test_select_disabled_fail1() {
+        $expectation = new ContainsSelectExpectation('selectname',
+                array('key1' => 'Choice1', 'key2' => 'Choice2'), null, true);
+        $this->assertFalse($expectation->test('
+                <select name="selectname" disabled="disabled">
+                    <option value="key1">Choice1</option>
+                    <option value="key2">Choice2</option>
+                </select>'));
+    }
+
+    function test_select_disabled_fail2() {
+        $expectation = new ContainsSelectExpectation('selectname',
+                array('key1' => 'Choice1', 'key2' => 'Choice2'), null, false);
+        $this->assertFalse($expectation->test('
+                <select name="selectname">
+                    <option value="key1">Choice1</option>
+                    <option value="key2">Choice2</option>
+                </select>'));
+    }
+}
+
+
+/**
+ * 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
+<input id="qIhr6wWLTt3,1_omact_gen_14" name="qIhr6wWLTt3,1_omact_gen_14" onclick="if(this.hasSubmitted) { return false; } this.hasSubmitted=true; preSubmit(this.form); return true;" type="submit" value="Check" />
+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('<span class="0">message</span>'));
+    }
+
+    function test_zero_different_attr_ok() {
+        $expectation = new DoesNotContainTagWithAttributes('span', array('class' => 'shrub'));
+        $this->assertTrue($expectation->test('<span class="tree">message</span>'));
+    }
+
+    function test_blank_attr() {
+        $expectation = new DoesNotContainTagWithAttributes('span', array('class' => ''));
+        $this->assertFalse($expectation->test('<span class="">message</span>'));
+    }
+
+    function test_blank_attr_does_not_match_zero() {
+        $expectation = new ContainsTagWithAttributes('span', array('class' => ''));
+        $this->assertFalse($expectation->test('<span class="0">message</span>'));
+    }
+}
index 33a1975..7ae7766 100644 (file)
@@ -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 .
+                ' <select> with name ' . $this->name . ' and choices ' .
+                implode(', ', $this->choices);
+        if ($this->selected) {
+            $output .= ' with ' . $this->selected . ' selected).';
+        }
+
+        return $output;
+    }
+}
+
+/**
+ * The opposite of {@link ContainsTagWithAttributes}. The test passes only if
+ * the HTML does not contain a tag with the given attributes.
+ *
+ * @copyright 2010 The Open University
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class DoesNotContainTagWithAttributes extends ContainsTagWithAttributes {
+    function __construct($tag, $expectedvalues, $message = '%s') {
+        parent::__construct($tag, $expectedvalues, array(), $message);
+    }
+    function test($html) {
+        return !parent::test($html);
+    }
+    function customMessage($html) {
+        $output = 'Content [' . $html . '] ';
+
+        $output .= 'contains the tag [' . $this->tag . '] with attributes [';
+        foreach ($this->expectedvalues 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.
  *