Merge MithrilJS/next into optimize-events
This commit is contained in:
commit
d150e71a85
6 changed files with 172 additions and 26 deletions
|
|
@ -24,6 +24,11 @@
|
|||
- API: Introduction of `m.redraw.sync()` ([#1592](https://github.com/MithrilJS/mithril.js/pull/1592))
|
||||
- API: Event handlers may also be objects with `handleEvent` methods ([#1939](https://github.com/MithrilJS/mithril.js/issues/1939)).
|
||||
|
||||
#### Ospec improvements:
|
||||
|
||||
- Added support for async functions and promises in tests - ([#1928](https://github.com/MithrilJS/mithril.js/pull/1928))
|
||||
- Error handling for async tests with `done` callbacks supports error as first argument
|
||||
|
||||
#### Bug fixes
|
||||
|
||||
- API: `m.route.set()` causes all mount points to be redrawn ([#1592](https://github.com/MithrilJS/mithril.js/pull/1592))
|
||||
|
|
|
|||
|
|
@ -148,6 +148,22 @@ o("setTimeout calls callback", function(done) {
|
|||
})
|
||||
```
|
||||
|
||||
Alternativly you can return a promise or even use an async function in tests:
|
||||
|
||||
```javascript
|
||||
o("promise test", function() {
|
||||
return new Promise(function(resolve) {
|
||||
setTimeout(resolve, 10)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
```javascript
|
||||
o("promise test", async function() {
|
||||
await someOtherAsyncFunction()
|
||||
})
|
||||
```
|
||||
|
||||
By default, asynchronous tests time out after 20ms. This can be changed on a per-test basis using the `timeout` argument:
|
||||
|
||||
```javascript
|
||||
|
|
@ -158,7 +174,22 @@ o("setTimeout calls callback", function(done, timeout) {
|
|||
})
|
||||
```
|
||||
|
||||
Note that the `timeout` function call must be the first statement in its test.
|
||||
Note that the `timeout` function call must be the first statement in its test. This currently does not work for promise tests. You can combine both methods to do this:
|
||||
|
||||
```javascript
|
||||
o("promise test", function(done, timeout) {
|
||||
timeout(1000)
|
||||
someOtherAsyncFunctionThatTakes900ms().then(done)
|
||||
})
|
||||
```
|
||||
|
||||
```javascript
|
||||
o("promise test", async function(done, timeout) {
|
||||
timeout(1000)
|
||||
await someOtherAsyncFunctionThatTakes900ms()
|
||||
done()
|
||||
})
|
||||
```
|
||||
|
||||
Asynchronous tests generate an assertion that succeeds upon calling `done` or fails on timeout with the error message `async test timed out`.
|
||||
|
||||
|
|
|
|||
|
|
@ -84,40 +84,56 @@ module.exports = new function init(name) {
|
|||
if (cursor === fns.length) return
|
||||
|
||||
var fn = fns[cursor++]
|
||||
var timeout = 0, delay = 200, s = new Date
|
||||
var isDone = false
|
||||
|
||||
function done(err) {
|
||||
if (err) {
|
||||
if (err.message) record(err.message, err)
|
||||
else record(err)
|
||||
subjects.pop()
|
||||
next()
|
||||
}
|
||||
if (timeout !== undefined) {
|
||||
timeout = clearTimeout(timeout)
|
||||
if (delay !== Infinity) record(null)
|
||||
if (!isDone) next()
|
||||
else throw new Error("`" + arg + "()` should only be called once")
|
||||
isDone = true
|
||||
}
|
||||
else console.log("# elapsed: " + Math.round(new Date - s) + "ms, expected under " + delay + "ms")
|
||||
}
|
||||
|
||||
function startTimer() {
|
||||
timeout = setTimeout(function() {
|
||||
timeout = undefined
|
||||
record("async test timed out")
|
||||
next()
|
||||
}, Math.min(delay, 2147483647))
|
||||
}
|
||||
|
||||
if (fn.length > 0) {
|
||||
var timeout = 0, delay = 200, s = new Date
|
||||
var isDone = false
|
||||
var body = fn.toString()
|
||||
var arg = (body.match(/\(([\w$]+)/) || body.match(/([\w$]+)\s*=>/) || []).pop()
|
||||
if (body.indexOf(arg) === body.lastIndexOf(arg)) throw new Error("`" + arg + "()` should be called at least once")
|
||||
try {
|
||||
fn(function done() {
|
||||
if (timeout !== undefined) {
|
||||
timeout = clearTimeout(timeout)
|
||||
if (delay !== Infinity) record(null)
|
||||
if (!isDone) next()
|
||||
else throw new Error("`" + arg + "()` should only be called once")
|
||||
isDone = true
|
||||
}
|
||||
else console.log("# elapsed: " + Math.round(new Date - s) + "ms, expected under " + delay + "ms")
|
||||
}, function(t) {delay = t})
|
||||
fn(done, function(t) {delay = t})
|
||||
}
|
||||
catch (e) {
|
||||
record(e.message, e)
|
||||
subjects.pop()
|
||||
next()
|
||||
done(e)
|
||||
}
|
||||
if (timeout === 0) {
|
||||
timeout = setTimeout(function() {
|
||||
timeout = undefined
|
||||
record("async test timed out")
|
||||
next()
|
||||
}, Math.min(delay, 2147483647))
|
||||
startTimer()
|
||||
}
|
||||
}
|
||||
else {
|
||||
fn()
|
||||
nextTickish(next)
|
||||
var p = fn()
|
||||
if (p && p.then) {
|
||||
startTimer()
|
||||
p.then(function() { done() }, done)
|
||||
} else {
|
||||
nextTickish(next)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ o.spec("ospec", function() {
|
|||
o(output).deepEquals({tag: "div", children: children})
|
||||
})
|
||||
})
|
||||
o.spec("async", function() {
|
||||
o.spec("async callback", function() {
|
||||
var a = 0, b = 0
|
||||
|
||||
o.before(function(done) {
|
||||
|
|
@ -148,4 +148,51 @@ o.spec("ospec", function() {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
o.spec("async promise", function() {
|
||||
var a = 0, b = 0
|
||||
|
||||
function wrapPromise(fn) {
|
||||
return new Promise((resolve, reject) => {
|
||||
callAsync(() => {
|
||||
try {
|
||||
fn()
|
||||
resolve()
|
||||
} catch(e) {
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
o.before(function() {
|
||||
return wrapPromise(() => {
|
||||
a = 1
|
||||
})
|
||||
})
|
||||
|
||||
o.after(function() {
|
||||
return wrapPromise(function() {
|
||||
a = 0
|
||||
})
|
||||
})
|
||||
|
||||
o.beforeEach(function() {
|
||||
return wrapPromise(function() {
|
||||
b = 1
|
||||
})
|
||||
})
|
||||
o.afterEach(function() {
|
||||
return wrapPromise(function() {
|
||||
b = 0
|
||||
})
|
||||
})
|
||||
|
||||
o("promise functions", async function() {
|
||||
await wrapPromise(function() {
|
||||
o(a).equals(b)
|
||||
o(a).equals(1)("a and b should be initialized")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ suite.on("complete", function() {
|
|||
suite.on("error", console.error.bind(console))
|
||||
|
||||
suite.add({
|
||||
name : "rerender without changes",
|
||||
name : "rerender identical vnode",
|
||||
onStart : function() {
|
||||
this.vdom = m("div", {class: "foo bar", "data-foo": "bar", p: 2},
|
||||
m("header",
|
||||
|
|
@ -119,6 +119,53 @@ suite.add({
|
|||
}
|
||||
})
|
||||
|
||||
suite.add({
|
||||
name : "rerender same tree",
|
||||
fn : function() {
|
||||
m.render(scratch, m("div", {class: "foo bar", "data-foo": "bar", p: 2},
|
||||
m("header",
|
||||
m("h1", {class: "asdf"}, "a ", "b", " c ", 0, " d"),
|
||||
m("nav",
|
||||
m("a", {href: "/foo"}, "Foo"),
|
||||
m("a", {href: "/bar"}, "Bar")
|
||||
)
|
||||
),
|
||||
m("main",
|
||||
m("form", {onSubmit: function onSubmit() {}},
|
||||
m("input", {type: "checkbox", checked: true}),
|
||||
m("input", {type: "checkbox", checked: false}),
|
||||
m("fieldset",
|
||||
m("label",
|
||||
m("input", {type: "radio", checked: true})
|
||||
),
|
||||
m("label",
|
||||
m("input", {type: "radio"})
|
||||
)
|
||||
),
|
||||
m("button-bar",
|
||||
m("button",
|
||||
{style: "width:10px; height:10px; border:1px solid #FFF;"},
|
||||
"Normal CSS"
|
||||
),
|
||||
m("button",
|
||||
{style: "top:0 ; right: 20"},
|
||||
"Poor CSS"
|
||||
),
|
||||
m("button",
|
||||
{style: "invalid-prop:1;padding:1px;font:12px/1.1 arial,sans-serif;", icon: true},
|
||||
"Poorer CSS"
|
||||
),
|
||||
m("button",
|
||||
{style: {margin: 0, padding: "10px", overflow: "visible"}},
|
||||
"Object CSS"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
}
|
||||
})
|
||||
|
||||
suite.add({
|
||||
name : "construct large VDOM tree",
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ o.spec("promise", function() {
|
|||
callAsync(function() {resolve(promise)})
|
||||
})
|
||||
|
||||
promise.then(null, done)
|
||||
promise.then(null, () => done())
|
||||
})
|
||||
o("non-function onFulfilled is ignored", function(done) {
|
||||
var promise = Promise.resolve(1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue