-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintegration_test.go
295 lines (270 loc) · 8.8 KB
/
integration_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
package g
import (
"errors"
"fmt"
"os"
"path/filepath"
"testing"
"time"
)
func Test_Integration(t *testing.T) {
// create a working directory
dir, err := os.MkdirTemp("", "")
e(err, t)
defer func() { _ = os.RemoveAll(dir) }()
// add a couple of files
e(os.WriteFile(filepath.Join(dir, "a"), []byte("a"), 0644), t)
e(os.WriteFile(filepath.Join(dir, "b"), []byte("b"), 0644), t)
// configure with dir working directory
e(Configure(WithPath(dir)), t)
// init, creating a .git folder
e(Init(), t)
// commit 'a' to branch 'main'
{
// check branch is main
assertCurrentBranch(t, "main")
// check that file 'a' is recorded as untracked in the current status,
assertStatus(t, map[string]IndexStatus{"a": UntrackedInIndex}, map[string]WDStatus{"a": Untracked})
// add 'a' to the index
assertAddFiles(t, []string{"a"})
// check its status is correct
assertStatus(t, map[string]IndexStatus{"a": AddedInIndex}, map[string]WDStatus{"a": IndexAndWorkingTreeMatch})
// create a commit
commitSha := assertCreateCommit(t, &Commit{
Author: fmt.Sprintf("%s <%s>", "tester", "[email protected]"),
AuthoredTime: time.Now(),
Committer: fmt.Sprintf("%s <%s>", "tester", "[email protected]"),
CommittedTime: time.Now(),
Message: []byte("this is a commit message"),
})
// check branch is still main
assertCurrentBranch(t, "main")
// check current HEAD sha matches the new commit sha
assertCurrentCommit(t, commitSha)
// check last commit message matches the created commit message
assertLookupCommit(t, commitSha, func(t *testing.T, commit *Commit) {
if string(commit.Message) != "this is a commit message\n" {
t.Errorf("expected commit message to be 'this is a commit message'")
}
})
}
// modify 'a',
// commit,
// create a branch 'test',
// switch to branch 'test',
// check file 'b' is still present untracked
{
// modify file a
e(os.WriteFile(filepath.Join(dir, "a"), []byte("aa"), 0644), t)
// add 'a' to the index
assertAddFiles(t, []string{"a"})
// create a commit
commitSha := assertCreateCommit(t, &Commit{
Author: fmt.Sprintf("%s <%s>", "tester", "[email protected]"),
AuthoredTime: time.Now(),
Committer: fmt.Sprintf("%s <%s>", "tester", "[email protected]"),
CommittedTime: time.Now(),
Message: []byte("this is a another commit message"),
})
// check last commit message matches the created commit message
assertLookupCommit(t, commitSha, func(t *testing.T, commit *Commit) {
if string(commit.Message) != "this is a another commit message\n" {
t.Errorf("expected commit message to be 'this is a another commit message'")
}
})
// check 'a' is still correct
assertStatus(t, map[string]IndexStatus{"a": NotUpdated}, map[string]WDStatus{"a": IndexAndWorkingTreeMatch})
// change to a new branch
e(CreateBranch("test"), t)
// switch to the new branch
assertSwitchBranch(t, "test", assertNoErrorFiles)
// check branch is now test
assertCurrentBranch(t, "test")
// check current commit is the last commit sha
assertCurrentCommit(t, commitSha)
// check 'a' is still correct
assertStatus(t, map[string]IndexStatus{"a": NotUpdated}, map[string]WDStatus{"a": IndexAndWorkingTreeMatch})
// check 'b' is still correct
assertStatus(t, map[string]IndexStatus{"b": UntrackedInIndex}, map[string]WDStatus{"b": Untracked})
}
// commit b
// switch to 'main' branch
// check 'b' is no longer in the working directory
{
// add 'b' to the index
assertAddFiles(t, []string{"b"})
// commit
commitSha := assertCreateCommit(t, &Commit{
Author: fmt.Sprintf("%s <%s>", "tester", "[email protected]"),
AuthoredTime: time.Now(),
Committer: fmt.Sprintf("%s <%s>", "tester", "[email protected]"),
CommittedTime: time.Now(),
Message: []byte("this is yet another commit message"),
})
// check commit
assertLookupCommit(t, commitSha, func(t *testing.T, commit *Commit) {
if string(commit.Message) != "this is yet another commit message\n" {
t.Errorf("expected commit message to be 'this is yet another commit message'")
}
})
// check status of 'b'
assertStatus(t, map[string]IndexStatus{"b": NotUpdated}, map[string]WDStatus{"b": IndexAndWorkingTreeMatch})
// switch to the main branch
assertSwitchBranch(t, "main", assertNoErrorFiles)
// check file 'b' is not in the status
assertNotInStatus(t, []string{"b"})
}
// switch back to branch 'test'
// add a new file 'c'
// add 'c' to the index
// switch back to 'main'
// 'c' should still be in the index
{
// switch back to branch 'test'
assertSwitchBranch(t, "test", assertNoErrorFiles)
// create a new file 'c'
e(os.WriteFile(filepath.Join(dir, "c"), []byte("c"), 0644), t)
// check 'c' has the correct status
assertStatus(t, map[string]IndexStatus{"c": UntrackedInIndex}, map[string]WDStatus{"c": Untracked})
// add 'c' to the index
assertAddFiles(t, []string{"c"})
// switch to branch 'main'
assertSwitchBranch(t, "main", assertNoErrorFiles)
// check 'c' has the correct status
assertStatus(t, map[string]IndexStatus{"c": AddedInIndex}, map[string]WDStatus{"c": IndexAndWorkingTreeMatch})
}
// restore --staged a file that is commited, has been modified, added to
// index
// restore a working tree file that is in a previous commit
{
// commit change to 'c'
_ = assertCreateCommit(t, &Commit{
Author: fmt.Sprintf("%s <%s>", "tester", "[email protected]"),
AuthoredTime: time.Now(),
Committer: fmt.Sprintf("%s <%s>", "tester", "[email protected]"),
CommittedTime: time.Now(),
Message: []byte("this is yet another commit message"),
})
// change 'c'
e(os.WriteFile(filepath.Join(dir, "c"), []byte("cc"), 0644), t)
// check status is correct
assertStatus(t, map[string]IndexStatus{"c": NotUpdated}, map[string]WDStatus{"c": WorktreeChangedSinceIndex})
// add to index
assertAddFiles(t, []string{"c"})
// check status
assertStatus(t, map[string]IndexStatus{"c": UpdatedInIndex}, map[string]WDStatus{"c": IndexAndWorkingTreeMatch})
// restore --staged c
assertRestore(t, "c", true)
// check status
assertStatus(t, map[string]IndexStatus{"c": NotUpdated}, map[string]WDStatus{"c": WorktreeChangedSinceIndex})
// git restore c
assertRestore(t, "c", false)
// check status
assertStatus(t, map[string]IndexStatus{"c": NotUpdated}, map[string]WDStatus{"c": IndexAndWorkingTreeMatch})
}
}
func e(err error, t *testing.T) {
t.Helper()
if err != nil {
t.Fatal(err)
}
}
func assertRestore(t *testing.T, path string, staged bool) {
if err := Restore(path, staged); err != nil {
t.Fatal(err)
}
}
func assertLookupCommit(t *testing.T, sha Sha, f func(*testing.T, *Commit)) {
t.Helper()
commit, err := ReadCommit(sha)
e(err, t)
f(t, commit)
}
func assertCurrentCommit(t *testing.T, commitSha Sha) {
t.Helper()
branch, err := CurrentBranch()
e(err, t)
sha, err := HeadSHA(branch)
e(err, t)
if sha.String() != commitSha.String() {
e(fmt.Errorf("expected current commit SHA %s to match SHA %s", sha, commitSha), t)
}
}
func assertCreateCommit(t *testing.T, commit *Commit) Sha {
t.Helper()
commitSha, err := CreateCommit(commit)
e(err, t)
if !commitSha.IsSet() {
e(errors.New("expected commit SHA to be set"), t)
}
return commitSha
}
func assertAddFiles(t *testing.T, filePaths []string) {
t.Helper()
idx, err := ReadIndex()
e(err, t)
fh, err := CurrentStatus()
e(err, t)
for _, v := range filePaths {
f, ok := fh.idx[v]
if !ok {
t.Errorf("file %s not found in index", v)
}
e(idx.addFromWorkTree(f), t)
}
e(idx.Write(), t)
}
func assertCurrentBranch(t *testing.T, expected string) {
t.Helper()
branch, err := CurrentBranch()
e(err, t)
if branch != expected {
t.Errorf("expected branch to be '%s' got '%s'", expected, branch)
}
}
func assertNotInStatus(t *testing.T, filePaths []string) {
t.Helper()
fh, err := CurrentStatus()
e(err, t)
for _, v := range filePaths {
if _, ok := fh.idx[v]; ok {
t.Errorf("file %s was not expected to be in status", v)
}
}
}
var assertNoErrorFiles = func(t *testing.T, paths []string) {
if len(paths) > 0 {
t.Errorf("expected 0 files, got %d", len(paths))
}
}
func assertSwitchBranch(t *testing.T, name string, f func(t *testing.T, fh []string)) {
t.Helper()
errFiles, err := SwitchBranch(name)
if err != nil {
t.Error(err)
}
f(t, errFiles)
}
func assertStatus(t *testing.T, i map[string]IndexStatus, w map[string]WDStatus) {
t.Helper()
fs, err := CurrentStatus()
e(err, t)
for k, v := range i {
f, ok := fs.Contains(k)
if !ok {
t.Fatalf("expected file '%s'", k)
}
if f.idxStatus != v {
t.Errorf("expected file '%s' to have index status '%s' got '%s'", k, v, f.idxStatus)
}
}
for k, v := range w {
f, ok := fs.Contains(k)
if !ok {
t.Fatalf("expected file '%s'", k)
}
if f.wdStatus != v {
t.Errorf("expected file '%s' to have working directory status '%s' got '%s'", k, v, f.wdStatus)
}
}
}