Skip to content

Commit

Permalink
Add tests for ParentNode#replaceChildren (#22524)
Browse files Browse the repository at this point in the history
* Add tests for ParentNode#replaceChildren

* more thorough hierarchy validation

* remove trailing whitespaces

* Reformat

* Add mutation test

* remove dummy implementation

* add a comment about insert()
  • Loading branch information
saschanaz authored Apr 20, 2020
1 parent bc186b9 commit b4c5887
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 52 deletions.
29 changes: 4 additions & 25 deletions dom/nodes/Node-insertBefore.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
<script>
var insertFunc = Node.prototype.insertBefore;
</script>
<script src="pre-insertion-checks.js"></script>
<script src="pre-insertion-validation-notfound.js"></script>
<script src="pre-insertion-validation-hierarchy.js"></script>
<script>
preInsertionValidateHierarchy("insertBefore");

function testLeafNode(nodeName, createNodeFunction) {
test(function() {
var node = createNodeFunction();
Expand Down Expand Up @@ -71,30 +74,6 @@
var doc = document.implementation.createHTMLDocument("title");
doc.removeChild(doc.documentElement);

var df = doc.createDocumentFragment();
df.appendChild(doc.createElement("a"));
df.appendChild(doc.createElement("b"));
assert_throws_dom("HierarchyRequestError", function() {
doc.insertBefore(df, null);
});

df = doc.createDocumentFragment();
df.appendChild(doc.createTextNode("text"));
assert_throws_dom("HierarchyRequestError", function() {
doc.insertBefore(df, null);
});

df = doc.createDocumentFragment();
df.appendChild(doc.createComment("comment"));
df.appendChild(doc.createTextNode("text"));
assert_throws_dom("HierarchyRequestError", function() {
doc.insertBefore(df, null);
});
}, "If the context node is a document, appending a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
test(function() {
var doc = document.implementation.createHTMLDocument("title");
doc.removeChild(doc.documentElement);

var df = doc.createDocumentFragment();
df.appendChild(doc.createElement("a"));
df.appendChild(doc.createElement("b"));
Expand Down
2 changes: 1 addition & 1 deletion dom/nodes/Node-replaceChild.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<script>
var insertFunc = Node.prototype.replaceChild;
</script>
<script src="pre-insertion-checks.js"></script>
<script src="pre-insertion-validation-notfound.js"></script>
<script>
// IDL.
test(function() {
Expand Down
27 changes: 14 additions & 13 deletions dom/nodes/ParentNode-append.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,55 @@
<link rel=help href="https://dom.spec.whatwg.org/#dom-parentnode-append">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="pre-insertion-validation-hierarchy.js"></script>
<script>
preInsertionValidateHierarchy("append");

function test_append(node, nodeName) {

test(function() {
var parent = node.cloneNode();
const parent = node.cloneNode();
parent.append();
assert_array_equals(parent.childNodes, []);
}, nodeName + '.append() without any argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
const parent = node.cloneNode();
parent.append(null);
assert_equals(parent.childNodes[0].textContent, 'null');
}, nodeName + '.append() with null as an argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
const parent = node.cloneNode();
parent.append(undefined);
assert_equals(parent.childNodes[0].textContent, 'undefined');
}, nodeName + '.append() with undefined as an argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
const parent = node.cloneNode();
parent.append('text');
assert_equals(parent.childNodes[0].textContent, 'text');
}, nodeName + '.append() with only text as an argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
var x = document.createElement('x');
const parent = node.cloneNode();
const x = document.createElement('x');
parent.append(x);
assert_array_equals(parent.childNodes, [x]);
}, nodeName + '.append() with only one element as an argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
var child = document.createElement('test');
const parent = node.cloneNode();
const child = document.createElement('test');
parent.appendChild(child);
parent.append(null);
assert_equals(parent.childNodes[0], child);
assert_equals(parent.childNodes[1].textContent, 'null');
}, nodeName + '.append() with null as an argument, on a parent having a child.');

test(function() {
var parent = node.cloneNode();
var x = document.createElement('x');
var child = document.createElement('test');
const parent = node.cloneNode();
const x = document.createElement('x');
const child = document.createElement('test');
parent.appendChild(child);
parent.append(x, 'text');
assert_equals(parent.childNodes[0], child);
Expand All @@ -61,6 +62,6 @@
}

test_append(document.createElement('div'), 'Element');
test_append(document.createDocumentFragment(), 'DocumentFrgment');
test_append(document.createDocumentFragment(), 'DocumentFragment');
</script>
</html>
27 changes: 14 additions & 13 deletions dom/nodes/ParentNode-prepend.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,55 @@
<link rel=help href="https://dom.spec.whatwg.org/#dom-parentnode-prepend">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="pre-insertion-validation-hierarchy.js"></script>
<script>
preInsertionValidateHierarchy("prepend");

function test_prepend(node, nodeName) {

test(function() {
var parent = node.cloneNode();
const parent = node.cloneNode();
parent.prepend();
assert_array_equals(parent.childNodes, []);
}, nodeName + '.prepend() without any argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
const parent = node.cloneNode();
parent.prepend(null);
assert_equals(parent.childNodes[0].textContent, 'null');
}, nodeName + '.prepend() with null as an argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
const parent = node.cloneNode();
parent.prepend(undefined);
assert_equals(parent.childNodes[0].textContent, 'undefined');
}, nodeName + '.prepend() with undefined as an argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
const parent = node.cloneNode();
parent.prepend('text');
assert_equals(parent.childNodes[0].textContent, 'text');
}, nodeName + '.prepend() with only text as an argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
var x = document.createElement('x');
const parent = node.cloneNode();
const x = document.createElement('x');
parent.prepend(x);
assert_array_equals(parent.childNodes, [x]);
}, nodeName + '.prepend() with only one element as an argument, on a parent having no child.');

