mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-03 13:21:56 +02:00
move input and assert into integration tests package
This commit is contained in:
parent
46ae55f91e
commit
d890238c7b
@ -24,7 +24,6 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/gui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/updates"
|
||||
)
|
||||
|
||||
@ -43,7 +42,6 @@ func Run(
|
||||
config config.AppConfigurer,
|
||||
common *common.Common,
|
||||
startArgs types.StartArgs,
|
||||
test integrationTypes.Test,
|
||||
) {
|
||||
app, err := NewApp(config, common)
|
||||
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/env"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/integration"
|
||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/logs"
|
||||
"gopkg.in/yaml.v3"
|
||||
@ -119,7 +118,7 @@ func Start(cliArgs *CliArgs, buildInfo *BuildInfo, test integrationTypes.Test) {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if test, ok := integration.CurrentIntegrationTest(); ok {
|
||||
if test != nil {
|
||||
test.SetupConfig(appConfig)
|
||||
}
|
||||
|
||||
@ -135,7 +134,7 @@ func Start(cliArgs *CliArgs, buildInfo *BuildInfo, test integrationTypes.Test) {
|
||||
|
||||
parsedGitArg := parseGitArg(cliArgs.GitArg)
|
||||
|
||||
Run(appConfig, common, types.NewStartArgs(cliArgs.FilterPath, parsedGitArg), test)
|
||||
Run(appConfig, common, types.NewStartArgs(cliArgs.FilterPath, parsedGitArg, test))
|
||||
}
|
||||
|
||||
func parseGitArg(gitArg string) types.GitArg {
|
||||
|
@ -1,109 +0,0 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
guiTypes "github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
)
|
||||
|
||||
type AssertImpl struct {
|
||||
gui *Gui
|
||||
}
|
||||
|
||||
var _ types.Assert = &AssertImpl{}
|
||||
|
||||
func (self *AssertImpl) WorkingTreeFileCount(expectedCount int) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actualCount := len(self.gui.State.Model.Files)
|
||||
|
||||
return actualCount == expectedCount, fmt.Sprintf(
|
||||
"Expected %d changed working tree files, but got %d",
|
||||
expectedCount, actualCount,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *AssertImpl) CommitCount(expectedCount int) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actualCount := len(self.gui.State.Model.Commits)
|
||||
|
||||
return actualCount == expectedCount, fmt.Sprintf(
|
||||
"Expected %d commits present, but got %d",
|
||||
expectedCount, actualCount,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *AssertImpl) HeadCommitMessage(expectedMessage string) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
if len(self.gui.State.Model.Commits) == 0 {
|
||||
return false, "Expected at least one commit to be present"
|
||||
}
|
||||
|
||||
headCommit := self.gui.State.Model.Commits[0]
|
||||
if headCommit.Name != expectedMessage {
|
||||
return false, fmt.Sprintf(
|
||||
"Expected commit message to be '%s', but got '%s'",
|
||||
expectedMessage, headCommit.Name,
|
||||
)
|
||||
}
|
||||
|
||||
return true, ""
|
||||
})
|
||||
}
|
||||
|
||||
func (self *AssertImpl) CurrentViewName(expectedViewName string) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actual := self.gui.currentViewName()
|
||||
return actual == expectedViewName, fmt.Sprintf("Expected current view name to be '%s', but got '%s'", expectedViewName, actual)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *AssertImpl) CurrentBranchName(expectedViewName string) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actual := self.gui.helpers.Refs.GetCheckedOutRef().Name
|
||||
return actual == expectedViewName, fmt.Sprintf("Expected current branch name to be '%s', but got '%s'", expectedViewName, actual)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *AssertImpl) InListContext() {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
currentContext := self.gui.currentContext()
|
||||
_, ok := currentContext.(guiTypes.IListContext)
|
||||
return ok, fmt.Sprintf("Expected current context to be a list context, but got %s", currentContext.GetKey())
|
||||
})
|
||||
}
|
||||
|
||||
func (self *AssertImpl) SelectedLineContains(text string) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
line := self.gui.currentContext().GetView().SelectedLine()
|
||||
return strings.Contains(line, text), fmt.Sprintf("Expected selected line to contain '%s', but got '%s'", text, line)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *AssertImpl) assertWithRetries(test func() (bool, string)) {
|
||||
waitTimes := []int{0, 1, 5, 10, 200, 500, 1000}
|
||||
|
||||
var message string
|
||||
for _, waitTime := range waitTimes {
|
||||
time.Sleep(time.Duration(waitTime) * time.Millisecond)
|
||||
|
||||
var ok bool
|
||||
ok, message = test()
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
self.Fail(message)
|
||||
}
|
||||
|
||||
func (self *AssertImpl) Fail(message string) {
|
||||
self.gui.g.Close()
|
||||
// need to give the gui time to close
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
panic(message)
|
||||
}
|
@ -31,7 +31,6 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/services/custom_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/integration"
|
||||
"github.com/jesseduffield/lazygit/pkg/tasks"
|
||||
"github.com/jesseduffield/lazygit/pkg/theme"
|
||||
"github.com/jesseduffield/lazygit/pkg/updates"
|
||||
@ -418,14 +417,14 @@ var RuneReplacements = map[rune]string{
|
||||
graph.CommitSymbol: "o",
|
||||
}
|
||||
|
||||
func (gui *Gui) initGocui(headless bool) (*gocui.Gui, error) {
|
||||
recordEvents := integration.RecordingEvents()
|
||||
func (gui *Gui) initGocui(headless bool, test types.Test) (*gocui.Gui, error) {
|
||||
recordEvents := RecordingEvents()
|
||||
playMode := gocui.NORMAL
|
||||
if recordEvents {
|
||||
playMode = gocui.RECORDING
|
||||
} else if integration.Replaying() {
|
||||
} else if Replaying() {
|
||||
playMode = gocui.REPLAYING
|
||||
} else if integration.IntegrationTestName() != "" {
|
||||
} else if test != nil {
|
||||
playMode = gocui.REPLAYING_NEW
|
||||
}
|
||||
|
||||
@ -478,7 +477,7 @@ func (gui *Gui) viewTabMap() map[string][]context.TabView {
|
||||
|
||||
// Run: setup the gui with keybindings and start the mainloop
|
||||
func (gui *Gui) Run(startArgs types.StartArgs) error {
|
||||
g, err := gui.initGocui(integration.Headless())
|
||||
g, err := gui.initGocui(Headless(), startArgs.Test)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -493,7 +492,7 @@ func (gui *Gui) Run(startArgs types.StartArgs) error {
|
||||
})
|
||||
deadlock.Opts.Disable = !gui.Debug
|
||||
|
||||
gui.handleTestMode()
|
||||
gui.handleTestMode(startArgs.Test)
|
||||
|
||||
gui.g.OnSearchEscape = gui.onSearchEscape
|
||||
if err := gui.Config.ReloadUserConfig(); err != nil {
|
||||
@ -580,7 +579,7 @@ func (gui *Gui) RunAndHandleError(startArgs types.StartArgs) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := integration.SaveRecording(gui.g.Recording); err != nil {
|
||||
if err := SaveRecording(gui.g.Recording); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -614,7 +613,7 @@ func (gui *Gui) runSubprocessWithSuspense(subprocess oscommands.ICmdObj) (bool,
|
||||
gui.Mutexes.SubprocessMutex.Lock()
|
||||
defer gui.Mutexes.SubprocessMutex.Unlock()
|
||||
|
||||
if integration.Replaying() {
|
||||
if Replaying() {
|
||||
// we do not yet support running subprocesses within integration tests. So if
|
||||
// we're replaying an integration test and we're inside this method, something
|
||||
// has gone wrong, so we should fail
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
)
|
||||
|
||||
// this gives our integration test a way of interacting with the gui for sending keypresses
|
||||
@ -18,7 +17,7 @@ type GuiAdapterImpl struct {
|
||||
gui *Gui
|
||||
}
|
||||
|
||||
var _ integrationTypes.GuiAdapter = &GuiAdapterImpl{}
|
||||
var _ types.GuiAdapter = &GuiAdapterImpl{}
|
||||
|
||||
func (self *GuiAdapterImpl) PressKey(keyStr string) {
|
||||
key := keybindings.GetKey(keyStr)
|
||||
|
@ -36,20 +36,19 @@ func Test(t *testing.T) {
|
||||
err := integration.RunTestsNew(
|
||||
t.Logf,
|
||||
runCmdHeadless,
|
||||
func(test types.Test, f func(*testing.T) error) {
|
||||
func(test types.Test, f func() error) {
|
||||
defer func() { testNumber += 1 }()
|
||||
if testNumber%parallelTotal != parallelIndex {
|
||||
return
|
||||
}
|
||||
|
||||
t.Run(test.Name(), func(t *testing.T) {
|
||||
err := f(t)
|
||||
err := f()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
},
|
||||
mode,
|
||||
func(t *testing.T, expected string, actual string, prefix string) {
|
||||
t.Helper()
|
||||
func(expected string, actual string, prefix string) {
|
||||
assert.Equal(t, expected, actual, fmt.Sprintf("Unexpected %s. Expected:\n%s\nActual:\n%s\n", prefix, expected, actual))
|
||||
},
|
||||
includeSkipped,
|
||||
|
166
pkg/gui/input.go
166
pkg/gui/input.go
@ -1,166 +0,0 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
|
||||
guiTypes "github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
)
|
||||
|
||||
type InputImpl struct {
|
||||
gui *Gui
|
||||
keys config.KeybindingConfig
|
||||
assert types.Assert
|
||||
pushKeyDelay int
|
||||
}
|
||||
|
||||
func NewInputImpl(gui *Gui, keys config.KeybindingConfig, assert types.Assert, pushKeyDelay int) *InputImpl {
|
||||
return &InputImpl{
|
||||
gui: gui,
|
||||
keys: keys,
|
||||
assert: assert,
|
||||
pushKeyDelay: pushKeyDelay,
|
||||
}
|
||||
}
|
||||
|
||||
var _ types.Input = &InputImpl{}
|
||||
|
||||
func (self *InputImpl) PressKeys(keyStrs ...string) {
|
||||
for _, keyStr := range keyStrs {
|
||||
self.pressKey(keyStr)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *InputImpl) pressKey(keyStr string) {
|
||||
self.Wait(self.pushKeyDelay)
|
||||
|
||||
key := keybindings.GetKey(keyStr)
|
||||
|
||||
var r rune
|
||||
var tcellKey tcell.Key
|
||||
switch v := key.(type) {
|
||||
case rune:
|
||||
r = v
|
||||
tcellKey = tcell.KeyRune
|
||||
case gocui.Key:
|
||||
tcellKey = tcell.Key(v)
|
||||
}
|
||||
|
||||
self.gui.g.ReplayedEvents.Keys <- gocui.NewTcellKeyEventWrapper(
|
||||
tcell.NewEventKey(tcellKey, r, tcell.ModNone),
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
func (self *InputImpl) SwitchToStatusWindow() {
|
||||
self.pressKey(self.keys.Universal.JumpToBlock[0])
|
||||
}
|
||||
|
||||
func (self *InputImpl) SwitchToFilesWindow() {
|
||||
self.pressKey(self.keys.Universal.JumpToBlock[1])
|
||||
}
|
||||
|
||||
func (self *InputImpl) SwitchToBranchesWindow() {
|
||||
self.pressKey(self.keys.Universal.JumpToBlock[2])
|
||||
}
|
||||
|
||||
func (self *InputImpl) SwitchToCommitsWindow() {
|
||||
self.pressKey(self.keys.Universal.JumpToBlock[3])
|
||||
}
|
||||
|
||||
func (self *InputImpl) SwitchToStashWindow() {
|
||||
self.pressKey(self.keys.Universal.JumpToBlock[4])
|
||||
}
|
||||
|
||||
func (self *InputImpl) Type(content string) {
|
||||
for _, char := range content {
|
||||
self.pressKey(string(char))
|
||||
}
|
||||
}
|
||||
|
||||
func (self *InputImpl) Confirm() {
|
||||
self.pressKey(self.keys.Universal.Confirm)
|
||||
}
|
||||
|
||||
func (self *InputImpl) Cancel() {
|
||||
self.pressKey(self.keys.Universal.Return)
|
||||
}
|
||||
|
||||
func (self *InputImpl) Select() {
|
||||
self.pressKey(self.keys.Universal.Select)
|
||||
}
|
||||
|
||||
func (self *InputImpl) NextItem() {
|
||||
self.pressKey(self.keys.Universal.NextItem)
|
||||
}
|
||||
|
||||
func (self *InputImpl) PreviousItem() {
|
||||
self.pressKey(self.keys.Universal.PrevItem)
|
||||
}
|
||||
|
||||
func (self *InputImpl) ContinueMerge() {
|
||||
self.PressKeys(self.keys.Universal.CreateRebaseOptionsMenu)
|
||||
self.assert.SelectedLineContains("continue")
|
||||
self.Confirm()
|
||||
}
|
||||
|
||||
func (self *InputImpl) ContinueRebase() {
|
||||
self.ContinueMerge()
|
||||
}
|
||||
|
||||
func (self *InputImpl) Wait(milliseconds int) {
|
||||
time.Sleep(time.Duration(milliseconds) * time.Millisecond)
|
||||
}
|
||||
|
||||
func (self *InputImpl) log(message string) {
|
||||
self.gui.c.LogAction(message)
|
||||
}
|
||||
|
||||
// NOTE: this currently assumes that ViewBufferLines returns all the lines that can be accessed.
|
||||
// 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 *InputImpl) NavigateToListItemContainingText(text string) {
|
||||
self.assert.InListContext()
|
||||
|
||||
currentContext := self.gui.currentContext().(guiTypes.IListContext)
|
||||
view := currentContext.GetView()
|
||||
|
||||
// first we look for a duplicate on the current screen. We won't bother looking beyond that though.
|
||||
matchCount := 0
|
||||
matchIndex := -1
|
||||
for i, line := range view.ViewBufferLines() {
|
||||
if strings.Contains(line, text) {
|
||||
matchCount++
|
||||
matchIndex = i
|
||||
}
|
||||
}
|
||||
if matchCount > 1 {
|
||||
self.assert.Fail(fmt.Sprintf("Found %d matches for %s, expected only a single match", matchCount, text))
|
||||
}
|
||||
if matchCount == 1 {
|
||||
selectedLineIdx := view.SelectedLineIdx()
|
||||
if selectedLineIdx == matchIndex {
|
||||
return
|
||||
}
|
||||
if selectedLineIdx < matchIndex {
|
||||
for i := selectedLineIdx; i < matchIndex; i++ {
|
||||
self.NextItem()
|
||||
}
|
||||
return
|
||||
} else {
|
||||
for i := selectedLineIdx; i > matchIndex; i-- {
|
||||
self.PreviousItem()
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
self.assert.Fail(fmt.Sprintf("Could not find item containing text: %s", text))
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/integration"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
@ -14,14 +17,8 @@ type IntegrationTest interface {
|
||||
Run(guiAdapter *GuiAdapterImpl)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleTestMode() {
|
||||
if integration.PlayingIntegrationTest() {
|
||||
test, ok := integration.CurrentIntegrationTest()
|
||||
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("test %s not found", integration.IntegrationTestName()))
|
||||
}
|
||||
|
||||
func (gui *Gui) handleTestMode(test types.Test) {
|
||||
if test != nil {
|
||||
go func() {
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
@ -42,14 +39,14 @@ func (gui *Gui) handleTestMode() {
|
||||
})
|
||||
}
|
||||
|
||||
if integration.Replaying() {
|
||||
if Replaying() {
|
||||
gui.g.RecordingConfig = gocui.RecordingConfig{
|
||||
Speed: integration.GetRecordingSpeed(),
|
||||
Speed: GetRecordingSpeed(),
|
||||
Leeway: 100,
|
||||
}
|
||||
|
||||
var err error
|
||||
gui.g.Recording, err = integration.LoadRecording()
|
||||
gui.g.Recording, err = LoadRecording()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -60,3 +57,68 @@ func (gui *Gui) handleTestMode() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Headless() bool {
|
||||
return os.Getenv("HEADLESS") != ""
|
||||
}
|
||||
|
||||
// OLD integration test format stuff
|
||||
|
||||
func Replaying() bool {
|
||||
return os.Getenv("REPLAY_EVENTS_FROM") != ""
|
||||
}
|
||||
|
||||
func RecordingEvents() bool {
|
||||
return recordEventsTo() != ""
|
||||
}
|
||||
|
||||
func recordEventsTo() string {
|
||||
return os.Getenv("RECORD_EVENTS_TO")
|
||||
}
|
||||
|
||||
func GetRecordingSpeed() float64 {
|
||||
// humans are slow so this speeds things up.
|
||||
speed := 1.0
|
||||
envReplaySpeed := os.Getenv("SPEED")
|
||||
if envReplaySpeed != "" {
|
||||
var err error
|
||||
speed, err = strconv.ParseFloat(envReplaySpeed, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
return speed
|
||||
}
|
||||
|
||||
func LoadRecording() (*gocui.Recording, error) {
|
||||
path := os.Getenv("REPLAY_EVENTS_FROM")
|
||||
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
recording := &gocui.Recording{}
|
||||
|
||||
err = json.Unmarshal(data, &recording)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return recording, nil
|
||||
}
|
||||
|
||||
func SaveRecording(recording *gocui.Recording) error {
|
||||
if !RecordingEvents() {
|
||||
return nil
|
||||
}
|
||||
|
||||
jsonEvents, err := json.Marshal(recording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path := recordEventsTo()
|
||||
|
||||
return ioutil.WriteFile(path, jsonEvents, 0o600)
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ type StartArgs struct {
|
||||
FilterPath string
|
||||
// GitArg determines what context we open in
|
||||
GitArg GitArg
|
||||
// integration test (only relevant when invoking lazygit in the context of an integration test)
|
||||
Test Test
|
||||
}
|
||||
|
||||
type GitArg string
|
||||
@ -18,9 +20,10 @@ const (
|
||||
GitArgStash GitArg = "stash"
|
||||
)
|
||||
|
||||
func NewStartArgs(filterPath string, gitArg GitArg) StartArgs {
|
||||
func NewStartArgs(filterPath string, gitArg GitArg, test Test) StartArgs {
|
||||
return StartArgs{
|
||||
FilterPath: filterPath,
|
||||
GitArg: gitArg,
|
||||
Test: test,
|
||||
}
|
||||
}
|
||||
|
27
pkg/gui/types/test.go
Normal file
27
pkg/gui/types/test.go
Normal file
@ -0,0 +1,27 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
)
|
||||
|
||||
type Test interface {
|
||||
Run(GuiAdapter)
|
||||
SetupConfig(config *config.AppConfig)
|
||||
}
|
||||
|
||||
// this is the interface through which our integration tests interact with the lazygit gui
|
||||
type GuiAdapter interface {
|
||||
PressKey(string)
|
||||
Keys() config.KeybindingConfig
|
||||
CurrentContext() Context
|
||||
Model() *Model
|
||||
Fail(message string)
|
||||
// These two log methods are for the sake of debugging while testing. There's no need to actually
|
||||
// commit any logging.
|
||||
// logs to the normal place that you log to i.e. viewable with `lazygit --logs`
|
||||
Log(message string)
|
||||
// logs in the actual UI (in the commands panel)
|
||||
LogUI(message string)
|
||||
CheckedOutRef() *models.Branch
|
||||
}
|
@ -8,10 +8,6 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
)
|
||||
|
||||
func Headless() bool {
|
||||
return os.Getenv("HEADLESS") != ""
|
||||
}
|
||||
|
||||
// NEW integration test format stuff
|
||||
|
||||
func IntegrationTestName() string {
|
||||
@ -31,17 +27,3 @@ func CurrentIntegrationTest() (types.Test, bool) {
|
||||
return test.Name() == IntegrationTestName()
|
||||
})
|
||||
}
|
||||
|
||||
// OLD integration test format stuff
|
||||
|
||||
func Replaying() bool {
|
||||
return os.Getenv("REPLAY_EVENTS_FROM") != ""
|
||||
}
|
||||
|
||||
func RecordingEvents() bool {
|
||||
return recordEventsTo() != ""
|
||||
}
|
||||
|
||||
func recordEventsTo() string {
|
||||
return os.Getenv("RECORD_EVENTS_TO")
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
type AssertImpl struct {
|
||||
gui integrationTypes.GuiAdapter
|
||||
gui types.GuiAdapter
|
||||
}
|
||||
|
||||
var _ integrationTypes.Assert = &AssertImpl{}
|
||||
|
@ -11,13 +11,13 @@ import (
|
||||
)
|
||||
|
||||
type InputImpl struct {
|
||||
gui integrationTypes.GuiAdapter
|
||||
gui types.GuiAdapter
|
||||
keys config.KeybindingConfig
|
||||
assert integrationTypes.Assert
|
||||
pushKeyDelay int
|
||||
}
|
||||
|
||||
func NewInputImpl(gui integrationTypes.GuiAdapter, keys config.KeybindingConfig, assert integrationTypes.Assert, pushKeyDelay int) *InputImpl {
|
||||
func NewInputImpl(gui types.GuiAdapter, keys config.KeybindingConfig, assert integrationTypes.Assert, pushKeyDelay int) *InputImpl {
|
||||
return &InputImpl{
|
||||
gui: gui,
|
||||
keys: keys,
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
guiTypes "github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
@ -73,9 +74,7 @@ func (self *TestImpl) SetupRepo(shell types.Shell) {
|
||||
}
|
||||
|
||||
// I want access to all contexts, the model, the ability to press a key, the ability to log,
|
||||
func (self *TestImpl) Run(
|
||||
gui types.GuiAdapter,
|
||||
) {
|
||||
func (self *TestImpl) Run(gui guiTypes.GuiAdapter) {
|
||||
shell := &ShellImpl{}
|
||||
assert := &AssertImpl{gui: gui}
|
||||
keys := gui.Keys()
|
||||
|
@ -7,8 +7,9 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"runtime/debug"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/app"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/integration/helpers"
|
||||
"github.com/jesseduffield/lazygit/pkg/integration/integration_tests"
|
||||
@ -20,9 +21,9 @@ import (
|
||||
func RunTestsNew(
|
||||
logf func(format string, formatArgs ...interface{}),
|
||||
runCmd func(cmd *exec.Cmd) error,
|
||||
fnWrapper func(test types.Test, f func(*testing.T) error),
|
||||
fnWrapper func(test types.Test, f func() error),
|
||||
mode Mode,
|
||||
onFail func(t *testing.T, expected string, actual string, prefix string),
|
||||
onFail func(expected string, actual string, prefix string),
|
||||
includeSkipped bool,
|
||||
) error {
|
||||
rootDir := GetRootDirectory()
|
||||
@ -42,7 +43,7 @@ func RunTestsNew(
|
||||
for _, test := range integration_tests.Tests {
|
||||
test := test
|
||||
|
||||
fnWrapper(test, func(t *testing.T) error { //nolint: thelper
|
||||
fnWrapper(test, func() error { //nolint: thelper
|
||||
if test.Skip() && !includeSkipped {
|
||||
logf("skipping test: %s", test.Name())
|
||||
return nil
|
||||
@ -65,12 +66,7 @@ func RunTestsNew(
|
||||
|
||||
configDir := filepath.Join(testPath, "used_config")
|
||||
|
||||
cmd, err := getLazygitCommandNew(test, testPath, rootDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = runCmd(cmd)
|
||||
err = runLazygit(test, testPath, rootDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -120,7 +116,7 @@ func RunTestsNew(
|
||||
}
|
||||
logf("%s", string(bytes))
|
||||
|
||||
onFail(t, expectedRepo, actualRepo, f.Name())
|
||||
onFail(expectedRepo, actualRepo, f.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,9 +150,7 @@ func createFixtureNew(test types.Test, actualDir string, rootDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLazygitCommandNew(test types.Test, testPath string, rootDir string) (*exec.Cmd, error) {
|
||||
osCommand := oscommands.NewDummyOSCommand()
|
||||
|
||||
func runLazygit(test types.Test, testPath string, rootDir string) error {
|
||||
templateConfigDir := filepath.Join(rootDir, "test", "default_test_config")
|
||||
actualRepoDir := filepath.Join(testPath, "actual", "repo")
|
||||
|
||||
@ -164,18 +158,38 @@ func getLazygitCommandNew(test types.Test, testPath string, rootDir string) (*ex
|
||||
|
||||
err := os.RemoveAll(configDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
err = oscommands.CopyDir(templateConfigDir, configDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
cmdStr := fmt.Sprintf("%s -debug --use-config-dir=%s --path=%s %s", tempLazygitPath(), configDir, actualRepoDir, test.ExtraCmdArgs())
|
||||
// TODO: support test.ExtraCmdArgs in some form.
|
||||
cliArgs := &app.CliArgs{
|
||||
Debug: true,
|
||||
UseConfigDir: configDir,
|
||||
RepoPath: actualRepoDir,
|
||||
}
|
||||
|
||||
cmdObj := osCommand.Cmd.New(cmdStr)
|
||||
buildInfo := &app.BuildInfo{
|
||||
Commit: "1234abc",
|
||||
Date: "2020-01-01",
|
||||
Version: "1.0.0",
|
||||
BuildSource: "unknown",
|
||||
}
|
||||
|
||||
cmdObj.AddEnvVars(fmt.Sprintf("LAZYGIT_TEST_NAME=%s", test.Name()))
|
||||
|
||||
return cmdObj.GetCmd(), nil
|
||||
return convertPanicToError(func() { app.Start(cliArgs, buildInfo, test) })
|
||||
}
|
||||
|
||||
func convertPanicToError(f func()) (err error) { //nolint: nakedret
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("Lazygit panicked. Stacktrace:: \n" + string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
|
||||
f()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -1,61 +0,0 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
)
|
||||
|
||||
// this all relates to the old way of doing integration tests where you record yourself
|
||||
// and then replay the events.
|
||||
|
||||
func GetRecordingSpeed() float64 {
|
||||
// humans are slow so this speeds things up.
|
||||
speed := 1.0
|
||||
envReplaySpeed := os.Getenv("SPEED")
|
||||
if envReplaySpeed != "" {
|
||||
var err error
|
||||
speed, err = strconv.ParseFloat(envReplaySpeed, 64)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
return speed
|
||||
}
|
||||
|
||||
func LoadRecording() (*gocui.Recording, error) {
|
||||
path := os.Getenv("REPLAY_EVENTS_FROM")
|
||||
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
recording := &gocui.Recording{}
|
||||
|
||||
err = json.Unmarshal(data, &recording)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return recording, nil
|
||||
}
|
||||
|
||||
func SaveRecording(recording *gocui.Recording) error {
|
||||
if !RecordingEvents() {
|
||||
return nil
|
||||
}
|
||||
|
||||
jsonEvents, err := json.Marshal(recording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path := recordEventsTo()
|
||||
|
||||
return ioutil.WriteFile(path, jsonEvents, 0o600)
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
@ -21,7 +20,7 @@ type Test interface {
|
||||
// so that they appear when lazygit runs
|
||||
SetupConfig(config *config.AppConfig)
|
||||
// this is called upon lazygit starting
|
||||
Run(GuiAdapter)
|
||||
Run(types.GuiAdapter)
|
||||
// e.g. '-debug'
|
||||
ExtraCmdArgs() string
|
||||
// for tests that are flakey and when we don't have time to fix them
|
||||
@ -98,18 +97,3 @@ type Assert interface {
|
||||
// for when you just want to fail the test yourself
|
||||
Fail(errorMessage string)
|
||||
}
|
||||
|
||||
type GuiAdapter interface {
|
||||
PressKey(string)
|
||||
Keys() config.KeybindingConfig
|
||||
CurrentContext() types.Context
|
||||
Model() *types.Model
|
||||
Fail(message string)
|
||||
// These two log methods are for the sake of debugging while testing. There's no need to actually
|
||||
// commit any logging.
|
||||
// logs to the normal place that you log to i.e. viewable with `lazygit --logs`
|
||||
Log(message string)
|
||||
// logs in the actual UI (in the commands panel)
|
||||
LogUI(message string)
|
||||
CheckedOutRef() *models.Branch
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/integration"
|
||||
"github.com/jesseduffield/lazygit/pkg/integration/integration_tests"
|
||||
@ -43,16 +42,16 @@ func main() {
|
||||
err := integration.RunTestsNew(
|
||||
log.Printf,
|
||||
runCmdInTerminal,
|
||||
func(test types.Test, f func(*testing.T) error) {
|
||||
func(test types.Test, f func() error) {
|
||||
if selectedTestName != "" && test.Name() != selectedTestName {
|
||||
return
|
||||
}
|
||||
if err := f(nil); err != nil {
|
||||
if err := f(); err != nil {
|
||||
log.Print(err.Error())
|
||||
}
|
||||
},
|
||||
mode,
|
||||
func(_t *testing.T, expected string, actual string, prefix string) { //nolint:thelper
|
||||
func(expected string, actual string, prefix string) { //nolint:thelper
|
||||
assert.Equal(MockTestingT{}, expected, actual, fmt.Sprintf("Unexpected %s. Expected:\n%s\nActual:\n%s\n", prefix, expected, actual))
|
||||
},
|
||||
includeSkipped,
|
||||
|
Loading…
x
Reference in New Issue
Block a user