1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-04 10:34:55 +02:00

ensuring you can't accidentally forget to add a test to the tests list

This commit is contained in:
Jesse Duffield 2022-08-14 20:32:17 +10:00
parent 53979f7cec
commit e875d6b448
8 changed files with 86 additions and 27 deletions

View File

@ -37,7 +37,7 @@ If you find yourself doing something frequently in a test, consider making it a
There are three ways to invoke a test:
1. go run cmd/integration_test/main.go cli [<testname>...]
1. go run cmd/integration_test/main.go cli [<testname or testpath>...]
2. go run cmd/integration_test/main.go tui
3. go test pkg/integration/clients/go_test.go

View File

@ -44,10 +44,11 @@ func runAndPrintError(test *components.IntegrationTest, f func() error) {
}
func getTestsToRun(testNames []string) []*components.IntegrationTest {
allIntegrationTests := tests.GetTests()
var testsToRun []*components.IntegrationTest
if len(testNames) == 0 {
return tests.Tests
return allIntegrationTests
}
testNames = slices.Map(testNames, func(name string) string {
@ -61,7 +62,7 @@ func getTestsToRun(testNames []string) []*components.IntegrationTest {
outer:
for _, testName := range testNames {
// check if our given test name actually exists
for _, test := range tests.Tests {
for _, test := range allIntegrationTests {
if test.Name() == testName {
testsToRun = append(testsToRun, test)
continue outer

View File

@ -29,7 +29,7 @@ func TestIntegration(t *testing.T) {
testNumber := 0
err := components.RunTests(
tests.Tests,
tests.GetTests(),
t.Logf,
runCmdHeadless,
func(test *components.IntegrationTest, f func() error) {

View File

@ -52,7 +52,8 @@ func getIntegrationTest() integrationTypes.IntegrationTest {
))
}
for _, candidateTest := range tests.Tests {
allTests := tests.GetTests()
for _, candidateTest := range allTests {
if candidateTest.Name() == integrationTestName {
return candidateTest
}

View File

@ -168,7 +168,7 @@ func RunTUI() {
return err
}
app.filteredTests = tests.Tests
app.filteredTests = app.allTests
app.renderTests()
app.editorView.TextArea.Clear()
app.editorView.Clear()
@ -204,6 +204,7 @@ func RunTUI() {
}
type app struct {
allTests []*components.IntegrationTest
filteredTests []*components.IntegrationTest
itemIdx int
testDir string
@ -214,7 +215,7 @@ type app struct {
}
func newApp(testDir string) *app {
return &app{testDir: testDir}
return &app{testDir: testDir, allTests: tests.GetTests()}
}
func (self *app) getCurrentTest() *components.IntegrationTest {
@ -226,7 +227,7 @@ func (self *app) getCurrentTest() *components.IntegrationTest {
}
func (self *app) loadTests() {
self.filteredTests = tests.Tests
self.filteredTests = self.allTests
self.adjustCursor()
}
@ -237,9 +238,9 @@ func (self *app) adjustCursor() {
func (self *app) filterWithString(needle string) {
if needle == "" {
self.filteredTests = tests.Tests
self.filteredTests = self.allTests
} else {
self.filteredTests = slices.Filter(tests.Tests, func(test *components.IntegrationTest) bool {
self.filteredTests = slices.Filter(self.allTests, func(test *components.IntegrationTest) bool {
return strings.Contains(test.Name(), needle)
})
}

View File

@ -21,12 +21,12 @@ func NewAssert(gui integrationTypes.GuiDriver) *Assert {
}
// for making assertions on string values
type matcher[T any] struct {
testFn func(T) (bool, string)
type matcher struct {
testFn func(string) (bool, string)
prefix string
}
func (self *matcher[T]) test(value T) (bool, string) {
func (self *matcher) test(value string) (bool, string) {
ok, message := self.testFn(value)
if ok {
return true, ""
@ -39,20 +39,20 @@ func (self *matcher[T]) test(value T) (bool, string) {
return false, message
}
func (self *matcher[T]) context(prefix string) *matcher[T] {
func (self *matcher) context(prefix string) *matcher {
self.prefix = prefix
return self
}
func Contains(target string) *matcher[string] {
return &matcher[string]{testFn: func(value string) (bool, string) {
func Contains(target string) *matcher {
return &matcher{testFn: func(value string) (bool, string) {
return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to contain '%s'", value, target)
}}
}
func Equals[T constraints.Ordered](target T) *matcher[T] {
return &matcher[T]{testFn: func(value T) (bool, string) {
func Equals[T constraints.Ordered](target string) *matcher {
return &matcher{testFn: func(value string) (bool, string) {
return target == value, fmt.Sprintf("Expected '%T' to equal '%T'", value, target)
}}
}
@ -79,7 +79,7 @@ func (self *Assert) CommitCount(expectedCount int) {
})
}
func (self *Assert) MatchHeadCommitMessage(matcher *matcher[string]) {
func (self *Assert) MatchHeadCommitMessage(matcher *matcher) {
self.assertWithRetries(func() (bool, string) {
return len(self.gui.Model().Commits) == 0, "Expected at least one commit to be present"
})
@ -113,7 +113,7 @@ func (self *Assert) InListContext() {
})
}
func (self *Assert) MatchSelectedLine(matcher *matcher[string]) {
func (self *Assert) MatchSelectedLine(matcher *matcher) {
self.matchString(matcher, "Unexpected selected line.",
func() string {
return self.gui.CurrentContext().GetView().SelectedLine()
@ -149,7 +149,7 @@ func (self *Assert) InMenu() {
})
}
func (self *Assert) MatchCurrentViewTitle(matcher *matcher[string]) {
func (self *Assert) MatchCurrentViewTitle(matcher *matcher) {
self.matchString(matcher, "Unexpected current view title.",
func() string {
return self.gui.CurrentContext().GetView().Title
@ -157,7 +157,7 @@ func (self *Assert) MatchCurrentViewTitle(matcher *matcher[string]) {
)
}
func (self *Assert) MatchMainViewContent(matcher *matcher[string]) {
func (self *Assert) MatchMainViewContent(matcher *matcher) {
self.matchString(matcher, "Unexpected main view content.",
func() string {
return self.gui.MainView().Buffer()
@ -165,7 +165,7 @@ func (self *Assert) MatchMainViewContent(matcher *matcher[string]) {
)
}
func (self *Assert) MatchSecondaryViewContent(matcher *matcher[string]) {
func (self *Assert) MatchSecondaryViewContent(matcher *matcher) {
self.matchString(matcher, "Unexpected secondary view title.",
func() string {
return self.gui.SecondaryView().Buffer()
@ -173,7 +173,7 @@ func (self *Assert) MatchSecondaryViewContent(matcher *matcher[string]) {
)
}
func (self *Assert) matchString(matcher *matcher[string], context string, getValue func() string) {
func (self *Assert) matchString(matcher *matcher, context string, getValue func() string) {
self.assertWithRetries(func() (bool, string) {
value := getValue()
return matcher.context(context).test(value)

View File

@ -53,7 +53,7 @@ func NewIntegrationTest(args NewIntegrationTestArgs) *IntegrationTest {
if args.Description != unitTestDescription {
// this panics if we're in a unit test for our integration tests,
// so we're using "test test" as a sentinel value
name = testNameFromFilePath()
name = testNameFromCurrentFilePath()
}
return &IntegrationTest{
@ -106,8 +106,12 @@ func (self *IntegrationTest) Run(gui integrationTypes.GuiDriver) {
}
}
func testNameFromFilePath() string {
func testNameFromCurrentFilePath() string {
path := utils.FilePath(3)
return TestNameFromFilePath(path)
}
func TestNameFromFilePath(path string) string {
name := strings.Split(path, "integration/tests/")[1]
return name[:len(name)-len(".go")]

View File

@ -1,17 +1,25 @@
package tests
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/jesseduffield/generics/set"
"github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/integration/components"
"github.com/jesseduffield/lazygit/pkg/integration/tests/branch"
"github.com/jesseduffield/lazygit/pkg/integration/tests/commit"
"github.com/jesseduffield/lazygit/pkg/integration/tests/custom_commands"
"github.com/jesseduffield/lazygit/pkg/integration/tests/interactive_rebase"
"github.com/jesseduffield/lazygit/pkg/utils"
)
// Here is where we lists the actual tests that will run. When you create a new test,
// be sure to add it to this list.
var Tests = []*components.IntegrationTest{
var tests = []*components.IntegrationTest{
commit.Commit,
commit.NewBranch,
branch.Suggestions,
@ -19,3 +27,47 @@ var Tests = []*components.IntegrationTest{
custom_commands.Basic,
custom_commands.MultiplePrompts,
}
func GetTests() []*components.IntegrationTest {
// first we ensure that each test in this directory has actually been added to the above list.
testCount := 0
testNamesSet := set.NewFromSlice(slices.Map(
tests,
func(test *components.IntegrationTest) string {
return test.Name()
},
))
missingTestNames := []string{}
if err := filepath.Walk(filepath.Join(utils.GetLazygitRootDirectory(), "pkg/integration/tests"), func(path string, info os.FileInfo, err error) error {
if !info.IsDir() && strings.HasSuffix(path, ".go") {
// ignoring this current file
if filepath.Base(path) == "tests.go" {
return nil
}
nameFromPath := components.TestNameFromFilePath(path)
if !testNamesSet.Includes(nameFromPath) {
missingTestNames = append(missingTestNames, nameFromPath)
}
testCount++
}
return nil
}); err != nil {
panic(fmt.Sprintf("failed to walk tests: %v", err))
}
if len(missingTestNames) > 0 {
panic(fmt.Sprintf("The following tests are missing from the list of tests: %s. You need to add them to `pkg/integration/tests/tests.go`.", strings.Join(missingTestNames, ", ")))
}
if testCount > len(tests) {
panic("you have not added all of the tests to the tests list in `pkg/integration/tests/tests.go`")
} else if testCount < len(tests) {
panic("There are more tests in `pkg/integration/tests/tests.go` than there are test files in the tests directory. Ensure that you only have one test per file and you haven't included the same test twice in the tests list.")
}
return tests
}