mithril-vndb/tests/mithril-tests.js
2016-03-03 10:27:26 +00:00

5592 lines
122 KiB
JavaScript

/* global m, test, mock */
(function () { // eslint-disable-line max-statements
"use strict"
m.deps(mock.window)
// m
test(function () { return typeof m.version() === "string" })
test(function () { return m("div").tag === "div" })
test(function () { return m(".foo").tag === "div" })
test(function () { return m(".foo").attrs.className === "foo" })
test(function () { return m("[title=bar]").tag === "div" })
test(function () { return m("[title=bar]").attrs.title === "bar" })
test(function () { return m("[empty]").attrs.empty === "" })
test(function () { return m("[title=\'bar\']").attrs.title === "bar" })
test(function () { return m("[title=\"bar\"]").attrs.title === "bar" })
test(function () { return m("div", "test").children[0] === "test" })
test(function () {
return m("div", "test", "test2").children[1] === "test2"
})
test(function () { return m("div", ["test"]).children[0] === "test" })
test(function () {
return m("div", {title: "bar"}, "test").attrs.title === "bar"
})
test(function () {
return m("div", {title: "bar"}, "test").children[0] === "test"
})
test(function () {
return m("div", {title: "bar"}, ["test"]).children[0] === "test"
})
test(function () {
return m("div", {title: "bar"}, m("div")).children[0].tag === "div"
})
test(function () {
return m("div", {title: "bar"}, [m("div")]).children[0].tag === "div"
})
// splat
test(function () {
var node = m("div", {title: "bar"}, "test0", "test1", "test2", "test3")
return node.children[3] === "test3"
})
test(function () {
var node = m("div", {title: "bar"}, m("div"), m("i"), m("span"))
return node.children[2].tag === "span"
})
test(function () { return m("div", ["a", "b"]).children.length === 2 })
test(function () { return m("div", [m("div")]).children[0].tag === "div" })
// yes, this is expected behavior: see method signature
test(function () { return m("div", m("div")).children[0].tag === "div" })
test(function () { return m("div", [undefined]).tag === "div" })
// as long as it doesn't throw errors, it's fine
test(function () { return m("div", [{foo: "bar"}]) })
test(function () { return m("svg", [m("g")]) })
test(function () { return m("svg", [m("a[href='http://google.com']")]) })
test(function () {
return m(".foo", {class: "bar"}).attrs.class === "foo bar"
})
test(function () {
return m(".foo", {className: "bar"}).attrs.className === "foo bar"
})
test(function () {
return m(".foo", {className: ""}).attrs.className === "foo"
})
// https://github.com/lhorie/mithril.js/issues/382 and 512
test(function () {
return m("div", {className: ""}).attrs.className === ""
})
test(function () {
return m("div", {class: ""}).attrs.className === undefined
})
test(function () {
return m("div", {className: ""}).attrs.class === undefined
})
test(function () { return m("div", {class: ""}).attrs.class === "" })
test(function () { return m("div", [1, 2, 3], 4).children.length === 2 })
test(function () { return m("div", [1, 2, 3], 4).children[0].length === 3 })
test(function () { return m("div", [1, 2, 3], 4).children[1] === 4 })
test(function () { return m("div", [1, 2, 3]).children.length === 3 })
test(function () {
return m("div", [1, 2, 3], [4, 5, 6, 7]).children.length === 2
})
test(function () {
return m("div", [1, 2, 3], [4, 5, 6, 7]).children[0].length === 3
})
test(function () {
return m("div", [1, 2, 3], [4, 5, 6, 7]).children[1].length === 4
})
test(function () { return m("div", [1], [2], [3]).children.length === 3 })
test(function () {
// class changes shouldn't trigger dom recreation
var v1 = m(".foo", {class: "", onclick: function () {}})
var v2 = m(".foo", {class: "bar", onclick: function () {}})
return Object.keys(v1.attrs).join() === Object.keys(v2.attrs).join()
})
test(function () {
// m should proxy object first arg to m.component
var component = {
controller: function (args) {
this.args = args
},
view: function () {
return m("div", "testing")
}
}
var args = {age: 12}
var c1 = m(component, args).controller()
var c2 = m.component(component, args).controller()
return c1.args === args && c1.args === c2.args
})
// m.mount
test(function () {
var root = mock.document.createElement("div")
var whatever = 1
var app = {
view: function () {
return [
whatever % 2 ? m("span", "% 2") : undefined,
m("div", "bugs"),
m("a")
]
}
}
m.mount(root, app)
mock.requestAnimationFrame.$resolve()
whatever++
m.redraw()
mock.requestAnimationFrame.$resolve()
whatever++
m.redraw()
mock.requestAnimationFrame.$resolve()
return root.childNodes.length
})
test(function () {
mock.requestAnimationFrame.$resolve()
var root1 = mock.document.createElement("div")
var mod1 = m.mount(root1, {
controller: function () { this.value = "test1" },
view: function (ctrl) { return ctrl.value }
})
var root2 = mock.document.createElement("div")
var mod2 = m.mount(root2, {
controller: function () { this.value = "test2" },
view: function (ctrl) { return ctrl.value }
})
mock.requestAnimationFrame.$resolve()
return (root1.childNodes[0].nodeValue === "test1" &&
root2.childNodes[0].nodeValue === "test2") &&
(mod1.value && mod1.value === "test1") &&
(mod2.value && mod2.value === "test2")
})
test(function () {
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var unloaded = false
m.mount(root, {
controller: function () {
this.value = "test1"
this.onunload = function () {
unloaded = true
}
},
view: function (ctrl) { return ctrl.value }
})
mock.requestAnimationFrame.$resolve()
m.mount(root, null)
mock.requestAnimationFrame.$resolve()
return unloaded
})
test(function () {
// component should pass args to both controller and view
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var slot1, slot2
var component = {
controller: function (options) { slot1 = options.a },
view: function (ctrl, options) { slot2 = options.a }
}
m.mount(root, m.component(component, {a: 1}))
mock.requestAnimationFrame.$resolve()
return slot1 === 1 && slot2 === 1
})
test(function () {
// component should work without controller
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var slot2
var component = {
view: function (ctrl, options) { slot2 = options.a }
}
m.mount(root, m.component(component, {a: 1}))
mock.requestAnimationFrame.$resolve()
return slot2 === 1
})
test(function () {
// component controller should only run once
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var count1 = 0
var count2 = 0
var sub = {
controller: function () {
count1++
},
view: function () {
count2++
return m("div", "test")
}
}
var component = {
view: function () {
return sub
}
}
m.mount(root, component)
mock.requestAnimationFrame.$resolve()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
return count1 === 1 && count2 === 2
})
test(function () {
// sub component controller should only run once
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var count1 = 0
var count2 = 0
var count3 = 0
var count4 = 0
var subsub = {
controller: function () {
count3++
},
view: function () {
count4++
return m("div", "test")
}
}
var sub = {
controller: function () {
count1++
},
view: function () {
count2++
return subsub
}
}
var component = {
view: function () {
return sub
}
}
m.mount(root, component)
mock.requestAnimationFrame.$resolve()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
return count1 === 1 && count2 === 2 && count3 === 1 && count4 === 2
})
test(function () {
// keys in components should work
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var list = [1, 2, 3]
var sub = {
controller: function () {},
view: function () {
return m("div")
}
}
var component = {
controller: function () {},
view: function () {
return list.map(function (i) {
return m.component(sub, {key: i})
})
}
}
m.mount(root, component)
var firstBefore = root.childNodes[0]
mock.requestAnimationFrame.$resolve()
list.reverse()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
var firstAfter = root.childNodes[2]
return firstBefore === firstAfter
})
test(function () {
//string keys in components should work
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var list = [1, 2, 3]
var component = {
controller: function () {},
view: function () {
return list.map(function (i) {
return m.component(sub, {key: "key" + i})
})
}
}
var sub = {
controller: function () {},
view: function () {
return m("div")
}
}
m.mount(root, component)
var firstBefore = root.childNodes[0]
mock.requestAnimationFrame.$resolve()
list.reverse()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
var firstAfter = root.childNodes[2]
return firstBefore === firstAfter
})
test(function () {
//keys in subcomponents should work
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var list = [1, 2, 3]
var subsub = {
controller: function () {},
view: function () {
return m("div")
}
}
var sub = {
view: function () {
return subsub
}
}
var component = {
controller: function () {},
view: function () {
return list.map(function (i) {
return m.component(sub, {key: i})
})
}
}
m.mount(root, component)
var firstBefore = root.childNodes[0]
mock.requestAnimationFrame.$resolve()
list.reverse()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
var firstAfter = root.childNodes[2]
return firstBefore === firstAfter
})
test(function () {
// keys in components should work even if component internally messes
// them up
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var list = [1, 2, 3]
var sub = {
controller: function () {},
view: function () {
return m("div", {key: 1})
}
}
var component = {
controller: function () {},
view: function () {
return list.map(function (i) {
return m.component(sub, {key: i})
})
}
}
m.mount(root, component)
var firstBefore = root.childNodes[0]
mock.requestAnimationFrame.$resolve()
list.reverse()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
var firstAfter = root.childNodes[2]
return firstBefore === firstAfter
})
test(function () {
// keys in subcomponents should work even if component internally messes
// them up
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var list = [1, 2, 3]
var subsub = {
controller: function () {},
view: function () {
return m("div", {key: 1})
}
}
var sub = {
controller: function () {},
view: function () {
return subsub
}
}
var component = {
controller: function () {},
view: function () {
return list.map(function (i) {
return m.component(sub, {key: i})
})
}
}
m.mount(root, component)
var firstBefore = root.childNodes[0]
mock.requestAnimationFrame.$resolve()
list.reverse()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
var firstAfter = root.childNodes[2]
return firstBefore === firstAfter
})
test(function () {
// component identity should stay intact if components are descendants
// of keyed elements
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var list = [1, 2, 3]
var sub = {
controller: function () {},
view: function () {
return m("div")
}
}
var component = {
controller: function () {},
view: function () {
return list.map(function (i) {
return m("div", {key: i}, sub)
})
}
}
m.mount(root, component)
var firstBefore = root.childNodes[0].childNodes[0]
mock.requestAnimationFrame.$resolve()
list.reverse()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
var firstAfter = root.childNodes[2].childNodes[0]
return firstBefore === firstAfter
})
test(function () {
// subcomponent identity should stay intact if components are
// descendants of keyed elements
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var list = [1, 2, 3]
var subsub = {
controller: function () {},
view: function () {
return m("div")
}
}
var sub = {
controller: function () {},
view: function () {
return subsub
}
}
var component = {
controller: function () {},
view: function () {
return list.map(function (i) {
return m("div", {key: i}, sub)
})
}
}
m.mount(root, component)
var firstBefore = root.childNodes[0].childNodes[0]
mock.requestAnimationFrame.$resolve()
list.reverse()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
var firstAfter = root.childNodes[2].childNodes[0]
return firstBefore === firstAfter
})
test(function () {
// component should call onunload when removed from template
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var list = [1, 2, 3]
var unloaded
var sub = {
controller: function (opts) {
this.onunload = function () {
unloaded = opts.key
}
},
view: function () {
return m("div")
}
}
var component = {
controller: function () {},
view: function () {
return list.map(function (i) {
return m.component(sub, {key: i})
})
}
}
m.mount(root, component)
mock.requestAnimationFrame.$resolve()
list.pop()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
return unloaded === 3
})
test(function () {
// subcomponent should call onunload when removed from template
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var list = [1, 2, 3]
var unloaded1, unloaded2
var subsub = {
controller: function (opts) {
this.onunload = function () {
unloaded2 = opts.key
}
},
view: function () {
return m("div")
}
}
var sub = {
controller: function (opts) {
this.onunload = function () {
unloaded1 = opts.key
}
},
view: function (ctrl, opts) {
return m.component(subsub, {key: opts.key})
}
}
var component = {
controller: function () {},
view: function () {
return list.map(function (i) {
return m.component(sub, {key: i})
})
}
}
m.mount(root, component)
mock.requestAnimationFrame.$resolve()
list.pop()
m.redraw(true)
mock.requestAnimationFrame.$resolve()
return unloaded1 === 3 && unloaded2 === 3
})
test(function () {
// calling m.redraw synchronously from controller constructor should not
// trigger extra redraws
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var count = 0
var sub = {
controller: function () {
m.redraw()
},
view: function () {
count++
return m("div")
}
}
var component = {
controller: function () {},
view: function () {
return sub
}
}
m.mount(root, component)
mock.requestAnimationFrame.$resolve()
return count === 1
})
test(function () {
// calling m.redraw synchronously from controller constructor should not
// trigger extra redraws
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var count = 0
var subsub = {
controller: function () {
m.redraw()
},
view: function () {
count++
return m("div")
}
}
var sub = {
controller: function () {},
view: function () {
return subsub
}
}
var component = {
controller: function () {},
view: function () {
return sub
}
}
m.mount(root, component)
mock.requestAnimationFrame.$resolve()
return count === 1
})
test(function () {
// calling preventDefault from component's onunload should prevent route
// change
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var loaded = false
var testEnabled = true
var sub = {
controller: function () {
this.onunload = function (e) {
if (testEnabled) e.preventDefault()
}
},
view: function () {
return m("div")
}
}
var component = {
controller: function () {},
view: function () {
return sub
}
}
m.route(root, "/a", {
"/a": component,
"/b": {
controller: function () { loaded = true },
view: function () {}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
testEnabled = false
return loaded === false
})
test(function () {
// calling preventDefault from subcomponent's onunload should prevent
// route change
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var loaded = false
var testEnabled = true
var subsub = {
controller: function () {
this.onunload = function (e) {
if (testEnabled) e.preventDefault()
}
},
view: function () {
return m("div")
}
}
var sub = {
controller: function () {},
view: function () {
return subsub
}
}
var component = {
controller: function () {},
view: function () {
return sub
}
}
m.route(root, "/a", {
"/a": component,
"/b": {
controller: function () { loaded = true },
view: function () {}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
testEnabled = false
return loaded === false
})
test(function () {
// calling preventDefault from non-curried component's onunload should
// prevent route change
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var loaded = false
var testEnabled = true
var sub = {
controller: function () {
this.onunload = function (e) {
if (testEnabled) e.preventDefault()
}
},
view: function () {
return m("div")
}
}
var component = {
controller: function () {},
view: function () {
return sub
}
}
m.route(root, "/a", {
"/a": component,
"/b": {
controller: function () { loaded = true },
view: function () {}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
testEnabled = false
return loaded === false
})
test(function () {
// calling preventDefault from non-curried subcomponent's onunload
// should prevent route change
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var loaded = false
var testEnabled = true
var subsub = {
controller: function () {
this.onunload = function (e) {
if (testEnabled) e.preventDefault()
}
},
view: function () {
return m("div")
}
}
var sub = {
controller: function () {},
view: function () {
return subsub
}
}
var component = {
controller: function () {},
view: function () {
return sub
}
}
m.route(root, "/a", {
"/a": component,
"/b": {
controller: function () { loaded = true },
view: function () {}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
testEnabled = false
return loaded === false
})
test(function () {
// nested components under keyed components should render
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var count = 0
var Reply = {
controller: function () {},
view: function () {
count++
return m(".reply")
}
}
var CommentList = {
controller: function () {},
view: function (ctrl, props) {
return m(".list", props.list.map(function (i) {
return m(".comment", [
m.component(Reply, {key: i})
])
}))
}
}
var App = {
controller: function () {},
view: function () {
return m(".outer", [
m(".inner", m.component(CommentList, {list: [1, 2, 3]}))
])
}
}
m.mount(root, App)
mock.requestAnimationFrame.$resolve()
return count === 3
})
test(function () {
// a route change should initialize a component's controller
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var countA = 0
var countB = 0
var subA = {
controller: function (){ countA += 1 },
view: function () { return m("div") }
}
var subB = {
controller: function () { countB += 1 },
view: function () { return m("div") }
}
m.route(root, "/a", {
"/a": {
view: function () {
return m(".page-a", [
m("h1"), m.component(subA, {x: 11})
])
}
},
"/b": {
view: function () {
return m(".page-b", [
m("h2"), m.component(subB, {y: 22})
])
}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
m.route("/a")
mock.requestAnimationFrame.$resolve()
return countA === 2 && countB === 1
})
test(function () {
var root = mock.document.createElement("div")
var component = {}
var unloaded = false
component.controller = function () {
this.onunload = function () { unloaded = true }
}
component.view = function () {}
m.mount(root, component)
m.mount(root, {controller: function () {}, view: function () {}})
return unloaded === true
})
test(function () {
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var initCount = 0
var component = {}
component.view = function () {
return m("div", {
config: function (el, init) {
if (!init) initCount++
}
})
}
m.mount(root, component)
mock.requestAnimationFrame.$resolve()
m.redraw()
mock.requestAnimationFrame.$resolve()
return initCount === 1
})
test(function () {
var root = mock.document.createElement("div")
var dom = mock.document.createElement("div")
var show = true
var component = {
view: function () {
return [
m(".foo", {
key: 1,
config: test,
onclick: function () { show = !show }
}),
show ? m(".bar", {key: 2}) : null
]
}
}
function test(el, init) {
if (!init) {
root.appendChild(dom)
}
}
m.mount(root, component)
mock.requestAnimationFrame.$resolve()
show = false
m.redraw()
mock.requestAnimationFrame.$resolve()
show = true
m.redraw()
mock.requestAnimationFrame.$resolve()
return root.childNodes.length === 3
})
test(function () {
var root = mock.document.createElement("div")
var show = true
var testcomponent = {
controller: function () {},
view: function () {
return m("div", "component")
}
}
var app = {
view: function () {
return show ? [
m("h1", "1"),
testcomponent
] : [
m("h1", "2")
]
}
}
m.mount(root, app)
mock.requestAnimationFrame.$resolve()
show = false
m.redraw()
mock.requestAnimationFrame.$resolve()
show = true
m.redraw()
mock.requestAnimationFrame.$resolve()
return root.childNodes.length === 2
})
test(function () {
// Components should not require a view
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var Component = {
view: function () {
return m(".comp")
}
}
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/foo", {
"/foo": {
view: function () {
return [Component]
}
}
})
mock.requestAnimationFrame.$resolve()
return root.childNodes[0].nodeName === "DIV"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/551
var root = mock.document.createElement("div")
var a = false
var found = false
var unloaded = false
var redraws = 0
var Comp = {
view: function () {
redraws++
return m("div", {config: Comp.config}, [
m("div", {
onclick: function () {
a = !a
m.redraw(true)
found = root.childNodes[0].childNodes[1]
}
}, "asd"),
a ? m("#a", "aaa") : null,
"test"
])
},
config: function (el, init, ctx) {
if (!init) ctx.onunload = function () { unloaded = true }
}
}
var Root = {
view: function () {
return Comp
}
}
m.mount(root, Root)
var target = root.childNodes[0].childNodes[0]
target.onclick({currentTarget: target})
mock.requestAnimationFrame.$resolve()
return !unloaded && found.id === "a" && redraws === 3
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/551
var root = mock.document.createElement("div")
var a = false
var found = false
var unloaded = false
var redraws = 0
var Comp = {
view: function () {
redraws++
return m("div", {config: Comp.config}, [
m("div", {
onclick: function () {
a = !a
m.redraw(true)
found = root.childNodes[0].childNodes[1]
m.redraw.strategy("none")
}
}, "asd"),
a ? m("#a", "aaa") : null,
"test"
])
},
config: function (el, init, ctx) {
if (!init) ctx.onunload = function () { unloaded = true }
}
}
var Root = {
view: function () {
return Comp
}
}
m.mount(root, Root)
var target = root.childNodes[0].childNodes[0]
target.onclick({currentTarget: target})
mock.requestAnimationFrame.$resolve()
return !unloaded && found.id === "a" && redraws === 2
})
test(function () {
var root = mock.document.createElement("div")
var redraws = 0
var Root = {
view: function () {
redraws++
return m("div", {onclick: function () { m.redraw(true) }})
}
}
m.mount(root, Root)
var target = root.childNodes[0]
target.onclick({currentTarget: target})
mock.requestAnimationFrame.$resolve()
return redraws === 3
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/555
var root = mock.document.createElement("div")
var MyComponent = {
controller: function (args) {
this.name = args.name
},
view: function (ctrl) {
return m("div", ctrl.name)
}
}
var FooPage = {
view: function () {
return m("div", [
m("a[href=/]", {config: m.route}, "foo"),
m("a[href=/bar]", {config: m.route}, "bar"),
m.component(MyComponent, {name: "Jane"})
])
}
}
var BarPage = {
view: function () {
return m("div", [
m("a[href=/]", {config: m.route}, "foo"),
m("a[href=/bar]", {config: m.route}, "bar"),
m.component(MyComponent, {name: "Bob"})
])
}
}
m.route(root, "/", {
"/": FooPage,
"/bar": BarPage
})
mock.requestAnimationFrame.$resolve()
m.route("/bar")
mock.requestAnimationFrame.$resolve()
var parent = root.childNodes[0].childNodes[2].childNodes[0]
return parent.nodeValue === "Bob"
})
test(function () {
var root = mock.document.createElement("div")
var redraws = 0
var data
var Comp = {
controller: function () {
this.foo = m.request({method: "GET", url: "/foo"})
},
view: function (ctrl) {
redraws++
data = ctrl.foo()
return m("div")
}
}
var Root = {
view: function () {
return Comp
}
}
m.mount(root, Root)
mock.requestAnimationFrame.$resolve()
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
mock.requestAnimationFrame.$resolve()
m.mount(root, null)
mock.requestAnimationFrame.$resolve()
return redraws === 1 && data.url === "/foo"
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var redraws1 = 0
var redraws2 = 0
var Comp1 = {
controller: function () {
this.foo = m.request({method: "GET", url: "/foo"})
},
view: function () {
redraws1++
return m("div")
}
}
var Comp2 = {
controller: function () {
this.bar = m.request({method: "GET", url: "/bar"})
},
view: function () {
redraws2++
return m("div")
}
}
var Root = {
view: function () {
return m("div", [Comp1, Comp2])
}
}
m.mount(root, Root)
mock.requestAnimationFrame.$resolve()
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
mock.requestAnimationFrame.$resolve()
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
mock.requestAnimationFrame.$resolve()
m.mount(root, null)
mock.requestAnimationFrame.$resolve()
return redraws1 === 1 && redraws2 === 1
})
test(function () {
var root = mock.document.createElement("div")
var redraws1 = 0
var redraws2 = 0
var Comp1 = {
controller: function () {
this.foo = m.request({method: "GET", url: "/foo"})
},
view: function () {
redraws1++
return m("div")
}
}
var Root1 = {
view: function () {
return Comp1
}
}
var Comp2 = {
controller: function () {
this.bar = m.request({method: "GET", url: "/bar"})
},
view: function () {
redraws2++
return m("div")
}
}
var Root2 = {
view: function () {
return Comp2
}
}
m.route(root, "/", {
"/": Root1,
"/root2": Root2
})
mock.requestAnimationFrame.$resolve()
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
m.route("/root2")
mock.requestAnimationFrame.$resolve()
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
mock.requestAnimationFrame.$resolve()
m.mount(root, null)
mock.requestAnimationFrame.$resolve()
return redraws1 === 1 && redraws2 === 1
})
test(function () {
var root = mock.document.createElement("div")
var cond = true
var controller1 = null
var controller2 = null
var Comp1 = {
view: function (ctrl) {
controller1 = ctrl
return m("div")
}
}
var Comp2 = {
view: function (ctrl) {
controller2 = ctrl
return m("div")
}
}
var Root = {
view: function () {
return cond ? Comp1 : Comp2
}
}
m.mount(root, Root)
mock.requestAnimationFrame.$resolve()
cond = false
m.redraw(true)
mock.requestAnimationFrame.$resolve()
return controller1 !== controller2
})
test(function () {
var root = mock.document.createElement("div")
var cond = true
var unloaded = false
var Comp1 = {
view: function () {
return m("div", {
config: function (el, init, ctx) {
ctx.onunload = function () { unloaded = true }
}
})
}
}
var Comp2 = {
view: function () {
return m("div")
}
}
var Root = {
view: function () {
return cond ? Comp1 : Comp2
}
}
m.mount(root, Root)
mock.requestAnimationFrame.$resolve()
cond = false
m.redraw(true)
mock.requestAnimationFrame.$resolve()
return unloaded
})
test(function () {
var root = mock.document.createElement("div")
var cond = true
var initialized = null
var Comp1 = {
view: function () {
return m("div")
}
}
var Comp2 = {
view: function () {
return m("div", {
config: function (el, init) { initialized = init }
})
}
}
var Root = {
view: function () {
return cond ? Comp1 : Comp2
}
}
m.mount(root, Root)
mock.requestAnimationFrame.$resolve()
cond = false
m.redraw(true)
mock.requestAnimationFrame.$resolve()
return initialized === false
})
test(function () {
var root = mock.document.createElement("div")
var el
var BarComponent = {
view: function () {
return m("#bar", "test")
}
}
var FooPage = {
view: function (ctrl) {
return m("div", [
m("button", {
onclick: function () {
ctrl.bar = true
m.redraw(true)
el = root.childNodes[0].childNodes[1]
}
}, "click me"),
ctrl.bar ? m.component(BarComponent) : ""
])
}
}
m.mount(root, FooPage)
root.childNodes[0].childNodes[0].onclick({})
return el.id === "bar"
})
// m.withAttr
test(function () {
// the handler is called with the correct value & context when
// callbackThis not given
var _this = {}
var value, context
var handler = m.withAttr("test", function (data) {
value = data
/* eslint-disable consistent-this, no-invalid-this */
context = this
/* eslint-enable consistent-this, no-invalid-this */
})
handler.call(_this, {currentTarget: {test: "foo"}})
return value === "foo" && context === _this
})
test(function () {
// the handler is called with the correct value & context when
// callbackThis is given
var _this = {}
var value, context
var handler = m.withAttr("test", function (data) {
value = data
/* eslint-disable consistent-this, no-invalid-this */
context = this
/* eslint-enable consistent-this, no-invalid-this */
}, _this)
handler({currentTarget: {test: "foo"}})
return value === "foo" && context === _this
})
// m.trust
test(function () { return m.trust("test").valueOf() === "test" })
// m.render
test(function () {
var root = mock.document.createElement("div")
m.render(root, "test")
return root.childNodes[0].nodeValue === "test"
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", {class: "a"}))
var elementBefore = root.childNodes[0]
m.render(root, m("div", {class: "b"}))
var elementAfter = root.childNodes[0]
return elementBefore === elementAfter
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m(".a"))
var elementBefore = root.childNodes[0]
m.render(root, m(".b"))
var elementAfter = root.childNodes[0]
return elementBefore === elementAfter
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", {id: "a"}))
var elementBefore = root.childNodes[0]
m.render(root, m("div", {title: "b"}))
var elementAfter = root.childNodes[0]
return elementBefore !== elementAfter
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("#a"))
var elementBefore = root.childNodes[0]
m.render(root, m("[title=b]"))
var elementAfter = root.childNodes[0]
return elementBefore !== elementAfter
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("#a"))
var elementBefore = root.childNodes[0]
m.render(root, "test")
var elementAfter = root.childNodes[0]
return elementBefore !== elementAfter
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", [undefined]))
return root.childNodes[0].childNodes[0].nodeValue === ""
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("svg", [m("g")]))
var g = root.childNodes[0].childNodes[0]
return g.nodeName === "G" &&
g.namespaceURI === "http://www.w3.org/2000/svg"
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("svg", [m("a[href='http://google.com']")]))
return root.childNodes[0].childNodes[0].nodeName === "A"
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div.classname", [m("a", {href: "/first"})]))
m.render(root, m("div", [m("a", {href: "/second"})]))
return root.childNodes[0].childNodes.length === 1
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("ul", [m("li")]))
m.render(root, m("ul", [m("li"), undefined]))
return root.childNodes[0].childNodes[1].nodeValue === ""
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("ul", [m("li"), m("li")]))
m.render(root, m("ul", [m("li"), undefined]))
return root.childNodes[0].childNodes[1].nodeValue === ""
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("ul", [m("li")]))
m.render(root, m("ul", [undefined]))
return root.childNodes[0].childNodes[0].nodeValue === ""
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("ul", [m("li")]))
m.render(root, m("ul", [{}]))
return root.childNodes[0].childNodes.length === 0
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("ul", [m("li")]))
m.render(root, m("ul", [{tag: "b", attrs: {}}]))
return root.childNodes[0].childNodes[0].nodeName === "B"
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("ul", [m("li")]))
/* eslint-disable no-new-wrappers */
m.render(root, m("ul", [{tag: new String("b"), attrs: {}}]))
/* eslint-enable no-new-wrappers */
return root.childNodes[0].childNodes[0].nodeName === "B"
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("ul", [m("li", [m("a")])]))
m.render(root, m("ul", [{subtree: "retain"}]))
return root.childNodes[0].childNodes[0].childNodes[0].nodeName === "A"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/43
var root = mock.document.createElement("div")
m.render(root, m("a", {config: m.route}, "test"))
m.render(root, m("a", {config: m.route}, "test"))
return root.childNodes[0].childNodes[0].nodeValue === "test"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/44 (1)
var root = mock.document.createElement("div")
m.render(root, m("#foo", [null, m("#bar")]))
m.render(root, m("#foo", ["test", m("#bar")]))
return root.childNodes[0].childNodes[0].nodeValue === "test"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/44 (2)
var root = mock.document.createElement("div")
m.render(root, m("#foo", [null, m("#bar")]))
m.render(root, m("#foo", [m("div"), m("#bar")]))
return root.childNodes[0].childNodes[0].nodeName === "DIV"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/44 (3)
var root = mock.document.createElement("div")
m.render(root, m("#foo", ["test", m("#bar")]))
m.render(root, m("#foo", [m("div"), m("#bar")]))
return root.childNodes[0].childNodes[0].nodeName === "DIV"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/44 (4)
var root = mock.document.createElement("div")
m.render(root, m("#foo", [m("div"), m("#bar")]))
m.render(root, m("#foo", ["test", m("#bar")]))
return root.childNodes[0].childNodes[0].nodeValue === "test"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/44 (5)
var root = mock.document.createElement("div")
m.render(root, m("#foo", [m("#bar")]))
m.render(root, m("#foo", [m("#bar"), [m("#baz")]]))
return root.childNodes[0].childNodes[1].id === "baz"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/48
var root = mock.document
m.render(root, m("html", [m("#foo")]))
var result = root.childNodes[0].childNodes[0].id === "foo"
root.childNodes = [mock.document.createElement("html")]
return result
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/49
var root = mock.document.createElement("div")
m.render(root, m("a", "test"))
m.render(root, m("a.foo", "test"))
return root.childNodes[0].childNodes[0].nodeValue === "test"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/49
var root = mock.document.createElement("div")
m.render(root, m("a.foo", "test"))
m.render(root, m("a", "test"))
return root.childNodes[0].childNodes[0].nodeValue === "test"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/49
var root = mock.document.createElement("div")
m.render(root, m("a.foo", "test"))
m.render(root, m("a", "test1"))
return root.childNodes[0].childNodes[0].nodeValue === "test1"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/49
var root = mock.document.createElement("div")
m.render(root, m("a", "test"))
m.render(root, m("a", "test1"))
return root.childNodes[0].childNodes[0].nodeValue === "test1"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/50
var root = mock.document.createElement("div")
m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], m("#bar")]))
return root.childNodes[0].childNodes[1].childNodes[0].nodeValue === "b"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/50
var root = mock.document.createElement("div")
m.render(root, m("#foo", [
[m("div", "a"), m("div", "b")],
m("#bar")
]))
m.render(root, m("#foo", [
[m("div", "a"), m("div", "b"), m("div", "c")],
m("#bar")
]))
return root.childNodes[0].childNodes[2].childNodes[0].nodeValue === "c"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/50
var root = mock.document.createElement("div")
m.render(root, m("#foo", [
[m("div", "a"), m("div", "b")],
[m("div", "c"), m("div", "d")],
m("#bar")
]))
var parent = root.childNodes[0]
return parent.childNodes[3].childNodes[0].nodeValue === "d" &&
parent.childNodes[4].id === "bar"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/50
var root = mock.document.createElement("div")
m.render(root, m("#foo", [[m("div", "a"), m("div", "b")], "test"]))
var parent = root.childNodes[0]
return parent.childNodes[1].childNodes[0].nodeValue === "b" &&
parent.childNodes[2].nodeValue === "test"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/50
var root = mock.document.createElement("div")
m.render(root, m("#foo", [["a", "b"], "test"]))
var parent = root.childNodes[0]
return parent.childNodes[1].nodeValue === "b" &&
parent.childNodes[2].nodeValue === "test"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/51
var root = mock.document.createElement("div")
m.render(root, m("main", [
m("button"),
m("article", [m("section"), m("nav")])
]))
m.render(root, m("main", [
m("button"),
m("article", [m("span"), m("nav")])
]))
var node = root.childNodes[0].childNodes[1].childNodes[0]
return node.nodeName === "SPAN"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/51
var root = mock.document.createElement("div")
m.render(root, m("main", [
m("button"),
m("article", [m("section"), m("nav")])
]))
m.render(root, m("main", [
m("button"),
m("article", ["test", m("nav")])
]))
var node = root.childNodes[0].childNodes[1].childNodes[0]
return node.nodeValue === "test"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/51
var root = mock.document.createElement("div")
m.render(root, m("main", [
m("button"),
m("article", [m("section"), m("nav")])
]))
m.render(root, m("main", [
m("button"),
m("article", [m.trust("test"), m("nav")])
]))
var node = root.childNodes[0].childNodes[1].childNodes[0]
return node.nodeValue === "test"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/55
var root = mock.document.createElement("div")
m.render(root, m("#a"))
var elementBefore = root.childNodes[0]
m.render(root, m("#b"))
var elementAfter = root.childNodes[0]
return elementBefore !== elementAfter
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/56
var root = mock.document.createElement("div")
m.render(root, [null, "foo"])
m.render(root, ["bar"])
return root.childNodes.length === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/56
var root = mock.document.createElement("div")
m.render(root, m("div", "foo"))
return root.childNodes.length === 1
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", [m("button"), m("ul")]))
var valueBefore = root.childNodes[0].childNodes[0].nodeName
m.render(root, m("div", [undefined, m("ul")]))
var valueAfter = root.childNodes[0].childNodes[0].nodeValue
return valueBefore === "BUTTON" && valueAfter === ""
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", [m("ul"), undefined]))
var valueBefore1 = root.childNodes[0].childNodes[0].nodeName
var valueBefore2 = root.childNodes[0].childNodes[1].nodeValue
m.render(root, m("div", [undefined, m("ul")]))
var valueAfter1 = root.childNodes[0].childNodes[0].nodeValue
var valueAfter2 = root.childNodes[0].childNodes[1].nodeName
return valueBefore1 === "UL" && valueAfter1 === "" &&
valueBefore2 === "" && valueAfter2 === "UL"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/79
var root = mock.document.createElement("div")
m.render(root, m("div", {style: {background: "red"}}))
var valueBefore = root.childNodes[0].style.background
m.render(root, m("div", {style: {}}))
var valueAfter = root.childNodes[0].style.background
return valueBefore === "red" && valueAfter === ""
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div[style='background:red']"))
return root.childNodes[0].style === "background:red"
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", {style: {background: "red"}}))
var valueBefore = root.childNodes[0].style.background
m.render(root, m("div", {}))
var valueAfter = root.childNodes[0].style.background
return valueBefore === "red" && valueAfter === undefined
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/87
var root = mock.document.createElement("div")
m.render(root, m("div", [[m("a"), m("a")], m("button")]))
m.render(root, m("div", [[m("a")], m("button")]))
return root.childNodes[0].childNodes.length === 2 &&
root.childNodes[0].childNodes[1].nodeName === "BUTTON"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/87
var root = mock.document.createElement("div")
m.render(root, m("div", [m("a"), m("b"), m("button")]))
m.render(root, m("div", [m("a"), m("button")]))
return root.childNodes[0].childNodes.length === 2 &&
root.childNodes[0].childNodes[1].nodeName === "BUTTON"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/99
var root = mock.document.createElement("div")
m.render(root, m("div", [m("img"), m("h1")]))
m.render(root, m("div", [m("a")]))
return root.childNodes[0].childNodes.length === 1 &&
root.childNodes[0].childNodes[0].nodeName === "A"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/120
var root = mock.document.createElement("div")
m.render(root, m("div", ["a", "b", "c", "d"]))
m.render(root, m("div", [["d", "e"]]))
var children = root.childNodes[0].childNodes
return children.length === 2 &&
children[0].nodeValue === "d" &&
children[1].nodeValue === "e"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/120
var root = mock.document.createElement("div")
m.render(root, m("div", [["a", "b", "c", "d"]]))
m.render(root, m("div", ["d", "e"]))
var children = root.childNodes[0].childNodes
return children.length === 2 &&
children[0].nodeValue === "d" &&
children[1].nodeValue === "e"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/120
var root = mock.document.createElement("div")
m.render(root, m("div", ["x", [["a"], "b", "c", "d"]]))
m.render(root, m("div", ["d", ["e"]]))
var children = root.childNodes[0].childNodes
return children.length === 2 &&
children[0].nodeValue === "d" &&
children[1].nodeValue === "e"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/120
var root = mock.document.createElement("div")
m.render(root, m("div", ["b"]))
m.render(root, m("div", [["e"]]))
var children = root.childNodes[0].childNodes
return children.length === 1 && children[0].nodeValue === "e"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/120
var root = mock.document.createElement("div")
m.render(root, m("div", ["a", ["b"]]))
m.render(root, m("div", ["d", [["e"]]]))
var children = root.childNodes[0].childNodes
return children.length === 2 &&
children[0].nodeValue === "d" &&
children[1].nodeValue === "e"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/120
var root = mock.document.createElement("div")
m.render(root, m("div", ["a", [["b"]]]))
m.render(root, m("div", ["d", ["e"]]))
var children = root.childNodes[0].childNodes
return children.length === 2 &&
children[0].nodeValue === "d" &&
children[1].nodeValue === "e"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/120
var root = mock.document.createElement("div")
m.render(root, m("div", ["a", [["b"], "c"]]))
m.render(root, m("div", ["d", [[["e"]], "x"]]))
var children = root.childNodes[0].childNodes
return children.length === 3 &&
children[0].nodeValue === "d" &&
children[1].nodeValue === "e"
})
test(function () {
var root = mock.document.createElement("div")
var success = false
m.render(root, m("div", {
config: function (elem, isInit, ctx) { ctx.data = 1 }
}))
m.render(root, m("div", {
config: function (elem, isInit, ctx) { success = ctx.data === 1 }
}))
return success
})
test(function () {
var root = mock.document.createElement("div")
var index = 0
var success = true
function statefulConfig(elem, isInit, ctx) { ctx.data = index++ }
var node = m("div", {config: statefulConfig})
m.render(root, [node, node])
index = 0
function checkConfig(elem, isInit, ctx) {
success = success && (ctx.data === index++)
}
node = m("div", {config: checkConfig})
m.render(root, [node, node])
return success
})
test(function () {
var root = mock.document.createElement("div")
var parent
m.render(root, m("div", m("a", {
config: function (el) { parent = el.parentNode.parentNode }
})))
return parent === root
})
test(function () {
var root = mock.document.createElement("div")
var count = 0
m.render(root, m("div", m("a", {
config: function () {
var island = mock.document.createElement("div")
count++
if (count > 2) throw new Error("too much recursion...")
m.render(island, m("div"))
}
})))
return count === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/129
var root = mock.document.createElement("div")
m.render(root, m("div", [
["foo", "bar"], ["foo", "bar"], ["foo", "bar"]
]))
m.render(root, m("div", ["asdf", "asdf2", "asdf3"]))
return true
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/98
// insert at beginning
var root = mock.document.createElement("div")
m.render(root, [
m("a", {key: 1}, 1),
m("a", {key: 2}, 2),
m("a", {key: 3}, 3)
])
var firstBefore = root.childNodes[0]
m.render(root, [
m("a", {key: 4}, 4),
m("a", {key: 1}, 1),
m("a", {key: 2}, 2),
m("a", {key: 3}, 3)
])
var firstAfter = root.childNodes[1]
return firstBefore === firstAfter &&
root.childNodes[0].childNodes[0].nodeValue === "4" &&
root.childNodes.length === 4
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/98
var root = mock.document.createElement("div")
m.render(root, [
m("a", {key: 1}, 1),
m("a", {key: 2}, 2),
m("a", {key: 3}, 3)
])
var firstBefore = root.childNodes[0]
m.render(root, [
m("a", {key: 4}, 4),
m("a", {key: 1}, 1),
m("a", {key: 2}, 2)
])
var firstAfter = root.childNodes[1]
return firstBefore === firstAfter &&
root.childNodes[0].childNodes[0].nodeValue === "4" &&
root.childNodes.length === 3
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/98
var root = mock.document.createElement("div")
m.render(root, [
m("a", {key: 1}, 1),
m("a", {key: 2}, 2),
m("a", {key: 3}, 3)
])
var firstBefore = root.childNodes[1]
m.render(root, [
m("a", {key: 2}, 2),
m("a", {key: 3}, 3),
m("a", {key: 4}, 4)
])
var firstAfter = root.childNodes[0]
return firstBefore === firstAfter &&
root.childNodes[0].childNodes[0].nodeValue === "2" &&
root.childNodes.length === 3
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/98
var root = mock.document.createElement("div")
m.render(root, [
m("a", {key: 1}, 1),
m("a", {key: 2}, 2),
m("a", {key: 3}, 3),
m("a", {key: 4}, 4),
m("a", {key: 5}, 5)
])
var firstBefore = root.childNodes[0]
var secondBefore = root.childNodes[1]
var fourthBefore = root.childNodes[3]
m.render(root, [
m("a", {key: 4}, 4),
m("a", {key: 10}, 10),
m("a", {key: 1}, 1),
m("a", {key: 2}, 2)
])
var firstAfter = root.childNodes[2]
var secondAfter = root.childNodes[3]
var fourthAfter = root.childNodes[0]
return firstBefore === firstAfter &&
secondBefore === secondAfter &&
fourthBefore === fourthAfter &&
root.childNodes[1].childNodes[0].nodeValue === "10" &&
root.childNodes.length === 4
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/98
var root = mock.document.createElement("div")
m.render(root, [
m("a", {key: 1}, 1),
m("a", {key: 2}, 2),
m("a", {key: 3}, 3),
m("a", {key: 4}, 4),
m("a", {key: 5}, 5)
])
var firstBefore = root.childNodes[0]
var secondBefore = root.childNodes[1]
var fourthBefore = root.childNodes[3]
m.render(root, [
m("a", {key: 4}, 4),
m("a", {key: 10}, 10),
m("a", {key: 2}, 2),
m("a", {key: 1}, 1),
m("a", {key: 6}, 6),
m("a", {key: 7}, 7)
])
var firstAfter = root.childNodes[3]
var secondAfter = root.childNodes[2]
var fourthAfter = root.childNodes[0]
return firstBefore === firstAfter &&
secondBefore === secondAfter &&
fourthBefore === fourthAfter &&
root.childNodes[1].childNodes[0].nodeValue === "10" &&
root.childNodes[4].childNodes[0].nodeValue === "6" &&
root.childNodes[5].childNodes[0].nodeValue === "7" &&
root.childNodes.length === 6
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/149
var root = mock.document.createElement("div")
m.render(root, [
m("a", {key: 1}),
m("a", {key: 2}),
m("a"),
m("a", {key: 4}),
m("a", {key: 5})
])
var firstBefore = root.childNodes[0]
var secondBefore = root.childNodes[1]
var thirdBefore = root.childNodes[2]
var fourthBefore = root.childNodes[3]
var fifthBefore = root.childNodes[4]
m.render(root, [
m("a", {key: 4}),
m("a", {key: 5}),
m("a"),
m("a", {key: 1}),
m("a", {key: 2})
])
var firstAfter = root.childNodes[3]
var secondAfter = root.childNodes[4]
var thirdAfter = root.childNodes[2]
var fourthAfter = root.childNodes[0]
var fifthAfter = root.childNodes[1]
return firstBefore === firstAfter &&
secondBefore === secondAfter &&
thirdBefore === thirdAfter &&
fourthBefore === fourthAfter &&
fifthBefore === fifthAfter
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/246
// insert at beginning with non-keyed in the middle
var root = mock.document.createElement("div")
m.render(root, [m("a", {key: 1}, 1)])
var firstBefore = root.childNodes[0]
m.render(root, [
m("a", {key: 2}, 2),
m("br"),
m("a", {key: 1}, 1)
])
var firstAfter = root.childNodes[2]
return firstBefore === firstAfter &&
root.childNodes[0].childNodes[0].nodeValue === "2" &&
root.childNodes.length === 3
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/134
var root = mock.document.createElement("div")
m.render(root, m("div", {contenteditable: true}, "test"))
mock.document.activeElement = root.childNodes[0]
m.render(root, m("div", {contenteditable: true}, "test1"))
m.render(root, m("div", {contenteditable: false}, "test2"))
return root.childNodes[0].childNodes[0].nodeValue === "test2"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/136
var root = mock.document.createElement("div")
m.render(root, m("textarea", ["test"]))
m.render(root, m("textarea", ["test1"]))
return root.childNodes[0].value === "test1"
})
test(function () {
var root = mock.document.createElement("div")
var unloaded = 0
m.render(root, [
m("div", {
key: 1,
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
])
m.render(root, [
m("div", {key: 2}),
m("div", {
key: 1,
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
])
return unloaded === 0
})
test(function () {
var root = mock.document.createElement("div")
var unloadedParent = 0
var unloadedChild = 0
function configParent(el, init, ctx) {
ctx.onunload = function () {
unloadedParent++
}
}
function configChild(el, init, ctx) {
ctx.onunload = function () {
unloadedChild++
}
}
m.render(root, m("div", {config: configParent}, [
m("a", {config: configChild})
]))
m.render(root, m("main", {config: configParent}, [
m("a", {config: configChild})
]))
return unloadedParent === 1 && unloadedChild === 0
})
test(function () {
var root = mock.document.createElement("div")
var unloadedParent = 0
var unloadedChild = 0
function configParent(el, init, ctx) {
ctx.onunload = function () {
unloadedParent++
}
}
function configChild(el, init, ctx) {
ctx.onunload = function () {
unloadedChild++
}
}
m.render(root, m("div", {config: configParent}, [
m("a", {config: configChild})
]))
m.render(root, m("main", {config: configParent}, [
m("b", {config: configChild})
]))
return unloadedParent === 1 && unloadedChild === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/150
var root = mock.document.createElement("div")
m.render(root, [m("a"), m("div")])
m.render(root, [[], m("div")])
return root.childNodes.length === 1 &&
root.childNodes[0].nodeName === "DIV"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/156
var root = mock.document.createElement("div")
m.render(root, m("div", [
["a", "b", "c", "d"].map(function () {
return [m("div"), " "]
}),
m("span")
]))
return root.childNodes[0].childNodes[8].nodeName === "SPAN"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/157
var root = mock.document.createElement("div")
m.render(root, m("ul", [
m("li", {key: 0}, 0),
m("li", {key: 2}, 2),
m("li", {key: 4}, 4)
]))
m.render(root, m("ul", [
m("li", {key: 0}, 0),
m("li", {key: 1}, 1),
m("li", {key: 2}, 2),
m("li", {key: 3}, 3),
m("li", {key: 4}, 4),
m("li", {key: 5}, 5)
]))
return root.childNodes[0].childNodes.map(function (n) {
return n.childNodes[0].nodeValue
}).join("") === "012345"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/157
var root = mock.document.createElement("div")
m.render(root, m("input", {value: "a"}))
m.render(root, m("input", {value: "aa"}))
return root.childNodes[0].childNodes.length === 0
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/157
var root = mock.document.createElement("div")
m.render(root, m("br", {class: "a"}))
m.render(root, m("br", {class: "aa"}))
return root.childNodes[0].childNodes.length === 0
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/194
var root = mock.document.createElement("div")
m.render(root, m("ul", [
m("li", {key: 0}, 0),
m("li", {key: 1}, 1),
m("li", {key: 2}, 2),
m("li", {key: 3}, 3),
m("li", {key: 4}, 4),
m("li", {key: 5}, 5)
]))
m.render(root, m("ul", [
m("li", {key: 0}, 0),
m("li", {key: 1}, 1),
m("li", {key: 2}, 2),
m("li", {key: 4}, 4),
m("li", {key: 5}, 5)
]))
return root.childNodes[0].childNodes.map(function (n) {
return n.childNodes[0].nodeValue
}).join("") === "01245"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/194
var root = mock.document.createElement("div")
m.render(root, m("ul", [
m("li", {key: 0}, 0),
m("li", {key: 1}, 1),
m("li", {key: 2}, 2),
m("li", {key: 3}, 3),
m("li", {key: 4}, 4),
m("li", {key: 5}, 5)
]))
m.render(root, m("ul", [
m("li", {key: 1}, 1),
m("li", {key: 2}, 2),
m("li", {key: 3}, 3),
m("li", {key: 4}, 4),
m("li", {key: 5}, 5),
m("li", {key: 6}, 6)
]))
m.render(root, m("ul", [
m("li", {key: 12}, 12),
m("li", {key: 13}, 13),
m("li", {key: 14}, 14),
m("li", {key: 15}, 15),
m("li", {key: 16}, 16),
m("li", {key: 17}, 17)
]))
return root.childNodes[0].childNodes.map(function (n) {
return n.childNodes[0].nodeValue
}).join(",") === "12,13,14,15,16,17"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/206
var root = mock.document.createElement("div")
m.render(root, m("div", undefined))
m.render(root, m("div", [m("div")]))
return root.childNodes[0].childNodes.length === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/206
var root = mock.document.createElement("div")
m.render(root, m("div", null))
m.render(root, m("div", [m("div")]))
return root.childNodes[0].childNodes.length === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/200
var root = mock.document.createElement("div")
var unloaded1 = false
function unloadable1(element, isInit, context) {
context.onunload = function () {
unloaded1 = true
}
}
m.render(root, [m("div", {config: unloadable1})])
m.render(root, [])
var unloaded2 = false
function unloadable2(element, isInit, context) {
context.onunload = function () {
unloaded2 = true
}
}
m.render(root, [m("div", {config: unloadable2})])
m.render(root, [])
return unloaded1 === true && unloaded2 === true
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, [m("div.blue")])
m.render(root, [m("div.green", [m("div")]), m("div.blue")])
return root.childNodes.length === 2
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/277
var root = mock.document.createElement("div")
function Field() {
this.tag = "div"
this.attrs = {}
this.children = "hello"
}
m.render(root, new Field())
return root.childNodes.length === 1
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, {foo: 123})
return root.childNodes.length === 0
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/299
var root = mock.document.createElement("div")
m.render(root, m("div", [
m("div", {key: 1}, 1),
m("div", {key: 2}, 2),
m("div", {key: 3}, 3),
m("div", {key: 4}, 4),
m("div", {key: 5}, 5),
null, null, null, null, null, null, null, null, null, null
]))
m.render(root, m("div", [
null, null,
m("div", {key: 3}, 3),
null, null,
m("div", {key: 6}, 6),
null, null,
m("div", {key: 9}, 9),
null, null,
m("div", {key: 12}, 12),
null, null,
m("div", {key: 15}, 15)
]))
m.render(root, m("div", [
m("div", {key: 1}, 1),
m("div", {key: 2}, 2),
m("div", {key: 3}, 3),
m("div", {key: 4}, 4),
m("div", {key: 5}, 5),
null, null, null, null, null, null, null, null, null, null
]))
return root.childNodes[0].childNodes.map(function (c) {
return c.childNodes ? c.childNodes[0].nodeValue : c.nodeValue
}).slice(0, 5).join("") === "12345"
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/377
var root = mock.document.createElement("div")
m.render(root, m("div", [
m("div", 1),
m("div", 2), [m("div", {key: 3}, 3),
m("div", {key: 4}, 4),
m("div", {key: 5}, 5)],
[m("div", {key: 6}, 6)]
]))
m.render(root, m("div", [
m("div", 1),
null,
[m("div", {key: 3}, 3),
m("div", {key: 4}, 4),
m("div", {key: 5}, 5)],
[m("div", {key: 6}, 6)]
]))
return root.childNodes[0].childNodes.map(function (c) {
return c.childNodes ? c.childNodes[0].nodeValue : c.nodeValue
}).join("") === "13456"
})
test(function () {
// don't throw rendering console.log in Firefox
var root = mock.document.createElement("div")
/* eslint-disable no-console */
m.render(root, m("div", [console.log()]))
/* eslint-enable no-console */
return true
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, [
m("#div-1", {key: 1}),
m("#div-2", {key: 2}),
m("#div-3", {key: 3})
])
root.appendChild(root.childNodes[1])
m.render(root, [
m("#div-1", {key: 1}),
m("#div-3", {key: 3}),
m("#div-2", {key: 2})
])
return root.childNodes.map(function (node) {
return node.id
}).join() === "div-1,div-3,div-2"
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", function () {}))
return root.childNodes[0].childNodes.length === 0
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", "foo", m("a")))
m.render(root, m("div", "test"))
return root.childNodes[0].childNodes.length === 1
})
test(function () {
// if an element is preceded by a conditional, it should not lose its
// identity
var root = mock.document.createElement("div")
m.render(root, m("div", [m("a"), m("input[autofocus]")]))
var before = root.childNodes[0].childNodes[1]
m.render(root, m("div", [undefined, m("input[autofocus]")]))
var after = root.childNodes[0].childNodes[1]
return before === after
})
test(function () {
// unkeyed element should maintain identity if mixed w/ keyed elements
// and identity can be inferred
var root = mock.document.createElement("div")
m.render(root, m("div", [
m("a", {key: 1}),
m("a", {key: 2}),
m("a", {key: 3}),
m("i")
]))
var before = root.childNodes[0].childNodes[3]
m.render(root, m("div", [
m("b", {key: 3}),
m("b", {key: 4}),
m("i"),
m("b", {key: 1})
]))
var after = root.childNodes[0].childNodes[2]
return before === after
})
test(function () {
// unkeyed element should maintain identity if mixed w/ keyed elements
// and text nodes and identity can be inferred
var root = mock.document.createElement("div")
m.render(root, m("div", [
m("a", {key: 1}),
m("a", {key: 2}),
"foo",
m("a", {key: 3}),
m("i")
]))
var before = root.childNodes[0].childNodes[4]
m.render(root, m("div", [
m("a", {key: 3}),
m("a", {key: 4}),
"bar",
m("i"),
m("a", {key: 1})
]))
var after = root.childNodes[0].childNodes[3]
return before === after
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", [
m("a", {key: 1}),
m("a", {key: 2}),
null,
m("a", {key: 3}),
m("i")
]))
var before = root.childNodes[0].childNodes[4]
m.render(root, m("div", [
m("a", {key: 3}),
m("a", {key: 4}),
null,
m("i"),
m("a", {key: 1})
]))
var after = root.childNodes[0].childNodes[3]
return before === after
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", [
m("a", {key: 1}),
m("a", {key: 2}),
undefined,
m("a", {key: 3}),
m("i")
]))
var before = root.childNodes[0].childNodes[4]
m.render(root, m("div", [
m("a", {key: 3}),
m("a", {key: 4}),
undefined,
m("i"),
m("a", {key: 1})
]))
var after = root.childNodes[0].childNodes[3]
return before === after
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m("div", [
m("a", {key: 1}),
m("a", {key: 2}),
m.trust("a"),
m("a", {key: 3}),
m("i")
]))
var before = root.childNodes[0].childNodes[4]
m.render(root, m("div", [
m("a", {key: 3}),
m("a", {key: 4}),
m.trust("a"),
m("i"),
m("a", {key: 1})
]))
var after = root.childNodes[0].childNodes[3]
return before === after
})
test(function () {
var root = mock.document.createElement("div")
var vdom = m("div.a", {class: undefined})
m.render(root, vdom)
return root.childNodes[0].class === "a"
})
test(function () {
var root = mock.document.createElement("div")
m.render(root, m(".a", [1]))
m.render(root, m(".a", []))
return root.childNodes[0].childNodes.length === 0
})
// end m.render
// m.redraw
test(function () {
mock.requestAnimationFrame.$resolve() // setup
var controller
var root = mock.document.createElement("div")
m.mount(root, {
controller: function () {
/* eslint-disable consistent-this, no-invalid-this */
controller = this
/* eslint-enable consistent-this, no-invalid-this */
},
view: function (ctrl) { return ctrl.value }
})
mock.requestAnimationFrame.$resolve()
var valueBefore = root.childNodes[0].nodeValue
controller.value = "foo"
m.redraw()
mock.requestAnimationFrame.$resolve()
return valueBefore === "" && root.childNodes[0].nodeValue === "foo"
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
var count = 0
var root = mock.document.createElement("div")
m.mount(root, {
controller: function () {},
view: function () { count++ }
})
mock.requestAnimationFrame.$resolve() // teardown
m.redraw() // should run synchronously
m.redraw() // rest should run asynchronously since they're spamming
m.redraw()
m.redraw()
mock.requestAnimationFrame.$resolve() // teardown
return count === 3
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
var count = 0
var root = mock.document.createElement("div")
m.mount(root, {
controller: function () {},
view: function () {
count++
}
})
mock.requestAnimationFrame.$resolve() // teardown
m.redraw(true) // should run synchronously
m.redraw(true) // forced to run synchronously
m.redraw(true)
m.redraw(true)
mock.requestAnimationFrame.$resolve() // teardown
return count === 5
})
// m.route
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/test1", {
"/test1": {
controller: function () {},
view: function () { return "foo" }
}
})
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test1" &&
root.childNodes[0].nodeValue === "foo"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.pathname = "/"
var root = mock.document.createElement("div")
m.route.mode = "pathname"
m.route(root, "/test2", {
"/test2": {
controller: function () {},
view: function () {
return [
"foo",
m("a", {href: "/test2", config: m.route}, "Test2")
]
}
}
})
mock.requestAnimationFrame.$resolve()
var result = mock.location.pathname === "/test2" &&
root.childNodes[0].nodeValue === "foo" &&
root.childNodes[1].href === "/test2"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.hash = "#"
var root = mock.document.createElement("div")
m.route.mode = "hash"
m.route(root, "/test3", {
"/test3": {
controller: function () {},
view: function () { return "foo" }
}
})
mock.requestAnimationFrame.$resolve()
var result = mock.location.hash === "#/test3" &&
root.childNodes[0].nodeValue === "foo"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/test4/foo", {
"/test4/:test": {
controller: function () {},
view: function () { return m.route.param("test") }
}
})
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test4/foo" &&
root.childNodes[0].nodeValue === "foo"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var component = {
controller: function () {},
view: function () { return m.route.param("test") }
}
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/test5/foo", {
"/": component,
"/test5/:test": component
})
var paramValueBefore = m.route.param("test")
mock.requestAnimationFrame.$resolve()
m.route("/")
var paramValueAfter = m.route.param("test")
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/" &&
paramValueBefore === "foo" &&
paramValueAfter === undefined
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var component = {
controller: function () {},
view: function () { return m.route.param("a1") }
}
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/test6/foo", {
"/": component,
"/test6/:a1": component
})
var paramValueBefore = m.route.param("a1")
mock.requestAnimationFrame.$resolve()
m.route("/")
var paramValueAfter = m.route.param("a1")
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/" &&
paramValueBefore === "foo" &&
paramValueAfter === undefined
m.mount(root, null) // teardown
return result
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/61
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var component = {
controller: function () {},
view: function () { return m.route.param("a1") }
}
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/test7/foo", {
"/": component,
"/test7/:a1": component
})
var routeValueBefore = m.route()
mock.requestAnimationFrame.$resolve()
m.route("/")
var routeValueAfter = m.route()
mock.requestAnimationFrame.$resolve()
var result = routeValueBefore === "/test7/foo" &&
routeValueAfter === "/"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/test8/foo/SEP/bar/baz", {
"/test8/:test/SEP/:path...": {
controller: function () {},
view: function () {
return m.route.param("test") + "_" + m.route.param("path")
}
}
})
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test8/foo/SEP/bar/baz" &&
root.childNodes[0].nodeValue === "foo_bar/baz"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/test9/foo/bar/SEP/baz", {
"/test9/:test.../SEP/:path": {
controller: function () {},
view: function () {
return m.route.param("test") + "_" + m.route.param("path")
}
}
})
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test9/foo/bar/SEP/baz" &&
root.childNodes[0].nodeValue === "foo/bar_baz"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/test10/foo%20bar", {
"/test10/:test": {
controller: function () {},
view: function () {
return m.route.param("test")
}
}
})
mock.requestAnimationFrame.$resolve()
var result = root.childNodes[0].nodeValue === "foo bar"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () { return "foo" }
},
"/test11": {
controller: function () {},
view: function () { return "bar" }
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test11/")
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test11/" &&
root.childNodes[0].nodeValue === "bar"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/", {
"/": {controller: function () {}, view: function () {}},
"/test12": {controller: function () {}, view: function () {}}
})
mock.requestAnimationFrame.$resolve()
m.route("/test12?a=foo&b=bar")
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test12?a=foo&b=bar" &&
m.route.param("a") === "foo" &&
m.route.param("b") === "bar"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () { return "bar" }
},
"/test13/:test": {
controller: function () {},
view: function () { return m.route.param("test") }
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test13/foo?test=bar")
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test13/foo?test=bar" &&
root.childNodes[0].nodeValue === "foo"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () { return "bar" }
},
"/test14": {
controller: function () {},
view: function () { return "foo" }
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test14?test&test2=")
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test14?test&test2=" &&
m.route.param("test") == null &&
m.route.param("test2") === ""
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/", {
"/": {controller: function () {}, view: function () {}},
"/test12": {controller: function () {}, view: function () {}}
})
mock.requestAnimationFrame.$resolve()
m.route("/test12", {a: "foo", b: "bar"})
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test12?a=foo&b=bar" &&
m.route.param("a") === "foo" &&
m.route.param("b") === "bar"
m.mount(root, null) // teardown
return result
})
test(function () {
// test route params returning params object if no key is given
mock.requestAnimationFrame.$resolve() // setup
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/", {
"/": {controller: function () {}, view: function () {}},
"/test12": {controller: function () {}, view: function () {}}
})
mock.requestAnimationFrame.$resolve()
m.route("/test12", {a: "foo", b: "bar"})
mock.requestAnimationFrame.$resolve()
var params = m.route.param()
var result = params.a === "foo" && params.b === "bar"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var route1, route2
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () { route1 = m.route() },
view: function () {}
},
"/test13": {
controller: function () { route2 = m.route() },
view: function () {}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test13")
mock.requestAnimationFrame.$resolve()
var result = route1 === "/" && route2 === "/test13"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var unloaded = 0
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () {
return m("div", {
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
}
},
"/test14": {controller: function () {}, view: function () {}}
})
mock.requestAnimationFrame.$resolve()
m.route("/test14")
mock.requestAnimationFrame.$resolve()
var result = unloaded === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var unloaded = 0
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () {
return [
m("div"),
m("div", {
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
]
}
},
"/test15": {
controller: function () {},
view: function () {
return [m("div")]
}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test15")
mock.requestAnimationFrame.$resolve()
var result = unloaded === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var unloaded = 0
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () {
return m("div", {
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
}
},
"/test16": {
controller: function () {},
view: function () {
return m("a")
}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test16")
mock.requestAnimationFrame.$resolve()
var result = unloaded === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var unloaded = 0
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () {
return [
m("div", {
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
]
}
},
"/test17": {
controller: function () {},
view: function () {
return m("a")
}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test17")
mock.requestAnimationFrame.$resolve()
var result = unloaded === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var unloaded = 0
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () {
return m("div", {
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
}
},
"/test18": {
controller: function () {},
view: function () {
return [m("a")]
}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test18")
mock.requestAnimationFrame.$resolve()
var result = unloaded === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var unloaded = 0
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () {
return [
m("div", {
key: 1,
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
]
}
},
"/test20": {
controller: function () {},
view: function () {
return [
m("div", {
key: 2,
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
]
}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test20")
mock.requestAnimationFrame.$resolve()
var result = unloaded === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var unloaded = 0
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () {
return [
m("div", {
key: 1,
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
]
}
},
"/test21": {
controller: function () {},
view: function () {
return [
m("div", {
config: function (el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
})
]
}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/test21")
mock.requestAnimationFrame.$resolve()
var result = unloaded === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/foo", {
"/foo": {
controller: function () {},
view: function () {
return m("div", "foo")
}
},
"/bar": {
controller: function () {},
view: function () {
return m("div", "bar")
}
}
})
mock.requestAnimationFrame.$resolve()
var foo = root.childNodes[0].childNodes[0].nodeValue
m.route("/bar")
mock.requestAnimationFrame.$resolve()
var bar = root.childNodes[0].childNodes[0].nodeValue
var result = (foo === "foo" && bar === "bar")
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var unloaded = 0
function config(el, init, ctx) {
ctx.onunload = function () {
unloaded++
}
}
m.route.mode = "search"
m.route(root, "/foo1", {
"/foo1": {
controller: function () {},
view: function () {
return m("div", m("a", {config: config}, "foo"))
}
},
"/bar1": {
controller: function () {},
view: function () {
return m("main", m("a", {config: config}, "foo"))
}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/bar1")
mock.requestAnimationFrame.$resolve()
var result = unloaded === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var strategy
m.route.mode = "search"
m.route(root, "/foo1", {
"/foo1": {
controller: function () {
strategy = m.redraw.strategy()
m.redraw.strategy("none")
},
view: function () {
return m("div")
}
}
})
mock.requestAnimationFrame.$resolve()
var result = strategy === "all" && root.childNodes.length === 0
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var count = 0
var strategy
function config(el, init) { if (!init) count++ }
m.route.mode = "search"
m.route(root, "/foo1", {
"/foo1": {
controller: function () {},
view: function () {
return m("div", {config: config})
}
},
"/bar1": {
controller: function () {
strategy = m.redraw.strategy()
m.redraw.strategy("redraw")
},
view: function () {
return m("div", {config: config})
}
}
})
mock.requestAnimationFrame.$resolve()
m.route("/bar1")
mock.requestAnimationFrame.$resolve()
var result = strategy === "all" && count === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var strategy
m.route.mode = "search"
m.route(root, "/foo1", {
"/foo1": {
controller: function () { this.number = 1 },
view: function (ctrl) {
return m("div", {onclick: function () {
strategy = m.redraw.strategy()
ctrl.number++
m.redraw.strategy("none")
}}, ctrl.number)
}
}
})
root.childNodes[0].onclick({})
mock.requestAnimationFrame.$resolve()
var result = strategy === "diff" &&
root.childNodes[0].childNodes[0].nodeValue === "1"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var count = 0
function config(el, init) { if (!init) count++ }
m.route.mode = "search"
m.route(root, "/foo1", {
"/foo1": {
controller: function () {},
view: function () {
return m("div", {
config: config,
onclick: function () {
m.redraw.strategy("all")
}
})
}
}
})
root.childNodes[0].onclick({})
mock.requestAnimationFrame.$resolve()
var result = count === 2
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var value
m.route(root, "/foo+bar", {
"/:arg": {
controller: function () { value = m.route.param("arg") },
view: function () {
return ""
}
}
})
var result = value === "foo+bar"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () { return "foo" }
},
"/test22": {
controller: function () {},
view: function () { return "bar" }
}
})
mock.requestAnimationFrame.$resolve()
m.route(String("/test22/"))
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test22/" &&
root.childNodes[0].nodeValue === "bar"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
m.route.mode = "search"
m.route(root, "/", {
"/": {
controller: function () {},
view: function () { return "foo" }
},
"/test23": {
controller: function () {},
view: function () { return "bar" }
}
})
mock.requestAnimationFrame.$resolve()
m.route(new String("/test23/")) // eslint-disable-line no-new-wrappers
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/test23/" &&
root.childNodes[0].nodeValue === "bar"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
var value
m.route(root, String("/foo+bar"), {
"/:arg": {
controller: function () { value = m.route.param("arg") },
view: function () { return "" }
}
})
var result = value === "foo+bar"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve() // setup
mock.location.search = "?"
var root = mock.document.createElement("div")
/* eslint-disable no-new-wrappers */
var initial = new String("/foo+bar")
/* eslint-enable no-new-wrappers */
var value
m.route(root, initial, {
"/:arg": {
controller: function () { value = m.route.param("arg") },
view: function () {
return ""
}
}
})
var result = value === "foo+bar"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var a = {}
a.controller = function () { m.route("/b") }
a.view = function () { return "a" }
var b = {}
b.controller = function () {}
b.view = function () { return "b" }
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
var result = root.childNodes[0].nodeValue === "b"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var a = {}
a.controller = function () {
m.route("/b?foo=1", {foo: 2})
}
a.view = function () { return "a" }
var b = {}
b.controller = function () {}
b.view = function () { return "b" }
m.route(root, "/", {
"/": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
var result = mock.location.search === "?/b?foo=2"
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
mock.history.$$length = 0
var root = mock.document.createElement("div")
var a = {}
a.controller = function () {}
a.view = function () { return "a" }
var b = {}
b.controller = function () {}
b.view = function () { return "b" }
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = mock.history.$$length === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
mock.history.$$length = 0
var root = mock.document.createElement("div")
var a = {}
a.controller = function () {}
a.view = function () { return "a" }
var b = {}
b.controller = function () {}
b.view = function () { return "b" }
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/a")
mock.requestAnimationFrame.$resolve()
var result = mock.history.$$length === 0
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () {}
a.view = function () {
return m("a", {config: function (el, init) {
if (!init) initCount++
}})
}
var b = {}
b.controller = function () {}
b.view = a.view
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 2
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () {}
a.view = function () {
return m("a", {config: function (el, init, ctx) {
ctx.retain = false
if (!init) initCount++
}})
}
var b = {}
b.controller = function () {}
b.view = a.view
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 2
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () {}
a.view = function () {
return m("a", {config: function (el, init, ctx) {
ctx.retain = true
if (!init) initCount++
}})
}
var b = {}
b.controller = function () {}
b.view = a.view
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () { m.redraw.strategy("diff") }
a.view = function () {
return m("a", {config: function (el, init) {
if (!init) initCount++
}})
}
var b = {}
b.controller = function () { m.redraw.strategy("diff") }
b.view = a.view
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () { m.redraw.strategy("diff") }
a.view = function () {
return m("a", {config: function (el, init, ctx) {
ctx.retain = true
if (!init) initCount++
}})
}
var b = {}
b.controller = function () { m.redraw.strategy("diff") }
b.view = a.view
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () { m.redraw.strategy("diff") }
a.view = function () {
return m("a", {config: function (el, init, ctx) {
ctx.retain = false
if (!init) initCount++
}})
}
var b = {}
b.controller = function () { m.redraw.strategy("diff") }
b.view = a.view
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 2
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () {}
a.view = function () {
return m("div", m("a", {config: function (el, init, ctx) {
ctx.retain = true
if (!init) initCount++
}}))
}
var b = {}
b.controller = function () {}
b.view = function () {
return m("section", m("a", {config: function (el, init, ctx) {
ctx.retain = true
if (!init) initCount++
}}))
}
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () {}
a.view = function () {
return m("div", m("a", {config: function (el, init, ctx) {
ctx.retain = false
if (!init) initCount++
}}))
}
var b = {}
b.controller = function () {}
b.view = function () {
return m("section", m("a", {config: function (el, init, ctx) {
ctx.retain = false
if (!init) initCount++
}}))
}
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 2
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () {}
a.view = function () {
return m("div", m("a", {config: function (el, init) {
if (!init) initCount++
}}))
}
var b = {}
b.controller = function () {}
b.view = function () {
return m("section", m("a", {config: function (el, init) {
if (!init) initCount++
}}))
}
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 2
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () { m.redraw.strategy("diff") }
a.view = function () {
return m("div", m("a", {config: function (el, init, ctx) {
ctx.retain = true
if (!init) initCount++
}}))
}
var b = {}
b.controller = function () { m.redraw.strategy("diff") }
b.view = function () {
return m("section", m("a", {config: function (el, init, ctx) {
ctx.retain = true
if (!init) initCount++
}}))
}
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 1
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () { m.redraw.strategy("diff") }
a.view = function () {
return m("div", m("a", {config: function (el, init, ctx) {
ctx.retain = false
if (!init) initCount++
}}))
}
var b = {}
b.controller = function () { m.redraw.strategy("diff") }
b.view = function () {
return m("section", m("a", {config: function (el, init, ctx) {
ctx.retain = false
if (!init) initCount++
}}))
}
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 2
m.mount(root, null) // teardown
return result
})
test(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () { m.redraw.strategy("diff") }
a.view = function () {
return m("div", m("a", {config: function (el, init) {
if (!init) initCount++
}}))
}
var b = {}
b.controller = function () { m.redraw.strategy("diff") }
b.view = function () {
return m("section", m("a", {config: function (el, init) {
if (!init) initCount++
}}))
}
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 1
m.mount(root, null) // teardown
return result
})
test(function () {
// retain flag should work inside component
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var initCount = 0
var a = {}
a.controller = function () {}
a.view = function () {
return m("div", m("a", {config: function (el, init, ctx) {
ctx.retain = true
if (!init) initCount++
}}))
}
var b = {}
b.controller = function () { m.redraw.strategy("diff") }
b.view = function () {
return m("section", m("a", {config: function (el, init, ctx) {
ctx.retain = true
if (!init) initCount++
}}))
}
m.route(root, "/a", {
"/a": {view: function () { return m("div", a) }},
"/b": {view: function () { return m("div", b) }}
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = initCount === 1
m.mount(root, null) // teardown
return result
})
test(function () {
// https://github.com/lhorie/mithril.js/pull/571
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
var root = mock.document.createElement("div")
var a = {}
a.controller = function () {}
a.view = function () {
return m("div", {config: function (elm) {
elm.childNodes[0].modified = true
}}, m("div"))
}
var b = {}
b.controller = function () {}
b.view = function () {
return m("div", m("div"))
}
m.route(root, "/a", {
"/a": a,
"/b": b
})
mock.requestAnimationFrame.$resolve()
m.route("/b")
mock.requestAnimationFrame.$resolve()
var result = !root.childNodes[0].childNodes[0].modified
m.mount(root, null) // teardown
return result
})
// end m.route
// m.route.parseQueryString
test(function () {
var str = "foo=bar&hello%5B%5D=world&hello%5B%5D=mars&hello%5B%5D=pluto"
var args = m.route.parseQueryString(str)
return args["hello[]"] instanceof Array &&
args["hello[]"].indexOf("world") > -1 &&
args["hello[]"].indexOf("mars") > -1 &&
args["hello[]"].indexOf("pluto") > -1
})
test(function () {
var str = "foo=bar&hello=world&hello=mars&bam=&yup"
var args = m.route.parseQueryString(str)
return args.foo === "bar" &&
args.hello[0] === "world" &&
args.hello[1] === "mars" &&
args.bam === "" &&
args.yup == null
})
test(function () {
var args = m.route.parseQueryString("")
return Object.keys(args).length === 0
})
// m.route.buildQueryString
test(function () {
var string = m.route.buildQueryString({
foo: "bar",
hello: ["world", "mars", "mars"],
world: {
test: 3
},
bam: "",
yup: null,
removed: undefined
})
var expected = "foo=bar&hello=world&hello=mars&" +
"world%5Btest%5D=3&bam=&yup"
return string === expected
})
test(function () {
var string = m.route.buildQueryString({})
return string === ""
})
// m.prop
test(function () {
var prop = m.prop("test")
return prop() === "test"
})
test(function () {
var prop = m.prop("test")
prop("foo")
return prop() === "foo"
})
test(function () {
var prop = m.prop("test")
return JSON.stringify(prop) === '"test"'
})
test(function () {
var obj = {prop: m.prop("test")}
return JSON.stringify(obj) === '{"prop":"test"}'
})
test(function () {
var defer = m.deferred()
var prop = m.prop(defer.promise)
defer.resolve("test")
return prop() === "test"
})
test(function () {
var defer = m.deferred()
var prop = m.prop(defer.promise).then(function () {
return "test2"
})
defer.resolve("test")
return prop() === "test2"
})
test(function () {
var prop = m.prop(null)
return prop() === null
})
// m.request
test(function () {
var prop = m.request({method: "GET", url: "test"})
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop().method === "GET" && prop().url === "test"
})
test(function () {
var prop = m.request({method: "GET", url: "test"})
.then(function () { return "foo" })
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop() === "foo"
})
test(function () {
var prop = m.request({
method: "POST", url: "http://domain.com:80",
data: {}
}).then(function (value) { return value })
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop().url === "http://domain.com:80"
})
test(function () {
var prop = m.request({
method: "POST",
url: "http://domain.com:80/:test1",
data: {test1: "foo"}
}).then(function (value) { return value })
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop().url === "http://domain.com:80/foo"
})
test(function () {
var error = m.prop("no error")
var prop = m.request({
method: "GET",
url: "test",
deserialize: function () { throw new Error("error occurred") }
}).then(null, error)
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop().message === "error occurred" &&
error().message === "error occurred"
})
test(function () {
var error = m.prop("no error")
var prop = m.request({
method: "GET",
url: "test",
deserialize: function () { throw new Error("error occurred") }
}).catch(error)
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop().message === "error occurred" &&
error().message === "error occurred"
})
test(function () {
var error = m.prop("no error")
var exception
var prop = m.request({
method: "GET",
url: "test",
deserialize: function () { throw new TypeError("error occurred") }
}).then(null, error)
try {
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
} catch (e) {
exception = e
}
return prop() === undefined &&
error() === "no error" &&
exception.message === "error occurred"
})
test(function () {
var error = m.prop("no error")
m.request({method: "POST", url: "test", data: {foo: 1}})
.then(null, error)
var xhr = mock.XMLHttpRequest.$instances.pop()
xhr.onreadystatechange()
var expected = "application/json; charset=utf-8"
return xhr.$headers["Content-Type"] === expected
})
test(function () {
var error = m.prop("no error")
m.request({method: "POST", url: "test"}).then(null, error)
var xhr = mock.XMLHttpRequest.$instances.pop()
xhr.onreadystatechange()
return xhr.$headers["Content-Type"] === undefined
})
test(function () {
var prop = m.request({method: "POST", url: "test", initialValue: "foo"})
.then(function (data) { return data })
var initialValue = prop()
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return initialValue === "foo"
})
test(function () {
var prop = m.request({method: "POST", url: "test", initialValue: "foo"})
var initialValue = prop()
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return initialValue === "foo"
})
test(function () {
var prop = m.request({method: "POST", url: "test", initialValue: "foo"})
.then(function () { return "bar" })
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop() === "bar"
})
test(function () {
var prop = m.request({method: "GET", url: "test", data: {foo: 1}})
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop().url === "test?foo=1"
})
test(function () {
var prop = m.request({method: "POST", url: "test", data: {foo: 1}})
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop().url === "test"
})
test(function () {
var prop = m.request({method: "GET", url: "test", data: {foo: [1, 2]}})
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return prop().url === "test?foo=1&foo=2"
})
test(function () {
var value
var prop1 = m.request({method: "GET", url: "test", initialValue: 123})
var val1 = prop1()
var prop2 = prop1.then(function () { return 1 })
var val2 = prop2()
var prop3 = prop1.then(function (v) { value = v })
var val3 = prop3()
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
return val1 === 123 &&
val2 === 123 &&
val3 === 123 &&
value.method === "GET" &&
value.url === "test"
})
// m.request over jsonp
test(function (){
// script tags cannot be appended directly on the document
var body = mock.document.createElement("body")
mock.document.body = body
mock.document.appendChild(body)
var error = m.prop("no error")
var data
m.request({url: "/test", dataType: "jsonp"})
.then(function (received) { data = received }, error)
var callbackKey = Object.keys(mock).filter(function (globalKey){
return globalKey.indexOf("mithril_callback") > -1
}).pop()
var scripts = mock.document.getElementsByTagName("script")
var scriptTag = [].slice.call(scripts).filter(function (script){
return script.src.indexOf(callbackKey) > -1
}).pop()
mock[callbackKey]({foo: "bar"})
mock.document.removeChild(body)
return scriptTag.src.indexOf("/test?callback=mithril_callback") > -1 &&
data.foo === "bar"
})
test(function (){
// script tags cannot be appended directly on the document
var body = mock.document.createElement("body")
mock.document.body = body
mock.document.appendChild(body)
var error = m.prop("no error")
var data
m.request({
url: "/test",
dataType: "jsonp",
callbackKey: "jsonpCallback"
}).then(function (received) { data = received }, error)
var callbackKey = Object.keys(mock).filter(function (globalKey){
return globalKey.indexOf("mithril_callback") > -1
}).pop()
var scripts = mock.document.getElementsByTagName("script")
var scriptTag = [].slice.call(scripts).filter(function (script){
return script.src.indexOf(callbackKey) > -1
}).pop()
mock[callbackKey]({foo: "bar1"})
mock.document.removeChild(body)
var url = "/test?jsonpCallback=mithril_callback"
return scriptTag.src.indexOf(url) > -1 &&
data.foo === "bar1"
})
test(function (){
var body = mock.document.createElement("body")
mock.document.body = body
mock.document.appendChild(body)
var req = m.request({url: "/test", dataType: "jsonp"})
var callbackKey = Object.keys(mock).filter(function (globalKey){
return globalKey.indexOf("mithril_callback") > -1
}).pop()
var scripts = mock.document.getElementsByTagName("script")
;[].slice.call(scripts).filter(function (script){
return script.src.indexOf(callbackKey) > -1
}).pop()
mock[callbackKey]({foo: "bar1"})
var out = {foo: "bar1"}
mock.document.removeChild(body)
return JSON.stringify(out) === JSON.stringify(req())
})
test(function (){
var body = mock.document.createElement("body")
mock.document.body = body
mock.document.appendChild(body)
m.request({url: "/test", dataType: "jsonp", data: {foo: "bar"}})
var callbackKey = Object.keys(mock).filter(function (globalKey){
return globalKey.indexOf("mithril_callback") > -1
}).pop()
var scripts = mock.document.getElementsByTagName("script")
var scriptTag = [].slice.call(scripts).filter(function (script){
return script.src.indexOf(callbackKey) > -1
}).pop()
mock[callbackKey]({foo: "bar"})
return scriptTag.src.indexOf("foo=bar") > -1
})
test(function (){
var body = mock.document.createElement("body")
mock.document.body = body
mock.document.appendChild(body)
m.request({
url: "/test",
dataType: "jsonp",
method: "GET",
data: {foo: "bar"}
})
var callbackKey = Object.keys(mock).filter(function (globalKey){
return globalKey.indexOf("mithril_callback") > -1
}).pop()
var scripts = mock.document.getElementsByTagName("script")
var scriptTag = [].slice.call(scripts).filter(function (script){
return script.src.indexOf(callbackKey) > -1
}).pop()
mock[callbackKey]({foo: "bar"})
mock.document.removeChild(body)
return scriptTag.src.match(/foo=bar/g).length === 1
})
// m.deferred
test(function () {
var deferred = m.deferred()
var value
deferred.promise.then(function (data) { value = data })
deferred.resolve("test")
return value === "test"
})
test(function () {
var deferred = m.deferred()
var value
deferred.promise
.then(function () { return "foo" })
.then(function (data) { value = data })
deferred.resolve("test")
return value === "foo"
})
test(function () {
var deferred = m.deferred()
var value
deferred.promise.then(null, function (data) { value = data })
deferred.reject("test")
return value === "test"
})
test(function () {
var value
var deferred = m.deferred()
deferred.promise.catch(function (data) { value = data })
deferred.reject("test")
return value === "test"
})
test(function () {
var deferred = m.deferred()
var value
deferred.promise
.then(null, function () { return "foo" })
.then(function (data) { value = data })
deferred.reject("test")
return value === "foo"
})
test(function () {
var deferred = m.deferred()
var value
deferred.promise
.catch(function () { return "foo" })
.then(function (data) { value = data })
deferred.reject("test")
return value === "foo"
})
test(function () {
var deferred = m.deferred()
var value1, value2
deferred.promise
.then(function () { throw new Error() })
.then(function () { value1 = 1 }, function (data) { value2 = data })
deferred.resolve("test")
return value1 === undefined && value2 instanceof Error
})
test(function () {
// Let unchecked exceptions bubble up in order to allow meaningful error
// messages in common cases like null reference exceptions due to typos
//
// An unchecked exception is defined as an object that is a subclass of
// Error (but not a direct instance of Error itself) - basically
// anything that can be thrown without an explicit `throw` keyword and
// that we'd never want to programmatically manipulate. In other words,
// an unchecked error is one where we only care about its line number
// and where the only reasonable way to deal with it is to change the
// buggy source code that caused the error to be thrown in the first
// place.
//
// By contrast, a checked exception is defined as anything that is
// explicitly thrown via the `throw` keyword and that can be
// programmatically handled, for example to display a validation error
// message on the UI. If an exception is a subclass of Error for
// whatever reason, but it is meant to be handled as a checked exception
// (i.e. follow the rejection rules for A+), it can be rethrown as an
// instance of Error
//
// This test tests two implementation details that differ from the
// Promises/A+ spec:
//
// 1) A+ requires the `then` callback to be called in a different event
// loop from the resolve call, i.e. it must be asynchronous (this
// requires a setImmediate polyfill, which cannot be implemented in a
// reasonable way for Mithril's purpose - the possible polyfills are
// either too big or too slow)
//
// 2) A+ swallows exceptions in a unrethrowable way, i.e. it's not
// possible to see default error messages on the console for runtime
// errors thrown from within a promise chain
var deferred = m.deferred()
var value1, value2, value3
try {
deferred.promise
/* eslint-disable no-undef */
// throws ReferenceError
.then(function () { return foo.bar.baz })
/* eslint-enable no-undef */
.then(
function () { value1 = 1 },
function (data) { value2 = data }
)
deferred.resolve("test")
} catch (e) {
value3 = e
}
return value1 === undefined &&
value2 === undefined &&
(value3 instanceof ReferenceError || value3 instanceof TypeError)
})
test(function () {
var deferred1 = m.deferred()
var deferred2 = m.deferred()
var value1, value2
deferred1.promise.then(function (data) {
value1 = data
return deferred2.promise
}).then(function (data) {
value2 = data
})
deferred1.resolve(1)
deferred2.resolve(2)
return value1 === 1 && value2 === 2
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/80
var deferred = m.deferred()
var value
deferred.resolve(1)
deferred.promise.then(function (data) {
value = data
})
return value === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/80
var deferred = m.deferred()
var value
deferred.reject(1)
deferred.promise.then(null, function (data) {
value = data
})
return value === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/80
var deferred = m.deferred()
var value
deferred.resolve(1)
deferred.resolve(2)
deferred.promise.then(function (data) {
value = data
})
return value === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/80
var deferred = m.deferred()
var value
deferred.promise.then(function (data) {
value = data
})
deferred.resolve(1)
deferred.resolve(2)
return value === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/80
var deferred = m.deferred()
var value1, value2
deferred.promise.then(function (data) {
value1 = data
}, function (data) {
value2 = data
})
deferred.resolve(1)
deferred.reject(2)
return value1 === 1 && value2 === undefined
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/80
var deferred = m.deferred()
var value1, value2
deferred.promise.then(function (data) {
value1 = data
}, function (data) {
value2 = data
})
deferred.reject(1)
deferred.resolve(2)
return value1 === undefined && value2 === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/80
var deferred = m.deferred()
var value
deferred.promise.then(null, function (data) {
value = data
})
deferred.reject(1)
deferred.reject(2)
return value === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/85
var deferred = m.deferred()
var value
deferred.resolve()
deferred.promise.then(function () {
value = 1
})
return value === 1
})
test(function () {
// https://github.com/lhorie/mithril.js/issues/85
var deferred = m.deferred()
var value
deferred.reject()
deferred.promise.then(null, function () {
value = 1
})
return value === 1
})
test(function () {
var deferred = m.deferred()
deferred.resolve(1)
return deferred.promise() === 1
})
test(function () {
var deferred = m.deferred()
var promise = deferred.promise.then(function (data) { return data + 1 })
deferred.resolve(1)
return promise() === 2
})
test(function () {
var deferred = m.deferred()
deferred.reject(1)
return deferred.promise() === undefined
})
// m.sync
test(function () {
var value
var deferred1 = m.deferred()
var deferred2 = m.deferred()
m.sync([deferred1.promise, deferred2.promise])
.then(function (data) { value = data })
deferred1.resolve("test")
deferred2.resolve("foo")
return value[0] === "test" && value[1] === "foo"
})
test(function () {
var value
var deferred1 = m.deferred()
var deferred2 = m.deferred()
m.sync([deferred1.promise, deferred2.promise])
.then(function (data) { value = data })
deferred2.resolve("foo")
deferred1.resolve("test")
return value[0] === "test" && value[1] === "foo"
})
test(function () {
var value
var deferred = m.deferred()
m.sync([deferred.promise]).catch(function (data) { value = data })
deferred.reject("fail")
return value[0] === "fail"
})
test(function () {
var value = 1
m.sync([]).then(function () { value = 2 })
return value === 2
})
test(function () {
var success
m.sync([]).then(function (value) { success = value instanceof Array })
return success
})
// m.startComputation/m.endComputation
test(function () {
mock.requestAnimationFrame.$resolve()
var root = mock.document.createElement("div")
var controller = m.mount(root, {
controller: function () {},
view: function (ctrl) { return ctrl.value }
})
mock.requestAnimationFrame.$resolve()
m.startComputation()
controller.value = "foo"
m.endComputation()
mock.requestAnimationFrame.$resolve()
return root.childNodes[0].nodeValue === "foo"
})
// config context
test(function () {
var root = mock.document.createElement("div")
var success = false
m.render(root, m("div", {
config: function (elem, isInit, ctx) { ctx.data = 1 }
}))
m.render(root, m("div", {
config: function (elem, isInit, ctx) { success = ctx.data === 1 }
}))
return success
})
// more complex config context
test(function () {
var root = mock.document.createElement("div")
var idx = 0
var success = true
function statefulConfig(elem, isInit, ctx) { ctx.data = idx++ }
var node = m("div", {config: statefulConfig})
m.render(root, [node, node])
idx = 0
function checkConfig(elem, isInit, ctx) {
success = success && (ctx.data === idx++)
}
node = m("div", {config: checkConfig})
m.render(root, [node, node])
return success
})
test.print(function (value) {
console.log(value) // eslint-disable-line no-console
})
})()