| // 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/gopls/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) |
| } |
| }) |
| } |