elastic_adapter 0.0.8 → 0.1.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.
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