1package repository
2
3import (
4 "crypto/sha1"
5 "fmt"
6
7 "github.com/MichaelMure/git-bug/util"
8)
9
10// mockRepoForTest defines an instance of Repo that can be used for testing.
11type mockRepoForTest struct {
12 blobs map[util.Hash][]byte
13 trees map[util.Hash]string
14 commits map[util.Hash]commit
15 refs map[string]util.Hash
16 createClock util.LamportClock
17 editClock util.LamportClock
18}
19
20type commit struct {
21 treeHash util.Hash
22 parent util.Hash
23}
24
25func NewMockRepoForTest() Repo {
26 return &mockRepoForTest{
27 blobs: make(map[util.Hash][]byte),
28 trees: make(map[util.Hash]string),
29 commits: make(map[util.Hash]commit),
30 refs: make(map[string]util.Hash),
31 createClock: util.NewLamportClock(),
32 editClock: util.NewLamportClock(),
33 }
34}
35
36// GetPath returns the path to the repo.
37func (r *mockRepoForTest) GetPath() string {
38 return "~/mockRepo/"
39}
40
41func (r *mockRepoForTest) GetUserName() (string, error) {
42 return "René Descartes", nil
43}
44
45// GetUserEmail returns the email address that the user has used to configure git.
46func (r *mockRepoForTest) GetUserEmail() (string, error) {
47 return "user@example.com", nil
48}
49
50// GetCoreEditor returns the name of the editor that the user has used to configure git.
51func (r *mockRepoForTest) GetCoreEditor() (string, error) {
52 return "vi", nil
53}
54
55// PushRefs push git refs to a remote
56func (r *mockRepoForTest) PushRefs(remote string, refSpec string) (string, error) {
57 return "", nil
58}
59
60func (r *mockRepoForTest) FetchRefs(remote string, refSpec string) (string, error) {
61 return "", nil
62}
63
64func (r *mockRepoForTest) StoreData(data []byte) (util.Hash, error) {
65 rawHash := sha1.Sum(data)
66 hash := util.Hash(fmt.Sprintf("%x", rawHash))
67 r.blobs[hash] = data
68 return hash, nil
69}
70
71func (r *mockRepoForTest) ReadData(hash util.Hash) ([]byte, error) {
72 data, ok := r.blobs[hash]
73
74 if !ok {
75 return nil, fmt.Errorf("unknown hash")
76 }
77
78 return data, nil
79}
80
81func (r *mockRepoForTest) StoreTree(entries []TreeEntry) (util.Hash, error) {
82 buffer := prepareTreeEntries(entries)
83 rawHash := sha1.Sum(buffer.Bytes())
84 hash := util.Hash(fmt.Sprintf("%x", rawHash))
85 r.trees[hash] = buffer.String()
86
87 return hash, nil
88}
89
90func (r *mockRepoForTest) StoreCommit(treeHash util.Hash) (util.Hash, error) {
91 rawHash := sha1.Sum([]byte(treeHash))
92 hash := util.Hash(fmt.Sprintf("%x", rawHash))
93 r.commits[hash] = commit{
94 treeHash: treeHash,
95 }
96 return hash, nil
97}
98
99func (r *mockRepoForTest) StoreCommitWithParent(treeHash util.Hash, parent util.Hash) (util.Hash, error) {
100 rawHash := sha1.Sum([]byte(treeHash + parent))
101 hash := util.Hash(fmt.Sprintf("%x", rawHash))
102 r.commits[hash] = commit{
103 treeHash: treeHash,
104 parent: parent,
105 }
106 return hash, nil
107}
108
109func (r *mockRepoForTest) UpdateRef(ref string, hash util.Hash) error {
110 r.refs[ref] = hash
111 return nil
112}
113
114func (r *mockRepoForTest) RefExist(ref string) (bool, error) {
115 _, exist := r.refs[ref]
116 return exist, nil
117}
118
119func (r *mockRepoForTest) CopyRef(source string, dest string) error {
120 hash, exist := r.refs[source]
121
122 if !exist {
123 return fmt.Errorf("Unknown ref")
124 }
125
126 r.refs[dest] = hash
127 return nil
128}
129
130func (r *mockRepoForTest) ListRefs(refspec string) ([]string, error) {
131 keys := make([]string, len(r.refs))
132
133 i := 0
134 for k := range r.refs {
135 keys[i] = k
136 i++
137 }
138
139 return keys, nil
140}
141
142func (r *mockRepoForTest) ListCommits(ref string) ([]util.Hash, error) {
143 var hashes []util.Hash
144
145 hash := r.refs[ref]
146
147 for {
148 commit, ok := r.commits[hash]
149
150 if !ok {
151 break
152 }
153
154 hashes = append([]util.Hash{hash}, hashes...)
155 hash = commit.parent
156 }
157
158 return hashes, nil
159}
160
161func (r *mockRepoForTest) ListEntries(hash util.Hash) ([]TreeEntry, error) {
162 var data string
163
164 data, ok := r.trees[hash]
165
166 if !ok {
167 // Git will understand a commit hash to reach a tree
168 commit, ok := r.commits[hash]
169
170 if !ok {
171 return nil, fmt.Errorf("unknown hash")
172 }
173
174 data, ok = r.trees[commit.treeHash]
175
176 if !ok {
177 return nil, fmt.Errorf("unknown hash")
178 }
179 }
180
181 return readTreeEntries(data)
182}
183
184func (r *mockRepoForTest) FindCommonAncestor(hash1 util.Hash, hash2 util.Hash) (util.Hash, error) {
185 panic("implement me")
186}
187
188func (r *mockRepoForTest) GetTreeHash(commit util.Hash) (util.Hash, error) {
189 panic("implement me")
190}
191
192func (r *mockRepoForTest) LoadClocks() error {
193 return nil
194}
195
196func (r *mockRepoForTest) WriteClocks() error {
197 return nil
198}
199
200func (r *mockRepoForTest) CreateTimeIncrement() (util.LamportTime, error) {
201 return r.createClock.Increment(), nil
202}
203
204func (r *mockRepoForTest) EditTimeIncrement() (util.LamportTime, error) {
205 return r.editClock.Increment(), nil
206}
207
208func (r *mockRepoForTest) CreateWitness(time util.LamportTime) error {
209 r.createClock.Witness(time)
210 return nil
211}
212
213func (r *mockRepoForTest) EditWitness(time util.LamportTime) error {
214 r.editClock.Witness(time)
215 return nil
216}