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