Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions _packages/native-preview/test/async/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5112,6 +5112,39 @@ describe("getDefaultProjectForFile", () => {
}
});

test("inferred project reflects file changes without a follow-up open/close request", async () => {
const { api, fs } = spawnAPIWithFS({
"/loose.ts": `export const foo = 1;`,
});
try {
const snapshot1 = await api.updateSnapshot({ openFiles: ["/loose.ts"] });
const project1 = await snapshot1.getDefaultProjectForFile("/loose.ts");
assert.ok(project1, "file with no config file in its ancestry should load into the inferred project");
const sf1 = await project1.program.getSourceFile("/loose.ts");
assert.ok(sf1);
assert.equal(sf1.text, `export const foo = 1;`);

// Mutate the file and notify only via fileChanges — no follow-up openFiles/closeFiles.
fs.writeFile!("/loose.ts", `export const foo = 2;`);
const snapshot2 = await api.updateSnapshot({
fileChanges: { changed: ["/loose.ts"] },
});

const project2 = await snapshot2.getDefaultProjectForFile("/loose.ts");
assert.ok(project2);
const sf2 = await project2.program.getSourceFile("/loose.ts");
assert.ok(sf2);
assert.equal(
sf2.text,
`export const foo = 2;`,
"inferred project's program should reflect the file change even without a follow-up open/close request",
);
}
finally {
await api.close();
}
});

test("keeps previously opened files open across subsequent openFiles calls", async () => {
const api = spawnAPI({
"/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true } }),
Expand Down
33 changes: 33 additions & 0 deletions _packages/native-preview/test/sync/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5120,6 +5120,39 @@ describe("getDefaultProjectForFile", () => {
}
});

test("inferred project reflects file changes without a follow-up open/close request", () => {
const { api, fs } = spawnAPIWithFS({
"/loose.ts": `export const foo = 1;`,
});
try {
const snapshot1 = api.updateSnapshot({ openFiles: ["/loose.ts"] });
const project1 = snapshot1.getDefaultProjectForFile("/loose.ts");
assert.ok(project1, "file with no config file in its ancestry should load into the inferred project");
const sf1 = project1.program.getSourceFile("/loose.ts");
assert.ok(sf1);
assert.equal(sf1.text, `export const foo = 1;`);

// Mutate the file and notify only via fileChanges — no follow-up openFiles/closeFiles.
fs.writeFile!("/loose.ts", `export const foo = 2;`);
const snapshot2 = api.updateSnapshot({
fileChanges: { changed: ["/loose.ts"] },
});

const project2 = snapshot2.getDefaultProjectForFile("/loose.ts");
assert.ok(project2);
const sf2 = project2.program.getSourceFile("/loose.ts");
assert.ok(sf2);
assert.equal(
sf2.text,
`export const foo = 2;`,
"inferred project's program should reflect the file change even without a follow-up open/close request",
);
}
finally {
api.close();
}
});

test("keeps previously opened files open across subsequent openFiles calls", () => {
const api = spawnAPI({
"/tsconfig.json": JSON.stringify({ compilerOptions: { strict: true } }),
Expand Down
6 changes: 3 additions & 3 deletions internal/project/projectcollectionbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,9 @@ func (b *ProjectCollectionBuilder) HandleAPIRequest(apiRequest *APISnapshotReque
retain.Union(&result.retain)
}
b.cleanupConfiguredProjects(&retain, logger)
if b.inferredProject.Value() != nil {
b.updateProgram(b.inferredProject, logger)
}
}
if b.inferredProject.Value() != nil {
b.updateProgram(b.inferredProject, logger)
Comment thread
piotrtomiak marked this conversation as resolved.
}

return nil
Expand Down