aboutsummaryrefslogtreecommitdiff
path: root/gopls/internal/regtest/modfile/modfile_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'gopls/internal/regtest/modfile/modfile_test.go')
-rw-r--r--gopls/internal/regtest/modfile/modfile_test.go349
1 files changed, 171 insertions, 178 deletions
diff --git a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regtest/modfile/modfile_test.go
index 868aa70aa..483118dd3 100644
--- a/gopls/internal/regtest/modfile/modfile_test.go
+++ b/gopls/internal/regtest/modfile/modfile_test.go
@@ -11,14 +11,16 @@ import (
"testing"
"golang.org/x/tools/gopls/internal/hooks"
- . "golang.org/x/tools/internal/lsp/regtest"
+ . "golang.org/x/tools/gopls/internal/lsp/regtest"
+ "golang.org/x/tools/gopls/internal/lsp/tests/compare"
+ "golang.org/x/tools/internal/bug"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/lsp/tests"
+ "golang.org/x/tools/gopls/internal/lsp/protocol"
"golang.org/x/tools/internal/testenv"
)
func TestMain(m *testing.M) {
+ bug.PanicOnBugs = true
Main(m, hooks.Options)
}
@@ -65,8 +67,6 @@ const Name = "Hello"
`
func TestModFileModification(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
const untidyModule = `
-- a/go.mod --
module mod.com
@@ -92,54 +92,59 @@ func main() {
// modify the go.mod file.
goModContent := env.ReadWorkspaceFile("a/go.mod")
env.OpenFile("a/main.go")
- env.Await(
- env.DiagnosticAtRegexp("a/main.go", "\"example.com/blah\""),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/main.go", "\"example.com/blah\"")),
)
if got := env.ReadWorkspaceFile("a/go.mod"); got != goModContent {
- t.Fatalf("go.mod changed on disk:\n%s", tests.Diff(t, goModContent, got))
+ t.Fatalf("go.mod changed on disk:\n%s", compare.Text(goModContent, got))
}
// Save the buffer, which will format and organize imports.
// Confirm that the go.mod file still does not change.
env.SaveBuffer("a/main.go")
- env.Await(
- env.DiagnosticAtRegexp("a/main.go", "\"example.com/blah\""),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/main.go", "\"example.com/blah\"")),
)
if got := env.ReadWorkspaceFile("a/go.mod"); got != goModContent {
- t.Fatalf("go.mod changed on disk:\n%s", tests.Diff(t, goModContent, got))
+ t.Fatalf("go.mod changed on disk:\n%s", compare.Text(goModContent, got))
}
})
})
// Reproduce golang/go#40269 by deleting and recreating main.go.
t.Run("delete main.go", func(t *testing.T) {
- t.Skip("This test will be flaky until golang/go#40269 is resolved.")
-
runner.Run(t, untidyModule, func(t *testing.T, env *Env) {
goModContent := env.ReadWorkspaceFile("a/go.mod")
mainContent := env.ReadWorkspaceFile("a/main.go")
env.OpenFile("a/main.go")
env.SaveBuffer("a/main.go")
+ // Ensure that we're done processing all the changes caused by opening
+ // and saving above. If not, we may run into a file locking issue on
+ // windows.
+ //
+ // If this proves insufficient, env.RemoveWorkspaceFile can be updated to
+ // retry file lock errors on windows.
+ env.AfterChange()
env.RemoveWorkspaceFile("a/main.go")
- env.Await(
- env.DoneWithOpen(),
- env.DoneWithSave(),
- env.DoneWithChangeWatchedFiles(),
- )
- env.WriteWorkspaceFile("main.go", mainContent)
- env.Await(
- env.DiagnosticAtRegexp("main.go", "\"example.com/blah\""),
+ // TODO(rfindley): awaiting here shouldn't really be necessary. We should
+ // be consistent eventually.
+ //
+ // Probably this was meant to exercise a race with the change below.
+ env.AfterChange()
+
+ env.WriteWorkspaceFile("a/main.go", mainContent)
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/main.go", "\"example.com/blah\"")),
)
- if got := env.ReadWorkspaceFile("go.mod"); got != goModContent {
- t.Fatalf("go.mod changed on disk:\n%s", tests.Diff(t, goModContent, got))
+ if got := env.ReadWorkspaceFile("a/go.mod"); got != goModContent {
+ t.Fatalf("go.mod changed on disk:\n%s", compare.Text(goModContent, got))
}
})
})
}
func TestGoGetFix(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
const mod = `
-- a/go.mod --
module mod.com
@@ -170,11 +175,9 @@ require example.com v1.2.3
}
env.OpenFile("a/main.go")
var d protocol.PublishDiagnosticsParams
- env.Await(
- OnceMet(
- env.DiagnosticAtRegexp("a/main.go", `"example.com/blah"`),
- ReadDiagnostics("a/main.go", &d),
- ),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/main.go", `"example.com/blah"`)),
+ ReadDiagnostics("a/main.go", &d),
)
var goGetDiag protocol.Diagnostic
for _, diag := range d.Diagnostics {
@@ -184,14 +187,13 @@ require example.com v1.2.3
}
env.ApplyQuickFixes("a/main.go", []protocol.Diagnostic{goGetDiag})
if got := env.ReadWorkspaceFile("a/go.mod"); got != want {
- t.Fatalf("unexpected go.mod content:\n%s", tests.Diff(t, want, got))
+ t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
}
})
}
// Tests that multiple missing dependencies gives good single fixes.
func TestMissingDependencyFixes(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
const mod = `
-- a/go.mod --
module mod.com
@@ -220,11 +222,9 @@ require random.org v1.2.3
}.Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("a/main.go")
var d protocol.PublishDiagnosticsParams
- env.Await(
- OnceMet(
- env.DiagnosticAtRegexp("a/main.go", `"random.org/blah"`),
- ReadDiagnostics("a/main.go", &d),
- ),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/main.go", `"random.org/blah"`)),
+ ReadDiagnostics("a/main.go", &d),
)
var randomDiag protocol.Diagnostic
for _, diag := range d.Diagnostics {
@@ -234,7 +234,7 @@ require random.org v1.2.3
}
env.ApplyQuickFixes("a/main.go", []protocol.Diagnostic{randomDiag})
if got := env.ReadWorkspaceFile("a/go.mod"); got != want {
- t.Fatalf("unexpected go.mod content:\n%s", tests.Diff(t, want, got))
+ t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
}
})
}
@@ -276,11 +276,9 @@ require random.org v1.2.3
}.Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("a/main.go")
var d protocol.PublishDiagnosticsParams
- env.Await(
- OnceMet(
- env.DiagnosticAtRegexp("a/main.go", `"random.org/blah"`),
- ReadDiagnostics("a/main.go", &d),
- ),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/main.go", `"random.org/blah"`)),
+ ReadDiagnostics("a/main.go", &d),
)
var randomDiag protocol.Diagnostic
for _, diag := range d.Diagnostics {
@@ -290,14 +288,12 @@ require random.org v1.2.3
}
env.ApplyQuickFixes("a/main.go", []protocol.Diagnostic{randomDiag})
if got := env.ReadWorkspaceFile("a/go.mod"); got != want {
- t.Fatalf("unexpected go.mod content:\n%s", tests.Diff(t, want, got))
+ t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
}
})
}
func TestIndirectDependencyFix(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
const mod = `
-- a/go.mod --
module mod.com
@@ -329,21 +325,18 @@ require example.com v1.2.3
}.Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("a/go.mod")
var d protocol.PublishDiagnosticsParams
- env.Await(
- OnceMet(
- env.DiagnosticAtRegexp("a/go.mod", "// indirect"),
- ReadDiagnostics("a/go.mod", &d),
- ),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/go.mod", "// indirect")),
+ ReadDiagnostics("a/go.mod", &d),
)
env.ApplyQuickFixes("a/go.mod", d.Diagnostics)
- if got := env.Editor.BufferText("a/go.mod"); got != want {
- t.Fatalf("unexpected go.mod content:\n%s", tests.Diff(t, want, got))
+ if got := env.BufferText("a/go.mod"); got != want {
+ t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
}
})
}
func TestUnusedDiag(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
const proxy = `
-- example.com@v1.0.0/x.go --
@@ -374,15 +367,13 @@ go 1.14
}.Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("a/go.mod")
var d protocol.PublishDiagnosticsParams
- env.Await(
- OnceMet(
- env.DiagnosticAtRegexp("a/go.mod", `require example.com`),
- ReadDiagnostics("a/go.mod", &d),
- ),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/go.mod", `require example.com`)),
+ ReadDiagnostics("a/go.mod", &d),
)
env.ApplyQuickFixes("a/go.mod", d.Diagnostics)
- if got := env.Editor.BufferText("a/go.mod"); got != want {
- t.Fatalf("unexpected go.mod content:\n%s", tests.Diff(t, want, got))
+ if got := env.BufferText("a/go.mod"); got != want {
+ t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got))
}
})
}
@@ -390,7 +381,6 @@ go 1.14
// Test to reproduce golang/go#39041. It adds a new require to a go.mod file
// that already has an unused require.
func TestNewDepWithUnusedDep(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
const proxy = `
-- github.com/esimov/caire@v1.2.5/go.mod --
@@ -437,11 +427,9 @@ func _() {
}.Run(t, repro, func(t *testing.T, env *Env) {
env.OpenFile("a/main.go")
var d protocol.PublishDiagnosticsParams
- env.Await(
- OnceMet(
- env.DiagnosticAtRegexp("a/main.go", `"github.com/esimov/caire"`),
- ReadDiagnostics("a/main.go", &d),
- ),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/main.go", `"github.com/esimov/caire"`)),
+ ReadDiagnostics("a/main.go", &d),
)
env.ApplyQuickFixes("a/main.go", d.Diagnostics)
want := `module mod.com
@@ -454,7 +442,7 @@ require (
)
`
if got := env.ReadWorkspaceFile("a/go.mod"); got != want {
- t.Fatalf("TestNewDepWithUnusedDep failed:\n%s", tests.Diff(t, want, got))
+ t.Fatalf("TestNewDepWithUnusedDep failed:\n%s", compare.Text(want, got))
}
})
}
@@ -463,8 +451,6 @@ require (
// the file watching GlobPattern in the capability registration. See
// golang/go#39384.
func TestModuleChangesOnDisk(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
const mod = `
-- a/go.mod --
module mod.com
@@ -485,10 +471,13 @@ func main() {
{"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))},
{"nested", WithOptions(ProxyFiles(proxy))},
}.Run(t, mod, func(t *testing.T, env *Env) {
- env.Await(env.DiagnosticAtRegexp("a/go.mod", "require"))
+ env.OnceMet(
+ InitialWorkspaceLoad,
+ Diagnostics(env.AtRegexp("a/go.mod", "require")),
+ )
env.RunGoCommandInDir("a", "mod", "tidy")
- env.Await(
- EmptyDiagnostics("a/go.mod"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/go.mod")),
)
})
}
@@ -496,8 +485,6 @@ func main() {
// Tests golang/go#39784: a missing indirect dependency, necessary
// due to blah@v2.0.0's incomplete go.mod file.
func TestBadlyVersionedModule(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
const proxy = `
-- example.com/blah/@v/v1.0.0.mod --
module example.com
@@ -544,13 +531,15 @@ var _ = blah.Name
}.Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("a/main.go")
env.OpenFile("a/go.mod")
- env.Await(
+ var modDiags protocol.PublishDiagnosticsParams
+ env.AfterChange(
// We would like for the error to appear in the v2 module, but
// as of writing non-workspace packages are not diagnosed.
- env.DiagnosticAtRegexpWithMessage("a/main.go", `"example.com/blah/v2"`, "cannot find module providing"),
- env.DiagnosticAtRegexpWithMessage("a/go.mod", `require example.com/blah/v2`, "cannot find module providing"),
+ Diagnostics(env.AtRegexp("a/main.go", `"example.com/blah/v2"`), WithMessage("cannot find module providing")),
+ Diagnostics(env.AtRegexp("a/go.mod", `require example.com/blah/v2`), WithMessage("cannot find module providing")),
+ ReadDiagnostics("a/go.mod", &modDiags),
)
- env.ApplyQuickFixes("a/go.mod", env.DiagnosticsFor("a/go.mod").Diagnostics)
+ env.ApplyQuickFixes("a/go.mod", modDiags.Diagnostics)
const want = `module mod.com
go 1.12
@@ -561,9 +550,9 @@ require (
)
`
env.SaveBuffer("a/go.mod")
- env.Await(EmptyDiagnostics("a/main.go"))
- if got := env.Editor.BufferText("a/go.mod"); got != want {
- t.Fatalf("suggested fixes failed:\n%s", tests.Diff(t, want, got))
+ env.AfterChange(NoDiagnostics(ForFile("a/main.go")))
+ if got := env.BufferText("a/go.mod"); got != want {
+ t.Fatalf("suggested fixes failed:\n%s", compare.Text(want, got))
}
})
}
@@ -573,9 +562,6 @@ func TestUnknownRevision(t *testing.T) {
if runtime.GOOS == "plan9" {
t.Skipf("skipping test that fails for unknown reasons on plan9; see https://go.dev/issue/50477")
}
-
- testenv.NeedsGo1Point(t, 14)
-
const unknown = `
-- a/go.mod --
module mod.com
@@ -601,19 +587,17 @@ func main() {
t.Run("bad", func(t *testing.T) {
runner.Run(t, unknown, func(t *testing.T, env *Env) {
env.OpenFile("a/go.mod")
- env.Await(
- env.DiagnosticAtRegexp("a/go.mod", "example.com v1.2.2"),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/go.mod", "example.com v1.2.2")),
)
env.RegexpReplace("a/go.mod", "v1.2.2", "v1.2.3")
env.SaveBuffer("a/go.mod") // Save to trigger diagnostics.
d := protocol.PublishDiagnosticsParams{}
- env.Await(
- OnceMet(
- // Make sure the diagnostic mentions the new version -- the old diagnostic is in the same place.
- env.DiagnosticAtRegexpWithMessage("a/go.mod", "example.com v1.2.3", "example.com@v1.2.3"),
- ReadDiagnostics("a/go.mod", &d),
- ),
+ env.AfterChange(
+ // Make sure the diagnostic mentions the new version -- the old diagnostic is in the same place.
+ Diagnostics(env.AtRegexp("a/go.mod", "example.com v1.2.3"), WithMessage("example.com@v1.2.3")),
+ ReadDiagnostics("a/go.mod", &d),
)
qfs := env.GetQuickFixes("a/go.mod", d.Diagnostics)
if len(qfs) == 0 {
@@ -621,9 +605,9 @@ func main() {
}
env.ApplyCodeAction(qfs[0]) // Arbitrarily pick a single fix to apply. Applying all of them seems to cause trouble in this particular test.
env.SaveBuffer("a/go.mod") // Save to trigger diagnostics.
- env.Await(
- EmptyDiagnostics("a/go.mod"),
- env.DiagnosticAtRegexp("a/main.go", "x = "),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/go.mod")),
+ Diagnostics(env.AtRegexp("a/main.go", "x = ")),
)
})
})
@@ -652,18 +636,18 @@ func main() {
t.Run("good", func(t *testing.T) {
runner.Run(t, known, func(t *testing.T, env *Env) {
env.OpenFile("a/go.mod")
- env.Await(
- env.DiagnosticAtRegexp("a/main.go", "x = "),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/main.go", "x = ")),
)
env.RegexpReplace("a/go.mod", "v1.2.3", "v1.2.2")
env.Editor.SaveBuffer(env.Ctx, "a/go.mod") // go.mod changes must be on disk
- env.Await(
- env.DiagnosticAtRegexp("a/go.mod", "example.com v1.2.2"),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/go.mod", "example.com v1.2.2")),
)
env.RegexpReplace("a/go.mod", "v1.2.2", "v1.2.3")
env.Editor.SaveBuffer(env.Ctx, "a/go.mod") // go.mod changes must be on disk
- env.Await(
- env.DiagnosticAtRegexp("a/main.go", "x = "),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/main.go", "x = ")),
)
})
})
@@ -672,8 +656,6 @@ func main() {
// Confirm that an error in an indirect dependency of a requirement is surfaced
// as a diagnostic in the go.mod file.
func TestErrorInIndirectDependency(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
const badProxy = `
-- example.com@v1.2.3/go.mod --
module example.com
@@ -715,8 +697,8 @@ func main() {
{"nested", WithOptions(ProxyFiles(badProxy))},
}.Run(t, module, func(t *testing.T, env *Env) {
env.OpenFile("a/go.mod")
- env.Await(
- env.DiagnosticAtRegexp("a/go.mod", "require example.com v1.2.3"),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/go.mod", "require example.com v1.2.3")),
)
})
}
@@ -738,35 +720,37 @@ func main() {
}
`
WithOptions(
- EditorConfig{
- Env: map[string]string{
- "GOFLAGS": "-mod=readonly",
- },
- },
+ EnvVars{"GOFLAGS": "-mod=readonly"},
ProxyFiles(proxy),
- Modes(Singleton),
+ Modes(Default),
).Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
original := env.ReadWorkspaceFile("go.mod")
- env.Await(
- env.DiagnosticAtRegexp("main.go", `"example.com/blah"`),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("main.go", `"example.com/blah"`)),
)
got := env.ReadWorkspaceFile("go.mod")
if got != original {
- t.Fatalf("go.mod file modified:\n%s", tests.Diff(t, original, got))
+ t.Fatalf("go.mod file modified:\n%s", compare.Text(original, got))
}
env.RunGoCommand("get", "example.com/blah@v1.2.3")
env.RunGoCommand("mod", "tidy")
- env.Await(
- EmptyDiagnostics("main.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("main.go")),
)
})
}
func TestMultiModuleModDiagnostics(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
+ testenv.NeedsGo1Point(t, 18) // uses go.work
const mod = `
+-- go.work --
+go 1.18
+
+use (
+ a
+ b
+)
-- a/go.mod --
module moda.com
@@ -799,17 +783,17 @@ func main() {
`
WithOptions(
ProxyFiles(workspaceProxy),
- Modes(Experimental),
).Run(t, mod, func(t *testing.T, env *Env) {
- env.Await(
- env.DiagnosticAtRegexpWithMessage("a/go.mod", "example.com v1.2.3", "is not used"),
+ env.AfterChange(
+ Diagnostics(
+ env.AtRegexp("a/go.mod", "example.com v1.2.3"),
+ WithMessage("is not used"),
+ ),
)
})
}
func TestModTidyWithBuildTags(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
const mod = `
-- go.mod --
module mod.com
@@ -828,12 +812,11 @@ func main() {
`
WithOptions(
ProxyFiles(workspaceProxy),
- EditorConfig{
- BuildFlags: []string{"-tags", "bob"},
- },
+ Settings{"buildFlags": []string{"-tags", "bob"}},
).Run(t, mod, func(t *testing.T, env *Env) {
- env.Await(
- env.DiagnosticAtRegexp("main.go", `"example.com/blah"`),
+ env.OnceMet(
+ InitialWorkspaceLoad,
+ Diagnostics(env.AtRegexp("main.go", `"example.com/blah"`)),
)
})
}
@@ -852,15 +835,13 @@ func main() {}
Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("go.mod")
env.RegexpReplace("go.mod", "module", "modul")
- env.Await(
- env.DiagnosticAtRegexp("go.mod", "modul"),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("go.mod", "modul")),
)
})
}
func TestSumUpdateFixesDiagnostics(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
const mod = `
-- go.mod --
module mod.com
@@ -887,16 +868,17 @@ func main() {
).Run(t, mod, func(t *testing.T, env *Env) {
d := &protocol.PublishDiagnosticsParams{}
env.OpenFile("go.mod")
- env.Await(
- OnceMet(
- env.GoSumDiagnostic("go.mod", `example.com v1.2.3`),
- ReadDiagnostics("go.mod", d),
+ env.AfterChange(
+ Diagnostics(
+ env.AtRegexp("go.mod", `example.com v1.2.3`),
+ WithMessage("go.sum is out of sync"),
),
+ ReadDiagnostics("go.mod", d),
)
env.ApplyQuickFixes("go.mod", d.Diagnostics)
env.SaveBuffer("go.mod") // Save to trigger diagnostics.
- env.Await(
- EmptyDiagnostics("go.mod"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("go.mod")),
)
})
}
@@ -924,20 +906,20 @@ func hello() {}
// TODO(rFindley) this doesn't work in multi-module workspace mode, because
// it keeps around the last parsing modfile. Update this test to also
// exercise the workspace module.
- Modes(Singleton),
+ Modes(Default),
).Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("go.mod")
env.Await(env.DoneWithOpen())
env.RegexpReplace("go.mod", "module", "modul")
// Confirm that we still have metadata with only on-disk edits.
env.OpenFile("main.go")
- file, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", "hello"))
- if filepath.Base(file) != "hello.go" {
- t.Fatalf("expected definition in hello.go, got %s", file)
+ loc := env.GoToDefinition(env.RegexpSearch("main.go", "hello"))
+ if filepath.Base(string(loc.URI)) != "hello.go" {
+ t.Fatalf("expected definition in hello.go, got %s", loc.URI)
}
// Confirm that we no longer have metadata when the file is saved.
env.SaveBufferWithoutActions("go.mod")
- _, _, err := env.Editor.GoToDefinition(env.Ctx, "main.go", env.RegexpSearch("main.go", "hello"))
+ _, err := env.Editor.GoToDefinition(env.Ctx, env.RegexpSearch("main.go", "hello"))
if err == nil {
t.Fatalf("expected error, got none")
}
@@ -945,8 +927,6 @@ func hello() {}
}
func TestRemoveUnusedDependency(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
const proxy = `
-- hasdep.com@v1.2.3/go.mod --
module hasdep.com
@@ -996,19 +976,17 @@ func main() {}
).Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("go.mod")
d := &protocol.PublishDiagnosticsParams{}
- env.Await(
- OnceMet(
- env.DiagnosticAtRegexp("go.mod", "require hasdep.com v1.2.3"),
- ReadDiagnostics("go.mod", d),
- ),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("go.mod", "require hasdep.com v1.2.3")),
+ ReadDiagnostics("go.mod", d),
)
const want = `module mod.com
go 1.12
`
env.ApplyQuickFixes("go.mod", d.Diagnostics)
- if got := env.Editor.BufferText("go.mod"); got != want {
- t.Fatalf("unexpected content in go.mod:\n%s", tests.Diff(t, want, got))
+ if got := env.BufferText("go.mod"); got != want {
+ t.Fatalf("unexpected content in go.mod:\n%s", compare.Text(want, got))
}
})
})
@@ -1039,12 +1017,10 @@ func main() {}
).Run(t, mod, func(t *testing.T, env *Env) {
d := &protocol.PublishDiagnosticsParams{}
env.OpenFile("go.mod")
- pos := env.RegexpSearch("go.mod", "require hasdep.com v1.2.3")
- env.Await(
- OnceMet(
- DiagnosticAt("go.mod", pos.Line, pos.Column),
- ReadDiagnostics("go.mod", d),
- ),
+ pos := env.RegexpSearch("go.mod", "require hasdep.com v1.2.3").Range.Start
+ env.AfterChange(
+ Diagnostics(AtPosition("go.mod", pos.Line, pos.Character)),
+ ReadDiagnostics("go.mod", d),
)
const want = `module mod.com
@@ -1060,15 +1036,14 @@ require random.com v1.2.3
diagnostics = append(diagnostics, d)
}
env.ApplyQuickFixes("go.mod", diagnostics)
- if got := env.Editor.BufferText("go.mod"); got != want {
- t.Fatalf("unexpected content in go.mod:\n%s", tests.Diff(t, want, got))
+ if got := env.BufferText("go.mod"); got != want {
+ t.Fatalf("unexpected content in go.mod:\n%s", compare.Text(want, got))
}
})
})
}
func TestSumUpdateQuickFix(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
const mod = `
-- go.mod --
module mod.com
@@ -1092,29 +1067,28 @@ func main() {
`
WithOptions(
ProxyFiles(workspaceProxy),
- Modes(Singleton),
+ Modes(Default),
).Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("go.mod")
params := &protocol.PublishDiagnosticsParams{}
- env.Await(
- OnceMet(
- env.GoSumDiagnostic("go.mod", "example.com"),
- ReadDiagnostics("go.mod", params),
+ env.AfterChange(
+ Diagnostics(
+ env.AtRegexp("go.mod", `example.com`),
+ WithMessage("go.sum is out of sync"),
),
+ ReadDiagnostics("go.mod", params),
)
env.ApplyQuickFixes("go.mod", params.Diagnostics)
const want = `example.com v1.2.3 h1:Yryq11hF02fEf2JlOS2eph+ICE2/ceevGV3C9dl5V/c=
example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
`
if got := env.ReadWorkspaceFile("go.sum"); got != want {
- t.Fatalf("unexpected go.sum contents:\n%s", tests.Diff(t, want, got))
+ t.Fatalf("unexpected go.sum contents:\n%s", compare.Text(want, got))
}
})
}
func TestDownloadDeps(t *testing.T) {
- testenv.NeedsGo1Point(t, 14)
-
const proxy = `
-- example.com@v1.2.3/go.mod --
module example.com
@@ -1161,24 +1135,26 @@ func main() {
`
WithOptions(
ProxyFiles(proxy),
- Modes(Singleton),
+ Modes(Default),
).Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
d := &protocol.PublishDiagnosticsParams{}
- env.Await(
- env.DiagnosticAtRegexpWithMessage("main.go", `"example.com/blah"`, `could not import example.com/blah (no required module provides package "example.com/blah")`),
+ env.AfterChange(
+ Diagnostics(
+ env.AtRegexp("main.go", `"example.com/blah"`),
+ WithMessage(`could not import example.com/blah (no required module provides package "example.com/blah")`),
+ ),
ReadDiagnostics("main.go", d),
)
env.ApplyQuickFixes("main.go", d.Diagnostics)
- env.Await(
- EmptyDiagnostics("main.go"),
- NoDiagnostics("go.mod"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("main.go")),
+ NoDiagnostics(ForFile("go.mod")),
)
})
}
func TestInvalidGoVersion(t *testing.T) {
- testenv.NeedsGo1Point(t, 14) // Times out on 1.13 for reasons unclear. Not worth worrying about.
const files = `
-- go.mod --
module mod.com
@@ -1188,8 +1164,25 @@ go foo
package main
`
Run(t, files, func(t *testing.T, env *Env) {
- env.Await(env.DiagnosticAtRegexpWithMessage("go.mod", `go foo`, "invalid go version"))
+ env.OnceMet(
+ InitialWorkspaceLoad,
+ Diagnostics(env.AtRegexp("go.mod", `go foo`), WithMessage("invalid go version")),
+ )
env.WriteWorkspaceFile("go.mod", "module mod.com \n\ngo 1.12\n")
- env.Await(EmptyDiagnostics("go.mod"))
+ env.AfterChange(NoDiagnostics(ForFile("go.mod")))
+ })
+}
+
+// This is a regression test for a bug in the line-oriented implementation
+// of the "apply diffs" operation used by the fake editor.
+func TestIssue57627(t *testing.T) {
+ const files = `
+-- go.work --
+package main
+`
+ Run(t, files, func(t *testing.T, env *Env) {
+ env.OpenFile("go.work")
+ env.SetBufferContent("go.work", "go 1.18\nuse moda/a")
+ env.SaveBuffer("go.work") // doesn't fail
})
}