diff --git a/gopls/internal/regtest/env.go b/gopls/internal/regtest/env.go
index 356fbb5..069a95d 100644
--- a/gopls/internal/regtest/env.go
+++ b/gopls/internal/regtest/env.go
@@ -7,7 +7,6 @@
 import (
 	"context"
 	"fmt"
-	"regexp"
 	"strings"
 	"sync"
 	"testing"
@@ -281,462 +280,6 @@
 	return finalVerdict, summary.String(), metBy
 }
 
-// An Expectation asserts that the state of the editor at a point in time
-// matches an expected condition. This is used for signaling in tests when
-// certain conditions in the editor are met.
-type Expectation interface {
-	// Check determines whether the state of the editor satisfies the
-	// expectation, returning the results that met the condition.
-	Check(State) (Verdict, interface{})
-	// Description is a human-readable description of the expectation.
-	Description() string
-}
-
-// A Verdict is the result of checking an expectation against the current
-// editor state.
-type Verdict int
-
-// Order matters for the following constants: verdicts are sorted in order of
-// decisiveness.
-const (
-	// Met indicates that an expectation is satisfied by the current state.
-	Met Verdict = iota
-	// Unmet indicates that an expectation is not currently met, but could be met
-	// in the future.
-	Unmet
-	// Unmeetable indicates that an expectation cannot be satisfied in the
-	// future.
-	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:
-		return "Met"
-	case Unmet:
-		return "Unmet"
-	case Unmeetable:
-		return "Unmeetable"
-	}
-	return fmt.Sprintf("unrecognized verdict %d", v)
-}
-
-// SimpleExpectation holds an arbitrary check func, and implements the Expectation interface.
-type SimpleExpectation struct {
-	check       func(State) (Verdict, interface{})
-	description string
-}
-
-// Check invokes e.check.
-func (e SimpleExpectation) Check(s State) (Verdict, interface{}) {
-	return e.check(s)
-}
-
-// Description returns e.descriptin.
-func (e SimpleExpectation) Description() string {
-	return e.description
-}
-
-// NoOutstandingWork asserts that there is no work initiated using the LSP
-// $/progress API that has not completed.
-func NoOutstandingWork() SimpleExpectation {
-	check := func(s State) (Verdict, interface{}) {
-		if len(s.outstandingWork) == 0 {
-			return Met, nil
-		}
-		return Unmet, nil
-	}
-	return SimpleExpectation{
-		check:       check,
-		description: "no outstanding work",
-	}
-}
-
-// NoShowMessage asserts that the editor has not received a ShowMessage.
-func NoShowMessage() SimpleExpectation {
-	check := func(s State) (Verdict, interface{}) {
-		if len(s.showMessage) == 0 {
-			return Met, "no ShowMessage"
-		}
-		return Unmeetable, nil
-	}
-	return SimpleExpectation{
-		check:       check,
-		description: "no ShowMessage received",
-	}
-}
-
-// ShownMessage asserts that the editor has received a ShownMessage with the
-// given title.
-func ShownMessage(title string) SimpleExpectation {
-	check := func(s State) (Verdict, interface{}) {
-		for _, m := range s.showMessage {
-			if strings.Contains(m.Message, title) {
-				return Met, m
-			}
-		}
-		return Unmet, nil
-	}
-	return SimpleExpectation{
-		check:       check,
-		description: "received ShowMessage",
-	}
-}
-
-// ShowMessageRequest asserts that the editor has received a ShowMessageRequest
-// with an action item that has the given title.
-func ShowMessageRequest(title string) SimpleExpectation {
-	check := func(s State) (Verdict, interface{}) {
-		if len(s.showMessageRequest) == 0 {
-			return Unmet, nil
-		}
-		// Only check the most recent one.
-		m := s.showMessageRequest[len(s.showMessageRequest)-1]
-		if len(m.Actions) == 0 || len(m.Actions) > 1 {
-			return Unmet, nil
-		}
-		if m.Actions[0].Title == title {
-			return Met, m.Actions[0]
-		}
-		return Unmet, nil
-	}
-	return SimpleExpectation{
-		check:       check,
-		description: "received ShowMessageRequest",
-	}
-}
-
-// CompletedWork expects a work item to have been completed >= atLeast times.
-//
-// Since the Progress API doesn't include any hidden metadata, we must use the
-// progress notification title to identify the work we expect to be completed.
-func CompletedWork(title string, atLeast int) SimpleExpectation {
-	check := func(s State) (Verdict, interface{}) {
-		if s.completedWork[title] >= atLeast {
-			return Met, title
-		}
-		return Unmet, nil
-	}
-	return SimpleExpectation{
-		check:       check,
-		description: fmt.Sprintf("completed work %q at least %d time(s)", title, atLeast),
-	}
-}
-
-// LogExpectation is an expectation on the log messages received by the editor
-// from gopls.
-type LogExpectation struct {
-	check       func([]*protocol.LogMessageParams) (Verdict, interface{})
-	description string
-}
-
-// Check implements the Expectation interface.
-func (e LogExpectation) Check(s State) (Verdict, interface{}) {
-	return e.check(s.logs)
-}
-
-// Description implements the Expectation interface.
-func (e LogExpectation) Description() string {
-	return e.description
-}
-
-// NoErrorLogs asserts that the client has not received any log messages of
-// error severity.
-func NoErrorLogs() LogExpectation {
-	return NoLogMatching(protocol.Error, "")
-}
-
-// 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 {
-	rec, err := regexp.Compile(re)
-	if err != nil {
-		panic(err)
-	}
-	check := func(msgs []*protocol.LogMessageParams) (Verdict, interface{}) {
-		var found int
-		for _, msg := range msgs {
-			if msg.Type == typ && rec.Match([]byte(msg.Message)) {
-				found++
-			}
-		}
-		if found == count {
-			return Met, nil
-		}
-		return Unmet, nil
-	}
-	return LogExpectation{
-		check:       check,
-		description: fmt.Sprintf("log message matching %q", re),
-	}
-}
-
-// NoLogMatching asserts that the client has not received a log message
-// of type typ matching the regexp re. If re is an empty string, any log
-// message is considered a match.
-func NoLogMatching(typ protocol.MessageType, re string) LogExpectation {
-	var r *regexp.Regexp
-	if re != "" {
-		var err error
-		r, err = regexp.Compile(re)
-		if err != nil {
-			panic(err)
-		}
-	}
-	check := func(msgs []*protocol.LogMessageParams) (Verdict, interface{}) {
-		for _, msg := range msgs {
-			if msg.Type != typ {
-				continue
-			}
-			if r == nil || r.Match([]byte(msg.Message)) {
-				return Unmeetable, nil
-			}
-		}
-		return Met, nil
-	}
-	return LogExpectation{
-		check:       check,
-		description: fmt.Sprintf("no log message matching %q", re),
-	}
-}
-
-// RegistrationExpectation is an expectation on the capability registrations
-// received by the editor from gopls.
-type RegistrationExpectation struct {
-	check       func([]*protocol.RegistrationParams) (Verdict, interface{})
-	description string
-}
-
-// Check implements the Expectation interface.
-func (e RegistrationExpectation) Check(s State) (Verdict, interface{}) {
-	return e.check(s.registrations)
-}
-
-// Description implements the Expectation interface.
-func (e RegistrationExpectation) Description() string {
-	return e.description
-}
-
-// RegistrationMatching asserts that the client has received a capability
-// registration matching the given regexp.
-func RegistrationMatching(re string) RegistrationExpectation {
-	rec, err := regexp.Compile(re)
-	if err != nil {
-		panic(err)
-	}
-	check := func(params []*protocol.RegistrationParams) (Verdict, interface{}) {
-		for _, p := range params {
-			for _, r := range p.Registrations {
-				if rec.Match([]byte(r.Method)) {
-					return Met, r
-				}
-			}
-		}
-		return Unmet, nil
-	}
-	return RegistrationExpectation{
-		check:       check,
-		description: fmt.Sprintf("registration matching %q", re),
-	}
-}
-
-// UnregistrationExpectation is an expectation on the capability
-// unregistrations received by the editor from gopls.
-type UnregistrationExpectation struct {
-	check       func([]*protocol.UnregistrationParams) (Verdict, interface{})
-	description string
-}
-
-// Check implements the Expectation interface.
-func (e UnregistrationExpectation) Check(s State) (Verdict, interface{}) {
-	return e.check(s.unregistrations)
-}
-
-// Description implements the Expectation interface.
-func (e UnregistrationExpectation) Description() string {
-	return e.description
-}
-
-// UnregistrationMatching asserts that the client has received an
-// unregistration whose ID matches the given regexp.
-func UnregistrationMatching(re string) UnregistrationExpectation {
-	rec, err := regexp.Compile(re)
-	if err != nil {
-		panic(err)
-	}
-	check := func(params []*protocol.UnregistrationParams) (Verdict, interface{}) {
-		for _, p := range params {
-			for _, r := range p.Unregisterations {
-				if rec.Match([]byte(r.Method)) {
-					return Met, r
-				}
-			}
-		}
-		return Unmet, nil
-	}
-	return UnregistrationExpectation{
-		check:       check,
-		description: fmt.Sprintf("unregistration matching %q", re),
-	}
-}
-
-// A DiagnosticExpectation is a condition that must be met by the current set
-// of diagnostics for a file.
-type DiagnosticExpectation struct {
-	// IsMet determines whether the diagnostics for this file version satisfy our
-	// expectation.
-	isMet func(*protocol.PublishDiagnosticsParams) bool
-	// Description is a human-readable description of the diagnostic expectation.
-	description string
-	// Path is the scratch workdir-relative path to the file being asserted on.
-	path string
-}
-
-// Check implements the Expectation interface.
-func (e DiagnosticExpectation) Check(s State) (Verdict, interface{}) {
-	if diags, ok := s.diagnostics[e.path]; ok && e.isMet(diags) {
-		return Met, diags
-	}
-	return Unmet, nil
-}
-
-// Description implements the Expectation interface.
-func (e DiagnosticExpectation) Description() string {
-	return fmt.Sprintf("%s: %s", e.path, e.description)
-}
-
-// EmptyDiagnostics asserts that empty diagnostics are sent for the
-// workspace-relative path name.
-func EmptyDiagnostics(name string) Expectation {
-	check := func(s State) (Verdict, interface{}) {
-		if diags := s.diagnostics[name]; diags != nil && len(diags.Diagnostics) == 0 {
-			return Met, nil
-		}
-		return Unmet, nil
-	}
-	return SimpleExpectation{
-		check:       check,
-		description: "empty diagnostics",
-	}
-}
-
-// NoDiagnostics asserts that no diagnostics are sent for the
-// workspace-relative path name. It should be used primarily in conjunction
-// with a OnceMet, as it has to check that all outstanding diagnostics have
-// already been delivered.
-func NoDiagnostics(name string) Expectation {
-	check := func(s State) (Verdict, interface{}) {
-		if _, ok := s.diagnostics[name]; !ok {
-			return Met, nil
-		}
-		return Unmet, nil
-	}
-	return SimpleExpectation{
-		check:       check,
-		description: "no diagnostics",
-	}
-}
-
-// AnyDiagnosticAtCurrentVersion asserts that there is a diagnostic report for
-// the current edited version of the buffer corresponding to the given
-// workdir-relative pathname.
-func (e *Env) AnyDiagnosticAtCurrentVersion(name string) DiagnosticExpectation {
-	version := e.Editor.BufferVersion(name)
-	isMet := func(diags *protocol.PublishDiagnosticsParams) bool {
-		return int(diags.Version) == version
-	}
-	return DiagnosticExpectation{
-		isMet:       isMet,
-		description: fmt.Sprintf("any diagnostics at version %d", version),
-		path:        name,
-	}
-}
-
-// DiagnosticAtRegexp expects that there is a diagnostic entry at the start
-// position matching the regexp search string re in the buffer specified by
-// name. Note that this currently ignores the end position.
-func (e *Env) DiagnosticAtRegexp(name, re string) DiagnosticExpectation {
-	e.T.Helper()
-	pos := e.RegexpSearch(name, re)
-	expectation := DiagnosticAt(name, pos.Line, pos.Column)
-	expectation.description += fmt.Sprintf(" (location of %q)", re)
-	return expectation
-}
-
-// DiagnosticAt asserts that there is a diagnostic entry at the position
-// specified by line and col, for the workdir-relative path name.
-func DiagnosticAt(name string, line, col int) DiagnosticExpectation {
-	isMet := func(diags *protocol.PublishDiagnosticsParams) bool {
-		for _, d := range diags.Diagnostics {
-			if d.Range.Start.Line == float64(line) && d.Range.Start.Character == float64(col) {
-				return true
-			}
-		}
-		return false
-	}
-	return DiagnosticExpectation{
-		isMet:       isMet,
-		description: fmt.Sprintf("diagnostic at {line:%d, column:%d}", line, col),
-		path:        name,
-	}
-}
-
-// NoDiagnosticAtRegexp expects that there is no diagnostic entry at the start
-// position matching the regexp search string re in the buffer specified by
-// name. Note that this currently ignores the end position.
-// This should only be used in combination with OnceMet for a given condition,
-// otherwise it may always succeed.
-func (e *Env) NoDiagnosticAtRegexp(name, re string) DiagnosticExpectation {
-	e.T.Helper()
-	pos := e.RegexpSearch(name, re)
-	expectation := NoDiagnosticAt(name, pos.Line, pos.Column)
-	expectation.description += fmt.Sprintf(" (location of %q)", re)
-	return expectation
-}
-
-// NoDiagnosticAt asserts that there is no diagnostic entry at the position
-// specified by line and col, for the workdir-relative path name.
-// This should only be used in combination with OnceMet for a given condition,
-// otherwise it may always succeed.
-func NoDiagnosticAt(name string, line, col int) DiagnosticExpectation {
-	isMet := func(diags *protocol.PublishDiagnosticsParams) bool {
-		for _, d := range diags.Diagnostics {
-			if d.Range.Start.Line == float64(line) && d.Range.Start.Character == float64(col) {
-				return false
-			}
-		}
-		return true
-	}
-	return DiagnosticExpectation{
-		isMet:       isMet,
-		description: fmt.Sprintf("no diagnostic at {line:%d, column:%d}", line, col),
-		path:        name,
-	}
-}
-
 // DiagnosticsFor returns the current diagnostics for the file. It is useful
 // after waiting on AnyDiagnosticAtCurrentVersion, when the desired diagnostic
 // is not simply described by DiagnosticAt.
