From dd34adb36c072b7bfd34991fdb117d7959efa113 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sat, 3 Jun 2023 15:12:31 +1000 Subject: [PATCH] Support matchers on integers in integration tests --- pkg/integration/components/alert_driver.go | 4 +- .../components/assertion_helper.go | 2 +- .../components/commit_message_panel_driver.go | 6 +- pkg/integration/components/common.go | 2 +- .../components/confirmation_driver.go | 4 +- pkg/integration/components/file_system.go | 2 +- pkg/integration/components/int_matcher.go | 58 +++++++++ pkg/integration/components/matcher.go | 118 ++---------------- pkg/integration/components/menu_driver.go | 8 +- pkg/integration/components/prompt_driver.go | 10 +- pkg/integration/components/search_driver.go | 2 +- pkg/integration/components/test_driver.go | 4 +- pkg/integration/components/text_matcher.go | 116 +++++++++++++++++ pkg/integration/components/view_driver.go | 26 ++-- .../tests/config/remote_named_star.go | 4 +- 15 files changed, 220 insertions(+), 146 deletions(-) create mode 100644 pkg/integration/components/int_matcher.go create mode 100644 pkg/integration/components/text_matcher.go diff --git a/pkg/integration/components/alert_driver.go b/pkg/integration/components/alert_driver.go index 7e1623041..f0cfaa4eb 100644 --- a/pkg/integration/components/alert_driver.go +++ b/pkg/integration/components/alert_driver.go @@ -11,7 +11,7 @@ func (self *AlertDriver) getViewDriver() *ViewDriver { } // asserts that the alert view has the expected title -func (self *AlertDriver) Title(expected *Matcher) *AlertDriver { +func (self *AlertDriver) Title(expected *TextMatcher) *AlertDriver { self.getViewDriver().Title(expected) self.hasCheckedTitle = true @@ -20,7 +20,7 @@ func (self *AlertDriver) Title(expected *Matcher) *AlertDriver { } // asserts that the alert view has the expected content -func (self *AlertDriver) Content(expected *Matcher) *AlertDriver { +func (self *AlertDriver) Content(expected *TextMatcher) *AlertDriver { self.getViewDriver().Content(expected) self.hasCheckedContent = true diff --git a/pkg/integration/components/assertion_helper.go b/pkg/integration/components/assertion_helper.go index 4ae785db2..48cc14741 100644 --- a/pkg/integration/components/assertion_helper.go +++ b/pkg/integration/components/assertion_helper.go @@ -22,7 +22,7 @@ func retryWaitTimes() []int { } } -func (self *assertionHelper) matchString(matcher *Matcher, context string, getValue func() string) { +func (self *assertionHelper) matchString(matcher *TextMatcher, context string, getValue func() string) { self.assertWithRetries(func() (bool, string) { value := getValue() return matcher.context(context).test(value) diff --git a/pkg/integration/components/commit_message_panel_driver.go b/pkg/integration/components/commit_message_panel_driver.go index d077761fc..f9089ee2e 100644 --- a/pkg/integration/components/commit_message_panel_driver.go +++ b/pkg/integration/components/commit_message_panel_driver.go @@ -9,19 +9,19 @@ func (self *CommitMessagePanelDriver) getViewDriver() *ViewDriver { } // asserts on the text initially present in the prompt -func (self *CommitMessagePanelDriver) InitialText(expected *Matcher) *CommitMessagePanelDriver { +func (self *CommitMessagePanelDriver) InitialText(expected *TextMatcher) *CommitMessagePanelDriver { return self.Content(expected) } // asserts on the current context in the prompt -func (self *CommitMessagePanelDriver) Content(expected *Matcher) *CommitMessagePanelDriver { +func (self *CommitMessagePanelDriver) Content(expected *TextMatcher) *CommitMessagePanelDriver { self.getViewDriver().Content(expected) return self } // asserts that the confirmation view has the expected title -func (self *CommitMessagePanelDriver) Title(expected *Matcher) *CommitMessagePanelDriver { +func (self *CommitMessagePanelDriver) Title(expected *TextMatcher) *CommitMessagePanelDriver { self.getViewDriver().Title(expected) return self diff --git a/pkg/integration/components/common.go b/pkg/integration/components/common.go index fe81438ee..904c73711 100644 --- a/pkg/integration/components/common.go +++ b/pkg/integration/components/common.go @@ -39,7 +39,7 @@ func (self *Common) ConfirmDiscardLines() { Confirm() } -func (self *Common) SelectPatchOption(matcher *Matcher) { +func (self *Common) SelectPatchOption(matcher *TextMatcher) { self.t.GlobalPress(self.t.keys.Universal.CreatePatchOptionsMenu) self.t.ExpectPopup().Menu().Title(Equals("Patch options")).Select(matcher).Confirm() diff --git a/pkg/integration/components/confirmation_driver.go b/pkg/integration/components/confirmation_driver.go index 687523833..aad5cc248 100644 --- a/pkg/integration/components/confirmation_driver.go +++ b/pkg/integration/components/confirmation_driver.go @@ -11,7 +11,7 @@ func (self *ConfirmationDriver) getViewDriver() *ViewDriver { } // asserts that the confirmation view has the expected title -func (self *ConfirmationDriver) Title(expected *Matcher) *ConfirmationDriver { +func (self *ConfirmationDriver) Title(expected *TextMatcher) *ConfirmationDriver { self.getViewDriver().Title(expected) self.hasCheckedTitle = true @@ -20,7 +20,7 @@ func (self *ConfirmationDriver) Title(expected *Matcher) *ConfirmationDriver { } // asserts that the confirmation view has the expected content -func (self *ConfirmationDriver) Content(expected *Matcher) *ConfirmationDriver { +func (self *ConfirmationDriver) Content(expected *TextMatcher) *ConfirmationDriver { self.getViewDriver().Content(expected) self.hasCheckedContent = true diff --git a/pkg/integration/components/file_system.go b/pkg/integration/components/file_system.go index cdc7413fb..74f179fdc 100644 --- a/pkg/integration/components/file_system.go +++ b/pkg/integration/components/file_system.go @@ -26,7 +26,7 @@ func (self *FileSystem) PathNotPresent(path string) { } // Asserts that the file at the given path has the given content -func (self *FileSystem) FileContent(path string, matcher *Matcher) { +func (self *FileSystem) FileContent(path string, matcher *TextMatcher) { self.assertWithRetries(func() (bool, string) { _, err := os.Stat(path) if os.IsNotExist(err) { diff --git a/pkg/integration/components/int_matcher.go b/pkg/integration/components/int_matcher.go new file mode 100644 index 000000000..c80a60c85 --- /dev/null +++ b/pkg/integration/components/int_matcher.go @@ -0,0 +1,58 @@ +package components + +import ( + "fmt" +) + +type IntMatcher struct { + *Matcher[int] +} + +func (self *IntMatcher) EqualsInt(target int) *IntMatcher { + self.appendRule(matcherRule[int]{ + name: fmt.Sprintf("equals '%d'", target), + testFn: func(value int) (bool, string) { + return value == target, fmt.Sprintf("Expected '%d' to equal '%d'", value, target) + }, + }) + + return self +} + +func (self *IntMatcher) GreaterThan(target int) *IntMatcher { + self.appendRule(matcherRule[int]{ + name: fmt.Sprintf("greater than '%d'", target), + testFn: func(value int) (bool, string) { + return value > target, fmt.Sprintf("Expected '%d' to greater than '%d'", value, target) + }, + }) + + return self +} + +func (self *IntMatcher) LessThan(target int) *IntMatcher { + self.appendRule(matcherRule[int]{ + name: fmt.Sprintf("less than '%d'", target), + testFn: func(value int) (bool, string) { + return value < target, fmt.Sprintf("Expected '%d' to less than '%d'", value, target) + }, + }) + + return self +} + +func AnyInt() *IntMatcher { + return &IntMatcher{Matcher: &Matcher[int]{}} +} + +func EqualsInt(target int) *IntMatcher { + return AnyInt().EqualsInt(target) +} + +func GreaterThan(target int) *IntMatcher { + return AnyInt().GreaterThan(target) +} + +func LessThan(target int) *IntMatcher { + return AnyInt().LessThan(target) +} diff --git a/pkg/integration/components/matcher.go b/pkg/integration/components/matcher.go index a87234654..d01aa92ef 100644 --- a/pkg/integration/components/matcher.go +++ b/pkg/integration/components/matcher.go @@ -1,46 +1,39 @@ package components import ( - "fmt" - "regexp" "strings" "github.com/samber/lo" ) // for making assertions on string values -type Matcher struct { - rules []matcherRule +type Matcher[T any] struct { + rules []matcherRule[T] // this is printed when there's an error so that it's clear what the context of the assertion is prefix string } -type matcherRule struct { +type matcherRule[T any] struct { // e.g. "contains 'foo'" name string // returns a bool that says whether the test passed and if it returns false, it // also returns a string of the error message - testFn func(string) (bool, string) + testFn func(T) (bool, string) } -func NewMatcher(name string, testFn func(string) (bool, string)) *Matcher { - rules := []matcherRule{{name: name, testFn: testFn}} - return &Matcher{rules: rules} -} - -func (self *Matcher) name() string { +func (self *Matcher[T]) name() string { if len(self.rules) == 0 { return "anything" } return strings.Join( - lo.Map(self.rules, func(rule matcherRule, _ int) string { return rule.name }), + lo.Map(self.rules, func(rule matcherRule[T], _ int) string { return rule.name }), ", ", ) } -func (self *Matcher) test(value string) (bool, string) { +func (self *Matcher[T]) test(value T) (bool, string) { for _, rule := range self.rules { ok, message := rule.testFn(value) if ok { @@ -57,65 +50,7 @@ func (self *Matcher) test(value string) (bool, string) { return true, "" } -func (self *Matcher) Contains(target string) *Matcher { - return self.appendRule(matcherRule{ - name: fmt.Sprintf("contains '%s'", target), - testFn: func(value string) (bool, string) { - // everything contains the empty string so we unconditionally return true here - if target == "" { - return true, "" - } - - return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to be found in '%s'", target, value) - }, - }) -} - -func (self *Matcher) DoesNotContain(target string) *Matcher { - return self.appendRule(matcherRule{ - name: fmt.Sprintf("does not contain '%s'", target), - testFn: func(value string) (bool, string) { - return !strings.Contains(value, target), fmt.Sprintf("Expected '%s' to NOT be found in '%s'", target, value) - }, - }) -} - -func (self *Matcher) MatchesRegexp(target string) *Matcher { - return self.appendRule(matcherRule{ - name: fmt.Sprintf("matches regular expression '%s'", target), - testFn: func(value string) (bool, string) { - matched, err := regexp.MatchString(target, value) - if err != nil { - return false, fmt.Sprintf("Unexpected error parsing regular expression '%s': %s", target, err.Error()) - } - return matched, fmt.Sprintf("Expected '%s' to match regular expression /%s/", value, target) - }, - }) -} - -func (self *Matcher) Equals(target string) *Matcher { - return self.appendRule(matcherRule{ - name: fmt.Sprintf("equals '%s'", target), - testFn: func(value string) (bool, string) { - return target == value, fmt.Sprintf("Expected '%s' to equal '%s'", value, target) - }, - }) -} - -const IS_SELECTED_RULE_NAME = "is selected" - -// special rule that is only to be used in the TopLines and Lines methods, as a way of -// asserting that a given line is selected. -func (self *Matcher) IsSelected() *Matcher { - return self.appendRule(matcherRule{ - name: IS_SELECTED_RULE_NAME, - testFn: func(value string) (bool, string) { - panic("Special IsSelected matcher is not supposed to have its testFn method called. This rule should only be used within the .Lines() and .TopLines() method on a ViewAsserter.") - }, - }) -} - -func (self *Matcher) appendRule(rule matcherRule) *Matcher { +func (self *Matcher[T]) appendRule(rule matcherRule[T]) *Matcher[T] { self.rules = append(self.rules, rule) return self @@ -123,43 +58,8 @@ func (self *Matcher) appendRule(rule matcherRule) *Matcher { // adds context so that if the matcher test(s) fails, we understand what we were trying to test. // E.g. prefix: "Unexpected content in view 'files'." -func (self *Matcher) context(prefix string) *Matcher { +func (self *Matcher[T]) context(prefix string) *Matcher[T] { self.prefix = prefix return self } - -// if the matcher has an `IsSelected` rule, it returns true, along with the matcher after that rule has been removed -func (self *Matcher) checkIsSelected() (bool, *Matcher) { - // copying into a new matcher in case we want to re-use the original later - newMatcher := &Matcher{} - *newMatcher = *self - - check := lo.ContainsBy(newMatcher.rules, func(rule matcherRule) bool { return rule.name == IS_SELECTED_RULE_NAME }) - - newMatcher.rules = lo.Filter(newMatcher.rules, func(rule matcherRule, _ int) bool { return rule.name != IS_SELECTED_RULE_NAME }) - - return check, newMatcher -} - -// this matcher has no rules meaning it always passes the test. Use this -// when you don't care what value you're dealing with. -func Anything() *Matcher { - return &Matcher{} -} - -func Contains(target string) *Matcher { - return Anything().Contains(target) -} - -func DoesNotContain(target string) *Matcher { - return Anything().DoesNotContain(target) -} - -func MatchesRegexp(target string) *Matcher { - return Anything().MatchesRegexp(target) -} - -func Equals(target string) *Matcher { - return Anything().Equals(target) -} diff --git a/pkg/integration/components/menu_driver.go b/pkg/integration/components/menu_driver.go index 4092879da..ac620f5a4 100644 --- a/pkg/integration/components/menu_driver.go +++ b/pkg/integration/components/menu_driver.go @@ -10,7 +10,7 @@ func (self *MenuDriver) getViewDriver() *ViewDriver { } // asserts that the popup has the expected title -func (self *MenuDriver) Title(expected *Matcher) *MenuDriver { +func (self *MenuDriver) Title(expected *TextMatcher) *MenuDriver { self.getViewDriver().Title(expected) self.hasCheckedTitle = true @@ -30,19 +30,19 @@ func (self *MenuDriver) Cancel() { self.getViewDriver().PressEscape() } -func (self *MenuDriver) Select(option *Matcher) *MenuDriver { +func (self *MenuDriver) Select(option *TextMatcher) *MenuDriver { self.getViewDriver().NavigateToLine(option) return self } -func (self *MenuDriver) Lines(matchers ...*Matcher) *MenuDriver { +func (self *MenuDriver) Lines(matchers ...*TextMatcher) *MenuDriver { self.getViewDriver().Lines(matchers...) return self } -func (self *MenuDriver) TopLines(matchers ...*Matcher) *MenuDriver { +func (self *MenuDriver) TopLines(matchers ...*TextMatcher) *MenuDriver { self.getViewDriver().TopLines(matchers...) return self diff --git a/pkg/integration/components/prompt_driver.go b/pkg/integration/components/prompt_driver.go index d21d6f95e..023c2f438 100644 --- a/pkg/integration/components/prompt_driver.go +++ b/pkg/integration/components/prompt_driver.go @@ -10,7 +10,7 @@ func (self *PromptDriver) getViewDriver() *ViewDriver { } // asserts that the popup has the expected title -func (self *PromptDriver) Title(expected *Matcher) *PromptDriver { +func (self *PromptDriver) Title(expected *TextMatcher) *PromptDriver { self.getViewDriver().Title(expected) self.hasCheckedTitle = true @@ -19,7 +19,7 @@ func (self *PromptDriver) Title(expected *Matcher) *PromptDriver { } // asserts on the text initially present in the prompt -func (self *PromptDriver) InitialText(expected *Matcher) *PromptDriver { +func (self *PromptDriver) InitialText(expected *TextMatcher) *PromptDriver { self.getViewDriver().Content(expected) return self @@ -55,13 +55,13 @@ func (self *PromptDriver) checkNecessaryChecksCompleted() { } } -func (self *PromptDriver) SuggestionLines(matchers ...*Matcher) *PromptDriver { +func (self *PromptDriver) SuggestionLines(matchers ...*TextMatcher) *PromptDriver { self.t.Views().Suggestions().Lines(matchers...) return self } -func (self *PromptDriver) SuggestionTopLines(matchers ...*Matcher) *PromptDriver { +func (self *PromptDriver) SuggestionTopLines(matchers ...*TextMatcher) *PromptDriver { self.t.Views().Suggestions().TopLines(matchers...) return self @@ -75,7 +75,7 @@ func (self *PromptDriver) ConfirmFirstSuggestion() { PressEnter() } -func (self *PromptDriver) ConfirmSuggestion(matcher *Matcher) { +func (self *PromptDriver) ConfirmSuggestion(matcher *TextMatcher) { self.t.press(self.t.keys.Universal.TogglePanel) self.t.Views().Suggestions(). IsFocused(). diff --git a/pkg/integration/components/search_driver.go b/pkg/integration/components/search_driver.go index 66a2fae41..498047cce 100644 --- a/pkg/integration/components/search_driver.go +++ b/pkg/integration/components/search_driver.go @@ -12,7 +12,7 @@ func (self *SearchDriver) getViewDriver() *ViewDriver { } // asserts on the text initially present in the prompt -func (self *SearchDriver) InitialText(expected *Matcher) *SearchDriver { +func (self *SearchDriver) InitialText(expected *TextMatcher) *SearchDriver { self.getViewDriver().Content(expected) return self diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index c67439b54..8ca3f1f70 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -80,11 +80,11 @@ func (self *TestDriver) ExpectPopup() *Popup { return &Popup{t: self} } -func (self *TestDriver) ExpectToast(matcher *Matcher) { +func (self *TestDriver) ExpectToast(matcher *TextMatcher) { self.Views().AppStatus().Content(matcher) } -func (self *TestDriver) ExpectClipboard(matcher *Matcher) { +func (self *TestDriver) ExpectClipboard(matcher *TextMatcher) { self.assertWithRetries(func() (bool, string) { text, err := clipboard.ReadAll() if err != nil { diff --git a/pkg/integration/components/text_matcher.go b/pkg/integration/components/text_matcher.go new file mode 100644 index 000000000..2d2c0e577 --- /dev/null +++ b/pkg/integration/components/text_matcher.go @@ -0,0 +1,116 @@ +package components + +import ( + "fmt" + "regexp" + "strings" + + "github.com/samber/lo" +) + +type TextMatcher struct { + *Matcher[string] +} + +func (self *TextMatcher) Contains(target string) *TextMatcher { + self.appendRule(matcherRule[string]{ + name: fmt.Sprintf("contains '%s'", target), + testFn: func(value string) (bool, string) { + // everything contains the empty string so we unconditionally return true here + if target == "" { + return true, "" + } + + return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to be found in '%s'", target, value) + }, + }) + + return self +} + +func (self *TextMatcher) DoesNotContain(target string) *TextMatcher { + self.appendRule(matcherRule[string]{ + name: fmt.Sprintf("does not contain '%s'", target), + testFn: func(value string) (bool, string) { + return !strings.Contains(value, target), fmt.Sprintf("Expected '%s' to NOT be found in '%s'", target, value) + }, + }) + + return self +} + +func (self *TextMatcher) MatchesRegexp(target string) *TextMatcher { + self.appendRule(matcherRule[string]{ + name: fmt.Sprintf("matches regular expression '%s'", target), + testFn: func(value string) (bool, string) { + matched, err := regexp.MatchString(target, value) + if err != nil { + return false, fmt.Sprintf("Unexpected error parsing regular expression '%s': %s", target, err.Error()) + } + return matched, fmt.Sprintf("Expected '%s' to match regular expression /%s/", value, target) + }, + }) + + return self +} + +func (self *TextMatcher) Equals(target string) *TextMatcher { + self.appendRule(matcherRule[string]{ + name: fmt.Sprintf("equals '%s'", target), + testFn: func(value string) (bool, string) { + return target == value, fmt.Sprintf("Expected '%s' to equal '%s'", value, target) + }, + }) + + return self +} + +const IS_SELECTED_RULE_NAME = "is selected" + +// special rule that is only to be used in the TopLines and Lines methods, as a way of +// asserting that a given line is selected. +func (self *TextMatcher) IsSelected() *TextMatcher { + self.appendRule(matcherRule[string]{ + name: IS_SELECTED_RULE_NAME, + testFn: func(value string) (bool, string) { + panic("Special IsSelected matcher is not supposed to have its testFn method called. This rule should only be used within the .Lines() and .TopLines() method on a ViewAsserter.") + }, + }) + + return self +} + +// if the matcher has an `IsSelected` rule, it returns true, along with the matcher after that rule has been removed +func (self *TextMatcher) checkIsSelected() (bool, *TextMatcher) { + // copying into a new matcher in case we want to re-use the original later + newMatcher := &TextMatcher{} + *newMatcher = *self + + check := lo.ContainsBy(newMatcher.rules, func(rule matcherRule[string]) bool { return rule.name == IS_SELECTED_RULE_NAME }) + + newMatcher.rules = lo.Filter(newMatcher.rules, func(rule matcherRule[string], _ int) bool { return rule.name != IS_SELECTED_RULE_NAME }) + + return check, newMatcher +} + +// this matcher has no rules meaning it always passes the test. Use this +// when you don't care what value you're dealing with. +func AnyString() *TextMatcher { + return &TextMatcher{Matcher: &Matcher[string]{}} +} + +func Contains(target string) *TextMatcher { + return AnyString().Contains(target) +} + +func DoesNotContain(target string) *TextMatcher { + return AnyString().DoesNotContain(target) +} + +func MatchesRegexp(target string) *TextMatcher { + return AnyString().MatchesRegexp(target) +} + +func Equals(target string) *TextMatcher { + return AnyString().Equals(target) +} diff --git a/pkg/integration/components/view_driver.go b/pkg/integration/components/view_driver.go index 1a5017b37..db7e76134 100644 --- a/pkg/integration/components/view_driver.go +++ b/pkg/integration/components/view_driver.go @@ -52,7 +52,7 @@ func (self *ViewDriver) getSelectedLineIdx() (int, error) { } // asserts that the view has the expected title -func (self *ViewDriver) Title(expected *Matcher) *ViewDriver { +func (self *ViewDriver) Title(expected *TextMatcher) *ViewDriver { self.t.assertWithRetries(func() (bool, string) { actual := self.getView().Title return expected.context(fmt.Sprintf("%s title", self.context)).test(actual) @@ -64,7 +64,7 @@ func (self *ViewDriver) Title(expected *Matcher) *ViewDriver { // asserts that the view has lines matching the given matchers. One matcher must be passed for each line. // If you only care about the top n lines, use the TopLines method instead. // If you only care about a subset of lines, use the ContainsLines method instead. -func (self *ViewDriver) Lines(matchers ...*Matcher) *ViewDriver { +func (self *ViewDriver) Lines(matchers ...*TextMatcher) *ViewDriver { self.validateMatchersPassed(matchers) self.LineCount(len(matchers)) @@ -75,7 +75,7 @@ func (self *ViewDriver) Lines(matchers ...*Matcher) *ViewDriver { // are passed, we only check the first three lines of the view. // This method is convenient when you have a list of commits but you only want to // assert on the first couple of commits. -func (self *ViewDriver) TopLines(matchers ...*Matcher) *ViewDriver { +func (self *ViewDriver) TopLines(matchers ...*TextMatcher) *ViewDriver { self.validateMatchersPassed(matchers) self.validateEnoughLines(matchers) @@ -83,7 +83,7 @@ func (self *ViewDriver) TopLines(matchers ...*Matcher) *ViewDriver { } // asserts that somewhere in the view there are consequetive lines matching the given matchers. -func (self *ViewDriver) ContainsLines(matchers ...*Matcher) *ViewDriver { +func (self *ViewDriver) ContainsLines(matchers ...*TextMatcher) *ViewDriver { self.validateMatchersPassed(matchers) self.validateEnoughLines(matchers) @@ -162,7 +162,7 @@ func (self *ViewDriver) DoesNotContainColoredText(fgColorStr string, text string } // asserts on the lines that are selected in the view. Don't use the `IsSelected` matcher with this because it's redundant. -func (self *ViewDriver) SelectedLines(matchers ...*Matcher) *ViewDriver { +func (self *ViewDriver) SelectedLines(matchers ...*TextMatcher) *ViewDriver { self.validateMatchersPassed(matchers) self.validateEnoughLines(matchers) @@ -197,13 +197,13 @@ func (self *ViewDriver) SelectedLines(matchers ...*Matcher) *ViewDriver { return self } -func (self *ViewDriver) validateMatchersPassed(matchers []*Matcher) { +func (self *ViewDriver) validateMatchersPassed(matchers []*TextMatcher) { if len(matchers) < 1 { self.t.fail("'Lines' methods require at least one matcher to be passed as an argument. If you are trying to assert that there are no lines, use .IsEmpty()") } } -func (self *ViewDriver) validateEnoughLines(matchers []*Matcher) { +func (self *ViewDriver) validateEnoughLines(matchers []*TextMatcher) { view := self.getView() self.t.assertWithRetries(func() (bool, string) { @@ -212,7 +212,7 @@ func (self *ViewDriver) validateEnoughLines(matchers []*Matcher) { }) } -func (self *ViewDriver) assertLines(offset int, matchers ...*Matcher) *ViewDriver { +func (self *ViewDriver) assertLines(offset int, matchers ...*TextMatcher) *ViewDriver { view := self.getView() for matcherIndex, matcher := range matchers { @@ -252,7 +252,7 @@ func (self *ViewDriver) assertLines(offset int, matchers ...*Matcher) *ViewDrive } // asserts on the content of the view i.e. the stuff within the view's frame. -func (self *ViewDriver) Content(matcher *Matcher) *ViewDriver { +func (self *ViewDriver) Content(matcher *TextMatcher) *ViewDriver { self.t.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context), func() string { return self.getView().Buffer() @@ -265,7 +265,7 @@ func (self *ViewDriver) Content(matcher *Matcher) *ViewDriver { // asserts on the selected line of the view. If your view has multiple lines selected, // but also has a concept of a cursor position, this will assert on the line that // the cursor is on. Otherwise it will assert on the first line of the selection. -func (self *ViewDriver) SelectedLine(matcher *Matcher) *ViewDriver { +func (self *ViewDriver) SelectedLine(matcher *TextMatcher) *ViewDriver { self.t.assertWithRetries(func() (bool, string) { selectedLineIdx, err := self.getSelectedLineIdx() if err != nil { @@ -410,7 +410,7 @@ func (self *ViewDriver) PressEscape() *ViewDriver { // If this changes in future, we'll need to update this code to first attempt to find the item // in the current page and failing that, jump to the top of the view and iterate through all of it, // looking for the item. -func (self *ViewDriver) NavigateToLine(matcher *Matcher) *ViewDriver { +func (self *ViewDriver) NavigateToLine(matcher *TextMatcher) *ViewDriver { self.IsFocused() view := self.getView() @@ -510,8 +510,8 @@ func (self *ViewDriver) Self() *ViewDriver { return self } -func expectedContentFromMatchers(matchers []*Matcher) string { - return strings.Join(lo.Map(matchers, func(matcher *Matcher, _ int) string { +func expectedContentFromMatchers(matchers []*TextMatcher) string { + return strings.Join(lo.Map(matchers, func(matcher *TextMatcher, _ int) string { return matcher.name() }), "\n") } diff --git a/pkg/integration/tests/config/remote_named_star.go b/pkg/integration/tests/config/remote_named_star.go index 94ff80b41..15bb45f2e 100644 --- a/pkg/integration/tests/config/remote_named_star.go +++ b/pkg/integration/tests/config/remote_named_star.go @@ -19,8 +19,8 @@ var RemoteNamedStar = NewIntegrationTest(NewIntegrationTestArgs{ // here we're just asserting that we haven't panicked upon starting lazygit t.Views().Commits(). Lines( - Anything(), - Anything(), + AnyString(), + AnyString(), ) }, })