test(function() {
var parent = node.cloneNode();
var child = document.createElement('test');
const parent = node.cloneNode();
const child = document.createElement('test');
parent.appendChild(child);
parent.prepend(null);
assert_equals(parent.childNodes[0].textContent, 'null');
assert_equals(parent.childNodes[1], child);
}, nodeName + '.prepend() with null as an argument, on a parent having a child.');

test(function() {
var parent = node.cloneNode();
var x = document.createElement('x');
var child = document.createElement('test');
const parent = node.cloneNode();
const x = document.createElement('x');
const child = document.createElement('test');
parent.appendChild(child);
parent.prepend(x, 'text');
assert_equals(parent.childNodes[0], x);
Expand All @@ -61,6 +62,6 @@
}

test_prepend(document.createElement('div'), 'Element');
test_prepend(document.createDocumentFragment(), 'DocumentFrgment');
test_prepend(document.createDocumentFragment(), 'DocumentFragment');
</script>
</html>
118 changes: 118 additions & 0 deletions dom/nodes/ParentNode-replaceChildren.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>ParentNode.replaceChildren</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-parentnode-replacechildren">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="pre-insertion-validation-hierarchy.js"></script>
<script>
preInsertionValidateHierarchy("replaceChildren");

function test_replacechildren(node, nodeName) {
test(() => {
const parent = node.cloneNode();
parent.replaceChildren();
assert_array_equals(parent.childNodes, []);
}, `${nodeName}.replaceChildren() without any argument, on a parent having no child.`);

test(() => {
const parent = node.cloneNode();
parent.replaceChildren(null);
assert_equals(parent.childNodes[0].textContent, 'null');
}, `${nodeName}.replaceChildren() with null as an argument, on a parent having no child.`);

test(() => {
const parent = node.cloneNode();
parent.replaceChildren(undefined);
assert_equals(parent.childNodes[0].textContent, 'undefined');
}, `${nodeName}.replaceChildren() with undefined as an argument, on a parent having no child.`);

test(() => {
const parent = node.cloneNode();
parent.replaceChildren('text');
assert_equals(parent.childNodes[0].textContent, 'text');
}, `${nodeName}.replaceChildren() with only text as an argument, on a parent having no child.`);

test(() => {
const parent = node.cloneNode();
const x = document.createElement('x');
parent.replaceChildren(x);
assert_array_equals(parent.childNodes, [x]);
}, `${nodeName}.replaceChildren() with only one element as an argument, on a parent having no child.`);

test(() => {
const parent = node.cloneNode();
const child = document.createElement('test');
parent.appendChild(child);
parent.replaceChildren(null);
assert_equals(parent.childNodes.length, 1);
assert_equals(parent.childNodes[0].textContent, 'null');
}, `${nodeName}.replaceChildren() with null as an argument, on a parent having a child.`);

test(() => {
const parent = node.cloneNode();
const x = document.createElement('x');
const child = document.createElement('test');
parent.appendChild(child);
parent.replaceChildren(x, 'text');
assert_equals(parent.childNodes.length, 2);
assert_equals(parent.childNodes[0], x);
assert_equals(parent.childNodes[1].textContent, 'text');
}, `${nodeName}.replaceChildren() with one element and text as argument, on a parent having a child.`);

async_test(t => {
let phase = 0;

const previousParent = node.cloneNode();
const insertions = [
document.createElement("test1"),
document.createElement("test2")
];
previousParent.append(...insertions);

const parent = node.cloneNode();
const children = [
document.createElement("test3"),
document.createElement("test4")
];
parent.append(...children);

const previousObserver = new MutationObserver(mutations => {
t.step(() => {
assert_equals(phase, 0);
assert_equals(mutations.length, 2);
for (const [i, mutation] of Object.entries(mutations)) {
assert_equals(mutation.type, "childList");
assert_equals(mutation.addedNodes.length, 0);
assert_equals(mutation.removedNodes.length, 1);
assert_equals(mutation.removedNodes[0], insertions[i]);
}
phase = 1;
});
});
previousObserver.observe(previousParent, { childList: true });

const observer = new MutationObserver(mutations => {
t.step(() => {
assert_equals(phase, 1);
assert_equals(mutations.length, 1);
const mutation = mutations[0];
assert_equals(mutation.type, "childList");
assert_equals(mutation.addedNodes.length, 2);
assert_array_equals([...mutation.addedNodes], insertions);
assert_equals(mutation.removedNodes.length, 2);
assert_array_equals([...mutation.removedNodes], children);
});
t.done();
});
observer.observe(parent, { childList: true });

parent.replaceChildren(...previousParent.children);
}, `${nodeName}.replaceChildren() should move nodes in the right order`);
}

test_replacechildren(document.createElement('div'), 'Element');
test_replacechildren(document.createDocumentFragment(), 'DocumentFragment');
</script>

</html>
Loading

0 comments on commit b4c5887

Please sign in to comment.