1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-10 04:07:18 +02:00
lazygit/pkg/integration/components/test.go
Jesse Duffield c92e687d3b Fix focus issue when opening recent-repos menu at launch
I don't know why we were setting the initial context to CurrentSideContext
and not just CurrentContext in the first place. If there is no current context
in either case it'll default to the files context. So the only issue is if
we anticipated that some random context would be focused and we didn't want to
activate that. But I can't think of any situation where that would happen.
2023-06-07 18:27:18 +10:00

200 lines
5.4 KiB
Go

package components
import (
"os"
"strconv"
"strings"
"github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/env"
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
"github.com/jesseduffield/lazygit/pkg/utils"
)
// IntegrationTest describes an integration test that will be run against the lazygit gui.
// our unit tests will use this description to avoid a panic caused by attempting
// to get the test's name via it's file's path.
const unitTestDescription = "test test"
type IntegrationTest struct {
name string
description string
extraCmdArgs []string
extraEnvVars map[string]string
skip bool
setupRepo func(shell *Shell)
setupConfig func(config *config.AppConfig)
run func(
testDriver *TestDriver,
keys config.KeybindingConfig,
)
gitVersion GitVersionRestriction
}
var _ integrationTypes.IntegrationTest = &IntegrationTest{}
type NewIntegrationTestArgs struct {
// Briefly describes what happens in the test and what it's testing for
Description string
// prepares a repo for testing
SetupRepo func(shell *Shell)
// takes a config and mutates. The mutated context will end up being passed to the gui
SetupConfig func(config *config.AppConfig)
// runs the test
Run func(t *TestDriver, keys config.KeybindingConfig)
// additional args passed to lazygit
ExtraCmdArgs []string
// for when a test is flakey
ExtraEnvVars map[string]string
Skip bool
// to run a test only on certain git versions
GitVersion GitVersionRestriction
}
type GitVersionRestriction struct {
// Only one of these fields can be non-empty; use functions below to construct
from string
before string
includes []string
}
// Verifies the version is at least the given version (inclusive)
func AtLeast(version string) GitVersionRestriction {
return GitVersionRestriction{from: version}
}
// Verifies the version is before the given version (exclusive)
func Before(version string) GitVersionRestriction {
return GitVersionRestriction{before: version}
}
func Includes(versions ...string) GitVersionRestriction {
return GitVersionRestriction{includes: versions}
}
func (self GitVersionRestriction) shouldRunOnVersion(version *git_commands.GitVersion) bool {
if self.from != "" {
from, err := git_commands.ParseGitVersion(self.from)
if err != nil {
panic("Invalid git version string: " + self.from)
}
return !version.IsOlderThanVersion(from)
}
if self.before != "" {
before, err := git_commands.ParseGitVersion(self.before)
if err != nil {
panic("Invalid git version string: " + self.before)
}
return version.IsOlderThanVersion(before)
}
if len(self.includes) != 0 {
return slices.Some(self.includes, func(str string) bool {
v, err := git_commands.ParseGitVersion(str)
if err != nil {
panic("Invalid git version string: " + str)
}
return version.Major == v.Major && version.Minor == v.Minor && version.Patch == v.Patch
})
}
return true
}
func NewIntegrationTest(args NewIntegrationTestArgs) *IntegrationTest {
name := ""
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 = testNameFromCurrentFilePath()
}
return &IntegrationTest{
name: name,
description: args.Description,
extraCmdArgs: args.ExtraCmdArgs,
extraEnvVars: args.ExtraEnvVars,
skip: args.Skip,
setupRepo: args.SetupRepo,
setupConfig: args.SetupConfig,
run: args.Run,
gitVersion: args.GitVersion,
}
}
func (self *IntegrationTest) Name() string {
return self.name
}
func (self *IntegrationTest) Description() string {
return self.description
}
func (self *IntegrationTest) ExtraCmdArgs() []string {
return self.extraCmdArgs
}
func (self *IntegrationTest) ExtraEnvVars() map[string]string {
return self.extraEnvVars
}
func (self *IntegrationTest) Skip() bool {
return self.skip
}
func (self *IntegrationTest) ShouldRunForGitVersion(version *git_commands.GitVersion) bool {
return self.gitVersion.shouldRunOnVersion(version)
}
func (self *IntegrationTest) SetupConfig(config *config.AppConfig) {
self.setupConfig(config)
}
func (self *IntegrationTest) SetupRepo(shell *Shell) {
self.setupRepo(shell)
}
func (self *IntegrationTest) Run(gui integrationTypes.GuiDriver) {
// we pass the --pass arg to lazygit when running an integration test, and that
// ends up stored in the following env var
repoPath := env.GetGitWorkTreeEnv()
shell := NewShell(repoPath, func(errorMsg string) { gui.Fail(errorMsg) })
keys := gui.Keys()
testDriver := NewTestDriver(gui, shell, keys, KeyPressDelay())
self.run(testDriver, keys)
if KeyPressDelay() > 0 {
// the dev would want to see the final state if they're running in slow mode
testDriver.Wait(2000)
}
}
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")]
}
// this is the delay in milliseconds between keypresses
// defaults to zero
func KeyPressDelay() int {
delayStr := os.Getenv("KEY_PRESS_DELAY")
if delayStr == "" {
return 0
}
delay, err := strconv.Atoi(delayStr)
if err != nil {
panic(err)
}
return delay
}