1package repository
2
3import (
4 "crypto/sha1"
5 "fmt"
6 "github.com/MichaelMure/git-bug/util"
7 "github.com/pkg/errors"
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}
17
18type commit struct {
19 treeHash util.Hash
20 parent util.Hash
21}
22
23func NewMockRepoForTest() Repo {
24 return &mockRepoForTest{
25 blobs: make(map[util.Hash][]byte),
26 trees: make(map[util.Hash]string),
27 commits: make(map[util.Hash]commit),
28 refs: make(map[string]util.Hash),
29 }
30}
31
32// GetPath returns the path to the repo.
33func (r *mockRepoForTest) GetPath() string {
34 return "~/mockRepo/"
35}
36
37func (r *mockRepoForTest) GetUserName() (string, error) {
38 return "René Descartes", nil
39}
40
41// GetUserEmail returns the email address that the user has used to configure git.
42func (r *mockRepoForTest) GetUserEmail() (string, error) {
43 return "user@example.com", nil
44}
45
46// GetCoreEditor returns the name of the editor that the user has used to configure git.
47func (r *mockRepoForTest) GetCoreEditor() (string, error) {
48 return "vi", nil
49}
50
51// PushRefs push git refs to a remote
52func (r *mockRepoForTest) PushRefs(remote string, refPattern string) error {
53 return nil
54}
55
56func (r *mockRepoForTest) PullRefs(remote string, refPattern string, remoteRefPattern string) error {
57 return nil
58}
59
60func (r *mockRepoForTest) StoreData(data []byte) (util.Hash, error) {
61 rawHash := sha1.Sum(data)
62 hash := util.Hash(fmt.Sprintf("%x", rawHash))
63 r.blobs[hash] = data
64 return hash, nil
65}
66
67func (r *mockRepoForTest) ReadData(hash util.Hash) ([]byte, error) {
68 data, ok := r.blobs[hash]
69
70 if !ok {
71 return nil, errors.New("unknown hash")
72 }
73
74 return data, nil
75}
76
77func (r *mockRepoForTest) StoreTree(entries []TreeEntry) (util.Hash, error) {
78 buffer := prepareTreeEntries(entries)
79 rawHash := sha1.Sum(buffer.Bytes())
80 hash := util.Hash(fmt.Sprintf("%x", rawHash))
81 r.trees[hash] = buffer.String()
82
83 return hash, nil
84}
85
86func (r *mockRepoForTest) StoreCommit(treeHash util.Hash) (util.Hash, error) {
87 rawHash := sha1.Sum([]byte(treeHash))
88 hash := util.Hash(fmt.Sprintf("%x", rawHash))
89 r.commits[hash] = commit{
90 treeHash: treeHash,
91 }
92 return hash, nil
93}
94
95func (r *mockRepoForTest) StoreCommitWithParent(treeHash util.Hash, parent util.Hash) (util.Hash, error) {
96 rawHash := sha1.Sum([]byte(treeHash + parent))
97 hash := util.Hash(fmt.Sprintf("%x", rawHash))
98 r.commits[hash] = commit{
99 treeHash: treeHash,
100 parent: parent,
101 }
102 return hash, nil
103}
104
105func (r *mockRepoForTest) UpdateRef(ref string, hash util.Hash) error {
106 r.refs[ref] = hash
107 return nil
108}
109
110func (r *mockRepoForTest) ListRefs(refspec string) ([]string, error) {
111 keys := make([]string, len(r.refs))
112
113 i := 0
114 for k := range r.refs {
115 keys[i] = k
116 i++
117 }
118
119 return keys, nil
120}
121
122func (r *mockRepoForTest) ListCommits(ref string) ([]util.Hash, error) {
123 var hashes []util.Hash
124
125 hash := r.refs[ref]
126
127 for {
128 commit, ok := r.commits[hash]
129
130 if !ok {
131 break
132 }
133
134 hashes = append([]util.Hash{hash}, hashes...)
135 hash = commit.parent
136 }
137
138 return hashes, nil
139}
140
141func (r *mockRepoForTest) ListEntries(hash util.Hash) ([]TreeEntry, error) {
142 var data string
143
144 data, ok := r.trees[hash]
145
146 if !ok {
147 // Git will understand a commit hash to reach a tree
148 commit, ok := r.commits[hash]
149
150 if !ok {
151 return nil, errors.New("unknown hash")
152 }
153
154 data, ok = r.trees[commit.treeHash]
155
156 if !ok {
157 return nil, errors.New("unknown hash")
158 }
159 }
160
161 return readTreeEntries(data)
162}