summaryrefslogtreecommitdiff
path: root/stash_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'stash_test.go')
-rw-r--r--stash_test.go198
1 files changed, 198 insertions, 0 deletions
diff --git a/stash_test.go b/stash_test.go
new file mode 100644
index 0000000..180a16b
--- /dev/null
+++ b/stash_test.go
@@ -0,0 +1,198 @@
+package git
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+ "reflect"
+ "runtime"
+ "testing"
+ "time"
+)
+
+func TestStash(t *testing.T) {
+ repo := createTestRepo(t)
+ defer cleanupTestRepo(t, repo)
+
+ prepareStashRepo(t, repo)
+
+ sig := &Signature{
+ Name: "Rand Om Hacker",
+ Email: "[email protected]",
+ When: time.Now(),
+ }
+
+ stash1, err := repo.Stashes.Save(sig, "First stash", StashDefault)
+ checkFatal(t, err)
+
+ _, err = repo.LookupCommit(stash1)
+ checkFatal(t, err)
+
+ b, err := ioutil.ReadFile(pathInRepo(repo, "README"))
+ checkFatal(t, err)
+ if string(b) == "Update README goes to stash\n" {
+ t.Errorf("README still contains the uncommitted changes")
+ }
+
+ if !fileExistsInRepo(repo, "untracked.txt") {
+ t.Errorf("untracked.txt doesn't exist in the repo; should be untracked")
+ }
+
+ // Apply: default
+
+ opts, err := DefaultStashApplyOptions()
+ checkFatal(t, err)
+
+ err = repo.Stashes.Apply(0, opts)
+ checkFatal(t, err)
+
+ b, err = ioutil.ReadFile(pathInRepo(repo, "README"))
+ checkFatal(t, err)
+ if string(b) != "Update README goes to stash\n" {
+ t.Errorf("README changes aren't here")
+ }
+
+ // Apply: no stash for the given index
+
+ err = repo.Stashes.Apply(1, opts)
+ if !IsErrorCode(err, ErrNotFound) {
+ t.Errorf("expecting GIT_ENOTFOUND error code %d, got %v", ErrNotFound, err)
+ }
+
+ // Apply: callback stopped
+
+ opts.ProgressCallback = func(progress StashApplyProgress) error {
+ if progress == StashApplyProgressCheckoutModified {
+ return fmt.Errorf("Stop")
+ }
+ return nil
+ }
+
+ err = repo.Stashes.Apply(0, opts)
+ if err.Error() != "Stop" {
+ t.Errorf("expecting error 'Stop', got %v", err)
+ }
+
+ // Create second stash with ignored files
+
+ os.MkdirAll(pathInRepo(repo, "tmp"), os.ModeDir|os.ModePerm)
+ err = ioutil.WriteFile(pathInRepo(repo, "tmp/ignored.txt"), []byte("Ignore me\n"), 0644)
+ checkFatal(t, err)
+
+ stash2, err := repo.Stashes.Save(sig, "Second stash", StashIncludeIgnored)
+ checkFatal(t, err)
+
+ if fileExistsInRepo(repo, "tmp/ignored.txt") {
+ t.Errorf("tmp/ignored.txt should not exist anymore in the work dir")
+ }
+
+ // Stash foreach
+
+ expected := []stash{
+ {0, "On master: Second stash", stash2.String()},
+ {1, "On master: First stash", stash1.String()},
+ }
+ checkStashes(t, repo, expected)
+
+ // Stash pop
+
+ opts, _ = DefaultStashApplyOptions()
+ err = repo.Stashes.Pop(1, opts)
+ checkFatal(t, err)
+
+ b, err = ioutil.ReadFile(pathInRepo(repo, "README"))
+ checkFatal(t, err)
+ if string(b) != "Update README goes to stash\n" {
+ t.Errorf("README changes aren't here")
+ }
+
+ expected = []stash{
+ {0, "On master: Second stash", stash2.String()},
+ }
+ checkStashes(t, repo, expected)
+
+ // Stash drop
+
+ err = repo.Stashes.Drop(0)
+ checkFatal(t, err)
+
+ expected = []stash{}
+ checkStashes(t, repo, expected)
+}
+
+type stash struct {
+ index int
+ msg string
+ id string
+}
+
+func checkStashes(t *testing.T, repo *Repository, expected []stash) {
+ var actual []stash
+
+ repo.Stashes.Foreach(func(index int, msg string, id *Oid) error {
+ stash := stash{index, msg, id.String()}
+ if len(expected) > len(actual) {
+ if s := expected[len(actual)]; s.id == "" {
+ stash.id = "" // don't check id
+ }
+ }
+ actual = append(actual, stash)
+ return nil
+ })
+
+ if len(expected) > 0 && !reflect.DeepEqual(expected, actual) {
+ // The failure happens at wherever we were called, not here
+ _, file, line, ok := runtime.Caller(1)
+ if !ok {
+ t.Fatalf("Unable to get caller")
+ }
+ t.Errorf("%v:%v: expecting %#v\ngot %#v", path.Base(file), line, expected, actual)
+ }
+}
+
+func prepareStashRepo(t *testing.T, repo *Repository) {
+ seedTestRepo(t, repo)
+
+ err := ioutil.WriteFile(pathInRepo(repo, ".gitignore"), []byte("tmp\n"), 0644)
+ checkFatal(t, err)
+
+ sig := &Signature{
+ Name: "Rand Om Hacker",
+ Email: "[email protected]",
+ When: time.Now(),
+ }
+
+ idx, err := repo.Index()
+ checkFatal(t, err)
+ err = idx.AddByPath(".gitignore")
+ checkFatal(t, err)
+ treeID, err := idx.WriteTree()
+ checkFatal(t, err)
+ err = idx.Write()
+ checkFatal(t, err)
+
+ currentBranch, err := repo.Head()
+ checkFatal(t, err)
+ currentTip, err := repo.LookupCommit(currentBranch.Target())
+ checkFatal(t, err)
+
+ message := "Add .gitignore\n"
+ tree, err := repo.LookupTree(treeID)
+ checkFatal(t, err)
+ _, err = repo.CreateCommit("HEAD", sig, sig, message, tree, currentTip)
+ checkFatal(t, err)
+
+ err = ioutil.WriteFile(pathInRepo(repo, "README"), []byte("Update README goes to stash\n"), 0644)
+ checkFatal(t, err)
+
+ err = ioutil.WriteFile(pathInRepo(repo, "untracked.txt"), []byte("Hello, World\n"), 0644)
+ checkFatal(t, err)
+}
+
+func fileExistsInRepo(repo *Repository, name string) bool {
+ if _, err := os.Stat(pathInRepo(repo, name)); err != nil {
+ return false
+ }
+ return true
+}