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
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'fauna'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
FAUNA_ROOT_KEY = ENV['FAUNA_ROOT_KEY']
|
5
|
+
FAUNA_DOMAIN = ENV['FAUNA_DOMAIN']
|
6
|
+
FAUNA_SCHEME = ENV['FAUNA_SCHEME']
|
7
|
+
FAUNA_PORT = ENV['FAUNA_PORT']
|
8
|
+
|
9
|
+
module FaunaTestHelpers
|
10
|
+
def get_client(params = {})
|
11
|
+
params = { domain: FAUNA_DOMAIN, scheme: FAUNA_SCHEME, port: FAUNA_PORT }.merge(params)
|
12
|
+
fail 'No secret provided' unless params.key? :secret
|
13
|
+
Fauna::Client.new params
|
14
|
+
end
|
15
|
+
|
16
|
+
def root_client
|
17
|
+
fail 'FAUNA_ROOT_KEY must be defined in your environment to run tests' unless FAUNA_ROOT_KEY
|
18
|
+
get_client secret: FAUNA_ROOT_KEY
|
19
|
+
end
|
20
|
+
|
21
|
+
def client
|
22
|
+
fail 'Server client not initialized' if @server_client.nil?
|
23
|
+
@server_client
|
24
|
+
end
|
25
|
+
|
26
|
+
def admin_client
|
27
|
+
fail 'Admin client not initialized' if @admin_client.nil?
|
28
|
+
@admin_client
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_test_db
|
32
|
+
@db_ref = Fauna::Ref.new("faunadb-ruby-test-#{random_string}", Fauna::Native.databases)
|
33
|
+
|
34
|
+
root = root_client
|
35
|
+
root.query { create ref('databases'), name: @db_ref.id }
|
36
|
+
|
37
|
+
begin
|
38
|
+
server_key = root.query { create ref('keys'), database: @db_ref, role: 'server' }
|
39
|
+
admin_key = root.query { create ref('keys'), database: @db_ref, role: 'admin' }
|
40
|
+
rescue
|
41
|
+
root.query { delete @db_ref }
|
42
|
+
@db_ref = nil
|
43
|
+
raise
|
44
|
+
end
|
45
|
+
|
46
|
+
@server_secret = server_key[:secret]
|
47
|
+
@server_client = get_client secret: @server_secret
|
48
|
+
@admin_secret = admin_key[:secret]
|
49
|
+
@admin_client = get_client secret: @admin_secret
|
50
|
+
end
|
51
|
+
|
52
|
+
def destroy_test_db
|
53
|
+
root_client.query { delete @db_ref } unless @db_ref.nil?
|
54
|
+
end
|
55
|
+
|
56
|
+
def stub_client(method, url, response = nil, headers = {})
|
57
|
+
stubs = Faraday::Adapter::Test::Stubs.new
|
58
|
+
stubs.send(method, url) do |env|
|
59
|
+
if response.nil?
|
60
|
+
[200, headers, { resource: { method: env.method.to_s.upcase, body: JSON.load(env.body) } }.to_json]
|
61
|
+
else
|
62
|
+
[200, headers, response]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
Fauna::Client.new(adapter: [:test, stubs])
|
66
|
+
end
|
67
|
+
|
68
|
+
def random_string
|
69
|
+
SecureRandom.hex(7)
|
70
|
+
end
|
71
|
+
|
72
|
+
def random_number
|
73
|
+
SecureRandom.random_number(1_000_000)
|
74
|
+
end
|
75
|
+
|
76
|
+
def random_bytes
|
77
|
+
SecureRandom.random_bytes(20)
|
78
|
+
end
|
79
|
+
|
80
|
+
def random_ref_string
|
81
|
+
"classes/#{random_string}/#{random_number}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_json(value)
|
85
|
+
Fauna::FaunaJson.to_json(value)
|
86
|
+
end
|
87
|
+
|
88
|
+
def from_json(value)
|
89
|
+
Fauna::FaunaJson.json_load(value)
|
90
|
+
end
|
91
|
+
|
92
|
+
def wait_for_index(*refs)
|
93
|
+
sleep 1 until client.query { map(refs) { |ref| select([:active], get(ref)) } }.all? { |active| active }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Shared classes
|
98
|
+
class DummyClass
|
99
|
+
def initialize(value)
|
100
|
+
@value = value
|
101
|
+
end
|
102
|
+
end
|
data/spec/json_spec.rb
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
RSpec.describe Fauna::FaunaJson do
|
2
|
+
describe '#deserialize' do
|
3
|
+
it 'deserializes ref' do
|
4
|
+
ref = random_ref_string
|
5
|
+
|
6
|
+
data = { :@ref => { id: ref } }
|
7
|
+
obj = Fauna::Ref.new(ref)
|
8
|
+
|
9
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'deserializes set' do
|
13
|
+
ref = random_ref_string
|
14
|
+
terms = random_string
|
15
|
+
|
16
|
+
data = { :@set => { match: { :@ref => { id: ref } }, terms: terms } }
|
17
|
+
obj = Fauna::SetRef.new(match: Fauna::Ref.new(ref), terms: terms)
|
18
|
+
|
19
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'deserializes query' do
|
23
|
+
query = { lambda: 'a', expr: { add: [{ var: 'a' }, 1] } }
|
24
|
+
obj = Fauna::QueryV.new(query)
|
25
|
+
|
26
|
+
expect(Fauna::FaunaJson.deserialize(:@query => query)).to eq(obj)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'deserializes obj' do
|
30
|
+
obj = { a: random_string, b: random_string }
|
31
|
+
data = { :@obj => obj }
|
32
|
+
|
33
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'deserializes ts' do
|
37
|
+
data = { :@ts => '1970-01-01T00:00:00.000000000Z' }
|
38
|
+
obj = Time.at(0).utc
|
39
|
+
|
40
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'deserializes date' do
|
44
|
+
data = { :@date => '1970-01-01' }
|
45
|
+
obj = Date.new(1970, 1, 1)
|
46
|
+
|
47
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'deserializes bytes' do
|
51
|
+
raw = random_bytes
|
52
|
+
|
53
|
+
data = { :@bytes => Base64.urlsafe_encode64(raw) }
|
54
|
+
obj = Fauna::Bytes.new(raw)
|
55
|
+
|
56
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'recursively deserializes hashes' do
|
60
|
+
ref = random_ref_string
|
61
|
+
|
62
|
+
data = { test: { :@obj => { :@ref => { id: ref } } } }
|
63
|
+
obj = { test: Fauna::Ref.new(ref) }
|
64
|
+
|
65
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'recursively deserializes arrays' do
|
69
|
+
ref1 = random_ref_string
|
70
|
+
ref2 = random_ref_string
|
71
|
+
|
72
|
+
data = [{ :@ref => { id: ref1 } }, { :@ref => { id: ref2 } }]
|
73
|
+
obj = [Fauna::Ref.new(ref1), Fauna::Ref.new(ref2)]
|
74
|
+
|
75
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#to_json' do
|
80
|
+
it 'serializes ref' do
|
81
|
+
ref = random_ref_string
|
82
|
+
|
83
|
+
data = { :@ref => { id: ref } }
|
84
|
+
obj = Fauna::Ref.new(ref)
|
85
|
+
|
86
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'serializes set' do
|
90
|
+
ref = random_ref_string
|
91
|
+
|
92
|
+
data = { :@ref => { id: ref } }
|
93
|
+
obj = Fauna::Ref.new(ref)
|
94
|
+
|
95
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'serializes query' do
|
99
|
+
query = { lambda: 'a', expr: { add: [{ var: 'a' }, 1] } }
|
100
|
+
obj = Fauna::QueryV.new(query)
|
101
|
+
|
102
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(:@query => query)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'serializes expr' do
|
106
|
+
data = { a: random_string, b: random_number }
|
107
|
+
obj = Fauna::Query::Expr.new(data)
|
108
|
+
|
109
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'serializes time' do
|
113
|
+
data = { :@ts => '1970-01-01T00:00:00.000000000Z' }
|
114
|
+
obj = Time.at(0).utc
|
115
|
+
|
116
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'serializes date' do
|
120
|
+
data = { :@date => '1970-01-01' }
|
121
|
+
obj = Date.new(1970, 1, 1)
|
122
|
+
|
123
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'serializes bytes' do
|
127
|
+
raw = random_bytes
|
128
|
+
|
129
|
+
data = { :@bytes => Base64.urlsafe_encode64(raw) }
|
130
|
+
obj = Fauna::Bytes.new(raw)
|
131
|
+
|
132
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'recursively serializes hashes' do
|
136
|
+
ref = random_ref_string
|
137
|
+
terms = random_string
|
138
|
+
|
139
|
+
data = { a: { time: { :@ts => '1970-01-01T00:00:00.000000000Z' } }, b: { :@set => { match: { :@ref => { id: ref } }, terms: terms } } }
|
140
|
+
obj = { a: { time: Time.at(0).utc }, b: Fauna::SetRef.new(match: Fauna::Ref.new(ref), terms: terms) }
|
141
|
+
|
142
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'recursively serializes arrays' do
|
146
|
+
ref1 = random_ref_string
|
147
|
+
ref2 = random_ref_string
|
148
|
+
|
149
|
+
data = [{ :@ref => { id: ref1 } }, { :@ref => { id: ref2 } }]
|
150
|
+
obj = [Fauna::Ref.new(ref1), Fauna::Ref.new(ref2)]
|
151
|
+
|
152
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'fails on unserializable objects' do
|
156
|
+
obj = DummyClass.new(random_string)
|
157
|
+
|
158
|
+
expect { Fauna::FaunaJson.serialize(obj) }.to raise_error(Fauna::SerializationError)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
data/spec/page_spec.rb
ADDED
@@ -0,0 +1,357 @@
|
|
1
|
+
RSpec.describe Fauna::Page do
|
2
|
+
before(:all) do
|
3
|
+
create_test_db
|
4
|
+
@test_class = client.query { create ref('classes'), name: 'page_test' }[:ref]
|
5
|
+
@foreach_class = client.query { create ref('classes'), name: 'page_foreach' }[:ref]
|
6
|
+
|
7
|
+
index_refs = client.query { create ref('indexes'), name: 'page_refs', source: @test_class }
|
8
|
+
index_values = client.query { create ref('indexes'), name: 'page_values', source: @test_class, values: [{ field: %w(data value) }] }
|
9
|
+
index_foreach = client.query { create ref('indexes'), name: 'page_apply', source: @foreach_class }
|
10
|
+
|
11
|
+
wait_for_index(index_refs[:ref], index_values[:ref], index_foreach[:ref])
|
12
|
+
|
13
|
+
@refs_index = index_refs[:ref]
|
14
|
+
@values_index = index_values[:ref]
|
15
|
+
@foreach_index = index_foreach[:ref]
|
16
|
+
|
17
|
+
@instances = client.query { (1..6).collect { |x| create(@test_class, data: { value: x }) } }.sort_by { |inst| inst[:ref].id }
|
18
|
+
@instance_refs = @instances.collect { |instance| instance[:ref] }
|
19
|
+
@instance_values = @instances.collect { |instance| instance[:data][:value] }.sort
|
20
|
+
|
21
|
+
@refs_match = Fauna::Query.match(@refs_index)
|
22
|
+
@values_match = Fauna::Query.match(@values_index)
|
23
|
+
@foreach_match = Fauna::Query.match(@foreach_index)
|
24
|
+
end
|
25
|
+
|
26
|
+
after(:all) do
|
27
|
+
destroy_test_db
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#==' do
|
31
|
+
it 'equals identical page' do
|
32
|
+
page1 = Fauna::Page.new(client, @refs_match, size: 1)
|
33
|
+
page2 = Fauna::Page.new(client, @refs_match, size: 1)
|
34
|
+
|
35
|
+
expect(page1).to eq(page2)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'does not equal different page' do
|
39
|
+
page1 = Fauna::Page.new(client, @refs_match, size: 1234)
|
40
|
+
page2 = Fauna::Page.new(client, @refs_match, size: 4321)
|
41
|
+
|
42
|
+
expect(page1).not_to eq(page2)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'can\'t mutate params directly' do
|
47
|
+
page = client.paginate(@refs_match)
|
48
|
+
|
49
|
+
expect { page.params[:ts] = random_number }.to raise_error(RuntimeError, 'can\'t modify frozen Hash')
|
50
|
+
|
51
|
+
page = page.with_params(ts: random_number)
|
52
|
+
|
53
|
+
expect { page.params[:ts] = random_number }.to raise_error(RuntimeError, 'can\'t modify frozen Hash')
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'builders' do
|
57
|
+
def get_funcs(page)
|
58
|
+
page.instance_variable_get(:@fauna_funcs)
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_postprocessing(page)
|
62
|
+
page.instance_variable_get(:@postprocessing_map)
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#with_params' do
|
66
|
+
let(:ref1) { random_ref_string }
|
67
|
+
let(:ref2) { random_ref_string }
|
68
|
+
|
69
|
+
it 'sets params on copy' do
|
70
|
+
ts1 = random_number
|
71
|
+
ts2 = random_number
|
72
|
+
|
73
|
+
page = client.paginate(@refs_match, ts: ts1)
|
74
|
+
|
75
|
+
expect(page.with_params(ts: ts2, sources: false).params).to eq(ts: ts2, sources: false)
|
76
|
+
expect(page.params).to eq(ts: ts1)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'reverses cursor' do
|
80
|
+
page = client.paginate(@refs_match, before: ref1)
|
81
|
+
|
82
|
+
expect(page.with_params(after: ref2).params).to eq(after: ref2)
|
83
|
+
expect(page.params).to eq(before: ref1)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'preserves nil' do
|
87
|
+
page = client.paginate(@refs_match, after: nil)
|
88
|
+
|
89
|
+
expect(page.with_params(before: nil).params).to eq(before: nil)
|
90
|
+
expect(page.params).to eq(after: nil)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'resets paging' do
|
94
|
+
page = client.paginate(@refs_match, size: 1)
|
95
|
+
page1 = page.page_after
|
96
|
+
|
97
|
+
page2 = page1.with_params(after: 0).page_after
|
98
|
+
|
99
|
+
expect(page2.data).to eq(page2.data)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#map' do
|
104
|
+
it 'sets map on copy' do
|
105
|
+
page = client.paginate(@refs_match)
|
106
|
+
|
107
|
+
expect(get_funcs(page.map { |ref| get ref }).length).to be(1)
|
108
|
+
expect(get_funcs(page).length).to be(0)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'performs map when paging' do
|
112
|
+
page = client.paginate(@refs_match).map { |ref| get ref }
|
113
|
+
|
114
|
+
expect(page.all).to eq(@instances)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#filter' do
|
119
|
+
it 'sets filter on copy' do
|
120
|
+
page = client.paginate(@values_match)
|
121
|
+
|
122
|
+
expect(get_funcs(page.filter { |value| equals(modulo(value, 2), 0) }).length).to be(1)
|
123
|
+
expect(get_funcs(page).length).to be(0)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'performs filter when paging' do
|
127
|
+
page = client.paginate(@values_match).filter { |value| equals(modulo(value, 2), 0) }
|
128
|
+
|
129
|
+
expect(page.all).to eq(@instance_values.find_all(&:even?))
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe '#postprocessing_map' do
|
134
|
+
it 'sets ruby map on copy' do
|
135
|
+
page = client.paginate(@refs_match)
|
136
|
+
|
137
|
+
expect(get_postprocessing(page.postprocessing_map(&:id))).to be_a(Proc)
|
138
|
+
expect(get_postprocessing(page)).to be_nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#load!' do
|
144
|
+
it 'explicitly loads page' do
|
145
|
+
page = client.paginate(@refs_match, size: 1, after: @instance_refs[1])
|
146
|
+
expected = [@instance_refs[1]]
|
147
|
+
|
148
|
+
expect(page.instance_variable_get(:@data)).to be_nil
|
149
|
+
page.load!
|
150
|
+
expect(page.instance_variable_get(:@data)).to eq(expected)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'returns true when page was loaded' do
|
154
|
+
page = client.paginate(@refs_match, size: 1, after: @instance_refs[1])
|
155
|
+
|
156
|
+
expect(page.instance_variable_get(:@populated)).to be(false)
|
157
|
+
expect(page.load!).to be(true)
|
158
|
+
expect(page.instance_variable_get(:@populated)).to be(true)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'returns false when page not loaded' do
|
162
|
+
page = client.paginate(@refs_match, size: 1, after: @instance_refs[1])
|
163
|
+
|
164
|
+
page.load!
|
165
|
+
expect(page.instance_variable_get(:@populated)).to be(true)
|
166
|
+
expect(page.load!).to be(false)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe '#data' do
|
171
|
+
it 'lazily loads page' do
|
172
|
+
page = client.paginate(@refs_match, size: 1, after: @instance_refs[1])
|
173
|
+
expected = [@instance_refs[1]]
|
174
|
+
|
175
|
+
expect(page.instance_variable_get(:@data)).to be_nil
|
176
|
+
expect(page.data).to eq(expected)
|
177
|
+
expect(page.instance_variable_get(:@data)).to eq(expected)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe '#before' do
|
182
|
+
it 'lazily loads page' do
|
183
|
+
page = client.paginate(@refs_match, size: 1, after: @instance_refs[1])
|
184
|
+
expected = [@instance_refs[1]]
|
185
|
+
|
186
|
+
expect(page.instance_variable_get(:@before)).to be_nil
|
187
|
+
expect(page.before).to eq(expected)
|
188
|
+
expect(page.instance_variable_get(:@before)).to eq(expected)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe '#after' do
|
193
|
+
it 'lazily loads page' do
|
194
|
+
page = client.paginate(@refs_match, size: 1, after: @instance_refs[1])
|
195
|
+
expected = [@instance_refs[2]]
|
196
|
+
|
197
|
+
expect(page.instance_variable_get(:@after)).to be_nil
|
198
|
+
expect(page.after).to eq(expected)
|
199
|
+
expect(page.instance_variable_get(:@after)).to eq(expected)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe '#page_after' do
|
204
|
+
it 'returns the page after' do
|
205
|
+
page = client.paginate(@refs_match, size: 1, after: 0)
|
206
|
+
|
207
|
+
@instance_refs.drop(1).each do |ref|
|
208
|
+
page = page.page_after
|
209
|
+
expect(page.data.first).to eq(ref)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'returns nil on last page' do
|
214
|
+
page = client.paginate(@refs_match, size: 1, after: @instance_refs.last)
|
215
|
+
|
216
|
+
expect(page.data.first).to eq(@instance_refs.last)
|
217
|
+
expect(page.page_after).to be_nil
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'is not affected by lazy loading' do
|
221
|
+
page = client.paginate(@refs_match, size: 1, after: 0)
|
222
|
+
|
223
|
+
expect(page.data.first).to eq(@instance_refs[0])
|
224
|
+
expect(page.page_after.data.first).to eq(@instance_refs[1])
|
225
|
+
|
226
|
+
page = client.paginate(@refs_match, size: 1, after: 0)
|
227
|
+
|
228
|
+
expect(page.page_after.data.first).to eq(@instance_refs[1])
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe '#page_before' do
|
233
|
+
it 'returns the page before' do
|
234
|
+
page = client.paginate(@refs_match, size: 1, before: nil)
|
235
|
+
|
236
|
+
@instance_refs.reverse.drop(1).each do |ref|
|
237
|
+
page = page.page_before
|
238
|
+
expect(page.data.first).to eq(ref)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'returns nil on last page' do
|
243
|
+
page = client.paginate(@refs_match, size: 1, before: @instance_refs.first)
|
244
|
+
|
245
|
+
expect(page.page_before).to be_nil
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'is not affected by lazy loading' do
|
249
|
+
page = client.paginate(@refs_match, size: 1, before: nil)
|
250
|
+
|
251
|
+
expect(page.data.first).to eq(@instance_refs[-1])
|
252
|
+
expect(page.page_before.data.first).to eq(@instance_refs[-2])
|
253
|
+
|
254
|
+
page = client.paginate(@refs_match, size: 1, before: nil)
|
255
|
+
|
256
|
+
expect(page.page_before.data.first).to eq(@instance_refs[-2])
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'pages both directions' do
|
261
|
+
page = client.paginate(@refs_match, size: 1, after: 0)
|
262
|
+
expect(page.data.first).to eq(@instance_refs[0])
|
263
|
+
|
264
|
+
page = page.page_after
|
265
|
+
expect(page.data.first).to eq(@instance_refs[1])
|
266
|
+
|
267
|
+
page = page.page_before
|
268
|
+
expect(page.data.first).to eq(@instance_refs[0])
|
269
|
+
end
|
270
|
+
|
271
|
+
describe '#each' do
|
272
|
+
it 'iterates the set in the after direction' do
|
273
|
+
page = client.paginate(@refs_match, size: 1)
|
274
|
+
refs = @instance_refs.collect { |ref| [ref] }
|
275
|
+
|
276
|
+
expect(page.each.collect { |ref| ref }).to eq(refs)
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'is not affected by lazy loading' do
|
280
|
+
page = client.paginate(@refs_match, size: 1)
|
281
|
+
refs = @instance_refs.collect { |ref| [ref] }
|
282
|
+
|
283
|
+
expect(page.each.collect { |ref| ref }).to eq(refs)
|
284
|
+
|
285
|
+
page = client.paginate(@refs_match, size: 1)
|
286
|
+
refs = @instance_refs.collect { |ref| [ref] }
|
287
|
+
|
288
|
+
expect(page.data).to eq([@instance_refs.first])
|
289
|
+
expect(page.each.collect { |ref| ref }).to eq(refs)
|
290
|
+
end
|
291
|
+
|
292
|
+
context 'with fauna map' do
|
293
|
+
it 'iterates the set using the fauna map' do
|
294
|
+
page = client.paginate(@refs_match, size: 1) { |ref| get(ref) }
|
295
|
+
instances = @instances.collect { |inst| [inst] }
|
296
|
+
|
297
|
+
expect(page.each.collect { |inst| inst }).to eq(instances)
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'chains multiple collection functions' do
|
301
|
+
page = client.paginate(@refs_match, size: 1)
|
302
|
+
# Map ref to value
|
303
|
+
page = page.map { |ref| select(['data', 'value'], get(ref)) }
|
304
|
+
# Filter out odd numbers
|
305
|
+
page = page.filter { |value| equals(modulo(value, 2), 0) }
|
306
|
+
# Map to double the value
|
307
|
+
page = page.map { |value| multiply(value, 2) }
|
308
|
+
|
309
|
+
# We are using the index on refs, not value, so we need to expect the values to be sorted by instance ref
|
310
|
+
expected = @instances.collect { |inst| inst[:data][:value] }.find_all(&:even?).collect { |v| v * 2 }
|
311
|
+
|
312
|
+
expect(page.all).to eq(expected)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'with ruby map' do
|
317
|
+
it 'iterates the set using the ruby map' do
|
318
|
+
page = client.paginate(@refs_match, size: 1).postprocessing_map(&:id)
|
319
|
+
ids = @instance_refs.collect { |ref| [ref.id] }
|
320
|
+
|
321
|
+
expect(page.each.collect { |id| id }).to eq(ids)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
describe '#reverse_each' do
|
327
|
+
it 'iterates the set in the before direction' do
|
328
|
+
page = client.paginate(@refs_match, size: 1, before: nil)
|
329
|
+
refs = @instance_refs.reverse.collect { |ref| [ref] }
|
330
|
+
|
331
|
+
expect(page.reverse_each.collect { |ref| ref }).to eq(refs)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
describe '#all' do
|
336
|
+
it 'returns full contents of the set' do
|
337
|
+
page = client.paginate(@refs_match, size: 1)
|
338
|
+
|
339
|
+
expect(page.all).to eq(@instance_refs)
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
describe '#foreach!' do
|
344
|
+
before(:each) do
|
345
|
+
@apply_refs = client.query { (1..3).collect { |x| select([:ref], create(@foreach_class, data: { value: x })) } }
|
346
|
+
end
|
347
|
+
|
348
|
+
it 'applies foreach to set' do
|
349
|
+
# Sanity
|
350
|
+
expect(client.query { map(@apply_refs) { |ref| exists ref } }).to eq(@apply_refs.collect { true })
|
351
|
+
|
352
|
+
client.paginate(@foreach_match, size: 1).foreach! { |ref| delete ref }
|
353
|
+
|
354
|
+
expect(client.query { map(@apply_refs) { |ref| exists ref } }).to eq(@apply_refs.collect { false })
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|