chore: sync current main into the CI baseline repair
Validate the baseline repairs against the latest JavaScript and CLI fixes. Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
This commit is contained in:
@@ -275,12 +275,3 @@ export const dataEffectMemberCallee = (
|
||||
t.isMemberExpression(node.callee) || t.isOptionalMemberExpression(node.callee)
|
||||
? node.callee
|
||||
: null;
|
||||
|
||||
/** Read a parent member's object when present. */
|
||||
export const dataEffectMemberObject = (
|
||||
node: t.Node | null,
|
||||
): t.Expression | t.Super | null =>
|
||||
node !== null &&
|
||||
(t.isMemberExpression(node) || t.isOptionalMemberExpression(node))
|
||||
? node.object
|
||||
: null;
|
||||
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
dataEffectArgumentBindingId as argumentBindingId,
|
||||
dataEffectLiteralString as literalString,
|
||||
dataEffectMemberCallee as memberCallee,
|
||||
dataEffectMemberObject as memberObject,
|
||||
dataEffectPrimitive as primitiveValue,
|
||||
isSemanticProcessObject as isProcessObject,
|
||||
outerDataEffectBinding as outerAssignedBinding,
|
||||
@@ -83,8 +82,8 @@ const collectConfigurations = (
|
||||
context: TraversalContext,
|
||||
): ConfigurationCandidate[] => {
|
||||
const output: ConfigurationCandidate[] = [];
|
||||
traverseWithContext(program, context, (node, parent) => {
|
||||
const details = configurationDetails(node, parent, context);
|
||||
traverseWithContext(program, context, (node) => {
|
||||
const details = configurationDetails(node, context);
|
||||
if (details === null) return;
|
||||
const operation: JavaScriptSemanticConfigurationOperation = {
|
||||
configId: `config:${details.kind}:${String(node.start ?? -1)}:${String(node.end ?? -1)}`,
|
||||
@@ -104,17 +103,13 @@ const collectConfigurations = (
|
||||
|
||||
const configurationDetails = (
|
||||
node: t.Node,
|
||||
parent: t.Node | null,
|
||||
context: TraversalContext,
|
||||
): {
|
||||
readonly kind: "environment" | "argv" | "file";
|
||||
readonly key: string | null;
|
||||
readonly resolution: "complete" | "partial";
|
||||
} | null => {
|
||||
if (
|
||||
(t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) &&
|
||||
!(memberObject(parent) === node)
|
||||
) {
|
||||
if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
|
||||
const processMember = processConfigurationMember(node, context.state);
|
||||
if (processMember !== null) return processMember;
|
||||
}
|
||||
|
||||
@@ -179,3 +179,25 @@ it("releases the timer and listener on dispose with a pending wait", async () =>
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
// Preserve the authored fractional-clock control while following the current
|
||||
// owning deadline's re-arm contract for an early native timer callback.
|
||||
it("reports zero after the re-armed deadline reaches a fractional early callback", async () => {
|
||||
vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout"] });
|
||||
const now = vi.spyOn(performance, "now").mockReturnValue(1_000);
|
||||
const deadline = new ProviderStartupDeadline(40);
|
||||
try {
|
||||
now.mockReturnValue(1_039.6);
|
||||
await vi.advanceTimersByTimeAsync(40);
|
||||
expect(deadline.signal.aborted).toBe(false);
|
||||
expect(deadline.remainingMs()).toBe(1);
|
||||
now.mockReturnValue(1_040);
|
||||
await vi.advanceTimersByTimeAsync(1);
|
||||
expect(deadline.signal.aborted).toBe(true);
|
||||
expect(deadline.interruption).toBe("timeout");
|
||||
expect(deadline.remainingMs()).toBe(0);
|
||||
} finally {
|
||||
deadline.dispose();
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -79,6 +79,9 @@ export class ProviderStartupDeadline {
|
||||
|
||||
/** Milliseconds still available to the next startup phase. */
|
||||
remainingMs(): number {
|
||||
// Node timers can fire a fraction of a millisecond before the monotonic
|
||||
// deadline, so an elapsed timer must not report time left to spend.
|
||||
if (this.#interruption === "timeout") return 0;
|
||||
return Math.max(0, Math.ceil(this.#deadlineAt - performance.now()));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import { join } from "node:path";
|
||||
|
||||
import { expect } from "vitest";
|
||||
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../../support/cli/cliFixture.js";
|
||||
import { analyzeJavaScriptDirectory } from "../../support/cli/javascriptApplication.js";
|
||||
import { writeFixtureFiles } from "../../support/javascriptApplicationFixture.js";
|
||||
|
||||
cliTest.for(["CLI", "stdio MCP"] as const)(
|
||||
"retains configuration sources consumed by member access through %s",
|
||||
async (surface, { cli, processes }) => {
|
||||
const root = await createTestTempDirectory("rea-config-reads-");
|
||||
await writeFixtureFiles(root, {
|
||||
"entry.mjs": [
|
||||
"const length = process.env.REA_ENDPOINT.length;",
|
||||
"const endpoint = process.env.REA_ENDPOINT;",
|
||||
"const argumentLength = process.argv[2].length;",
|
||||
"const mode = process.argv[3].trim();",
|
||||
"const optional = process.env.REA_MISSING?.length;",
|
||||
"function shadow(process) { return process.env.LOCAL.length + process.argv[2].length; }",
|
||||
'const local = { env: { FAKE: "fake" }, argv: [0, 1, "abc"] };',
|
||||
'const control = shadow({ env: { LOCAL: "local" }, argv: [0, 1, "abc"] });',
|
||||
"console.log(JSON.stringify([length, endpoint, argumentLength, mode, optional, control, local.env.FAKE.length]));",
|
||||
].join("\n"),
|
||||
});
|
||||
const control = await processes.run(
|
||||
process.execPath,
|
||||
[join(root, "entry.mjs"), "abc", " mode "],
|
||||
{ env: { REA_ENDPOINT: "endpoint" }, timeoutMs: 15_000 },
|
||||
);
|
||||
expect(control.exitCode, control.stderr).toBe(0);
|
||||
expect(JSON.parse(control.stdout)).toEqual([
|
||||
8,
|
||||
"endpoint",
|
||||
3,
|
||||
"mode",
|
||||
null,
|
||||
8,
|
||||
4,
|
||||
]);
|
||||
const graph = (await analyzeJavaScriptDirectory(surface, cli, root))
|
||||
.semantic_graph;
|
||||
const sources = graph.nodes.filter((node) => node.kind === "config-source");
|
||||
expect(
|
||||
sources
|
||||
.map((node) => [node.properties.source_kind, node.properties.key])
|
||||
.sort(),
|
||||
).toEqual([
|
||||
["argv", "2"],
|
||||
["argv", "3"],
|
||||
["environment", "REA_ENDPOINT"],
|
||||
["environment", "REA_ENDPOINT"],
|
||||
["environment", "REA_MISSING"],
|
||||
]);
|
||||
expect(sources.every((node) => node.properties.value === null)).toBe(true);
|
||||
const endpoint = graph.nodes.find(
|
||||
(node) => node.kind === "binding" && node.label === "endpoint",
|
||||
);
|
||||
expect(endpoint).toBeDefined();
|
||||
for (const source of sources) {
|
||||
const bindingTargets = graph.relations
|
||||
.filter((relation) => relation.source_node_id === source.node_id)
|
||||
.flatMap((relation) =>
|
||||
graph.nodes.filter(
|
||||
(node) =>
|
||||
node.node_id === relation.target_node_id &&
|
||||
node.kind === "binding",
|
||||
),
|
||||
);
|
||||
expect(bindingTargets.map((node) => node.node_id)).toEqual(
|
||||
source.identity.source_range?.start.line === 2
|
||||
? [endpoint?.node_id]
|
||||
: [],
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,32 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
import { expect } from "vitest";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../../support/cli/cliFixture.js";
|
||||
|
||||
const packageSchema = z.object({ version: z.string() });
|
||||
|
||||
// Node's Windows home lookup throws for an empty USERPROFILE, so a dependency
|
||||
// that resolves the home during import used to stop every command there.
|
||||
cliTest("starts when the selected home is empty", async ({ cli }) => {
|
||||
const { version } = packageSchema.parse(
|
||||
JSON.parse(await readFile("package.json", "utf8")),
|
||||
);
|
||||
const cwd = await createTestTempDirectory("rea-empty-home-startup-");
|
||||
const environment = { HOME: "", USERPROFILE: "" };
|
||||
|
||||
const reported = await cli.run({
|
||||
arguments: ["--version"],
|
||||
cwd,
|
||||
environment,
|
||||
});
|
||||
expect(reported.stderr).toBe("");
|
||||
expect(reported.exitCode).toBe(0);
|
||||
expect(reported.stdout.trim()).toBe(version);
|
||||
|
||||
const help = await cli.run({ arguments: ["--help"], cwd, environment });
|
||||
expect(help.stderr).not.toContain("uv_os_homedir");
|
||||
expect(help.exitCode).toBe(0);
|
||||
});
|
||||
Reference in New Issue
Block a user