CloudSesame 0.6.8 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +12 -0
  3. data/.gitignore +1 -1
  4. data/Gemfile.lock +13 -13
  5. data/Guardfile +1 -0
  6. data/cloud_sesame.gemspec +2 -2
  7. data/coverage/.last_run.json +1 -1
  8. data/coverage/.resultset.json +679 -591
  9. data/lib/cloud_sesame/config/credential.rb +6 -6
  10. data/lib/cloud_sesame/context.rb +0 -5
  11. data/lib/cloud_sesame/domain/base.rb +147 -128
  12. data/lib/cloud_sesame/domain/client.rb +25 -25
  13. data/lib/cloud_sesame/domain/client_module/caching/base.rb +19 -23
  14. data/lib/cloud_sesame/domain/client_module/caching/no_cache.rb +11 -11
  15. data/lib/cloud_sesame/domain/client_module/caching/rails_cache.rb +32 -28
  16. data/lib/cloud_sesame/domain/client_module/caching.rb +19 -28
  17. data/lib/cloud_sesame/domain/client_module/retry.rb +6 -6
  18. data/lib/cloud_sesame/domain/config.rb +6 -6
  19. data/lib/cloud_sesame/query/ast/abstract/multi_expression_operator.rb +37 -0
  20. data/lib/cloud_sesame/query/ast/abstract/operator.rb +27 -0
  21. data/lib/cloud_sesame/query/ast/abstract/single_expression_operator.rb +39 -0
  22. data/lib/cloud_sesame/query/ast/abstract/value.rb +88 -0
  23. data/lib/cloud_sesame/query/ast/and.rb +1 -1
  24. data/lib/cloud_sesame/query/ast/date_value.rb +19 -3
  25. data/lib/cloud_sesame/query/ast/literal.rb +13 -28
  26. data/lib/cloud_sesame/query/ast/near.rb +4 -4
  27. data/lib/cloud_sesame/query/ast/not.rb +6 -7
  28. data/lib/cloud_sesame/query/ast/numeric_value.rb +20 -12
  29. data/lib/cloud_sesame/query/ast/or.rb +1 -1
  30. data/lib/cloud_sesame/query/ast/phrase.rb +1 -1
  31. data/lib/cloud_sesame/query/ast/prefix.rb +1 -1
  32. data/lib/cloud_sesame/query/ast/range_value.rb +40 -39
  33. data/lib/cloud_sesame/query/ast/root.rb +2 -6
  34. data/lib/cloud_sesame/query/ast/string_value.rb +26 -0
  35. data/lib/cloud_sesame/query/ast/term.rb +1 -1
  36. data/lib/cloud_sesame/query/ast/value.rb +25 -54
  37. data/lib/cloud_sesame/query/builder.rb +83 -54
  38. data/lib/cloud_sesame/query/domain/block.rb +3 -1
  39. data/lib/cloud_sesame/query/dsl/applied_filter_query.rb +14 -23
  40. data/lib/cloud_sesame/query/dsl/field_accessors.rb +25 -22
  41. data/lib/cloud_sesame/query/dsl/field_array_methods.rb +1 -1
  42. data/lib/cloud_sesame/query/dsl/inspect_method.rb +31 -0
  43. data/lib/cloud_sesame/query/dsl/sort_methods.rb +5 -4
  44. data/lib/cloud_sesame/query/node/abstract.rb +1 -2
  45. data/lib/cloud_sesame/query/node/facet.rb +1 -5
  46. data/lib/cloud_sesame/query/node/filter_query.rb +15 -2
  47. data/lib/cloud_sesame/query/node/fuzziness.rb +4 -3
  48. data/lib/cloud_sesame/query/node/page.rb +2 -2
  49. data/lib/cloud_sesame/query/node/query.rb +4 -17
  50. data/lib/cloud_sesame/query/node/query_options.rb +6 -16
  51. data/lib/cloud_sesame/query/node/query_options_field.rb +3 -1
  52. data/lib/cloud_sesame/query/node/query_parser.rb +8 -10
  53. data/lib/cloud_sesame/query/node/request.rb +57 -31
  54. data/lib/cloud_sesame/query/node/sort.rb +25 -11
  55. data/lib/cloud_sesame.rb +15 -12
  56. data/lib/{abstract_object.rb → services/abstract_object.rb} +0 -0
  57. data/lib/services/class_specific.rb +44 -0
  58. data/lib/services/lazy_object.rb +19 -0
  59. data/spec/cloud_sesame/domain/base_spec.rb +26 -11
  60. data/spec/cloud_sesame/domain/client_module/caching/base_spec.rb +2 -1
  61. data/spec/cloud_sesame/domain/client_module/caching/no_cache_spec.rb +2 -3
  62. data/spec/cloud_sesame/domain/client_module/caching/rails_cache_spec.rb +6 -6
  63. data/spec/cloud_sesame/domain/client_module/caching_spec.rb +33 -32
  64. data/spec/cloud_sesame/query/ast/abstract/multi_expression_operator_spec.rb +67 -0
  65. data/spec/cloud_sesame/query/ast/abstract/operator_spec.rb +29 -0
  66. data/spec/cloud_sesame/query/ast/abstract/single_expression_operator_spec.rb +70 -0
  67. data/spec/cloud_sesame/query/ast/abstract/value_spec.rb +118 -0
  68. data/spec/cloud_sesame/query/ast/and_spec.rb +1 -1
  69. data/spec/cloud_sesame/query/ast/or_spec.rb +1 -1
  70. data/spec/cloud_sesame/query/ast/range_value_spec.rb +5 -11
  71. data/spec/cloud_sesame/query/builder_spec.rb +10 -4
  72. data/spec/cloud_sesame/query/domain/block_spec.rb +15 -8
  73. data/spec/cloud_sesame/query/dsl/{block_methods_spec.rb → block_styled_operators_spec.rb} +0 -0
  74. data/spec/cloud_sesame/query/dsl/field_accessors_spec.rb +88 -50
  75. data/spec/cloud_sesame/query/dsl/field_array_methods_spec.rb +0 -2
  76. data/spec/cloud_sesame/query/node/facet_spec.rb +1 -15
  77. data/spec/cloud_sesame/query/node/filter_query_spec.rb +16 -2
  78. data/spec/cloud_sesame/query/node/page_spec.rb +3 -2
  79. data/spec/cloud_sesame/query/node/query_options_spec.rb +1 -1
  80. data/spec/cloud_sesame/query/node/query_parser_spec.rb +1 -7
  81. data/spec/cloud_sesame/query/node/query_spec.rb +10 -28
  82. data/spec/cloud_sesame/query/node/sort_spec.rb +19 -28
  83. data/spec/cloud_sesame_spec.rb +2 -156
  84. data/spec/helpers/benchmark_helper.rb +12 -0
  85. data/spec/integration/filter_query_spec.rb +0 -0
  86. data/spec/profiling_spec.rb +155 -0
  87. data/spec/{abstract_object_spec.rb → services/abstract_object_spec.rb} +0 -0
  88. data/spec/services/class_specific_spec.rb +135 -0
  89. data/spec/spec_helper.rb +3 -0
  90. metadata +32 -22
  91. data/lib/active_support/core_ext/object/deep_dup.rb +0 -53
  92. data/lib/active_support/core_ext/object/duplicable.rb +0 -98
  93. data/lib/cloud_sesame/query/ast/multi_expression_operator.rb +0 -35
  94. data/lib/cloud_sesame/query/ast/operator.rb +0 -25
  95. data/lib/cloud_sesame/query/ast/single_expression_operator.rb +0 -35
  96. data/lib/cloud_sesame/query/scope.rb +0 -21
  97. data/profiler.rb +0 -91
  98. data/spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb +0 -76
  99. data/spec/cloud_sesame/query/ast/operator_spec.rb +0 -29
  100. data/spec/cloud_sesame/query/ast/single_expression_operator_spec.rb +0 -78
  101. 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 ||= Query.new(context[: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
- query,
47
- query_options,
48
- query_parser,
49
- filter_query,
50
- facet,
51
- page,
52
- sort,
53
- return_field
54
- ].each_with_object({}) do |node, object|
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
- if compiled[:filter_query].empty?
59
- compiled.delete(:filter_query)
60
- elsif compiled[:query].nil? || compiled[:query].empty?
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
- compiled
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
- private
83
+ def insert_query_parser(compiled)
84
+ compiled[:query_parser] = query_parser.compile
85
+ end
68
86
 
69
- def convert_to_structured_query(compiled)
70
- replace(compiled, :query, :filter_query).merge! query_parser.structured.compile
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 replace(hash, key1, key2)
74
- hash[key1] = hash.delete key2
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 :sorting_attributes
6
+ attr_writer :attributes
7
7
 
8
- def sorting_attributes
9
- @sorting_attributes ||= deserialize context[:sort]
8
+ def attributes
9
+ @attributes ||= {}
10
10
  end
11
11
 
12
12
  def [](attribute)
13
- sorting_attributes[attribute.to_sym]
13
+ attributes[attribute.to_sym]
14
14
  end
15
15
 
16
- def []=(attribute, order = :desc)
17
- sorting_attributes[attribute.to_sym] = order.to_sym if order
16
+ def []=(attribute, order)
17
+ attributes[attribute.to_sym] = order
18
18
  end
19
19
 
20
20
  def compile
21
- (result = serialize(sorting_attributes)).empty? ? {} : { sort: result }
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.to_a.map { |i| i.join(' ') }.join(',')
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 deserialize(string)
31
- Hash[*((string || "").split(',').map { |i| i.strip.split(' ').map(&:to_sym) }.flatten)]
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 'cloud_sesame/config/credential'
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/value'
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
  # ===============================================
@@ -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
- it 'should create an field accessor' do
212
- field_name = :an_indexed_field
213
- expect{ subject.field field_name, {} }.to change{ Query::DSL::FieldAccessors.instance_methods }.by([field_name])
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 eq({})
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,7 +6,8 @@ module CloudSesame
6
6
 
7
7
  class Searchable; end
8
8
 
9
- subject { Base.new(Searchable) {} }
9
+ let(:client) { instance_double(Client) }
10
+ subject { Base.new(client, Searchable) }
10
11
 
11
12
  describe 'fetch' do
12
13
  it 'should raise an error by default' do
@@ -6,9 +6,8 @@ module CloudSesame
6
6
 
7
7
  class Searchable; end
8
8
 
9
- let(:client) { OpenStruct.new(search: nil) }
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 hashify(params)
31
- subject.send(:hashify, params)
30
+ def hexdigest(params)
31
+ subject.send(:hexdigest, params)
32
32
  end
33
33
 
34
34
  # TESTS
35
35
  # =====================================
36
36
 
37
- let(:client) { OpenStruct.new(search: nil) }
38
- subject { RailsCache.new(Searchable) { client } }
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[hashify(params)]).to eq results
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 = hashify(params)
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
- # SETUP
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
- class Caching::BadCache < Caching::Base
14
- end
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
- def searchable
24
- nil
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
- # TESTS
29
- # =======================================
24
+ subject { test_client.new }
25
+ let(:aws_client) { subject.aws_client }
26
+ let(:searchable) { subject.searchable }
30
27
 
31
- subject { TestClient.new }
28
+ before { custom_cache }
32
29
 
33
30
  describe '#caching_with' do
34
31
  context 'when giving an existing caching module' do
35
- context 'and caching_module respond to fetch' do
36
- let(:caching_module) { Caching::GoodCache }
37
- before {
38
- subject.caching_with(:GoodCache) }
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(:RedisCache) }.to raise_error(Error::Caching, "Unrecognized Caching Module")
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(subject.searchable) do |_, &lazy_client|
57
- expect(lazy_client.call).to eq subject.aws_client
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(subject.searchable) do |_, &lazy_client|
66
- expect(lazy_client.call).to eq subject.aws_client
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