diff --git a/internal/lsp/regtest/diagnostics_test.go b/internal/lsp/regtest/diagnostics_test.go index 8a46bf9008..11c893192b 100644 --- a/internal/lsp/regtest/diagnostics_test.go +++ b/internal/lsp/regtest/diagnostics_test.go @@ -28,13 +28,21 @@ func main() { }` func TestDiagnosticErrorInEditedFile(t *testing.T) { + // This test is very basic: start with a clean Go program, make an error, and + // get a diagnostic for that error. However, it also demonstrates how to + // combine Expectations to await more complex state in the editor. runner.Run(t, exampleProgram, func(t *testing.T, env *Env) { // Deleting the 'n' at the end of Println should generate a single error // diagnostic. env.OpenFile("main.go") env.RegexpReplace("main.go", "Printl(n)", "") env.Await( - env.DiagnosticAtRegexp("main.go", "Printl"), + // Once we have gotten diagnostics for the change above, we should + // satisfy the DiagnosticAtRegexp assertion. + OnceMet( + CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), 1), + env.DiagnosticAtRegexp("main.go", "Printl"), + ), // Assert that this test has sent no error logs to the client. This is not // strictly necessary for testing this regression, but is included here // as an example of using the NoErrorLogs() expectation. Feel free to diff --git a/internal/lsp/regtest/env.go b/internal/lsp/regtest/env.go index 1865b80472..30ab143cf8 100644 --- a/internal/lsp/regtest/env.go +++ b/internal/lsp/regtest/env.go @@ -259,6 +259,29 @@ const ( Unmeetable ) +// OnceMet returns an Expectation that, once the precondition is met, asserts +// that mustMeet is met. +func OnceMet(precondition Expectation, mustMeet Expectation) *SimpleExpectation { + check := func(s State) (Verdict, interface{}) { + switch pre, _ := precondition.Check(s); pre { + case Unmeetable: + return Unmeetable, nil + case Met: + verdict, metBy := mustMeet.Check(s) + if verdict != Met { + return Unmeetable, metBy + } + return Met, metBy + default: + return Unmet, nil + } + } + return &SimpleExpectation{ + check: check, + description: fmt.Sprintf("once %q is met, must have %q", precondition.Description(), mustMeet.Description()), + } +} + func (v Verdict) String() string { switch v { case Met: