Details: 1. All tests now live in `test`. All test dependencies that aren't from npm live in `test-deps`. 2. The QUnit tests are gone, as well as their dependencies. Half of them duplicated existing tests, and some of them depended on the real DOM to properly test. 3. All tests are now using Mocha to run the tests, Chai for assertions, and Sinon and Sinon Chai for testing some callbacks. 4. Tests are run through mocha-phantomjs. If you want to run just the tests, run `grunt mocha_phantomjs` or fire up a server in the root and open `http://localhost:<port>/test/index.html`, e.g. `python3 -m http.server`. 5. The linter I chose is ESLint. It is relatively easy to configure, but with a lot of flexibility. The rules I chose mostly were in tune to the style the project was already using. I'm not including a style guide in this commit, but one will likely come. You can check out the `.eslintrc` in the root and in `test/` for the two configs. The `.eslintignore` includes a TODO for `mithril.js` itself targeted at me, in the root. Other info: - As a drive-by fix, I fixed line endings on a few of the files. - I also took care of a few other files and linted them as I went: - `Gruntfile.js` - `test/input-cursor.html` (was in `tests/`) - `test/svg.html` (was in `tests/`) - `docs/layout/tools/template-converter.html` - `docs/layout/tools/template-converter.js` I didn't test the template converter after linting it, because it needs further scrutiny to ensure it works with the latest version of Mithril. I know the API has changed a little, which is why I want to be sure. - I simplified the `.travis.yml` file because none of the tests are run directly through Node anymore. They are always run in a browser of some kind. Hopefully, this turned out all right...
802 lines
17 KiB
JavaScript
802 lines
17 KiB
JavaScript
describe("m.mount()", function () {
|
|
"use strict"
|
|
|
|
// This is a frequent idiom
|
|
function refresh(force) {
|
|
m.redraw(!!force)
|
|
mock.requestAnimationFrame.$resolve()
|
|
}
|
|
|
|
function clear(root) {
|
|
m.mount(root, null)
|
|
mock.requestAnimationFrame.$resolve()
|
|
}
|
|
|
|
function mount(root, mod) {
|
|
var res = m.mount(root, mod)
|
|
mock.requestAnimationFrame.$resolve()
|
|
return res
|
|
}
|
|
|
|
// This is extremely frequent in the tests
|
|
function pure(view) {
|
|
return {
|
|
controller: function () {},
|
|
view: view
|
|
}
|
|
}
|
|
|
|
it("exists", function () {
|
|
expect(m.mount).to.be.a("function")
|
|
})
|
|
|
|
it("mounts onto the root", function () {
|
|
var root = mock.document.createElement("div")
|
|
var whatever = 1
|
|
|
|
var app = pure(function () {
|
|
return [
|
|
whatever % 2 ? m("span", "% 2") : undefined,
|
|
m("div", "bugs"),
|
|
m("a")
|
|
]
|
|
})
|
|
|
|
mount(root, app)
|
|
|
|
whatever++
|
|
refresh()
|
|
|
|
whatever++
|
|
refresh()
|
|
|
|
expect(root.childNodes).to.have.length.above(0)
|
|
})
|
|
|
|
it("reloads components correctly", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root1 = mock.document.createElement("div")
|
|
var controller1 = sinon.spy(function () { this.value = "test1" }) // eslint-disable-line
|
|
var view1 = sinon.stub().returns("test1")
|
|
|
|
var mod1 = m.mount(root1, {
|
|
controller: controller1,
|
|
view: view1
|
|
})
|
|
|
|
var controller2 = sinon.spy(function () { this.value = "test2" }) // eslint-disable-line
|
|
var view2 = sinon.stub().returns("test2")
|
|
var root2 = mock.document.createElement("div")
|
|
|
|
var mod2 = mount(root2, {
|
|
controller: controller2,
|
|
view: view2
|
|
})
|
|
|
|
expect(controller1).to.have.been.called
|
|
expect(view1).to.have.been.called
|
|
expect(controller2).to.have.been.called
|
|
expect(view2).to.have.been.called
|
|
|
|
expect(root1.childNodes[0].nodeValue).to.equal("test1")
|
|
expect(root2.childNodes[0].nodeValue).to.equal("test2")
|
|
expect(mod1).to.have.property("value", "test1")
|
|
expect(mod2).to.have.property("value", "test2")
|
|
})
|
|
|
|
it("triggers an unload when the element is removed", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var spy = sinon.spy()
|
|
|
|
mount(root, {
|
|
controller: function () {
|
|
this.onunload = spy
|
|
},
|
|
view: function () {}
|
|
})
|
|
|
|
clear(root)
|
|
|
|
expect(spy).to.have.been.called
|
|
})
|
|
|
|
it("passes the args to both component & view", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var ctrlSpy = sinon.spy()
|
|
var viewSpy = sinon.stub().returns(m("div"))
|
|
|
|
var component = {
|
|
controller: ctrlSpy,
|
|
view: viewSpy
|
|
}
|
|
|
|
var arg = {}
|
|
|
|
mount(root, m.component(component, arg))
|
|
|
|
expect(ctrlSpy).to.have.been.calledWith(arg)
|
|
expect(viewSpy.firstCall.args[1]).to.equal(arg)
|
|
})
|
|
|
|
it("mounts a component without a controller", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var arg = {}
|
|
var spy = sinon.spy()
|
|
|
|
var component = pure(spy)
|
|
|
|
mount(root, m.component(component, arg))
|
|
|
|
expect(spy.firstCall.args[1]).to.equal(arg)
|
|
})
|
|
|
|
it("only runs a component controller once", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var ctrlSpy = sinon.spy()
|
|
var viewSpy = sinon.stub().returns(m("div"))
|
|
|
|
var sub = {
|
|
controller: ctrlSpy,
|
|
view: viewSpy
|
|
}
|
|
|
|
mount(root, pure(function () { return sub }))
|
|
|
|
refresh(true)
|
|
|
|
expect(ctrlSpy).to.have.been.calledOnce
|
|
expect(viewSpy).to.have.been.calledTwice
|
|
})
|
|
|
|
it("only runs a subcomponent controller once", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var ctrl1 = sinon.spy()
|
|
var view1 = sinon.stub().returns(m("div"))
|
|
|
|
var subsub = {
|
|
controller: ctrl1,
|
|
view: view1
|
|
}
|
|
|
|
var ctrl2 = sinon.spy()
|
|
var view2 = sinon.stub().returns(subsub)
|
|
|
|
var sub = {
|
|
controller: ctrl2,
|
|
view: view2
|
|
}
|
|
|
|
mount(root, pure(function () { return sub }))
|
|
|
|
refresh(true)
|
|
|
|
expect(ctrl1).to.have.been.calledOnce
|
|
expect(ctrl2).to.have.been.calledOnce
|
|
expect(view1).to.have.been.calledTwice
|
|
expect(view2).to.have.been.calledTwice
|
|
})
|
|
|
|
it("addresses keys in components", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var list = [1, 2, 3]
|
|
|
|
var sub = pure(function () { return m("div") })
|
|
|
|
m.mount(root, pure(function () {
|
|
return list.map(function (i) {
|
|
return m.component(sub, {key: i})
|
|
})
|
|
}))
|
|
|
|
var firstBefore = root.childNodes[0]
|
|
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
list.reverse()
|
|
refresh(true)
|
|
|
|
expect(root.childNodes[2]).to.equal(firstBefore)
|
|
})
|
|
|
|
it("addresses keys in subcomponents correctly", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var list = [1, 2, 3]
|
|
|
|
var subsub = pure(function () { return m("div") })
|
|
|
|
var sub = pure(function () { return subsub })
|
|
|
|
m.mount(root, pure(function () {
|
|
return list.map(function (i) {
|
|
return m.component(sub, {key: i})
|
|
})
|
|
}))
|
|
|
|
var firstBefore = root.childNodes[0]
|
|
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
list.reverse()
|
|
refresh(true)
|
|
|
|
expect(root.childNodes[2]).to.equal(firstBefore)
|
|
})
|
|
|
|
it("is error resistant with keys in components", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var list = [1, 2, 3]
|
|
|
|
var sub = pure(function () { return m("div", {key: 1}) })
|
|
|
|
m.mount(root, pure(function () {
|
|
return list.map(function (i) {
|
|
return m.component(sub, {key: i})
|
|
})
|
|
}))
|
|
|
|
var firstBefore = root.childNodes[0]
|
|
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
list.reverse()
|
|
refresh(true)
|
|
|
|
expect(root.childNodes[2]).to.equal(firstBefore)
|
|
})
|
|
|
|
it("is error resistant with keys in subcomponents", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var list = [1, 2, 3]
|
|
|
|
var subsub = pure(function () { return m("div", {key: 1}) })
|
|
|
|
var sub = pure(function () { return subsub })
|
|
|
|
m.mount(root, pure(function () {
|
|
return list.map(function (i) {
|
|
return m.component(sub, {key: i})
|
|
})
|
|
}))
|
|
|
|
var firstBefore = root.childNodes[0]
|
|
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
list.reverse()
|
|
refresh(true)
|
|
|
|
expect(root.childNodes[2]).to.equal(firstBefore)
|
|
})
|
|
|
|
it("retains subcomponent identity if child of keyed element", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var list = [1, 2, 3]
|
|
|
|
var sub = pure(function () { return m("div") })
|
|
|
|
m.mount(root, pure(function () {
|
|
return list.map(function (i) {
|
|
return m("div", {key: i}, sub)
|
|
})
|
|
}))
|
|
|
|
var firstBefore = root.childNodes[0].childNodes[0]
|
|
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
list.reverse()
|
|
refresh(true)
|
|
|
|
expect(root.childNodes[2].childNodes[0]).to.equal(firstBefore)
|
|
})
|
|
|
|
it("calls component onunload when removed from template", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var list = [1, 2, 3]
|
|
var spies = []
|
|
|
|
var sub = {
|
|
controller: function (opts) {
|
|
this.onunload = spies[opts.key] = sinon.spy()
|
|
},
|
|
view: function () {
|
|
return m("div")
|
|
}
|
|
}
|
|
|
|
mount(root, pure(function () {
|
|
return list.map(function (i) {
|
|
return m.component(sub, {key: i})
|
|
})
|
|
}))
|
|
|
|
list.pop()
|
|
refresh(true)
|
|
|
|
// TODO: These fail.
|
|
// expect(spies[1]).to.have.been.called
|
|
// expect(spies[2]).to.have.been.called
|
|
expect(spies[3]).to.have.been.called
|
|
})
|
|
|
|
it("calls subcomponent onunload when removed from template", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var list = [1, 2, 3]
|
|
var spies1 = []
|
|
var spies2 = []
|
|
|
|
var subsub = {
|
|
controller: function (opts) {
|
|
this.onunload = spies1[opts.key] = sinon.spy()
|
|
},
|
|
view: function () {
|
|
return m("div")
|
|
}
|
|
}
|
|
|
|
var sub = {
|
|
controller: function (opts) {
|
|
this.onunload = spies2[opts.key] = sinon.spy()
|
|
},
|
|
view: function (ctrl, opts) {
|
|
return m.component(subsub, {key: opts.key})
|
|
}
|
|
}
|
|
|
|
mount(root, pure(function () {
|
|
return list.map(function (i) {
|
|
return m.component(sub, {key: i})
|
|
})
|
|
}))
|
|
|
|
list.pop()
|
|
refresh(true)
|
|
|
|
// TODO: These fail.
|
|
// expect(spies1[1]).to.have.been.called
|
|
// expect(spies1[2]).to.have.been.called
|
|
expect(spies1[3]).to.have.been.called
|
|
|
|
// TODO: These fail.
|
|
// expect(spies2[1]).to.have.been.called
|
|
// expect(spies2[2]).to.have.been.called
|
|
expect(spies2[3]).to.have.been.called
|
|
})
|
|
|
|
it("doesn't redraw if m.render() is called by controller constructor", function () { // eslint-disable-line
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var spy = sinon.stub().returns(m("div"))
|
|
|
|
var sub = {
|
|
controller: function () {
|
|
m.redraw()
|
|
},
|
|
view: spy
|
|
}
|
|
|
|
mount(root, pure(function () { return sub }))
|
|
|
|
expect(spy).to.have.been.called
|
|
})
|
|
|
|
it("doesn't redraw if m.render() is called by subcomponent controller constructor", function () { // eslint-disable-line
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var spy = sinon.stub().returns(m("div"))
|
|
|
|
var subsub = {
|
|
controller: function () {
|
|
m.redraw()
|
|
},
|
|
view: spy
|
|
}
|
|
|
|
var sub = pure(function () { return subsub })
|
|
|
|
mount(root, pure(function () { return sub }))
|
|
|
|
expect(spy).to.have.been.called
|
|
})
|
|
|
|
it("renders nested components under keyed components", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var spy = sinon.stub().returns(m(".reply"))
|
|
|
|
var Reply = pure(spy)
|
|
|
|
var CommentList = pure(function (ctrl, props) {
|
|
return m(".list", props.list.map(function (i) {
|
|
return m(".comment", [
|
|
m.component(Reply, {key: i})
|
|
])
|
|
}))
|
|
})
|
|
|
|
mount(root, pure(function () {
|
|
return m(".outer", [
|
|
m(".inner", m.component(CommentList, {list: [1, 2, 3]}))
|
|
])
|
|
}))
|
|
|
|
expect(spy).to.have.been.calledThrice
|
|
})
|
|
|
|
it("calls unload when the component is replaced with another component", function () { // eslint-disable-line
|
|
var root = mock.document.createElement("div")
|
|
var spy = sinon.spy()
|
|
|
|
m.mount(root, {
|
|
controller: function () {
|
|
this.onunload = spy
|
|
},
|
|
view: function () {}
|
|
})
|
|
|
|
m.mount(root, pure(function () {}))
|
|
|
|
expect(spy).to.have.been.called
|
|
})
|
|
|
|
|
|
it("calls config with truthy init only once", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
var root = mock.document.createElement("div")
|
|
var count = 0
|
|
|
|
mount(root, pure(function () {
|
|
return m("div", {
|
|
config: function (el, init) {
|
|
if (init) count += 1
|
|
}
|
|
})
|
|
}))
|
|
|
|
refresh()
|
|
|
|
expect(count).to.equal(1)
|
|
})
|
|
|
|
it("doesn't recreate node that modifies DOM in config, but stays same between redraws", function () { // eslint-disable-line
|
|
var root = mock.document.createElement("div")
|
|
var child = mock.document.createElement("div")
|
|
|
|
var show = true
|
|
|
|
function test(el, init) {
|
|
if (!init) {
|
|
root.appendChild(child)
|
|
}
|
|
}
|
|
|
|
mount(root, pure(function () {
|
|
return [
|
|
m(".foo", {
|
|
key: 1,
|
|
config: test,
|
|
onclick: function () { show = !show }
|
|
}),
|
|
show ? m(".bar", {key: 2}) : null
|
|
]
|
|
}))
|
|
|
|
show = false
|
|
refresh()
|
|
|
|
show = true
|
|
refresh()
|
|
|
|
expect(root.childNodes).to.have.length(3)
|
|
})
|
|
|
|
it("correctly replaces nodes", function () {
|
|
var root = mock.document.createElement("div")
|
|
var show = true
|
|
|
|
var sub = pure(function () { return m("div", "component") })
|
|
|
|
mount(root, pure(function () {
|
|
return show ? [
|
|
m("h1", "1"),
|
|
sub
|
|
] : [
|
|
m("h1", "2")
|
|
]
|
|
}))
|
|
|
|
show = false
|
|
refresh()
|
|
|
|
show = true
|
|
refresh()
|
|
|
|
expect(root.childNodes).to.have.length(2)
|
|
})
|
|
|
|
// https://github.com/lhorie/mithril.js/issues/551
|
|
it("only redraws a component when clicked", function () {
|
|
var root = mock.document.createElement("div")
|
|
var a = false
|
|
var found = {}
|
|
|
|
var onunload = sinon.spy()
|
|
var view = sinon.spy(function () {
|
|
return m("div", {config: Comp.config}, [ // eslint-disable-line
|
|
m("div", {
|
|
onclick: function () {
|
|
a = !a
|
|
m.redraw(true)
|
|
found = root.childNodes[0].childNodes[1]
|
|
}
|
|
}, "asd"),
|
|
a ? m("#a", "aaa") : null,
|
|
"test"
|
|
])
|
|
})
|
|
|
|
var Comp = {
|
|
view: view,
|
|
|
|
config: function (el, init, ctx) {
|
|
if (!init) ctx.onunload = onunload
|
|
}
|
|
}
|
|
|
|
m.mount(root, pure(function () { return Comp }))
|
|
|
|
var target = root.childNodes[0].childNodes[0]
|
|
|
|
target.onclick({currentTarget: target})
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
expect(onunload).to.not.be.called
|
|
expect(found).to.have.property("id", "a")
|
|
expect(view).to.have.been.calledThrice
|
|
})
|
|
|
|
// https://github.com/lhorie/mithril.js/issues/551
|
|
it("only redraws a component when clicked if the strategy is `none`", function () { // eslint-disable-line
|
|
var root = mock.document.createElement("div")
|
|
var a = false
|
|
var found = {}
|
|
|
|
var onunload = sinon.spy()
|
|
var view = sinon.spy(function () {
|
|
return m("div", {config: Comp.config}, [ // eslint-disable-line
|
|
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"
|
|
])
|
|
})
|
|
|
|
var Comp = {
|
|
view: view,
|
|
|
|
config: function (el, init, ctx) {
|
|
if (!init) ctx.onunload = onunload
|
|
}
|
|
}
|
|
|
|
m.mount(root, pure(function () { return Comp }))
|
|
|
|
var target = root.childNodes[0].childNodes[0]
|
|
|
|
target.onclick({currentTarget: target})
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
expect(onunload).to.not.be.called
|
|
expect(found).to.have.property("id", "a")
|
|
expect(view).to.have.been.calledTwice
|
|
})
|
|
|
|
it("redraws when clicked and click handler forces redraw", function () {
|
|
var root = mock.document.createElement("div")
|
|
var view = sinon.stub().returns(m("div", {
|
|
onclick: function () { m.redraw(true) }
|
|
}))
|
|
|
|
m.mount(root, pure(view))
|
|
|
|
var target = root.childNodes[0]
|
|
|
|
target.onclick({currentTarget: target})
|
|
mock.requestAnimationFrame.$resolve()
|
|
|
|
expect(view).to.be.calledThrice
|
|
})
|
|
|
|
function resolveXhr() {
|
|
mock.XMLHttpRequest.$instances.pop().onreadystatechange()
|
|
mock.requestAnimationFrame.$resolve()
|
|
}
|
|
|
|
it("doesn't redraw on a single synchronous request", function () {
|
|
var root = mock.document.createElement("div")
|
|
|
|
var data
|
|
var view = sinon.spy(function (ctrl) {
|
|
data = ctrl.foo()
|
|
return m("div")
|
|
})
|
|
|
|
var Comp = {
|
|
controller: function () {
|
|
this.foo = m.request({method: "GET", url: "/foo"})
|
|
},
|
|
|
|
view: view
|
|
}
|
|
|
|
mount(root, pure(function () { return Comp }))
|
|
|
|
resolveXhr()
|
|
|
|
clear(root)
|
|
|
|
expect(view).to.be.calledOnce
|
|
expect(data).to.have.property("url", "/foo")
|
|
})
|
|
|
|
it("doesn't redraw on multiple synchronous requests", function () {
|
|
mock.requestAnimationFrame.$resolve()
|
|
mock.location.search = "?"
|
|
|
|
var root = mock.document.createElement("div")
|
|
var view1 = sinon.stub().returns(m("div"))
|
|
var view2 = sinon.stub().returns(m("div"))
|
|
|
|
var Comp1 = {
|
|
controller: function () {
|
|
this.foo = m.request({method: "GET", url: "/foo"})
|
|
},
|
|
view: view1
|
|
}
|
|
|
|
var Comp2 = {
|
|
controller: function () {
|
|
this.bar = m.request({method: "GET", url: "/bar"})
|
|
},
|
|
view: view2
|
|
}
|
|
|
|
mount(root, pure(function () {
|
|
return m("div", [
|
|
Comp1,
|
|
Comp2
|
|
])
|
|
}))
|
|
|
|
resolveXhr()
|
|
resolveXhr()
|
|
|
|
clear(root)
|
|
|
|
expect(view1).to.be.calledOnce
|
|
expect(view2).to.be.calledOnce
|
|
})
|
|
|
|
it("instantiates different controllers for components without controller constructors", function () { // eslint-disable-line
|
|
var root = mock.document.createElement("div")
|
|
|
|
var cond = true
|
|
var controller1, controller2
|
|
|
|
var Comp1 = pure(function (ctrl) {
|
|
controller1 = ctrl
|
|
return m("div")
|
|
})
|
|
|
|
var Comp2 = pure(function (ctrl) {
|
|
controller2 = ctrl
|
|
return m("div")
|
|
})
|
|
|
|
mount(root, pure(function () { return cond ? Comp1 : Comp2 }))
|
|
|
|
cond = false
|
|
refresh(true)
|
|
|
|
expect(controller1).to.not.equal(controller2)
|
|
})
|
|
|
|
it("unloads removed components", function () {
|
|
var root = mock.document.createElement("div")
|
|
|
|
var onunload = sinon.spy()
|
|
var cond = true
|
|
|
|
var Comp1 = pure(function () {
|
|
return m("div", {
|
|
config: function (el, init, ctx) {
|
|
ctx.onunload = onunload
|
|
}
|
|
})
|
|
})
|
|
|
|
var Comp2 = pure(function () { return m("div") })
|
|
|
|
mount(root, pure(function () { return cond ? Comp1 : Comp2 }))
|
|
|
|
cond = false
|
|
refresh(true)
|
|
|
|
expect(onunload).to.be.called
|
|
})
|
|
|
|
it("calls config with its second argument false first", function () {
|
|
var root = mock.document.createElement("div")
|
|
|
|
var cond = true
|
|
var config = sinon.spy()
|
|
|
|
var Comp1 = pure(function () { return m("div") })
|
|
var Comp2 = pure(function () { return m("div", {config: config}) })
|
|
|
|
mount(root, pure(function () { return cond ? Comp1 : Comp2 }))
|
|
|
|
cond = false
|
|
refresh(true)
|
|
|
|
expect(config.firstCall.args[1]).to.be.false
|
|
})
|
|
|
|
it("refreshes the component when it's redrawn in a handler", function () {
|
|
var root = mock.document.createElement("div")
|
|
var sub = pure(function () { return m("#bar", "test") })
|
|
var el
|
|
|
|
m.mount(root, pure(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(sub) : ""
|
|
])
|
|
}))
|
|
|
|
root.childNodes[0].childNodes[0].onclick({})
|
|
|
|
expect(el).to.have.property("id", "bar")
|
|
})
|
|
})
|