Merge branch 'rewrite' into array-isArray

This commit is contained in:
Barney Carroll 2017-01-04 14:24:07 +00:00
commit fbb454c6fd
45 changed files with 1132 additions and 449 deletions

View file

@ -14,6 +14,7 @@
<script src="../../render/fragment.js"></script>
<script src="../../render/hyperscript.js"></script>
<script src="../../render/render.js"></script>
<script src="../../promise/promise.js"></script>
<script src="test-hyperscript.js"></script>
<script src="test-trust.js"></script>
<script src="test-fragment.js"></script>

View file

@ -11,7 +11,43 @@ o.spec("attributes", function() {
root = $window.document.body
render = vdom($window).render
})
o.spec("customElements", function(){
o("when vnode is customElement, custom setAttribute called", function(){
var normal = [
{ tag: "input", attrs: { value: 'hello' } },
{ tag: "input", attrs: { value: 'hello' } },
{ tag: "input", attrs: { value: 'hello' } }
]
var custom = [
{ tag: "custom-element", attrs: { custom: 'x' } },
{ tag: "input", attrs: { is: 'something-special', custom: 'x' } },
{ tag: "custom-element", attrs: { is: 'something-special', custom: 'x' } }
]
var view = normal.concat(custom)
var f = $window.document.createElement
var spy
$window.document.createElement = function(tag, is){
var el = f(tag, is)
if(!spy){
spy = o.spy(el.setAttribute)
}
el.setAttribute = spy
return el
}
render(root, view)
o(spy.callCount).equals( custom.length )
})
})
o.spec("input readonly", function() {
o("when input readonly is true, attribute is present", function() {
var a = {tag: "input", attrs: {readonly: true}}

View file

@ -588,14 +588,12 @@ o.spec("component", function() {
o("calls onbeforeremove", function() {
var called = 0
var component = {
onbeforeremove: function(vnode, done) {
onbeforeremove: function(vnode) {
called++
o(vnode.dom).notEquals(undefined)
o(vnode.dom).equals(root.firstChild)
o(root.childNodes.length).equals(1)
done()
},
view: function() {
return {tag: "div", attrs: {id: "a"}, text: "b"}
@ -614,14 +612,12 @@ o.spec("component", function() {
o("calls onbeforeremove when returning fragment", function() {
var called = 0
var component = {
onbeforeremove: function(vnode, done) {
onbeforeremove: function(vnode) {
called++
o(vnode.dom).notEquals(undefined)
o(vnode.dom).equals(root.firstChild)
o(root.childNodes.length).equals(1)
done()
},
view: function() {
return [{tag: "div", attrs: {id: "a"}, text: "b"}]
@ -672,6 +668,10 @@ o.spec("component", function() {
function init(vnode) {
o(vnode.state.data).deepEquals(data)
o(vnode.state.data).equals(data)
//inherits state via prototype
component.x = 1
o(vnode.state.x).equals(1)
}
})
o("state copy is shallow", function() {

View file

@ -4,6 +4,7 @@ var o = require("../../ospec/ospec")
var callAsync = require("../../test-utils/callAsync")
var domMock = require("../../test-utils/domMock")
var vdom = require("../../render/render")
var Promise = require("../../promise/promise")
o.spec("onbeforeremove", function() {
var $window, root, render
@ -43,17 +44,13 @@ o.spec("onbeforeremove", function() {
render(root, [vnode])
render(root, [])
function remove(node, complete) {
function remove(node) {
o(node).equals(vnode)
o(this).equals(vnode.state)
o(root.childNodes.length).equals(1)
o(root.firstChild).equals(vnode.dom)
callAsync(function() {
o(root.childNodes.length).equals(1)
complete()
o(root.childNodes.length).equals(0)
done()
@ -66,16 +63,12 @@ o.spec("onbeforeremove", function() {
render(root, [vnode])
render(root, [])
function remove(node, complete) {
function remove(node) {
o(node).equals(vnode)
o(root.childNodes.length).equals(1)
o(root.firstChild).equals(vnode.dom)
callAsync(function() {
o(root.childNodes.length).equals(1)
complete()
o(root.childNodes.length).equals(0)
done()
@ -88,16 +81,12 @@ o.spec("onbeforeremove", function() {
render(root, [vnode])
render(root, [])
function remove(node, complete) {
function remove(node) {
o(node).equals(vnode)
o(root.childNodes.length).equals(1)
o(root.firstChild).equals(vnode.dom)
callAsync(function() {
o(root.childNodes.length).equals(1)
complete()
o(root.childNodes.length).equals(0)
done()
@ -110,16 +99,12 @@ o.spec("onbeforeremove", function() {
render(root, [vnode])
render(root, [])
function remove(node, complete) {
function remove(node) {
o(node).equals(vnode)
o(root.childNodes.length).equals(1)
o(root.firstChild).equals(vnode.dom)
callAsync(function() {
o(root.childNodes.length).equals(1)
complete()
o(root.childNodes.length).equals(0)
done()
@ -133,17 +118,12 @@ o.spec("onbeforeremove", function() {
render(root, [vnode])
render(root, [])
function remove(node, complete) {
function remove(node) {
o(node).equals(vnode)
o(root.childNodes.length).equals(1)
o(root.firstChild).equals(vnode.dom)
callAsync(function() {
o(root.childNodes.length).equals(1)
o(spy.callCount).equals(0)
complete()
o(root.childNodes.length).equals(0)
o(spy.callCount).equals(1)
@ -161,7 +141,7 @@ o.spec("onbeforeremove", function() {
o(vnode.dom.attributes["onbeforeremove"]).equals(undefined)
})
o("does not recycle when there's an onbeforeremove", function() {
var remove = function(vnode, done) {done()}
var remove = function(vnode) {}
var vnode = {tag: "div", key: 1, attrs: {onbeforeremove: remove}}
var updated = {tag: "div", key: 1, attrs: {onbeforeremove: remove}}
@ -171,26 +151,27 @@ o.spec("onbeforeremove", function() {
o(vnode.dom).notEquals(updated.dom)
})
o("does not leave elements out of order during removal", function() {
var finish
var remove = function(vnode, done) {finish = done}
o("does not leave elements out of order during removal", function(done) {
var remove = function(vnode) {return Promise.resolve()}
var vnodes = [{tag: "div", key: 1, attrs: {onbeforeremove: remove}, text: "1"}, {tag: "div", key: 2, attrs: {onbeforeremove: remove}, text: "2"}]
var updated = {tag: "div", key: 2, attrs: {onbeforeremove: remove}, text: "2"}
render(root, vnodes)
render(root, updated)
o(root.childNodes.length).equals(2)
o(root.firstChild.firstChild.nodeValue).equals("1")
finish()
o(root.childNodes.length).equals(1)
o(root.firstChild.firstChild.nodeValue).equals("2")
callAsync(function() {
o(root.childNodes.length).equals(1)
o(root.firstChild.firstChild.nodeValue).equals("2")
done()
})
})
o("finalizes the remove phase only once when `done()` is called synchronously from both attrs- and tag.onbeforeremove", function() {
o("finalizes the remove phase asynchronously when promise is returned synchronously from both attrs- and tag.onbeforeremove", function(done) {
var onremove = o.spy()
var onbeforeremove = function(vnode, done){done()}
var onbeforeremove = function(){return Promise.resolve()}
var component = {
onbeforeremove: onbeforeremove,
onremove: onremove,
@ -198,30 +179,30 @@ o.spec("onbeforeremove", function() {
}
render(root, [{tag: component, attrs: {onbeforeremove: onbeforeremove, onremove: onremove}}])
render(root, [])
o(onremove.callCount).equals(2) // once for `tag`, once for `attrs`
callAsync(function() {
o(onremove.callCount).equals(2) // once for `tag`, once for `attrs`
done()
})
})
o("doesn't finalize prematurely if `done` is called twice in the `tag` hook", function(done) {
var async = false
o("awaits promise resolution before removing the node", function(done) {
var view = o.spy()
var onremove = o.spy()
var onbeforeremove = function(){return new Promise(function(resolve){callAsync(resolve)})}
var component = {
view: function() {},
onbeforeremove: function(vnode, doneRemoving){
doneRemoving()
doneRemoving()
},
onremove: function() {
o(async).equals(true)
done()
},
onbeforeremove: onbeforeremove,
onremove: onremove,
view: view,
}
render(root, [{
tag:component,
attrs: {
onbeforeremove: function(vnode, doneRemoving){
callAsync(doneRemoving)
}
}
}])
render(root, [{tag: component}])
render(root, [])
async = true
callAsync(function(){
o(onremove.callCount).equals(0)
callAsync(function() {
o(onremove.callCount).equals(1)
done()
})
})
})
})

View file

@ -104,6 +104,15 @@ o.spec("updateNodes", function() {
o(updated[0].dom.nodeValue).equals("a")
o(updated[0].dom).equals(root.childNodes[0])
})
o("handles undefined to null noop", function() {
var vnodes = [null, {tag: "div"}]
var updated = [undefined, {tag: "div"}]
render(root, vnodes)
render(root, updated)
o(root.childNodes.length).equals(1)
})
o("reverses els w/ even count", function() {
var vnodes = [{tag: "a", key: 1}, {tag: "b", key: 2}, {tag: "i", key: 3}, {tag: "s", key: 4}]
var updated = [{tag: "s", key: 4}, {tag: "i", key: 3}, {tag: "b", key: 2}, {tag: "a", key: 1}]
@ -871,7 +880,7 @@ o.spec("updateNodes", function() {
o(onupdate.callCount).equals(0)
})
o("cached, keyed nodes skip diff", function () {
var onupdate = o.spy();
var onupdate = o.spy()
var cached = {tag:"a", key:"a", attrs:{onupdate: onupdate}}
render(root, cached)
@ -917,4 +926,14 @@ o.spec("updateNodes", function() {
o(update.callCount).equals(2)
o(remove.callCount).equals(0)
})
o("component is recreated if key changes to undefined", function () {
var vnode = {tag: "b", key: 1}
var updated = {tag: "b"}
render(root, vnode)
var dom = vnode.dom
render(root, updated)
o(vnode.dom).notEquals(updated.dom)
})
})