* Minify stream, add stream stuff to releases again * Kill off a lot of tech debt, drop internal utilities from npm 1. Kill `module/`, internalize `bundler/`, privatize `test-utils/` We've been telling people to move elsewhere from these for a while, and it's about time we just pull the plug here and finally remove them. - We officially removed the bundler from the public API in v2.0, and that was the only one of these that was ever publicly documented. Usage should be low enough by now it shouldn't break anyone- I'm not seeing bundler bugs being reported anymore, either. - The `module/` utility was so narrow and caveat-filled that I'm not sure anyone really used it (even us core Mithril devs never really used it), and we only had it documented in the repo folder it lived in. I think only one bug was ever filed, and it's because it somehow ended up completely non-functional without any of us realizing it. - The test utilities were meant to be internal from day 1, but people started using it despite us core developers constantly telling people to look elsewhere and even the docs recommending specific alternatives without mention of our internal mocks. (Now if people would RTFM, that'd be nice...) 2. Add dedicated HTML test files to verify ospec and the promise polyfill, and ensure the promise tests are in pure ES5. These are made specially for those and should be much easier to just run now. 3. Fix the benchmark script to use the real DOM in browsers and to not require as many dependencies to create. Also, tweak them to be much more effective and precise on what's being tested. Previously, it was rendering to the HTML file itself, while now it's rendering to the `body`. This means in browsers, it's triggering layout and everything, benchmarking how well Mithril optimizes for style and layout recalcs, too. It also puts some pressure on the hyperscript parser attribute application, so that can be noticed as well. * Update dependencies
765 lines
18 KiB
JavaScript
765 lines
18 KiB
JavaScript
"use strict"
|
|
|
|
// So it can load correctly in browsers using a global instance.
|
|
var o, callAsync
|
|
|
|
if (typeof require !== "undefined") {
|
|
/* eslint-disable global-require */
|
|
callAsync = require("../../test-utils/callAsync")
|
|
o = require("../ospec")
|
|
/* eslint-enable global-require */
|
|
} else {
|
|
callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout
|
|
o = window.o
|
|
}
|
|
|
|
// this throws an async error that can't be caught in browsers
|
|
if (typeof process !== "undefined") {
|
|
o("incomplete assertion", function(done) {
|
|
var stackMatcher = /([\w\.\\\/\-]+):(\d+):/
|
|
// /!\ this test relies on the `new Error` expression being six lines
|
|
// above the `oo("test", function(){...})` call.
|
|
var matches = (new Error).stack.match(stackMatcher)
|
|
if (matches != null) {
|
|
var name = matches[1]
|
|
var num = Number(matches[2])
|
|
}
|
|
var oo = o.new()
|
|
oo("test", function() {
|
|
oo("incomplete")
|
|
})
|
|
oo.run(function(results) {
|
|
o(results.length).equals(1)
|
|
o(results[0].message).equals("Incomplete assertion in the test definition starting at...")
|
|
o(results[0].pass).equals(null)
|
|
var stack = o.cleanStackTrace(results[0].testError)
|
|
var matches2 = stack && stack.match(stackMatcher)
|
|
if (matches != null && matches2 != null) {
|
|
o(matches[1]).equals(name)
|
|
o(Number(matches2[2])).equals(num + 6)
|
|
}
|
|
done()
|
|
})
|
|
})
|
|
}
|
|
|
|
o("o.only", function(done) {
|
|
var oo = o.new()
|
|
|
|
oo.spec("won't run", function() {
|
|
oo("nope, skipped", function() {
|
|
o(true).equals(false)
|
|
})
|
|
})
|
|
|
|
oo.spec("ospec", function() {
|
|
oo("skipped as well", function() {
|
|
oo(true).equals(false)
|
|
})
|
|
oo.only(".only()", function() {
|
|
oo(2).equals(2)
|
|
}, true)
|
|
oo.only("another .only()", function(done) {
|
|
done("that fails")
|
|
}, true)
|
|
})
|
|
|
|
oo.run(function(results){
|
|
o(results.length).equals(2)
|
|
o(results[0].pass).equals(true)
|
|
o(results[1].pass).equals(false)
|
|
|
|
done()
|
|
})
|
|
})
|
|
|
|
// Predicate test passing on clone results
|
|
o.spec("reporting", function() {
|
|
var oo
|
|
o.beforeEach(function(){
|
|
oo = o.new()
|
|
|
|
oo.spec("clone", function() {
|
|
oo("fail", function() {
|
|
oo(true).equals(false)
|
|
})
|
|
|
|
oo("pass", function() {
|
|
oo(true).equals(true)
|
|
})
|
|
})
|
|
})
|
|
o("reports per instance", function(done, timeout) {
|
|
timeout(100) // Waiting on clone
|
|
|
|
oo.run(function(results) {
|
|
o(typeof results).equals("object")
|
|
o("length" in results).equals(true)
|
|
o(results.length).equals(2)("Two results")
|
|
|
|
o("error" in results[0] && "pass" in results[0]).equals(true)("error and pass keys present in failing result")
|
|
o("message" in results[0] && "context" in results[0]).equals(true)("message and context keys present in failing result")
|
|
o("message" in results[1] && "context" in results[1]).equals(true)("message and context keys present in passing result")
|
|
o(results[0].pass).equals(false)("Test meant to fail has failed")
|
|
o(results[1].pass).equals(true)("Test meant to pass has passed")
|
|
|
|
done()
|
|
})
|
|
})
|
|
o("o.report() returns the number of failures", function () {
|
|
var log = console.log, error = console.error
|
|
console.log = o.spy()
|
|
console.error = o.spy()
|
|
|
|
function makeError(msg) {try{throw msg ? new Error(msg) : new Error} catch(e){return e}}
|
|
try {
|
|
var errCount = o.report([{pass: true}, {pass: true}])
|
|
|
|
o(errCount).equals(0)
|
|
o(console.log.callCount).equals(1)
|
|
o(console.error.callCount).equals(0)
|
|
|
|
errCount = o.report([
|
|
{pass: false, error: makeError("hey"), message: "hey"}
|
|
])
|
|
|
|
o(errCount).equals(1)
|
|
o(console.log.callCount).equals(2)
|
|
o(console.error.callCount).equals(1)
|
|
|
|
errCount = o.report([
|
|
{pass: false, error: makeError("hey"), message: "hey"},
|
|
{pass: true},
|
|
{pass: false, error: makeError("ho"), message: "ho"}
|
|
])
|
|
|
|
o(errCount).equals(2)
|
|
o(console.log.callCount).equals(3)
|
|
o(console.error.callCount).equals(3)
|
|
} catch (e) {
|
|
o(1).equals(0)("Error while testing the reporter")
|
|
}
|
|
|
|
console.log = log
|
|
console.error = error
|
|
})
|
|
})
|
|
|
|
o.spec("ospec", function() {
|
|
o.spec("sync", function() {
|
|
var a = 0, b = 0, illegalAssertionThrows = false
|
|
var reservedTestNameTrows = false
|
|
|
|
o.before(function() {a = 1})
|
|
o.after(function() {a = 0})
|
|
|
|
o.beforeEach(function() {b = 1})
|
|
o.afterEach(function() {b = 0})
|
|
|
|
try {o("illegal assertion")} catch (e) {illegalAssertionThrows = true}
|
|
try {o("\x01reserved test name", function(){})} catch (e) {reservedTestNameTrows = true}
|
|
|
|
o("assertions", function() {
|
|
var nestedTestDeclarationThrows = false
|
|
try {o("illegal nested test", function(){})} catch (e) {nestedTestDeclarationThrows = true}
|
|
|
|
o(illegalAssertionThrows).equals(true)
|
|
o(nestedTestDeclarationThrows).equals(true)
|
|
o(reservedTestNameTrows).equals(true)
|
|
|
|
var spy = o.spy()
|
|
spy(a)
|
|
|
|
o(a).equals(b)
|
|
o(a).notEquals(2)
|
|
o({a: [1, 2], b: 3}).deepEquals({a: [1, 2], b: 3})
|
|
o([{a: 1, b: 2}, {c: 3}]).deepEquals([{a: 1, b: 2}, {c: 3}])
|
|
o(function(){throw new Error()}).throws(Error)
|
|
o(function(){"ayy".foo()}).throws(TypeError)
|
|
o(function(){Math.PI.toFixed(Math.pow(10,20))}).throws(RangeError)
|
|
o(function(){decodeURIComponent("%")}).throws(URIError)
|
|
|
|
o(function(){"ayy".foo()}).notThrows(SyntaxError)
|
|
o(function(){throw new Error("foo")}).throws("foo")
|
|
o(function(){throw new Error("foo")}).notThrows("bar")
|
|
|
|
var undef1 = {undef: void 0}
|
|
var undef2 = {UNDEF: void 0}
|
|
|
|
o(undef1).notDeepEquals(undef2)
|
|
o(undef1).notDeepEquals({})
|
|
o({}).notDeepEquals(undef1)
|
|
|
|
var sparse1 = [void 1, void 2, void 3]
|
|
delete sparse1[0]
|
|
var sparse2 = [void 1, void 2, void 3]
|
|
delete sparse2[1]
|
|
|
|
o(sparse1).notDeepEquals(sparse2)
|
|
|
|
var monkeypatch1 = [1, 2]
|
|
monkeypatch1.field = 3
|
|
var monkeypatch2 = [1, 2]
|
|
monkeypatch2.field = 4
|
|
|
|
o(monkeypatch1).notDeepEquals([1, 2])
|
|
o(monkeypatch1).notDeepEquals(monkeypatch2)
|
|
|
|
monkeypatch2.field = 3
|
|
o(monkeypatch1).deepEquals(monkeypatch2)
|
|
|
|
monkeypatch1.undef = undefined
|
|
monkeypatch2.UNDEF = undefined
|
|
|
|
o(monkeypatch1).notDeepEquals(monkeypatch2)
|
|
|
|
var values = ["a", "", 1, 0, true, false, null, undefined, Date(0), ["a"], [], function() {return arguments}.call(), new Uint8Array(), {a: 1}, {}]
|
|
for (var i = 0; i < values.length; i++) {
|
|
for (var j = 0; j < values.length; j++) {
|
|
if (i === j) o(values[i]).deepEquals(values[j])
|
|
else o(values[i]).notDeepEquals(values[j])
|
|
}
|
|
}
|
|
|
|
o(spy.callCount).equals(1)
|
|
o(spy.args.length).equals(1)
|
|
o(spy.args[0]).equals(1)
|
|
o(spy.calls.length).equals(1)
|
|
o(spy.calls[0]).deepEquals({this: undefined, args: [1]})
|
|
})
|
|
o("spy wrapping", function() {
|
|
var spy = o.spy(function view(vnode){
|
|
this.drawn = true
|
|
|
|
return {tag: "div", children: vnode.children}
|
|
})
|
|
var children = [""]
|
|
var state = {}
|
|
|
|
var output = spy.call(state, {children: children})
|
|
|
|
o(spy.length).equals(1)
|
|
o(spy.name).equals("view")
|
|
o(spy.callCount).equals(1)
|
|
o(spy.args.length).equals(1)
|
|
o(spy.args[0]).deepEquals({children: children})
|
|
o(spy.calls.length).equals(1)
|
|
o(spy.calls[0]).deepEquals({this: state, args: [{children: children}]})
|
|
o(state).deepEquals({drawn: true})
|
|
o(output).deepEquals({tag: "div", children: children})
|
|
})
|
|
})
|
|
o.spec("async callback", function() {
|
|
var a = 0, b = 0
|
|
o.after(function() {
|
|
o(a).equals(0)
|
|
o(b).equals(0)
|
|
})
|
|
o.spec("", function(){
|
|
o.before(function(done) {
|
|
callAsync(function() {
|
|
a = 1
|
|
done()
|
|
})
|
|
})
|
|
o.after(function(done) {
|
|
callAsync(function() {
|
|
a = 0
|
|
done()
|
|
})
|
|
})
|
|
|
|
o.beforeEach(function(done) {
|
|
o(b).equals(0)
|
|
callAsync(function() {
|
|
b = 1
|
|
done()
|
|
})
|
|
})
|
|
o.afterEach(function(done) {
|
|
callAsync(function() {
|
|
b = 0
|
|
done()
|
|
})
|
|
})
|
|
|
|
o("hooks work as intended the first time", function(done) {
|
|
callAsync(function() {
|
|
var spy = o.spy()
|
|
spy(a)
|
|
|
|
o(a).equals(1)
|
|
o(b).equals(1)
|
|
|
|
done()
|
|
})
|
|
})
|
|
o("hooks work as intended the second time", function(done) {
|
|
callAsync(function() {
|
|
var spy = o.spy()
|
|
spy(a)
|
|
|
|
o(a).equals(1)
|
|
o(b).equals(1)
|
|
|
|
done()
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
o.spec("throwing in test context is recorded as a failure", function() {
|
|
var oo
|
|
o.beforeEach(function(){oo = o.new()})
|
|
o.afterEach(function() {
|
|
oo.run(function(results) {
|
|
o(results.length).equals(1)
|
|
o(results[0].pass).equals(false)
|
|
})
|
|
})
|
|
o("sync test", function() {
|
|
oo("throw in sync test", function() {throw new Error})
|
|
})
|
|
o("async test", function() {
|
|
oo("throw in async test", function(done) {
|
|
throw new Error
|
|
done() // eslint-disable-line no-unreachable
|
|
})
|
|
})
|
|
})
|
|
|
|
o.spec("timeout", function () {
|
|
o("when using done()", function(done) {
|
|
var oo = o.new()
|
|
var err
|
|
// the success of this test is dependent on having the
|
|
// oo() call three linew below this one
|
|
try {throw new Error} catch(e) {err = e}
|
|
if (err.stack) {
|
|
var line = Number(err.stack.match(/:(\d+):/)[1])
|
|
oo("", function(oodone, timeout) {
|
|
// oodone() keep this line for now
|
|
timeout(1)
|
|
})
|
|
oo.run((function(results) {
|
|
o(results.length).equals(1)
|
|
o(results[0].pass).equals(false)
|
|
// todo test cleaned up results[0].error stack trace for the presence
|
|
// of the timeout stack entry
|
|
o(results[0].testError instanceof Error).equals(true)
|
|
o(o.cleanStackTrace(results[0].testError).indexOf("test-ospec.js:" + (line + 3) + ":")).notEquals(-1)
|
|
|
|
done()
|
|
}))
|
|
} else {
|
|
done()
|
|
}
|
|
})
|
|
o("when using a thenable", function(done) {
|
|
var oo = o.new()
|
|
var err
|
|
// the success of this test is dependent on having the
|
|
// oo() call three linew below this one
|
|
try {throw new Error} catch(e) {err = e}
|
|
if (err.stack) {
|
|
var line = Number(err.stack.match(/:(\d+):/)[1])
|
|
oo("", function() {
|
|
oo.timeout(1)
|
|
return {then: function(){}}
|
|
})
|
|
oo.run((function(results) {
|
|
o(results.length).equals(1)
|
|
o(results[0].pass).equals(false)
|
|
o(results[0].testError instanceof Error).equals(true)
|
|
o(o.cleanStackTrace(results[0].testError).indexOf("test-ospec.js:" + (line + 3) + ":")).notEquals(-1)
|
|
|
|
done()
|
|
}))
|
|
} else {
|
|
done()
|
|
}
|
|
})
|
|
})
|
|
o.spec("o.timeout", function() {
|
|
o("throws when called out of test definitions", function(done) {
|
|
var oo = o.new()
|
|
var count = 0
|
|
try { oo.timeout(1) } catch (e) { count++ }
|
|
oo.spec("a spec", function() {
|
|
try { oo.timeout(1) } catch (e) { count++ }
|
|
})
|
|
oo("", function() {
|
|
oo.timeout(30)
|
|
return {then: function(f) {setTimeout(f)}}
|
|
})
|
|
oo.run(function(){
|
|
o(count).equals(2)
|
|
|
|
done()
|
|
})
|
|
})
|
|
o("works", function(done) {
|
|
var oo = o.new()
|
|
var t = new Date
|
|
oo("", function() {
|
|
oo.timeout(10)
|
|
return {then: function() {}}
|
|
})
|
|
oo.run(function(){
|
|
o(new Date - t >= 10).equals(true)
|
|
o(200 > new Date - t).equals(true)
|
|
|
|
done()
|
|
})
|
|
})
|
|
})
|
|
o.spec("o.specTimeout", function() {
|
|
o("throws when called inside of test definitions", function(done) {
|
|
var err
|
|
var oo = o.new()
|
|
oo("", function() {
|
|
try { oo.specTimeout(5) } catch (e) {err = e}
|
|
return {then: function(f) {setTimeout(f)}}
|
|
})
|
|
oo.run(function(){
|
|
o(err instanceof Error).equals(true)
|
|
|
|
done()
|
|
})
|
|
})
|
|
o("works", function(done) {
|
|
var oo = o.new()
|
|
var t
|
|
|
|
oo.specTimeout(10)
|
|
oo.beforeEach(function () {
|
|
t = new Date
|
|
})
|
|
oo.afterEach(function () {
|
|
var diff = new Date - t
|
|
o(diff >= 10).equals(true)
|
|
o(diff < 200).equals(true)
|
|
})
|
|
|
|
oo("", function() {
|
|
oo(true).equals(true)
|
|
|
|
return {then: function() {}}
|
|
})
|
|
|
|
oo.run(function(results) {
|
|
o(results.length).equals(2)
|
|
o(results[0].pass).equals(true)
|
|
o(results[1].pass).equals(false)
|
|
done()
|
|
})
|
|
})
|
|
o("The parent and sibling suites are not affected by the specTimeout", function(done) {
|
|
var oo = o.new()
|
|
var t
|
|
|
|
oo.specTimeout(50)
|
|
oo.beforeEach(function () {
|
|
t = new Date
|
|
})
|
|
oo.afterEach(function () {
|
|
var diff = new Date - t
|
|
o(diff >= 50).equals(true)
|
|
o(diff < 80).equals(true)
|
|
})
|
|
|
|
oo.spec("nested 1", function () {
|
|
oo.specTimeout(80)
|
|
})
|
|
|
|
oo("", function() {
|
|
oo(true).equals(true)
|
|
|
|
return {then: function() {}}
|
|
})
|
|
oo.spec("nested 2", function () {
|
|
oo.specTimeout(80)
|
|
})
|
|
oo.spec("nested 3", function () {
|
|
oo("", function() {
|
|
oo(true).equals(true)
|
|
|
|
return {then: function() {}}
|
|
})
|
|
})
|
|
oo.run(function(results) {
|
|
o(results.length).equals(4)
|
|
o(results[0].pass).equals(true)
|
|
o(results[1].pass).equals(false)
|
|
o(results[2].pass).equals(true)
|
|
o(results[3].pass).equals(false)
|
|
done()
|
|
})
|
|
})
|
|
o("nested suites inherit the specTimeout", function(done) {
|
|
var oo = o.new()
|
|
|
|
oo.specTimeout(50)
|
|
oo.spec("nested", function () {
|
|
oo.spec("deeply", function() {
|
|
var t
|
|
|
|
oo.beforeEach(function () {
|
|
t = new Date
|
|
})
|
|
oo.afterEach(function () {
|
|
var diff = new Date - t
|
|
o(diff >= 50).equals(true)
|
|
o(diff < 80).equals(true)
|
|
})
|
|
|
|
oo("", function() {
|
|
oo(true).equals(true)
|
|
|
|
return {then: function() {}}
|
|
})
|
|
})
|
|
})
|
|
oo.run(function(results) {
|
|
o(results.length).equals(2)
|
|
o(results[0].pass).equals(true)
|
|
o(results[1].pass).equals(false)
|
|
done()
|
|
})
|
|
})
|
|
})
|
|
|
|
o.spec("calling done() twice throws", function () {
|
|
o("two successes", function(done) {
|
|
var oo = o.new()
|
|
var err = null
|
|
oo("foo", function(oodone) {
|
|
try {
|
|
oodone()
|
|
oodone()
|
|
} catch (e) {
|
|
err = e
|
|
}
|
|
o(err instanceof Error).equals(true)
|
|
o(err.message).equals("'oodone()' should only be called once.")
|
|
})
|
|
oo.run(function(results) {
|
|
o(results.length).equals(1)
|
|
o(results[0].pass).equals(true)
|
|
done()
|
|
})
|
|
})
|
|
o("a success followed by an error", function(done) {
|
|
var oo = o.new()
|
|
var err = null
|
|
oo("foo", function(oodone) {
|
|
try {
|
|
oodone()
|
|
oodone("error")
|
|
} catch (e) {
|
|
err = e
|
|
}
|
|
o(err instanceof Error).equals(true)
|
|
o(err.message).equals("'oodone()' should only be called once.")
|
|
})
|
|
oo.run(function(results) {
|
|
o(results.length).equals(1)
|
|
o(results[0].pass).equals(true)
|
|
done()
|
|
})
|
|
})
|
|
o("two errors", function(done) {
|
|
var oo = o.new()
|
|
var err = null
|
|
oo("foo", function(oodone) {
|
|
try {
|
|
oodone("bar")
|
|
oodone("baz")
|
|
} catch (e) {
|
|
err = e
|
|
}
|
|
o(err instanceof Error).equals(true)
|
|
o(err.message).equals("'oodone()' should only be called once.")
|
|
})
|
|
oo.run(function(results) {
|
|
o(results.length).equals(1)
|
|
o(results[0].pass).equals(false)
|
|
o(results[0].message).equals("bar")
|
|
done()
|
|
})
|
|
})
|
|
o("an error followed by a success", function(done) {
|
|
var oo = o.new()
|
|
var err = null
|
|
oo("foo", function(oodone) {
|
|
try {
|
|
oodone("bar")
|
|
oodone()
|
|
} catch (e) {
|
|
err = e
|
|
}
|
|
o(err instanceof Error).equals(true)
|
|
o(err.message).equals("'oodone()' should only be called once.")
|
|
})
|
|
oo.run(function(results) {
|
|
o(results.length).equals(1)
|
|
o(results[0].pass).equals(false)
|
|
o(results[0].message).equals("bar")
|
|
done()
|
|
})
|
|
})
|
|
})
|
|
|
|
o.spec("stack trace cleaner", function() {
|
|
o("handles line breaks", function() {
|
|
try {
|
|
throw new Error("line\nbreak")
|
|
} catch(error) {
|
|
var trace = o.cleanStackTrace(error)
|
|
o(trace).notEquals("break")
|
|
o(trace.indexOf("test-ospec.js") !== -1).equals(true)
|
|
}
|
|
})
|
|
})
|
|
|
|
o.spec("async promise", function() {
|
|
var a = 0, b = 0
|
|
|
|
function wrapPromise(fn) {
|
|
return new Promise(function (resolve, reject) {
|
|
callAsync(function () {
|
|
try {
|
|
fn()
|
|
resolve()
|
|
} catch(e) {
|
|
reject(e)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
o.before(function() {
|
|
return wrapPromise(function () {
|
|
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", function() {
|
|
return wrapPromise(function() {
|
|
o(a).equals(b)
|
|
o(a).equals(1)("a and b should be initialized")
|
|
})
|
|
})
|
|
})
|
|
|
|
o.spec("descriptions", function() {
|
|
o("description returned on failure", function(done) {
|
|
var oo = o.new()
|
|
oo("no description", function() {
|
|
oo(1).equals(2)
|
|
})
|
|
oo("description", function() {
|
|
oo(1).equals(2)("howdy")
|
|
})
|
|
oo.run(function(results) {
|
|
o(results.length).equals(2)
|
|
o(results[1].message).equals(`howdy\n\n${results[0].message}`)
|
|
o(results[1].pass).equals(false)
|
|
done()
|
|
})
|
|
})
|
|
})
|
|
})
|
|
o.spec("the done parser", function() {
|
|
o("accepts non-English names", function() {
|
|
var oo = o.new()
|
|
var threw = false
|
|
oo("test", function(完了) {
|
|
oo(true).equals(true)
|
|
完了()
|
|
})
|
|
try {oo.run(function(){})} catch(e) {threw = true}
|
|
o(threw).equals(false)
|
|
})
|
|
o("tolerates comments", function() {
|
|
var oo = o.new()
|
|
var threw = false
|
|
oo("test", function(/*hey
|
|
*/ /**/ //ho
|
|
done /*hey
|
|
*/ /**/ //huuu
|
|
, timeout
|
|
) {
|
|
timeout(5)
|
|
oo(true).equals(true)
|
|
done()
|
|
})
|
|
try {oo.run(function(){})} catch(e) {threw = true}
|
|
o(threw).equals(false)
|
|
})
|
|
/*eslint-disable no-eval*/
|
|
try {eval("(()=>{})()"); o.spec("with ES6 arrow functions", function() {
|
|
function getCommentContent(f) {
|
|
f = f.toString()
|
|
return f.slice(f.indexOf("/*") + 2, f.lastIndexOf("*/"))
|
|
}
|
|
o("has no false positives 1", function(){
|
|
var oo = o.new()
|
|
var threw = false
|
|
eval(getCommentContent(function(){/*
|
|
oo(
|
|
'Async test parser mistakenly identified 1st token after a parens to be `done` reference',
|
|
done => {
|
|
oo(threw).equals(false)
|
|
done()
|
|
}
|
|
)
|
|
*/}))
|
|
try {oo.run(function(){})} catch(e) {threw = true}
|
|
o(threw).equals(false)
|
|
})
|
|
o("has no false negatives", function(){
|
|
var oo = o.new()
|
|
var threw = false
|
|
eval(getCommentContent(function(){/*
|
|
oo(
|
|
"Multiple references to the wrong thing doesn't fool the checker",
|
|
done => {
|
|
oo(threw).equals(false)
|
|
oo(threw).equals(false)
|
|
}
|
|
)
|
|
*/}))
|
|
try {oo.run(function(){})} catch(e) {threw = true}
|
|
o(threw).equals(true)
|
|
})
|
|
o("isn't fooled by comments", function(){
|
|
var oo = o.new()
|
|
var threw = false
|
|
oo(
|
|
"comments won't throw the parser off",
|
|
eval("done /*hey*/ /**/ => {oo(threw).equals(false);done()}")
|
|
)
|
|
try {oo.run(function(){})} catch(e) {threw = true}
|
|
o(threw).equals(false)
|
|
})
|
|
})} catch (e) {/*ES5 env, or no eval, ignore*/}
|
|
/*eslint-enable no-eval*/
|
|
})
|