mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-12-10 11:10:18 +02:00
allow checking if line is selected in Lines and TopLines methods
This commit is contained in:
parent
96310288ee
commit
09db4c4397
@ -41,11 +41,6 @@ func (self *matcher) name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *matcher) test(value string) (bool, string) {
|
func (self *matcher) test(value string) (bool, string) {
|
||||||
// if there are no rules, then we pass the test by default
|
|
||||||
if len(self.rules) == 0 {
|
|
||||||
return true, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rule := range self.rules {
|
for _, rule := range self.rules {
|
||||||
ok, message := rule.testFn(value)
|
ok, message := rule.testFn(value)
|
||||||
if ok {
|
if ok {
|
||||||
@ -63,33 +58,25 @@ func (self *matcher) test(value string) (bool, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *matcher) Contains(target string) *matcher {
|
func (self *matcher) Contains(target string) *matcher {
|
||||||
rule := matcherRule{
|
return self.appendRule(matcherRule{
|
||||||
name: fmt.Sprintf("contains '%s'", target),
|
name: fmt.Sprintf("contains '%s'", target),
|
||||||
testFn: func(value string) (bool, string) {
|
testFn: func(value string) (bool, string) {
|
||||||
return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to be found in '%s'", target, value)
|
return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to be found in '%s'", target, value)
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
self.rules = append(self.rules, rule)
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *matcher) DoesNotContain(target string) *matcher {
|
func (self *matcher) DoesNotContain(target string) *matcher {
|
||||||
rule := matcherRule{
|
return self.appendRule(matcherRule{
|
||||||
name: fmt.Sprintf("does not contain '%s'", target),
|
name: fmt.Sprintf("does not contain '%s'", target),
|
||||||
testFn: func(value string) (bool, string) {
|
testFn: func(value string) (bool, string) {
|
||||||
return !strings.Contains(value, target), fmt.Sprintf("Expected '%s' to NOT be found in '%s'", target, value)
|
return !strings.Contains(value, target), fmt.Sprintf("Expected '%s' to NOT be found in '%s'", target, value)
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
self.rules = append(self.rules, rule)
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *matcher) MatchesRegexp(target string) *matcher {
|
func (self *matcher) MatchesRegexp(target string) *matcher {
|
||||||
rule := matcherRule{
|
return self.appendRule(matcherRule{
|
||||||
name: fmt.Sprintf("matches regular expression '%s'", target),
|
name: fmt.Sprintf("matches regular expression '%s'", target),
|
||||||
testFn: func(value string) (bool, string) {
|
testFn: func(value string) (bool, string) {
|
||||||
matched, err := regexp.MatchString(target, value)
|
matched, err := regexp.MatchString(target, value)
|
||||||
@ -98,32 +85,54 @@ func (self *matcher) MatchesRegexp(target string) *matcher {
|
|||||||
}
|
}
|
||||||
return matched, fmt.Sprintf("Expected '%s' to match regular expression '%s'", value, target)
|
return matched, fmt.Sprintf("Expected '%s' to match regular expression '%s'", value, target)
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
self.rules = append(self.rules, rule)
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *matcher) Equals(target string) *matcher {
|
func (self *matcher) Equals(target string) *matcher {
|
||||||
rule := matcherRule{
|
return self.appendRule(matcherRule{
|
||||||
name: fmt.Sprintf("equals '%s'", target),
|
name: fmt.Sprintf("equals '%s'", target),
|
||||||
testFn: func(value string) (bool, string) {
|
testFn: func(value string) (bool, string) {
|
||||||
return target == value, fmt.Sprintf("Expected '%s' to equal '%s'", value, target)
|
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 {
|
||||||
self.rules = append(self.rules, rule)
|
self.rules = append(self.rules, rule)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) context(prefix string) *matcher {
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
|
|
||||||
return self
|
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) {
|
||||||
|
check := lo.ContainsBy(self.rules, func(rule matcherRule) bool { return rule.name == IS_SELECTED_RULE_NAME })
|
||||||
|
|
||||||
|
self.rules = lo.Filter(self.rules, func(rule matcherRule, _ int) bool { return rule.name != IS_SELECTED_RULE_NAME })
|
||||||
|
|
||||||
|
return check, self
|
||||||
|
}
|
||||||
|
|
||||||
// this matcher has no rules meaning it always passes the test. Use this
|
// this matcher has no rules meaning it always passes the test. Use this
|
||||||
// when you don't care what value you're dealing with.
|
// when you don't care what value you're dealing with.
|
||||||
func Anything() *matcher {
|
func Anything() *matcher {
|
||||||
|
@ -44,17 +44,7 @@ func (self *ViewAsserter) TopLines(matchers ...*matcher) *ViewAsserter {
|
|||||||
return len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines))
|
return len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines))
|
||||||
})
|
})
|
||||||
|
|
||||||
view := self.getView()
|
return self.assertLines(matchers...)
|
||||||
|
|
||||||
for i, matcher := range matchers {
|
|
||||||
self.assert.matchString(matcher, fmt.Sprintf("Unexpected content in view '%s'.", view.Name()),
|
|
||||||
func() string {
|
|
||||||
return view.BufferLines()[i]
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// asserts that the view has lines matching the given matchers. One matcher must be passed for each line.
|
// asserts that the view has lines matching the given matchers. One matcher must be passed for each line.
|
||||||
@ -65,14 +55,27 @@ func (self *ViewAsserter) Lines(matchers ...*matcher) *ViewAsserter {
|
|||||||
return len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines))
|
return len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return self.assertLines(matchers...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *ViewAsserter) assertLines(matchers ...*matcher) *ViewAsserter {
|
||||||
view := self.getView()
|
view := self.getView()
|
||||||
|
|
||||||
for i, matcher := range matchers {
|
for i, matcher := range matchers {
|
||||||
|
checkIsSelected, matcher := matcher.checkIsSelected()
|
||||||
|
|
||||||
self.assert.matchString(matcher, fmt.Sprintf("Unexpected content in view '%s'.", view.Name()),
|
self.assert.matchString(matcher, fmt.Sprintf("Unexpected content in view '%s'.", view.Name()),
|
||||||
func() string {
|
func() string {
|
||||||
return view.BufferLines()[i]
|
return view.BufferLines()[i]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if checkIsSelected {
|
||||||
|
self.assert.assertWithRetries(func() (bool, string) {
|
||||||
|
lineIdx := view.SelectedLineIdx()
|
||||||
|
return lineIdx == i, fmt.Sprintf("Unexpected selected line index in view '%s'. Expected %d, got %d", view.Name(), i, lineIdx)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
@ -42,8 +42,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
|
|
||||||
assert.View("information").Content(Contains("bisecting"))
|
assert.View("information").Content(Contains("bisecting"))
|
||||||
|
|
||||||
assert.CurrentView().Name("commits")
|
assert.CurrentView().Name("commits").SelectedLine(Contains("<-- bad"))
|
||||||
assert.CurrentView().SelectedLine(Contains("<-- bad"))
|
|
||||||
|
|
||||||
input.NavigateToListItem(Contains("commit 02"))
|
input.NavigateToListItem(Contains("commit 02"))
|
||||||
|
|
||||||
|
@ -36,8 +36,7 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
assert.CurrentView().Name("localBranches").
|
assert.CurrentView().Name("localBranches").
|
||||||
Lines(
|
Lines(
|
||||||
MatchesRegexp(`\*.*branch-two`),
|
MatchesRegexp(`\*.*branch-two`),
|
||||||
MatchesRegexp(`master`),
|
MatchesRegexp(`master`).IsSelected(),
|
||||||
).
|
)
|
||||||
SelectedLineIdx(1)
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -27,7 +27,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert.View("commits").TopLines(
|
assert.View("commits").TopLines(
|
||||||
Contains("to keep"),
|
Contains("to keep").IsSelected(),
|
||||||
Contains("to remove"),
|
Contains("to remove"),
|
||||||
Contains("first change"),
|
Contains("first change"),
|
||||||
Contains("original"),
|
Contains("original"),
|
||||||
@ -44,22 +44,29 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
|
|
||||||
assert.CurrentView().
|
assert.CurrentView().
|
||||||
Name("files").
|
Name("files").
|
||||||
SelectedLine(Contains("file"))
|
SelectedLine(MatchesRegexp("UU.*file"))
|
||||||
|
|
||||||
input.SwitchToCommitsView()
|
input.SwitchToCommitsView()
|
||||||
assert.CurrentView().
|
assert.CurrentView().
|
||||||
TopLines(
|
TopLines(
|
||||||
MatchesRegexp(`pick.*to keep`),
|
MatchesRegexp(`pick.*to keep`).IsSelected(),
|
||||||
MatchesRegexp(`pick.*to remove`),
|
MatchesRegexp(`pick.*to remove`),
|
||||||
MatchesRegexp("YOU ARE HERE.*second-change-branch unrelated change"),
|
MatchesRegexp("YOU ARE HERE.*second-change-branch unrelated change"),
|
||||||
MatchesRegexp("second change"),
|
MatchesRegexp("second change"),
|
||||||
MatchesRegexp("original"),
|
MatchesRegexp("original"),
|
||||||
).
|
)
|
||||||
SelectedLineIdx(0)
|
|
||||||
|
|
||||||
input.NextItem()
|
input.NextItem()
|
||||||
input.Press(keys.Universal.Remove)
|
input.Press(keys.Universal.Remove)
|
||||||
assert.CurrentView().SelectedLine(MatchesRegexp(`drop.*to remove`))
|
|
||||||
|
assert.CurrentView().
|
||||||
|
TopLines(
|
||||||
|
MatchesRegexp(`pick.*to keep`),
|
||||||
|
MatchesRegexp(`drop.*to remove`).IsSelected(),
|
||||||
|
MatchesRegexp("YOU ARE HERE.*second-change-branch unrelated change"),
|
||||||
|
MatchesRegexp("second change"),
|
||||||
|
MatchesRegexp("original"),
|
||||||
|
)
|
||||||
|
|
||||||
input.SwitchToFilesView()
|
input.SwitchToFilesView()
|
||||||
|
|
||||||
@ -76,7 +83,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
|
|
||||||
assert.View("commits").TopLines(
|
assert.View("commits").TopLines(
|
||||||
Contains("to keep"),
|
Contains("to keep"),
|
||||||
Contains("second-change-branch unrelated change"),
|
Contains("second-change-branch unrelated change").IsSelected(),
|
||||||
Contains("second change"),
|
Contains("second change"),
|
||||||
Contains("original"),
|
Contains("original"),
|
||||||
)
|
)
|
||||||
|
@ -29,10 +29,9 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
|
|
||||||
assert.CurrentView().Name("commits").
|
assert.CurrentView().Name("commits").
|
||||||
Lines(
|
Lines(
|
||||||
Contains("Revert \"first commit\""),
|
Contains("Revert \"first commit\"").IsSelected(),
|
||||||
Contains("first commit"),
|
Contains("first commit"),
|
||||||
).
|
)
|
||||||
SelectedLineIdx(0)
|
|
||||||
|
|
||||||
assert.MainView().Content(Contains("-myfile content"))
|
assert.MainView().Content(Contains("-myfile content"))
|
||||||
assert.FileSystemPathNotPresent("myfile")
|
assert.FileSystemPathNotPresent("myfile")
|
||||||
|
@ -48,8 +48,7 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
|
|
||||||
input.Enter()
|
input.Enter()
|
||||||
|
|
||||||
assert.CurrentView().Name("commitFiles")
|
assert.CurrentView().Name("commitFiles").SelectedLine(Contains("file1"))
|
||||||
assert.CurrentView().SelectedLine(Contains("file1"))
|
|
||||||
assert.MainView().Content(Contains("+second line\n+third line"))
|
assert.MainView().Content(Contains("+second line\n+third line"))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user