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