-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathiterate.go
137 lines (113 loc) · 2.73 KB
/
iterate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package reltest
import (
"context"
"fmt"
"io"
"reflect"
"github.com/go-rel/rel"
)
type iterate []*MockIterate
func (i *iterate) register(ctxData ctxData, query rel.Query, options ...rel.IteratorOption) *MockIterate {
mi := &MockIterate{
assert: &Assert{ctxData: ctxData, repeatability: 1},
argQuery: query,
argOptions: options,
}
*i = append(*i, mi)
return mi
}
func (i iterate) execute(ctx context.Context, query rel.Query, options ...rel.IteratorOption) rel.Iterator {
for _, mi := range i {
if reflect.DeepEqual(mi.argOptions, options) &&
matchQuery(mi.argQuery, query) &&
mi.assert.call(ctx) {
return mi
}
}
mi := &MockIterate{
assert: &Assert{ctxData: fetchContext(ctx)},
argQuery: query,
argOptions: options,
}
panic(failExecuteMessage(mi, i))
}
func (i *iterate) assert(t TestingT) bool {
t.Helper()
for _, mi := range *i {
if !mi.assert.assert(t, mi) {
return false
}
}
*i = nil
return true
}
type data interface {
Len() int
Get(index int) *rel.Document
}
// MockIterate asserts and simulate Delete function for test.
type MockIterate struct {
assert *Assert
result data
current int
err error
argQuery rel.Query
argOptions []rel.IteratorOption
}
// Result sets the result of preload.
func (mi *MockIterate) Result(result any) *Assert {
rt := reflect.TypeOf(result)
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
if rt.Kind() == reflect.Slice {
mi.result = rel.NewCollection(result, true)
} else {
mi.result = rel.NewDocument(result, true)
}
return mi.assert
}
// Error sets error to be returned.
func (mi *MockIterate) Error(err error) *Assert {
mi.err = err
return mi.assert
}
// ConnectionClosed sets this error to be returned.
func (mi *MockIterate) ConnectionClosed() *Assert {
return mi.Error(ErrConnectionClosed)
}
// Close iterator.
func (mi MockIterate) Close() error {
return nil
}
// Next return next entity in iterator.
func (mi *MockIterate) Next(entity any) error {
if mi.err != nil {
return mi.err
}
if mi.result == nil || mi.current == mi.result.Len() {
return io.EOF
}
var (
doc = mi.result.Get(mi.current)
)
reflect.ValueOf(entity).Elem().Set(doc.ReflectValue())
mi.current++
return nil
}
// String representation of mocked call.
func (mi MockIterate) String() string {
argOptions := ""
for i := range mi.argOptions {
argOptions += fmt.Sprintf(", %v", mi.argOptions[i])
}
return mi.assert.sprintf("Iterate(ctx, %s%s)", mi.argQuery, argOptions)
}
// ExpectString representation of mocked call.
func (mi MockIterate) ExpectString() string {
argOptions := ""
for i := range mi.argOptions {
argOptions += fmt.Sprintf(", %v", mi.argOptions[i])
}
return mi.assert.sprintf("ExpectIterate(%s%s)", mi.argQuery, argOptions)
}