1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 22:27:35 +00:00

test-js: Sometimes include more details for failures

LibJS doesn't store stacks for exception objects, so this
only amends test-common.js's __expect() with an optional
`details` function that can produce a more detailed error
message, and it lets test-js.cpp read and print that
error message.  I added the optional details parameter to
a few matchers, most notably toBe() where it now prints
expected and actual value.

It'd be nice to have line numbers of failures, but that
seems hard to do with the current design, and this is already
much better than the current state.
This commit is contained in:
Nico Weber 2020-08-21 21:53:54 -04:00 committed by Andreas Kling
parent 3fbb02c3cc
commit 96891669c3
2 changed files with 26 additions and 14 deletions

View file

@ -63,14 +63,15 @@ class ExpectationError extends Error {
toBe(value) {
this.__doMatcher(() => {
this.__expect(Object.is(this.target, value));
this.__expect(Object.is(this.target, value),
() => ("toBe: expected _" + String(value) + "_, got _" + String(this.target) + "_"));
});
}
// FIXME: Take a precision argument like jest's toBeCloseTo matcher
toBeCloseTo(value) {
this.__expect(typeof this.target === "number");
this.__expect(typeof value === "number");
this.__expect(typeof this.target === "number", () => "toBeCloseTo: target not of type number");
this.__expect(typeof value === "number", () => "toBeCloseTo: argument not of type number");
this.__doMatcher(() => {
this.__expect(Math.abs(this.target - value) < 0.000001);
@ -78,7 +79,7 @@ class ExpectationError extends Error {
}
toHaveLength(length) {
this.__expect(typeof this.target.length === "number");
this.__expect(typeof this.target.length === "number", () => "toHaveLength: target.length not of type number");
this.__doMatcher(() => {
this.__expect(Object.is(this.target.length, length));
@ -120,7 +121,7 @@ class ExpectationError extends Error {
toBeDefined() {
this.__doMatcher(() => {
this.__expect(this.target !== undefined);
this.__expect(this.target !== undefined, () => "toBeDefined: target was undefined");
});
}
@ -138,13 +139,13 @@ class ExpectationError extends Error {
toBeUndefined() {
this.__doMatcher(() => {
this.__expect(this.target === undefined);
this.__expect(this.target === undefined, () => "toBeUndefined: target was not undefined");
});
}
toBeNaN() {
this.__doMatcher(() => {
this.__expect(isNaN(this.target));
this.__expect(isNaN(this.target), () => ("toBeNaN: target was _" + String(this.target) + "_, not NaN"));
});
}
@ -258,9 +259,8 @@ class ExpectationError extends Error {
// jest-extended
fail(message) {
// FIXME: message is currently ignored
this.__doMatcher(() => {
this.__expect(false);
this.__expect(false, message);
});
}
@ -391,12 +391,17 @@ class ExpectationError extends Error {
} catch (e) {
if (e.name === "ExpectationError") threw = true;
}
if (!threw) throw new ExpectationError();
if (!threw) throw new ExpectationError("not: test didn't fail");
}
}
__expect(value) {
if (value !== true) throw new ExpectationError();
__expect(value, details) {
if (value !== true) {
if (details !== undefined)
throw new ExpectationError(details());
else
throw new ExpectationError();
}
}
}
@ -432,6 +437,7 @@ class ExpectationError extends Error {
} catch (e) {
suite[message] = {
result: "fail",
details: String(e),
};
}
};