func (e *Env) AnyDiagnosticAtCurrentVersion(name string) Expectation {
	version := e.Editor.BufferVersion(name)
	check := func(s State) Verdict {
		diags, ok := s.diagnostics[name]
		if ok && diags.Version == int32(version) {
			return Met
		}
		return Unmet
	}
	return SimpleExpectation{
		check:       check,
		description: fmt.Sprintf("any diagnostics at version %d", version),
	}
}
AnyDiagnosticAtCurrentVersion asserts that there is a diagnostic report for
the current edited version of the buffer corresponding to the given
workdir-relative pathname.
package regtest
import (
	"fmt"
	"regexp"
	"strings"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp/fake"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp/protocol"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/testenv"
)
type Expectation interface {
	Check(State) Verdict
	Description() string
}
var (
	InitialWorkspaceLoad = CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromInitialWorkspaceLoad), 1, false)
)
type Verdict int
const (
	Met Verdict = iota
	Unmet
	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)
}
type SimpleExpectation struct {
	check       func(State) Verdict
	description string
}
func (e SimpleExpectation) Check(s State) Verdict {
	return e.check(s)
}
func (e SimpleExpectation) Description() string {
	return e.description
}
func OnceMet(precondition Expectation, mustMeets ...Expectation) *SimpleExpectation {
	check := func(s State) Verdict {
		switch pre := precondition.Check(s); pre {
		case Unmeetable:
			return Unmeetable
		case Met:
			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(), strings.Join(descriptions, "\n")),
	}
}
func ReadDiagnostics(fileName string, into *protocol.PublishDiagnosticsParams) *SimpleExpectation {
	check := func(s State) Verdict {
		diags, ok := s.diagnostics[fileName]
		if !ok {
			return Unmeetable
		}
		*into = *diags
		return Met
	}
	return &SimpleExpectation{
		check:       check,
		description: fmt.Sprintf("read diagnostics for %q", fileName),
	}
}
func NoOutstandingWork() SimpleExpectation {
	check := func(s State) Verdict {
		if len(s.outstandingWork) == 0 {
			return Met
		}
		return Unmet
	}
	return SimpleExpectation{
		check:       check,
		description: "no outstanding work",
	}
}
func NoShowMessage() SimpleExpectation {
	check := func(s State) Verdict {
		if len(s.showMessage) == 0 {
			return Met
		}
		return Unmeetable
	}
	return SimpleExpectation{
		check:       check,
		description: "no ShowMessage received",
	}
}
func ShownMessage(title string) SimpleExpectation {
	check := func(s State) Verdict {
		for _, m := range s.showMessage {
			if strings.Contains(m.Message, title) {
				return Met
			}
		}
		return Unmet
	}
	return SimpleExpectation{
		check:       check,
		description: "received ShowMessage",
	}
}
func ShowMessageRequest(title string) SimpleExpectation {
	check := func(s State) Verdict {
		if len(s.showMessageRequest) == 0 {
			return Unmet
		}
		m := s.showMessageRequest[len(s.showMessageRequest)-1]
		if len(m.Actions) == 0 || len(m.Actions) > 1 {
			return Unmet
		}
		if m.Actions[0].Title == title {
			return Met
		}
		return Unmet
	}
	return SimpleExpectation{
		check:       check,
		description: "received ShowMessageRequest",
	}
}
func (e *Env) DoneWithOpen() Expectation {
	opens := e.Editor.Stats().DidOpen
	return CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidOpen), opens, true)
}
func StartedChange(i uint64) Expectation {
	return StartedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), i)
}
func (e *Env) DoneWithChange() Expectation {
	changes := e.Editor.Stats().DidChange
	return CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChange), changes, true)
}
func (e *Env) DoneWithSave() Expectation {
	saves := e.Editor.Stats().DidSave
	return CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidSave), saves, true)
}
func (e *Env) DoneWithChangeWatchedFiles() Expectation {
	changes := e.Editor.Stats().DidChangeWatchedFiles
	return CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), changes, true)
}
func (e *Env) DoneWithClose() Expectation {
	changes := e.Editor.Stats().DidClose
	return CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidClose), changes, true)
}
func StartedWork(title string, atLeast uint64) SimpleExpectation {
	check := func(s State) Verdict {
		if s.startedWork[title] >= atLeast {
			return Met
		}
		return Unmet
	}
	return SimpleExpectation{
		check:       check,
		description: fmt.Sprintf("started work %q at least %d time(s)", title, atLeast),
	}
}
func CompletedWork(title string, count uint64, atLeast bool) SimpleExpectation {
	check := func(s State) Verdict {
		if s.completedWork[title] == count || atLeast && s.completedWork[title] > count {
			return Met
		}
		return Unmet
	}
	desc := fmt.Sprintf("completed work %q %v times", title, count)
	if atLeast {
		desc = fmt.Sprintf("completed work %q at least %d time(s)", title, count)
	}
	return SimpleExpectation{
		check:       check,
		description: desc,
	}
}
func OutstandingWork(title, msg string) SimpleExpectation {
	check := func(s State) Verdict {
		for _, work := range s.outstandingWork {
			if work.title == title && strings.Contains(work.msg, msg) {
				return Met
			}
		}
		return Unmet
	}
	return SimpleExpectation{
		check:       check,
		description: fmt.Sprintf("outstanding work: %s", title),
	}
}
type LogExpectation struct {
	check       func([]*protocol.LogMessageParams) Verdict
	description string
}
func (e LogExpectation) Check(s State) Verdict {
	return e.check(s.logs)
}
func (e LogExpectation) Description() string {
	return e.description
}
func NoErrorLogs() LogExpectation {
	return NoLogMatching(protocol.Error, "")
}
func LogMatching(typ protocol.MessageType, re string, count int, atLeast bool) LogExpectation {
	rec, err := regexp.Compile(re)
	if err != nil {
		panic(err)
	}
	check := func(msgs []*protocol.LogMessageParams) Verdict {
		var found int
		for _, msg := range msgs {
			if msg.Type == typ && rec.Match([]byte(msg.Message)) {
				found++
			}
		}
		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: desc,
	}
}
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 {
		for _, msg := range msgs {
			if msg.Type != typ {
				continue
			}
			if r == nil || r.Match([]byte(msg.Message)) {
				return Unmeetable
			}
		}
		return Met
	}
	return LogExpectation{
		check:       check,
		description: fmt.Sprintf("no log message matching %q", re),
	}
}
type RegistrationExpectation struct {
	check       func([]*protocol.RegistrationParams) Verdict
	description string
}
func (e RegistrationExpectation) Check(s State) Verdict {
	return e.check(s.registrations)
}
func (e RegistrationExpectation) Description() string {
	return e.description
}
func RegistrationMatching(re string) RegistrationExpectation {
	rec, err := regexp.Compile(re)
	if err != nil {
		panic(err)
	}
	check := func(params []*protocol.RegistrationParams) Verdict {
		for _, p := range params {
			for _, r := range p.Registrations {
				if rec.Match([]byte(r.Method)) {
					return Met
				}
			}
		}
		return Unmet
	}
	return RegistrationExpectation{
		check:       check,
		description: fmt.Sprintf("registration matching %q", re),
	}
}
type UnregistrationExpectation struct {
	check       func([]*protocol.UnregistrationParams) Verdict
	description string
}
func (e UnregistrationExpectation) Check(s State) Verdict {
	return e.check(s.unregistrations)
}
func (e UnregistrationExpectation) Description() string {
	return e.description
}
func UnregistrationMatching(re string) UnregistrationExpectation {
	rec, err := regexp.Compile(re)
	if err != nil {
		panic(err)
	}
	check := func(params []*protocol.UnregistrationParams) Verdict {
		for _, p := range params {
			for _, r := range p.Unregisterations {
				if rec.Match([]byte(r.Method)) {
					return Met
				}
			}
		}
		return Unmet
	}
	return UnregistrationExpectation{
		check:       check,
		description: fmt.Sprintf("unregistration matching %q", re),
	}
}
type DiagnosticExpectation struct {
	pos *fake.Pos
	re  string
	message string
	present bool
	path string
}
func (e DiagnosticExpectation) Check(s State) Verdict {
	diags, ok := s.diagnostics[e.path]
	if !ok {
		if !e.present {
			return Met
		}
		return Unmet
	}
	found := false
	for _, d := range diags.Diagnostics {
		if e.pos != nil {
			if d.Range.Start.Line != uint32(e.pos.Line) || d.Range.Start.Character != uint32(e.pos.Column) {
				continue
			}
		}
		if e.message != "" {
			if !strings.Contains(d.Message, e.message) {
				continue
			}
		}
		found = true
		break
	}
	if found == e.present {
		return Met
	}
	return Unmet
}
func (e DiagnosticExpectation) Description() string {
	desc := e.path + ":"
	if !e.present {
		desc += " no"
	}
	desc += " diagnostic"
	if e.pos != nil {
		desc += fmt.Sprintf(" at {line:%d, column:%d}", e.pos.Line, e.pos.Column)
		if e.re != "" {
			desc += fmt.Sprintf(" (location of %q)", e.re)
		}
	}
	if e.message != "" {
		desc += fmt.Sprintf(" with message %q", e.message)
	}
	return desc
}
func EmptyDiagnostics(name string) Expectation {
	check := func(s State) Verdict {
		if diags := s.diagnostics[name]; diags != nil && len(diags.Diagnostics) == 0 {
			return Met
		}
		return Unmet
	}
	return SimpleExpectation{
		check:       check,
		description: fmt.Sprintf("empty diagnostics for %q", name),
	}
}
func EmptyOrNoDiagnostics(name string) Expectation {
	check := func(s State) Verdict {
		if diags := s.diagnostics[name]; diags == nil || len(diags.Diagnostics) == 0 {
			return Met
		}
		return Unmet
	}
	return SimpleExpectation{
		check:       check,
		description: fmt.Sprintf("empty or no diagnostics for %q", name),
	}
}
func NoDiagnostics(name string) Expectation {
	check := func(s State) Verdict {
		if _, ok := s.diagnostics[name]; !ok {
			return Met
		}
		return Unmet
	}
	return SimpleExpectation{
		check:       check,
		description: "no diagnostics",
	}
}