diff --git a/gopls/internal/regtest/expectation.go b/gopls/internal/regtest/expectation.go
new file mode 100644
index 0000000..19f5ff2
--- /dev/null
+++ b/gopls/internal/regtest/expectation.go
@@ -0,0 +1,469 @@
+// Copyright 2020 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 regtest
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+
+	"golang.org/x/tools/internal/lsp/protocol"
+)
+
+// An Expectation asserts that the state of the editor at a point in time
+// matches an expected condition. This is used for signaling in tests when
+// certain conditions in the editor are met.
+type Expectation interface {
+	// Check determines whether the state of the editor satisfies the
+	// expectation, returning the results that met the condition.
+	Check(State) (Verdict, interface{})
+	// Description is a human-readable description of the expectation.
+	Description() string
+}
+
+// A Verdict is the result of checking an expectation against the current
+// editor state.
+type Verdict int
+
+// Order matters for the following constants: verdicts are sorted in order of
+// decisiveness.
+const (
+	// Met indicates that an expectation is satisfied by the current state.
+	Met Verdict = iota
+	// Unmet indicates that an expectation is not currently met, but could be met
+	// in the future.
+	Unmet
+	// Unmeetable indicates that an expectation cannot be satisfied in the
+	// future.
+	Unmeetable
+)
+
+func (v Verdict) String() string {
+	switch v {
+	case Met:
+		return "Met"
+	case Unmet:
+		return "Unmet"
+	case Unmeetable:
+		return "Unmeetable"
+	}
+	return fmt.Sprintf("unrecognized verdict %d", v)
+}
+
+// SimpleExpectation holds an arbitrary check func, and implements the Expectation interface.
+type SimpleExpectation struct {
+	check       func(State) (Verdict, interface{})
+	description string
+}
+
+// Check invokes e.check.
+func (e SimpleExpectation) Check(s State) (Verdict, interface{}) {
+	return e.check(s)
+}
+
+// Description returns e.descriptin.
+func (e SimpleExpectation) Description() string {
+	return e.description
+}
+
+// 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()),
+	}
+}
+
+// NoOutstandingWork asserts that there is no work initiated using the LSP
+// $/progress API that has not completed.
+func NoOutstandingWork() SimpleExpectation {
+	check := func(s State) (Verdict, interface{}) {
+		if len(s.outstandingWork) == 0 {
+			return Met, nil
+		}
+		return Unmet, nil
+	}
+	return SimpleExpectation{
+		check:       check,
+		description: "no outstanding work",
+	}
+}
+
+// NoShowMessage asserts that the editor has not received a ShowMessage.
+func NoShowMessage() SimpleExpectation {
+	check := func(s State) (Verdict, interface{}) {
+		if len(s.showMessage) == 0 {
+			return Met, "no ShowMessage"
+		}
+		return Unmeetable, nil
+	}
+	return SimpleExpectation{
+		check:       check,
+		description: "no ShowMessage received",
+	}
+}
+
+// ShownMessage asserts that the editor has received a ShownMessage with the
+// given title.
+func ShownMessage(title string) SimpleExpectation {
+	check := func(s State) (Verdict, interface{}) {
+		for _, m := range s.showMessage {
+			if strings.Contains(m.Message, title) {
+				return Met, m
+			}
+		}
+		return Unmet, nil
+	}
+	return SimpleExpectation{
+		check:       check,
+		description: "received ShowMessage",
+	}
+}
+
+// ShowMessageRequest asserts that the editor has received a ShowMessageRequest
+// with an action item that has the given title.
+func ShowMessageRequest(title string) SimpleExpectation {
+	check := func(s State) (Verdict, interface{}) {
+		if len(s.showMessageRequest) == 0 {
+			return Unmet, nil
+		}
+		// Only check the most recent one.
+		m := s.showMessageRequest[len(s.showMessageRequest)-1]
+		if len(m.Actions) == 0 || len(m.Actions) > 1 {
+			return Unmet, nil
+		}
+		if m.Actions[0].Title == title {
+			return Met, m.Actions[0]
+		}
+		return Unmet, nil
+	}
+	return SimpleExpectation{
+		check:       check,
+		description: "received ShowMessageRequest",
+	}
+}
+
+// CompletedWork expects a work item to have been completed >= atLeast times.
+//
+// Since the Progress API doesn't include any hidden metadata, we must use the
+// progress notification title to identify the work we expect to be completed.
+func CompletedWork(title string, atLeast int) SimpleExpectation {
+	check := func(s State) (Verdict, interface{}) {
+		if s.completedWork[title] >= atLeast {
+			return Met, title
+		}
+		return Unmet, nil
+	}
+	return SimpleExpectation{
+		check:       check,
+		description: fmt.Sprintf("completed work %q at least %d time(s)", title, atLeast),
+	}
+}
+
+// LogExpectation is an expectation on the log messages received by the editor
+// from gopls.
+type LogExpectation struct {
+	check       func([]*protocol.LogMessageParams) (Verdict, interface{})
+	description string
+}
+
+// Check implements the Expectation interface.
+func (e LogExpectation) Check(s State) (Verdict, interface{}) {
+	return e.check(s.logs)
+}
+
+// Description implements the Expectation interface.
+func (e LogExpectation) Description() string {
+	return e.description
+}
+
+// NoErrorLogs asserts that the client has not received any log messages of
+// error severity.
+func NoErrorLogs() LogExpectation {
+	return NoLogMatching(protocol.Error, "")
+}
+
+// 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 {
+	rec, err := regexp.Compile(re)
+	if err != nil {
+		panic(err)
+	}
+	check := func(msgs []*protocol.LogMessageParams) (Verdict, interface{}) {
+		var found int
+		for _, msg := range msgs {
+			if msg.Type == typ && rec.Match([]byte(msg.Message)) {
+				found++
+			}
+		}
+		if found == count {
+			return Met, nil
+		}
+		return Unmet, nil
+	}
+	return LogExpectation{
+		check:       check,
+		description: fmt.Sprintf("log message matching %q", re),
+	}
+}
+
+// NoLogMatching asserts that the client has not received a log message
+// of type typ matching the regexp re. If re is an empty string, any log
+// message is considered a match.
+func NoLogMatching(typ protocol.MessageType, re string) LogExpectation {
+	var r *regexp.Regexp
+	if re != "" {
+		var err error
+		r, err = regexp.Compile(re)
+		if err != nil {
+			panic(err)
+		}
+	}
+	check := func(msgs []*protocol.LogMessageParams) (Verdict, interface{}) {
+		for _, msg := range msgs {
+			if msg.Type != typ {
+				continue
+			}
+			if r == nil || r.Match([]byte(msg.Message)) {
+				return Unmeetable, nil
+			}
+		}
+		return Met, nil
+	}
+	return LogExpectation{
+		check:       check,
+		description: fmt.Sprintf("no log message matching %q", re),
+	}
+}
+
+// RegistrationExpectation is an expectation on the capability registrations
+// received by the editor from gopls.
+type RegistrationExpectation struct {
+	check       func([]*protocol.RegistrationParams) (Verdict, interface{})
+	description string
+}
+
+// Check implements the Expectation interface.
+func (e RegistrationExpectation) Check(s State) (Verdict, interface{}) {
+	return e.check(s.registrations)
+}
+
+// Description implements the Expectation interface.
+func (e RegistrationExpectation) Description() string {
+	return e.description
+}
+
+// RegistrationMatching asserts that the client has received a capability
+// registration matching the given regexp.
+func RegistrationMatching(re string) RegistrationExpectation {
+	rec, err := regexp.Compile(re)
+	if err != nil {
+		panic(err)
+	}
+	check := func(params []*protocol.RegistrationParams) (Verdict, interface{}) {
+		for _, p := range params {
+			for _, r := range p.Registrations {
+				if rec.Match([]byte(r.Method)) {
+					return Met, r
+				}
+			}
+		}
+		return Unmet, nil
+	}
+	return RegistrationExpectation{
+		check:       check,
+		description: fmt.Sprintf("registration matching %q", re),
+	}
+}
+
+// UnregistrationExpectation is an expectation on the capability
+// unregistrations received by the editor from gopls.
+type UnregistrationExpectation struct {
+	check       func([]*protocol.UnregistrationParams) (Verdict, interface{})
+	description string
+}
+
+// Check implements the Expectation interface.
+func (e UnregistrationExpectation) Check(s State) (Verdict, interface{}) {
+	return e.check(s.unregistrations)
+}
+
+// Description implements the Expectation interface.
+func (e UnregistrationExpectation) Description() string {
+	return e.description
+}
+
+// UnregistrationMatching asserts that the client has received an
+// unregistration whose ID matches the given regexp.
+func UnregistrationMatching(re string) UnregistrationExpectation {
+	rec, err := regexp.Compile(re)
+	if err != nil {
+		panic(err)
+	}
+	check := func(params []*protocol.UnregistrationParams) (Verdict, interface{}) {
+		for _, p := range params {
+			for _, r := range p.Unregisterations {
+				if rec.Match([]byte(r.Method)) {
+					return Met, r
+				}
+			}
+		}
+		return Unmet, nil
+	}
+	return UnregistrationExpectation{
+		check:       check,
+		description: fmt.Sprintf("unregistration matching %q", re),
+	}
+}
+
+// A DiagnosticExpectation is a condition that must be met by the current set
+// of diagnostics for a file.
+type DiagnosticExpectation struct {
+	// IsMet determines whether the diagnostics for this file version satisfy our
+	// expectation.
+	isMet func(*protocol.PublishDiagnosticsParams) bool
+	// Description is a human-readable description of the diagnostic expectation.
+	description string
+	// Path is the scratch workdir-relative path to the file being asserted on.
+	path string
+}
+
+// Check implements the Expectation interface.
+func (e DiagnosticExpectation) Check(s State) (Verdict, interface{}) {
+	if diags, ok := s.diagnostics[e.path]; ok && e.isMet(diags) {
+		return Met, diags
+	}
+	return Unmet, nil
+}
+
+// Description implements the Expectation interface.
+func (e DiagnosticExpectation) Description() string {
+	return fmt.Sprintf("%s: %s", e.path, e.description)
+}
+
+// EmptyDiagnostics asserts that empty diagnostics are sent for the
+// workspace-relative path name.
+func EmptyDiagnostics(name string) Expectation {
+	check := func(s State) (Verdict, interface{}) {
+		if diags := s.diagnostics[name]; diags != nil && len(diags.Diagnostics) == 0 {
+			return Met, nil
+		}
+		return Unmet, nil
+	}
+	return SimpleExpectation{
+		check:       check,
+		description: "empty diagnostics",
+	}
+}
+
+// NoDiagnostics asserts that no diagnostics are sent for the
+// workspace-relative path name. It should be used primarily in conjunction
+// with a OnceMet, as it has to check that all outstanding diagnostics have
+// already been delivered.
+func NoDiagnostics(name string) Expectation {
+	check := func(s State) (Verdict, interface{}) {
+		if _, ok := s.diagnostics[name]; !ok {
+			return Met, nil
+		}
+		return Unmet, nil
+	}
+	return SimpleExpectation{
+		check:       check,
+		description: "no diagnostics",
+	}
+}
+
+// AnyDiagnosticAtCurrentVersion asserts that there is a diagnostic report for
+// the current edited version of the buffer corresponding to the given
+// workdir-relative pathname.
+func (e *Env) AnyDiagnosticAtCurrentVersion(name string) DiagnosticExpectation {
+	version := e.Editor.BufferVersion(name)
+	isMet := func(diags *protocol.PublishDiagnosticsParams) bool {
+		return int(diags.Version) == version
+	}
+	return DiagnosticExpectation{
+		isMet:       isMet,
+		description: fmt.Sprintf("any diagnostics at version %d", version),
+		path:        name,
+	}
+}
+
+// DiagnosticAtRegexp expects that there is a diagnostic entry at the start
+// position matching the regexp search string re in the buffer specified by
+// name. Note that this currently ignores the end position.
+func (e *Env) DiagnosticAtRegexp(name, re string) DiagnosticExpectation {
+	e.T.Helper()
+	pos := e.RegexpSearch(name, re)
+	expectation := DiagnosticAt(name, pos.Line, pos.Column)
+	expectation.description += fmt.Sprintf(" (location of %q)", re)
+	return expectation
+}
+
+// DiagnosticAt asserts that there is a diagnostic entry at the position
+// specified by line and col, for the workdir-relative path name.
+func DiagnosticAt(name string, line, col int) DiagnosticExpectation {
+	isMet := func(diags *protocol.PublishDiagnosticsParams) bool {
+		for _, d := range diags.Diagnostics {
+			if d.Range.Start.Line == float64(line) && d.Range.Start.Character == float64(col) {
+				return true
+			}
+		}
+		return false
+	}
+	return DiagnosticExpectation{
+		isMet:       isMet,
+		description: fmt.Sprintf("diagnostic at {line:%d, column:%d}", line, col),
+		path:        name,
+	}
+}
+
+// NoDiagnosticAtRegexp expects that there is no diagnostic entry at the start
+// position matching the regexp search string re in the buffer specified by
+// name. Note that this currently ignores the end position.
+// This should only be used in combination with OnceMet for a given condition,
+// otherwise it may always succeed.
+func (e *Env) NoDiagnosticAtRegexp(name, re string) DiagnosticExpectation {
+	e.T.Helper()
+	pos := e.RegexpSearch(name, re)
+	expectation := NoDiagnosticAt(name, pos.Line, pos.Column)
+	expectation.description += fmt.Sprintf(" (location of %q)", re)
+	return expectation
+}
+
+// NoDiagnosticAt asserts that there is no diagnostic entry at the position
+// specified by line and col, for the workdir-relative path name.
+// This should only be used in combination with OnceMet for a given condition,
+// otherwise it may always succeed.
+func NoDiagnosticAt(name string, line, col int) DiagnosticExpectation {
+	isMet := func(diags *protocol.PublishDiagnosticsParams) bool {
+		for _, d := range diags.Diagnostics {
+			if d.Range.Start.Line == float64(line) && d.Range.Start.Character == float64(col) {
+				return false
+			}
+		}
+		return true
+	}
+	return DiagnosticExpectation{
+		isMet:       isMet,
+		description: fmt.Sprintf("no diagnostic at {line:%d, column:%d}", line, col),
+		path:        name,
+	}
+}
