var o = require("ospec") var components = require("../../test-utils/components") var domMock = require("../../test-utils/domMock") var vdom = require("../../render/render") var m = require("../../render/hyperscript") var fragment = require("../../render/fragment") var domFor = require('../../render/dom-for').domFor o.spec("domFor(vnode)", function() { var $window, root, render o.beforeEach(function() { $window = domMock() root = $window.document.createElement("div") render = vdom($window) }) o('works for simple vnodes', function() { render(root, m('div', {oncreate(vnode){ let n = 0 for (const dom of domFor(vnode)) { o(dom).equals(root.firstChild) o(++n).equals(1) } }})) }) o('works for fragments', function () { render(root, fragment({ oncreate(vnode){ let n = 0 for (const dom of domFor(vnode)) { o(dom).equals(root.childNodes[n]) n++ } o(n).equals(2) } }, [ m('a'), m('b') ])) }) o('works in fragments with children that have delayed removal', function() { function oncreate(vnode){ o(root.childNodes.length).equals(3) o(root.childNodes[0].nodeName).equals('A') o(root.childNodes[1].nodeName).equals('B') o(root.childNodes[2].nodeName).equals('C') const iter = domFor(vnode) o(iter.next()).deepEquals({done:false, value: root.childNodes[0]}) o(iter.next()).deepEquals({done:false, value: root.childNodes[1]}) o(iter.next()).deepEquals({done:false, value: root.childNodes[2]}) o(iter.next().done).deepEquals(true) o(root.childNodes.length).equals(3) } function onupdate(vnode) { // the b node is still present in the DOM o(root.childNodes.length).equals(3) o(root.childNodes[0].nodeName).equals('A') o(root.childNodes[1].nodeName).equals('B') o(root.childNodes[2].nodeName).equals('C') const iter = domFor(vnode) o(iter.next()).deepEquals({done:false, value: root.childNodes[0]}) o(iter.next()).deepEquals({done:false, value: root.childNodes[2]}) o(iter.next().done).deepEquals(true) o(root.childNodes.length).equals(3) } render(root, fragment( {oncreate, onupdate}, [ m('a'), m('b', {onbeforeremove(){return {then(){}, finally(){}}}}), m('c') ] )) render(root, fragment( {oncreate, onupdate}, [ m('a'), null, m('c'), ] )) }) components.forEach(function(cmp){ o.spec(cmp.kind, function(){ var createComponent = cmp.create o('works for components that return one element', function() { const C = createComponent({ view(){return m('div')}, oncreate(vnode){ let n = 0 for (const dom of domFor(vnode)) { o(dom).equals(root.firstChild) o(++n).equals(1) } } }) render(root, m(C)) }) o('works for components that return fragments', function () { const oncreate = o.spy(function oncreate(vnode){ o(root.childNodes.length).equals(3) o(root.childNodes[0].nodeName).equals('A') o(root.childNodes[1].nodeName).equals('B') o(root.childNodes[2].nodeName).equals('C') const iter = domFor(vnode) o(iter.next()).deepEquals({done:false, value: root.childNodes[0]}) o(iter.next()).deepEquals({done:false, value: root.childNodes[1]}) o(iter.next()).deepEquals({done:false, value: root.childNodes[2]}) o(iter.next().done).deepEquals(true) o(root.childNodes.length).equals(3) }) const C = createComponent({ view({children}){return children}, oncreate }) render(root, m(C, [ m('a'), m('b'), m('c') ])) o(oncreate.callCount).equals(1) }) o('works for components that return fragments with delayed removal', function () { const onbeforeremove = o.spy(function onbeforeremove(){return {then(){}, finally(){}}}) const oncreate = o.spy(function oncreate(vnode){ o(root.childNodes.length).equals(3) o(root.childNodes[0].nodeName).equals('A') o(root.childNodes[1].nodeName).equals('B') o(root.childNodes[2].nodeName).equals('C') const iter = domFor(vnode) o(iter.next()).deepEquals({done:false, value: root.childNodes[0]}) o(iter.next()).deepEquals({done:false, value: root.childNodes[1]}) o(iter.next()).deepEquals({done:false, value: root.childNodes[2]}) o(iter.next().done).deepEquals(true) o(root.childNodes.length).equals(3) }) const onupdate = o.spy(function onupdate(vnode) { o(root.childNodes.length).equals(3) o(root.childNodes[0].nodeName).equals('A') o(root.childNodes[1].nodeName).equals('B') o(root.childNodes[2].nodeName).equals('C') const iter = domFor(vnode) o(iter.next()).deepEquals({done:false, value: root.childNodes[0]}) o(iter.next()).deepEquals({done:false, value: root.childNodes[2]}) o(iter.next().done).deepEquals(true) o(root.childNodes.length).equals(3) }) const C = createComponent({ view({children}){return children}, oncreate, onupdate }) render(root, m(C, [ m('a'), m('b', {onbeforeremove}), m('c') ])) render(root, m(C, [ m('a'), null, m('c') ])) o(oncreate.callCount).equals(1) o(onupdate.callCount).equals(1) o(onbeforeremove.callCount).equals(1) }) }) }) })