Add tests for dynamic changes in msqrt/mroot
authorfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Jun 2014 08:10:43 +0000 (08:10 +0000)
committerfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 7 Jun 2014 08:10:43 +0000 (08:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=133557

Reviewed by Chris Fleizach.

This patch adds some tests to verify that a MathML msqrt/mroot element to which we applied dynamic additions and removals of children renders the same as its static equivalent and that no crashes happen.
Unfortunately, the existing code does not handle them very well so they are skipped until we do the refactoring of bug 119038.

* TestExpectations: skip the tests.
* mathml/roots-addChild-expected.html: Added.
* mathml/roots-addChild.html: Added.
* mathml/roots-removeChild-expected.html: Added.
* mathml/roots-removeChild.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@169671 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/mathml/roots-addChild-expected.html [new file with mode: 0644]
LayoutTests/mathml/roots-addChild.html [new file with mode: 0644]
LayoutTests/mathml/roots-removeChild-expected.html [new file with mode: 0644]
LayoutTests/mathml/roots-removeChild.html [new file with mode: 0644]

index dc2967b..82488b1 100644 (file)
@@ -1,3 +1,19 @@
+2014-06-07  Frédéric Wang  <fred.wang@free.fr>
+
+        Add tests for dynamic changes in msqrt/mroot
+        https://bugs.webkit.org/show_bug.cgi?id=133557
+
+        Reviewed by Chris Fleizach.
+
+        This patch adds some tests to verify that a MathML msqrt/mroot element to which we applied dynamic additions and removals of children renders the same as its static equivalent and that no crashes happen.
+        Unfortunately, the existing code does not handle them very well so they are skipped until we do the refactoring of bug 119038.
+
+        * TestExpectations: skip the tests.
+        * mathml/roots-addChild-expected.html: Added.
+        * mathml/roots-addChild.html: Added.
+        * mathml/roots-removeChild-expected.html: Added.
+        * mathml/roots-removeChild.html: Added.
+
 2014-06-06  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
 
         Scheme of content utils should be compared in an ASCII case-insensitive manner
index af054d3..153753b 100644 (file)
@@ -67,6 +67,11 @@ webkit.org/b/126166 [ Debug ] js/dfg-uint32array-overflow-values.html [ Skip ]
 
 webkit.org/b/127860 [ Debug ] js/function-apply-aliased.html [ Skip ]
 
+# These tests verify dynamic manipulation of the mroot and msqrt elements.
+# Unfortunately, the current MathML code does not handle them well.
+webkit.org/b/119038 mathml/roots-addChild.html [ Skip ]
+webkit.org/b/119038 mathml/roots-removeChild.html [ Skip ]
+
 # This test verifies that a mismatch reftest will fail as intended if both results are same. (introduced in r93187)
 fast/harness/sample-fail-mismatch-reftest.html [ WontFix ImageOnlyFailure ]
 
diff --git a/LayoutTests/mathml/roots-addChild-expected.html b/LayoutTests/mathml/roots-addChild-expected.html
new file mode 100644 (file)
index 0000000..5185b35
--- /dev/null
@@ -0,0 +1,90 @@
+<!doctype html>
+<html>
+  <head>
+    <title>MathML roots: adding children</title>
+
+    <style type="text/css">
+      div { border: 1px solid; margin: .5em; }
+    </style>
+  </head>
+
+  <body>
+
+    <!-- Test 1: insert in normal and reverse order. -->
+    <div id="test1">Test 1:
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn><mn>6</mn><mn>7</mn></mroot></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn><mn>6</mn><mn>7</mn></msqrt></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn><mn>6</mn><mn>7</mn></mroot></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn><mn>6</mn><mn>7</mn></msqrt></math>
+    </div>
+
+    <!-- Test 2: insert an <mn> element at the first position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test2">Test 2:
+      <math><msqrt><mn>1</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><mroot><mn>1</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+    </div>
+
+    <!-- Test 3: insert an <mn> element at the last position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test3">Test 3:
+      <math><msqrt><mn>1</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><mroot><mn>1</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+    </div>
+
+    <!-- Test 4: insert an <mn> element at the second position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test4">Test 4:
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn></msqrt></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn></mroot></math>
+    </div>
+
+    <!-- Test 5: insert an <mn> element at the penultimate position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test5">Test 5:
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn></msqrt></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn></mroot></math>
+    </div>
+
+    <!-- Test 6: insert an <mn> element at the third position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test6">Test 6:
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn></msqrt></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn></mroot></math>
+    </div>
+
+    <!-- Test 7: insert an <mn> element at the antipenultimate position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test7">Test 7:
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn></msqrt></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn><mn>5</mn></mroot></math>
+    </div>
+
+  </body>
+</html>
diff --git a/LayoutTests/mathml/roots-addChild.html b/LayoutTests/mathml/roots-addChild.html
new file mode 100644 (file)
index 0000000..a18d6c4
--- /dev/null
@@ -0,0 +1,200 @@
+<!doctype html>
+<html>
+  <head>
+    <title>MathML roots: adding children</title>
+
+    <!-- This test verifies insertion of children into an <mroot>/<msqrt> element using DOM operations. It should not crash and should render the same as the equivalent static page. -->
+
+    <style type="text/css">
+      div { border: 1px solid; margin: .5em; }
+    </style>
+    <script type="text/javascript">
+      var mathmlNS = "http://www.w3.org/1998/Math/MathML";
+
+      function newMn(n)
+      {
+        var t = document.createTextNode(n.toString());
+        var mn = document.createElementNS(mathmlNS, "mn");
+        mn.appendChild(t);
+        return mn;
+      }
+
+      function test1()
+      {
+        var test1content = document.getElementById("test1content");
+        var mroot = document.getElementById("test1").getElementsByTagNameNS(mathmlNS, "mroot");
+        var msqrt = document.getElementById("test1").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var i;
+
+        // We insert children in normal order.
+        for (i = 1; i <= 7; i++) {
+          mroot[0].appendChild(newMn(i));
+          msqrt[0].appendChild(newMn(i));
+        }
+
+        // We insert children in reverse order.
+        for (i = 7; i >= 1; i--) {
+          mroot[1].insertBefore(newMn(i), mroot[1].firstChild);
+          msqrt[1].insertBefore(newMn(i), msqrt[1].firstChild);
+        }
+      }
+
+      function test2()
+      {
+        var msqrt = document.getElementById("test2").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test2").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].insertBefore(newMn(1), msqrt[i].firstChild);
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].insertBefore(newMn(1), mroot[i].firstChild);
+      }
+
+      function test3()
+      {
+        var msqrt = document.getElementById("test3").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test3").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].appendChild(newMn(msqrt[i].childElementCount+1));
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].appendChild(newMn(mroot[i].childElementCount+1));
+      }
+
+      function test4()
+      {
+        var msqrt = document.getElementById("test4").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test4").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].insertBefore(newMn(2), msqrt[i].firstChild.nextSibling);
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].insertBefore(newMn(2), mroot[i].firstChild.nextSibling);
+      }
+
+      function test5()
+      {
+        var msqrt = document.getElementById("test5").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test5").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].insertBefore(newMn(msqrt[i].childElementCount), msqrt[i].lastChild);
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].insertBefore(newMn(mroot[i].childElementCount), mroot[i].lastChild);
+      }
+
+      function test6()
+      {
+        var msqrt = document.getElementById("test6").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test6").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].insertBefore(newMn(3), msqrt[i].firstChild.nextSibling.nextSibling);
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].insertBefore(newMn(3), mroot[i].firstChild.nextSibling.nextSibling);
+      }
+
+      function test7()
+      {
+        var msqrt = document.getElementById("test7").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test7").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].insertBefore(newMn(msqrt[i].childElementCount-1), msqrt[i].lastChild.previousSibling);
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].insertBefore(newMn(mroot[i].childElementCount-1), mroot[i].lastChild.previousSibling);
+      }
+
+      function run()
+      {
+        test1();
+        test2();
+        test3();
+        test4();
+        test5();
+        test6();
+        test7();
+      }
+    </script>
+  </head>
+
+  <body onload="run()">
+
+    <!-- Test 1: insert in normal and reverse order. -->
+    <div id="test1">Test 1:
+      <math><mroot></mroot></math>
+      <math><msqrt></msqrt></math>
+      <math><mroot></mroot></math>
+      <math><msqrt></msqrt></math>
+    </div>
+
+    <!-- Test 2: insert an <mn> element at the first position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test2">Test 2:
+      <math><msqrt></msqrt></math>
+      <math><msqrt><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><mroot></mroot></math>
+      <math><mroot><mn>2</mn></mroot></math>
+      <math><mroot><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+    </div>
+
+    <!-- Test 3: insert an <mn> element at the last position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test3">Test 3:
+      <math><msqrt></msqrt></math>
+      <math><msqrt><mn>1</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><mroot></mroot></math>
+      <math><mroot><mn>1</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+    </div>
+
+    <!-- Test 4: insert an <mn> element at the second position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test4">Test 4:
+      <math><msqrt><mn>1</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>3</mn><mn>4</mn><mn>5</mn></msqrt></math>
+      <math><mroot><mn>1</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>3</mn><mn>4</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>3</mn><mn>4</mn><mn>5</mn></mroot></math>
+    </div>
+
+    <!-- Test 5: insert an <mn> element at the penultimate position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test5">Test 5:
+      <math><msqrt><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>4</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>5</mn></msqrt></math>
+      <math><mroot><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>4</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>5</mn></mroot></math>
+    </div>
+
+    <!-- Test 6: insert an <mn> element at the third position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test6">Test 6:
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>4</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>4</mn><mn>5</mn></msqrt></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>4</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>4</mn><mn>5</mn></mroot></math>
+    </div>
+
+    <!-- Test 7: insert an <mn> element at the antipenultimate position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test7">Test 7:
+      <math><msqrt><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>4</mn><mn>5</mn></msqrt></math>
+      <math><mroot><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>3</mn><mn>4</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>4</mn><mn>5</mn></mroot></math>
+    </div>
+
+  </body>
+</html>
diff --git a/LayoutTests/mathml/roots-removeChild-expected.html b/LayoutTests/mathml/roots-removeChild-expected.html
new file mode 100644 (file)
index 0000000..ba0df5d
--- /dev/null
@@ -0,0 +1,60 @@
+<!doctype html>
+<html>
+  <head>
+    <title>MathML script elements: removing children</title>
+
+    <style type="text/css">
+      div { border: 1px solid; margin: .5em; }
+    </style>
+  </head>
+
+  <body>
+
+    <!-- Test 1: remove an element at the first position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test1">Test 1:
+      <math><msqrt></msqrt></math>
+      <math><msqrt><mn>1</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><mroot></mroot></math>
+      <math><mroot><mn>1</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+    </div>
+
+    <!-- Test 2: remove an <mn> element at the last position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test2">Test 2:
+      <math><msqrt><mn>1</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><mroot><mn>1</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+    </div>
+
+    <!-- Test 3: remove an element at the second position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test3">Test 3:
+      <math><msqrt><mn>1</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><mroot><mn>1</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+    </div>
+
+    <!-- Test 4: remove an element at the penultimate position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test4">Test 4:
+      <math><msqrt><mn>1</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><mroot><mn>1</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+    </div>
+
+  </body>
+</html>
diff --git a/LayoutTests/mathml/roots-removeChild.html b/LayoutTests/mathml/roots-removeChild.html
new file mode 100644 (file)
index 0000000..88f01f0
--- /dev/null
@@ -0,0 +1,125 @@
+<!doctype html>
+<html>
+  <head>
+    <title>MathML script elements: removing children</title>
+
+    <!-- This test verifies removal of children from an <mroot>/<msqrt> element using DOM operations. It should not crash and should render the same as the equivalent static page. -->
+
+    <style type="text/css">
+      div { border: 1px solid; margin: .5em; }
+    </style>
+    <script type="text/javascript">
+      var mathmlNS = "http://www.w3.org/1998/Math/MathML";
+
+      function newMn(n)
+      {
+        var t = document.createTextNode(n.toString());
+        var mn = document.createElementNS(mathmlNS, "mn");
+        mn.appendChild(t);
+        return mn;
+      }
+
+      function test1()
+      {
+        var msqrt = document.getElementById("test1").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test1").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].removeChild(msqrt[i].firstChild);
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].removeChild(mroot[i].firstChild);
+      }
+
+      function test2()
+      {
+        var msqrt = document.getElementById("test2").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test2").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].removeChild(msqrt[i].lastChild);
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].removeChild(mroot[i].lastChild);
+      }
+
+      function test3()
+      {
+        var msqrt = document.getElementById("test3").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test3").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].removeChild(msqrt[i].firstChild.nextSibling);
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].removeChild(mroot[i].firstChild.nextSibling);
+      }
+
+      function test4()
+      {
+        var msqrt = document.getElementById("test4").getElementsByTagNameNS(mathmlNS, "msqrt");
+        var mroot = document.getElementById("test4").getElementsByTagNameNS(mathmlNS, "mroot");
+        var i;
+        for (i = 0; i < msqrt.length; i++)
+          msqrt[i].removeChild(msqrt[i].lastChild.previousSibling);
+        for (i = 0; i < mroot.length; i++)
+          mroot[i].removeChild(mroot[i].lastChild.previousSibling);
+      }
+
+      function run()
+      {
+        test1();
+        test2();
+        test3();
+        test4();
+      }
+    </script>
+  </head>
+
+  <body onload="run()">
+
+    <!-- Test 1: remove an element at the first position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test1">Test 1:
+      <math><msqrt><mi>X</mi></msqrt></math>
+      <math><msqrt><mi>X</mi><mn>1</mn></msqrt></math>
+      <math><msqrt><mi>X</mi><mn>1</mn><mn>2</mn></msqrt></math>
+      <math><msqrt><mi>X</mi><mn>1</mn><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><mroot><mi>X</mi></mroot></math>
+      <math><mroot><mi>X</mi><mn>1</mn></mroot></math>
+      <math><mroot><mi>X</mi><mn>1</mn><mn>2</mn></mroot></math>
+      <math><mroot><mi>X</mi><mn>1</mn><mn>2</mn><mn>3</mn></mroot></math>
+    </div>
+
+    <!-- Test 2: remove an <mn> element at the last position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test2">Test 2:
+      <math><msqrt><mn>1</mn><mi>X</mi></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mi>X</mi></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mi>X</mi></msqrt></math>
+      <math><mroot><mn>1</mn><mi>X</mi></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mi>X</mi></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mi>X</mi></mroot></math>
+    </div>
+
+    <!-- Test 3: remove an element at the second position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test3">Test 3:
+      <math><msqrt><mn>1</mn><mi>X</mi></msqrt></math>
+      <math><msqrt><mn>1</mn><mi>X</mi><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mi>X</mi><mn>2</mn><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mi>X</mi><mn>2</mn><mn>3</mn><mn>4</mn></msqrt></math>
+      <math><mroot><mn>1</mn><mi>X</mi></mroot></math>
+      <math><mroot><mn>1</mn><mi>X</mi><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mi>X</mi><mn>2</mn><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mi>X</mi><mn>2</mn><mn>3</mn><mn>4</mn></mroot></math>
+    </div>
+
+    <!-- Test 4: remove an element at the penultimate position in an <mroot>/<msqrt> element with various number of children. -->
+    <div id="test4">Test 4:
+      <math><msqrt><mi>X</mi><mn>1</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mi>X</mi><mn>2</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mi>X</mi><mn>3</mn></msqrt></math>
+      <math><msqrt><mn>1</mn><mn>2</mn><mn>3</mn><mi>X</mi><mn>4</mn></msqrt></math>
+      <math><mroot><mi>X</mi><mn>1</mn></mroot></math>
+      <math><mroot><mn>1</mn><mi>X</mi><mn>2</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mi>X</mi><mn>3</mn></mroot></math>
+      <math><mroot><mn>1</mn><mn>2</mn><mn>3</mn><mi>X</mi><mn>4</mn></mroot></math>
+    </div>
+
+  </body>
+</html>