aboutsummaryrefslogtreecommitdiff
path: root/gopls/internal/regtest/watch/watch_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'gopls/internal/regtest/watch/watch_test.go')
-rw-r--r--gopls/internal/regtest/watch/watch_test.go292
1 files changed, 114 insertions, 178 deletions
diff --git a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/watch/watch_test.go
index 5b432e18a..edb479a9c 100644
--- a/gopls/internal/regtest/watch/watch_test.go
+++ b/gopls/internal/regtest/watch/watch_test.go
@@ -8,14 +8,15 @@ 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/internal/bug"
- "golang.org/x/tools/internal/lsp/fake"
- "golang.org/x/tools/internal/lsp/protocol"
- "golang.org/x/tools/internal/testenv"
+ "golang.org/x/tools/gopls/internal/lsp/fake"
+ "golang.org/x/tools/gopls/internal/lsp/protocol"
)
func TestMain(m *testing.M) {
+ bug.PanicOnBugs = true
Main(m, hooks.Options)
}
@@ -36,12 +37,13 @@ func _() {
// diagnostics are updated.
t.Run("unopened", func(t *testing.T) {
Run(t, pkg, func(t *testing.T, env *Env) {
- env.Await(
- env.DiagnosticAtRegexp("a/a.go", "x"),
+ env.OnceMet(
+ InitialWorkspaceLoad,
+ Diagnostics(env.AtRegexp("a/a.go", "x")),
)
env.WriteWorkspaceFile("a/a.go", `package a; func _() {};`)
- env.Await(
- EmptyDiagnostics("a/a.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
)
})
})
@@ -54,13 +56,11 @@ func _() {
// Insert a trivial edit so that we don't automatically update the buffer
// (see CL 267577).
env.EditBuffer("a/a.go", fake.NewEdit(0, 0, 0, 0, " "))
- env.Await(env.DoneWithOpen())
+ env.AfterChange()
env.WriteWorkspaceFile("a/a.go", `package a; func _() {};`)
- env.Await(
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- env.DiagnosticAtRegexp("a/a.go", "x"),
- ))
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/a.go", "x")),
+ )
})
})
}
@@ -89,10 +89,10 @@ func _() {
`
Run(t, pkg, func(t *testing.T, env *Env) {
env.OpenFile("a/a.go")
- env.Await(env.DoneWithOpen())
+ env.AfterChange()
env.WriteWorkspaceFile("b/b.go", `package b; func B() {};`)
- env.Await(
- env.DiagnosticAtRegexp("a/a.go", "b.B"),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/a.go", "b.B")),
)
})
}
@@ -122,8 +122,9 @@ func _() {
}
`
Run(t, pkg, func(t *testing.T, env *Env) {
- env.Await(
- env.DiagnosticAtRegexp("a/a.go", "x"),
+ env.OnceMet(
+ InitialWorkspaceLoad,
+ Diagnostics(env.AtRegexp("a/a.go", "x")),
)
env.WriteWorkspaceFiles(map[string]string{
"b/b.go": `package b; func B() {};`,
@@ -135,9 +136,9 @@ func _() {
b.B()
}`,
})
- env.Await(
- EmptyDiagnostics("a/a.go"),
- NoDiagnostics("b/b.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
+ NoDiagnostics(ForFile("b/b.go")),
)
})
}
@@ -166,10 +167,10 @@ func _() {
`
Run(t, pkg, func(t *testing.T, env *Env) {
env.OpenFile("a/a.go")
- env.Await(env.DoneWithOpen())
+ env.AfterChange()
env.RemoveWorkspaceFile("b/b.go")
- env.Await(
- env.DiagnosticAtRegexp("a/a.go", "\"mod.com/b\""),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/a.go", "\"mod.com/b\"")),
)
})
}
@@ -197,14 +198,13 @@ func _() {
}
`
Run(t, missing, func(t *testing.T, env *Env) {
- t.Skip("the initial workspace load fails and never retries")
-
- env.Await(
- env.DiagnosticAtRegexp("a/a.go", "\"mod.com/c\""),
+ env.OnceMet(
+ InitialWorkspaceLoad,
+ Diagnostics(env.AtRegexp("a/a.go", "\"mod.com/c\"")),
)
env.WriteWorkspaceFile("c/c.go", `package c; func C() {};`)
- env.Await(
- EmptyDiagnostics("c/c.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
)
})
}
@@ -225,8 +225,8 @@ func _() {}
Run(t, original, func(t *testing.T, env *Env) {
env.WriteWorkspaceFile("c/c.go", `package c; func C() {};`)
env.WriteWorkspaceFile("a/a.go", `package a; import "mod.com/c"; func _() { c.C() }`)
- env.Await(
- NoDiagnostics("a/a.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
)
})
}
@@ -246,12 +246,13 @@ func _() {
}
`
Run(t, pkg, func(t *testing.T, env *Env) {
- env.Await(
- env.DiagnosticAtRegexp("a/a.go", "hello"),
+ env.OnceMet(
+ InitialWorkspaceLoad,
+ Diagnostics(env.AtRegexp("a/a.go", "hello")),
)
env.WriteWorkspaceFile("a/a2.go", `package a; func hello() {};`)
- env.Await(
- EmptyDiagnostics("a/a.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
)
})
}
@@ -322,15 +323,12 @@ func _() {
t.Run("method before implementation", func(t *testing.T) {
Run(t, pkg, func(t *testing.T, env *Env) {
env.WriteWorkspaceFile("b/b.go", newMethod)
- env.Await(
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- DiagnosticAt("a/a.go", 12, 12),
- ),
+ env.AfterChange(
+ Diagnostics(AtPosition("a/a.go", 12, 12)),
)
env.WriteWorkspaceFile("a/a.go", implementation)
- env.Await(
- EmptyDiagnostics("a/a.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
)
})
})
@@ -338,15 +336,12 @@ func _() {
t.Run("implementation before method", func(t *testing.T) {
Run(t, pkg, func(t *testing.T, env *Env) {
env.WriteWorkspaceFile("a/a.go", implementation)
- env.Await(
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- NoDiagnostics("a/a.go"),
- ),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
)
env.WriteWorkspaceFile("b/b.go", newMethod)
- env.Await(
- NoDiagnostics("a/a.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
)
})
})
@@ -357,12 +352,9 @@ func _() {
"a/a.go": implementation,
"b/b.go": newMethod,
})
- env.Await(
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- NoDiagnostics("a/a.go"),
- ),
- NoDiagnostics("b/b.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
+ NoDiagnostics(ForFile("b/b.go")),
)
})
})
@@ -371,7 +363,6 @@ func _() {
// Tests golang/go#38498. Delete a file and then force a reload.
// Assert that we no longer try to load the file.
func TestDeleteFiles(t *testing.T) {
- testenv.NeedsGo1Point(t, 13) // Poor overlay support causes problems on 1.12.
const pkg = `
-- go.mod --
module mod.com
@@ -387,69 +378,57 @@ func _() {
package a
`
t.Run("close then delete", func(t *testing.T) {
- WithOptions(EditorConfig{
- VerboseOutput: true,
- }).Run(t, pkg, func(t *testing.T, env *Env) {
+ WithOptions(
+ Settings{"verboseOutput": true},
+ ).Run(t, pkg, func(t *testing.T, env *Env) {
env.OpenFile("a/a.go")
env.OpenFile("a/a_unneeded.go")
- env.Await(
- OnceMet(
- env.DoneWithOpen(),
- LogMatching(protocol.Info, "a_unneeded.go", 1, false),
- ),
+ env.AfterChange(
+ LogMatching(protocol.Info, "a_unneeded.go", 1, false),
)
// Close and delete the open file, mimicking what an editor would do.
env.CloseBuffer("a/a_unneeded.go")
env.RemoveWorkspaceFile("a/a_unneeded.go")
env.RegexpReplace("a/a.go", "var _ int", "fmt.Println(\"\")")
- env.Await(
- env.DiagnosticAtRegexp("a/a.go", "fmt"),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/a.go", "fmt")),
)
env.SaveBuffer("a/a.go")
- env.Await(
- OnceMet(
- env.DoneWithSave(),
- // There should only be one log message containing
- // a_unneeded.go, from the initial workspace load, which we
- // check for earlier. If there are more, there's a bug.
- LogMatching(protocol.Info, "a_unneeded.go", 1, false),
- ),
- EmptyDiagnostics("a/a.go"),
+ env.AfterChange(
+ // There should only be one log message containing
+ // a_unneeded.go, from the initial workspace load, which we
+ // check for earlier. If there are more, there's a bug.
+ LogMatching(protocol.Info, "a_unneeded.go", 1, false),
+ NoDiagnostics(ForFile("a/a.go")),
)
})
})
t.Run("delete then close", func(t *testing.T) {
WithOptions(
- EditorConfig{VerboseOutput: true},
+ Settings{"verboseOutput": true},
).Run(t, pkg, func(t *testing.T, env *Env) {
env.OpenFile("a/a.go")
env.OpenFile("a/a_unneeded.go")
- env.Await(
- OnceMet(
- env.DoneWithOpen(),
- LogMatching(protocol.Info, "a_unneeded.go", 1, false),
- ),
+ env.AfterChange(
+ LogMatching(protocol.Info, "a_unneeded.go", 1, false),
)
// Delete and then close the file.
env.RemoveWorkspaceFile("a/a_unneeded.go")
env.CloseBuffer("a/a_unneeded.go")
env.RegexpReplace("a/a.go", "var _ int", "fmt.Println(\"\")")
- env.Await(
- env.DiagnosticAtRegexp("a/a.go", "fmt"),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("a/a.go", "fmt")),
)
env.SaveBuffer("a/a.go")
- env.Await(
- OnceMet(
- env.DoneWithSave(),
- // There should only be one log message containing
- // a_unneeded.go, from the initial workspace load, which we
- // check for earlier. If there are more, there's a bug.
- LogMatching(protocol.Info, "a_unneeded.go", 1, false),
- ),
- EmptyDiagnostics("a/a.go"),
+ env.AfterChange(
+ // There should only be one log message containing
+ // a_unneeded.go, from the initial workspace load, which we
+ // check for earlier. If there are more, there's a bug.
+ LogMatching(protocol.Info, "a_unneeded.go", 1, false),
+ NoDiagnostics(ForFile("a/a.go")),
)
})
})
@@ -487,39 +466,11 @@ package a
func _() {}
`
Run(t, pkg, func(t *testing.T, env *Env) {
- env.ChangeFilesOnDisk([]fake.FileEvent{
- {
- Path: "a/a3.go",
- Content: `package a
-
-var Hello int
-`,
- ProtocolEvent: protocol.FileEvent{
- URI: env.Sandbox.Workdir.URI("a/a3.go"),
- Type: protocol.Created,
- },
- },
- {
- Path: "a/a1.go",
- ProtocolEvent: protocol.FileEvent{
- URI: env.Sandbox.Workdir.URI("a/a1.go"),
- Type: protocol.Deleted,
- },
- },
- {
- Path: "a/a2.go",
- Content: `package a; func _() {};`,
- ProtocolEvent: protocol.FileEvent{
- URI: env.Sandbox.Workdir.URI("a/a2.go"),
- Type: protocol.Changed,
- },
- },
- })
- env.Await(
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- NoDiagnostics("main.go"),
- ),
+ env.WriteWorkspaceFile("a/a3.go", "package a\n\nvar Hello int\n")
+ env.RemoveWorkspaceFile("a/a1.go")
+ env.WriteWorkspaceFile("a/a2.go", "package a; func _() {};")
+ env.AfterChange(
+ NoDiagnostics(ForFile("main.go")),
)
})
}
@@ -563,6 +514,9 @@ module mod.com
go 1.12
require example.com v1.2.2
+-- go.sum --
+example.com v1.2.3 h1:OnPPkx+rW63kj9pgILsu12MORKhSlnFa3DVRJq1HZ7g=
+example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
-- main.go --
package main
@@ -591,26 +545,24 @@ func main() {
}
`,
})
- env.Await(
+ env.AfterChange(
env.DoneWithChangeWatchedFiles(),
- NoDiagnostics("main.go"),
+ NoDiagnostics(ForFile("main.go")),
)
})
}
// Reproduces golang/go#40340.
-func TestSwitchFromGOPATHToModules(t *testing.T) {
- testenv.NeedsGo1Point(t, 13)
-
+func TestSwitchFromGOPATHToModuleMode(t *testing.T) {
const files = `
-- foo/blah/blah.go --
package blah
const Name = ""
--- foo/main.go --
+-- main.go --
package main
-import "blah"
+import "foo/blah"
func main() {
_ = blah.Name
@@ -618,29 +570,32 @@ func main() {
`
WithOptions(
InGOPATH(),
- EditorConfig{
- Env: map[string]string{
- "GO111MODULE": "auto",
- },
- },
- Modes(Experimental), // module is in a subdirectory
+ Modes(Default), // golang/go#57521: this test is temporarily failing in 'experimental' mode
+ EnvVars{"GO111MODULE": "auto"},
).Run(t, files, func(t *testing.T, env *Env) {
- env.OpenFile("foo/main.go")
- env.Await(env.DiagnosticAtRegexp("foo/main.go", `"blah"`))
- if err := env.Sandbox.RunGoCommand(env.Ctx, "foo", "mod", []string{"init", "mod.com"}, true); err != nil {
+ env.OpenFile("main.go")
+ env.AfterChange(
+ NoDiagnostics(ForFile("main.go")),
+ )
+ if err := env.Sandbox.RunGoCommand(env.Ctx, "", "mod", []string{"init", "mod.com"}, true); err != nil {
t.Fatal(err)
}
- env.RegexpReplace("foo/main.go", `"blah"`, `"mod.com/blah"`)
- env.Await(
- EmptyDiagnostics("foo/main.go"),
+
+ // TODO(golang/go#57558, golang/go#57512): file watching is asynchronous,
+ // and we must wait for the view to be reconstructed before touching
+ // main.go, so that the new view "knows" about main.go. This is a bug, but
+ // awaiting the change here avoids it.
+ env.AfterChange()
+
+ env.RegexpReplace("main.go", `"foo/blah"`, `"mod.com/foo/blah"`)
+ env.AfterChange(
+ NoDiagnostics(ForFile("main.go")),
)
})
}
// Reproduces golang/go#40487.
func TestSwitchFromModulesToGOPATH(t *testing.T) {
- testenv.NeedsGo1Point(t, 13)
-
const files = `
-- foo/go.mod --
module mod.com
@@ -661,23 +616,16 @@ func main() {
`
WithOptions(
InGOPATH(),
- EditorConfig{
- Env: map[string]string{
- "GO111MODULE": "auto",
- },
- },
+ EnvVars{"GO111MODULE": "auto"},
).Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("foo/main.go")
env.RemoveWorkspaceFile("foo/go.mod")
- env.Await(
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- env.DiagnosticAtRegexp("foo/main.go", `"mod.com/blah"`),
- ),
+ env.AfterChange(
+ Diagnostics(env.AtRegexp("foo/main.go", `"mod.com/blah"`)),
)
env.RegexpReplace("foo/main.go", `"mod.com/blah"`, `"foo/blah"`)
- env.Await(
- EmptyDiagnostics("foo/main.go"),
+ env.AfterChange(
+ NoDiagnostics(ForFile("foo/main.go")),
)
})
}
@@ -720,15 +668,9 @@ func TestAll(t *testing.T) {
}
`,
})
- env.Await(
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- NoDiagnostics("a/a.go"),
- ),
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- NoDiagnostics("a/a_test.go"),
- ),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a.go")),
+ NoDiagnostics(ForFile("a/a_test.go")),
)
// Now, add a new file to the test variant and use its symbol in the
// original test file. Expect no diagnostics.
@@ -752,15 +694,9 @@ func hi() {}
func TestSomething(t *testing.T) {}
`,
})
- env.Await(
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- NoDiagnostics("a/a_test.go"),
- ),
- OnceMet(
- env.DoneWithChangeWatchedFiles(),
- NoDiagnostics("a/a2_test.go"),
- ),
+ env.AfterChange(
+ NoDiagnostics(ForFile("a/a_test.go")),
+ NoDiagnostics(ForFile("a/a2_test.go")),
)
})
}