gopls/internal/regtest: clean up TestFillReturnsPanic
The test doesn't necessarily need to require exactly 2 log messages, so
the match doesn't need to be so exact.
Updates golang/go#46546
Change-Id: I6ec5dee820c76c41db7b1d4bad3925fc7afe25e4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/324760
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/gopls/internal/regtest/diagnostics/diagnostics_test.go b/gopls/internal/regtest/diagnostics/diagnostics_test.go
index 019ba65..832b85e 100644
--- a/gopls/internal/regtest/diagnostics/diagnostics_test.go
+++ b/gopls/internal/regtest/diagnostics/diagnostics_test.go
@@ -438,7 +438,7 @@
func TestMissingDependency(t *testing.T) {
Run(t, testPackageWithRequire, func(t *testing.T, env *Env) {
env.OpenFile("print.go")
- env.Await(LogMatching(protocol.Error, "initial workspace load failed", 1))
+ env.Await(LogMatching(protocol.Error, "initial workspace load failed", 1, false))
})
}
@@ -1886,29 +1886,33 @@
})
}
-// Tests golang/go#45075, a panic in fillreturns breaks diagnostics.
+// Tests golang/go#45075: A panic in fillreturns broke diagnostics.
+// Expect an error log indicating that fillreturns panicked, as well type
+// errors for the broken code.
func TestFillReturnsPanic(t *testing.T) {
// At tip, the panic no longer reproduces.
testenv.SkipAfterGo1Point(t, 16)
+
const files = `
-- go.mod --
module mod.com
-go 1.16
+go 1.15
-- main.go --
package main
-
func foo() int {
return x, nil
}
-
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
env.Await(
- env.DiagnosticAtRegexpWithMessage("main.go", `return x`, "wrong number of return values"),
- LogMatching(protocol.Error, `.*analysis fillreturns.*panicked.*`, 2),
+ OnceMet(
+ env.DoneWithOpen(),
+ LogMatching(protocol.Error, `.*analysis fillreturns.*panicked.*`, 1, true),
+ env.DiagnosticAtRegexpWithMessage("main.go", `return x`, "wrong number of return values"),
+ ),
)
})
}
@@ -1931,7 +1935,7 @@
env.Await(
OnceMet(
env.DoneWithOpen(),
- LogMatching(protocol.Info, `.*query=\[builtin mod.com/...\].*`, 1),
+ LogMatching(protocol.Info, `.*query=\[builtin mod.com/...\].*`, 1, false),
),
)
})
diff --git a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/watch/watch_test.go
index 8d98539..5b432e1 100644
--- a/gopls/internal/regtest/watch/watch_test.go
+++ b/gopls/internal/regtest/watch/watch_test.go
@@ -395,7 +395,7 @@
env.Await(
OnceMet(
env.DoneWithOpen(),
- LogMatching(protocol.Info, "a_unneeded.go", 1),
+ LogMatching(protocol.Info, "a_unneeded.go", 1, false),
),
)
@@ -413,7 +413,7 @@
// 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),
+ LogMatching(protocol.Info, "a_unneeded.go", 1, false),
),
EmptyDiagnostics("a/a.go"),
)
@@ -429,7 +429,7 @@
env.Await(
OnceMet(
env.DoneWithOpen(),
- LogMatching(protocol.Info, "a_unneeded.go", 1),
+ LogMatching(protocol.Info, "a_unneeded.go", 1, false),
),
)
@@ -447,7 +447,7 @@
// 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),
+ LogMatching(protocol.Info, "a_unneeded.go", 1, false),
),
EmptyDiagnostics("a/a.go"),
)
diff --git a/internal/lsp/regtest/expectation.go b/internal/lsp/regtest/expectation.go
index 748e698..bd7649d 100644
--- a/internal/lsp/regtest/expectation.go
+++ b/internal/lsp/regtest/expectation.go
@@ -79,24 +79,30 @@
// OnceMet returns an Expectation that, once the precondition is met, asserts
// that mustMeet is met.
-func OnceMet(precondition Expectation, mustMeet Expectation) *SimpleExpectation {
+func OnceMet(precondition Expectation, mustMeets ...Expectation) *SimpleExpectation {
check := func(s State) Verdict {
switch pre := precondition.Check(s); pre {
case Unmeetable:
return Unmeetable
case Met:
- verdict := mustMeet.Check(s)
- if verdict != Met {
- return Unmeetable
+ for _, mustMeet := range mustMeets {
+ verdict := mustMeet.Check(s)
+ if verdict != Met {
+ return Unmeetable
+ }
}
return Met
default:
return Unmet
}
}
+ var descriptions []string
+ for _, mustMeet := range mustMeets {
+ descriptions = append(descriptions, mustMeet.Description())
+ }
return &SimpleExpectation{
check: check,
- description: fmt.Sprintf("once %q is met, must have %q", precondition.Description(), mustMeet.Description()),
+ description: fmt.Sprintf("once %q is met, must have %q", precondition.Description(), strings.Join(descriptions, "\n")),
}
}
@@ -303,7 +309,7 @@
// LogMatching asserts that the client has received a log message
// of type typ matching the regexp re.
-func LogMatching(typ protocol.MessageType, re string, count int) LogExpectation {
+func LogMatching(typ protocol.MessageType, re string, count int, atLeast bool) LogExpectation {
rec, err := regexp.Compile(re)
if err != nil {
panic(err)
@@ -315,14 +321,19 @@
found++
}
}
- if found == count {
+ // Check for an exact or "at least" match.
+ if found == count || (found >= count && atLeast) {
return Met
}
return Unmet
}
+ desc := fmt.Sprintf("log message matching %q expected %v times", re, count)
+ if atLeast {
+ desc = fmt.Sprintf("log message matching %q expected at least %v times", re, count)
+ }
return LogExpectation{
check: check,
- description: fmt.Sprintf("log message matching %q", re),
+ description: desc,
}
}