-
Notifications
You must be signed in to change notification settings - Fork 1
/
helpers_test.go
240 lines (204 loc) · 5.54 KB
/
helpers_test.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
package mongo
import (
"fmt"
"os"
"testing"
"time"
"github.com/globalsign/mgo"
"github.com/globalsign/mgo/bson"
)
const (
// Const values to help tests legibility.
idE = "000000000000746573746964"
id1 = "000070726f64756374316964"
id2 = "000070726f64756374326964"
id3 = "000070726f64756374336964"
)
var (
// Helpful vars for testing with database.
fixtures = map[string]*product{
"products.id1": newProductWithID(id1),
"products.id2": newProductWithID(id2),
"products.id3": newProductWithID(id3),
}
colFixtures = "{id1, id2, id3}"
resetDB func() error
)
// fixture returns the i-st element from fixtures.
func fixture(i int) (p *product) {
p = fixtures[fmt.Sprintf("products.id%[1]v", i)]
return
}
// cleanChanges call resetDB ignoring its error.
func cleanChanges() {
_ = resetDB()
}
// PrepareTestMongoAndRun setup test to run with a temporary database
// initialized with fixtures. It also tests Disconnect and Session.
func PrepareTestMongoAndRun(m *testing.M) {
// Prepare clean env
Disconnect()
InitConnecter(NewTestableConnecter("", "testing", fixtures, &resetDB))
_ = Connect()
defer Disconnect()
// Check session
_ = Session()
retCode := m.Run()
defer os.Exit(retCode)
}
// product it's a type embedding the Document struct.
type product struct {
IDV ObjectId `bson:"_id"`
CreatedOnV int64 `bson:"created_on"`
UpdatedOnV int64 `bson:"updated_on"`
}
// newProduct returns a empty product.
func newProduct() (p *product) {
p = &product{}
return
}
// newProductWithID returns a product with ID and CreatedOn defined.
func newProductWithID(id string) (p *product) {
p = &product{
IDV: ObjectIdHex(id),
}
p.CalculateCreatedOn()
return
}
// New creates a new instance of the same product, used on another
// functions for clone purposes.
func (p *product) New() (doc Documenter) {
doc = newProduct()
return
}
// Validate checks for initialization problems on product, and return
// error to be returned in any opration.
func (p *product) Validate() (err error) {
return
}
// Map translates a product to a M object, more easily read by mgo
// methods.
func (p *product) Map() (out M, err error) {
out, err = MapDocumenter(p)
return
}
// Init translates a M received, to the product structure. It
// fills the structure fields with the values of each key in the
// M received.
func (p *product) Init(in M) (err error) {
var doc Documenter = p
err = InitDocumenter(in, &doc)
return
}
// ID returns the _id attribute of a Document.
func (p *product) ID() (id ObjectId) {
id = p.IDV
return
}
// CreatedOn returns the created_on attribute of a Document.
func (p *product) CreatedOn() (t int64) {
t = p.CreatedOnV
return
}
// UpdatedOn returns the updated_on attribute of a Document.
func (p *product) UpdatedOn() (t int64) {
t = p.UpdatedOnV
return
}
// GenerateID creates a new id for a document.
func (p *product) GenerateID() {
p.IDV = NewID()
}
// CalculateCreatedOn update the created_on attribute with a value
// corresponding to actual time.
func (p *product) CalculateCreatedOn() {
p.CreatedOnV = NowInMilli()
}
// CalculateUpdatedOn update the updated_on attribute with a value
// corresponding to actual time.
func (p *product) CalculateUpdatedOn() {
p.UpdatedOnV = NowInMilli()
}
// productHandle it's a type embedding the Handle struct, it's capable
// of storing Products.
type productHandle struct {
*Handle
}
// newProductHandle returns a empty productHandle.
func newProductHandle() (p *productHandle) {
p = &productHandle{
Handle: NewHandle("products", newProduct(), mgo.Index{
Key: []string{"created_on"},
}),
}
return
}
// Safely sets Handler to close after any operation.
func (p *productHandle) Safely() (ph *productHandle) {
p.Handle.Safely()
ph = p
return
}
// Clean documents and search map values, returns Handle for chaining
// purposes.
func (p *productHandle) Clean() (ph *productHandle) {
p.Handle.Clean()
ph = p
return
}
// Find search on connected collection for a document matching data
// stored on productHandle and returns it.
func (p *productHandle) Find() (prod *product, err error) {
var doc Documenter
doc, err = p.Handle.Find()
prod = doc.(*product)
return
}
// FindAll search on connected collection for all documents matching
// data stored on productHandle and returns it. Accept options to alter
// query results.
func (p *productHandle) FindAll(opts ...QueryOptions) (proda []*product, err error) {
var da []Documenter
da, err = p.Handle.FindAll(opts...)
proda = make([]*product, len(da))
for i := range da {
//noinspection GoNilContainerIndexing
proda[i] = da[i].(*product)
}
return
}
// SetDocument sets product on Handle and returns Handle for chaining
// purposes.
func (p *productHandle) SetDocument(d *product) (r *productHandle) {
p.Handle.SetDocument(d)
r = p
return
}
// Document returns the Document of Handle with correct type.
func (p *productHandle) Document() (d *product) {
d = p.Handle.Document().(*product)
return
}
// Set search map value for Handle and returns Handle for chaining
// purposes.
func (p *productHandle) SearchFor(s M) (r *productHandle) {
p.Handle.SearchFor(s)
r = p
return
}
// timeFmt parses time well formatted.
func timeFmt(s string) (t time.Time) {
t, _ = time.Parse("02-01-2006 15:04:05", s)
return
}
// expectedNowInMilli returns expected return from NowInMilli function,
// given the time returned by time.Now().
func expectedNowInMilli(t time.Time) (r int64) {
r = t.UnixNano() / int64(time.Millisecond)
return
}
// resetUtils reset the functions named now and newID.
func resetUtils() {
now = time.Now
newID = bson.NewObjectId
}