elastic_adapter 0.0.8 → 0.1.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/.codeclimate.yml +8 -0
  3. data/lib/elastic_adapter/index.rb +16 -15
  4. data/lib/elastic_adapter/response.rb +25 -0
  5. data/lib/elastic_adapter/responses/with_aggregations.rb +9 -0
  6. data/lib/elastic_adapter/responses/with_count.rb +9 -0
  7. data/lib/elastic_adapter/responses/with_exception.rb +9 -0
  8. data/lib/elastic_adapter/responses/with_hit.rb +24 -0
  9. data/lib/elastic_adapter/responses/with_hits.rb +18 -0
  10. data/lib/elastic_adapter/responses/with_suggestions.rb +9 -0
  11. data/lib/elastic_adapter/responses/with_validations.rb +13 -0
  12. data/lib/elastic_adapter/version.rb +1 -1
  13. data/lib/elastic_adapter.rb +8 -9
  14. data/spec/cassettes/ElasticAdapter_Index/_aggregate/response/{is_a_AggregationResponse.yml → has_a_aggregation.yml} +3 -3
  15. data/spec/cassettes/ElasticAdapter_Index/_aggregate/response/is_a_WithAggregation.yml +30 -0
  16. data/spec/cassettes/ElasticAdapter_Index/_aggregate.yml +8 -8
  17. data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/is_a_fixnum.yml +5 -5
  18. data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/returns_the_amount_of_all_documents.yml +1 -1
  19. data/spec/cassettes/ElasticAdapter_Index/_count/empty_index.yml +2 -2
  20. data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index/is_a_fixnum.yml +5 -5
  21. data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index/returns_1.yml +1 -1
  22. data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index.yml +4 -4
  23. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_is_present/response/has_an_exception.yml +1 -1
  24. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_is_present/response/is_a_Response.yml +1 -1
  25. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_is_present.yml +2 -2
  26. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_not_present/response/has_no_exception.yml +1 -1
  27. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_not_present/response/is_a_Response.yml +1 -1
  28. data/spec/cassettes/ElasticAdapter_Index/_create_index/index_not_present/response.yml +1 -1
  29. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_not_present/repsonse/has_an_exception.yml +1 -1
  30. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_not_present/repsonse/is_a_Response.yml +1 -1
  31. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/has_no_exception.yml +1 -1
  32. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/has_no_exceptionElasticAdapter_Index/_delete_index/index_present/repsonse.yml +1 -1
  33. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/is_a_Response.yml +1 -1
  34. data/spec/cassettes/ElasticAdapter_Index/_delete_index/index_present/repsonse/is_a_ResponseElasticAdapter_Index/_delete_index/index_present/repsonse.yml +1 -1
  35. data/spec/cassettes/ElasticAdapter_Index/_get/document_exists/response/document/returns_the_document.yml +1 -1
  36. data/spec/cassettes/ElasticAdapter_Index/_get/document_exists.yml +3 -3
  37. data/spec/cassettes/ElasticAdapter_Index/_index/existing_document/doesn_t_change_the_document_count.yml +1 -55
  38. data/spec/cassettes/ElasticAdapter_Index/_index/existing_document/invokes_to_hash_on_the_document.yml +2 -2
  39. data/spec/cassettes/ElasticAdapter_Index/_index/existing_document/updates_the_document.yml +2 -2
  40. data/spec/cassettes/ElasticAdapter_Index/_index/existing_document.yml +3 -3
  41. data/spec/cassettes/ElasticAdapter_Index/_index/new_document/indexes_a_document.yml +3 -3
  42. data/spec/cassettes/ElasticAdapter_Index/_index/new_document/invokes_to_hash_on_the_document.yml +2 -2
  43. data/spec/cassettes/ElasticAdapter_Index/_index/new_document.yml +2 -2
  44. data/spec/cassettes/ElasticAdapter_Index/_search/match_all/returns_all_documents.yml +2 -2
  45. data/spec/cassettes/ElasticAdapter_Index/_search/zoo/returns_one_document.yml +3 -3
  46. data/spec/cassettes/ElasticAdapter_Index/_search/zoo/returns_the_wanted_document.yml +2 -2
  47. data/spec/cassettes/ElasticAdapter_Index/_search.yml +16 -16
  48. data/spec/cassettes/ElasticAdapter_Index/_suggest/query_ba_/returns_bar.yml +1 -1
  49. data/spec/cassettes/ElasticAdapter_Index/_suggest/query_ba_/returns_one_result.yml +1 -1
  50. data/spec/cassettes/ElasticAdapter_Index/_suggest.yml +4 -4
  51. data/spec/cassettes/ElasticAdapter_Index/_validate/invalid_query/is_a_response.yml +1 -1
  52. data/spec/cassettes/ElasticAdapter_Index/_validate/invalid_query/valid_/is_false.yml +1 -1
  53. data/spec/cassettes/ElasticAdapter_Index/_validate/valid_query/is_a_response.yml +1 -1
  54. data/spec/cassettes/ElasticAdapter_Index/_validate/valid_query/is_true.yml +1 -1
  55. data/spec/cassettes/ElasticAdapter_Index/_validate.yml +2 -2
  56. data/spec/{index → integration/index}/aggregation_spec.rb +10 -2
  57. data/spec/{index → integration/index}/count_spec.rb +5 -10
  58. data/spec/{index → integration/index}/create_index_spec.rb +0 -0
  59. data/spec/{index → integration/index}/delete_index_spec.rb +0 -0
  60. data/spec/{index → integration/index}/get_spec.rb +8 -1
  61. data/spec/integration/index/index_spec.rb +28 -0
  62. data/spec/{index → integration/index}/search_spec.rb +2 -2
  63. data/spec/{index → integration/index}/shared_context.rb +0 -0
  64. data/spec/{index → integration/index}/shared_examples.rb +2 -2
  65. data/spec/{index → integration/index}/suggest_spec.rb +2 -6
  66. data/spec/{index → integration/index}/unit_spec.rb +0 -0
  67. data/spec/{index → integration/index}/validate_spec.rb +1 -16
  68. data/spec/{document_type_spec.rb → unit/document_type_spec.rb} +0 -0
  69. data/spec/{elastic_adapter_spec.rb → unit/elastic_adapter_spec.rb} +0 -0
  70. data/spec/unit/index_spec.rb +218 -0
  71. data/spec/unit/response_spec.rb +28 -0
  72. data/spec/unit/responses/with_aggregations_spec.rb +30 -0
  73. data/spec/unit/responses/with_count_spec.rb +22 -0
  74. data/spec/unit/responses/with_exception_spec.rb +17 -0
  75. data/spec/unit/responses/with_hit_spec.rb +49 -0
  76. data/spec/unit/responses/with_hits_spec.rb +79 -0
  77. data/spec/unit/responses/with_suggestions_spec.rb +33 -0
  78. data/spec/unit/responses/with_validations_spec.rb +34 -0
  79. metadata +61 -65
  80. data/lib/elastic_adapter/responses/aggregation_response.rb +0 -28
  81. data/lib/elastic_adapter/responses/base_response.rb +0 -28
  82. data/lib/elastic_adapter/responses/count_response.rb +0 -13
  83. data/lib/elastic_adapter/responses/get_response.rb +0 -13
  84. data/lib/elastic_adapter/responses/response_decorator_factory.rb +0 -28
  85. data/lib/elastic_adapter/responses/sanitized_response.rb +0 -46
  86. data/lib/elastic_adapter/responses/search_response.rb +0 -33
  87. data/lib/elastic_adapter/responses/suggestion_response.rb +0 -46
  88. data/lib/elastic_adapter/responses/validation_response.rb +0 -18
  89. data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/is_a_response.yml +0 -30
  90. data/spec/cassettes/ElasticAdapter_Index/_count/empty_index/number.yml +0 -57
  91. data/spec/cassettes/ElasticAdapter_Index/_count/not_empty_index/is_a_response.yml +0 -30
  92. data/spec/index/index_spec.rb +0 -60
  93. data/spec/responses/aggregation_response_spec.rb +0 -57
  94. data/spec/responses/base_response_spec.rb +0 -19
  95. data/spec/responses/count_response_spec.rb +0 -24
  96. data/spec/responses/get_response_spec.rb +0 -29
  97. data/spec/responses/response_decorator_factory_spec.rb +0 -126
  98. data/spec/responses/sanitized_response_spec.rb +0 -36
  99. data/spec/responses/search_response_spec.rb +0 -122
  100. data/spec/responses/suggestion_response_spec.rb +0 -63
  101. data/spec/responses/validation_response_spec.rb +0 -45
