summaryrefslogtreecommitdiffstats
path: root/pkg/gui/gui_test.go
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2020-10-04 18:41:33 +1100
committerJesse Duffield <jessedduffield@gmail.com>2020-10-10 00:23:01 +1100
commitf76196937a6d4e5dfe86736ab06f521180a0c7ce (patch)
treebfead5cfd07322b6647aaceae047fc5879c2fd35 /pkg/gui/gui_test.go
parentece93e5eef487f6a8455205c7dbb919ccca43647 (diff)
support integration testing
WIP
Diffstat (limited to 'pkg/gui/gui_test.go')
-rw-r--r--pkg/gui/gui_test.go224
1 files changed, 224 insertions, 0 deletions
diff --git a/pkg/gui/gui_test.go b/pkg/gui/gui_test.go
new file mode 100644
index 000000000..d0a22710a
--- /dev/null
+++ b/pkg/gui/gui_test.go
@@ -0,0 +1,224 @@
+package gui
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+
+ "github.com/go-errors/errors"
+ "github.com/jesseduffield/lazygit/pkg/commands/oscommands"
+ "github.com/stretchr/testify/assert"
+)
+
+// To run an integration test, e.g. for test 'commit', go:
+// go test pkg/gui/gui_test.go -run /commit
+//
+// To record keypresses for an integration test, pass RECORD_EVENTS=true like so:
+// RECORD_EVENTS=true go test pkg/gui/gui_test.go -run /commit
+//
+// To update a snapshot for an integration test, pass UPDATE_SNAPSHOT=true
+// UPDATE_SNAPSHOT=true go test pkg/gui/gui_test.go -run /commit
+//
+// When RECORD_EVENTS is true, updates will be updated automatically
+//
+// integration tests are run in test/integration_test and the final test does
+// not clean up that directory so you can cd into it to see for yourself what
+// happened when a test failed.
+//
+// TODO: support passing an env var for playback speed, given it's currently pretty fast
+
+type integrationTest struct {
+ name string
+ prepare func() error
+}
+
+func generateSnapshot(t *testing.T) string {
+ osCommand := oscommands.NewDummyOSCommand()
+ cmd := `sh -c "git status; cat ./*; git log --pretty=%B -p"`
+
+ snapshot, err := osCommand.RunCommandWithOutput(cmd)
+ assert.NoError(t, err)
+
+ return snapshot
+}
+
+func findOrCreateDir(path string) {
+ _, err := os.Stat(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ err = os.MkdirAll(path, 0777)
+ if err != nil {
+ panic(err)
+ }
+ } else {
+ panic(err)
+ }
+ }
+}
+
+func Test(t *testing.T) {
+ tests := []integrationTest{
+ {
+ name: "commit",
+ prepare: createFixture1,
+ },
+ {
+ name: "squash",
+ prepare: createFixture2,
+ },
+ }
+
+ gotoRootDirectory()
+
+ rootDir, err := os.Getwd()
+ if err != nil {
+ panic(err)
+ }
+
+ for _, test := range tests {
+ test := test
+ t.Run(test.name, func(t *testing.T) {
+ testPath := filepath.Join(rootDir, "test", "integration", test.name)
+ findOrCreateDir(testPath)
+
+ replayPath := filepath.Join(testPath, "recording.json")
+ snapshotPath := filepath.Join(testPath, "snapshot.txt")
+
+ err := os.Chdir(rootDir)
+ assert.NoError(t, err)
+
+ prepareIntegrationTestDir()
+
+ err = test.prepare()
+ assert.NoError(t, err)
+
+ record := os.Getenv("RECORD_EVENTS") != ""
+ runLazygit(t, replayPath, record)
+
+ updateSnapshot := os.Getenv("UPDATE_SNAPSHOT") != ""
+
+ actual := generateSnapshot(t)
+
+ if updateSnapshot {
+ err := ioutil.WriteFile(snapshotPath, []byte(actual), 0600)
+ assert.NoError(t, err)
+ }
+
+ expectedBytes, err := ioutil.ReadFile(snapshotPath)
+ assert.NoError(t, err)
+ expected := string(expectedBytes)
+
+ assert.Equal(t, expected, actual, fmt.Sprintf("expected:\n%s\nactual:\n%s\n", expected, actual))
+ })
+ }
+}
+
+func createFixture1() error {
+ cmds := []string{
+ "git init",
+ `sh -c "echo test > myfile"`,
+ }
+
+ return runCommands(cmds)
+}
+
+func createFixture2() error {
+ cmds := []string{
+ "git init",
+ `sh -c "echo test1 > myfile1"`,
+ `git add .`,
+ `git commit -am "myfile1"`,
+ `sh -c "echo test2 > myfile2"`,
+ `git add .`,
+ `git commit -am "myfile2"`,
+ `sh -c "echo test3 > myfile3"`,
+ `git add .`,
+ `git commit -am "myfile3"`,
+ `sh -c "echo test4 > myfile4"`,
+ `git add .`,
+ `git commit -am "myfile4"`,
+ `sh -c "echo test5 > myfile5"`,
+ `git add .`,
+ `git commit -am "myfile5"`,
+ }
+
+ return runCommands(cmds)
+}
+
+func runCommands(cmds []string) error {
+ osCommand := oscommands.NewDummyOSCommand()
+
+ for _, cmd := range cmds {
+ if err := osCommand.RunCommand(cmd); err != nil {
+ return errors.New(fmt.Sprintf("error running command `%s`: %v", cmd, err))
+ }
+ }
+
+ return nil
+}
+
+func gotoRootDirectory() {
+ for {
+ _, err := os.Stat(".git")
+
+ if err == nil {
+ return
+ }
+
+ if !os.IsNotExist(err) {
+ panic(err)
+ }
+
+ if err = os.Chdir(".."); err != nil {
+ panic(err)
+ }
+ }
+}
+
+func runLazygit(t *testing.T, replayPath string, record bool) {
+ osCommand := oscommands.NewDummyOSCommand()
+
+ var cmd *exec.Cmd
+ if record {
+ cmd = osCommand.ExecutableFromString("lazygit")
+ cmd.Env = append(
+ cmd.Env,
+ fmt.Sprintf("RECORD_EVENTS_TO=%s", replayPath),
+ )
+ } else {
+ cmd = osCommand.ExecutableFromString("lazygit")
+ cmd.Env = append(
+ cmd.Env,
+ fmt.Sprintf("REPLAY_EVENTS_FROM=%s", replayPath),
+ )
+ }
+ err := osCommand.RunExecutable(cmd)
+ assert.NoError(t, err)
+}
+
+func prepareIntegrationTestDir() {
+ path := filepath.Join("test", "integration_test")
+
+ // remove contents of integration test directory
+ dir, err := ioutil.ReadDir(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ err = os.Mkdir(path, 0777)
+ if err != nil {
+ panic(err)
+ }
+ } else {
+ panic(err)
+ }
+ }
+ for _, d := range dir {
+ os.RemoveAll(filepath.Join(path, d.Name()))
+ }
+
+ if err := os.Chdir(path); err != nil {
+ panic(err)
+ }
+}