1package dag
2
3import (
4 "encoding/json"
5 "fmt"
6 "testing"
7
8 "github.com/stretchr/testify/require"
9
10 "github.com/MichaelMure/git-bug/entity"
11 "github.com/MichaelMure/git-bug/identity"
12 "github.com/MichaelMure/git-bug/repository"
13)
14
15// This file contains an example dummy entity to be used in the tests
16
17/*
18 Operations
19*/
20
21type op1 struct {
22 author identity.Interface
23
24 OperationType int `json:"type"`
25 Field1 string `json:"field_1"`
26 Files []repository.Hash `json:"files"`
27}
28
29func newOp1(author identity.Interface, field1 string, files ...repository.Hash) *op1 {
30 return &op1{author: author, OperationType: 1, Field1: field1, Files: files}
31}
32
33func (o *op1) Id() entity.Id {
34 data, _ := json.Marshal(o)
35 return entity.DeriveId(data)
36}
37
38func (o *op1) Validate() error { return nil }
39
40func (o *op1) Author() identity.Interface {
41 return o.author
42}
43
44func (o *op1) GetFiles() []repository.Hash {
45 return o.Files
46}
47
48type op2 struct {
49 author identity.Interface
50
51 OperationType int `json:"type"`
52 Field2 string `json:"field_2"`
53}
54
55func newOp2(author identity.Interface, field2 string) *op2 {
56 return &op2{author: author, OperationType: 2, Field2: field2}
57}
58
59func (o *op2) Id() entity.Id {
60 data, _ := json.Marshal(o)
61 return entity.DeriveId(data)
62}
63
64func (o *op2) Validate() error { return nil }
65
66func (o *op2) Author() identity.Interface {
67 return o.author
68}
69
70func unmarshaler(author identity.Interface, raw json.RawMessage, resolver identity.Resolver) (Operation, error) {
71 var t struct {
72 OperationType int `json:"type"`
73 }
74
75 if err := json.Unmarshal(raw, &t); err != nil {
76 return nil, err
77 }
78
79 switch t.OperationType {
80 case 1:
81 op := &op1{}
82 err := json.Unmarshal(raw, &op)
83 op.author = author
84 return op, err
85 case 2:
86 op := &op2{}
87 err := json.Unmarshal(raw, &op)
88 op.author = author
89 return op, err
90 default:
91 return nil, fmt.Errorf("unknown operation type %v", t.OperationType)
92 }
93}
94
95/*
96 Identities + repo + definition
97*/
98
99func makeTestContext() (repository.ClockedRepo, identity.Interface, identity.Interface, identity.Resolver, Definition) {
100 repo := repository.NewMockRepo()
101 id1, id2, resolver, def := makeTestContextInternal(repo)
102 return repo, id1, id2, resolver, def
103}
104
105func makeTestContextRemote(t *testing.T) (repository.ClockedRepo, repository.ClockedRepo, repository.ClockedRepo, identity.Interface, identity.Interface, identity.Resolver, Definition) {
106 repoA := repository.CreateGoGitTestRepo(false)
107 repoB := repository.CreateGoGitTestRepo(false)
108 remote := repository.CreateGoGitTestRepo(true)
109
110 err := repoA.AddRemote("remote", remote.GetLocalRemote())
111 require.NoError(t, err)
112 err = repoA.AddRemote("repoB", repoB.GetLocalRemote())
113 require.NoError(t, err)
114 err = repoB.AddRemote("remote", remote.GetLocalRemote())
115 require.NoError(t, err)
116 err = repoB.AddRemote("repoA", repoA.GetLocalRemote())
117 require.NoError(t, err)
118
119 id1, id2, resolver, def := makeTestContextInternal(repoA)
120
121 // distribute the identities
122 _, err = identity.Push(repoA, "remote")
123 require.NoError(t, err)
124 err = identity.Pull(repoB, "remote")
125 require.NoError(t, err)
126
127 return repoA, repoB, remote, id1, id2, resolver, def
128}
129
130func makeTestContextInternal(repo repository.ClockedRepo) (identity.Interface, identity.Interface, identity.Resolver, Definition) {
131 id1, err := identity.NewIdentity(repo, "name1", "email1")
132 if err != nil {
133 panic(err)
134 }
135 err = id1.Commit(repo)
136 if err != nil {
137 panic(err)
138 }
139 id2, err := identity.NewIdentity(repo, "name2", "email2")
140 if err != nil {
141 panic(err)
142 }
143 err = id2.Commit(repo)
144 if err != nil {
145 panic(err)
146 }
147
148 resolver := identityResolverFunc(func(id entity.Id) (identity.Interface, error) {
149 switch id {
150 case id1.Id():
151 return id1, nil
152 case id2.Id():
153 return id2, nil
154 default:
155 return nil, identity.ErrIdentityNotExist
156 }
157 })
158
159 def := Definition{
160 Typename: "foo",
161 Namespace: "foos",
162 OperationUnmarshaler: unmarshaler,
163 FormatVersion: 1,
164 }
165
166 return id1, id2, resolver, def
167}
168
169type identityResolverFunc func(id entity.Id) (identity.Interface, error)
170
171func (fn identityResolverFunc) ResolveIdentity(id entity.Id) (identity.Interface, error) {
172 return fn(id)
173}