blob: dd75c591ddbe8d1c526f623470f7f231d9db7107 [file] [log] [blame]
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package workspace
import (
"testing"
"github.com/google/go-cmp/cmp"
"golang.org/x/tools/gopls/internal/lsp/cache"
"golang.org/x/tools/gopls/internal/lsp/command"
. "golang.org/x/tools/gopls/internal/test/integration"
)
func TestAddAndRemoveGoWork(t *testing.T) {
// Use a workspace with a module in the root directory to exercise the case
// where a go.work is added to the existing root directory. This verifies
// that we're detecting changes to the module source, not just the root
// directory.
const nomod = `
-- go.mod --
module a.com
go 1.16
-- main.go --
package main
func main() {}
-- b/go.mod --
module b.com
go 1.16
-- b/main.go --
package main
func main() {}
`
WithOptions(
Modes(Default),
).Run(t, nomod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
env.OpenFile("b/main.go")
summary := func(typ cache.ViewType, root, folder string) command.View {
return command.View{
Type: typ.String(),
Root: env.Sandbox.Workdir.URI(root),
Folder: env.Sandbox.Workdir.URI(folder),
}
}
checkViews := func(want ...command.View) {
got := env.Views()
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("SummarizeViews() mismatch (-want +got):\n%s", diff)
}
}
// Zero-config gopls makes this work.
env.AfterChange(
NoDiagnostics(ForFile("main.go")),
NoDiagnostics(env.AtRegexp("b/main.go", "package (main)")),
)
checkViews(summary(cache.GoModView, ".", "."), summary(cache.GoModView, "b", "."))
env.WriteWorkspaceFile("go.work", `go 1.16
use (
.
b
)
`)
env.AfterChange(NoDiagnostics())
checkViews(summary(cache.GoWorkView, ".", "."))
// Removing the go.work file should put us back where we started.
env.RemoveWorkspaceFile("go.work")
// Again, zero-config gopls makes this work.
env.AfterChange(
NoDiagnostics(ForFile("main.go")),
NoDiagnostics(env.AtRegexp("b/main.go", "package (main)")),
)
checkViews(summary(cache.GoModView, ".", "."), summary(cache.GoModView, "b", "."))
// Close and reopen b, to ensure the views are adjusted accordingly.
env.CloseBuffer("b/main.go")
env.AfterChange()
checkViews(summary(cache.GoModView, ".", "."))
env.OpenFile("b/main.go")
env.AfterChange()
checkViews(summary(cache.GoModView, ".", "."), summary(cache.GoModView, "b", "."))
})
}
func TestOpenAndClosePorts(t *testing.T) {
// This test checks that as we open and close files requiring a different
// port, the set of Views is adjusted accordingly.
const files = `
-- go.mod --
module a.com/a
go 1.20
-- a_linux.go --
package a
-- a_darwin.go --
package a
-- a_windows.go --
package a
`
WithOptions(
EnvVars{
"GOOS": "linux", // assume that linux is the default GOOS
},
).Run(t, files, func(t *testing.T, env *Env) {
summary := func(envOverlay ...string) command.View {
return command.View{
Type: cache.GoModView.String(),
Root: env.Sandbox.Workdir.URI("."),
Folder: env.Sandbox.Workdir.URI("."),
EnvOverlay: envOverlay,
}
}
checkViews := func(want ...command.View) {
got := env.Views()
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("SummarizeViews() mismatch (-want +got):\n%s", diff)
}
}
checkViews(summary())
env.OpenFile("a_linux.go")
checkViews(summary())
env.OpenFile("a_darwin.go")
checkViews(
summary(),
summary("GOARCH=amd64", "GOOS=darwin"),
)
env.OpenFile("a_windows.go")
checkViews(
summary(),
summary("GOARCH=amd64", "GOOS=darwin"),
summary("GOARCH=amd64", "GOOS=windows"),
)
env.CloseBuffer("a_darwin.go")
checkViews(
summary(),
summary("GOARCH=amd64", "GOOS=windows"),
)
env.CloseBuffer("a_linux.go")
checkViews(
summary(),
summary("GOARCH=amd64", "GOOS=windows"),
)
env.CloseBuffer("a_windows.go")
checkViews(summary())
})
}
func TestCriticalErrorsInOrphanedFiles(t *testing.T) {
// This test checks that as we open and close files requiring a different
// port, the set of Views is adjusted accordingly.
const files = `
-- go.mod --
modul golang.org/lsptests/broken
go 1.20
-- a.go --
package broken
const C = 0
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("a.go")
env.AfterChange(
Diagnostics(env.AtRegexp("go.mod", "modul")),
Diagnostics(env.AtRegexp("a.go", "broken"), WithMessage("initialization failed")),
)
})
}