Skip to content

Commit

Permalink
fix: Correctly handle timed out tests in Jest
Browse files Browse the repository at this point in the history
When a test times out, Jest passes a message string back as an
error instead of an Error instace. Handle this case.

Fixes #46
  • Loading branch information
dividedmind committed Dec 4, 2023
1 parent 0be438e commit 35e0147
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 10 deletions.
7 changes: 1 addition & 6 deletions src/hooks/jest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function eventHandler(event: Circus.Event) {
break;
case "test_fn_failure":
recording.metadata.test_status = "failed";
recording.metadata.exception = extractTestError(event.test.errors);
recording.metadata.exception = exceptionMetadata(event.error);
return recording.finish();
case "test_fn_success":
recording.metadata.test_status = "succeeded";
Expand All @@ -80,8 +80,3 @@ function createRecording(test: Circus.TestEntry): Recording {
const recording = new Recording("tests", "jest", ...testNames(test));
return recording;
}

function extractTestError([error]: Circus.TestError[]): AppMap.ExceptionMetadata | undefined {
const exc = (Array.isArray(error) ? error[0] : error) as unknown;
if (exc) return exceptionMetadata(exc);
}
6 changes: 4 additions & 2 deletions src/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export const defaultMetadata: Partial<AppMap.Metadata> & { client: AppMap.Client
app: appName,
};

export function exceptionMetadata(exc: unknown): AppMap.ExceptionMetadata | undefined {
return pick(examineException(exc)[0], "class", "message");
export function exceptionMetadata(error: unknown): AppMap.ExceptionMetadata | undefined {
const [exc] = examineException(error);
if (exc) return pick(exc, "class", "message");
if (typeof error === "string") return { message: error, class: "String" };
}
82 changes: 80 additions & 2 deletions test/__snapshots__/jest.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ exports[`mapping Jest tests 1`] = `
{
"children": [
{
"location": "test.js:17",
"location": "test.js:18",
"name": "errorOut",
"static": true,
"type": "function",
Expand All @@ -28,7 +28,7 @@ exports[`mapping Jest tests 1`] = `
"defined_class": "",
"event": "call",
"id": 1,
"lineno": 17,
"lineno": 18,
"method_id": "errorOut",
"parameters": [],
"path": "test.js",
Expand Down Expand Up @@ -75,6 +75,84 @@ exports[`mapping Jest tests 1`] = `
},
"version": "1.12",
},
"./tmp/appmap/jest/exception handling/times out.appmap.json": {
"classMap": [
{
"children": [
{
"children": [
{
"location": "test.js:22",
"name": "wait",
"static": true,
"type": "function",
},
],
"name": "test",
"type": "class",
},
],
"name": "test",
"type": "package",
},
],
"events": [
{
"defined_class": "",
"event": "call",
"id": 1,
"lineno": 22,
"method_id": "wait",
"parameters": [
{
"class": "Number",
"name": "ms",
"value": "20",
},
],
"path": "test.js",
"static": true,
"thread_id": 0,
},
{
"elapsed": 31.337,
"event": "return",
"id": 2,
"parent_id": 1,
"return_value": {
"class": "Promise",
"object_id": 3,
"value": "Promise { <pending> }",
},
"thread_id": 0,
},
],
"metadata": {
"app": "jest-appmap-node-test",
"client": {
"name": "appmap-node",
"url": "https://github.com/getappmap/appmap-node",
"version": "test node-appmap version",
},
"exception": {
"class": "String",
"message": "Exceeded timeout of 10 ms for a test.
Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout.",
},
"language": {
"engine": "Node.js",
"name": "javascript",
"version": "test node version",
},
"name": "exception handling times out",
"recorder": {
"name": "jest",
"type": "tests",
},
"test_status": "failed",
},
"version": "1.12",
},
"./tmp/appmap/jest/sub/subtracts numbers correctly.appmap.json": {
"classMap": [
{
Expand Down
7 changes: 7 additions & 0 deletions test/jest/test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { setTimeout } = require("timers/promises");
const { sum, sub } = require("./calc");

describe(sum, () => {
Expand All @@ -18,6 +19,12 @@ function errorOut() {
throw new TestError("test error");
}

async function wait(ms) {
await setTimeout(ms);
}

describe("exception handling", () => {
it("intentionally throws", errorOut);

it("times out", () => wait(20), 10);
});

0 comments on commit 35e0147

Please sign in to comment.