Public
Edited
Oct 4
Insert cell
Insert cell
Insert cell
Insert cell
it("3 equals 3", () => {
expect(3).to.equal(3);
expect({ a: 1 }).to.deep.equal({ a: 1 });
})
Insert cell
it("1 is undefined", () => {
expect(1).to.be.undefined();
})
Insert cell
it('calls done after 1000ms', done => {
Promises.tick(1000).then(() => done());
})
Insert cell
it('forgets to call done', done => {
//
})
Insert cell
it("1 is undefined within promise callback", (done) => {
Promises.tick(1000).then(() => {
expect(1).to.be.undefined();
done();
});
})
Insert cell
it("3 equals 3 in async test", async () => {
expect(3).to.equal(3);
})
Insert cell
it("1 is undefined within async test", async () => {
await Promises.tick(1000)
expect(1).to.be.undefined();
})
Insert cell
it("async test does not resolve after timeout", async () => {
await Promises.tick(10000)
})
Insert cell
Insert cell
timeout = 2000
Insert cell
md` ## Implementation`
Insert cell
test = function (title, fn) {
if (typeof fn === "undefined") throw new NoTestError();
if (fn[Symbol.toStringTag] == "AsyncFunction") return testAsync(title, fn);
if (fn.length === 1) return testWithDoneCallback(title, fn);
else return testSync(title, fn);
}
Insert cell
it = test
Insert cell
testWithDoneCallback = function (title, fn) {
let doneCb;

const done = new Promise((s) => {
doneCb = () => s(success(title));
});

testSync(title, () => fn(doneCb));
return Promise.race([
Promises.tick(timeout).then(() => failure(title, new NotDoneError())),
done
]);
}
Insert cell
testSync = function(title, fn) {
try {
fn();
} catch (e) {
return failure(title, e);
}
return success(title);
}
Insert cell
testAsync = function (title, asyncFn) {
const test = asyncFn()
.then(() => success(title))
.catch((e) => failure(title, e))

const testTimeout = Promises.tick(timeout).then(() => failure(title, new AsyncTestTimeoutError()))
return Promise.race([test, testTimeout]);
}
Insert cell
success = (title = "Test Passed") =>
html`<div style="color:green; white-space: pre-wrap; font: 14px/1.5 Menlo,Consolas,monospace" >✔ ${title}</div>`
Insert cell
failure = (title = "Test Failed", error) => {
const prettyError = Object.create(error);
prettyError.toString = function () {
return `✘ ${title}\n ${error.toString()}`;
};
throw prettyError;
}
Insert cell
class NotDoneError extends Error {
constructor() {
super("done() was not called within " + timeout + "ms");
this.name = "NotDoneError";
}
}
Insert cell
class NoTestError extends Error {
constructor() {
super("no test was provided to the test runner");
this.name = "NoTestError";
}
}
Insert cell
class AsyncTestTimeoutError extends Error {
constructor() {
super(`async test did not finish within ${timeout} ms`)
this.name = "AsyncTestTimeoutError"
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more