diff --git a/render/fragment.js b/render/fragment.js index 3ee22f5b7..a3b217a26 100644 --- a/render/fragment.js +++ b/render/fragment.js @@ -6,6 +6,7 @@ var hyperscriptVnode = require("./hyperscriptVnode") module.exports = function(attrs, ...children) { var vnode = hyperscriptVnode(attrs, children) + if (vnode.attrs == null) vnode.attrs = {} vnode.tag = "[" vnode.children = Vnode.normalizeChildren(vnode.children) return vnode diff --git a/render/hyperscript.js b/render/hyperscript.js index 7429faf54..7844ae743 100644 --- a/render/hyperscript.js +++ b/render/hyperscript.js @@ -96,6 +96,7 @@ function hyperscript(selector, attrs, ...children) { if (selector !== "[") return execSelector(selectorCache[selector] || compileSelector(selector), vnode) } + if (vnode.attrs == null) vnode.attrs = {} vnode.tag = selector return vnode } diff --git a/render/tests/test-fragment.js b/render/tests/test-fragment.js index cea868c0d..b67f566bc 100644 --- a/render/tests/test-fragment.js +++ b/render/tests/test-fragment.js @@ -44,50 +44,59 @@ function runTest(name, fragment) { o("handles string single child", function() { var vnode = fragment(["a"]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("a") }) o("handles falsy string single child", function() { var vnode = fragment([""]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("") }) o("handles number single child", function() { var vnode = fragment([1]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("1") }) o("handles falsy number single child", function() { var vnode = fragment([0]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("0") }) o("handles boolean single child", function() { var vnode = fragment([true]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null]) }) o("handles falsy boolean single child", function() { var vnode = fragment([false]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null]) }) o("handles null single child", function() { var vnode = fragment([null]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0]).equals(null) }) o("handles undefined single child", function() { var vnode = fragment([undefined]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null]) }) o("handles multiple string children", function() { var vnode = fragment(["", "a"]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("") o(vnode.children[1].tag).equals("#") @@ -96,6 +105,7 @@ function runTest(name, fragment) { o("handles multiple number children", function() { var vnode = fragment([0, 1]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("0") o(vnode.children[1].tag).equals("#") @@ -104,16 +114,19 @@ function runTest(name, fragment) { o("handles multiple boolean children", function() { var vnode = fragment([false, true]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null, null]) }) o("handles multiple null/undefined child", function() { var vnode = fragment([null, undefined]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null, null]) }) o("handles falsy number single child without attrs", function() { var vnode = fragment(0) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("0") }) @@ -122,50 +135,59 @@ function runTest(name, fragment) { o("handles string single child", function() { var vnode = fragment({}, ["a"]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("a") }) o("handles falsy string single child", function() { var vnode = fragment({}, [""]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("") }) o("handles number single child", function() { var vnode = fragment({}, [1]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("1") }) o("handles falsy number single child", function() { var vnode = fragment({}, [0]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("0") }) o("handles boolean single child", function() { var vnode = fragment({}, [true]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null]) }) o("handles falsy boolean single child", function() { var vnode = fragment({}, [false]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null]) }) o("handles null single child", function() { var vnode = fragment({}, [null]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null]) }) o("handles undefined single child", function() { var vnode = fragment({}, [undefined]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null]) }) o("handles multiple string children", function() { var vnode = fragment({}, ["", "a"]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("") o(vnode.children[1].tag).equals("#") @@ -174,6 +196,7 @@ function runTest(name, fragment) { o("handles multiple number children", function() { var vnode = fragment({}, [0, 1]) + o(vnode.attrs).deepEquals({}) o(vnode.children[0].tag).equals("#") o(vnode.children[0].children).equals("0") o(vnode.children[1].tag).equals("#") @@ -182,11 +205,13 @@ function runTest(name, fragment) { o("handles multiple boolean children", function() { var vnode = fragment({}, [false, true]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null, null]) }) o("handles multiple null/undefined child", function() { var vnode = fragment({}, [null, undefined]) + o(vnode.attrs).deepEquals({}) o(vnode.children).deepEquals([null, null]) }) }) diff --git a/render/tests/test-hyperscript.js b/render/tests/test-hyperscript.js index ed918fe1e..9577bdfac 100644 --- a/render/tests/test-hyperscript.js +++ b/render/tests/test-hyperscript.js @@ -568,6 +568,26 @@ o.spec("hyperscript", function() { o(vnode.children[0].tag).equals("i") o(vnode.children[1].tag).equals("s") }) + o("handles children without attr (fragment)", function() { + var vnode = m("[", [m("i"), m("s")]) + + o(vnode.attrs).deepEquals({}) + o(vnode.children[0].tag).equals("i") + o(vnode.children[1].tag).equals("s") + }) + o("handles child without attr unwrapped (fragment)", function() { + var vnode = m("[", m("i")) + + o(vnode.attrs).deepEquals({}) + o(vnode.children[0].tag).equals("i") + }) + o("handles children without attr unwrapped (fragment)", function() { + var vnode = m("[", m("i"), m("s")) + + o(vnode.attrs).deepEquals({}) + o(vnode.children[0].tag).equals("i") + o(vnode.children[1].tag).equals("s") + }) o("handles shared attrs", function() { var attrs = {a: "b"} @@ -664,5 +684,41 @@ o.spec("hyperscript", function() { o(vnode.children.length).equals(1) o(vnode.children[0]).equals("b") }) + o("works with POJOs (without attrs)", function() { + var component = { + view: function() {} + } + var vnode = m(component, "b") + + o(vnode.tag).equals(component) + o(vnode.attrs).deepEquals({}) + o(vnode.children.length).equals(1) + o(vnode.children[0]).equals("b") + }) + o("works with constructibles (without attrs)", function() { + var component = o.spy() + component.prototype.view = function() {} + + var vnode = m(component, "b") + + o(component.callCount).equals(0) + + o(vnode.tag).equals(component) + o(vnode.attrs).deepEquals({}) + o(vnode.children.length).equals(1) + o(vnode.children[0]).equals("b") + }) + o("works with closures (without attrs)", function () { + var component = o.spy() + + var vnode = m(component, "b") + + o(component.callCount).equals(0) + + o(vnode.tag).equals(component) + o(vnode.attrs).deepEquals({}) + o(vnode.children.length).equals(1) + o(vnode.children[0]).equals("b") + }) }) })