Skip to content

Commit

Permalink
Implemented awaiting an uncaught exception
Browse files Browse the repository at this point in the history
  • Loading branch information
kraenhansen committed Jul 19, 2024
1 parent 2914c69 commit 7c26045
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 14 deletions.
26 changes: 24 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"--import=tsx",
"--expose_gc",
"--enable-source-maps",
"--no-warnings",
"--force-node-api-uncaught-exceptions-policy",
"${workspaceRoot}/node_modules/mocha/lib/cli/cli.js",
"--require",
"src/node/inject-dev-environment.ts",
Expand All @@ -85,6 +85,28 @@
"${input:integrationTestFilter}"
]
},
{
"type": "lldb",
"request": "launch",
"name": "LLDB: Integration tests (throwing from listeners)",
"program": "node",
"cwd": "${workspaceRoot}/integration-tests/tests",
"args": [
"--inspect",
"--import=tsx",
"--expose_gc",
"--enable-source-maps",
"--force-node-api-uncaught-exceptions-policy",
"${workspaceRoot}/node_modules/mocha/lib/cli/cli.js",
"--require",
"src/node/inject-dev-environment.ts",
"src/node/index.ts",
"--timeout",
"10000",
"--grep",
"can throw from a listener"
]
},
{
"type": "node",
"presentation": {
Expand All @@ -99,7 +121,7 @@
"--import=tsx",
"--expose_gc",
"--enable-source-maps",
"--no-warnings"
"--force-node-api-uncaught-exceptions-policy"
],
"args": [
"--require",
Expand Down
6 changes: 3 additions & 3 deletions integration-tests/environments/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
"scripts": {
"test": "wireit",
"test:commonjs": "wireit",
"test:ci": "mocha-remote --reporter @realm/mocha-reporter -- tsx index.mjs",
"test:ci": "mocha-remote --reporter @realm/mocha-reporter -- tsx --force-node-api-uncaught-exceptions-policy index.mjs",
"lint": "eslint --ext js,mjs ."
},
"wireit": {
"test": {
"command": "mocha-remote --reporter @realm/mocha-reporter -- tsx index.mjs",
"command": "mocha-remote --reporter @realm/mocha-reporter -- tsx --force-node-api-uncaught-exceptions-policy index.mjs",
"dependencies": [
"../../../packages/realm:build:ts",
"../../../packages/realm:build:node",
"../../../packages/mocha-reporter:bundle"
]
},
"test:commonjs": {
"command": "mocha-remote --reporter @realm/mocha-reporter -- tsx index.cjs",
"command": "mocha-remote --reporter @realm/mocha-reporter -- tsx --force-node-api-uncaught-exceptions-policy index.cjs",
"dependencies": [
"../../../packages/realm:build:ts",
"../../../packages/realm:build:node",
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/.mocharc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"import=tsx",
"expose_gc",
"enable-source-maps",
"no-warnings"
"force-node-api-uncaught-exceptions-policy"
],
"reporter": "@realm/mocha-reporter",
"require": [
Expand Down
23 changes: 23 additions & 0 deletions integration-tests/tests/src/node/setup-globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,29 @@ Object.assign(globalThis, {
},
},
gc: vm.runInNewContext("gc"),
async nextUncaughtException(timeoutMs = 5000) {
// Remove any other listeners, storing them later so they can be restored
const listenersBefore = process.listeners("uncaughtException");
process.removeAllListeners("uncaughtException");
try {
return await new Promise<Error>((resolve, reject) => {
const timeoutTimer = setTimeout(() => {
process.off("uncaughtException", handleException);
const error = new Error(`Timed out waiting for uncaught exception (waited ${timeoutMs} ms)`);
reject(error);
}, timeoutMs);
function handleException(error: Error) {
clearTimeout(timeoutTimer);
resolve(error);
}
process.once("uncaughtException", handleException);
});
} finally {
for (const listener of listenersBefore) {
process.addListener("uncaughtException", listener);
}
}
},
});

// Indicate that the tests are running in Node
Expand Down
12 changes: 10 additions & 2 deletions integration-tests/tests/src/tests/observable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,12 +467,16 @@ describe("Observable", () => {
});

it.skipIf(
!environment.testThrowingListeners,
typeof nextUncaughtException !== "function",
"can throw from a listener",
async function (this: RealmObjectContext<Person>) {
assert(typeof nextUncaughtException === "function", "Expected ability to await an uncaught exception");
const uncaughtException = nextUncaughtException();
this.object.addListener(() => {
throw new Error("boom!");
});
const error = await uncaughtException;
expect(error.message).equals("boom!");
},
);

Expand Down Expand Up @@ -880,12 +884,16 @@ describe("Observable", () => {
});

it.skipIf(
!environment.testThrowingListeners,
typeof nextUncaughtException !== "function",
"can throw from a listener",
async function (this: RealmObjectContext<Person>) {
assert(typeof nextUncaughtException === "function", "Expected ability to await an uncaught exception");
const uncaughtException = nextUncaughtException();
this.realm.objects("Person").addListener(() => {
throw new Error("boom!");
});
const error = await uncaughtException;
expect(error.message).equals("boom!");
},
);

Expand Down
7 changes: 1 addition & 6 deletions integration-tests/tests/src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,6 @@ type KnownEnvironment = {
* React native specific variable injected by the runner, to signal if the tests are ran by the legacy chrome debugger (i.e. in a browser).
* @deprecated Since we no longer support the legacy chrome debugger. */
chromeDebugging?: true;

/**
* Test throwing from listeners.
* These tests are skipped by default, because we don't want these to fail and we don't have a good way to instrument Mocha to expect these uncaught exceptions.
*/
testThrowingListeners?: true;
};

type Environment = KnownEnvironment & Record<string, unknown>;
Expand All @@ -122,6 +116,7 @@ declare const fs: fs;
declare const path: path;
declare const environment: Environment;
declare const gc: undefined | (() => void);
declare const nextUncaughtException: undefined | (() => Promise<Error>);

// Extend the mocha test function with the skipIf that we patch in from index.ts
declare namespace Mocha {
Expand Down

0 comments on commit 7c26045

Please sign in to comment.