blob: 7eedcff688aeeeb952d586be67797fd09e30ba59 [file] [log] [blame]
// Copyright 2024 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"
"github.com/google/go-cmp/cmp"
"golang.org/x/tools/gopls/internal/protocol"
"golang.org/x/tools/gopls/internal/protocol/command"
. "golang.org/x/tools/gopls/internal/test/integration"
)
func TestModulesCmd(t *testing.T) {
const goModView = `
-- go.mod --
module foo
-- pkg/pkg.go --
package pkg
func Pkg()
-- bar/bar.go --
package bar
func Bar()
-- bar/baz/go.mod --
module baz
-- bar/baz/baz.go --
package baz
func Baz()
`
const goWorkView = `
-- go.work --
use ./foo
use ./bar
-- foo/go.mod --
module foo
-- foo/foo.go --
package foo
func Foo()
-- bar/go.mod --
module bar
-- bar/bar.go --
package bar
func Bar()
`
t.Run("go.mod view", func(t *testing.T) {
// If baz isn't loaded, it will not be included
t.Run("unloaded", func(t *testing.T) {
Run(t, goModView, func(t *testing.T, env *Env) {
checkModules(t, env, env.Editor.DocumentURI(""), -1, []command.Module{
{
Path: "foo",
GoMod: env.Editor.DocumentURI("go.mod"),
},
})
})
})
// With baz loaded and recursion enabled, baz will be included
t.Run("recurse", func(t *testing.T) {
Run(t, goModView, func(t *testing.T, env *Env) {
env.OpenFile("bar/baz/baz.go")
checkModules(t, env, env.Editor.DocumentURI(""), -1, []command.Module{
{
Path: "baz",
GoMod: env.Editor.DocumentURI("bar/baz/go.mod"),
},
{
Path: "foo",
GoMod: env.Editor.DocumentURI("go.mod"),
},
})
})
})
// With recursion=1, baz will not be included
t.Run("depth", func(t *testing.T) {
Run(t, goModView, func(t *testing.T, env *Env) {
env.OpenFile("bar/baz/baz.go")
checkModules(t, env, env.Editor.DocumentURI(""), 1, []command.Module{
{
Path: "foo",
GoMod: env.Editor.DocumentURI("go.mod"),
},
})
})
})
// Baz will be included if it is requested specifically
t.Run("nested", func(t *testing.T) {
Run(t, goModView, func(t *testing.T, env *Env) {
env.OpenFile("bar/baz/baz.go")
checkModules(t, env, env.Editor.DocumentURI("bar/baz"), 0, []command.Module{
{
Path: "baz",
GoMod: env.Editor.DocumentURI("bar/baz/go.mod"),
},
})
})
})
})
t.Run("go.work view", func(t *testing.T) {
t.Run("base", func(t *testing.T) {
Run(t, goWorkView, func(t *testing.T, env *Env) {
checkModules(t, env, env.Editor.DocumentURI(""), 0, nil)
})
})
t.Run("recursive", func(t *testing.T) {
Run(t, goWorkView, func(t *testing.T, env *Env) {
checkModules(t, env, env.Editor.DocumentURI(""), -1, []command.Module{
{
Path: "bar",
GoMod: env.Editor.DocumentURI("bar/go.mod"),
},
{
Path: "foo",
GoMod: env.Editor.DocumentURI("foo/go.mod"),
},
})
})
})
})
}
func checkModules(t testing.TB, env *Env, dir protocol.DocumentURI, maxDepth int, want []command.Module) {
t.Helper()
cmd := command.NewModulesCommand("Modules", command.ModulesArgs{Dir: dir, MaxDepth: maxDepth})
var result command.ModulesResult
env.ExecuteCommand(&protocol.ExecuteCommandParams{
Command: command.Modules.String(),
Arguments: cmd.Arguments,
}, &result)
// The ordering of results is undefined and modules from a go.work view are
// retrieved from a map, so sort the results to ensure consistency
sort.Slice(result.Modules, func(i, j int) bool {
a, b := result.Modules[i], result.Modules[j]
return strings.Compare(a.Path, b.Path) < 0
})
diff := cmp.Diff(want, result.Modules)
if diff != "" {
t.Errorf("Modules(%v) returned unexpected diff (-want +got):\n%s", dir, diff)
}
}