CloudSesame 0.6.8 → 0.7.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/.editorconfig +12 -0
- data/.gitignore +1 -1
- data/Gemfile.lock +13 -13
- data/Guardfile +1 -0
- data/cloud_sesame.gemspec +2 -2
- data/coverage/.last_run.json +1 -1
- data/coverage/.resultset.json +679 -591
- data/lib/cloud_sesame/config/credential.rb +6 -6
- data/lib/cloud_sesame/context.rb +0 -5
- data/lib/cloud_sesame/domain/base.rb +147 -128
- data/lib/cloud_sesame/domain/client.rb +25 -25
- data/lib/cloud_sesame/domain/client_module/caching/base.rb +19 -23
- data/lib/cloud_sesame/domain/client_module/caching/no_cache.rb +11 -11
- data/lib/cloud_sesame/domain/client_module/caching/rails_cache.rb +32 -28
- data/lib/cloud_sesame/domain/client_module/caching.rb +19 -28
- data/lib/cloud_sesame/domain/client_module/retry.rb +6 -6
- data/lib/cloud_sesame/domain/config.rb +6 -6
- data/lib/cloud_sesame/query/ast/abstract/multi_expression_operator.rb +37 -0
- data/lib/cloud_sesame/query/ast/abstract/operator.rb +27 -0
- data/lib/cloud_sesame/query/ast/abstract/single_expression_operator.rb +39 -0
- data/lib/cloud_sesame/query/ast/abstract/value.rb +88 -0
- data/lib/cloud_sesame/query/ast/and.rb +1 -1
- data/lib/cloud_sesame/query/ast/date_value.rb +19 -3
- data/lib/cloud_sesame/query/ast/literal.rb +13 -28
- data/lib/cloud_sesame/query/ast/near.rb +4 -4
- data/lib/cloud_sesame/query/ast/not.rb +6 -7
- data/lib/cloud_sesame/query/ast/numeric_value.rb +20 -12
- data/lib/cloud_sesame/query/ast/or.rb +1 -1
- data/lib/cloud_sesame/query/ast/phrase.rb +1 -1
- data/lib/cloud_sesame/query/ast/prefix.rb +1 -1
- data/lib/cloud_sesame/query/ast/range_value.rb +40 -39
- data/lib/cloud_sesame/query/ast/root.rb +2 -6
- data/lib/cloud_sesame/query/ast/string_value.rb +26 -0
- data/lib/cloud_sesame/query/ast/term.rb +1 -1
- data/lib/cloud_sesame/query/ast/value.rb +25 -54
- data/lib/cloud_sesame/query/builder.rb +83 -54
- data/lib/cloud_sesame/query/domain/block.rb +3 -1
- data/lib/cloud_sesame/query/dsl/applied_filter_query.rb +14 -23
- data/lib/cloud_sesame/query/dsl/field_accessors.rb +25 -22
- data/lib/cloud_sesame/query/dsl/field_array_methods.rb +1 -1
- data/lib/cloud_sesame/query/dsl/inspect_method.rb +31 -0
- data/lib/cloud_sesame/query/dsl/sort_methods.rb +5 -4
- data/lib/cloud_sesame/query/node/abstract.rb +1 -2
- data/lib/cloud_sesame/query/node/facet.rb +1 -5
- data/lib/cloud_sesame/query/node/filter_query.rb +15 -2
- data/lib/cloud_sesame/query/node/fuzziness.rb +4 -3
- data/lib/cloud_sesame/query/node/page.rb +2 -2
- data/lib/cloud_sesame/query/node/query.rb +4 -17
- data/lib/cloud_sesame/query/node/query_options.rb +6 -16
- data/lib/cloud_sesame/query/node/query_options_field.rb +3 -1
- data/lib/cloud_sesame/query/node/query_parser.rb +8 -10
- data/lib/cloud_sesame/query/node/request.rb +57 -31
- data/lib/cloud_sesame/query/node/sort.rb +25 -11
- data/lib/cloud_sesame.rb +15 -12
- data/lib/{abstract_object.rb → services/abstract_object.rb} +0 -0
- data/lib/services/class_specific.rb +44 -0
- data/lib/services/lazy_object.rb +19 -0
- data/spec/cloud_sesame/domain/base_spec.rb +26 -11
- data/spec/cloud_sesame/domain/client_module/caching/base_spec.rb +2 -1
- data/spec/cloud_sesame/domain/client_module/caching/no_cache_spec.rb +2 -3
- data/spec/cloud_sesame/domain/client_module/caching/rails_cache_spec.rb +6 -6
- data/spec/cloud_sesame/domain/client_module/caching_spec.rb +33 -32
- data/spec/cloud_sesame/query/ast/abstract/multi_expression_operator_spec.rb +67 -0
- data/spec/cloud_sesame/query/ast/abstract/operator_spec.rb +29 -0
- data/spec/cloud_sesame/query/ast/abstract/single_expression_operator_spec.rb +70 -0
- data/spec/cloud_sesame/query/ast/abstract/value_spec.rb +118 -0
- data/spec/cloud_sesame/query/ast/and_spec.rb +1 -1
- data/spec/cloud_sesame/query/ast/or_spec.rb +1 -1
- data/spec/cloud_sesame/query/ast/range_value_spec.rb +5 -11
- data/spec/cloud_sesame/query/builder_spec.rb +10 -4
- data/spec/cloud_sesame/query/domain/block_spec.rb +15 -8
- data/spec/cloud_sesame/query/dsl/{block_methods_spec.rb → block_styled_operators_spec.rb} +0 -0
- data/spec/cloud_sesame/query/dsl/field_accessors_spec.rb +88 -50
- data/spec/cloud_sesame/query/dsl/field_array_methods_spec.rb +0 -2
- data/spec/cloud_sesame/query/node/facet_spec.rb +1 -15
- data/spec/cloud_sesame/query/node/filter_query_spec.rb +16 -2
- data/spec/cloud_sesame/query/node/page_spec.rb +3 -2
- data/spec/cloud_sesame/query/node/query_options_spec.rb +1 -1
- data/spec/cloud_sesame/query/node/query_parser_spec.rb +1 -7
- data/spec/cloud_sesame/query/node/query_spec.rb +10 -28
- data/spec/cloud_sesame/query/node/sort_spec.rb +19 -28
- data/spec/cloud_sesame_spec.rb +2 -156
- data/spec/helpers/benchmark_helper.rb +12 -0
- data/spec/integration/filter_query_spec.rb +0 -0
- data/spec/profiling_spec.rb +155 -0
- data/spec/{abstract_object_spec.rb → services/abstract_object_spec.rb} +0 -0
- data/spec/services/class_specific_spec.rb +135 -0
- data/spec/spec_helper.rb +3 -0
- metadata +32 -22
- data/lib/active_support/core_ext/object/deep_dup.rb +0 -53
- data/lib/active_support/core_ext/object/duplicable.rb +0 -98
- data/lib/cloud_sesame/query/ast/multi_expression_operator.rb +0 -35
- data/lib/cloud_sesame/query/ast/operator.rb +0 -25
- data/lib/cloud_sesame/query/ast/single_expression_operator.rb +0 -35
- data/lib/cloud_sesame/query/scope.rb +0 -21
- data/profiler.rb +0 -91
- data/spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb +0 -76
- data/spec/cloud_sesame/query/ast/operator_spec.rb +0 -29
- data/spec/cloud_sesame/query/ast/single_expression_operator_spec.rb +0 -78
- data/spec/context_spec.rb +0 -17
@@ -2,77 +2,103 @@ module CloudSesame
|
|
2
2
|
module Query
|
3
3
|
module Node
|
4
4
|
class Request < Abstract
|
5
|
+
extend ClassSpecific
|
6
|
+
|
7
|
+
after_construct do |searchable|
|
8
|
+
@query = Query.construct_class(searchable)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.query
|
12
|
+
@query
|
13
|
+
end
|
5
14
|
|
6
15
|
# CHILDREN
|
7
16
|
# =========================================
|
8
17
|
|
9
18
|
def query
|
10
|
-
@query ||=
|
19
|
+
@query ||= self.class.query.new(context[:query])
|
11
20
|
end
|
12
21
|
|
13
22
|
def query_options
|
14
|
-
@query_options ||= QueryOptions.new(context[:query_options]
|
23
|
+
@query_options ||= QueryOptions.new(context[:query_options])
|
15
24
|
end
|
16
25
|
|
17
26
|
def query_parser
|
18
|
-
@query_parser ||= QueryParser.new(context[:query_parser]
|
27
|
+
@query_parser ||= QueryParser.new(context[:query_parser])
|
19
28
|
end
|
20
29
|
|
21
30
|
def filter_query
|
22
|
-
@filter_query ||= FilterQuery.new(context[:filter_query]
|
31
|
+
@filter_query ||= FilterQuery.new(context[:filter_query])
|
23
32
|
end
|
24
33
|
|
25
34
|
def facet
|
26
|
-
@facet ||= Facet.new(context[:facet]
|
35
|
+
@facet ||= Facet.new(context[:facet])
|
27
36
|
end
|
28
37
|
|
29
38
|
def page
|
30
|
-
@page ||= Page.new(context[:page]
|
39
|
+
@page ||= Page.new(context[:page])
|
31
40
|
end
|
32
41
|
|
33
42
|
def sort
|
34
|
-
@sort ||= Sort.new(context[:sort]
|
43
|
+
@sort ||= Sort.new(context[:sort])
|
35
44
|
end
|
36
45
|
|
37
46
|
def return_field
|
38
|
-
@return ||= Return.new(context[:return]
|
47
|
+
@return ||= Return.new(context[:return])
|
39
48
|
end
|
40
49
|
|
41
50
|
# EVALUATION
|
42
51
|
# =========================================
|
43
52
|
|
44
53
|
def compile
|
45
|
-
compiled =
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
object.merge!(node.compile || {})
|
56
|
-
end
|
54
|
+
compiled = {}
|
55
|
+
insert_query compiled
|
56
|
+
insert_filter_query compiled
|
57
|
+
insert_query_parser compiled
|
58
|
+
insert_rest compiled
|
59
|
+
insert_page compiled
|
60
|
+
compiled
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
57
64
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
convert_to_structured_query(compiled)
|
65
|
+
def insert_query(compiled)
|
66
|
+
if (compiled_query = query.compile) && !compiled_query.empty?
|
67
|
+
compiled[:query] = compiled_query
|
62
68
|
end
|
69
|
+
end
|
63
70
|
|
64
|
-
|
71
|
+
def insert_filter_query(compiled)
|
72
|
+
if (compiled_fq = filter_query.compile)
|
73
|
+
if compiled[:query]
|
74
|
+
query_parser.simple
|
75
|
+
compiled[:filter_query] = compiled_fq
|
76
|
+
else
|
77
|
+
query_parser.structured
|
78
|
+
compiled[:query] = compiled_fq
|
79
|
+
end
|
80
|
+
end
|
65
81
|
end
|
66
82
|
|
67
|
-
|
83
|
+
def insert_query_parser(compiled)
|
84
|
+
compiled[:query_parser] = query_parser.compile
|
85
|
+
end
|
68
86
|
|
69
|
-
def
|
70
|
-
|
87
|
+
def insert_rest(compiled)
|
88
|
+
{
|
89
|
+
query_options: query_options,
|
90
|
+
facet: facet,
|
91
|
+
sort: sort,
|
92
|
+
return: return_field
|
93
|
+
}.each do |name, node|
|
94
|
+
compiled_node = node.compile
|
95
|
+
compiled[name] = compiled_node if compiled_node
|
96
|
+
end
|
97
|
+
compiled
|
71
98
|
end
|
72
99
|
|
73
|
-
def
|
74
|
-
|
75
|
-
hash
|
100
|
+
def insert_page(compiled)
|
101
|
+
compiled.merge! page.compile
|
76
102
|
end
|
77
103
|
|
78
104
|
end
|
@@ -3,32 +3,46 @@ module CloudSesame
|
|
3
3
|
module Node
|
4
4
|
class Sort < Abstract
|
5
5
|
|
6
|
-
attr_writer :
|
6
|
+
attr_writer :attributes
|
7
7
|
|
8
|
-
def
|
9
|
-
@
|
8
|
+
def attributes
|
9
|
+
@attributes ||= {}
|
10
10
|
end
|
11
11
|
|
12
12
|
def [](attribute)
|
13
|
-
|
13
|
+
attributes[attribute.to_sym]
|
14
14
|
end
|
15
15
|
|
16
|
-
def []=(attribute, order
|
17
|
-
|
16
|
+
def []=(attribute, order)
|
17
|
+
attributes[attribute.to_sym] = order
|
18
18
|
end
|
19
19
|
|
20
20
|
def compile
|
21
|
-
(
|
21
|
+
unless (compiled = serialize attributes).empty?
|
22
|
+
compiled
|
23
|
+
end
|
22
24
|
end
|
23
25
|
|
24
26
|
private
|
25
27
|
|
26
|
-
def serialize(hash
|
27
|
-
hash.
|
28
|
+
def serialize(hash)
|
29
|
+
hash.each_with_object("") do |(k, v), o|
|
30
|
+
o << (o.empty? ? '' : ',') << serialize_field(k, v)
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
|
-
def
|
31
|
-
|
34
|
+
def serialize_field(name, value)
|
35
|
+
"#{ field_name(name) } #{ value }"
|
36
|
+
end
|
37
|
+
|
38
|
+
def field_name(key)
|
39
|
+
(name = alias_field(key)) ? name : key
|
40
|
+
end
|
41
|
+
|
42
|
+
def alias_field(key)
|
43
|
+
context[:fields] &&
|
44
|
+
context[:fields][key] &&
|
45
|
+
context[:fields][key][:as]
|
32
46
|
end
|
33
47
|
|
34
48
|
end
|
data/lib/cloud_sesame.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# External Libraries
|
2
2
|
# ===============================================
|
3
|
-
require 'active_support/core_ext/object/deep_dup'
|
4
3
|
require 'aws-sdk'
|
5
4
|
require 'forwardable'
|
6
5
|
|
7
6
|
# Internal Libraries
|
8
7
|
# ===============================================
|
9
|
-
require 'abstract_object'
|
10
|
-
require '
|
8
|
+
require 'services/abstract_object'
|
9
|
+
require 'services/class_specific'
|
10
|
+
require 'services/lazy_object'
|
11
11
|
|
12
12
|
# Custom Errors
|
13
13
|
# ===============================================
|
@@ -16,6 +16,10 @@ require 'cloud_sesame/query/error/missing_operator_symbol'
|
|
16
16
|
require 'cloud_sesame/query/error/missing_query'
|
17
17
|
require 'cloud_sesame/query/error/scope_not_defined'
|
18
18
|
|
19
|
+
# Global Credential
|
20
|
+
# ===============================================
|
21
|
+
require 'cloud_sesame/config/credential'
|
22
|
+
|
19
23
|
# Query DSL Methods
|
20
24
|
# ===============================================
|
21
25
|
require 'cloud_sesame/query/dsl/applied_filter_query'
|
@@ -25,14 +29,12 @@ require 'cloud_sesame/query/dsl/field_accessors'
|
|
25
29
|
require 'cloud_sesame/query/dsl/scope_accessors'
|
26
30
|
require 'cloud_sesame/query/dsl/operators'
|
27
31
|
require 'cloud_sesame/query/dsl/field_array_methods'
|
28
|
-
|
29
|
-
require 'cloud_sesame/query/dsl/range_helper'
|
32
|
+
require 'cloud_sesame/query/dsl/inspect_method'
|
30
33
|
require 'cloud_sesame/query/dsl/page_methods'
|
31
34
|
require 'cloud_sesame/query/dsl/query_methods'
|
32
|
-
|
35
|
+
require 'cloud_sesame/query/dsl/range_helper'
|
33
36
|
require 'cloud_sesame/query/dsl/response_methods'
|
34
37
|
require 'cloud_sesame/query/dsl/return_methods'
|
35
|
-
|
36
38
|
require 'cloud_sesame/query/dsl/sort_methods'
|
37
39
|
|
38
40
|
# Query Query Domain Objects
|
@@ -43,9 +45,10 @@ require 'cloud_sesame/query/domain/literal'
|
|
43
45
|
|
44
46
|
# Query Query Filter Query AST Tree
|
45
47
|
# ===============================================
|
46
|
-
require 'cloud_sesame/query/ast/operator'
|
47
|
-
require 'cloud_sesame/query/ast/multi_expression_operator'
|
48
|
-
require 'cloud_sesame/query/ast/single_expression_operator'
|
48
|
+
require 'cloud_sesame/query/ast/abstract/operator'
|
49
|
+
require 'cloud_sesame/query/ast/abstract/multi_expression_operator'
|
50
|
+
require 'cloud_sesame/query/ast/abstract/single_expression_operator'
|
51
|
+
require 'cloud_sesame/query/ast/abstract/value'
|
49
52
|
require 'cloud_sesame/query/ast/field_array'
|
50
53
|
require 'cloud_sesame/query/ast/and'
|
51
54
|
require 'cloud_sesame/query/ast/or'
|
@@ -55,10 +58,11 @@ require 'cloud_sesame/query/ast/phrase'
|
|
55
58
|
require 'cloud_sesame/query/ast/prefix'
|
56
59
|
require 'cloud_sesame/query/ast/term'
|
57
60
|
require 'cloud_sesame/query/ast/literal'
|
58
|
-
require 'cloud_sesame/query/ast/
|
61
|
+
require 'cloud_sesame/query/ast/string_value'
|
59
62
|
require 'cloud_sesame/query/ast/date_value'
|
60
63
|
require 'cloud_sesame/query/ast/numeric_value'
|
61
64
|
require 'cloud_sesame/query/ast/range_value'
|
65
|
+
require 'cloud_sesame/query/ast/value'
|
62
66
|
require 'cloud_sesame/query/ast/root'
|
63
67
|
|
64
68
|
# Query Request Nodes
|
@@ -80,7 +84,6 @@ require 'cloud_sesame/query/node/return'
|
|
80
84
|
# Query Builder Interface
|
81
85
|
# ===============================================
|
82
86
|
require 'cloud_sesame/query/builder'
|
83
|
-
require 'cloud_sesame/query/scope'
|
84
87
|
|
85
88
|
# Domain Objects
|
86
89
|
# ===============================================
|
File without changes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ClassSpecific
|
2
|
+
|
3
|
+
def construct_class(klass, callback_args: [])
|
4
|
+
__constructor__(klass, callback_args) { |name| __define_subclass__ name, self }
|
5
|
+
end
|
6
|
+
|
7
|
+
def construct_module(klass, callback_args: [])
|
8
|
+
__constructor__(klass, callback_args) { |name| __define_submodule__ name, self }
|
9
|
+
end
|
10
|
+
|
11
|
+
def after_construct(&block)
|
12
|
+
@__construct_callback__ = block
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def __constructor__(klass, callback_args)
|
18
|
+
constant = !(name = __get_constant_name__(klass)) ? self :
|
19
|
+
constants(false).include?(name.to_sym) ? const_get(name) :
|
20
|
+
yield(name)
|
21
|
+
|
22
|
+
__invoke_callback__(constant, klass, *callback_args) if @__construct_callback__
|
23
|
+
constant
|
24
|
+
end
|
25
|
+
|
26
|
+
def __invoke_callback__(constant, klass, *args)
|
27
|
+
eval_method = constant.is_a?(Class) ? :class_exec : :module_exec
|
28
|
+
constant.send(eval_method, klass, *args, &@__construct_callback__)
|
29
|
+
@__construct_callback__ = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def __define_subclass__(name, parent)
|
33
|
+
parent.const_set(name, Class.new(parent))
|
34
|
+
end
|
35
|
+
|
36
|
+
def __define_submodule__(name, parent)
|
37
|
+
parent.const_set(name, parent.clone)
|
38
|
+
end
|
39
|
+
|
40
|
+
def __get_constant_name__(constant)
|
41
|
+
(name = constant.to_s) ? name.slice(/(?=\:\:)?\w+$/) : nil
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class LazyObject < BasicObject
|
2
|
+
|
3
|
+
def initialize(&callable)
|
4
|
+
@callable = callable
|
5
|
+
end
|
6
|
+
|
7
|
+
def __target_object__
|
8
|
+
@__target_object__ ||= @callable.call
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(object)
|
12
|
+
__target_object__ == object
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(method_name, *args, &block)
|
16
|
+
__target_object__.send(method_name, *args, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -177,18 +177,12 @@ module CloudSesame
|
|
177
177
|
end
|
178
178
|
|
179
179
|
context 'when options :default is passed in' do
|
180
|
-
let(:proc) { Proc.new {
|
180
|
+
let(:proc) { Proc.new { } }
|
181
181
|
let(:options) {{ default: proc }}
|
182
182
|
it 'should remove the default lambda or proc from the options' do
|
183
183
|
expect(options).to receive(:delete).with(:default)
|
184
184
|
subject.field field_name, options
|
185
185
|
end
|
186
|
-
it 'should create a literal node using Query::Domain::Literal' do
|
187
|
-
domain = Query::Domain::Literal.new(field_name, {}, self)
|
188
|
-
expect(Query::Domain::Literal).to receive(:new).with(field_name, {}, self).and_return(domain)
|
189
|
-
expect(domain).to receive(:_eval) { |&block| expect(block).to eq proc }
|
190
|
-
subject.field field_name, options
|
191
|
-
end
|
192
186
|
|
193
187
|
context 'when default proc/lambda returns value' do
|
194
188
|
let(:proc) { Proc.new { "name" } }
|
@@ -208,9 +202,30 @@ module CloudSesame
|
|
208
202
|
end
|
209
203
|
end
|
210
204
|
|
211
|
-
|
212
|
-
|
213
|
-
|
205
|
+
context 'when option type is given' do
|
206
|
+
let(:options) {{ type: type }}
|
207
|
+
context 'and type is valid' do
|
208
|
+
let(:type) { :string }
|
209
|
+
it 'should reaplce the type symbol with the corresponded class' do
|
210
|
+
subject.field field_name, options
|
211
|
+
expect(subject.context[:filter_query][:fields][field_name]).to include({type: CloudSesame::Query::AST::StringValue })
|
212
|
+
end
|
213
|
+
end
|
214
|
+
context 'and type is not valid' do
|
215
|
+
let(:type) { nil }
|
216
|
+
it 'should reaplce the type symbol with the default value class' do
|
217
|
+
subject.field field_name, options
|
218
|
+
expect(subject.context[:filter_query][:fields][field_name]).to include({type: CloudSesame::Query::AST::Value })
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'when option type is not given' do
|
224
|
+
let(:options) {{}}
|
225
|
+
it 'should set the field type to the default value class' do
|
226
|
+
subject.field field_name, options
|
227
|
+
expect(subject.context[:filter_query][:fields][field_name]).to include({type: CloudSesame::Query::AST::Value })
|
228
|
+
end
|
214
229
|
end
|
215
230
|
|
216
231
|
context 'when options is passed in' do
|
@@ -224,7 +239,7 @@ module CloudSesame
|
|
224
239
|
context 'when no options is passed in' do
|
225
240
|
it 'should create a options in filter query fields' do
|
226
241
|
subject.field field_name
|
227
|
-
expect(subject.context[:filter_query][:fields][field_name]).to
|
242
|
+
expect(subject.context[:filter_query][:fields][field_name]).to include({type: CloudSesame::Query::AST::Value})
|
228
243
|
end
|
229
244
|
end
|
230
245
|
end
|
@@ -6,9 +6,8 @@ module CloudSesame
|
|
6
6
|
|
7
7
|
class Searchable; end
|
8
8
|
|
9
|
-
let(:client) {
|
10
|
-
|
11
|
-
subject { NoCache.new(Searchable) { client } }
|
9
|
+
let(:client) { instance_double(Client) }
|
10
|
+
subject { NoCache.new(client, Searchable) }
|
12
11
|
|
13
12
|
describe 'fetch' do
|
14
13
|
let(:params) {{}}
|
@@ -27,20 +27,20 @@ module CloudSesame
|
|
27
27
|
|
28
28
|
# HELPERS
|
29
29
|
# =====================================
|
30
|
-
def
|
31
|
-
subject.send(:
|
30
|
+
def hexdigest(params)
|
31
|
+
subject.send(:hexdigest, params)
|
32
32
|
end
|
33
33
|
|
34
34
|
# TESTS
|
35
35
|
# =====================================
|
36
36
|
|
37
|
-
let(:client) {
|
38
|
-
subject { RailsCache.new(Searchable)
|
37
|
+
let(:client) { instance_double(Client) }
|
38
|
+
subject { RailsCache.new(client, Searchable) }
|
39
39
|
|
40
40
|
shared_examples 'cache stored' do
|
41
41
|
it 'should cache the result' do
|
42
42
|
expect{ subject.fetch(params) }.to change{ Rails.cache.table.keys.size }
|
43
|
-
expect(Rails.cache.table[
|
43
|
+
expect(Rails.cache.table[hexdigest(params)]).to eq results
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -54,7 +54,7 @@ module CloudSesame
|
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'should use the hash key generated from params to fetch the cache from Rails' do
|
57
|
-
hash_key =
|
57
|
+
hash_key = hexdigest(params)
|
58
58
|
expect(Rails.cache).to receive(:fetch).with(hash_key)
|
59
59
|
subject.fetch(params)
|
60
60
|
end
|
@@ -3,67 +3,68 @@ module CloudSesame
|
|
3
3
|
module ClientModule
|
4
4
|
describe Caching do
|
5
5
|
|
6
|
-
|
7
|
-
# =======================================
|
8
|
-
|
9
|
-
class Caching::GoodCache < Caching::Base
|
6
|
+
class Caching::GoodCache < Caching::Base
|
10
7
|
def fetch(params); end
|
11
8
|
end
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
class TestClient
|
17
|
-
include Caching
|
18
|
-
|
19
|
-
def aws_client
|
20
|
-
nil
|
10
|
+
let(:custom_cache) do
|
11
|
+
Class.new(Caching::Base) do
|
12
|
+
def fetch(params); end
|
21
13
|
end
|
14
|
+
end
|
22
15
|
|
23
|
-
|
24
|
-
|
16
|
+
let(:test_client) do
|
17
|
+
Class.new do
|
18
|
+
include Caching
|
19
|
+
def aws_client; end
|
20
|
+
def searchable; end
|
25
21
|
end
|
26
22
|
end
|
27
23
|
|
28
|
-
|
29
|
-
|
24
|
+
subject { test_client.new }
|
25
|
+
let(:aws_client) { subject.aws_client }
|
26
|
+
let(:searchable) { subject.searchable }
|
30
27
|
|
31
|
-
|
28
|
+
before { custom_cache }
|
32
29
|
|
33
30
|
describe '#caching_with' do
|
34
31
|
context 'when giving an existing caching module' do
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
it 'should set executor to the caching module' do
|
40
|
-
expect(subject.send(:executor)).to be_kind_of caching_module
|
41
|
-
end
|
32
|
+
let(:caching_module) { Caching::GoodCache }
|
33
|
+
before { subject.caching_with(:GoodCache) }
|
34
|
+
it 'should set executor to the caching module' do
|
35
|
+
expect(subject.executor).to be_kind_of caching_module
|
42
36
|
end
|
43
37
|
end
|
44
38
|
context 'when giving a non-existing caching module' do
|
45
39
|
it 'should raise Unrecognized Caching Module' do
|
46
|
-
expect{ subject.caching_with(:
|
40
|
+
expect{ subject.caching_with(:UnknowCache) }.to raise_error(NameError)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
context 'when give a class directly' do
|
44
|
+
let(:caching_module) { custom_cache }
|
45
|
+
before { subject.caching_with(caching_module) }
|
46
|
+
it 'should set executor as the caching module' do
|
47
|
+
expect(subject.executor).to be_kind_of caching_module
|
47
48
|
end
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
51
52
|
describe 'executor getter' do
|
52
|
-
it 'should return an Caching::NoCache executor by default' do
|
53
|
-
expect(subject.executor).to be_kind_of(Caching::NoCache)
|
54
|
-
end
|
55
53
|
it 'should default to Caching::NoCache' do
|
56
|
-
expect(Caching::NoCache).to receive(:new).with(
|
57
|
-
expect(
|
54
|
+
expect(Caching::NoCache).to receive(:new).with(aws_client, searchable) do |client, _|
|
55
|
+
expect(client).to eq subject.aws_client
|
58
56
|
end
|
59
57
|
subject.executor
|
60
58
|
end
|
59
|
+
it 'should return an Caching::NoCache executor by default' do
|
60
|
+
expect(subject.executor).to be_kind_of(Caching::NoCache)
|
61
|
+
end
|
61
62
|
end
|
62
63
|
|
63
64
|
describe 'executor setter' do
|
64
65
|
it 'should accept a caching module' do
|
65
|
-
expect(Caching::GoodCache).to receive(:new).with(
|
66
|
-
expect(
|
66
|
+
expect(Caching::GoodCache).to receive(:new).with(aws_client, searchable) do |client, _|
|
67
|
+
expect(client).to eq aws_client
|
67
68
|
end
|
68
69
|
subject.executor = Caching::GoodCache
|
69
70
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module AST
|
4
|
+
module Abstract
|
5
|
+
describe MultiExpressionOperator do
|
6
|
+
|
7
|
+
let(:context) { {} }
|
8
|
+
let(:options) { {} }
|
9
|
+
let(:block) { Proc.new {} }
|
10
|
+
|
11
|
+
subject { MultiExpressionOperator.new(context, options, &block) }
|
12
|
+
|
13
|
+
it 'should be a type of operator' do
|
14
|
+
expect(MultiExpressionOperator.ancestors).to include(Operator)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#children' do
|
18
|
+
it 'should be empty by default' do
|
19
|
+
expect(subject.children).to be_empty
|
20
|
+
end
|
21
|
+
it 'should be an Field Array' do
|
22
|
+
expect(subject.children).to be_a AST::FieldArray
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#compile' do
|
27
|
+
context 'when theres children' do
|
28
|
+
let(:child) { OpenStruct.new(compile: "compiled") }
|
29
|
+
before { subject.children << child }
|
30
|
+
|
31
|
+
it 'should compile to children' do
|
32
|
+
expect(subject.children).to receive(:compile)
|
33
|
+
subject.compile
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'and boost options is given' do
|
37
|
+
before { subject.options[:boost] = 2 }
|
38
|
+
it 'should return compiled string with boost' do
|
39
|
+
expect(subject.compile).to eq "( boost=2 compiled)"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
context 'and boost options is not given' do
|
43
|
+
it 'should return compiled string with boost' do
|
44
|
+
expect(subject.compile).to eq "( compiled)"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
context 'when theres no children' do
|
49
|
+
it 'should return nothing' do
|
50
|
+
expect(subject.compile).to eq nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#<<' do
|
56
|
+
it 'should push object into the children' do
|
57
|
+
object = :hello
|
58
|
+
expect(subject.children).to receive(:<<).with(object)
|
59
|
+
subject << object
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module CloudSesame
|
2
|
+
module Query
|
3
|
+
module AST
|
4
|
+
module Abstract
|
5
|
+
describe Operator do
|
6
|
+
let(:context) {{}}
|
7
|
+
let(:options) {{}}
|
8
|
+
let(:block) { Proc.new {} }
|
9
|
+
subject { Operator.new(context, options, &block) }
|
10
|
+
|
11
|
+
describe '#boost' do
|
12
|
+
context 'given boost option' do
|
13
|
+
let(:options) { { boost: 2 } }
|
14
|
+
it 'should return an compiled boost value' do
|
15
|
+
expect(subject.boost).to eq " boost=2"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
context 'given no boost option' do
|
19
|
+
it 'should return nothing' do
|
20
|
+
expect(subject.boost).to eq nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|