187 lines
7.7 KiB
Go
187 lines
7.7 KiB
Go
package project_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/bundled"
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/lsp/lsproto"
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/testutil/projecttestutil"
|
|
"gotest.tools/v3/assert"
|
|
)
|
|
|
|
func TestConfigFileChanges(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if !bundled.Embedded {
|
|
t.Skip("bundled files are not embedded")
|
|
}
|
|
|
|
files := map[string]any{
|
|
"/tsconfig.base.json": `{"compilerOptions": {"strict": true}}`,
|
|
"/src/tsconfig.json": `{"extends": "../tsconfig.base.json", "compilerOptions": {"target": "es6"}, "references": [{"path": "../utils"}]}`,
|
|
"/src/index.ts": `console.log("Hello, world!");`,
|
|
"/src/subfolder/foo.ts": `export const foo = "bar";`,
|
|
|
|
"/utils/tsconfig.json": `{"compilerOptions": {"composite": true}}`,
|
|
"/utils/index.ts": `console.log("Hello, test!");`,
|
|
}
|
|
|
|
t.Run("should update program options on config file change", func(t *testing.T) {
|
|
t.Parallel()
|
|
session, utils := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
|
|
err := utils.FS().WriteFile("/src/tsconfig.json", `{"extends": "../tsconfig.base.json", "compilerOptions": {"target": "esnext"}, "references": [{"path": "../utils"}]}`, false /*writeByteOrderMark*/)
|
|
assert.NilError(t, err)
|
|
session.DidChangeWatchedFiles(context.Background(), []*lsproto.FileEvent{
|
|
{
|
|
Uri: lsproto.DocumentUri("file:///src/tsconfig.json"),
|
|
Type: lsproto.FileChangeTypeChanged,
|
|
},
|
|
})
|
|
|
|
ls, err := session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
assert.Equal(t, ls.GetProgram().Options().Target, core.ScriptTargetESNext)
|
|
})
|
|
|
|
t.Run("should update project on extended config file change", func(t *testing.T) {
|
|
t.Parallel()
|
|
session, utils := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
|
|
err := utils.FS().WriteFile("/tsconfig.base.json", `{"compilerOptions": {"strict": false}}`, false /*writeByteOrderMark*/)
|
|
assert.NilError(t, err)
|
|
session.DidChangeWatchedFiles(context.Background(), []*lsproto.FileEvent{
|
|
{
|
|
Uri: lsproto.DocumentUri("file:///tsconfig.base.json"),
|
|
Type: lsproto.FileChangeTypeChanged,
|
|
},
|
|
})
|
|
|
|
ls, err := session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
assert.Equal(t, ls.GetProgram().Options().Strict, core.TSFalse)
|
|
})
|
|
|
|
t.Run("should update project on referenced config file change", func(t *testing.T) {
|
|
t.Parallel()
|
|
session, utils := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
snapshotBefore, release := session.Snapshot()
|
|
defer release()
|
|
|
|
err := utils.FS().WriteFile("/utils/tsconfig.json", `{"compilerOptions": {"composite": true, "target": "esnext"}}`, false /*writeByteOrderMark*/)
|
|
assert.NilError(t, err)
|
|
session.DidChangeWatchedFiles(context.Background(), []*lsproto.FileEvent{
|
|
{
|
|
Uri: lsproto.DocumentUri("file:///utils/tsconfig.json"),
|
|
Type: lsproto.FileChangeTypeChanged,
|
|
},
|
|
})
|
|
|
|
_, err = session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
snapshotAfter, release := session.Snapshot()
|
|
defer release()
|
|
assert.Assert(t, snapshotAfter != snapshotBefore, "Snapshot should be updated after config file change")
|
|
})
|
|
|
|
t.Run("should close project on config file deletion", func(t *testing.T) {
|
|
t.Parallel()
|
|
session, utils := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
|
|
err := utils.FS().Remove("/src/tsconfig.json")
|
|
assert.NilError(t, err)
|
|
session.DidChangeWatchedFiles(context.Background(), []*lsproto.FileEvent{
|
|
{
|
|
Uri: lsproto.DocumentUri("file:///src/tsconfig.json"),
|
|
Type: lsproto.FileChangeTypeDeleted,
|
|
},
|
|
})
|
|
|
|
_, err = session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
snapshot, release := session.Snapshot()
|
|
defer release()
|
|
assert.Assert(t, len(snapshot.ProjectCollection.Projects()) == 1)
|
|
assert.Assert(t, snapshot.ProjectCollection.InferredProject() != nil)
|
|
})
|
|
|
|
t.Run("config file creation then deletion", func(t *testing.T) {
|
|
t.Parallel()
|
|
session, utils := projecttestutil.Setup(files)
|
|
session.DidOpenFile(context.Background(), "file:///src/subfolder/foo.ts", 1, files["/src/subfolder/foo.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
|
|
err := utils.FS().WriteFile("/src/subfolder/tsconfig.json", `{}`, false /*writeByteOrderMark*/)
|
|
assert.NilError(t, err)
|
|
session.DidChangeWatchedFiles(context.Background(), []*lsproto.FileEvent{
|
|
{
|
|
Uri: lsproto.DocumentUri("file:///src/subfolder/tsconfig.json"),
|
|
Type: lsproto.FileChangeTypeCreated,
|
|
},
|
|
})
|
|
|
|
_, err = session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/subfolder/foo.ts"))
|
|
assert.NilError(t, err)
|
|
snapshot, release := session.Snapshot()
|
|
defer release()
|
|
assert.Equal(t, len(snapshot.ProjectCollection.Projects()), 2)
|
|
assert.Equal(t, snapshot.GetDefaultProject(lsproto.DocumentUri("file:///src/subfolder/foo.ts")).Name(), "/src/subfolder/tsconfig.json")
|
|
|
|
err = utils.FS().Remove("/src/subfolder/tsconfig.json")
|
|
assert.NilError(t, err)
|
|
session.DidChangeWatchedFiles(context.Background(), []*lsproto.FileEvent{
|
|
{
|
|
Uri: lsproto.DocumentUri("file:///src/subfolder/tsconfig.json"),
|
|
Type: lsproto.FileChangeTypeDeleted,
|
|
},
|
|
})
|
|
|
|
_, err = session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/subfolder/foo.ts"))
|
|
assert.NilError(t, err)
|
|
snapshot, release = session.Snapshot()
|
|
defer release()
|
|
assert.Equal(t, snapshot.GetDefaultProject(lsproto.DocumentUri("file:///src/subfolder/foo.ts")).Name(), "/src/tsconfig.json")
|
|
assert.Equal(t, len(snapshot.ProjectCollection.Projects()), 2) // Old project will be cleaned up on next file open
|
|
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, files["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
snapshot, release = session.Snapshot()
|
|
defer release()
|
|
assert.Equal(t, len(snapshot.ProjectCollection.Projects()), 1)
|
|
})
|
|
|
|
t.Run("should update project when missing extended config is created", func(t *testing.T) {
|
|
t.Parallel()
|
|
// Start with a project whose tsconfig extends a base config that doesn't exist yet
|
|
missingBaseFiles := map[string]any{}
|
|
for k, v := range files {
|
|
if k == "/tsconfig.base.json" {
|
|
continue
|
|
}
|
|
missingBaseFiles[k] = v
|
|
}
|
|
|
|
session, utils := projecttestutil.Setup(missingBaseFiles)
|
|
session.DidOpenFile(context.Background(), "file:///src/index.ts", 1, missingBaseFiles["/src/index.ts"].(string), lsproto.LanguageKindTypeScript)
|
|
|
|
// Create the previously-missing base config file that is extended by /src/tsconfig.json
|
|
err := utils.FS().WriteFile("/tsconfig.base.json", `{"compilerOptions": {"strict": true}}`, false /*writeByteOrderMark*/)
|
|
assert.NilError(t, err)
|
|
session.DidChangeWatchedFiles(context.Background(), []*lsproto.FileEvent{
|
|
{
|
|
Uri: lsproto.DocumentUri("file:///tsconfig.base.json"),
|
|
Type: lsproto.FileChangeTypeCreated,
|
|
},
|
|
})
|
|
|
|
// Accessing the language service should trigger project update
|
|
ls, err := session.GetLanguageService(context.Background(), lsproto.DocumentUri("file:///src/index.ts"))
|
|
assert.NilError(t, err)
|
|
assert.Equal(t, ls.GetProgram().Options().Strict, core.TSTrue)
|
|
})
|
|
}
|