tarantool 0.2.5 → 0.3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +14 -12
- data/LICENSE +4 -4
- data/README.md +15 -9
- data/Rakefile +5 -129
- data/lib/tarantool/base_record.rb +288 -0
- data/lib/tarantool/block_db.rb +135 -0
- data/lib/tarantool/callback_db.rb +47 -0
- data/lib/tarantool/core-ext.rb +12 -0
- data/lib/tarantool/em_db.rb +37 -0
- data/lib/tarantool/exceptions.rb +52 -7
- data/lib/tarantool/fiber_db.rb +152 -0
- data/lib/tarantool/light_record.rb +68 -0
- data/lib/tarantool/query.rb +127 -0
- data/lib/tarantool/record/select.rb +59 -0
- data/lib/tarantool/record.rb +93 -282
- data/lib/tarantool/request.rb +351 -52
- data/lib/tarantool/response.rb +108 -45
- data/lib/tarantool/serializers/bson.rb +2 -2
- data/lib/tarantool/serializers.rb +32 -4
- data/lib/tarantool/space_array.rb +153 -0
- data/lib/tarantool/space_hash.rb +262 -0
- data/lib/tarantool/util.rb +182 -0
- data/lib/tarantool/version.rb +3 -0
- data/lib/tarantool.rb +79 -29
- data/test/box.pid +1 -0
- data/test/helper.rb +164 -0
- data/test/run_all.rb +3 -0
- data/test/shared_query.rb +73 -0
- data/test/shared_record.rb +474 -0
- data/test/shared_space_array.rb +284 -0
- data/test/shared_space_hash.rb +239 -0
- data/test/tarant/init.lua +22 -0
- data/test/tarantool.cfg +62 -0
- data/test/tarantool.log +6 -0
- data/{spec/tarantool.cfg → test/tarantool_repl.cfg} +11 -5
- data/test/test_light_record.rb +48 -0
- data/test/test_query_block.rb +6 -0
- data/test/test_query_fiber.rb +7 -0
- data/test/test_record.rb +88 -0
- data/{spec/tarantool/composite_primary_key_spec.rb → test/test_record_composite_pk.rb} +5 -7
- data/test/test_space_array_block.rb +6 -0
- data/test/test_space_array_callback.rb +255 -0
- data/test/test_space_array_callback_nodef.rb +190 -0
- data/test/test_space_array_fiber.rb +7 -0
- data/test/test_space_hash_block.rb +6 -0
- data/test/test_space_hash_fiber.rb +7 -0
- metadata +78 -55
- data/Gemfile.lock +0 -54
- data/examples/em_simple.rb +0 -16
- data/examples/record.rb +0 -68
- data/examples/simple.rb +0 -13
- data/lib/tarantool/requests/call.rb +0 -20
- data/lib/tarantool/requests/delete.rb +0 -18
- data/lib/tarantool/requests/insert.rb +0 -19
- data/lib/tarantool/requests/ping.rb +0 -16
- data/lib/tarantool/requests/select.rb +0 -22
- data/lib/tarantool/requests/update.rb +0 -35
- data/lib/tarantool/requests.rb +0 -19
- data/lib/tarantool/serializers/integer.rb +0 -14
- data/lib/tarantool/serializers/string.rb +0 -14
- data/lib/tarantool/space.rb +0 -39
- data/spec/helpers/let.rb +0 -11
- data/spec/helpers/truncate.rb +0 -12
- data/spec/spec_helper.rb +0 -21
- data/spec/tarantool/em_spec.rb +0 -22
- data/spec/tarantool/record_spec.rb +0 -316
- data/spec/tarantool/request_spec.rb +0 -103
- data/tarantool.gemspec +0 -69
@@ -0,0 +1,474 @@
|
|
1
|
+
require File.expand_path('../helper.rb', __FILE__)
|
2
|
+
require 'yajl'
|
3
|
+
require 'tarantool/serializers/bson'
|
4
|
+
|
5
|
+
shared_examples_for :record do
|
6
|
+
DB = Tarantool.new(TCONFIG.merge(type: :block))
|
7
|
+
before{ truncate }
|
8
|
+
|
9
|
+
let(:user_class) do
|
10
|
+
Class.new(base_class) do
|
11
|
+
set_tarantool DB
|
12
|
+
set_space_no 0
|
13
|
+
|
14
|
+
def self.name # For naming
|
15
|
+
"User"
|
16
|
+
end
|
17
|
+
|
18
|
+
field :login, :string
|
19
|
+
field :name, :string
|
20
|
+
field :email, :string
|
21
|
+
field :apples_count, :integer, default: 0
|
22
|
+
index :name, :email
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:second_class) do
|
27
|
+
Class.new(base_class) do
|
28
|
+
set_tarantool DB
|
29
|
+
set_space_no 1
|
30
|
+
|
31
|
+
def self.name # For naming
|
32
|
+
"Second"
|
33
|
+
end
|
34
|
+
|
35
|
+
field :id, :int
|
36
|
+
field :count1, :int
|
37
|
+
field :count2, :int
|
38
|
+
_tail :str, :int
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
let(:user) { user_class.new }
|
43
|
+
|
44
|
+
it "should set and get attributes" do
|
45
|
+
user.name = 'Andrew'
|
46
|
+
user.name.must_equal 'Andrew'
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "inheritance" do
|
50
|
+
let(:author_class) do
|
51
|
+
Class.new(user_class) do
|
52
|
+
field :best_book, Integer
|
53
|
+
end
|
54
|
+
end
|
55
|
+
let(:artist_class) do
|
56
|
+
Class.new(user_class) do
|
57
|
+
field :imdb_id, Integer
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "Artist from User" do
|
62
|
+
it "should has only itself field" do
|
63
|
+
artist_class.fields.keys.must_equal [:login, :name, :email, :apples_count, :imdb_id]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should has same space no as parent" do
|
68
|
+
user_class.space_no = 1
|
69
|
+
artist_class.space_no.must_equal 1
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should has different space no to parent if setted" do
|
73
|
+
artist_class.space_no = 1
|
74
|
+
user_class.space_no.must_equal 0
|
75
|
+
artist_class.space_no.must_equal 1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "save" do
|
80
|
+
it "should save and select record" do
|
81
|
+
u = user_class.new login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
|
82
|
+
u.save
|
83
|
+
u = user_class.find 'prepor'
|
84
|
+
u.id.must_equal 'prepor'
|
85
|
+
u.email.must_equal 'ceo@prepor.ru'
|
86
|
+
u.name.must_equal 'Andrew'
|
87
|
+
u.apples_count.must_equal 0
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should update dirty attributes" do
|
91
|
+
u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
|
92
|
+
u.name = 'Petr'
|
93
|
+
u.save
|
94
|
+
u = user_class.find 'prepor'
|
95
|
+
u.email.must_equal 'ceo@prepor.ru'
|
96
|
+
u.name.must_equal 'Petr'
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "with nils" do
|
100
|
+
before do
|
101
|
+
user_class.field :score, :integer
|
102
|
+
user_class.field :info, Tarantool::Serializers::BSON #:bson
|
103
|
+
end
|
104
|
+
it "should work properly with nils values" do
|
105
|
+
u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru', apples_count: 1
|
106
|
+
u.info.must_be_nil
|
107
|
+
u.score.must_be_nil
|
108
|
+
u.reload
|
109
|
+
u.info.must_be_nil
|
110
|
+
u.score.must_be_nil
|
111
|
+
u.info = {'bio' => 'hi!'}
|
112
|
+
u.score = 1
|
113
|
+
u.save
|
114
|
+
u.reload
|
115
|
+
u.info.must_equal({ 'bio' => 'hi!' })
|
116
|
+
u.score.must_equal 1
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "reload" do
|
122
|
+
it "should reload current record" do
|
123
|
+
u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
|
124
|
+
u.name = 'Petr'
|
125
|
+
u.reload.name.must_equal 'Andrew'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "update" do
|
130
|
+
let(:user) { user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru' }
|
131
|
+
it "should update fields" do
|
132
|
+
user.update(name: "Andrey", email: [":", 0, 3, "prepor"], apples_count: [:+, 7])
|
133
|
+
user.name.must_equal "Andrey"
|
134
|
+
user.email.must_equal "prepor@prepor.ru"
|
135
|
+
user.apples_count.must_equal 7
|
136
|
+
|
137
|
+
user.update(apples_count: [:^, 12])
|
138
|
+
user.apples_count.must_equal 11
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "increment" do
|
142
|
+
it "should increment apples count by 1" do
|
143
|
+
user.increment :apples_count
|
144
|
+
user.apples_count.must_equal 1
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should increment apples count by 3" do
|
148
|
+
user.increment :apples_count, 3
|
149
|
+
user.apples_count.must_equal 3
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "tail" do
|
155
|
+
let(:attrs){ {:id => 100, :count1 => 1, :count2 => 2,
|
156
|
+
:_tail => [['hello', 23], ['world', 42]]} }
|
157
|
+
it "should insert with tail" do
|
158
|
+
obj = second_class.insert(attrs, true)
|
159
|
+
obj.attributes.must_equal attrs
|
160
|
+
second_class.by_pk(100).attributes.must_equal attrs
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should create with tail" do
|
164
|
+
obj = second_class.create(attrs)
|
165
|
+
obj.attributes.must_equal attrs
|
166
|
+
second_class.by_pk(100).attributes.must_equal attrs
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should save tail" do
|
170
|
+
iron_tail = [['i',1],['am',2],['irontail',3]]
|
171
|
+
obj = second_class.create(attrs)
|
172
|
+
obj._tail = iron_tail
|
173
|
+
obj.save
|
174
|
+
obj = second_class.by_pk(100)
|
175
|
+
obj.attributes.must_equal attrs.merge(:_tail => iron_tail)
|
176
|
+
obj._tail.must_equal iron_tail
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "dismissed record" do
|
181
|
+
before {
|
182
|
+
@user = user_class.create login: 'prapor', name: 'Crocos', email: 'focus@poc.us'
|
183
|
+
user_class.delete 'prapor'
|
184
|
+
}
|
185
|
+
|
186
|
+
it "should raise error on save" do
|
187
|
+
proc{
|
188
|
+
@user.apples_count += 1
|
189
|
+
@user.save
|
190
|
+
}.must_raise Tarantool::TupleDoesntExists
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should raise error on update" do
|
194
|
+
proc{
|
195
|
+
@user.update(:apples_count => [:+, 1])
|
196
|
+
}.must_raise Tarantool::TupleDoesntExists
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should raise error on reload" do
|
200
|
+
proc{
|
201
|
+
@user.reload
|
202
|
+
}.must_raise Tarantool::TupleDoesntExists
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe "destroy" do
|
207
|
+
it "should destroy record" do
|
208
|
+
u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
|
209
|
+
u.destroy
|
210
|
+
user_class.find('prepor').must_equal nil
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "select" do
|
215
|
+
describe "by name Andrew" do
|
216
|
+
let(:select) { user_class.where(name: 'Andrew') }
|
217
|
+
before do
|
218
|
+
user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
|
219
|
+
user_class.create login: 'petro', name: 'Petr', email: 'petro@gmail.com'
|
220
|
+
user_class.create login: 'ruden', name: 'Andrew', email: 'rudenkoco@gmail.com'
|
221
|
+
end
|
222
|
+
it "should select all records with name == 'Andrew'" do
|
223
|
+
select.all.map(&:login).must_equal ['prepor', 'ruden']
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should select first record with name == 'Andrew'" do
|
227
|
+
select.first.login.must_equal 'prepor'
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should select 1 record by name and email" do
|
231
|
+
user_class.where(name: 'Andrew', email: 'rudenkoco@gmail.com').map(&:login).must_equal ['ruden']
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should select 2 record by name and email" do
|
235
|
+
user_class.where(name: ['Andrew', 'Andrew'], email: ['ceo@prepor.ru', 'rudenkoco@gmail.com']).map(&:login).must_equal ['prepor', 'ruden']
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should select 3 record by names" do
|
239
|
+
user_class.where(name: ['Andrew', 'Petr']).map(&:login).must_equal ['prepor', 'ruden', 'petro']
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should raise an error for wrong index" do
|
243
|
+
proc{ user_class.where(namee: "Andrew").all }.must_raise Tarantool::ArgumentError
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "with limit 1" do
|
247
|
+
let(:select_limit) { select.limit(1) }
|
248
|
+
it "should select first record with name == 'Andrew'" do
|
249
|
+
select_limit.map(&:login).must_equal ['prepor']
|
250
|
+
end
|
251
|
+
|
252
|
+
describe "with offset 1" do
|
253
|
+
let(:select_offset) { select_limit.offset(1) }
|
254
|
+
it "should select last record with name == 'Andrew'" do
|
255
|
+
select_offset.map(&:login).must_equal ['ruden']
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
describe "==" do
|
262
|
+
before do
|
263
|
+
user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
|
264
|
+
user_class.create login: 'petro', name: 'Petr', email: 'petro@gmail.com'
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should return equality as true" do
|
268
|
+
u1 = user_class.where(login: "prepor").first
|
269
|
+
u2 = user_class.where(login: "prepor").first
|
270
|
+
(u1 == u2).must_equal true
|
271
|
+
end
|
272
|
+
|
273
|
+
it "should not return equality as true" do
|
274
|
+
u1 = user_class.where(login: "prepor")
|
275
|
+
u2 = user_class.where(login: "petro")
|
276
|
+
(u1 == u2).must_equal false
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
describe "call" do
|
282
|
+
let(:res) { user_class.select.call('box.select_range', 0, 2)}
|
283
|
+
|
284
|
+
it "should select 2 records and return UserClass instances" do
|
285
|
+
user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'
|
286
|
+
user_class.create login: 'petro', name: 'Petr', email: 'petro@gmail.com'
|
287
|
+
user_class.create login: 'ruden', name: 'Andrew', email: 'rudenkoco@gmail.com'
|
288
|
+
res.size.must_equal 2
|
289
|
+
res.any? { |v| v.is_a? user_class }
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
describe "light api" do
|
295
|
+
let(:prepor){ {login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru'} }
|
296
|
+
let(:petro){ {login: 'petro', name: 'Petr', email: 'petro@gmail.com'} }
|
297
|
+
let(:ruden){ {login: 'ruden', name: 'Andrew', email: 'rudenkoco@gmail.com'} }
|
298
|
+
before do
|
299
|
+
user_class.create prepor
|
300
|
+
user_class.create petro
|
301
|
+
user_class.create ruden
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should search by_pk" do
|
305
|
+
user_class.by_pk('prepor').email.must_equal 'ceo@prepor.ru'
|
306
|
+
user_class.by_pk(['petro']).email.must_equal 'petro@gmail.com'
|
307
|
+
user_class.by_pk(login: 'ruden').email.must_equal 'rudenkoco@gmail.com'
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should search by_pks" do
|
311
|
+
user_class.by_pks(['prepor', ['petro'], {login: 'ruden'}]).
|
312
|
+
map(&:email).must_equal %w{ceo@prepor.ru petro@gmail.com rudenkoco@gmail.com}
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should find" do
|
316
|
+
user_class.find('prepor').email.must_equal 'ceo@prepor.ru'
|
317
|
+
user_class.find(['petro']).email.must_equal 'petro@gmail.com'
|
318
|
+
user_class.find(login: 'ruden').email.must_equal 'rudenkoco@gmail.com'
|
319
|
+
user_class.find('prepor', ['petro'], {login: 'ruden'}).
|
320
|
+
map(&:email).must_equal %w{ceo@prepor.ru petro@gmail.com rudenkoco@gmail.com}
|
321
|
+
end
|
322
|
+
|
323
|
+
it "should find first" do
|
324
|
+
user_class.first(name: 'Petr', email: 'petro@gmail.com').login.must_equal 'petro'
|
325
|
+
['prepor', 'ruden'].must_include user_class.first(name: 'Andrew').login
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should find all" do
|
329
|
+
user_class.select(name: 'Andrew').map(&:login).sort.must_equal %w{prepor ruden}
|
330
|
+
|
331
|
+
limited = user_class.select({name: 'Andrew'}, limit: 1).map(&:login)
|
332
|
+
limited.size.must_equal 1
|
333
|
+
limited.must_equal limited & %w{prepor ruden}
|
334
|
+
|
335
|
+
offsetted = user_class.all({name: 'Andrew'}, offset: 1).map(&:login)
|
336
|
+
offsetted.size.must_equal 1
|
337
|
+
offsetted.must_equal offsetted & %w{prepor ruden}
|
338
|
+
limited.wont_equal offsetted
|
339
|
+
(limited+offsetted).sort.must_equal %w{prepor ruden}
|
340
|
+
|
341
|
+
user_class.all(name: 'Andrew', email: 'ceo@prepor.ru').map(&:login).must_equal %w{prepor}
|
342
|
+
end
|
343
|
+
|
344
|
+
let(:zuma){ {login: 'zuma', name: 'Zuma', email: 'a@b.c', apples_count: 0} }
|
345
|
+
let(:vova){ {login: 'vova', name: 'Vova', email: 'a@b.c'} }
|
346
|
+
let(:_lila){ {login: 'lila', name: 'lila', email: 'l@i.la', apples_count: 1} }
|
347
|
+
|
348
|
+
it "should insert" do
|
349
|
+
user_class.insert(zuma).must_equal 1
|
350
|
+
proc {
|
351
|
+
user_class.insert(zuma)
|
352
|
+
}.must_raise Tarantool::TupleExists
|
353
|
+
user = user_class.insert(_lila, true)
|
354
|
+
user.must_be_instance_of user_class
|
355
|
+
user.attributes.must_equal _lila
|
356
|
+
user.attributes.wont_be_same_as _lila
|
357
|
+
end
|
358
|
+
|
359
|
+
it "should insert with nil" do
|
360
|
+
second_class.insert(id: 100).must_equal 1
|
361
|
+
obj = second_class.by_pk(100)
|
362
|
+
obj.attributes.must_equal({id: 100, count1: nil, count2: nil})
|
363
|
+
tuple = DB.space(1, [:int, :int, :int], keys: 0).by_pk(100)
|
364
|
+
tuple.must_equal([100, nil, nil])
|
365
|
+
|
366
|
+
second_class.insert(id: 101, count2: 102).must_equal 1
|
367
|
+
obj = second_class.by_pk(101)
|
368
|
+
obj.attributes.must_equal({id: 101, count1: nil, count2: 102})
|
369
|
+
tuple = DB.space(1, [:int, :int, :int], keys: 0).by_pk(101)
|
370
|
+
tuple.must_equal([101, nil, 102])
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should replace" do
|
374
|
+
proc {
|
375
|
+
user_class.replace(vova)
|
376
|
+
}.must_raise Tarantool::TupleDoesntExists
|
377
|
+
|
378
|
+
user_class.replace(ruden.merge(apples_count: 10)).must_equal 1
|
379
|
+
user_class.by_pk('ruden').apples_count.must_equal 10
|
380
|
+
|
381
|
+
user_class.replace(petro.merge(apples_count: 11), true).
|
382
|
+
attributes.must_equal petro.merge(apples_count: 11)
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should update" do
|
386
|
+
user_class.update('ruden', {apples_count: [:+, 2]})
|
387
|
+
user_class.by_pk('ruden').apples_count.must_equal 2
|
388
|
+
|
389
|
+
user_class.update('prepor', {apples_count: [:+, 2]}, true).
|
390
|
+
attributes.must_equal prepor.merge(apples_count: 2)
|
391
|
+
|
392
|
+
user_class.update('fdsaf', {name: 'no'}).must_equal 0
|
393
|
+
user_class.update('fdsaf', {name: 'no'}, true).must_be_nil
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should delete" do
|
397
|
+
user_class.delete(login: 'ruden').must_equal 1
|
398
|
+
user_class.by_pk('ruden').must_be_nil
|
399
|
+
end
|
400
|
+
|
401
|
+
it "should invoke" do
|
402
|
+
user_class.by_pk('ruden').attributes.must_equal ruden.merge(apples_count: 0)
|
403
|
+
user_class.invoke('box.delete', 'ruden').must_equal 1
|
404
|
+
user_class.by_pk('ruden').must_be_nil
|
405
|
+
|
406
|
+
user_class.by_pk('petro').attributes.must_equal petro.merge(apples_count: 0)
|
407
|
+
user_class.invoke('box.delete', user_class.space_no, 'petro', space_no: nil).must_equal 1
|
408
|
+
user_class.by_pk('petro').must_be_nil
|
409
|
+
end
|
410
|
+
|
411
|
+
it "should call" do
|
412
|
+
user_class.by_pk('ruden').attributes.must_equal ruden.merge(apples_count: 0)
|
413
|
+
user_class.call('box.delete', 'ruden')[0].attributes.must_equal ruden.merge(apples_count: 0)
|
414
|
+
user_class.by_pk('ruden').must_be_nil
|
415
|
+
|
416
|
+
user_class.by_pk('petro').attributes.must_equal petro.merge(apples_count: 0)
|
417
|
+
user_class.call('box.delete', user_class.space_no, 'petro', space_no: nil)[0].
|
418
|
+
attributes.must_equal petro.merge(apples_count: 0)
|
419
|
+
user_class.by_pk('petro').must_be_nil
|
420
|
+
end
|
421
|
+
|
422
|
+
it "should call with custom returns" do
|
423
|
+
v = user_class.call('box.delete', 'ruden', returns: [:str, :str, :str, :int])
|
424
|
+
v.must_equal [ruden.values + [0]]
|
425
|
+
v = user_class.call('box.delete', 'prepor', returns: {a: :str, b: :str, c: :str, d: :int})
|
426
|
+
v.must_equal [{a: 'prepor', b: 'Andrew', c: 'ceo@prepor.ru', d: 0}]
|
427
|
+
end
|
428
|
+
|
429
|
+
describe "auto_space" do
|
430
|
+
let(:auto_space){ user_class.auto_space }
|
431
|
+
it "should return records on search" do
|
432
|
+
p = auto_space.by_pk('prepor')
|
433
|
+
p.must_be_instance_of user_class
|
434
|
+
p.attributes.must_equal prepor.merge(apples_count: 0)
|
435
|
+
|
436
|
+
p = auto_space.all_by_pks(['petro', {login: 'prepor'}])
|
437
|
+
p[0].must_be_instance_of user_class
|
438
|
+
p[1].must_be_instance_of user_class
|
439
|
+
p.map(&:email).sort.must_equal %w[ceo@prepor.ru petro@gmail.com]
|
440
|
+
|
441
|
+
p = auto_space.select({name: 'Andrew', email: 'rudenkoco@gmail.com'}, 0, 1)
|
442
|
+
p[0].must_be_instance_of user_class
|
443
|
+
p[0].attributes.must_equal ruden.merge(apples_count: 0)
|
444
|
+
|
445
|
+
p = auto_space.call('box.select_range', [0, 1000])
|
446
|
+
p.each{|o| o.must_be_instance_of user_class}
|
447
|
+
p.map(&:login).sort.must_equal %w{petro prepor ruden}
|
448
|
+
|
449
|
+
p = auto_space.insert({name: 'a', login: 'b', email: 'r', apples_count: 100}, return_tuple: true)
|
450
|
+
p.must_be_instance_of user_class
|
451
|
+
p.name.must_equal 'a'
|
452
|
+
p.login.must_equal 'b'
|
453
|
+
p.email.must_equal 'r'
|
454
|
+
p.apples_count.must_equal 100
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
describe "fields serializers" do
|
460
|
+
before do
|
461
|
+
user_class.field :info, :bson
|
462
|
+
end
|
463
|
+
|
464
|
+
it "should serialise and deserialize info field" do
|
465
|
+
info = { 'bio' => "hi!", 'age' => 23, 'hobbies' => ['mufa', 'tuka'] }
|
466
|
+
u = user_class.create login: 'prepor', name: 'Andrew', email: 'ceo@prepor.ru', info: info
|
467
|
+
u.info['hobbies'].must_equal ['mufa', 'tuka']
|
468
|
+
u.reload
|
469
|
+
u.info['hobbies'].must_equal ['mufa', 'tuka']
|
470
|
+
u = user_class.find u.login
|
471
|
+
u.info['hobbies'].must_equal ['mufa', 'tuka']
|
472
|
+
end
|
473
|
+
end
|
474
|
+
end
|