178 lines
8.5 KiB
Go
178 lines
8.5 KiB
Go
package project_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/bundled"
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/lsp/lsproto"
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/project"
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/testutil/projecttestutil"
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
|
|
"gotest.tools/v3/assert"
|
|
)
|
|
|
|
// These tests explicitly verify ProgramUpdateKind using subtests with shared helpers.
|
|
func TestProjectProgramUpdateKind(t *testing.T) {
|
|
t.Parallel()
|
|
if !bundled.Embedded {
|
|
t.Skip("bundled files are not embedded")
|
|
}
|
|
|
|
// Use the default session setup for tests.
|
|
|
|
t.Run("NewFiles on initial build", func(t *testing.T) {
|
|
t.Parallel()
|
|
files := map[string]any{
|
|
"/src/tsconfig.json": "{}",
|
|
"/src/index.ts": "export const x = 1;",
|
|
}
|
|
session, _ := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
_, err := session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
snapshot, release := session.Snapshot()
|
|
defer release()
|
|
configured := snapshot.ProjectCollection.ConfiguredProject(tspath.Path("/src/tsconfig.json"))
|
|
assert.Assert(t, configured != nil)
|
|
assert.Equal(t, configured.ProgramUpdateKind, project.ProgramUpdateKindNewFiles)
|
|
})
|
|
|
|
t.Run("Cloned on single-file change", func(t *testing.T) {
|
|
t.Parallel()
|
|
files := map[string]any{
|
|
"/src/tsconfig.json": "{}",
|
|
"/src/index.ts": "console.log('Hello');",
|
|
}
|
|
session, _ := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
_, err := session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
session.DidChangeFile(context.Background(), "file:///src/index.ts", 2, []lsproto.TextDocumentContentChangePartialOrWholeDocument{{
|
|
Partial: &lsproto.TextDocumentContentChangePartial{Text: "\n", Range: lsproto.Range{Start: lsproto.Position{Line: 0, Character: 20}, End: lsproto.Position{Line: 0, Character: 20}}},
|
|
}})
|
|
_, err = session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
snapshot, release := session.Snapshot()
|
|
defer release()
|
|
configured := snapshot.ProjectCollection.ConfiguredProject(tspath.Path("/src/tsconfig.json"))
|
|
assert.Assert(t, configured != nil)
|
|
assert.Equal(t, configured.ProgramUpdateKind, project.ProgramUpdateKindCloned)
|
|
})
|
|
|
|
t.Run("SameFileNames on config change without root changes", func(t *testing.T) {
|
|
t.Parallel()
|
|
files := map[string]any{
|
|
"/src/tsconfig.json": `{"compilerOptions": {"strict": true}}`,
|
|
"/src/index.ts": "export const x = 1;",
|
|
}
|
|
session, utils := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
_, err := session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
err = utils.FS().WriteFile("/src/tsconfig.json", `{"compilerOptions": {"strict": false}}`, false)
|
|
assert.NilError(t, err)
|
|
session.DidChangeWatchedFiles(context.Background(), []*lsproto.FileEvent{{Uri: lsproto.DocumentUri("file:///src/tsconfig.json"), Type: lsproto.FileChangeTypeChanged}})
|
|
_, err = session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
snapshot, release := session.Snapshot()
|
|
defer release()
|
|
configured := snapshot.ProjectCollection.ConfiguredProject(tspath.Path("/src/tsconfig.json"))
|
|
assert.Assert(t, configured != nil)
|
|
assert.Equal(t, configured.ProgramUpdateKind, project.ProgramUpdateKindSameFileNames)
|
|
})
|
|
|
|
t.Run("NewFiles on root addition", func(t *testing.T) {
|
|
t.Parallel()
|
|
files := map[string]any{
|
|
"/src/tsconfig.json": "{}",
|
|
"/src/index.ts": "export {}",
|
|
}
|
|
session, utils := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
_, err := session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
content := "export const y = 2;"
|
|
err = utils.FS().WriteFile("/src/newfile.ts", content, false)
|
|
assert.NilError(t, err)
|
|
session.DidChangeWatchedFiles(context.Background(), []*lsproto.FileEvent{{Uri: lsproto.DocumentUri("file:///src/newfile.ts"), Type: lsproto.FileChangeTypeCreated}})
|
|
session.DidOpenFile(context.Background(), "file:///src/newfile.ts", 1, content, lsproto.LanguageKindTypeScript)
|
|
_, err = session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/newfile.ts"))
|
|
assert.NilError(t, err)
|
|
snapshot, release := session.Snapshot()
|
|
defer release()
|
|
configured := snapshot.ProjectCollection.ConfiguredProject(tspath.Path("/src/tsconfig.json"))
|
|
assert.Assert(t, configured != nil)
|
|
assert.Equal(t, configured.ProgramUpdateKind, project.ProgramUpdateKindNewFiles)
|
|
})
|
|
|
|
t.Run("SameFileNames when adding an unresolvable import with multi-file change", func(t *testing.T) {
|
|
t.Parallel()
|
|
files := map[string]any{
|
|
"/src/tsconfig.json": "{}",
|
|
"/src/index.ts": "export const x = 1;",
|
|
"/src/other.ts": "export const z = 3;",
|
|
}
|
|
session, _ := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
_, err := session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
// Change index.ts to add an unresolvable import
|
|
session.DidChangeFile(context.Background(), "file:///src/index.ts", 2, []lsproto.TextDocumentContentChangePartialOrWholeDocument{{
|
|
Partial: &lsproto.TextDocumentContentChangePartial{Text: "\nimport \"./does-not-exist\";\n", Range: lsproto.Range{Start: lsproto.Position{Line: 0, Character: 0}, End: lsproto.Position{Line: 0, Character: 0}}},
|
|
}})
|
|
_, err = session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
snapshot, release := session.Snapshot()
|
|
defer release()
|
|
configured := snapshot.ProjectCollection.ConfiguredProject(tspath.Path("/src/tsconfig.json"))
|
|
assert.Assert(t, configured != nil)
|
|
assert.Equal(t, configured.ProgramUpdateKind, project.ProgramUpdateKindSameFileNames)
|
|
})
|
|
}
|
|
|
|
func TestProject(t *testing.T) {
|
|
t.Parallel()
|
|
if !bundled.Embedded {
|
|
t.Skip("bundled files are not embedded")
|
|
}
|
|
|
|
t.Run("commandLineWithTypingsFiles is reset on CommandLine change", func(t *testing.T) {
|
|
t.Parallel()
|
|
files := map[string]any{
|
|
"/user/username/projects/project1/app.js": ``,
|
|
"/user/username/projects/project1/package.json": `{"name":"p1","dependencies":{"jquery":"^3.1.0"}}`,
|
|
"/user/username/projects/project2/app.js": ``,
|
|
}
|
|
|
|
session, utils := projecttestutil.SetupWithTypingsInstaller(files, &projecttestutil.TypingsInstallerOptions{
|
|
PackageToFile: map[string]string{
|
|
// Provide typings content to be installed for jquery so ATA actually installs something
|
|
"jquery": `declare const $: { x: number }`,
|
|
},
|
|
})
|
|
|
|
// 1) Open an inferred project file that triggers ATA
|
|
uri1 := lsproto.DocumentUri("file:///user/username/projects/project1/app.js")
|
|
session.DidOpenFile(context.Background(), uri1, 1, files["/user/username/projects/project1/app.js"].(string), lsproto.LanguageKindJavaScript)
|
|
|
|
// 2) Wait for ATA/background tasks to finish, then get a language service for the first file
|
|
session.WaitForBackgroundTasks()
|
|
// Sanity check: ensure ATA performed at least one install
|
|
npmCalls := utils.NpmExecutor().NpmInstallCalls()
|
|
assert.Assert(t, len(npmCalls) > 0, "expected at least one npm install call from ATA")
|
|
_, err := session.GetLanguageService(context.Background(), uri1)
|
|
assert.NilError(t, err)
|
|
|
|
// 3) Open another inferred project file
|
|
uri2 := lsproto.DocumentUri("file:///user/username/projects/project2/app.js")
|
|
session.DidOpenFile(context.Background(), uri2, 1, ``, lsproto.LanguageKindJavaScript)
|
|
|
|
// 4) Get a language service for the second file
|
|
// If commandLineWithTypingsFiles was not reset, the new program command line
|
|
// won't include the newly opened file and this will fail.
|
|
_, err = session.GetLanguageService(context.Background(), uri2)
|
|
assert.NilError(t, err)
|
|
})
|
|
}
|