mock_repo.go

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