Skip to content

Commit 10e6acf

Browse files
committed
Cover cancelled module resolution snapshot rejection
Snapshot construction deliberately completes to preserve cache ownership, but callback resolution must remain cancellable. Verify that a cancelled callback rejects the update rather than publishing missing resolutions.
1 parent 4e2603a commit 10e6acf

1 file changed

Lines changed: 49 additions & 31 deletions

File tree

‎tsc/internal/api/session_module_resolution_test.go‎

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ func (c *failingModuleResolutionConn) Run(context.Context) error {
2525
func (c *failingModuleResolutionConn) Call(ctx context.Context, _ string, _ any) (json.Value, error) {
2626
c.calls++
2727
c.contexts = append(c.contexts, ctx)
28+
if err := ctx.Err(); err != nil {
29+
return nil, err
30+
}
2831
return nil, errors.New("callback error")
2932
}
3033

@@ -288,42 +291,57 @@ func TestModuleResolutionFactoryUsesCurrentContext(t *testing.T) {
288291

289292
func TestModuleResolutionCallbackErrorRejectsLanguageServerUpdate(t *testing.T) {
290293
t.Parallel()
291-
292-
projectSession, _ := projecttestutil.Setup(map[string]any{
293-
"/src/index.ts": `import "pkg";`,
294-
})
295-
defer projectSession.Close()
296-
session := NewLSPSession(projectSession, nil)
297-
defer session.Close()
298-
session.conn = &failingModuleResolutionConn{}
299-
resolver, err := session.handleCreateModuleResolver(&CreateModuleResolverParams{
300-
CompilerOptions: core.CompilerOptions{
301-
NoLib: core.TSTrue,
302-
Module: core.ModuleKindNodeNext,
303-
ModuleResolution: core.ModuleResolutionKindNodeNext,
304-
},
305-
ResolveModuleNameCallback: "resolveModuleName/1",
306-
})
307-
assert.NilError(t, err)
308-
baseSnapshot := projectSession.Snapshot()
309-
310-
_, err = session.handleGetCurrentLanguageServerSnapshot(context.Background(), &GetCurrentLanguageServerSnapshotParams{
311-
Changes: &LanguageServerSnapshotChanges{SnapshotRequestChangesParams{
312-
CreatePrograms: []*CreateSnapshotProgramParams{{
313-
RootFiles: []DocumentIdentifier{{FileName: "/src/index.ts"}},
294+
for _, name := range []string{"callback error", "cancelled context"} {
295+
t.Run(name, func(t *testing.T) {
296+
t.Parallel()
297+
projectSession, _ := projecttestutil.Setup(map[string]any{
298+
"/src/index.ts": `import "pkg";`,
299+
})
300+
defer projectSession.Close()
301+
session := NewLSPSession(projectSession, nil)
302+
defer session.Close()
303+
conn := &failingModuleResolutionConn{}
304+
session.conn = conn
305+
resolver, err := session.handleCreateModuleResolver(&CreateModuleResolverParams{
314306
CompilerOptions: core.CompilerOptions{
315307
NoLib: core.TSTrue,
316308
Module: core.ModuleKindNodeNext,
317309
ModuleResolution: core.ModuleResolutionKindNodeNext,
318310
},
319-
Options: &CreateProgramOptions{ModuleResolver: resolver},
320-
}},
321-
}},
322-
})
323-
assert.ErrorContains(t, err, "callback error")
324-
assert.Equal(t, len(session.programResolutionContexts), 0)
325-
assert.Assert(t, projectSession.Snapshot() == baseSnapshot)
326-
assert.Equal(t, len(projectSession.Snapshot().ProjectCollection.SyntheticProjects()), 0)
311+
ResolveModuleNameCallback: "resolveModuleName/1",
312+
})
313+
assert.NilError(t, err)
314+
baseSnapshot := projectSession.Snapshot()
315+
ctx, cancel := context.WithCancel(t.Context())
316+
defer cancel()
317+
if name == "cancelled context" {
318+
cancel()
319+
}
320+
321+
_, err = session.handleGetCurrentLanguageServerSnapshot(ctx, &GetCurrentLanguageServerSnapshotParams{
322+
Changes: &LanguageServerSnapshotChanges{SnapshotRequestChangesParams{
323+
CreatePrograms: []*CreateSnapshotProgramParams{{
324+
RootFiles: []DocumentIdentifier{{FileName: "/src/index.ts"}},
325+
CompilerOptions: core.CompilerOptions{
326+
NoLib: core.TSTrue,
327+
Module: core.ModuleKindNodeNext,
328+
ModuleResolution: core.ModuleResolutionKindNodeNext,
329+
},
330+
Options: &CreateProgramOptions{ModuleResolver: resolver},
331+
}},
332+
}},
333+
})
334+
if name == "cancelled context" {
335+
assert.Assert(t, errors.Is(err, context.Canceled))
336+
} else {
337+
assert.ErrorContains(t, err, "callback error")
338+
}
339+
assert.Equal(t, conn.calls, 1)
340+
assert.Equal(t, len(session.programResolutionContexts), 0)
341+
assert.Assert(t, projectSession.Snapshot() == baseSnapshot)
342+
assert.Equal(t, len(projectSession.Snapshot().ProjectCollection.SyntheticProjects()), 0)
343+
})
344+
}
327345
}
328346

329347
func staticResolutionEntry(moduleName string, directory string, mode *core.ModuleKind, fileName string) *ModuleResolutionEntry {

0 commit comments

Comments
 (0)