initial release
This commit is contained in:
parent
554e8358cf
commit
70b2489539
81 changed files with 6702 additions and 2 deletions
7
tests/index.html
Normal file
7
tests/index.html
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<!doctype html>
|
||||
<script src="../mithril.js"></script>
|
||||
<script src="test.js"></script>
|
||||
<script src="mock.js"></script>
|
||||
<script src="mithril-tests.js"></script>
|
||||
|
||||
<p>Open the console to see the test report</p>
|
||||
226
tests/mithril-tests.js
Normal file
226
tests/mithril-tests.js
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
function testMithril(mock) {
|
||||
m.deps(mock)
|
||||
|
||||
//m
|
||||
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("[title=\'bar\']").attrs.title === "bar"})
|
||||
test(function() {return m("[title=\"bar\"]").attrs.title === "bar"})
|
||||
test(function() {return m("div", "test").children === "test"})
|
||||
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 === "test"})
|
||||
test(function() {return m("div", {title: "bar"}, ["test"]).children[0] === "test"})
|
||||
test(function() {return m("div", {title: "bar"}, m("div")).children.tag === "div"})
|
||||
test(function() {return m("div", {title: "bar"}, [m("div")]).children[0].tag === "div"})
|
||||
test(function() {return m("div", ["a", "b"]).children.length === 2})
|
||||
test(function() {return m("div", [m("div")]).children[0].tag === "div"})
|
||||
test(function() {return m("div", m("div")).attrs.tag === "div"}) //yes, this is expected behavior: see method signature
|
||||
|
||||
//m.module
|
||||
for (var i = 0; i < 2; i++) {
|
||||
//first iteration tests immediate rendering
|
||||
//second iteration tests deferred rendering
|
||||
test(function() {
|
||||
var root = mock.document.createElement("div")
|
||||
m.module(root, {
|
||||
controller: function() {this.value = "test"},
|
||||
view: function(ctrl) {return ctrl.value}
|
||||
})
|
||||
return root.childNodes[0].nodeValue === "test"
|
||||
})
|
||||
}
|
||||
|
||||
//m.withAttr
|
||||
test(function() {
|
||||
var value
|
||||
var handler = m.withAttr("test", function(data) {value = data})
|
||||
handler({currentTarget: {test: "foo"}})
|
||||
return value === "foo"
|
||||
})
|
||||
|
||||
//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", {id: "a"}))
|
||||
var elementBefore = root.childNodes[0]
|
||||
m.render(root, m("div", {id: "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
|
||||
})
|
||||
|
||||
//m.redraw
|
||||
test(function() {
|
||||
var controller
|
||||
var root = mock.document.createElement("div")
|
||||
m.module(root, {
|
||||
controller: function() {controller = this},
|
||||
view: function(ctrl) {return ctrl.value}
|
||||
})
|
||||
controller.value = "foo"
|
||||
m.redraw()
|
||||
return root.childNodes[0].nodeValue === "foo"
|
||||
})
|
||||
|
||||
//m.route
|
||||
test(function() {
|
||||
var root = mock.document.createElement("div")
|
||||
m.route.mode = "search"
|
||||
m.route(root, "/test1", {
|
||||
"/test1": {controller: function() {}, view: function() {return "foo"}}
|
||||
})
|
||||
return mock.location.search == "?/test1" && root.childNodes[0].nodeValue === "foo"
|
||||
})
|
||||
test(function() {
|
||||
var root = mock.document.createElement("div")
|
||||
m.route.mode = "pathname"
|
||||
m.route(root, "/test2", {
|
||||
"/test2": {controller: function() {}, view: function() {return "foo"}}
|
||||
})
|
||||
return mock.location.pathname == "/test2" && root.childNodes[0].nodeValue === "foo"
|
||||
})
|
||||
test(function() {
|
||||
var root = mock.document.createElement("div")
|
||||
m.route.mode = "hash"
|
||||
m.route(root, "/test3", {
|
||||
"/test3": {controller: function() {}, view: function() {return "foo"}}
|
||||
})
|
||||
return mock.location.hash == "#/test3" && root.childNodes[0].nodeValue === "foo"
|
||||
})
|
||||
test(function() {
|
||||
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")}}
|
||||
})
|
||||
return mock.location.search == "?/test4/foo" && root.childNodes[0].nodeValue === "foo"
|
||||
})
|
||||
|
||||
//m.prop
|
||||
test(function() {
|
||||
var prop = m.prop("test")
|
||||
return prop() === "test"
|
||||
})
|
||||
test(function() {
|
||||
var prop = m.prop("test")
|
||||
prop("foo")
|
||||
return prop() == "foo"
|
||||
})
|
||||
|
||||
//m.request
|
||||
test(function() {
|
||||
var prop = m.request({method: "GET", url: "test"})
|
||||
var e = mock.XMLHttpRequest.$events.pop()
|
||||
e.target.onload(e)
|
||||
return prop().method === "GET" && prop().url === "test"
|
||||
})
|
||||
test(function() {
|
||||
var prop = m.request({method: "GET", url: "test"}).then(function(value) {return "foo"})
|
||||
var e = mock.XMLHttpRequest.$events.pop()
|
||||
e.target.onload(e)
|
||||
return prop() === "foo"
|
||||
})
|
||||
|
||||
//m.deferred
|
||||
test(function() {
|
||||
var value
|
||||
var deferred = m.deferred()
|
||||
deferred.promise.then(function(data) {value = data})
|
||||
deferred.resolve("test")
|
||||
return value === "test"
|
||||
})
|
||||
test(function() {
|
||||
var value
|
||||
var deferred = m.deferred()
|
||||
deferred.promise.then(function(value) {return "foo"}).then(function(data) {value = data})
|
||||
deferred.resolve("test")
|
||||
return value === "foo"
|
||||
})
|
||||
test(function() {
|
||||
var value
|
||||
var deferred = m.deferred()
|
||||
deferred.promise.then(null, function(data) {value = data})
|
||||
deferred.reject("test")
|
||||
return value === "test"
|
||||
})
|
||||
test(function() {
|
||||
var value
|
||||
var deferred = m.deferred()
|
||||
deferred.promise.then(null, function(value) {return "foo"}).then(null, function(data) {value = data})
|
||||
deferred.reject("test")
|
||||
return value === "foo"
|
||||
})
|
||||
|
||||
//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"
|
||||
})
|
||||
|
||||
//m.startComputation/m.endComputation
|
||||
test(function() {
|
||||
var controller
|
||||
var root = mock.document.createElement("div")
|
||||
m.module(root, {
|
||||
controller: function() {controller = this},
|
||||
view: function(ctrl) {return ctrl.value}
|
||||
})
|
||||
m.startComputation()
|
||||
controller.value = "foo"
|
||||
m.endComputation()
|
||||
return root.childNodes[0].nodeValue === "foo"
|
||||
})
|
||||
}
|
||||
|
||||
//mocks
|
||||
testMithril(mock.window)
|
||||
|
||||
test.print(console.log)
|
||||
71
tests/mock.js
Normal file
71
tests/mock.js
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
var mock = {}
|
||||
mock.window = new function() {
|
||||
var window = {}
|
||||
window.document = {}
|
||||
window.document.childNodes = []
|
||||
window.document.createElement = function(tag) {
|
||||
return {
|
||||
childNodes: [],
|
||||
nodeName: tag.toUpperCase(),
|
||||
appendChild: window.document.appendChild,
|
||||
removeChild: window.document.removeChild,
|
||||
replaceChild: window.document.replaceChild,
|
||||
setAttribute: function(name, value) {
|
||||
this[name] = value.toString()
|
||||
},
|
||||
getAttribute: function(name, value) {
|
||||
return this[name]
|
||||
},
|
||||
}
|
||||
}
|
||||
window.document.createTextNode = function(text) {
|
||||
return {nodeValue: text.toString()}
|
||||
}
|
||||
window.document.documentElement = null
|
||||
window.document.replaceChild = function(newChild, oldChild) {
|
||||
var index = this.childNodes.indexOf(oldChild)
|
||||
if (index > -1) this.childNodes.splice(index, 1, newChild)
|
||||
else this.childNodes.push(newChild)
|
||||
newChild.parentNode = this
|
||||
oldChild.parentNode = null
|
||||
}
|
||||
window.document.appendChild = function(child) {
|
||||
this.childNodes.push(child)
|
||||
child.parentNode = this
|
||||
}
|
||||
window.document.removeChild = function(child) {
|
||||
var index = this.childNodes.indexOf(child)
|
||||
this.childNodes.splice(index, 1)
|
||||
child.parentNode = null
|
||||
}
|
||||
window.performance = new function () {
|
||||
var timestamp = 50
|
||||
this.$elapse = function(amount) {timestamp = amount}
|
||||
this.now = function() {return timestamp}
|
||||
}
|
||||
window.cancelAnimationFrame = function() {}
|
||||
window.requestAnimationFrame = function(callback) {callback()}
|
||||
window.XMLHttpRequest = new function() {
|
||||
var request = function() {
|
||||
this.open = function(method, url) {
|
||||
this.method = method
|
||||
this.url = url
|
||||
}
|
||||
this.send = function() {
|
||||
this.responseText = JSON.stringify(this)
|
||||
request.$events.push({type: "load", target: this})
|
||||
}
|
||||
}
|
||||
request.$events = []
|
||||
return request
|
||||
}
|
||||
window.location = {search: "", pathname: "", hash: ""},
|
||||
window.history = {}
|
||||
window.history.pushState = function(data, title, url) {
|
||||
window.location.pathname = window.location.search = window.location.hash = url
|
||||
},
|
||||
window.history.replaceState = function(data, title, url) {
|
||||
window.location.pathname = window.location.search = window.location.hash = url
|
||||
}
|
||||
return window
|
||||
}
|
||||
13
tests/test.js
Normal file
13
tests/test.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
function test(condition) {
|
||||
try {if (!condition()) throw new Error}
|
||||
catch (e) {test.failures.push(condition)}
|
||||
test.total++
|
||||
}
|
||||
test.total = 0
|
||||
test.failures = []
|
||||
test.print = function(print) {
|
||||
for (var i = 0; i < test.failures.length; i++) {
|
||||
print(test.failures[i].toString())
|
||||
}
|
||||
print("tests: " + test.total + "\nfailures: " + test.failures.length)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue