Fix #1881 + related ospec bug (#2492)

* Fix #1881 + related ospec bug

* Test duplicate resolves, update changelog
This commit is contained in:
Isiah Meadows 2019-07-26 18:19:40 -04:00 committed by GitHub
parent 90f96ebfee
commit 39fa2b32c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 362 additions and 59 deletions

View file

@ -214,6 +214,224 @@ o.spec("onremove", function() {
o(vnode.dom).notEquals(updated.dom) // this used to be a recycling pool test
o(onremove.callCount).equals(1)
})
// Warning: this test is complicated because it's replicating a race condition.
o("removes correct nodes when child delays removal, parent removes, then child resolves", function () {
// Sugar over the complexity - I need to test the entire tree for consistency.
function expect(expectedPairs) {
var expected = []
for (var i = 0; i < expectedPairs.length; i++) {
var name = expectedPairs[i][0]
var text = expectedPairs[i][1]
expected.push({
name: name,
firstType: name === "#text" ? null : "#text",
text: text,
})
}
var actual = []
var list = root.firstChild.childNodes
for (var i = 0; i < list.length; i++) {
var current = list[i]
var textNode = current.childNodes.length === 1
? current.firstChild
: current
actual.push({
name: current.nodeName,
firstType: textNode === current ? null : textNode.nodeName,
text: textNode.nodeValue,
})
}
o(actual).deepEquals(expected)
}
var resolve
function update(id, showParent, showChild) {
render(root, [
{tag: "div", children: [
showParent ? {tag: "[", children: [
{tag: "#", children: ""}, // Required
showChild ? {tag: "[", attrs: {
onbeforeremove: function () {
return {then: function (r) { resolve = r }}
},
}, children: [
{tag: "div", text: id},
]} : undefined,
]} : undefined,
]}
])
}
update("1", true, true)
expect([
["#text", ""],
["DIV", "1"],
])
o(resolve).equals(undefined)
update("2", true, false)
expect([
["#text", ""],
["DIV", "1"],
])
o(typeof resolve).equals("function")
var original = resolve
update("3", true, true)
expect([
["#text", ""],
["DIV", "1"],
["DIV", "3"],
])
o(resolve).equals(original)
update("4", false, true)
expect([
["DIV", "1"],
])
o(resolve).equals(original)
update("5", true, true)
expect([
["DIV", "1"],
["#text", ""],
["DIV", "5"],
])
o(resolve).equals(original)
resolve()
expect([
["#text", ""],
["DIV", "5"],
])
o(resolve).equals(original)
update("6", true, true)
expect([
["#text", ""],
["DIV", "6"],
])
o(resolve).equals(original)
})
// Warning: this test is complicated because it's replicating a race condition.
o("removes correct nodes when child delays removal, parent removes, then child resolves + rejects both", function () {
// Sugar over the complexity - I need to test the entire tree for consistency.
function expect(expectedPairs) {
var expected = []
for (var i = 0; i < expectedPairs.length; i++) {
var name = expectedPairs[i][0]
var text = expectedPairs[i][1]
expected.push({
name: name,
firstType: name === "#text" ? null : "#text",
text: text,
})
}
var actual = []
var list = root.firstChild.childNodes
for (var i = 0; i < list.length; i++) {
var current = list[i]
var textNode = current.childNodes.length === 1
? current.firstChild
: current
actual.push({
name: current.nodeName,
firstType: textNode === current ? null : textNode.nodeName,
text: textNode.nodeValue,
})
}
o(actual).deepEquals(expected)
}
var resolve, reject
function update(id, showParent, showChild) {
render(root, [
{tag: "div", children: [
showParent ? {tag: "[", children: [
{tag: "#", children: ""}, // Required
showChild ? {tag: "[", attrs: {
onbeforeremove: function () {
return {then: function (res, rej) {
resolve = res
reject = rej
}}
},
}, children: [
{tag: "div", text: id},
]} : undefined,
]} : undefined,
]}
])
}
update("1", true, true)
expect([
["#text", ""],
["DIV", "1"],
])
o(resolve).equals(undefined)
update("2", true, false)
expect([
["#text", ""],
["DIV", "1"],
])
o(typeof resolve).equals("function")
var originalResolve = resolve
var originalReject = reject
update("3", true, true)
expect([
["#text", ""],
["DIV", "1"],
["DIV", "3"],
])
o(resolve).equals(originalResolve)
o(reject).equals(originalReject)
update("4", false, true)
expect([
["DIV", "1"],
])
o(resolve).equals(originalResolve)
o(reject).equals(originalReject)
update("5", true, true)
expect([
["DIV", "1"],
["#text", ""],
["DIV", "5"],
])
o(resolve).equals(originalResolve)
o(reject).equals(originalReject)
resolve()
reject()
reject()
resolve()
expect([
["#text", ""],
["DIV", "5"],
])
o(resolve).equals(originalResolve)
o(reject).equals(originalReject)
update("6", true, true)
expect([
["#text", ""],
["DIV", "6"],
])
o(resolve).equals(originalResolve)
o(reject).equals(originalReject)
})
})
})
})

View file

@ -13,7 +13,7 @@ o.spec("updateNodes keyed list Fuzzer", function() {
render = vdom($window)
})
void [
{delMax: 0, movMax: 50, insMax: 9},
{delMax: 3, movMax: 5, insMax: 5},
@ -31,7 +31,7 @@ o.spec("updateNodes keyed list Fuzzer", function() {
render(root, test.updated.map(function(x){return {tag: x, key: x}}))
if (root.appendChild.callCount + root.insertBefore.callCount !== test.expected.creations + test.expected.moves) console.log(test, {aC: root.appendChild.callCount, iB: root.insertBefore.callCount}, [].map.call(root.childNodes, function(n){return n.nodeName.toLowerCase()}))
o(root.appendChild.callCount + root.insertBefore.callCount).equals(test.expected.creations + test.expected.moves)("moves")
o(root.removeChild.callCount).equals(test.expected.deletions)("deletions")
o([].map.call(root.childNodes, function(n){return n.nodeName.toLowerCase()})).deepEquals(test.updated)
@ -154,4 +154,3 @@ function addSpies(node) {
node.insertBefore = o.spy(node.insertBefore)
node.removeChild = o.spy(node.removeChild)
}