mithril-vndb/test/mithril.redraw.js

224 lines
4.9 KiB
JavaScript

describe("m.redraw()", function () {
"use strict"
beforeEach(function () {
mock.requestAnimationFrame.$resolve()
})
it("exists", function () {
expect(m.redraw).to.be.a("function")
})
it("correctly renders a property if the controller value changes", function () { // eslint-disable-line
var ctx
var root = mock.document.createElement("div")
m.mount(root, {
controller: function () { ctx = this }, // eslint-disable-line
view: function (ctrl) { return ctrl.value }
})
mock.requestAnimationFrame.$resolve()
var valueBefore = root.childNodes[0].nodeValue
ctx.value = "foo"
m.redraw()
mock.requestAnimationFrame.$resolve()
expect(valueBefore).to.equal("")
expect(root.childNodes[0].nodeValue).to.equal("foo")
})
it("runs unnecessary redraws asynchronously", function () {
if (mock.phantom) return
var root = mock.document.createElement("div")
var view = sinon.spy()
m.mount(root, {
controller: function () {},
view: view
})
mock.requestAnimationFrame.$resolve() // teardown
m.redraw()
// These should run asynchronously
m.redraw()
m.redraw()
m.redraw()
mock.requestAnimationFrame.$resolve() // teardown
expect(view).to.be.calledThrice
})
it("runs unnecessary forced redraws asynchronously", function () {
var root = mock.document.createElement("div")
var view = sinon.spy()
m.mount(root, {
controller: function () {},
view: view
})
mock.requestAnimationFrame.$resolve() // teardown
m.redraw(true)
// These should run asynchronously
m.redraw(true)
m.redraw(true)
m.redraw(true)
mock.requestAnimationFrame.$resolve() // teardown
expect(view).to.have.callCount(5)
})
context("m.redraw.strategy()", function () {
// Use this instead of m.route() unless you have to call m.route and do
// something else in the same frame.
function route() {
var res = m.route.apply(null, arguments)
mock.requestAnimationFrame.$resolve()
return res
}
// Little helper utility
function noop() {}
// Use this if all you need to do is render a view (i.e. a pure
// component).
function pure(view) {
return {
controller: noop,
view: view
}
}
// Use these instead of `it` and `xit` in this set of tests if you need
// a root element.
var dit = makeIt(it)
// Wraps the `it` function for dependency injection that doesn't require
// `this`
/* eslint-disable no-invalid-this */
function makeIt(it) {
return function (name, callback) {
return it(name, function () {
var args = [this.root]
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i])
}
callback.apply(null, args)
})
}
}
beforeEach(function () {
mock.requestAnimationFrame.$resolve()
mock.location.search = "?"
m.route.mode = "search"
this.root = mock.document.createElement("div")
})
afterEach(function () {
m.mount(this.root, null)
})
/* eslint-enable no-invalid-this */
it("exists", function () {
expect(m.redraw.strategy).to.be.a("function")
})
dit("works with \"all\"", function (root) {
var strategy
route(root, "/foo1", {
"/foo1": {
controller: function () {
strategy = m.redraw.strategy()
m.redraw.strategy("none")
},
view: function () {
return m("div")
}
}
})
expect(strategy).to.equal("all")
expect(root.childNodes).to.be.empty
})
dit("works with \"redraw\"", function (root) {
var count = 0
var strategy
function config(el, init) {
if (!init) count++
}
route(root, "/foo1", {
"/foo1": pure(function () {
return m("div", {config: config})
}),
"/bar1": {
controller: function () {
strategy = m.redraw.strategy()
m.redraw.strategy("redraw")
},
view: function () {
return m("div", {config: config})
}
}
})
route("/bar1")
expect(strategy).to.equal("all")
expect(count).to.equal(1)
})
dit("works with \"diff\"", function (root) {
var strategy
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()
expect(strategy).to.equal("diff")
expect(root.childNodes[0].childNodes[0].nodeValue).to.equal("1")
})
dit("recreates the component when \"all\"", function (root) {
if (mock.phantom) return
var count = 0
function config(el, init) {
if (!init) count++
}
m.route(root, "/foo1", {
"/foo1": pure(function () {
return m("div", {
config: config,
onclick: function () {
m.redraw.strategy("all")
}
})
})
})
root.childNodes[0].onclick({})
mock.requestAnimationFrame.$resolve()
expect(count).to.equal(2)
})
})
})