yax-fauna 3.0.1
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.
- checksums.yaml +7 -0
- data/CHANGELOG +51 -0
- data/Gemfile +6 -0
- data/LICENSE +12 -0
- data/README.md +148 -0
- data/Rakefile +13 -0
- data/fauna.gemspec +26 -0
- data/lib/fauna.rb +25 -0
- data/lib/fauna/client.rb +253 -0
- data/lib/fauna/client_logger.rb +52 -0
- data/lib/fauna/context.rb +81 -0
- data/lib/fauna/deprecate.rb +29 -0
- data/lib/fauna/errors.rb +235 -0
- data/lib/fauna/json.rb +99 -0
- data/lib/fauna/objects.rb +147 -0
- data/lib/fauna/page.rb +374 -0
- data/lib/fauna/query.rb +899 -0
- data/lib/fauna/request_result.rb +58 -0
- data/lib/fauna/util.rb +50 -0
- data/lib/fauna/version.rb +4 -0
- data/spec/bytes_spec.rb +36 -0
- data/spec/client_logger_spec.rb +73 -0
- data/spec/client_spec.rb +127 -0
- data/spec/context_spec.rb +84 -0
- data/spec/errors_spec.rb +185 -0
- data/spec/fauna_helper.rb +102 -0
- data/spec/json_spec.rb +161 -0
- data/spec/page_spec.rb +357 -0
- data/spec/query_spec.rb +1104 -0
- data/spec/queryv_spec.rb +25 -0
- data/spec/ref_spec.rb +99 -0
- data/spec/setref_spec.rb +23 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/util_spec.rb +19 -0
- metadata +181 -0
data/spec/query_spec.rb
ADDED
@@ -0,0 +1,1104 @@
|
|
1
|
+
RSpec.describe Fauna::Query do
|
2
|
+
before(:all) do
|
3
|
+
create_test_db
|
4
|
+
@test_class = client.query { create ref('classes'), name: 'query_test' }[:ref]
|
5
|
+
|
6
|
+
index_x = client.query do
|
7
|
+
create ref('indexes'), name: 'query_by_x', source: @test_class, terms: [{ field: %w(data x) }]
|
8
|
+
end
|
9
|
+
index_y = client.query do
|
10
|
+
create ref('indexes'), name: 'query_by_y', source: @test_class, terms: [{ field: %w(data y) }]
|
11
|
+
end
|
12
|
+
|
13
|
+
wait_for_index(index_x[:ref], index_y[:ref])
|
14
|
+
|
15
|
+
@test_by_x = index_x[:ref]
|
16
|
+
@test_by_y = index_y[:ref]
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:all) do
|
20
|
+
destroy_test_db
|
21
|
+
end
|
22
|
+
|
23
|
+
# Alias for creating test class instance with provided data
|
24
|
+
def create_instance(data = {})
|
25
|
+
client.query { create(@test_class, data: data) }
|
26
|
+
end
|
27
|
+
|
28
|
+
# Helper to collect all the contents of a set
|
29
|
+
def get_set_data(set, params = {})
|
30
|
+
data = []
|
31
|
+
|
32
|
+
page = client.query { paginate(set, params) }
|
33
|
+
data += page[:data]
|
34
|
+
while page.key? :after
|
35
|
+
page = client.query { paginate(set, params.merge(after: page[:after])) }
|
36
|
+
data += page[:data]
|
37
|
+
end
|
38
|
+
|
39
|
+
data
|
40
|
+
end
|
41
|
+
|
42
|
+
describe Fauna::Query::Expr do
|
43
|
+
describe '#to_s' do
|
44
|
+
it 'converts to string' do
|
45
|
+
expr = Fauna::Query::Expr.new(
|
46
|
+
add: Fauna::Query::Expr.new(
|
47
|
+
[1, Fauna::Query::Expr.new(divide: Fauna::Query::Expr.new([4, 2]))]
|
48
|
+
)
|
49
|
+
)
|
50
|
+
as_string = 'Expr({:add=>Expr([1, Expr({:divide=>Expr([4, 2])})])})'
|
51
|
+
|
52
|
+
expect(expr.to_s).to eq(as_string)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#==' do
|
57
|
+
it 'equals identical expression' do
|
58
|
+
expr1 = Fauna::Query::Expr.new(add: Fauna::Query::Expr.new([1, 2]))
|
59
|
+
expr2 = Fauna::Query::Expr.new(add: Fauna::Query::Expr.new([1, 2]))
|
60
|
+
|
61
|
+
expect(expr1).to eq(expr2)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'does not equal different expression' do
|
65
|
+
expr1 = Fauna::Query::Expr.new(add: Fauna::Query::Expr.new([1, 2]))
|
66
|
+
expr2 = Fauna::Query::Expr.new(
|
67
|
+
add: Fauna::Query::Expr.new(
|
68
|
+
[1, Fauna::Query::Expr.new(divide: Fauna::Query::Expr.new([4, 2]))]
|
69
|
+
)
|
70
|
+
)
|
71
|
+
|
72
|
+
expect(expr1).not_to eq(expr2)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#expr' do
|
78
|
+
it 'maintains lexical scope' do
|
79
|
+
def test_method
|
80
|
+
'foo'
|
81
|
+
end
|
82
|
+
test_var = 'bar'
|
83
|
+
|
84
|
+
expect(Fauna::Query.expr { test_method }).to eq('foo')
|
85
|
+
expect(Fauna::Query.expr { test_var }).to eq('bar')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'converts proc blocks' do
|
89
|
+
expr = Fauna::Query.expr { proc { |a| add(a, a) } }
|
90
|
+
query = { lambda: :a, expr: { add: [{ var: :a }, { var: :a }] } }
|
91
|
+
|
92
|
+
expect(to_json(expr)).to eq(to_json(query))
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'recursively wraps arrays' do
|
96
|
+
expr = Fauna::Query.expr { [1, { foo: 2 }, add(1, 2)] }
|
97
|
+
query = [1, { object: { foo: 2 } }, { add: [1, 2] }]
|
98
|
+
|
99
|
+
expect(to_json(expr)).to eq(to_json(query))
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'recursively wraps hashes' do
|
103
|
+
expr = Fauna::Query.expr { { x: 1, y: { foo: 2 }, z: add(1, 2), a: [1, 2, { b: 3, c: add(1, 3) }] } }
|
104
|
+
query = { object: { x: 1, y: { object: { foo: 2 } }, z: { add: [1, 2] }, a: [1, 2, { object: { b: 3, c: { add: [1, 3] } } }] } }
|
105
|
+
|
106
|
+
expect(to_json(expr)).to eq(to_json(query))
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'recursively wraps to_h objects' do
|
110
|
+
class ToH
|
111
|
+
def initialize(obj)
|
112
|
+
@obj = obj
|
113
|
+
end
|
114
|
+
|
115
|
+
def to_h
|
116
|
+
@obj
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
expr = Fauna::Query.expr { ToH.new(x: 1, y: ToH.new(foo: 2), z: add(1, 2)) }
|
121
|
+
query = { object: { x: 1, y: { object: { foo: 2 } }, z: { add: [1, 2] } } }
|
122
|
+
|
123
|
+
expect(to_json(expr)).to eq(to_json(query))
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'recursively wraps to_hash objects' do
|
127
|
+
class ToHash
|
128
|
+
def initialize(obj)
|
129
|
+
@obj = obj
|
130
|
+
end
|
131
|
+
|
132
|
+
def to_hash
|
133
|
+
@obj
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
expr = Fauna::Query.expr { ToHash.new(x: 1, y: ToHash.new(foo: 2), z: add(1, 2)) }
|
138
|
+
query = { object: { x: 1, y: { object: { foo: 2 } }, z: { add: [1, 2] } } }
|
139
|
+
|
140
|
+
expect(to_json(expr)).to eq(to_json(query))
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'recursively wraps special types' do
|
144
|
+
expr = Fauna::Query.expr { { x: { y: Time.at(0).utc } } }
|
145
|
+
query = { object: { x: { object: { y: { :@ts => '1970-01-01T00:00:00.000000000Z' } } } } }
|
146
|
+
|
147
|
+
expect(to_json(expr)).to eq(to_json(query))
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'round-trips special types', skip: 'Support for auto-escaping of special types is deferred' do
|
151
|
+
expect(client.query { { '@ref' => 'foo' } }).to eq(:@ref => 'foo')
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'fails on unserializable objects' do
|
155
|
+
obj = DummyClass.new(random_string)
|
156
|
+
|
157
|
+
expect { Fauna::Query.expr { obj } }.to raise_error(Fauna::SerializationError)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '#ref' do
|
162
|
+
it 'returns a ref from a string' do
|
163
|
+
cls = random_string
|
164
|
+
id = random_number.to_s
|
165
|
+
str = "classes/#{cls}/#{id}"
|
166
|
+
expect(client.query { ref(str) }).to eq(Fauna::Ref.new(id, Fauna::Ref.new(cls, Fauna::Native.classes)))
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'constructs a ref' do
|
170
|
+
expect(client.query { ref(@test_class, '123') }).to eq(Fauna::Ref.new('123', @test_class))
|
171
|
+
expect(client.query { ref(@test_class, new_id) }.id).to match(%r{\d+$})
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe '#abort' do
|
176
|
+
it 'aborts the execution' do
|
177
|
+
expect { client.query { abort('message') }}.to raise_error(Fauna::BadRequest)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe '#object' do
|
182
|
+
it 'wraps fields in object' do
|
183
|
+
data = { a: random_string, b: random_number }
|
184
|
+
expect(Fauna::Query.object(data).raw).to eq(object: data)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe '#query' do
|
189
|
+
it 'wraps fields in query' do
|
190
|
+
data = Fauna::Query::Expr.new(lambda: random_string, expr: Fauna::Query::Expr.new(add: Fauna::Query::Expr.wrap([1, 1])))
|
191
|
+
expect(Fauna::Query.query(data).raw).to eq(query: data)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '#at' do
|
196
|
+
it 'performs at for given expression' do
|
197
|
+
instance = create_instance
|
198
|
+
ref = instance[:ref]
|
199
|
+
ts = instance[:ts]
|
200
|
+
|
201
|
+
prev_ts = ts - 1
|
202
|
+
value = random_number
|
203
|
+
client.query { insert(ref, prev_ts, :create, data: { x: value }) }
|
204
|
+
|
205
|
+
expect(client.query { at(prev_ts, get(ref)) }[:data]).to eq(x: value)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe '#let' do
|
210
|
+
it 'performs let with expression' do
|
211
|
+
x = random_number
|
212
|
+
expect(client.query { let({ x: x }, var(:x)) }).to eq(x)
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'performs let with block' do
|
216
|
+
x = random_number
|
217
|
+
expect(client.query { let(x: x) { x } }).to eq(x)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
describe '#var' do
|
222
|
+
it 'creates a var' do
|
223
|
+
name = random_string
|
224
|
+
expect(Fauna::Query.var(name).raw).to eq(var: name)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe '#if_' do
|
229
|
+
it 'performs an if' do
|
230
|
+
expect(client.query { if_(true, 't', 'f') }).to eq('t')
|
231
|
+
expect(client.query { if_(false, 't', 'f') }).to eq('f')
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe '#do_' do
|
236
|
+
it 'performs do' do
|
237
|
+
instance = create_instance
|
238
|
+
expect(client.query { do_(delete(instance[:ref]), 1) }).to eq(1)
|
239
|
+
expect(client.query { exists instance[:ref] }).to be(false)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe '#lambda' do
|
244
|
+
it 'raises when block takes no arguments' do
|
245
|
+
expect { Fauna::Query.lambda {} }.to raise_error(ArgumentError)
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'raises when block takes splat argument' do
|
249
|
+
expect { Fauna::Query.lambda { |*vars| add(vars) } }.to raise_error(ArgumentError)
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'performs lambda from single argument' do
|
253
|
+
expr = Fauna::Query.expr { lambda { |a| add(a, a) } }
|
254
|
+
query = { lambda: :a, expr: { add: [{ var: :a }, { var: :a }] } }
|
255
|
+
|
256
|
+
expect(to_json(expr)).to eq(to_json(query))
|
257
|
+
expect(client.query { map([1, 2, 3], expr) }).to eq([2, 4, 6])
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'performs lambda from multiple arguments' do
|
261
|
+
expr = Fauna::Query.expr { lambda { |a, b| [b, a] } }
|
262
|
+
query = { lambda: [:a, :b], expr: [{ var: :b }, { var: :a }] }
|
263
|
+
|
264
|
+
expect(to_json(expr)).to eq(to_json(query))
|
265
|
+
expect(client.query { map([[1, 2], [3, 4]], expr) }).to eq([[2, 1], [4, 3]])
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
describe '#lambda_expr' do
|
270
|
+
it 'performs lambda from expression' do
|
271
|
+
expr = Fauna::Query.expr { lambda_expr(:a, add(var(:a), var(:a))) }
|
272
|
+
query = { lambda: :a, expr: { add: [{ var: :a }, { var: :a }] } }
|
273
|
+
|
274
|
+
expect(to_json(expr)).to eq(to_json(query))
|
275
|
+
expect(client.query { map([1, 2, 3], expr) }).to eq([2, 4, 6])
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'destructures single element arrays' do
|
279
|
+
expr = Fauna::Query.expr { lambda_expr([:a], add(var(:a), var(:a))) }
|
280
|
+
query = { lambda: [:a], expr: { add: [{ var: :a }, { var: :a }] } }
|
281
|
+
|
282
|
+
expect(to_json(expr)).to eq(to_json(query))
|
283
|
+
expect(client.query { map([[1], [2], [3]], expr) }).to eq([2, 4, 6])
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
describe '#call' do
|
288
|
+
it 'performs called function' do
|
289
|
+
test_func = client.query do
|
290
|
+
func_body = lambda do |x|
|
291
|
+
[add(x, 1), add(x, 2), add(x, 3)]
|
292
|
+
end
|
293
|
+
|
294
|
+
create ref('functions'), name: 'call_func_test', body: query(func_body)
|
295
|
+
end
|
296
|
+
|
297
|
+
x = random_number
|
298
|
+
|
299
|
+
expect(client.query { call(test_func[:ref], x) }).to eq([x + 1, x + 2, x + 3])
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'handles multiple arguments' do
|
303
|
+
test_func = client.query do
|
304
|
+
func_body = lambda do |x, y, z|
|
305
|
+
[multiply(x, 2), multiply(y, 3), multiply(z, 4)]
|
306
|
+
end
|
307
|
+
|
308
|
+
create ref('functions'), name: 'call_multiarg_test', body: query(func_body)
|
309
|
+
end
|
310
|
+
|
311
|
+
x = random_number
|
312
|
+
y = random_number
|
313
|
+
z = random_number
|
314
|
+
|
315
|
+
expect(client.query { call(test_func[:ref], x, y, z) }).to eq([x * 2, y * 3, z * 4])
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe '#map' do
|
320
|
+
it 'performs map from expression' do
|
321
|
+
input = (1..3).collect { random_number }
|
322
|
+
output = input.collect { |x| 2 * x }
|
323
|
+
|
324
|
+
expect(client.query { map(input, lambda { |a| multiply 2, a }) }).to eq(output)
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'performs map from block' do
|
328
|
+
input = (1..3).collect { random_number }
|
329
|
+
output = input.collect { |x| 2 * x }
|
330
|
+
|
331
|
+
expect(client.query { map(input) { |a| multiply 2, a } }).to eq(output)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
describe '#foreach' do
|
336
|
+
before(:each) do
|
337
|
+
@refs = (1..3).collect { create_instance[:ref] }
|
338
|
+
|
339
|
+
# Sanity check
|
340
|
+
expect(client.query { @refs.collect { |ref| exists ref } }).to eq(@refs.collect { true })
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'performs foreach from expression' do
|
344
|
+
client.query { foreach @refs, lambda { |a| delete a } }
|
345
|
+
|
346
|
+
expect(client.query { @refs.collect { |ref| exists ref } }).to eq(@refs.collect { false })
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'performs foreach from block' do
|
350
|
+
client.query { foreach(@refs) { |a| delete a } }
|
351
|
+
|
352
|
+
expect(client.query { @refs.collect { |ref| exists ref } }).to eq(@refs.collect { false })
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
describe '#filter' do
|
357
|
+
it 'performs filter from expression' do
|
358
|
+
expect(client.query { filter([1, 2, 3, 4], lambda { |a| equals modulo(a, 2), 0 }) }).to eq([2, 4])
|
359
|
+
end
|
360
|
+
|
361
|
+
it 'performs filter from block' do
|
362
|
+
expect(client.query { filter([1, 2, 3, 4]) { |a| equals modulo(a, 2), 0 } }).to eq([2, 4])
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
describe '#take' do
|
367
|
+
it 'performs take' do
|
368
|
+
expect(client.query { take(1, [1, 2]) }).to eq([1])
|
369
|
+
expect(client.query { take(3, [1, 2]) }).to eq([1, 2])
|
370
|
+
expect(client.query { take(-1, [1, 2]) }).to eq([])
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
describe '#drop' do
|
375
|
+
it 'performs drop' do
|
376
|
+
expect(client.query { drop(1, [1, 2]) }).to eq([2])
|
377
|
+
expect(client.query { drop(3, [1, 2]) }).to eq([])
|
378
|
+
expect(client.query { drop(-1, [1, 2]) }).to eq([1, 2])
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
describe '#prepend' do
|
383
|
+
it 'performs prepend' do
|
384
|
+
expect(client.query { prepend([1, 2, 3], [4, 5, 6]) }).to eq([1, 2, 3, 4, 5, 6])
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
describe '#append' do
|
389
|
+
it 'performs append' do
|
390
|
+
expect(client.query { append([1, 2, 3], [4, 5, 6]) }).to eq([4, 5, 6, 1, 2, 3])
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
describe '#is_empty' do
|
395
|
+
it 'performs is_empty on collections' do
|
396
|
+
expect(client.query { is_empty([]) }).to be(true)
|
397
|
+
expect(client.query { is_empty([1, 2, 3]) }).to be(false)
|
398
|
+
end
|
399
|
+
|
400
|
+
it 'performs is_empty on pages' do
|
401
|
+
expect(client.query { is_empty(paginate(classes(), size: 0)) }).to be(true)
|
402
|
+
expect(client.query { is_empty(paginate(classes(), size: 1)) }).to be(false)
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
describe '#is_nonempty' do
|
407
|
+
it 'performs is_nonempty on collections' do
|
408
|
+
expect(client.query { is_nonempty([]) }).to be(false)
|
409
|
+
expect(client.query { is_nonempty([1, 2, 3]) }).to be(true)
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'performs is_empty on pages' do
|
413
|
+
expect(client.query { is_nonempty(paginate(classes(), size: 0)) }).to be(false)
|
414
|
+
expect(client.query { is_nonempty(paginate(classes(), size: 1)) }).to be(true)
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
describe '#get' do
|
419
|
+
it 'performs get' do
|
420
|
+
instance = create_instance
|
421
|
+
|
422
|
+
expect(client.query { get instance[:ref] }).to eq(instance)
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
describe '#key_from_secret' do
|
427
|
+
it 'gets key from secret' do
|
428
|
+
# Create a key
|
429
|
+
db_ref = admin_client.query { create(ref('databases'), name: random_string) }[:ref]
|
430
|
+
key = admin_client.query { create_key(database: db_ref, role: 'server') }
|
431
|
+
|
432
|
+
expect(admin_client.query { key_from_secret key[:secret] }).to eq(admin_client.query { get key[:ref] })
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
describe '#paginate' do
|
437
|
+
before do
|
438
|
+
@x_value = random_number
|
439
|
+
@x_refs = (1..3).collect { create_instance(x: @x_value)[:ref] }
|
440
|
+
end
|
441
|
+
|
442
|
+
it 'performs paginate' do
|
443
|
+
set = Fauna::Query.match(@test_by_x, @x_value)
|
444
|
+
|
445
|
+
expect(get_set_data(set, size: 1)).to eq(@x_refs)
|
446
|
+
end
|
447
|
+
|
448
|
+
it 'performs paginate with sources' do
|
449
|
+
response = {
|
450
|
+
data: @x_refs.collect do |ref|
|
451
|
+
{ sources: [Fauna::SetRef.new(match: @test_by_x, terms: @x_value)], value: ref }
|
452
|
+
end
|
453
|
+
}
|
454
|
+
|
455
|
+
expect(client.query { paginate(match(@test_by_x, @x_value), sources: true) }).to eq(response)
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
describe '#exists' do
|
460
|
+
it 'performs exists' do
|
461
|
+
ref = create_instance[:ref]
|
462
|
+
|
463
|
+
expect(client.query { exists ref }).to be(true)
|
464
|
+
client.query { delete ref }
|
465
|
+
expect(client.query { exists ref }).to be(false)
|
466
|
+
|
467
|
+
# Sanity check
|
468
|
+
expect { client.query { get ref } }.to raise_error(Fauna::NotFound)
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
describe '#create' do
|
473
|
+
it 'performs create' do
|
474
|
+
instance = client.query { create(@test_class, {}) }
|
475
|
+
|
476
|
+
expect(instance[:ref].class_).to eq(@test_class)
|
477
|
+
expect(client.query { exists instance[:ref] }).to be(true)
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
describe '#update' do
|
482
|
+
it 'performs update' do
|
483
|
+
x = random_number
|
484
|
+
y = random_number
|
485
|
+
ref = create_instance(x: x)[:ref]
|
486
|
+
|
487
|
+
instance = client.query { update(ref, data: { y: y }) }
|
488
|
+
expect(instance[:data]).to eq(x: x, y: y)
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
describe '#replace' do
|
493
|
+
it 'performs replace' do
|
494
|
+
x = random_number
|
495
|
+
y = random_number
|
496
|
+
ref = create_instance(x: x)[:ref]
|
497
|
+
|
498
|
+
instance = client.query { replace(ref, data: { y: y }) }
|
499
|
+
expect(instance[:data]).to eq(y: y)
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
describe '#delete' do
|
504
|
+
it 'performs delete' do
|
505
|
+
ref = create_instance[:ref]
|
506
|
+
|
507
|
+
client.query { delete ref }
|
508
|
+
expect(client.query { exists ref }).to be(false)
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
describe '#insert' do
|
513
|
+
it 'performs insert' do
|
514
|
+
instance = create_instance
|
515
|
+
ref = instance[:ref]
|
516
|
+
ts = instance[:ts]
|
517
|
+
|
518
|
+
prev_ts = ts - 1
|
519
|
+
value = random_number
|
520
|
+
client.query { insert(ref, prev_ts, :create, data: { x: value }) }
|
521
|
+
|
522
|
+
expect(client.query { get(ref, ts: prev_ts) }[:data]).to eq(x: value)
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
describe '#remove' do
|
527
|
+
it 'performs remove' do
|
528
|
+
# Create the instance
|
529
|
+
instance = create_instance
|
530
|
+
ref = instance[:ref]
|
531
|
+
|
532
|
+
# Change the instance
|
533
|
+
new_instance = client.query { replace(ref, data: { x: random_number }) }
|
534
|
+
expect(client.query { get(ref) }).to eq(new_instance)
|
535
|
+
|
536
|
+
# Delete the event
|
537
|
+
client.query { remove(ref, new_instance[:ts], :create) }
|
538
|
+
|
539
|
+
# Assert it changed
|
540
|
+
expect(client.query { get(ref) }).to eq(instance)
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
describe '#create_class' do
|
545
|
+
it 'creates a class' do
|
546
|
+
# Create a class
|
547
|
+
ref = client.query { create_class(name: random_string) }[:ref]
|
548
|
+
|
549
|
+
# Assert it was created
|
550
|
+
expect(client.query { exists(ref) }).to be(true)
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
describe '#create_index' do
|
555
|
+
it 'creates an index' do
|
556
|
+
# Create an index
|
557
|
+
class_ref = client.query { create(ref('classes'), name: random_string) }[:ref]
|
558
|
+
ref = client.query { create_index(name: random_string, source: class_ref) }[:ref]
|
559
|
+
|
560
|
+
# Assert it was created
|
561
|
+
expect(client.query { exists(ref) }).to be(true)
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
describe '#create_database' do
|
566
|
+
it 'creates a database' do
|
567
|
+
# Create a database
|
568
|
+
ref = admin_client.query { create_database(name: random_string) }[:ref]
|
569
|
+
|
570
|
+
# Assert it was created
|
571
|
+
expect(admin_client.query { exists(ref) }).to be(true)
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
describe '#create_key' do
|
576
|
+
it 'creates a key' do
|
577
|
+
# Create a key
|
578
|
+
db_ref = admin_client.query { create(ref('databases'), name: random_string) }[:ref]
|
579
|
+
ref = admin_client.query { create_key(database: db_ref, role: 'server') }[:ref]
|
580
|
+
|
581
|
+
# Assert it was created
|
582
|
+
expect(admin_client.query { exists(ref) }).to be(true)
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
describe '#create_function' do
|
587
|
+
it 'creates a function' do
|
588
|
+
# Create a function
|
589
|
+
ref = client.query { create_function(name: random_string, body: query(lambda { |a| add(a, 1) })) }[:ref]
|
590
|
+
|
591
|
+
# Assert it was created
|
592
|
+
expect(client.query { exists(ref) }).to be(true)
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
describe 'sets' do
|
597
|
+
before do
|
598
|
+
@x_value = random_number
|
599
|
+
@y_value = random_number
|
600
|
+
|
601
|
+
@ref_x = create_instance(x: @x_value)[:ref]
|
602
|
+
@ref_y = create_instance(y: @y_value)[:ref]
|
603
|
+
@ref_xy = create_instance(x: @x_value, y: @y_value)[:ref]
|
604
|
+
end
|
605
|
+
|
606
|
+
describe '#events' do
|
607
|
+
it 'performs events' do
|
608
|
+
client.query { update @ref_x, data: {x: random_number} }
|
609
|
+
client.query { delete @ref_x }
|
610
|
+
|
611
|
+
events = client.query { paginate events(@ref_x) }[:data]
|
612
|
+
|
613
|
+
expect(events.count).to be(3)
|
614
|
+
|
615
|
+
expect(events[0][:action]).to eq('create')
|
616
|
+
expect(events[0][:instance]).to eq(@ref_x)
|
617
|
+
|
618
|
+
expect(events[1][:action]).to eq('update')
|
619
|
+
expect(events[1][:instance]).to eq(@ref_x)
|
620
|
+
|
621
|
+
expect(events[2][:action]).to eq('delete')
|
622
|
+
expect(events[2][:instance]).to eq(@ref_x)
|
623
|
+
end
|
624
|
+
end
|
625
|
+
|
626
|
+
describe '#singleton' do
|
627
|
+
it 'performs singleton' do
|
628
|
+
client.query { update @ref_x, data: {x: random_number} }
|
629
|
+
client.query { delete @ref_x }
|
630
|
+
|
631
|
+
events = client.query { paginate events(singleton(@ref_x)) }[:data]
|
632
|
+
|
633
|
+
expect(events.count).to be(2)
|
634
|
+
|
635
|
+
expect(events[0][:action]).to eq('add')
|
636
|
+
expect(events[0][:instance]).to eq(@ref_x)
|
637
|
+
|
638
|
+
expect(events[1][:action]).to eq('remove')
|
639
|
+
expect(events[1][:instance]).to eq(@ref_x)
|
640
|
+
end
|
641
|
+
end
|
642
|
+
|
643
|
+
describe '#match' do
|
644
|
+
it 'performs match' do
|
645
|
+
set = Fauna::Query.expr { match(@test_by_x, @x_value) }
|
646
|
+
expect(get_set_data(set)).to contain_exactly(@ref_x, @ref_xy)
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
650
|
+
describe '#union' do
|
651
|
+
it 'performs union' do
|
652
|
+
set = Fauna::Query.expr { union(match(@test_by_x, @x_value), match(@test_by_y, @y_value)) }
|
653
|
+
expect(get_set_data(set)).to contain_exactly(@ref_x, @ref_y, @ref_xy)
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
describe '#intersection' do
|
658
|
+
it 'performs intersection' do
|
659
|
+
set = Fauna::Query.expr { intersection(match(@test_by_x, @x_value), match(@test_by_y, @y_value)) }
|
660
|
+
expect(get_set_data(set)).to contain_exactly(@ref_xy)
|
661
|
+
end
|
662
|
+
end
|
663
|
+
|
664
|
+
describe '#difference' do
|
665
|
+
it 'performs difference' do
|
666
|
+
set = Fauna::Query.expr { difference(match(@test_by_x, @x_value), match(@test_by_y, @y_value)) }
|
667
|
+
expect(get_set_data(set)).to contain_exactly(@ref_x)
|
668
|
+
end
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
describe '#distinct' do
|
673
|
+
before do
|
674
|
+
over_z = client.query do
|
675
|
+
create ref('indexes'), name: 'query_over_z', source: @test_class, values: [{ field: %w(data z) }]
|
676
|
+
end
|
677
|
+
wait_for_index(over_z[:ref])
|
678
|
+
@test_over_z = over_z[:ref]
|
679
|
+
|
680
|
+
@refs = []
|
681
|
+
@refs << client.query { create @test_class, data: { z: 0 } }[:ref]
|
682
|
+
@refs << client.query { create @test_class, data: { z: 1 } }[:ref]
|
683
|
+
@refs << client.query { create @test_class, data: { z: 1 } }[:ref]
|
684
|
+
end
|
685
|
+
|
686
|
+
it 'performs distinct' do
|
687
|
+
set = Fauna::Query.match(@test_over_z)
|
688
|
+
distinct = Fauna::Query.distinct(set)
|
689
|
+
|
690
|
+
expect(get_set_data(set)).to eq([0, 1, 1])
|
691
|
+
expect(get_set_data(distinct)).to eq([0, 1])
|
692
|
+
end
|
693
|
+
end
|
694
|
+
|
695
|
+
describe '#join' do
|
696
|
+
before do
|
697
|
+
@x_value = random_number
|
698
|
+
@join_refs = (1..3).collect { create_instance(x: @x_value)[:ref] }
|
699
|
+
@assoc_refs = @join_refs.collect { |ref| create_instance(y: ref)[:ref] }
|
700
|
+
end
|
701
|
+
|
702
|
+
context 'with expression' do
|
703
|
+
it 'performs join' do
|
704
|
+
source = Fauna::Query.match(@test_by_x, @x_value)
|
705
|
+
expect(get_set_data(source)).to eq(@join_refs)
|
706
|
+
|
707
|
+
# Get associated refs
|
708
|
+
set = Fauna::Query.expr { join(source, lambda { |a| match(@test_by_y, a) }) }
|
709
|
+
expect(get_set_data(set)).to eq(@assoc_refs)
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
713
|
+
context 'with block' do
|
714
|
+
it 'performs join' do
|
715
|
+
source = Fauna::Query.match(@test_by_x, @x_value)
|
716
|
+
expect(get_set_data(source)).to eq(@join_refs)
|
717
|
+
|
718
|
+
# Get associated refs
|
719
|
+
set = Fauna::Query.expr { join(source) { |a| match(@test_by_y, a) } }
|
720
|
+
expect(get_set_data(set)).to eq(@assoc_refs)
|
721
|
+
end
|
722
|
+
end
|
723
|
+
|
724
|
+
context 'with index' do
|
725
|
+
it 'performs join' do
|
726
|
+
source = Fauna::Query.match(@test_by_x, @x_value)
|
727
|
+
expect(get_set_data(source)).to eq(@join_refs)
|
728
|
+
|
729
|
+
# Get associated refs
|
730
|
+
set = Fauna::Query.expr { join(source, @test_by_y) }
|
731
|
+
expect(get_set_data(set)).to eq(@assoc_refs)
|
732
|
+
end
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
describe 'authentication' do
|
737
|
+
before do
|
738
|
+
@password = random_string
|
739
|
+
@user = client.query { create @test_class, credentials: { password: @password } }
|
740
|
+
end
|
741
|
+
|
742
|
+
describe '#login' do
|
743
|
+
it 'performs login' do
|
744
|
+
token = client.query { login @user[:ref], password: @password }
|
745
|
+
user_client = get_client secret: token[:secret]
|
746
|
+
|
747
|
+
self_ = Fauna::Ref.new('self', Fauna::Native.tokens)
|
748
|
+
expect(user_client.query { select(:ref, get(self_)) }).to eq(token[:ref])
|
749
|
+
end
|
750
|
+
end
|
751
|
+
|
752
|
+
describe '#logout' do
|
753
|
+
it 'performs logout' do
|
754
|
+
token = client.query { login @user[:ref], password: @password }
|
755
|
+
user_client = get_client secret: token[:secret]
|
756
|
+
|
757
|
+
expect(user_client.query { logout true }).to be(true)
|
758
|
+
end
|
759
|
+
end
|
760
|
+
|
761
|
+
describe '#identify' do
|
762
|
+
it 'performs identify' do
|
763
|
+
expect(client.query { identify(@user[:ref], @password) }).to be(true)
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
describe '#has_identity' do
|
768
|
+
it 'performs has_identity' do
|
769
|
+
token = client.query { login @user[:ref], password: @password }
|
770
|
+
user_client = get_client secret: token[:secret]
|
771
|
+
|
772
|
+
expect(client.query { has_identity }).to be(false)
|
773
|
+
expect(user_client.query { has_identity }).to be(true)
|
774
|
+
end
|
775
|
+
end
|
776
|
+
|
777
|
+
describe '#identity' do
|
778
|
+
it 'performs identity' do
|
779
|
+
token = client.query { login @user[:ref], password: @password }
|
780
|
+
user_client = get_client secret: token[:secret]
|
781
|
+
|
782
|
+
expect(user_client.query { identity }).to eq(@user[:ref])
|
783
|
+
end
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
describe '#concat' do
|
788
|
+
it 'performs concat' do
|
789
|
+
expect(client.query { concat ['a', 'b', 'c'] }).to eq('abc')
|
790
|
+
expect(client.query { concat [] }).to eq('')
|
791
|
+
end
|
792
|
+
|
793
|
+
it 'performs concat with separator' do
|
794
|
+
expect(client.query { concat(['a', 'b', 'c'], '.') }).to eq('a.b.c')
|
795
|
+
end
|
796
|
+
end
|
797
|
+
|
798
|
+
describe '#casefold' do
|
799
|
+
it 'performs casefold' do
|
800
|
+
expect(client.query { casefold 'Hen Wen' }).to eq('hen wen')
|
801
|
+
|
802
|
+
# https://unicode.org/reports/tr15/
|
803
|
+
expect(client.query { casefold("\u212B", "NFD") } ).to eq("A\u030A")
|
804
|
+
expect(client.query { casefold("\u212B", "NFC") } ).to eq("\u00C5")
|
805
|
+
expect(client.query { casefold("\u1E9B\u0323", "NFKD") } ).to eq("\u0073\u0323\u0307")
|
806
|
+
expect(client.query { casefold("\u1E9B\u0323", "NFKC") } ).to eq("\u1E69")
|
807
|
+
|
808
|
+
expect(client.query { casefold("\u212B", "NFKCCaseFold") } ).to eq("\u00E5")
|
809
|
+
end
|
810
|
+
end
|
811
|
+
|
812
|
+
describe '#ngram' do
|
813
|
+
it 'performs ngram' do
|
814
|
+
expect(client.query { ngram 'what' }).to eq(['w', 'wh', 'h', 'ha', 'a', 'at', 't'])
|
815
|
+
expect(client.query { ngram 'what', min: 2, max: 3 }).to eq(['wh', 'wha', 'ha', 'hat', 'at'])
|
816
|
+
|
817
|
+
expect(client.query { ngram ['john', 'doe'] }).to eq(['j', 'jo', 'o', 'oh', 'h', 'hn', 'n', 'd', 'do', 'o', 'oe', 'e'])
|
818
|
+
expect(client.query { ngram ['john', 'doe'], min: 3, max: 4 }).to eq(['joh', 'john', 'ohn', 'doe'])
|
819
|
+
end
|
820
|
+
end
|
821
|
+
|
822
|
+
describe '#test' do
|
823
|
+
it 'performs time' do
|
824
|
+
# `.round 9` is necessary because MRI 1.9.3 stores with greater precision than just nanoseconds.
|
825
|
+
# This cuts it down to just nanoseconds so that the times compare as equal.
|
826
|
+
time = Time.at(0, 123_456.789).round 9
|
827
|
+
expect(client.query { time '1970-01-01T00:00:00.123456789Z' }).to eq(time)
|
828
|
+
|
829
|
+
# 'now' refers to the current time.
|
830
|
+
expect(client.query { time 'now' }).to be_a(Time)
|
831
|
+
end
|
832
|
+
end
|
833
|
+
|
834
|
+
describe '#epoch' do
|
835
|
+
it 'performs epoch for seconds' do
|
836
|
+
secs = random_number
|
837
|
+
expect(client.query { epoch(secs, 'second') }).to eq(Time.at(secs).utc)
|
838
|
+
end
|
839
|
+
|
840
|
+
it 'performs epoch for nanoseconds' do
|
841
|
+
nanos = random_number
|
842
|
+
expect(client.query { epoch(nanos, 'nanosecond') }).to eq(Time.at(Rational(nanos, 1_000_000_000)).utc)
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
describe '#date' do
|
847
|
+
it 'performs date' do
|
848
|
+
expect(client.query { date('1970-01-01') }).to eq(Date.new(1970, 1, 1))
|
849
|
+
end
|
850
|
+
end
|
851
|
+
|
852
|
+
describe '#new_id' do
|
853
|
+
it 'gets a new id' do
|
854
|
+
expect(client.query { new_id }).to be_a(String)
|
855
|
+
end
|
856
|
+
end
|
857
|
+
|
858
|
+
describe '#database' do
|
859
|
+
it 'gets an existing database' do
|
860
|
+
# Create a database
|
861
|
+
name = random_string
|
862
|
+
ref = admin_client.query { create_database(name: name) }[:ref]
|
863
|
+
|
864
|
+
# Get the database ref
|
865
|
+
expect(admin_client.query { database(name) }).to eq(ref)
|
866
|
+
end
|
867
|
+
end
|
868
|
+
|
869
|
+
describe '#class_' do
|
870
|
+
it 'gets an existing class' do
|
871
|
+
# Create a class
|
872
|
+
name = random_string
|
873
|
+
ref = client.query { create_class(name: name) }[:ref]
|
874
|
+
|
875
|
+
# Get the class ref
|
876
|
+
expect(client.query { class_(name) }).to eq(ref)
|
877
|
+
end
|
878
|
+
end
|
879
|
+
|
880
|
+
describe '#index' do
|
881
|
+
it 'gets an existing index' do
|
882
|
+
# Create an index
|
883
|
+
class_ref = client.query { create_class(name: random_string) }[:ref]
|
884
|
+
name = random_string
|
885
|
+
ref = client.query { create_index(name: name, source: class_ref) }[:ref]
|
886
|
+
|
887
|
+
# Get the index ref
|
888
|
+
expect(client.query { index(name) }).to eq(ref)
|
889
|
+
end
|
890
|
+
end
|
891
|
+
|
892
|
+
describe '#function' do
|
893
|
+
it 'gets an existing function' do
|
894
|
+
# Create a function
|
895
|
+
name = random_string
|
896
|
+
ref = client.query { create_function(name: name, body: query(lambda { |a| add(a, 1) })) }[:ref]
|
897
|
+
|
898
|
+
# Get the function ref
|
899
|
+
expect(client.query { function(name) }).to eq(ref)
|
900
|
+
end
|
901
|
+
end
|
902
|
+
|
903
|
+
describe '#equals' do
|
904
|
+
it 'performs equals' do
|
905
|
+
expect(client.query { equals(1, 1, 1) }).to be(true)
|
906
|
+
expect(client.query { equals(1, 1, 2) }).to be(false)
|
907
|
+
expect(client.query { equals 1 }).to be(true)
|
908
|
+
end
|
909
|
+
end
|
910
|
+
|
911
|
+
describe '#contains' do
|
912
|
+
it 'performs contains' do
|
913
|
+
obj = { a: { b: 1 } }
|
914
|
+
|
915
|
+
expect(client.query { contains([:a, :b], obj) }).to be(true)
|
916
|
+
expect(client.query { contains(:a, obj) }).to be(true)
|
917
|
+
expect(client.query { contains([:a, :c], obj) }).to be(false)
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
describe '#select' do
|
922
|
+
it 'performs select with hash' do
|
923
|
+
obj = { a: { b: 1 } }
|
924
|
+
|
925
|
+
expect(client.query { select(:a, obj) }).to eq(b: 1)
|
926
|
+
expect(client.query { select([:a, :b], obj) }).to eq(1)
|
927
|
+
expect(client.query { select(:c, obj, default: nil) }).to be_nil
|
928
|
+
expect { client.query { select(:c, obj) } }.to raise_error(Fauna::NotFound)
|
929
|
+
end
|
930
|
+
|
931
|
+
it 'performs select with array' do
|
932
|
+
arr = [1, 2, 3]
|
933
|
+
|
934
|
+
expect(client.query { select(2, arr) }).to eq(3)
|
935
|
+
expect { client.query { select(3, arr) } }.to raise_error(Fauna::NotFound)
|
936
|
+
end
|
937
|
+
end
|
938
|
+
|
939
|
+
describe '#select_all' do
|
940
|
+
it 'performs select_all with hash' do
|
941
|
+
obj1 = { foo: 'bar' }
|
942
|
+
obj2 = { foo: 'baz' }
|
943
|
+
|
944
|
+
expect(client.query { select_all(:foo, [obj1, obj2]) }).to eq(['bar', 'baz'])
|
945
|
+
end
|
946
|
+
|
947
|
+
it 'performs select_all with array' do
|
948
|
+
obj1 = { foo: [0, 1] }
|
949
|
+
obj2 = { foo: [2, 3] }
|
950
|
+
|
951
|
+
expect(client.query { select_all([:foo, 0], [obj1, obj2]) }).to eq([0, 2])
|
952
|
+
end
|
953
|
+
end
|
954
|
+
|
955
|
+
describe '#add' do
|
956
|
+
it 'performs add' do
|
957
|
+
expect(client.query { add(2, 3, 5) }).to eq(10)
|
958
|
+
end
|
959
|
+
end
|
960
|
+
|
961
|
+
describe '#multiply' do
|
962
|
+
it 'performs multiply' do
|
963
|
+
expect(client.query { multiply(2, 3, 5) }).to eq(30)
|
964
|
+
end
|
965
|
+
end
|
966
|
+
|
967
|
+
describe '#subtract' do
|
968
|
+
it 'performs subtract' do
|
969
|
+
expect(client.query { subtract(2, 3, 5) }).to eq(-6)
|
970
|
+
expect(client.query { subtract(2) }).to eq(2)
|
971
|
+
end
|
972
|
+
end
|
973
|
+
|
974
|
+
describe '#divide' do
|
975
|
+
it 'performs divide' do
|
976
|
+
expect(client.query { divide(2.0, 3, 5) }).to eq(2.0 / 15)
|
977
|
+
expect(client.query { divide(2) }).to eq(2)
|
978
|
+
end
|
979
|
+
end
|
980
|
+
|
981
|
+
describe '#modulo' do
|
982
|
+
it 'performs modulo' do
|
983
|
+
expect(client.query { modulo(5, 2) }).to eq(1)
|
984
|
+
expect(client.query { modulo(15, 10, 2) }).to eq(1)
|
985
|
+
expect(client.query { modulo(2) }).to eq(2)
|
986
|
+
end
|
987
|
+
end
|
988
|
+
|
989
|
+
describe '#lt' do
|
990
|
+
it 'performs lt' do
|
991
|
+
expect(client.query { lt(1, 2) }).to be(true)
|
992
|
+
expect(client.query { lt(2, 2) }).to be(false)
|
993
|
+
end
|
994
|
+
end
|
995
|
+
|
996
|
+
describe '#lte' do
|
997
|
+
it 'performs lte' do
|
998
|
+
expect(client.query { lte(1, 1) }).to be(true)
|
999
|
+
expect(client.query { lte(2, 1) }).to be(false)
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
describe '#gt' do
|
1004
|
+
it 'performs gt' do
|
1005
|
+
expect(client.query { gt(2, 1) }).to be(true)
|
1006
|
+
expect(client.query { gt(2, 2) }).to be(false)
|
1007
|
+
end
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
describe '#gte' do
|
1011
|
+
it 'performs gte' do
|
1012
|
+
expect(client.query { gte(2, 2) }).to be(true)
|
1013
|
+
expect(client.query { gte(2, 3) }).to be(false)
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
describe '#and_' do
|
1018
|
+
it 'performs and' do
|
1019
|
+
expect(client.query { and_(true, true, false) }).to be(false)
|
1020
|
+
expect(client.query { and_(true, true, true) }).to be(true)
|
1021
|
+
expect(client.query { and_(true) }).to be(true)
|
1022
|
+
expect(client.query { and_(false) }).to be(false)
|
1023
|
+
end
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
describe '#or_' do
|
1027
|
+
it 'performs or' do
|
1028
|
+
expect(client.query { or_(false, false, true) }).to be(true)
|
1029
|
+
expect(client.query { or_(false, false, false) }).to be(false)
|
1030
|
+
expect(client.query { or_(true) }).to be(true)
|
1031
|
+
expect(client.query { or_(false) }).to be(false)
|
1032
|
+
end
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
describe '#not_' do
|
1036
|
+
it 'performs not' do
|
1037
|
+
expect(client.query { not_(true) }).to be(false)
|
1038
|
+
expect(client.query { not_(false) }).to be(true)
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
describe '#to_string' do
|
1043
|
+
it 'performs to_string' do
|
1044
|
+
expect(client.query { to_string(42) }).to eq("42")
|
1045
|
+
end
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
describe '#to_number' do
|
1049
|
+
it 'performs to_number' do
|
1050
|
+
expect(client.query { to_number("42") }).to be(42)
|
1051
|
+
end
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
describe '#to_time' do
|
1055
|
+
it 'performs to_time' do
|
1056
|
+
expect(client.query { to_time("1970-01-01T00:00:00Z") }).to eq(Time.at(0).utc)
|
1057
|
+
end
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
describe '#to_date' do
|
1061
|
+
it 'performs to_date' do
|
1062
|
+
expect(client.query { to_date("1970-01-01") }).to eq(Date.new(1970, 1, 1))
|
1063
|
+
end
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
describe '#recursive references' do
|
1067
|
+
it 'create nested keys' do
|
1068
|
+
new_client = create_new_database(admin_client, 'db-for-keys')
|
1069
|
+
new_client.query { create_database name: 'db-test' }
|
1070
|
+
|
1071
|
+
server_key = new_client.query { create_key database: database('db-test'), role: 'server' }
|
1072
|
+
admin_key = new_client.query { create_key database: database('db-test'), role: 'admin' }
|
1073
|
+
|
1074
|
+
expect(new_client.query { paginate keys() }).to eq(data: [server_key[:ref], admin_key[:ref]])
|
1075
|
+
expect(admin_client.query { paginate keys(database('db-for-keys')) }).to eq(data: [server_key[:ref], admin_key[:ref]])
|
1076
|
+
end
|
1077
|
+
|
1078
|
+
it 'create nested class' do
|
1079
|
+
client1 = create_new_database(admin_client, 'parent-database')
|
1080
|
+
create_new_database(client1, 'child-database')
|
1081
|
+
|
1082
|
+
key = client1.query { create_key database: database('child-database'), role: 'server' }
|
1083
|
+
client2 = get_client secret: key[:secret]
|
1084
|
+
client2.query { create_class name: 'a_class' }
|
1085
|
+
|
1086
|
+
nested_database = Fauna::Query.database('child-database', Fauna::Query.database('parent-database'))
|
1087
|
+
nested_class = Fauna::Query.class_('a_class', nested_database)
|
1088
|
+
all_nested_classes = Fauna::Query.classes(nested_database)
|
1089
|
+
|
1090
|
+
parent_database_ref = Fauna::Ref.new('parent-database', Fauna::Native.databases)
|
1091
|
+
child_database_ref = Fauna::Ref.new('child-database', Fauna::Native.databases, parent_database_ref)
|
1092
|
+
a_class_ref = Fauna::Ref.new('a_class', Fauna::Native.classes, child_database_ref)
|
1093
|
+
|
1094
|
+
expect(client.query { exists nested_class }).to be(true)
|
1095
|
+
expect(client.query { paginate all_nested_classes }).to eq(data: [a_class_ref])
|
1096
|
+
end
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
def create_new_database(client, name)
|
1100
|
+
client.query { create_database name: name }
|
1101
|
+
key = client.query { create_key database: database(name), role: 'admin' }
|
1102
|
+
get_client secret: key[:secret]
|
1103
|
+
end
|
1104
|
+
end
|