fix(javascript): retain bridge conditions on IPC joins (#2747)
* fix(javascript): retain bridge conditions on IPC joins * fix(javascript): retain IPC condition ownership * style(javascript): format bridge path regression * fix(process): report no remaining time after a provider deadline fires Node timers can fire while performance.now() is still a fraction of a millisecond short of the monotonic deadline. ProviderStartupDeadline then reported interruption "timeout" and an aborted signal while remainingMs() returned ceil(0.x) = 1, so polling loops guarded by remainingMs() > 0 (Hopper and Ghidra startup) could run past an elapsed deadline, and the real-timer test "aborts a bounded wait when its real monotonic deadline expires" failed intermittently in CI (expected 1 to be 0). Once the deadline's own timer has classified a timeout, report zero remaining time. A deterministic regression test fires the timer with the monotonic clock 0.4 ms short of the deadline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(javascript): preserve Electron join condition coverage --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Codex <codex@users.noreply.github.com>
This commit is contained in:
parent
3a4d49406a
commit
c6166d4b56
|
|
@ -165,7 +165,8 @@ export const addElectronCallPaths = (
|
|||
pairing_basis: "unique-exact-literal-channel",
|
||||
resolution: "candidate",
|
||||
handler_path: to.file.path,
|
||||
conditions: to.path.conditions,
|
||||
bridge_conditions: from.path.conditions,
|
||||
handler_conditions: to.path.conditions,
|
||||
},
|
||||
limitations: [
|
||||
"The unique static channel match does not establish runtime registration, sender acceptance, or dispatch.",
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ cliTest(
|
|||
expect(
|
||||
byId.get(edge.target_node_id)?.observations[0]?.properties.channel,
|
||||
).toBe(edge.properties.channel);
|
||||
expect(edge.properties.conditions).toEqual([
|
||||
expect(edge.properties.bridge_conditions).toEqual([]);
|
||||
expect(edge.properties.handler_conditions).toEqual([
|
||||
expect.objectContaining({ expression: "allowed(event)" }),
|
||||
]);
|
||||
}
|
||||
|
|
@ -495,3 +496,44 @@ cliTest(
|
|||
).toEqual(["empty:key"]);
|
||||
},
|
||||
);
|
||||
|
||||
cliTest(
|
||||
"retains bridge and handler conditions on Electron IPC join edges",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-electron-join-conditions-");
|
||||
await writeFixtureFiles(root, {
|
||||
"preload.js": `const e=require("electron");
|
||||
e.contextBridge.exposeInMainWorld("desktop", {
|
||||
choose: flag
|
||||
? () => e.ipcRenderer.send("test:copy")
|
||||
: () => e.ipcRenderer.send("test:cut")
|
||||
});`,
|
||||
"main.js": `const e=require("electron");
|
||||
if(!flag)e.ipcMain.on("test:copy",event=>allowed(event)&&event.sender.copy());
|
||||
if(flag)e.ipcMain.on("test:cut",event=>allowed(event)&&event.sender.cut());`,
|
||||
});
|
||||
const { graph } = await analyzeJavaScriptDirectory("CLI", cli, root);
|
||||
const joins = graph.edges.filter(
|
||||
(edge) =>
|
||||
edge.evidence.extractor.operation === "join-electron-wrapper-paths",
|
||||
);
|
||||
expect(joins).toHaveLength(2);
|
||||
for (const [channel, bridgeCondition] of [
|
||||
["test:copy", "flag"],
|
||||
["test:cut", "!(flag)"],
|
||||
]) {
|
||||
const edge = joins.find(
|
||||
(candidate) => candidate.properties.channel === channel,
|
||||
);
|
||||
expect(edge?.properties.bridge_conditions).toEqual([
|
||||
expect.objectContaining({ expression: bridgeCondition }),
|
||||
]);
|
||||
expect(edge?.properties.handler_conditions).toEqual([
|
||||
expect.objectContaining({
|
||||
expression: channel === "test:copy" ? "!flag" : "flag",
|
||||
}),
|
||||
expect.objectContaining({ expression: "allowed(event)" }),
|
||||
]);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue