mock_repo.go

  1package repository
  2
  3import (
  4	"crypto/sha1"
  5	"fmt"
  6	"strconv"
  7	"strings"
  8
  9	"github.com/MichaelMure/git-bug/util/git"
 10	"github.com/MichaelMure/git-bug/util/lamport"
 11)
 12
 13var _ ClockedRepo = &mockRepoForTest{}
 14
 15// mockRepoForTest defines an instance of Repo that can be used for testing.
 16type mockRepoForTest struct {
 17	config       map[string]string
 18	globalConfig map[string]string
 19	blobs        map[git.Hash][]byte
 20	trees        map[git.Hash]string
 21	commits      map[git.Hash]commit
 22	refs         map[string]git.Hash
 23	createClock  lamport.Clock
 24	editClock    lamport.Clock
 25}
 26
 27type commit struct {
 28	treeHash git.Hash
 29	parent   git.Hash
 30}
 31
 32func NewMockRepoForTest() *mockRepoForTest {
 33	return &mockRepoForTest{
 34		config:      make(map[string]string),
 35		blobs:       make(map[git.Hash][]byte),
 36		trees:       make(map[git.Hash]string),
 37		commits:     make(map[git.Hash]commit),
 38		refs:        make(map[string]git.Hash),
 39		createClock: lamport.NewClock(),
 40		editClock:   lamport.NewClock(),
 41	}
 42}
 43
 44func (r *mockRepoForTest) LocalConfig() Config {
 45	return newRuntimeConfig(r.config)
 46}
 47
 48func (r *mockRepoForTest) GlobalConfig() Config {
 49	return newRuntimeConfig(r.globalConfig)
 50}
 51
 52// GetPath returns the path to the repo.
 53func (r *mockRepoForTest) GetPath() string {
 54	return "~/mockRepo/"
 55}
 56
 57func (r *mockRepoForTest) GetUserName() (string, error) {
 58	return "René Descartes", nil
 59}
 60
 61// GetUserEmail returns the email address that the user has used to configure git.
 62func (r *mockRepoForTest) GetUserEmail() (string, error) {
 63	return "user@example.com", nil
 64}
 65
 66// GetCoreEditor returns the name of the editor that the user has used to configure git.
 67func (r *mockRepoForTest) GetCoreEditor() (string, error) {
 68	return "vi", nil
 69}
 70
 71// GetRemotes returns the configured remotes repositories.
 72func (r *mockRepoForTest) GetRemotes() (map[string]string, error) {
 73	return map[string]string{
 74		"origin": "git://github.com/MichaelMure/git-bug",
 75	}, nil
 76}
 77
 78func (r *mockRepoForTest) StoreConfig(key string, value string) error {
 79	r.config[key] = value
 80	return nil
 81}
 82
 83func (r *mockRepoForTest) ReadConfigs(keyPrefix string) (map[string]string, error) {
 84	result := make(map[string]string)
 85
 86	for key, val := range r.config {
 87		if strings.HasPrefix(key, keyPrefix) {
 88			result[key] = val
 89		}
 90	}
 91
 92	return result, nil
 93}
 94
 95func (r *mockRepoForTest) ReadConfigBool(key string) (bool, error) {
 96	// unlike git, the mock can only store one value for the same key
 97	val, ok := r.config[key]
 98	if !ok {
 99		return false, ErrNoConfigEntry
100	}
101
102	return strconv.ParseBool(val)
103}
104
105func (r *mockRepoForTest) ReadConfigString(key string) (string, error) {
106	// unlike git, the mock can only store one value for the same key
107	val, ok := r.config[key]
108	if !ok {
109		return "", ErrNoConfigEntry
110	}
111
112	return val, nil
113}
114
115// RmConfigs remove all key/value pair matching the key prefix
116func (r *mockRepoForTest) RmConfigs(keyPrefix string) error {
117	for key := range r.config {
118		if strings.HasPrefix(key, keyPrefix) {
119			delete(r.config, key)
120		}
121	}
122	return nil
123}
124
125// PushRefs push git refs to a remote
126func (r *mockRepoForTest) PushRefs(remote string, refSpec string) (string, error) {
127	return "", nil
128}
129
130func (r *mockRepoForTest) FetchRefs(remote string, refSpec string) (string, error) {
131	return "", nil
132}
133
134func (r *mockRepoForTest) StoreData(data []byte) (git.Hash, error) {
135	rawHash := sha1.Sum(data)
136	hash := git.Hash(fmt.Sprintf("%x", rawHash))
137	r.blobs[hash] = data
138	return hash, nil
139}
140
141func (r *mockRepoForTest) ReadData(hash git.Hash) ([]byte, error) {
142	data, ok := r.blobs[hash]
143
144	if !ok {
145		return nil, fmt.Errorf("unknown hash")
146	}
147
148	return data, nil
149}
150
151func (r *mockRepoForTest) StoreTree(entries []TreeEntry) (git.Hash, error) {
152	buffer := prepareTreeEntries(entries)
153	rawHash := sha1.Sum(buffer.Bytes())
154	hash := git.Hash(fmt.Sprintf("%x", rawHash))
155	r.trees[hash] = buffer.String()
156
157	return hash, nil
158}
159
160func (r *mockRepoForTest) StoreCommit(treeHash git.Hash) (git.Hash, error) {
161	rawHash := sha1.Sum([]byte(treeHash))
162	hash := git.Hash(fmt.Sprintf("%x", rawHash))
163	r.commits[hash] = commit{
164		treeHash: treeHash,
165	}
166	return hash, nil
167}
168
169func (r *mockRepoForTest) StoreCommitWithParent(treeHash git.Hash, parent git.Hash) (git.Hash, error) {
170	rawHash := sha1.Sum([]byte(treeHash + parent))
171	hash := git.Hash(fmt.Sprintf("%x", rawHash))
172	r.commits[hash] = commit{
173		treeHash: treeHash,
174		parent:   parent,
175	}
176	return hash, nil
177}
178
179func (r *mockRepoForTest) UpdateRef(ref string, hash git.Hash) error {
180	r.refs[ref] = hash
181	return nil
182}
183
184func (r *mockRepoForTest) RefExist(ref string) (bool, error) {
185	_, exist := r.refs[ref]
186	return exist, nil
187}
188
189func (r *mockRepoForTest) CopyRef(source string, dest string) error {
190	hash, exist := r.refs[source]
191
192	if !exist {
193		return fmt.Errorf("Unknown ref")
194	}
195
196	r.refs[dest] = hash
197	return nil
198}
199
200func (r *mockRepoForTest) ListRefs(refspec string) ([]string, error) {
201	keys := make([]string, len(r.refs))
202
203	i := 0
204	for k := range r.refs {
205		keys[i] = k
206		i++
207	}
208
209	return keys, nil
210}
211
212func (r *mockRepoForTest) ListCommits(ref string) ([]git.Hash, error) {
213	var hashes []git.Hash
214
215	hash := r.refs[ref]
216
217	for {
218		commit, ok := r.commits[hash]
219
220		if !ok {
221			break
222		}
223
224		hashes = append([]git.Hash{hash}, hashes...)
225		hash = commit.parent
226	}
227
228	return hashes, nil
229}
230
231func (r *mockRepoForTest) ListEntries(hash git.Hash) ([]TreeEntry, error) {
232	var data string
233
234	data, ok := r.trees[hash]
235
236	if !ok {
237		// Git will understand a commit hash to reach a tree
238		commit, ok := r.commits[hash]
239
240		if !ok {
241			return nil, fmt.Errorf("unknown hash")
242		}
243
244		data, ok = r.trees[commit.treeHash]
245
246		if !ok {
247			return nil, fmt.Errorf("unknown hash")
248		}
249	}
250
251	return readTreeEntries(data)
252}
253
254func (r *mockRepoForTest) FindCommonAncestor(hash1 git.Hash, hash2 git.Hash) (git.Hash, error) {
255	panic("implement me")
256}
257
258func (r *mockRepoForTest) GetTreeHash(commit git.Hash) (git.Hash, error) {
259	panic("implement me")
260}
261
262func (r *mockRepoForTest) LoadClocks() error {
263	return nil
264}
265
266func (r *mockRepoForTest) WriteClocks() error {
267	return nil
268}
269
270func (r *mockRepoForTest) CreateTime() lamport.Time {
271	return r.createClock.Time()
272}
273
274func (r *mockRepoForTest) CreateTimeIncrement() (lamport.Time, error) {
275	return r.createClock.Increment(), nil
276}
277
278func (r *mockRepoForTest) EditTime() lamport.Time {
279	return r.editClock.Time()
280}
281
282func (r *mockRepoForTest) EditTimeIncrement() (lamport.Time, error) {
283	return r.editClock.Increment(), nil
284}
285
286func (r *mockRepoForTest) CreateWitness(time lamport.Time) error {
287	r.createClock.Witness(time)
288	return nil
289}
290
291func (r *mockRepoForTest) EditWitness(time lamport.Time) error {
292	r.editClock.Witness(time)
293	return nil
294}