CloudSesame 0.7.5 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +14 -12
- data/Guardfile +2 -2
- data/cloud_sesame.gemspec +2 -2
- data/coverage/.last_run.json +1 -1
- data/coverage/.resultset.json +1363 -248
- data/lib/cloud_sesame/domain/base.rb +1 -1
- data/lib/cloud_sesame/query/ast/abstract/multi_expression_operator.rb +3 -4
- data/lib/cloud_sesame/query/ast/abstract/value.rb +10 -2
- data/lib/cloud_sesame/query/ast/date_value.rb +1 -4
- data/lib/cloud_sesame/query/ast/literal.rb +20 -12
- data/lib/cloud_sesame/query/ast/{field_array.rb → multi_expression_operator_children.rb} +8 -2
- data/lib/cloud_sesame/query/ast/not.rb +1 -7
- data/lib/cloud_sesame/query/ast/range_value.rb +43 -28
- data/lib/cloud_sesame/query/ast/root.rb +2 -4
- data/lib/cloud_sesame/query/ast/value.rb +1 -9
- data/lib/cloud_sesame/query/builder.rb +9 -11
- data/lib/cloud_sesame/query/domain/block.rb +1 -3
- data/lib/cloud_sesame/query/domain/chaining_block.rb +3 -4
- data/lib/cloud_sesame/query/domain/literal.rb +1 -3
- data/lib/cloud_sesame/query/dsl/bind_caller.rb +13 -6
- data/lib/cloud_sesame/query/dsl/{field_array_methods.rb → literal_chaining_methods.rb} +1 -6
- data/lib/cloud_sesame/query/dsl/{field_accessors.rb → literal_methods.rb} +1 -1
- data/lib/cloud_sesame/query/node/fuzziness.rb +1 -1
- data/lib/cloud_sesame.rb +4 -3
- data/spec/cloud_sesame/query/ast/abstract/multi_expression_operator_spec.rb +5 -1
- data/spec/cloud_sesame/query/ast/field_array_spec.rb +57 -0
- data/spec/cloud_sesame/query/ast/literal_spec.rb +136 -0
- data/spec/cloud_sesame/query/ast/not_spec.rb +30 -0
- data/spec/cloud_sesame/query/ast/phrase_spec.rb +20 -0
- data/spec/cloud_sesame/query/ast/range_value_spec.rb +245 -30
- data/spec/cloud_sesame/query/ast/string_value_spec.rb +39 -0
- data/spec/cloud_sesame/query/ast/term_spec.rb +20 -0
- data/spec/cloud_sesame/query/ast/value_spec.rb +109 -0
- data/spec/cloud_sesame/query/builder_spec.rb +4 -4
- data/spec/cloud_sesame/query/domain/block_spec.rb +3 -3
- data/spec/cloud_sesame/query/dsl/{field_array_methods_spec.rb → literal_chaining_methods_spec.rb} +1 -1
- data/spec/cloud_sesame/query/dsl/{field_accessors_spec.rb → literal_methods_spec.rb} +3 -3
- data/spec/cloud_sesame/query/node/query_spec.rb +22 -0
- data/spec/profiling_spec.rb +155 -155
- metadata +23 -9
@@ -0,0 +1,136 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module AST
|
4
|
+
describe Literal do
|
5
|
+
|
6
|
+
let(:field) { :literal }
|
7
|
+
let(:value) { "value" }
|
8
|
+
let(:options) { {} }
|
9
|
+
subject { Literal.new(field, value, options) }
|
10
|
+
|
11
|
+
describe '#initialize' do
|
12
|
+
context 'when the value is given' do
|
13
|
+
|
14
|
+
it 'should create an lazy object' do
|
15
|
+
expect(LazyObject).to receive(:new)
|
16
|
+
subject
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'and the options contains field type' do
|
20
|
+
let(:field_type) { class_double(Value) }
|
21
|
+
let(:options) {{ type: field_type }}
|
22
|
+
before { allow(LazyObject).to receive(:new) { |&b| b.call } }
|
23
|
+
|
24
|
+
it 'should parse value with field type inside the lazy object' do
|
25
|
+
expect(field_type).to receive(:parse).with(value)
|
26
|
+
subject
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'and the options does not contain type' do
|
31
|
+
before { allow(LazyObject).to receive(:new) { |&b| b.call } }
|
32
|
+
|
33
|
+
it 'should create a lazy object' do
|
34
|
+
expect(Value).to receive(:parse).with(value)
|
35
|
+
subject
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when the value is nil' do
|
42
|
+
let(:value) { nil }
|
43
|
+
it 'should not parse the value using lazy object' do
|
44
|
+
expect(LazyObject).to_not receive(:new)
|
45
|
+
subject
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when the options is nil' do
|
50
|
+
let(:options) { nil }
|
51
|
+
it 'should use the default options' do
|
52
|
+
expect(subject.options).to eq({ type: Value })
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#applied' do
|
58
|
+
let(:included) { true }
|
59
|
+
context 'when value is given' do
|
60
|
+
it 'should return an hash contains field value and included' do
|
61
|
+
expect(subject.applied(included)).to include(
|
62
|
+
field: field,
|
63
|
+
value: CloudSesame::Query::AST::StringValue.new(value),
|
64
|
+
included: included
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
context 'when value is not given' do
|
69
|
+
let(:value) { nil }
|
70
|
+
it 'should return nothing' do
|
71
|
+
expect(subject.applied(included)).to be_nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#actual_field_name' do
|
77
|
+
context 'when options contains :as value' do
|
78
|
+
let(:actual_field_name) { :field1 }
|
79
|
+
let(:options) { { as: actual_field_name } }
|
80
|
+
it 'should use the :as value as the actual field name' do
|
81
|
+
expect(subject.actual_field_name).to eq actual_field_name
|
82
|
+
end
|
83
|
+
end
|
84
|
+
context 'when options does not contain :as value' do
|
85
|
+
it 'should use the field as the actual field name' do
|
86
|
+
expect(subject.actual_field_name).to eq field
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#compile' do
|
92
|
+
context 'when value is not present' do
|
93
|
+
let(:value) { nil }
|
94
|
+
it 'should return nothing' do
|
95
|
+
expect(subject.compile).to be_nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
context 'when value is present' do
|
99
|
+
it 'should compile the value' do
|
100
|
+
expect(subject.value).to receive(:compile)
|
101
|
+
subject.compile
|
102
|
+
end
|
103
|
+
it 'should compile into standard format by default' do
|
104
|
+
expect(subject.compile).to eq "#{ field }:#{ subject.value.compile }"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
context 'when request detailed format' do
|
108
|
+
it 'should compile into detailed format' do
|
109
|
+
expect(subject.compile(true)).to eq("field='#{ field }' #{ subject.value.compile }")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#is_for' do
|
115
|
+
let(:new_field) { :new_literal }
|
116
|
+
it 'should set the field' do
|
117
|
+
expect{ subject.is_for(new_field, nil) }.to change{ subject.field }.from(field).to(new_field)
|
118
|
+
end
|
119
|
+
context 'when options is present' do
|
120
|
+
let(:options) { { old: "value" } }
|
121
|
+
let(:new_options) { { new: "new value" } }
|
122
|
+
it 'should take the options and merge with existing options' do
|
123
|
+
expect{ subject.is_for(field, new_options) }.to change{ subject.options }.from(options.clone).to(options.merge(new_options))
|
124
|
+
end
|
125
|
+
end
|
126
|
+
context 'when options is not present' do
|
127
|
+
it 'should do nothing with the existing options' do
|
128
|
+
expect{ subject.is_for(field, nil) }.to_not change{ subject.options }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module AST
|
4
|
+
describe Not do
|
5
|
+
|
6
|
+
let(:context) {{}}
|
7
|
+
subject { Not.new(context) }
|
8
|
+
|
9
|
+
it 'should be a type of operator' do
|
10
|
+
expect(Not.ancestors).to include(Abstract::SingleExpressionOperator)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should have symbol :not' do
|
14
|
+
expect(Not::SYMBOL).to eq :not
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#applied' do
|
18
|
+
let(:included) { false }
|
19
|
+
let(:child) { instance_double(Abstract::SingleExpressionOperator) }
|
20
|
+
before { subject << child }
|
21
|
+
it 'should inverse included and broadcast to it\'s child' do
|
22
|
+
expect(child).to receive(:applied).with(!included)
|
23
|
+
subject.applied(included)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module AST
|
4
|
+
describe Phrase do
|
5
|
+
it 'should be a type of operator' do
|
6
|
+
expect(Phrase.ancestors).to include(Abstract::SingleExpressionOperator)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should have symbol :term' do
|
10
|
+
expect(Phrase::SYMBOL).to eq :phrase
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be set to detailed' do
|
14
|
+
expect(Phrase::DETAILED).to eq true
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -3,48 +3,263 @@ module CloudSesame
|
|
3
3
|
module AST
|
4
4
|
describe RangeValue do
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
let(:type) { nil }
|
7
|
+
subject { RangeValue.new(initial_value, type) }
|
8
|
+
|
9
|
+
describe '#initialize' do
|
10
|
+
|
11
|
+
shared_examples 'determine lower bound, begin, end' do
|
12
|
+
it 'should determine the lower bound' do
|
13
|
+
expect(subject.lower_bound).to eq lower_bound
|
14
|
+
end
|
15
|
+
it 'should determine the begin value' do
|
16
|
+
expect(subject.begin).to eq start_value
|
17
|
+
end
|
18
|
+
it 'should determine the end value' do
|
19
|
+
expect(subject.end).to eq end_value
|
20
|
+
end
|
21
|
+
it 'should determine the upper bound' do
|
22
|
+
expect(subject.upper_bound).to eq upper_bound
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
shared_examples 'possible upper bound' do
|
27
|
+
context 'when upper bound is included' do
|
28
|
+
let(:upper_bound) { ']' }
|
29
|
+
include_examples 'determine lower bound, begin, end'
|
10
30
|
end
|
11
|
-
|
12
|
-
|
31
|
+
context 'when upper bound is excluded' do
|
32
|
+
let(:upper_bound) { '}' }
|
33
|
+
include_examples 'determine lower bound, begin, end'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when given a ruby range object' do
|
38
|
+
let(:start_value) { 10 }
|
39
|
+
let(:end_value) { 20 }
|
40
|
+
|
41
|
+
let(:lower_bound) { '[' }
|
42
|
+
context 'when upper bound is included' do
|
43
|
+
let(:upper_bound) { ']' }
|
44
|
+
let(:initial_value) { start_value..end_value }
|
45
|
+
include_examples 'determine lower bound, begin, end'
|
46
|
+
end
|
47
|
+
context 'when lower bound is excluded' do
|
48
|
+
let(:initial_value) { start_value...end_value }
|
49
|
+
let(:upper_bound) { '}' }
|
50
|
+
include_examples 'determine lower bound, begin, end'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when given a aws range string' do
|
55
|
+
let(:start_value) { "10" }
|
56
|
+
let(:end_value) { "20" }
|
57
|
+
let(:initial_value) { "#{ lower_bound }#{ start_value },#{ end_value }#{ upper_bound }" }
|
58
|
+
|
59
|
+
context 'when lower bound is included' do
|
60
|
+
let(:lower_bound) { '[' }
|
61
|
+
include_examples 'possible upper bound'
|
13
62
|
end
|
14
|
-
|
15
|
-
|
63
|
+
context 'when lower bound is excluded' do
|
64
|
+
let(:lower_bound) { '{' }
|
65
|
+
include_examples 'possible upper bound'
|
16
66
|
end
|
17
67
|
end
|
18
68
|
|
19
|
-
context 'when given
|
20
|
-
{
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
69
|
+
context 'when given no initial value' do
|
70
|
+
let(:initial_value) { nil }
|
71
|
+
let(:lower_bound) { "[" }
|
72
|
+
let(:upper_bound) { "]" }
|
73
|
+
let(:start_value) { nil }
|
74
|
+
let(:end_value) { nil }
|
75
|
+
include_examples 'determine lower bound, begin, end'
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when given type' do
|
79
|
+
let(:start_value) { 10 }
|
80
|
+
let(:end_value) { 20 }
|
81
|
+
let(:initial_value) { start_value..end_value }
|
82
|
+
let(:type) { Value }
|
83
|
+
it 'should parse the start and end value with type' do
|
84
|
+
expect(type).to receive(:parse).with(end_value)
|
85
|
+
expect(type).to receive(:parse).with(start_value)
|
86
|
+
subject
|
87
|
+
end
|
88
|
+
it 'should convert start and end value to value object' do
|
89
|
+
expect(subject.begin).to be_kind_of(Abstract::Value)
|
90
|
+
expect(subject.end).to be_kind_of(Abstract::Value)
|
28
91
|
end
|
29
92
|
end
|
30
93
|
|
31
|
-
context 'when given
|
32
|
-
{
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
subject
|
37
|
-
|
38
|
-
|
94
|
+
context 'when given no type' do
|
95
|
+
let(:initial_value) { 10..20 }
|
96
|
+
|
97
|
+
it 'should not parse the start and end value' do
|
98
|
+
expect(type).to_not receive(:parse)
|
99
|
+
subject
|
100
|
+
end
|
101
|
+
it 'should keep the original start and end value' do
|
102
|
+
expect(subject.begin).to be_kind_of(Numeric)
|
103
|
+
expect(subject.end).to be_kind_of(Numeric)
|
39
104
|
end
|
40
105
|
end
|
41
106
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#parse' do
|
110
|
+
let(:begin_value) { 1 }
|
111
|
+
let(:end_value) { 10 }
|
112
|
+
let(:initial_value) { begin_value..end_value }
|
113
|
+
|
114
|
+
it 'should return self' do
|
115
|
+
expect(subject.parse(nil)).to eq subject
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'given type and type respond to parse' do
|
119
|
+
let(:parse_type) { Value }
|
120
|
+
|
121
|
+
context 'and begin and end value is not empty in string form' do
|
122
|
+
it 'should parse the begin and end value' do
|
123
|
+
expect(parse_type).to receive(:parse).with(end_value)
|
124
|
+
expect(parse_type).to receive(:parse).with(begin_value)
|
125
|
+
subject.parse(parse_type)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
context 'and begin and end value is empty in string form' do
|
129
|
+
let(:begin_value) { nil }
|
130
|
+
let(:end_value) { nil }
|
131
|
+
|
132
|
+
it 'should not try to parse the begin and end value' do
|
133
|
+
expect(parse_type).to_not receive(:parse)
|
134
|
+
subject.parse(parse_type)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
context 'given type does not respond to parse' do
|
139
|
+
let(:parse_type) { "Random Type" }
|
140
|
+
before { allow(parse_type).to receive(:respond_to?).and_return(false) }
|
141
|
+
it 'should not try to parse the begin and end value' do
|
142
|
+
expect(parse_type).to_not receive(:parse)
|
143
|
+
subject.parse(parse_type)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
context 'given type is nil' do
|
147
|
+
let(:parse_type) { nil }
|
148
|
+
it 'should not try to parse the begin and end value' do
|
149
|
+
expect(parse_type).to_not receive(:parse)
|
150
|
+
subject.parse(parse_type)
|
47
151
|
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '#begin' do
|
156
|
+
let(:begin_value) { 1 }
|
157
|
+
let(:end_value) { 10 }
|
158
|
+
let(:initial_value) { begin_value..end_value }
|
159
|
+
it 'should return the begin value' do
|
160
|
+
expect(subject.begin).to eq begin_value
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe '#end' do
|
165
|
+
let(:begin_value) { 1 }
|
166
|
+
let(:end_value) { 10 }
|
167
|
+
let(:initial_value) { begin_value..end_value }
|
168
|
+
it 'should return the end value' do
|
169
|
+
expect(subject.end).to eq end_value
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '#lower_bound' do
|
174
|
+
let(:lower_bound) { "{" }
|
175
|
+
let(:upper_bound) { "}" }
|
176
|
+
let(:begin_value) { "1" }
|
177
|
+
let(:end_value) { "10" }
|
178
|
+
let(:initial_value) { lower_bound + begin_value + ',' + end_value + upper_bound }
|
179
|
+
it 'should return the lower bound symbol' do
|
180
|
+
expect(subject.lower_bound).to eq lower_bound
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe '#upper_bound' do
|
185
|
+
let(:lower_bound) { "{" }
|
186
|
+
let(:upper_bound) { "}" }
|
187
|
+
let(:begin_value) { "1" }
|
188
|
+
let(:end_value) { "10" }
|
189
|
+
let(:initial_value) { lower_bound + begin_value + ',' + end_value + upper_bound }
|
190
|
+
it 'should return the upper bound symbol' do
|
191
|
+
expect(subject.upper_bound).to eq upper_bound
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '#gt' do
|
196
|
+
let(:value) { 100 }
|
197
|
+
let(:initial_value) { nil }
|
198
|
+
it 'should set the begin value' do
|
199
|
+
expect{ subject.gt(value) }.to change{ subject.begin }.from(nil).to(value)
|
200
|
+
end
|
201
|
+
it 'should set the lower bound to be excluded' do
|
202
|
+
subject.gt(value)
|
203
|
+
expect(subject.lower_bound).to eq '{'
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe '#gte' do
|
208
|
+
let(:value) { 101 }
|
209
|
+
let(:initial_value) { nil }
|
210
|
+
it 'should set the begin value' do
|
211
|
+
expect{ subject.gte(value) }.to change{ subject.begin }.from(nil).to(value)
|
212
|
+
end
|
213
|
+
it 'should set the lower bound to be excluded' do
|
214
|
+
subject.gte(value)
|
215
|
+
expect(subject.lower_bound).to eq '['
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#lt' do
|
220
|
+
let(:value) { 100 }
|
221
|
+
let(:initial_value) { nil }
|
222
|
+
it 'should set the begin value' do
|
223
|
+
expect{ subject.lt(value) }.to change{ subject.end }.from(nil).to(value)
|
224
|
+
end
|
225
|
+
it 'should set the lower bound to be excluded' do
|
226
|
+
subject.lt(value)
|
227
|
+
expect(subject.upper_bound).to eq '}'
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '#lte' do
|
232
|
+
let(:value) { 100 }
|
233
|
+
let(:initial_value) { nil }
|
234
|
+
it 'should set the begin value' do
|
235
|
+
expect{ subject.lte(value) }.to change{ subject.end }.from(nil).to(value)
|
236
|
+
end
|
237
|
+
it 'should set the lower bound to be excluded' do
|
238
|
+
subject.lte(value)
|
239
|
+
expect(subject.upper_bound).to eq ']'
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe '#to_s' do
|
244
|
+
let(:initial_value) { 10..255 }
|
245
|
+
it 'should return the compiled value' do
|
246
|
+
expect(subject.to_s).to eq subject.compile
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe '#==' do
|
251
|
+
let(:initial_value) { 10...255 }
|
252
|
+
let(:object) { "[10,255}" }
|
253
|
+
it 'should convert the object comparing with to RangeValue' do
|
254
|
+
subject
|
255
|
+
expect(RangeValue).to receive(:new).with(object, Value).and_call_original
|
256
|
+
subject == object
|
257
|
+
end
|
258
|
+
it 'should return true when the parsed value are the same' do
|
259
|
+
expect(subject == object).to eq true
|
260
|
+
end
|
261
|
+
it 'should return false when the parsed value is different' do
|
262
|
+
expect(subject == (10..255)).to eq false
|
48
263
|
end
|
49
264
|
end
|
50
265
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module AST
|
4
|
+
describe StringValue do
|
5
|
+
|
6
|
+
describe '.parse' do
|
7
|
+
let(:value) { "value" }
|
8
|
+
|
9
|
+
it 'should instantiate a StringValue' do
|
10
|
+
expect(StringValue).to receive(:new).with(value)
|
11
|
+
StringValue.parse(value)
|
12
|
+
end
|
13
|
+
it 'should return the StringValue' do
|
14
|
+
expect(StringValue.parse(value)).to be_kind_of(StringValue)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.compile' do
|
19
|
+
subject { StringValue.new(value) }
|
20
|
+
|
21
|
+
context 'when value is not present' do
|
22
|
+
let(:value) { nil }
|
23
|
+
it 'should return nothing' do
|
24
|
+
expect(subject.compile).to eq nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
context 'when value is present' do
|
28
|
+
let(:value) { "value" }
|
29
|
+
it 'should return the escaped the value' do
|
30
|
+
expect(subject.compile).to eq "'#{ value }'"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module AST
|
4
|
+
describe Term do
|
5
|
+
it 'should be a type of operator' do
|
6
|
+
expect(Term.ancestors).to include(Abstract::SingleExpressionOperator)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should have symbol :term' do
|
10
|
+
expect(Term::SYMBOL).to eq :term
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be set to detailed' do
|
14
|
+
expect(Term::DETAILED).to eq true
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
module CloudSesame
|
4
|
+
module Query
|
5
|
+
module AST
|
6
|
+
describe Value do
|
7
|
+
|
8
|
+
describe '.map_type' do
|
9
|
+
it 'should return self when type does not match' do
|
10
|
+
expect(Value.map_type(:random)).to eq(Value)
|
11
|
+
end
|
12
|
+
it 'should return the class matched the type' do
|
13
|
+
expect(Value.map_type(:string)).to eq(StringValue)
|
14
|
+
expect(Value.map_type(:numeric)).to eq(NumericValue)
|
15
|
+
expect(Value.map_type(:datetime)).to eq(DateValue)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.parse' do
|
20
|
+
context 'when value is a RangeValue object' do
|
21
|
+
let(:begin_value) { 100 }
|
22
|
+
let(:end_value) { 200 }
|
23
|
+
let(:value) { RangeValue.new(begin_value..end_value) }
|
24
|
+
it 'should parse the RangeValue' do
|
25
|
+
expect(value).to receive(:parse).with(Value).and_call_original
|
26
|
+
expect(Value.parse(value)).to eq value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
context 'when value is an ruby range object' do
|
30
|
+
let(:begin_value) { 100 }
|
31
|
+
let(:end_value) { 200 }
|
32
|
+
let(:value) { begin_value..end_value }
|
33
|
+
it 'should initialize a RangeValue' do
|
34
|
+
expect(RangeValue).to receive(:new).with(value, Value).and_call_original
|
35
|
+
expect(Value.parse(value)).to be_kind_of(RangeValue)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
context 'when value is a AWS range string' do
|
39
|
+
let(:lower_bound) { '{' }
|
40
|
+
let(:upper_bound) { '}' }
|
41
|
+
let(:begin_value) { 100 }
|
42
|
+
let(:end_value) { 200 }
|
43
|
+
let(:value) { "#{ lower_bound }#{ begin_value },#{ end_value }#{ upper_bound }" }
|
44
|
+
it 'should initialize a RangeValue' do
|
45
|
+
expect(RangeValue).to receive(:new).with(value, Value).and_call_original
|
46
|
+
expect(Value.parse(value)).to be_kind_of(RangeValue)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
context 'when value is a numeric value' do
|
50
|
+
let(:value) { 10 }
|
51
|
+
it 'should initialize a NumericValue' do
|
52
|
+
expect(NumericValue).to receive(:new).with(value, Value).and_call_original
|
53
|
+
expect(Value.parse(value)).to be_kind_of(NumericValue)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
context 'when value is a string contains numeric' do
|
57
|
+
let(:value) { "10" }
|
58
|
+
it 'should initialize a NumericValue' do
|
59
|
+
expect(NumericValue).to receive(:new).with(value, Value).and_call_original
|
60
|
+
expect(Value.parse(value)).to be_kind_of(NumericValue)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
context 'when value is not neither a range, numeric or range' do
|
64
|
+
let(:value) { [10] }
|
65
|
+
it 'should initialize a NumericValue' do
|
66
|
+
expect(StringValue).to receive(:new).with(value, Value).and_call_original
|
67
|
+
expect(Value.parse(value)).to be_kind_of(StringValue)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '.range_value?' do
|
73
|
+
it 'should return true when value is a ruby range object' do
|
74
|
+
expect(Value.range_value?(1..20)).to eq true
|
75
|
+
end
|
76
|
+
it 'should return true when value is a aws range string' do
|
77
|
+
expect(Value.range_value?("[1,20]")).to eq true
|
78
|
+
expect(Value.range_value?("[1,20}")).to eq true
|
79
|
+
expect(Value.range_value?("{,20]")).to eq true
|
80
|
+
expect(Value.range_value?("{1,}")).to eq true
|
81
|
+
end
|
82
|
+
it 'should return false when value is not a range' do
|
83
|
+
expect(Value.range_value?("abc")).to eq false
|
84
|
+
expect(Value.range_value?(['[', 2, 3, '}'])).to eq false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'numeric_value?' do
|
89
|
+
it 'should return true when value is a integer, float, or bigdecimal' do
|
90
|
+
expect(Value.numeric_value?(1)).to eq true
|
91
|
+
expect(Value.numeric_value?(0.99)).to eq true
|
92
|
+
expect(Value.numeric_value?(BigDecimal.new("10"))).to eq true
|
93
|
+
end
|
94
|
+
it 'should return true when value matches string numeric format' do
|
95
|
+
expect(Value.numeric_value?("1")).to eq true
|
96
|
+
expect(Value.numeric_value?("0.99")).to eq true
|
97
|
+
end
|
98
|
+
it 'should return false when value is not a numeric' do
|
99
|
+
expect(Value.numeric_value?("abc")).to eq false
|
100
|
+
expect(Value.numeric_value?([1, 2, 3])).to eq false
|
101
|
+
expect(Value.numeric_value?(h: 2)).to eq false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require_relative 'dsl/applied_filter_query_spec'
|
2
|
-
require_relative 'dsl/
|
2
|
+
require_relative 'dsl/literal_methods_spec'
|
3
3
|
|
4
4
|
module CloudSesame
|
5
5
|
module Query
|
@@ -9,11 +9,11 @@ module CloudSesame
|
|
9
9
|
subject { Builder.new({}, "Searchable") }
|
10
10
|
end
|
11
11
|
|
12
|
-
it_behaves_like DSL::
|
12
|
+
it_behaves_like DSL::LiteralMethods do
|
13
13
|
subject { Builder.new({}, "Searchable") }
|
14
14
|
before {
|
15
|
-
Builder.send(:include, DSL::
|
16
|
-
Domain::Block.send(:include, DSL::
|
15
|
+
Builder.send(:include, DSL::LiteralMethods)
|
16
|
+
Domain::Block.send(:include, DSL::LiteralMethods)
|
17
17
|
allow(_scope).to receive(:context).and_return(context)
|
18
18
|
}
|
19
19
|
end
|