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