fauna 2.4.0 → 3.0.0
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 +4 -4
- data/CHANGELOG +11 -0
- data/README.md +4 -1
- data/fauna.gemspec +2 -1
- data/lib/fauna.rb +1 -0
- data/lib/fauna/client.rb +6 -69
- data/lib/fauna/deprecate.rb +29 -0
- data/lib/fauna/json.rb +11 -2
- data/lib/fauna/objects.rb +33 -31
- data/lib/fauna/page.rb +4 -4
- data/lib/fauna/query.rb +141 -15
- data/lib/fauna/version.rb +1 -1
- data/spec/client_logger_spec.rb +13 -13
- data/spec/client_spec.rb +21 -96
- data/spec/context_spec.rb +1 -46
- data/spec/errors_spec.rb +27 -33
- data/spec/fauna_helper.rb +1 -1
- data/spec/json_spec.rb +8 -8
- data/spec/page_spec.rb +1 -1
- data/spec/query_spec.rb +139 -11
- data/spec/ref_spec.rb +63 -27
- metadata +20 -5
data/lib/fauna/version.rb
CHANGED
data/spec/client_logger_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
RSpec.describe Fauna::ClientLogger do
|
2
2
|
before(:all) do
|
3
3
|
create_test_db
|
4
|
-
@test_class = client.
|
4
|
+
@test_class = client.query { create_class(name: 'logger_test') }[:ref]
|
5
5
|
end
|
6
6
|
|
7
7
|
after(:all) do
|
@@ -20,7 +20,7 @@ RSpec.describe Fauna::ClientLogger do
|
|
20
20
|
|
21
21
|
it 'logs response' do
|
22
22
|
reader = capture_log do |client|
|
23
|
-
expect(client.ping).to eq('Scope
|
23
|
+
expect(client.ping).to eq('Scope write is OK')
|
24
24
|
end
|
25
25
|
|
26
26
|
expect(reader.call).to eq('Fauna GET /ping')
|
@@ -37,7 +37,7 @@ RSpec.describe Fauna::ClientLogger do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
expect(reader.call).to eq(' Response JSON: {')
|
40
|
-
expect(reader.call).to eq(' "resource": "Scope
|
40
|
+
expect(reader.call).to eq(' "resource": "Scope write is OK"')
|
41
41
|
expect(reader.call).to eq(' }')
|
42
42
|
expect(reader.call).to match(/^ Response \(200\): Network latency \d+ms$/)
|
43
43
|
end
|
@@ -45,29 +45,29 @@ RSpec.describe Fauna::ClientLogger do
|
|
45
45
|
it 'logs request content' do
|
46
46
|
value = random_number
|
47
47
|
reader = capture_log do |client|
|
48
|
-
client.
|
48
|
+
client.query data: { a: value }
|
49
49
|
end
|
50
50
|
|
51
|
-
expect(reader.call).to eq("Fauna POST
|
51
|
+
expect(reader.call).to eq("Fauna POST /")
|
52
52
|
expect(reader.call).to match(/^ Credentials:/)
|
53
53
|
expect(reader.call).to eq(' Request JSON: {')
|
54
|
-
expect(reader.call).to eq(' "
|
55
|
-
expect(reader.call).to eq(
|
54
|
+
expect(reader.call).to eq(' "object": {')
|
55
|
+
expect(reader.call).to eq(' "data": {')
|
56
|
+
expect(reader.call).to eq(' "object": {')
|
57
|
+
expect(reader.call).to eq(" \"a\": #{value}")
|
58
|
+
expect(reader.call).to eq(' }')
|
59
|
+
expect(reader.call).to eq(' }')
|
56
60
|
expect(reader.call).to eq(' }')
|
57
61
|
expect(reader.call).to eq(' }')
|
58
62
|
# Ignore the rest
|
59
63
|
end
|
60
64
|
|
61
65
|
it 'logs request query' do
|
62
|
-
instance = client.post(@test_class)
|
63
|
-
ref = instance[:ref]
|
64
|
-
ts = instance[:ts]
|
65
|
-
|
66
66
|
reader = capture_log do |client|
|
67
|
-
client.
|
67
|
+
client.ping scope: 'global'
|
68
68
|
end
|
69
69
|
|
70
|
-
expect(reader.call).to eq("Fauna GET
|
70
|
+
expect(reader.call).to eq("Fauna GET /ping?scope=global")
|
71
71
|
# Ignore the rest
|
72
72
|
end
|
73
73
|
end
|
data/spec/client_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
RSpec.describe Fauna::Client do
|
2
2
|
before(:all) do
|
3
3
|
create_test_db
|
4
|
-
@test_class = client.
|
4
|
+
@test_class = client.query { create_class(name: 'client_test') }[:ref]
|
5
5
|
end
|
6
6
|
|
7
7
|
after(:all) do
|
@@ -23,32 +23,32 @@ RSpec.describe Fauna::Client do
|
|
23
23
|
|
24
24
|
it 'decodes gzip response' do
|
25
25
|
response = gzipped '{"resource": 1}'
|
26
|
-
test_client = stub_client(:
|
27
|
-
expect(test_client.
|
26
|
+
test_client = stub_client(:post, '/', response, 'Content-Encoding' => 'gzip')
|
27
|
+
expect(test_client.query('tests/decode')).to be(1)
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'decodes deflate response' do
|
31
31
|
response = Zlib::Deflate.deflate '{"resource": 1}'
|
32
|
-
test_client = stub_client(:
|
33
|
-
expect(test_client.
|
32
|
+
test_client = stub_client(:post, '/', response, 'Content-Encoding' => 'deflate')
|
33
|
+
expect(test_client.query('tests/decode')).to be(1)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
describe 'serialization' do
|
38
38
|
it 'decodes ref' do
|
39
|
-
ref = Fauna::Ref.new(
|
40
|
-
test_client = stub_client(:
|
39
|
+
ref = Fauna::Ref.new(random_number, Fauna::Ref.new(random_string, Fauna::Native.classes))
|
40
|
+
test_client = stub_client(:post, '/', to_json(resource: ref))
|
41
41
|
|
42
|
-
response = test_client.
|
42
|
+
response = test_client.query('tests/ref')
|
43
43
|
expect(response).to be_a(Fauna::Ref)
|
44
44
|
expect(response).to eq(ref)
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'decodes set' do
|
48
|
-
set = Fauna::SetRef.new(match: Fauna::Ref.new(
|
49
|
-
test_client = stub_client(:
|
48
|
+
set = Fauna::SetRef.new(match: Fauna::Ref.new(random_string, Fauna::Native.indexes), terms: random_string)
|
49
|
+
test_client = stub_client(:post, '/', to_json(resource: set))
|
50
50
|
|
51
|
-
response = test_client.
|
51
|
+
response = test_client.query('tests/set')
|
52
52
|
expect(response).to be_a(Fauna::SetRef)
|
53
53
|
expect(response).to eq(set)
|
54
54
|
end
|
@@ -56,27 +56,27 @@ RSpec.describe Fauna::Client do
|
|
56
56
|
it 'decodes obj' do
|
57
57
|
data = { random_string.to_sym => random_string }
|
58
58
|
obj = { :@obj => data }
|
59
|
-
test_client = stub_client(:
|
59
|
+
test_client = stub_client(:post, '/', to_json(resource: obj))
|
60
60
|
|
61
|
-
response = test_client.
|
61
|
+
response = test_client.query('tests/obj')
|
62
62
|
expect(response).to be_a(Hash)
|
63
63
|
expect(response).to eq(data)
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'decodes ts' do
|
67
67
|
ts = Time.at(0).utc
|
68
|
-
test_client = stub_client(:
|
68
|
+
test_client = stub_client(:post, '/', to_json(resource: ts))
|
69
69
|
|
70
|
-
response = test_client.
|
70
|
+
response = test_client.query('tests/ts')
|
71
71
|
expect(response).to be_a(Time)
|
72
72
|
expect(response).to eq(ts)
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'decodes date' do
|
76
76
|
date = Date.new(1970, 1, 1)
|
77
|
-
test_client = stub_client(:
|
77
|
+
test_client = stub_client(:post, '/', to_json(resource: date))
|
78
78
|
|
79
|
-
response = test_client.
|
79
|
+
response = test_client.query('tests/date')
|
80
80
|
expect(response).to be_a(Date)
|
81
81
|
expect(response).to eq(date)
|
82
82
|
end
|
@@ -99,9 +99,9 @@ RSpec.describe Fauna::Client do
|
|
99
99
|
it 'performs query from expression' do
|
100
100
|
value = random_number
|
101
101
|
|
102
|
-
instance = client.query
|
102
|
+
instance = client.query { create(@test_class, data: { a: value }) }
|
103
103
|
|
104
|
-
expect(instance[:
|
104
|
+
expect(instance[:ref].class_).to eq(@test_class)
|
105
105
|
expect(instance[:data][:a]).to eq(value)
|
106
106
|
end
|
107
107
|
|
@@ -110,89 +110,14 @@ RSpec.describe Fauna::Client do
|
|
110
110
|
|
111
111
|
instance = client.query { create @test_class, data: { a: value } }
|
112
112
|
|
113
|
-
expect(instance[:
|
113
|
+
expect(instance[:ref].class_).to eq(@test_class)
|
114
114
|
expect(instance[:data][:a]).to eq(value)
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
describe '#get' do
|
119
|
-
it 'performs GET' do
|
120
|
-
value = random_number
|
121
|
-
ref = client.post(@test_class, data: { a: value })[:ref]
|
122
|
-
|
123
|
-
instance = client.get(ref)
|
124
|
-
|
125
|
-
expect(instance[:ref]).to eq(ref)
|
126
|
-
expect(instance[:data][:a]).to eq(value)
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'performs GET with query' do
|
130
|
-
value = random_number
|
131
|
-
created = client.post(@test_class, data: { a: value })
|
132
|
-
ref = created[:ref]
|
133
|
-
ts = created[:ts]
|
134
|
-
|
135
|
-
instance = client.get(ref, ts: ts)
|
136
|
-
|
137
|
-
expect(instance[:ref]).to eq(ref)
|
138
|
-
expect(instance[:data][:a]).to eq(value)
|
139
|
-
|
140
|
-
expect { client.get(ref, ts: ts - 1) }.to raise_error(Fauna::NotFound)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
describe '#post' do
|
145
|
-
it 'performs POST' do
|
146
|
-
value = random_number
|
147
|
-
|
148
|
-
instance = client.post(@test_class, data: { a: value })
|
149
|
-
|
150
|
-
expect(instance[:class]).to eq(@test_class)
|
151
|
-
expect(instance[:data][:a]).to eq(value)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
describe '#put' do
|
156
|
-
it 'performs PUT' do
|
157
|
-
value = random_number
|
158
|
-
ref = client.post(@test_class, data: { a: random_number })[:ref]
|
159
|
-
|
160
|
-
instance = client.put(ref, data: { b: value })
|
161
|
-
|
162
|
-
expect(instance[:ref]).to eq(ref)
|
163
|
-
expect(instance[:data][:a]).to be_nil
|
164
|
-
expect(instance[:data][:b]).to eq(value)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
describe '#patch' do
|
169
|
-
it 'performs PATCH' do
|
170
|
-
value1 = random_number
|
171
|
-
value2 = random_number
|
172
|
-
ref = client.post(@test_class, data: { a: value1 })[:ref]
|
173
|
-
|
174
|
-
instance = client.patch(ref, data: { b: value2 })
|
175
|
-
|
176
|
-
expect(instance[:ref]).to eq(ref)
|
177
|
-
expect(instance[:data][:a]).to eq(value1)
|
178
|
-
expect(instance[:data][:b]).to eq(value2)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
describe '#delete' do
|
183
|
-
it 'performs DELETE' do
|
184
|
-
ref = client.post(@test_class, data: { a: random_number })[:ref]
|
185
|
-
|
186
|
-
instance = client.delete(ref)
|
187
|
-
|
188
|
-
expect(instance[:ref]).to eq(ref)
|
189
|
-
expect { client.get(ref) }.to raise_error(Fauna::NotFound)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
118
|
describe '#ping' do
|
194
119
|
it 'performs ping' do
|
195
|
-
expect(client.ping).to eq('Scope
|
120
|
+
expect(client.ping).to eq('Scope write is OK')
|
196
121
|
end
|
197
122
|
|
198
123
|
it 'performs ping with scope' do
|
data/spec/context_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
RSpec.describe Fauna::Context do
|
2
2
|
before(:all) do
|
3
3
|
create_test_db
|
4
|
-
@test_class = client.
|
4
|
+
@test_class = client.query { create_class(name: 'context_test') }[:ref]
|
5
5
|
end
|
6
6
|
|
7
7
|
after(:all) do
|
@@ -15,51 +15,6 @@ RSpec.describe Fauna::Context do
|
|
15
15
|
Fauna::Context.reset
|
16
16
|
end
|
17
17
|
|
18
|
-
describe 'REST methods' do
|
19
|
-
around do |ex|
|
20
|
-
stubs = Faraday::Adapter::Test::Stubs.new
|
21
|
-
[:get, :post, :put, :patch, :delete].each do |method|
|
22
|
-
stubs.send(method, '/tests/context') do |env|
|
23
|
-
[200, {}, { resource: env.method.to_s.upcase }.to_json]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
Fauna::Context.block(Fauna::Client.new(adapter: [:test, stubs])) do
|
28
|
-
ex.run
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe '#get' do
|
33
|
-
it 'performs GET request' do
|
34
|
-
expect(Fauna::Context.get('tests/context')).to eq('GET')
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe '#post' do
|
39
|
-
it 'performs POST request' do
|
40
|
-
expect(Fauna::Context.post('tests/context')).to eq('POST')
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe '#put' do
|
45
|
-
it 'performs PUT request' do
|
46
|
-
expect(Fauna::Context.put('tests/context')).to eq('PUT')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
describe '#patch' do
|
51
|
-
it 'performs PATCH request' do
|
52
|
-
expect(Fauna::Context.patch('tests/context')).to eq('PATCH')
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe '#delete' do
|
57
|
-
it 'performs DELETE request' do
|
58
|
-
expect(Fauna::Context.delete('tests/context')).to eq('DELETE')
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
18
|
describe '#query' do
|
64
19
|
it 'performs query' do
|
65
20
|
Fauna::Context.block(client) do
|
data/spec/errors_spec.rb
CHANGED
@@ -23,9 +23,9 @@ RSpec.describe 'Fauna Errors' do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# Create client with stub adapter responding to / with the given status and response
|
26
|
-
def
|
26
|
+
def stub_post(status_code, response)
|
27
27
|
stubs = Faraday::Adapter::Test::Stubs.new
|
28
|
-
stubs.
|
28
|
+
stubs.post '/' do
|
29
29
|
[status_code, {}, response]
|
30
30
|
end
|
31
31
|
Fauna::Client.new(adapter: [:test, stubs])
|
@@ -34,16 +34,16 @@ RSpec.describe 'Fauna Errors' do
|
|
34
34
|
# Create client with stub adapter responding to / with the given exception
|
35
35
|
def stub_error(exception)
|
36
36
|
stubs = Faraday::Adapter::Test::Stubs.new
|
37
|
-
stubs.
|
37
|
+
stubs.post '/' do
|
38
38
|
fail exception
|
39
39
|
end
|
40
40
|
Fauna::Client.new(adapter: [:test, stubs])
|
41
41
|
end
|
42
42
|
|
43
43
|
it 'sets request result' do
|
44
|
-
expect { client.
|
44
|
+
expect { client.query { add 1, :two } }.to raise_error do |err|
|
45
45
|
expect(err).to be_a(Fauna::BadRequest)
|
46
|
-
expect(err.request_result.request_content).to eq(
|
46
|
+
expect(err.request_result.request_content).to eq(Fauna::Query.add [1, :two])
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -81,7 +81,7 @@ RSpec.describe 'Fauna Errors' do
|
|
81
81
|
|
82
82
|
describe Fauna::BadRequest do
|
83
83
|
it 'is handled' do
|
84
|
-
expect { client.
|
84
|
+
expect { client.query { add 1, 'string' } }.to raise_error(Fauna::BadRequest)
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
@@ -103,65 +103,59 @@ RSpec.describe 'Fauna Errors' do
|
|
103
103
|
|
104
104
|
describe Fauna::NotFound do
|
105
105
|
it 'is handled' do
|
106
|
-
expect { client.
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe Fauna::MethodNotAllowed do
|
111
|
-
it 'is handled' do
|
112
|
-
expect { client.delete 'classes' }.to raise_fauna_error(Fauna::MethodNotAllowed, 'method not allowed')
|
106
|
+
expect { client.query { delete Fauna::Ref.new('classes') } }.to raise_fauna_error(Fauna::NotFound, 'instance not found', [])
|
113
107
|
end
|
114
108
|
end
|
115
109
|
|
116
110
|
describe Fauna::InternalError do
|
117
111
|
it 'is handled' do
|
118
|
-
stub_client =
|
112
|
+
stub_client = stub_post 500,
|
119
113
|
'{"errors": [{"code": "internal server error", "description": "sample text", "stacktrace": []}]}'
|
120
114
|
|
121
|
-
expect { stub_client.
|
115
|
+
expect { stub_client.query '' }.to raise_fauna_error(Fauna::InternalError, 'internal server error')
|
122
116
|
end
|
123
117
|
end
|
124
118
|
|
125
119
|
describe Fauna::UnavailableError do
|
126
120
|
it 'handles fauna 503' do
|
127
|
-
stub_client =
|
128
|
-
expect { stub_client.
|
121
|
+
stub_client = stub_post 503, '{"errors": [{"code": "unavailable", "description": "on vacation"}]}'
|
122
|
+
expect { stub_client.query '' }.to raise_fauna_error(Fauna::UnavailableError, 'unavailable')
|
129
123
|
end
|
130
124
|
|
131
125
|
it 'handles upstream 502' do
|
132
|
-
stub_client =
|
133
|
-
expect { stub_client.
|
126
|
+
stub_client = stub_post 502, 'Bad gateway'
|
127
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Bad gateway')
|
134
128
|
end
|
135
129
|
|
136
130
|
it 'handles upstream 503' do
|
137
|
-
stub_client =
|
138
|
-
expect { stub_client.
|
131
|
+
stub_client = stub_post 503, 'Unable to reach server'
|
132
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Unable to reach server')
|
139
133
|
end
|
140
134
|
|
141
135
|
it 'handles upstream 504' do
|
142
|
-
stub_client =
|
143
|
-
expect { stub_client.
|
136
|
+
stub_client = stub_post 504, 'Server timeout'
|
137
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Server timeout')
|
144
138
|
end
|
145
139
|
|
146
140
|
it 'handles upstream json 503' do
|
147
|
-
stub_client =
|
148
|
-
expect { stub_client.
|
141
|
+
stub_client = stub_post 503, '{ "error" : "service unavailable" }'
|
142
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, '{ "error" : "service unavailable" }')
|
149
143
|
end
|
150
144
|
|
151
145
|
it 'handles timeout error' do
|
152
146
|
stub_client = stub_error Faraday::TimeoutError.new('timeout')
|
153
|
-
expect { stub_client.
|
147
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Faraday::TimeoutError: timeout')
|
154
148
|
end
|
155
149
|
|
156
150
|
it 'handles connection error' do
|
157
151
|
stub_client = stub_error Faraday::ConnectionFailed.new('connection refused')
|
158
|
-
expect { stub_client.
|
152
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Faraday::ConnectionFailed: connection refused')
|
159
153
|
end
|
160
154
|
end
|
161
155
|
|
162
156
|
describe Fauna::UnexpectedError do
|
163
157
|
it 'raised for json error' do
|
164
|
-
expect {
|
158
|
+
expect { stub_post(200, 'I like fine wine').query('') }.to raise_error(Fauna::UnexpectedError, /json/i) do |err|
|
165
159
|
rr = err.request_result
|
166
160
|
expect(rr.response_content).to be_nil
|
167
161
|
expect(rr.response_raw).to eq('I like fine wine')
|
@@ -169,23 +163,23 @@ RSpec.describe 'Fauna Errors' do
|
|
169
163
|
end
|
170
164
|
|
171
165
|
it 'raised for missing resource' do
|
172
|
-
expect {
|
166
|
+
expect { stub_post(200, '{"notaresource": 1}').query('') }.to raise_error(Fauna::UnexpectedError, /expected key/)
|
173
167
|
end
|
174
168
|
|
175
169
|
it 'raised for unexpected code' do
|
176
|
-
expect {
|
170
|
+
expect { stub_post(1337, '{"errors": []}').query('') }.to raise_error(Fauna::UnexpectedError, /status code/)
|
177
171
|
end
|
178
172
|
|
179
173
|
it 'raised for bad errors format' do
|
180
|
-
expect {
|
174
|
+
expect { stub_post(500, '{"errors": true}').query('') }.to raise_error(Fauna::UnexpectedError, /unexpected format/)
|
181
175
|
end
|
182
176
|
|
183
177
|
it 'raised for empty errors' do
|
184
|
-
expect {
|
178
|
+
expect { stub_post(500, '{"errors": []}').query('') }.to raise_error(Fauna::UnexpectedError, /blank/)
|
185
179
|
end
|
186
180
|
|
187
181
|
it 'raised for parsing error' do
|
188
|
-
expect { stub_error(Faraday::ParsingError.new('parse error')).
|
182
|
+
expect { stub_error(Faraday::ParsingError.new('parse error')).query('') }.to raise_error(Fauna::UnexpectedError, /parse error/)
|
189
183
|
end
|
190
184
|
end
|
191
185
|
end
|