@@ -0,0 +1,218 @@
1
+ require "spec_helper"
2
+
3
+ module ElasticAdapter
4
+ describe Index do
5
+ let(:name) { "test_index" }
6
+ let(:mappings) do
7
+ {
8
+ test_index: {
9
+ properties: {
10
+ foo: {
11
+ type: "string",
12
+ foo_suggest: { type: "completion" }
13
+ }
14
+ }
15
+ }
16
+ }
17
+ end
18
+ let(:document_type) do
19
+ OpenStruct.new(name: "test_doc", mappings: mappings)
20
+ end
21
+ let(:settings) { { number_of_shards: 1 } }
22
+ let(:log) { true }
23
+ let(:url) { "http://localhost:9200"}
24
+ let(:indices) { double("indices") }
25
+ let(:client) { double("client") }
26
+
27
+ subject do
28
+ ElasticAdapter::Index.new(
29
+ name: name,
30
+ settings: settings,
31
+ document_type: document_type,
32
+ url: url,
33
+ log: log,
34
+ client: client
35
+ )
36
+ end
37
+
38
+ before do
39
+ allow(client).to receive(:indices).and_return(indices)
40
+ end
41
+
42
+ let(:query) {{ query: { match_all: {} } }}
43
+
44
+ describe "#initialize" do
45
+ it "takes a hash as arguments" do
46
+ expect { subject }.not_to raise_error
47
+ end
48
+ end
49
+
50
+ describe "#name" do
51
+ it "returns the name" do
52
+ expect(subject.name).to be name
53
+ end
54
+ end
55
+
56
+ describe "#settings" do
57
+ it "returns the settings" do
58
+ expect(subject.settings).to be settings
59
+ end
60
+ end
61
+
62
+ describe "#document_type" do
63
+ it "returns the document type" do
64
+ expect(subject.document_type).to be document_type
65
+ end
66
+ end
67
+
68
+ describe "#url" do
69
+ it "returns the url" do
70
+ expect(subject.url).to be url
71
+ end
72
+ end
73
+
74
+ describe "#log" do
75
+ it "returns log" do
76
+ expect(subject.log).to be log
77
+ end
78
+ end
79
+
80
+ describe "client" do
81
+ it "returns a client" do
82
+ expect(subject.client).to be client
83
+ end
84
+ end
85
+
86
+ describe "#create_index" do
87
+ it "creates the index" do
88
+ expect(indices).to receive(:create)
89
+ .with(
90
+ index: name,
91
+ body: {
92
+ mappings: document_type.mappings,
93
+ settings: settings
94
+ }
95
+ )
96
+ subject.create_index
97
+ end
98
+ end
99
+
100
+ describe "#delete_index" do
101
+ it "deletes the index" do
102
+ expect(indices).to receive(:delete).with(index: name)
103
+ subject.delete_index
104
+ end
105
+ end
106
+
107
+ describe "#count" do
108
+ it "does a count request" do
109
+ expect(client).to receive(:count).with(index: name, body: query)
110
+ subject.count(query)
111
+ end
112
+
113
+ it "returns a response with count" do
114
+ expect(client).to receive(:count).and_return({})
115
+ expect(subject.count(query).singleton_class).to be < Responses::WithCount
116
+ end
117
+ end
118
+
119
+ describe "#index" do
120
+ let(:doc) {{ id: 1, foo: "bar" }}
121
+
122
+ it "indexes the document" do
123
+ expect(client).to receive(:index)
124
+ .with(
125
+ index: name,
126
+ id: 1,
127
+ type: document_type.name,
128
+ body: { foo: "bar" }
129
+ )
130
+ subject.index(doc)
131
+ end
132
+
133
+ it "returns a response" do
134
+ expect(client).to receive(:index).and_return({})
135
+ result = subject.index(doc)
136
+ expect(result).to be_a Response
137
+ end
138
+ end
139
+
140
+ describe "#get" do
141
+ it "does a get request" do
142
+ expect(client).to receive(:get).with(index: name, type: document_type.name, id: 1)
143
+ subject.get(1)
144
+ end
145
+
146
+ it "returns a response with hit" do
147
+ expect(client).to receive(:get).and_return({})
148
+ result = subject.get(1)
149
+ expect(result.singleton_class).to be < Responses::WithHit
150
+ end
151
+ end
152
+
153
+ describe "#search" do
154
+ it "does a search request" do
155
+ expect(client).to receive(:search).with(index: name, body: query)
156
+ subject.search(query)
157
+ end
158
+
159
+ it "returns a response with hits, aggregations and suggestions" do
160
+ expect(client).to receive(:search).and_return({})
161
+ result = subject.search(query)
162
+ expect(result.singleton_class).to be < Responses::WithHits
163
+ expect(result.singleton_class).to be < Responses::WithSuggestions
164
+ expect(result.singleton_class).to be < Responses::WithAggregations
165
+ end
166
+ end
167
+
168
+ describe "#suggest" do
169
+ it "does a suggest request" do
170
+ expect(client).to receive(:suggest).with(index: name, body: query)
171
+ subject.suggest(query)
172
+ end
173
+
174
+ it "returns a response with suggestions" do
175
+ expect(client).to receive(:suggest).and_return({})
176
+ result = subject.suggest(query)
177
+ expect(result.singleton_class).to be < Responses::WithSuggestions
178
+ end
179
+ end
180
+
181
+ describe "#aggregate" do
182
+ it "does a aggregate request" do
183
+ expect(client).to receive(:search).with(index: name, body: query)
184
+ subject.aggregate(query)
185
+ end
186
+
187
+ it "returns a response with aggregations" do
188
+ expect(client).to receive(:search).and_return({})
189
+ result = subject.aggregate(query)
190
+ expect(result.singleton_class).to be < Responses::WithAggregations
191
+ end
192
+ end
193
+
194
+ describe "#validate" do
195
+ it "does a validate request" do
196
+ expect(indices).to receive(:validate_query).with(index: name, body: query, explain: true)
197
+ subject.validate(query)
198
+ end
199
+
200
+ it "returns a response with validations" do
201
+ expect(indices).to receive(:validate_query).and_return({})
202
+ result = subject.validate(query)
203
+ expect(result.singleton_class).to be < Responses::WithValidations
204
+ end
205
+ end
206
+
207
+ describe "error handling" do
208
+ before do
209
+ allow(client).to receive(:search).and_raise(Elasticsearch::Transport::Transport::Error)
210
+ end
211
+
212
+ it "returns a response with exception" do
213
+ result = subject.search(query)
214
+ expect(result.singleton_class).to be < Responses::WithException
215
+ end
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ module ElasticAdapter
4
+ describe Response do
5
+ let(:object) {{
6
+ "foo" => { "bim" => "bam" },
7
+ "bar" => [
8
+ { "biz" => "buz" }
9
+ ],
10
+ "boo" => "bam"
11
+ }}
12
+
13
+ subject { Response.new(object) }
14
+
15
+ describe "symbolize keys" do
16
+ it "symbolizes all keys" do
17
+ expected = {
18
+ foo: { bim: "bam" },
19
+ bar: [
20
+ { biz: "buz" }
21
+ ],
22
+ boo: "bam"
23
+ }
24
+ expect(subject.object).to eq expected
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+
3
+ module ElasticAdapter
4
+ describe Responses::WithAggregations do
5
+ let(:plain_response) {{
6
+ aggregations: {
7
+ products: {
8
+ doc_count_error_upper_bound: 46,
9
+ buckets: [
10
+ {
11
+ key: "Product A",
12
+ doc_count: 100
13
+ },
14
+ {
15
+ key: "Product Z",
16
+ doc_count: 52
17
+ }
18
+ ]
19
+ }
20
+ }
21
+ }}
22
+ subject { Response.new(plain_response).extend(Responses::WithAggregations) }
23
+
24
+ describe "#aggregations" do
25
+ it "includes the products aggregation" do
26
+ expect(subject.aggregations).to eq plain_response[:aggregations]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ module ElasticAdapter
4
+ describe Responses::WithCount do
5
+ let(:plain_response) {{
6
+ count: 1,
7
+ shards: {
8
+ total: 5,
9
+ successful: 5,
10
+ failed: 0
11
+ }
12
+ }}
13
+
14
+ subject { Response.new(plain_response).extend(Responses::WithCount) }
15
+
16
+ describe "#count" do
17
+ it "returns the count" do
18
+ expect(subject.count).to eq 1
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ module ElasticAdapter
4
+ describe Responses::WithException do
5
+ let(:plain_response) {{
6
+ exception: ArgumentError.new()
7
+ }}
8
+
9
+ subject { Response.new(plain_response).extend(Responses::WithException) }
10
+
11
+ describe "#exception" do
12
+ it "returns the exception" do
13
+ expect(subject.exception).to be plain_response[:exception]
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ require "spec_helper"
2
+
3
+ module ElasticAdapter
4
+ describe Responses::WithHits do
5
+ let(:plain_response) {{
6
+ index: "twitter",
7
+ type: "tweet",
8
+ id: "1",
9
+ version: 1,
10
+ found: true,
11
+ source: {
12
+ user: "kimchy",
13
+ postDate: "2009-11-15T14:12:12",
14
+ message: "trying out Elasticsearch"
15
+ }
16
+ }}
17
+ subject { Response.new(plain_response).extend(Responses::WithHit) }
18
+
19
+ describe "#hit" do
20
+ it "is the hit" do
21
+ doc = {
22
+ index: "twitter",
23
+ type: "tweet",
24
+ id: "1",
25
+ source: {
26
+ user: "kimchy",
27
+ postDate: "2009-11-15T14:12:12",
28
+ message: "trying out Elasticsearch"
29
+ }
30
+ }
31
+
32
+ expect(subject.hit).to eq doc
33
+
34
+ end
35
+
36
+ describe "#found?" do
37
+ it "returns true" do
38
+ expect(subject.hit.found?).to be true
39
+ end
40
+ end
41
+
42
+ describe "#found" do
43
+ it "returns the version" do
44
+ expect(subject.hit.version).to eq 1
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,79 @@
1
+ require "spec_helper"
2
+
3
+ module ElasticAdapter
4
+ describe Responses::WithHits do
5
+ context "with hits" do
6
+ let(:plain_response) {{
7
+ shards: {
8
+ total: 5,
9
+ successful: 5,
10
+ failed: 0
11
+ },
12
+ hits: {
13
+ total: 100,
14
+ hits: [
15
+ {
16
+ index: "twitter",
17
+ type: "tweet",
18
+ id: "1",
19
+ source: {
20
+ user: "kimchy",
21
+ postDate: "2009-11-15T14:12:12",
22
+ message: "trying out Elasticsearch"
23
+ }
24
+ }
25
+ ]
26
+ }
27
+ }}
28
+
29
+ subject { Response.new(plain_response).extend(Responses::WithHits) }
30
+
31
+ describe "#hits" do
32
+ it "includes the hit in a flattened format" do
33
+ doc = {
34
+ index: "twitter",
35
+ type: "tweet",
36
+ id: "1",
37
+ source: {
38
+ user: "kimchy",
39
+ postDate: "2009-11-15T14:12:12",
40
+ message: "trying out Elasticsearch"
41
+ }
42
+ }
43
+
44
+ expect(subject.hits).to include doc
45
+ end
46
+
47
+ describe "#count" do
48
+ it "returns the count" do
49
+ expect(subject.hits.count).to be plain_response[:hits][:total]
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ context "without hits" do
56
+ let(:plain_response) {{
57
+ shards: {
58
+ total: 5,
59
+ successful: 5,
60
+ failed: 0
61
+ },
62
+ hits: {
63
+ total: 0,
64
+ hits: []
65
+ }
66
+ }}
67
+
68
+ subject { Response.new(plain_response).extend(Responses::WithHits) }
69
+
70
+ describe "#hits" do
71
+ describe "#count" do
72
+ it "returns 0" do
73
+ expect(subject.hits.count).to eq 0
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,33 @@
1
+ require "spec_helper"
2
+
3
+ module ElasticAdapter
4
+ describe Responses::WithSuggestions do
5
+ let(:plain_response) {{
6
+ shards: {
7
+ total: 5, successful: 5, failed: 0
8
+ },
9
+ suggest: {
10
+ foo_suggest: [
11
+ {
12
+ text: "ba",
13
+ offset: 0,
14
+ length: 2,
15
+ options: [
16
+ {
17
+ text: "bar",
18
+ score: 1.0
19
+ }
20
+ ]
21
+ }
22
+ ]
23
+ }
24
+ }}
25
+ subject { Response.new(plain_response).extend(Responses::WithSuggestions) }
26
+
27
+ describe "#suggestions" do
28
+ it "includes the suggestion" do
29
+ expect(subject.suggestions).to eq plain_response[:suggest]
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+
3
+ module ElasticAdapter
4
+ describe Responses::WithValidations do
5
+ let(:plain_response) {{
6
+ valid: false,
7
+ shards: {
8
+ total: 1,
9
+ successful: 1,
10
+ failed: 0
11
+ },
12
+ explanations: [
13
+ {
14
+ index: "twitter",
15
+ valid: false,
16
+ error: "some error message"
17
+ }
18
+ ]
19
+ }}
20
+ subject { Response.new(plain_response).extend(Responses::WithValidations) }
21
+
22
+ describe "#explanations" do
23
+ it "includes the explanation" do
24
+ expect(subject.explanations).to eq plain_response[:explanations]
25
+ end
26
+ end
27
+
28
+ describe "#valid?" do
29
+ it "returns false" do
30
+ expect(subject.valid?).to be false
31
+ end
32
+ end
33
+ end
34
+ end