blob: bdc60a06ee36bbc83413bc4dab3c205724d1865e [file] [log] [blame]
// Copyright 2022 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 (
"sort"
"strings"
"testing"
. "golang.org/x/tools/internal/lsp/regtest"
)
// This file contains regression tests for the directoryFilters setting.
//
// TODO:
// - consolidate some of these tests into a single test
// - add more tests for changing directory filters
func TestDirectoryFilters(t *testing.T) {
WithOptions(
ProxyFiles(workspaceProxy),
WorkspaceFolders("pkg"),
Settings{
"directoryFilters": []string{"-inner"},
},
).Run(t, workspaceModule, func(t *testing.T, env *Env) {
syms := env.WorkspaceSymbol("Hi")
sort.Slice(syms, func(i, j int) bool { return syms[i].ContainerName < syms[j].ContainerName })
for _, s := range syms {
if strings.Contains(s.ContainerName, "inner") {
t.Errorf("WorkspaceSymbol: found symbol %q with container %q, want \"inner\" excluded", s.Name, s.ContainerName)
}
}
})
}
func TestDirectoryFiltersLoads(t *testing.T) {
// exclude, and its error, should be excluded from the workspace.
const files = `
-- go.mod --
module example.com
go 1.12
-- exclude/exclude.go --
package exclude
const _ = Nonexistant
`
WithOptions(
Settings{"directoryFilters": []string{"-exclude"}},
).Run(t, files, func(t *testing.T, env *Env) {
env.Await(NoDiagnostics("exclude/x.go"))
})
}
func TestDirectoryFiltersTransitiveDep(t *testing.T) {
// Even though exclude is excluded from the workspace, it should
// still be importable as a non-workspace package.
const files = `
-- go.mod --
module example.com
go 1.12
-- include/include.go --
package include
import "example.com/exclude"
const _ = exclude.X
-- exclude/exclude.go --
package exclude
const _ = Nonexistant // should be ignored, since this is a non-workspace package
const X = 1
`
WithOptions(
Settings{"directoryFilters": []string{"-exclude"}},
).Run(t, files, func(t *testing.T, env *Env) {
env.Await(
NoDiagnostics("exclude/exclude.go"), // filtered out
NoDiagnostics("include/include.go"), // successfully builds
)
})
}
func TestDirectoryFiltersWorkspaceModules(t *testing.T) {
// Define a module include.com which should be in the workspace, plus a
// module exclude.com which should be excluded and therefore come from
// the proxy.
const files = `
-- include/go.mod --
module include.com
go 1.12
require exclude.com v1.0.0
-- include/go.sum --
exclude.com v1.0.0 h1:Q5QSfDXY5qyNCBeUiWovUGqcLCRZKoTs9XdBeVz+w1I=
exclude.com v1.0.0/go.mod h1:hFox2uDlNB2s2Jfd9tHlQVfgqUiLVTmh6ZKat4cvnj4=
-- include/include.go --
package include
import "exclude.com"
var _ = exclude.X // satisfied only by the workspace version
-- exclude/go.mod --
module exclude.com
go 1.12
-- exclude/exclude.go --
package exclude
const X = 1
`
const proxy = `
-- exclude.com@v1.0.0/go.mod --
module exclude.com
go 1.12
-- exclude.com@v1.0.0/exclude.go --
package exclude
`
WithOptions(
Modes(Experimental),
ProxyFiles(proxy),
Settings{"directoryFilters": []string{"-exclude"}},
).Run(t, files, func(t *testing.T, env *Env) {
env.Await(env.DiagnosticAtRegexp("include/include.go", `exclude.(X)`))
})
}
// Test for golang/go#46438: support for '**' in directory filters.
func TestDirectoryFilters_Wildcard(t *testing.T) {
filters := []string{"-**/bye"}
WithOptions(
ProxyFiles(workspaceProxy),
WorkspaceFolders("pkg"),
Settings{
"directoryFilters": filters,
},
).Run(t, workspaceModule, func(t *testing.T, env *Env) {
syms := env.WorkspaceSymbol("Bye")
sort.Slice(syms, func(i, j int) bool { return syms[i].ContainerName < syms[j].ContainerName })
for _, s := range syms {
if strings.Contains(s.ContainerName, "bye") {
t.Errorf("WorkspaceSymbol: found symbol %q with container %q with filters %v", s.Name, s.ContainerName, filters)
}
}
})
}
// Test for golang/go#52993: wildcard directoryFilters should apply to
// goimports scanning as well.
func TestDirectoryFilters_ImportScanning(t *testing.T) {
const files = `
-- go.mod --
module mod.test
go 1.12
-- main.go --
package main
func main() {
bye.Goodbye()
}
-- p/bye/bye.go --
package bye
func Goodbye() {}
`
WithOptions(
Settings{
"directoryFilters": []string{"-**/bye"},
},
// This test breaks in 'Experimental' mode, because with
// experimentalWorkspaceModule set we the goimports scan behaves
// differently.
//
// Since this feature is going away (golang/go#52897), don't investigate.
Modes(Default),
).Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
beforeSave := env.Editor.BufferText("main.go")
env.OrganizeImports("main.go")
got := env.Editor.BufferText("main.go")
if got != beforeSave {
t.Errorf("after organizeImports code action, got modified buffer:\n%s", got)
}
})
}
// Test for golang/go#52993: non-wildcard directoryFilters should still be
// applied relative to the workspace folder, not the module root.
func TestDirectoryFilters_MultiRootImportScanning(t *testing.T) {
const files = `
-- go.work --
go 1.18
use (
a
b
)
-- a/go.mod --
module mod1.test
go 1.18
-- a/main.go --
package main
func main() {
hi.Hi()
}
-- a/hi/hi.go --
package hi
func Hi() {}
-- b/go.mod --
module mod2.test
go 1.18
-- b/main.go --
package main
func main() {
hi.Hi()
}
-- b/hi/hi.go --
package hi
func Hi() {}
`
WithOptions(
Settings{
"directoryFilters": []string{"-hi"}, // this test fails with -**/hi
},
).Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("a/main.go")
beforeSave := env.Editor.BufferText("a/main.go")
env.OrganizeImports("a/main.go")
got := env.Editor.BufferText("a/main.go")
if got == beforeSave {
t.Errorf("after organizeImports code action, got identical buffer:\n%s", got)
}
})
}