fauna 1.3.4 → 2.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 +5 -13
- data/CHANGELOG +2 -0
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.md +65 -102
- data/Rakefile +12 -20
- data/fauna.gemspec +19 -44
- data/lib/fauna.rb +12 -14
- data/lib/fauna/client.rb +225 -27
- data/lib/fauna/client_logger.rb +52 -0
- data/lib/fauna/context.rb +135 -0
- data/lib/fauna/errors.rb +181 -0
- data/lib/fauna/json.rb +60 -0
- data/lib/fauna/objects.rb +96 -0
- data/lib/fauna/query.rb +601 -0
- data/lib/fauna/request_result.rb +58 -0
- data/lib/fauna/util.rb +41 -0
- data/lib/fauna/version.rb +4 -0
- data/spec/client_logger_spec.rb +73 -0
- data/spec/client_spec.rb +202 -0
- data/spec/context_spec.rb +121 -0
- data/spec/errors_spec.rb +144 -0
- data/spec/fauna_helper.rb +87 -0
- data/spec/json_spec.rb +123 -0
- data/spec/query_spec.rb +675 -0
- data/spec/ref_spec.rb +77 -0
- data/spec/setref_spec.rb +23 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/util_spec.rb +19 -0
- metadata +65 -83
- data/Manifest +0 -25
- data/lib/fauna/cache.rb +0 -64
- data/lib/fauna/connection.rb +0 -152
- data/lib/fauna/named_resource.rb +0 -17
- data/lib/fauna/rails.rb +0 -120
- data/lib/fauna/resource.rb +0 -175
- data/lib/fauna/set.rb +0 -240
- data/lib/tasks/fauna.rake +0 -71
- data/test/class_test.rb +0 -65
- data/test/client_test.rb +0 -63
- data/test/connection_test.rb +0 -66
- data/test/database_test.rb +0 -48
- data/test/query_test.rb +0 -48
- data/test/readme_test.rb +0 -30
- data/test/set_test.rb +0 -71
- data/test/test_helper.rb +0 -86
data/spec/errors_spec.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
RSpec.describe 'Fauna Errors' do
|
2
|
+
RSpec::Matchers.define :raise_fauna_error do |exception, code, position = nil|
|
3
|
+
match do |block|
|
4
|
+
expect(&block).to raise_error(exception) do |ex|
|
5
|
+
expect(ex.errors.length).to be(1)
|
6
|
+
error = ex.errors.first
|
7
|
+
expect(error.code).to eq(code)
|
8
|
+
expect(error.position).to eq(position)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def supports_block_expectations?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:all) do
|
18
|
+
create_test_db
|
19
|
+
end
|
20
|
+
|
21
|
+
after(:all) do
|
22
|
+
destroy_test_db
|
23
|
+
end
|
24
|
+
|
25
|
+
# Create client with stub adapter responding to / with the given status and response
|
26
|
+
def stub_get(status_code, response)
|
27
|
+
stubs = Faraday::Adapter::Test::Stubs.new
|
28
|
+
stubs.get '/' do
|
29
|
+
[status_code, {}, response]
|
30
|
+
end
|
31
|
+
Fauna::Client.new(adapter: [:test, stubs])
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'sets request result' do
|
35
|
+
expect { client.post '', foo: 'bar' }.to raise_error do |err|
|
36
|
+
expect(err).to be_a(Fauna::BadRequest)
|
37
|
+
expect(err.request_result.request_content).to eq(foo: 'bar')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'parses query errors' do
|
42
|
+
expect { client.query { add 1, :two } }.to raise_fauna_error(Fauna::BadRequest, 'invalid argument', [:add, 1])
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'parses invalid data' do
|
46
|
+
expect { client.query { create ref('classes'), name: 123 } }.to raise_error(Fauna::BadRequest) do |err|
|
47
|
+
expect(err.errors.length).to eq(1)
|
48
|
+
error = err.errors.first
|
49
|
+
|
50
|
+
expect(error.code).to eq('validation failed')
|
51
|
+
expect(error.position).to eq([])
|
52
|
+
expect(error.failures.length).to eq(1)
|
53
|
+
failure = error.failures.first
|
54
|
+
|
55
|
+
expect(failure.code).to eq('invalid type')
|
56
|
+
expect(failure.field).to eq([:name])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe Fauna::ErrorData do
|
61
|
+
it 'handles inspect' do
|
62
|
+
err = Fauna::ErrorData.new 'code', 'desc', nil, nil
|
63
|
+
expect(err.inspect).to eq('ErrorData("code", "desc", nil, nil)')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'handles inspect with failures' do
|
67
|
+
failure = Fauna::Failure.new 'code', 'desc', [:a, :b]
|
68
|
+
err = Fauna::ErrorData.new 'code', 'desc', [:pos], [failure]
|
69
|
+
expect(err.inspect).to eq('ErrorData("code", "desc", [:pos], [Failure("code", "desc", [:a, :b])])')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe Fauna::BadRequest do
|
74
|
+
it 'is handled' do
|
75
|
+
expect { client.post '', foo: 'bar' }.to raise_error(Fauna::BadRequest)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe Fauna::Unauthorized do
|
80
|
+
it 'is handled' do
|
81
|
+
bad_client = get_client secret: 'bad_key'
|
82
|
+
expect { bad_client.query { get @db_ref } }.to raise_error(Fauna::Unauthorized)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe Fauna::PermissionDenied do
|
87
|
+
it 'is handled' do
|
88
|
+
key = root_client.query { create ref('keys'), database: @db_ref, role: :client }
|
89
|
+
|
90
|
+
expect { get_client(secret: key[:secret]).query { paginate ref('databases') } }.to raise_fauna_error(
|
91
|
+
Fauna::PermissionDenied, 'permission denied', [:paginate])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe Fauna::NotFound do
|
96
|
+
it 'is handled' do
|
97
|
+
expect { client.get 'classes/no_class' }.to raise_fauna_error(Fauna::NotFound, 'not found')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe Fauna::MethodNotAllowed do
|
102
|
+
it 'is handled' do
|
103
|
+
expect { client.delete 'classes' }.to raise_fauna_error(Fauna::MethodNotAllowed, 'method not allowed')
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe Fauna::InternalError do
|
108
|
+
it 'is handled' do
|
109
|
+
stub_client = stub_get 500,
|
110
|
+
'{"errors": [{"code": "internal server error", "description": "sample text", "stacktrace": []}]}'
|
111
|
+
|
112
|
+
expect { stub_client.get '' }.to raise_fauna_error(Fauna::InternalError, 'internal server error')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe Fauna::UnavailableError do
|
117
|
+
it 'is handled' do
|
118
|
+
stub_client = stub_get 503, '{"errors": [{"code": "unavailable", "description": "on vacation"}]}'
|
119
|
+
expect { stub_client.get '' }.to raise_fauna_error(Fauna::UnavailableError, 'unavailable')
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe Fauna::UnexpectedError do
|
124
|
+
it 'raised for json error' do
|
125
|
+
expect { stub_get(200, 'I like fine wine').get('') }.to raise_error(Fauna::UnexpectedError, /json/i) do |err|
|
126
|
+
rr = err.request_result
|
127
|
+
expect(rr.response_content).to be_nil
|
128
|
+
expect(rr.response_raw).to eq('I like fine wine')
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'raised for missing resource' do
|
133
|
+
expect { stub_get(200, '{"notaresource": 1}').get('') }.to raise_error(Fauna::UnexpectedError, /expected key/)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'raised for unexpected code' do
|
137
|
+
expect { stub_get(1337, '{"errors": []}').get('') }.to raise_error(Fauna::UnexpectedError, /status code/)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'raised for bad errors format' do
|
141
|
+
expect { stub_get(500, '{"errors": true}').get('') }.to raise_error(Fauna::UnexpectedError, /unexpected format/)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,87 @@
|
|
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 create_test_db
|
27
|
+
@db_ref = Fauna::Ref.new 'databases', "faunadb-ruby-test-#{random_string}"
|
28
|
+
|
29
|
+
root = root_client
|
30
|
+
root.query { create ref('databases'), name: @db_ref.id }
|
31
|
+
|
32
|
+
begin
|
33
|
+
server_key = root.query { create ref('keys'), database: @db_ref, role: 'server' }
|
34
|
+
rescue
|
35
|
+
root.query { delete @db_ref }
|
36
|
+
@db_ref = nil
|
37
|
+
raise
|
38
|
+
end
|
39
|
+
|
40
|
+
@server_secret = server_key[:secret]
|
41
|
+
@server_client = get_client secret: @server_secret
|
42
|
+
end
|
43
|
+
|
44
|
+
def destroy_test_db
|
45
|
+
root_client.query { delete @db_ref } unless @db_ref.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
def stub_client(method, url, response = nil, headers = {})
|
49
|
+
stubs = Faraday::Adapter::Test::Stubs.new
|
50
|
+
stubs.send(method, url) do |env|
|
51
|
+
if response.nil?
|
52
|
+
[200, headers, { resource: { method: env.method.to_s.upcase, body: JSON.load(env.body) } }.to_json]
|
53
|
+
else
|
54
|
+
[200, headers, response]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
Fauna::Client.new(adapter: [:test, stubs])
|
58
|
+
end
|
59
|
+
|
60
|
+
def random_string
|
61
|
+
SecureRandom.hex(7)
|
62
|
+
end
|
63
|
+
|
64
|
+
def random_number
|
65
|
+
SecureRandom.random_number(1_000_000)
|
66
|
+
end
|
67
|
+
|
68
|
+
def random_ref
|
69
|
+
"classes/#{random_string}/#{random_number}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def random_class_ref
|
73
|
+
"classes/#{random_string}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_json(value)
|
77
|
+
Fauna::FaunaJson.to_json(value)
|
78
|
+
end
|
79
|
+
|
80
|
+
def from_json(value)
|
81
|
+
Fauna::FaunaJson.json_load(value)
|
82
|
+
end
|
83
|
+
|
84
|
+
def wait_for_active(ref)
|
85
|
+
sleep 1 until client.query { get(ref) }[:active]
|
86
|
+
end
|
87
|
+
end
|
data/spec/json_spec.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
RSpec.describe Fauna::FaunaJson do
|
2
|
+
describe '#deserialize' do
|
3
|
+
it 'deserializes ref' do
|
4
|
+
ref = random_ref
|
5
|
+
|
6
|
+
data = { :@ref => 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
|
14
|
+
terms = random_string
|
15
|
+
|
16
|
+
data = { :@set => { match: { :@ref => 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 obj' do
|
23
|
+
obj = { a: random_string, b: random_string }
|
24
|
+
data = { :@obj => obj }
|
25
|
+
|
26
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'deserializes ts' do
|
30
|
+
data = { :@ts => '1970-01-01T00:00:00.000000000Z' }
|
31
|
+
obj = Time.at(0).utc
|
32
|
+
|
33
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'deserializes date' do
|
37
|
+
data = { :@date => '1970-01-01' }
|
38
|
+
obj = Date.new(1970, 1, 1)
|
39
|
+
|
40
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'recursively deserializes hashes' do
|
44
|
+
ref = random_ref
|
45
|
+
|
46
|
+
data = { test: { :@obj => { :@ref => ref } } }
|
47
|
+
obj = { test: Fauna::Ref.new(ref) }
|
48
|
+
|
49
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'recursively deserializes arrays' do
|
53
|
+
ref1 = random_ref
|
54
|
+
ref2 = random_ref
|
55
|
+
|
56
|
+
data = [{ :@ref => ref1 }, { :@ref => ref2 }]
|
57
|
+
obj = [Fauna::Ref.new(ref1), Fauna::Ref.new(ref2)]
|
58
|
+
|
59
|
+
expect(Fauna::FaunaJson.deserialize(data)).to eq(obj)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#to_json' do
|
64
|
+
it 'serializes ref' do
|
65
|
+
ref = random_ref
|
66
|
+
|
67
|
+
data = { :@ref => ref }
|
68
|
+
obj = Fauna::Ref.new(ref)
|
69
|
+
|
70
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'serializes set' do
|
74
|
+
ref = random_ref
|
75
|
+
|
76
|
+
data = { :@ref => ref }
|
77
|
+
obj = Fauna::Ref.new(ref)
|
78
|
+
|
79
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'serializes expr' do
|
83
|
+
data = { a: random_string, b: random_number }
|
84
|
+
obj = Fauna::Query::Expr.new(data)
|
85
|
+
|
86
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'serializes time' do
|
90
|
+
data = { :@ts => '1970-01-01T00:00:00.000000000Z' }
|
91
|
+
obj = Time.at(0).utc
|
92
|
+
|
93
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'serializes date' do
|
97
|
+
data = { :@date => '1970-01-01' }
|
98
|
+
obj = Date.new(1970, 1, 1)
|
99
|
+
|
100
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'recursively serializes hashes' do
|
104
|
+
ref = random_ref
|
105
|
+
terms = random_string
|
106
|
+
|
107
|
+
data = { a: { time: { :@ts => '1970-01-01T00:00:00.000000000Z' } }, b: { :@set => { match: { :@ref => ref }, terms: terms } } }
|
108
|
+
obj = { a: { time: Time.at(0).utc }, b: Fauna::SetRef.new(match: Fauna::Ref.new(ref), terms: terms) }
|
109
|
+
|
110
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'recursively serializes arrays' do
|
114
|
+
ref1 = random_ref
|
115
|
+
ref2 = random_ref
|
116
|
+
|
117
|
+
data = [{ :@ref => ref1 }, { :@ref => ref2 }]
|
118
|
+
obj = [Fauna::Ref.new(ref1), Fauna::Ref.new(ref2)]
|
119
|
+
|
120
|
+
expect(Fauna::FaunaJson.serialize(obj)).to eq(data)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/spec/query_spec.rb
ADDED
@@ -0,0 +1,675 @@
|
|
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: [{ path: 'data.x' }]
|
8
|
+
end
|
9
|
+
index_y = client.query do
|
10
|
+
create ref('indexes'), name: 'query_by_y', source: @test_class, terms: [{ path: 'data.y' }]
|
11
|
+
end
|
12
|
+
|
13
|
+
wait_for_active(index_x[:ref])
|
14
|
+
wait_for_active(index_y[:ref])
|
15
|
+
|
16
|
+
@test_by_x = index_x[:ref]
|
17
|
+
@test_by_y = index_y[:ref]
|
18
|
+
end
|
19
|
+
|
20
|
+
after(:all) do
|
21
|
+
destroy_test_db
|
22
|
+
end
|
23
|
+
|
24
|
+
# Alias for creating test class instance with provided data
|
25
|
+
def create_instance(data = {})
|
26
|
+
client.query { create(@test_class, data: data) }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Helper to collect all the contents of a set
|
30
|
+
def get_set_data(set, params = {})
|
31
|
+
data = []
|
32
|
+
|
33
|
+
page = client.query { paginate(set, params) }
|
34
|
+
data += page[:data]
|
35
|
+
while page.key? :after
|
36
|
+
page = client.query { paginate(set, params.merge(after: page[:after])) }
|
37
|
+
data += page[:data]
|
38
|
+
end
|
39
|
+
|
40
|
+
data
|
41
|
+
end
|
42
|
+
|
43
|
+
describe Fauna::Query::Expr 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 '#expr' do
|
57
|
+
it 'maintains lexical scope' do
|
58
|
+
def test_method
|
59
|
+
'foo'
|
60
|
+
end
|
61
|
+
test_var = 'bar'
|
62
|
+
|
63
|
+
expect(Fauna::Query.expr { test_method }).to eq('foo')
|
64
|
+
expect(Fauna::Query.expr { test_var }).to eq('bar')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'recursively wraps hashes' do
|
68
|
+
expr = Fauna::Query.expr { { x: 1, y: { foo: 2 }, z: add(1, 2) } }
|
69
|
+
query = { object: { x: 1, y: { object: { foo: 2 } }, z: { add: [1, 2] } } }
|
70
|
+
|
71
|
+
expect(to_json(expr)).to eq(to_json(query))
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'recursively wraps special types' do
|
75
|
+
expr = Fauna::Query.expr { { x: { y: Time.at(0).utc } } }
|
76
|
+
query = { object: { x: { object: { y: { :@ts => '1970-01-01T00:00:00.000000000Z' } } } } }
|
77
|
+
|
78
|
+
expect(to_json(expr)).to eq(to_json(query))
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'round-trips special types', skip: 'Support for auto-escaping of special types is deferred' do
|
82
|
+
expect(client.query { { '@ref' => 'foo' } }).to eq(:@ref => 'foo')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#ref' do
|
87
|
+
it 'creates a ref' do
|
88
|
+
ref = random_ref
|
89
|
+
expect(Fauna::Query.ref(ref)).to eq(Fauna::Ref.new(ref))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#object' do
|
94
|
+
it 'wraps fields in object' do
|
95
|
+
data = { a: random_string, b: random_number }
|
96
|
+
expect(Fauna::Query.object(data).raw).to eq(object: data)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#let' do
|
101
|
+
it 'performs let with expression' do
|
102
|
+
x = random_number
|
103
|
+
expect(client.query { let({ x: x }, var(:x)) }).to eq(x)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'performs let with block' do
|
107
|
+
x = random_number
|
108
|
+
expect(client.query { let(x: x) { x } }).to eq(x)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#var' do
|
113
|
+
it 'creates a var' do
|
114
|
+
name = random_string
|
115
|
+
expect(Fauna::Query.var(name).raw).to eq(var: name)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '#if_' do
|
120
|
+
it 'performs an if' do
|
121
|
+
expect(client.query { if_(true, 't', 'f') }).to eq('t')
|
122
|
+
expect(client.query { if_(false, 't', 'f') }).to eq('f')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#do_' do
|
127
|
+
it 'performs do' do
|
128
|
+
instance = create_instance
|
129
|
+
expect(client.query { do_(delete(instance[:ref]), 1) }).to eq(1)
|
130
|
+
expect(client.query { exists instance[:ref] }).to be(false)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#lambda' do
|
135
|
+
it 'raises when block takes no arguments' do
|
136
|
+
expect { Fauna::Query.lambda {} }.to raise_error(ArgumentError)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'raises when block takes splat argument' do
|
140
|
+
expect { Fauna::Query.lambda { |*vars| add(vars) } }.to raise_error(ArgumentError)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'performs lambda from single argument' do
|
144
|
+
expr = Fauna::Query.expr { lambda { |a| add(a, a) } }
|
145
|
+
query = { lambda: :a, expr: { add: [{ var: :a }, { var: :a }] } }
|
146
|
+
|
147
|
+
expect(to_json(expr)).to eq(to_json(query))
|
148
|
+
expect(client.query { map([1, 2, 3], expr) }).to eq([2, 4, 6])
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'performs lambda from multiple arguments' do
|
152
|
+
expr = Fauna::Query.expr { lambda { |a, b| [b, a] } }
|
153
|
+
query = { lambda: [:a, :b], expr: [{ var: :b }, { var: :a }] }
|
154
|
+
|
155
|
+
expect(to_json(expr)).to eq(to_json(query))
|
156
|
+
expect(client.query { map([[1, 2], [3, 4]], expr) }).to eq([[2, 1], [4, 3]])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe '#lambda_expr' do
|
161
|
+
it 'performs lambda from expression' do
|
162
|
+
expr = Fauna::Query.expr { lambda_expr(:a, add(var(:a), var(:a))) }
|
163
|
+
query = { lambda: :a, expr: { add: [{ var: :a }, { var: :a }] } }
|
164
|
+
|
165
|
+
expect(to_json(expr)).to eq(to_json(query))
|
166
|
+
expect(client.query { map([1, 2, 3], expr) }).to eq([2, 4, 6])
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'destructures single element arrays' do
|
170
|
+
expr = Fauna::Query.expr { lambda_expr([:a], add(var(:a), var(:a))) }
|
171
|
+
query = { lambda: [:a], expr: { add: [{ var: :a }, { var: :a }] } }
|
172
|
+
|
173
|
+
expect(to_json(expr)).to eq(to_json(query))
|
174
|
+
expect(client.query { map([[1], [2], [3]], expr) }).to eq([2, 4, 6])
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe '#map' do
|
179
|
+
it 'performs map from expression' do
|
180
|
+
input = (1..3).collect { random_number }
|
181
|
+
output = input.collect { |x| 2 * x }
|
182
|
+
|
183
|
+
expect(client.query { map(input, lambda { |a| multiply 2, a }) }).to eq(output)
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'performs map from block' do
|
187
|
+
input = (1..3).collect { random_number }
|
188
|
+
output = input.collect { |x| 2 * x }
|
189
|
+
|
190
|
+
expect(client.query { map(input) { |a| multiply 2, a } }).to eq(output)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe '#foreach' do
|
195
|
+
before(:each) do
|
196
|
+
@refs = (1..3).collect { create_instance[:ref] }
|
197
|
+
|
198
|
+
# Sanity check
|
199
|
+
expect(client.query { @refs.collect { |ref| exists ref } }).to eq(@refs.collect { true })
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'performs foreach from expression' do
|
203
|
+
client.query { foreach @refs, lambda { |a| delete a } }
|
204
|
+
|
205
|
+
expect(client.query { @refs.collect { |ref| exists ref } }).to eq(@refs.collect { false })
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'performs foreach from block' do
|
209
|
+
client.query { foreach(@refs) { |a| delete a } }
|
210
|
+
|
211
|
+
expect(client.query { @refs.collect { |ref| exists ref } }).to eq(@refs.collect { false })
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe '#filter' do
|
216
|
+
it 'performs filter from expression' do
|
217
|
+
expect(client.query { filter([1, 2, 3, 4], lambda { |a| equals modulo(a, 2), 0 }) }).to eq([2, 4])
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'performs filter from block' do
|
221
|
+
expect(client.query { filter([1, 2, 3, 4]) { |a| equals modulo(a, 2), 0 } }).to eq([2, 4])
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe '#take' do
|
226
|
+
it 'performs take' do
|
227
|
+
expect(client.query { take(1, [1, 2]) }).to eq([1])
|
228
|
+
expect(client.query { take(3, [1, 2]) }).to eq([1, 2])
|
229
|
+
expect(client.query { take(-1, [1, 2]) }).to eq([])
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe '#drop' do
|
234
|
+
it 'performs drop' do
|
235
|
+
expect(client.query { drop(1, [1, 2]) }).to eq([2])
|
236
|
+
expect(client.query { drop(3, [1, 2]) }).to eq([])
|
237
|
+
expect(client.query { drop(-1, [1, 2]) }).to eq([1, 2])
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe '#prepend' do
|
242
|
+
it 'performs prepend' do
|
243
|
+
expect(client.query { prepend([4, 5, 6], [1, 2, 3]) }).to eq([1, 2, 3, 4, 5, 6])
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
describe '#append' do
|
248
|
+
it 'performs append' do
|
249
|
+
expect(client.query { append([1, 2, 3], [4, 5, 6]) }).to eq([1, 2, 3, 4, 5, 6])
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe '#get' do
|
254
|
+
it 'performs get' do
|
255
|
+
instance = create_instance
|
256
|
+
|
257
|
+
expect(client.query { get instance[:ref] }).to eq(instance)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
describe '#paginate' do
|
262
|
+
before do
|
263
|
+
@x_value = random_number
|
264
|
+
@x_refs = (1..3).collect { create_instance(x: @x_value)[:ref] }
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'performs paginate' do
|
268
|
+
set = Fauna::Query.match(@test_by_x, @x_value)
|
269
|
+
|
270
|
+
expect(get_set_data(set, size: 1)).to eq(@x_refs)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'performs paginate with sources' do
|
274
|
+
response = {
|
275
|
+
data: @x_refs.collect do |ref|
|
276
|
+
{ sources: [Fauna::SetRef.new(match: @test_by_x, terms: @x_value)], value: ref }
|
277
|
+
end
|
278
|
+
}
|
279
|
+
|
280
|
+
expect(client.query { paginate(match(@test_by_x, @x_value), sources: true) }).to eq(response)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
describe '#exists' do
|
285
|
+
it 'performs exists' do
|
286
|
+
ref = create_instance[:ref]
|
287
|
+
|
288
|
+
expect(client.query { exists ref }).to be(true)
|
289
|
+
client.query { delete ref }
|
290
|
+
expect(client.query { exists ref }).to be(false)
|
291
|
+
|
292
|
+
# Sanity check
|
293
|
+
expect { client.query { get ref } }.to raise_error(Fauna::NotFound)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
describe '#count' do
|
298
|
+
before do
|
299
|
+
@x_value = random_number
|
300
|
+
@x_refs = (1..3).collect { create_instance(x: @x_value)[:ref] }
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'performs count' do
|
304
|
+
set = Fauna::Query.match(@test_by_x, @x_value)
|
305
|
+
|
306
|
+
# Count is only approximate; should be equal to @x_refs.length
|
307
|
+
expect(client.query { count set }).to be_a(Integer)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
describe '#create' do
|
312
|
+
it 'performs create' do
|
313
|
+
instance = client.query { create(@test_class, {}) }
|
314
|
+
|
315
|
+
expect(instance[:class]).to eq(@test_class)
|
316
|
+
expect(client.query { exists instance[:ref] }).to be(true)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
describe '#update' do
|
321
|
+
it 'performs update' do
|
322
|
+
x = random_number
|
323
|
+
y = random_number
|
324
|
+
ref = create_instance(x: x)[:ref]
|
325
|
+
|
326
|
+
instance = client.query { update(ref, data: { y: y }) }
|
327
|
+
expect(instance[:data]).to eq(x: x, y: y)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
describe '#replace' do
|
332
|
+
it 'performs replace' do
|
333
|
+
x = random_number
|
334
|
+
y = random_number
|
335
|
+
ref = create_instance(x: x)[:ref]
|
336
|
+
|
337
|
+
instance = client.query { replace(ref, data: { y: y }) }
|
338
|
+
expect(instance[:data]).to eq(y: y)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe '#delete' do
|
343
|
+
it 'performs delete' do
|
344
|
+
ref = create_instance[:ref]
|
345
|
+
|
346
|
+
client.query { delete ref }
|
347
|
+
expect(client.query { exists ref }).to be(false)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
describe '#insert' do
|
352
|
+
it 'performs insert' do
|
353
|
+
instance = create_instance
|
354
|
+
ref = instance[:ref]
|
355
|
+
ts = instance[:ts]
|
356
|
+
|
357
|
+
prev_ts = ts - 1
|
358
|
+
value = random_number
|
359
|
+
client.query { insert(ref, prev_ts, :create, data: { x: value }) }
|
360
|
+
|
361
|
+
expect(client.query { get(ref, ts: prev_ts) }[:data]).to eq(x: value)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
describe '#remove' do
|
366
|
+
it 'performs remove' do
|
367
|
+
# Create the instance
|
368
|
+
instance = create_instance
|
369
|
+
ref = instance[:ref]
|
370
|
+
|
371
|
+
# Change the instance
|
372
|
+
new_instance = client.query { replace(ref, data: { x: random_number }) }
|
373
|
+
expect(client.query { get(ref) }).to eq(new_instance)
|
374
|
+
|
375
|
+
# Delete the event
|
376
|
+
client.query { remove(ref, new_instance[:ts], :create) }
|
377
|
+
|
378
|
+
# Assert it changed
|
379
|
+
expect(client.query { get(ref) }).to eq(instance)
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
describe 'sets' do
|
384
|
+
before do
|
385
|
+
@x_value = random_number
|
386
|
+
@y_value = random_number
|
387
|
+
|
388
|
+
@ref_x = create_instance(x: @x_value)[:ref]
|
389
|
+
@ref_y = create_instance(y: @y_value)[:ref]
|
390
|
+
@ref_xy = create_instance(x: @x_value, y: @y_value)[:ref]
|
391
|
+
end
|
392
|
+
|
393
|
+
describe '#match' do
|
394
|
+
it 'performs match' do
|
395
|
+
set = Fauna::Query.expr { match(@test_by_x, @x_value) }
|
396
|
+
expect(get_set_data(set)).to contain_exactly(@ref_x, @ref_xy)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
describe '#union' do
|
401
|
+
it 'performs union' do
|
402
|
+
set = Fauna::Query.expr { union(match(@test_by_x, @x_value), match(@test_by_y, @y_value)) }
|
403
|
+
expect(get_set_data(set)).to contain_exactly(@ref_x, @ref_y, @ref_xy)
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
describe '#intersection' do
|
408
|
+
it 'performs intersection' do
|
409
|
+
set = Fauna::Query.expr { intersection(match(@test_by_x, @x_value), match(@test_by_y, @y_value)) }
|
410
|
+
expect(get_set_data(set)).to contain_exactly(@ref_xy)
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
describe '#difference' do
|
415
|
+
it 'performs difference' do
|
416
|
+
set = Fauna::Query.expr { difference(match(@test_by_x, @x_value), match(@test_by_y, @y_value)) }
|
417
|
+
expect(get_set_data(set)).to contain_exactly(@ref_x)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
describe '#distinct' do
|
423
|
+
before do
|
424
|
+
over_z = client.query do
|
425
|
+
create ref('indexes'), name: 'query_over_z', source: @test_class, values: [{ path: 'data.z' }]
|
426
|
+
end
|
427
|
+
wait_for_active(over_z[:ref])
|
428
|
+
@test_over_z = over_z[:ref]
|
429
|
+
|
430
|
+
@refs = []
|
431
|
+
@refs << client.query { create @test_class, data: { z: 0 } }[:ref]
|
432
|
+
@refs << client.query { create @test_class, data: { z: 1 } }[:ref]
|
433
|
+
@refs << client.query { create @test_class, data: { z: 1 } }[:ref]
|
434
|
+
end
|
435
|
+
|
436
|
+
it 'performs distinct' do
|
437
|
+
set = Fauna::Query.match(@test_over_z)
|
438
|
+
distinct = Fauna::Query.distinct(set)
|
439
|
+
|
440
|
+
expect(get_set_data(set)).to eq([0, 1, 1])
|
441
|
+
expect(get_set_data(distinct)).to eq([0, 1])
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
describe '#join' do
|
446
|
+
before do
|
447
|
+
@x_value = random_number
|
448
|
+
@join_refs = (1..3).collect { create_instance(x: @x_value)[:ref] }
|
449
|
+
@assoc_refs = @join_refs.collect { |ref| create_instance(y: ref)[:ref] }
|
450
|
+
end
|
451
|
+
|
452
|
+
context 'with expression' do
|
453
|
+
it 'performs join' do
|
454
|
+
source = Fauna::Query.match(@test_by_x, @x_value)
|
455
|
+
expect(get_set_data(source)).to eq(@join_refs)
|
456
|
+
|
457
|
+
# Get associated refs
|
458
|
+
set = Fauna::Query.expr { join(source, lambda { |a| match(@test_by_y, a) }) }
|
459
|
+
expect(get_set_data(set)).to eq(@assoc_refs)
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
context 'with block' do
|
464
|
+
it 'performs join' do
|
465
|
+
source = Fauna::Query.match(@test_by_x, @x_value)
|
466
|
+
expect(get_set_data(source)).to eq(@join_refs)
|
467
|
+
|
468
|
+
# Get associated refs
|
469
|
+
set = Fauna::Query.expr { join(source) { |a| match(@test_by_y, a) } }
|
470
|
+
expect(get_set_data(set)).to eq(@assoc_refs)
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
describe 'authentication' do
|
476
|
+
before do
|
477
|
+
@password = random_string
|
478
|
+
@user = client.query { create @test_class, credentials: { password: @password } }
|
479
|
+
end
|
480
|
+
|
481
|
+
describe '#login' do
|
482
|
+
it 'performs login' do
|
483
|
+
token = client.query { login @user[:ref], password: @password }
|
484
|
+
user_client = get_client secret: token[:secret]
|
485
|
+
|
486
|
+
expect(user_client.query { select(:ref, get(ref('tokens/self'))) }).to eq(token[:ref])
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
describe '#logout' do
|
491
|
+
it 'performs logout' do
|
492
|
+
token = client.query { login @user[:ref], password: @password }
|
493
|
+
user_client = get_client secret: token[:secret]
|
494
|
+
|
495
|
+
expect(user_client.query { logout true }).to be(true)
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
describe '#identify' do
|
500
|
+
it 'performs identify' do
|
501
|
+
expect(client.query { identify(@user[:ref], @password) }).to be(true)
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
describe '#concat' do
|
507
|
+
it 'performs concat' do
|
508
|
+
expect(client.query { concat ['a', 'b', 'c'] }).to eq('abc')
|
509
|
+
expect(client.query { concat [] }).to eq('')
|
510
|
+
end
|
511
|
+
|
512
|
+
it 'performs concat with separator' do
|
513
|
+
expect(client.query { concat(['a', 'b', 'c'], '.') }).to eq('a.b.c')
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
describe '#casefold' do
|
518
|
+
it 'performs casefold' do
|
519
|
+
expect(client.query { casefold 'Hen Wen' }).to eq('hen wen')
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
describe '#test' do
|
524
|
+
it 'performs time' do
|
525
|
+
# `.round 9` is necessary because MRI 1.9.3 stores with greater precision than just nanoseconds.
|
526
|
+
# This cuts it down to just nanoseconds so that the times compare as equal.
|
527
|
+
time = Time.at(0, 123_456.789).round 9
|
528
|
+
expect(client.query { time '1970-01-01T00:00:00.123456789Z' }).to eq(time)
|
529
|
+
|
530
|
+
# 'now' refers to the current time.
|
531
|
+
expect(client.query { time 'now' }).to be_a(Time)
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
describe '#epoch' do
|
536
|
+
it 'performs epoch for seconds' do
|
537
|
+
secs = random_number
|
538
|
+
expect(client.query { epoch(secs, 'second') }).to eq(Time.at(secs).utc)
|
539
|
+
end
|
540
|
+
|
541
|
+
it 'performs epoch for nanoseconds' do
|
542
|
+
nanos = random_number
|
543
|
+
expect(client.query { epoch(nanos, 'nanosecond') }).to eq(Time.at(Rational(nanos, 1_000_000_000)).utc)
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
describe '#date' do
|
548
|
+
it 'performs date' do
|
549
|
+
expect(client.query { date('1970-01-01') }).to eq(Date.new(1970, 1, 1))
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
describe '#equals' do
|
554
|
+
it 'performs equals' do
|
555
|
+
expect(client.query { equals(1, 1, 1) }).to be(true)
|
556
|
+
expect(client.query { equals(1, 1, 2) }).to be(false)
|
557
|
+
expect(client.query { equals 1 }).to be(true)
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
describe '#contains' do
|
562
|
+
it 'performs contains' do
|
563
|
+
obj = { a: { b: 1 } }
|
564
|
+
|
565
|
+
expect(client.query { contains([:a, :b], obj) }).to be(true)
|
566
|
+
expect(client.query { contains(:a, obj) }).to be(true)
|
567
|
+
expect(client.query { contains([:a, :c], obj) }).to be(false)
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
571
|
+
describe '#select' do
|
572
|
+
it 'performs select with hash' do
|
573
|
+
obj = { a: { b: 1 } }
|
574
|
+
|
575
|
+
expect(client.query { select(:a, obj) }).to eq(b: 1)
|
576
|
+
expect(client.query { select([:a, :b], obj) }).to eq(1)
|
577
|
+
expect(client.query { select(:c, obj, default: nil) }).to be_nil
|
578
|
+
expect { client.query { select(:c, obj) } }.to raise_error(Fauna::NotFound)
|
579
|
+
end
|
580
|
+
|
581
|
+
it 'performs select with array' do
|
582
|
+
arr = [1, 2, 3]
|
583
|
+
|
584
|
+
expect(client.query { select(2, arr) }).to eq(3)
|
585
|
+
expect { client.query { select(3, arr) } }.to raise_error(Fauna::NotFound)
|
586
|
+
end
|
587
|
+
end
|
588
|
+
|
589
|
+
describe '#add' do
|
590
|
+
it 'performs add' do
|
591
|
+
expect(client.query { add(2, 3, 5) }).to eq(10)
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
describe '#multiply' do
|
596
|
+
it 'performs multiply' do
|
597
|
+
expect(client.query { multiply(2, 3, 5) }).to eq(30)
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
describe '#subtract' do
|
602
|
+
it 'performs subtract' do
|
603
|
+
expect(client.query { subtract(2, 3, 5) }).to eq(-6)
|
604
|
+
expect(client.query { subtract(2) }).to eq(2)
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
describe '#divide' do
|
609
|
+
it 'performs divide' do
|
610
|
+
expect(client.query { divide(2.0, 3, 5) }).to eq(2.0 / 15)
|
611
|
+
expect(client.query { divide(2) }).to eq(2)
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
describe '#modulo' do
|
616
|
+
it 'performs modulo' do
|
617
|
+
expect(client.query { modulo(5, 2) }).to eq(1)
|
618
|
+
expect(client.query { modulo(15, 10, 2) }).to eq(1)
|
619
|
+
expect(client.query { modulo(2) }).to eq(2)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
describe '#lt' do
|
624
|
+
it 'performs lt' do
|
625
|
+
expect(client.query { lt(1, 2) }).to be(true)
|
626
|
+
expect(client.query { lt(2, 2) }).to be(false)
|
627
|
+
end
|
628
|
+
end
|
629
|
+
|
630
|
+
describe '#lte' do
|
631
|
+
it 'performs lte' do
|
632
|
+
expect(client.query { lte(1, 1) }).to be(true)
|
633
|
+
expect(client.query { lte(2, 1) }).to be(false)
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
describe '#gt' do
|
638
|
+
it 'performs gt' do
|
639
|
+
expect(client.query { gt(2, 1) }).to be(true)
|
640
|
+
expect(client.query { gt(2, 2) }).to be(false)
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
describe '#gte' do
|
645
|
+
it 'performs gte' do
|
646
|
+
expect(client.query { gte(2, 2) }).to be(true)
|
647
|
+
expect(client.query { gte(2, 3) }).to be(false)
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
describe '#and_' do
|
652
|
+
it 'performs and' do
|
653
|
+
expect(client.query { and_(true, true, false) }).to be(false)
|
654
|
+
expect(client.query { and_(true, true, true) }).to be(true)
|
655
|
+
expect(client.query { and_(true) }).to be(true)
|
656
|
+
expect(client.query { and_(false) }).to be(false)
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
describe '#or_' do
|
661
|
+
it 'performs or' do
|
662
|
+
expect(client.query { or_(false, false, true) }).to be(true)
|
663
|
+
expect(client.query { or_(false, false, false) }).to be(false)
|
664
|
+
expect(client.query { or_(true) }).to be(true)
|
665
|
+
expect(client.query { or_(false) }).to be(false)
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
describe '#not_' do
|
670
|
+
it 'performs not' do
|
671
|
+
expect(client.query { not_(true) }).to be(false)
|
672
|
+
expect(client.query { not_(false) }).to be(true)
|
673
|
+
end
|
674
|
+
end
|
675
|
+
end
|