esearch 0.2.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. data/.gitignore +5 -0
  2. data/.rspec +6 -0
  3. data/.travis.yml +19 -0
  4. data/Changelog.md +27 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.devtools +60 -0
  7. data/Guardfile +18 -0
  8. data/LICENSE +20 -0
  9. data/README.md +93 -0
  10. data/Rakefile +2 -0
  11. data/TODO +3 -0
  12. data/config/devtools.yml +2 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +3 -0
  15. data/config/mutant.yml +3 -0
  16. data/config/reek.yml +103 -0
  17. data/config/yardstick.yml +2 -0
  18. data/esearch.gemspec +26 -0
  19. data/lib/esearch.rb +43 -0
  20. data/lib/esearch/cluster.rb +85 -0
  21. data/lib/esearch/command.rb +158 -0
  22. data/lib/esearch/command/cluster.rb +28 -0
  23. data/lib/esearch/command/document.rb +111 -0
  24. data/lib/esearch/command/exist.rb +37 -0
  25. data/lib/esearch/command/index.rb +66 -0
  26. data/lib/esearch/command/search.rb +24 -0
  27. data/lib/esearch/command/status.rb +24 -0
  28. data/lib/esearch/connection.rb +36 -0
  29. data/lib/esearch/document.rb +53 -0
  30. data/lib/esearch/index.rb +61 -0
  31. data/lib/esearch/indices.rb +52 -0
  32. data/lib/esearch/mixin.rb +111 -0
  33. data/lib/esearch/presenter.rb +43 -0
  34. data/lib/esearch/presenter/aspect.rb +17 -0
  35. data/lib/esearch/presenter/aspect/range.rb +63 -0
  36. data/lib/esearch/presenter/aspect/term.rb +19 -0
  37. data/lib/esearch/presenter/cluster.rb +84 -0
  38. data/lib/esearch/presenter/document.rb +102 -0
  39. data/lib/esearch/presenter/facet.rb +72 -0
  40. data/lib/esearch/presenter/hit.rb +70 -0
  41. data/lib/esearch/presenter/hits.rb +60 -0
  42. data/lib/esearch/presenter/index.rb +23 -0
  43. data/lib/esearch/presenter/search.rb +32 -0
  44. data/lib/esearch/presenter/status.rb +18 -0
  45. data/lib/esearch/request.rb +90 -0
  46. data/lib/esearch/type.rb +40 -0
  47. data/spec/integration/esearch/spike_spec.rb +50 -0
  48. data/spec/spec_helper.rb +65 -0
  49. data/spec/support/example_group_methods.rb +7 -0
  50. data/spec/support/ice_nine_config.rb +6 -0
  51. data/spec/unit/esearch/cluster/class_methods/connect_spec.rb +16 -0
  52. data/spec/unit/esearch/cluster/health_spec.rb +10 -0
  53. data/spec/unit/esearch/cluster/index_spec.rb +11 -0
  54. data/spec/unit/esearch/cluster/indices_spec.rb +11 -0
  55. data/spec/unit/esearch/cluster/path_spec.rb +11 -0
  56. data/spec/unit/esearch/command/class_methods/run_spec.rb +16 -0
  57. data/spec/unit/esearch/command/cluster/health/run_spec.rb +14 -0
  58. data/spec/unit/esearch/command/document/delete/run_spec.rb +13 -0
  59. data/spec/unit/esearch/command/document/get/result_spec.rb +27 -0
  60. data/spec/unit/esearch/command/document/index/create/run_spec.rb +17 -0
  61. data/spec/unit/esearch/command/document/index/run_create_spec.rb +17 -0
  62. data/spec/unit/esearch/command/document/index/run_spec.rb +15 -0
  63. data/spec/unit/esearch/command/document/index/run_update_spec.rb +15 -0
  64. data/spec/unit/esearch/command/document/index/update/run_spec.rb +15 -0
  65. data/spec/unit/esearch/command/exist/result_spec.rb +39 -0
  66. data/spec/unit/esearch/command/index/create/run_spec.rb +14 -0
  67. data/spec/unit/esearch/command/index/delete/run_spec.rb +13 -0
  68. data/spec/unit/esearch/command/index/refresh/run_spec.rb +13 -0
  69. data/spec/unit/esearch/command/result_spec.rb +68 -0
  70. data/spec/unit/esearch/command/search/run_spec.rb +14 -0
  71. data/spec/unit/esearch/command/status/run_spec.rb +13 -0
  72. data/spec/unit/esearch/connection/class_methods/build_spec.rb +29 -0
  73. data/spec/unit/esearch/connection/run_spec.rb +36 -0
  74. data/spec/unit/esearch/document/connection_spec.rb +12 -0
  75. data/spec/unit/esearch/document/delete_spec.rb +12 -0
  76. data/spec/unit/esearch/document/get_spec.rb +12 -0
  77. data/spec/unit/esearch/index/create_spec.rb +12 -0
  78. data/spec/unit/esearch/index/delete_spec.rb +11 -0
  79. data/spec/unit/esearch/index/type_spec.rb +12 -0
  80. data/spec/unit/esearch/indices/all/path_spec.rb +12 -0
  81. data/spec/unit/esearch/mixin/document/index_create_spec.rb +31 -0
  82. data/spec/unit/esearch/mixin/document/index_spec.rb +31 -0
  83. data/spec/unit/esearch/mixin/document/index_update_spec.rb +31 -0
  84. data/spec/unit/esearch/mixin/exist/exist_predicate_spec.rb +16 -0
  85. data/spec/unit/esearch/mixin/index/refresh_spec.rb +16 -0
  86. data/spec/unit/esearch/mixin/index/status_spec.rb +16 -0
  87. data/spec/unit/esearch/mixin/search/search_spec.rb +18 -0
  88. data/spec/unit/esearch/presenter/aspect/range/from_spec.rb +24 -0
  89. data/spec/unit/esearch/presenter/aspect/range/to_spec.rb +24 -0
  90. data/spec/unit/esearch/presenter/class_methods/new_spec.rb +37 -0
  91. data/spec/unit/esearch/presenter/facet/build_spec.rb +26 -0
  92. data/spec/unit/esearch/presenter/facet/class_methods/build_spec.rb +26 -0
  93. data/spec/unit/esearch/presenter/hit/fields_spec.rb +24 -0
  94. data/spec/unit/esearch/presenter/hit/source_spec.rb +24 -0
  95. data/spec/unit/esearch/presenter/hits/each_spec.rb +15 -0
  96. data/spec/unit/esearch/presenter/hits/size_spec.rb +13 -0
  97. data/spec/unit/esearch/request/initialize_spec.rb +39 -0
  98. data/spec/unit/esearch/request/run_spec.rb +39 -0
  99. data/spec/unit/esearch/type/connection_spec.rb +15 -0
  100. data/spec/unit/esearch/type/document_spec.rb +12 -0
  101. metadata +330 -0
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Mixin::Document, '#index' do
4
+
5
+ let(:object) { class_under_test.new(connection) }
6
+
7
+ let(:class_under_test) do
8
+ Class.new do
9
+ include Concord.new(:connection), Esearch::Mixin::Document
10
+ end
11
+ end
12
+
13
+ context 'with one arg' do
14
+ subject { object.index(document) }
15
+ let(:document) { mock('Document') }
16
+
17
+ let(:expected_arguments) { [document, {}] }
18
+
19
+ expect_to_run_command(Esearch::Command::Document::Index)
20
+ end
21
+
22
+ context 'with two args' do
23
+ subject { object.index(document, options) }
24
+ let(:document) { mock('Document') }
25
+ let(:options) { mock('Options') }
26
+
27
+ let(:expected_arguments) { [document, options] }
28
+
29
+ expect_to_run_command(Esearch::Command::Document::Index)
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Mixin::Document, '#index_update' do
4
+
5
+ let(:object) { class_under_test.new(connection) }
6
+
7
+ let(:class_under_test) do
8
+ Class.new do
9
+ include Concord.new(:connection), Esearch::Mixin::Document
10
+ end
11
+ end
12
+
13
+ context 'with one arg' do
14
+ subject { object.index_update(document) }
15
+ let(:document) { mock('Document') }
16
+
17
+ let(:expected_arguments) { [document, {}] }
18
+
19
+ expect_to_run_command(Esearch::Command::Document::Index::Update)
20
+ end
21
+
22
+ context 'with two args' do
23
+ subject { object.index_update(document, options) }
24
+ let(:document) { mock('Document') }
25
+ let(:options) { mock('Options') }
26
+
27
+ let(:expected_arguments) { [document, options] }
28
+
29
+ expect_to_run_command(Esearch::Command::Document::Index::Update)
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Mixin::Exist, '#exist?' do
4
+ subject { object.exist? }
5
+
6
+ let(:object) { class_under_test.new(connection) }
7
+
8
+ let(:class_under_test) do
9
+ Class.new do
10
+ include Concord.new(:connection), Esearch::Mixin::Exist
11
+ end
12
+ end
13
+
14
+ let(:expected_arguments) { [] }
15
+ expect_to_run_command(Esearch::Command::Exist)
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Mixin::Index, '#refresh' do
4
+ subject { object.refresh }
5
+
6
+ let(:object) { class_under_test.new(connection) }
7
+
8
+ let(:class_under_test) do
9
+ Class.new do
10
+ include Concord.new(:connection), Esearch::Mixin::Index
11
+ end
12
+ end
13
+
14
+ let(:expected_arguments) { [] }
15
+ expect_to_run_command(Esearch::Command::Index::Refresh)
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Mixin::Index, '#status' do
4
+ subject { object.status }
5
+
6
+ let(:object) { class_under_test.new(connection) }
7
+
8
+ let(:class_under_test) do
9
+ Class.new do
10
+ include Concord.new(:connection), Esearch::Mixin::Index
11
+ end
12
+ end
13
+
14
+ let(:expected_arguments) { [] }
15
+ expect_to_run_command(Esearch::Command::Status)
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Mixin::Search, '#search' do
4
+ subject { object.search(query) }
5
+
6
+ let(:object) { class_under_test.new(connection) }
7
+
8
+ let(:class_under_test) do
9
+ Class.new do
10
+ include Concord.new(:connection), Esearch::Mixin::Search
11
+ end
12
+ end
13
+
14
+ let(:query) { mock('Query') }
15
+ let(:expected_arguments) { [query] }
16
+
17
+ expect_to_run_command(Esearch::Command::Search)
18
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Presenter::Aspect::Range, '#from' do
4
+ subject { object.from }
5
+
6
+ let(:object) { described_class.new(raw) }
7
+ let(:value) { mock('Value') }
8
+
9
+ context 'when _source is present' do
10
+ let(:raw) { { 'from' => value } }
11
+
12
+ it { should be(value) }
13
+
14
+ it_should_behave_like 'an idempotent method'
15
+ end
16
+
17
+ context 'when _source is NOT present' do
18
+ let(:raw) { {} }
19
+
20
+ it { should be(nil) }
21
+
22
+ it_should_behave_like 'an idempotent method'
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Presenter::Aspect::Range, '#to' do
4
+ subject { object.to }
5
+
6
+ let(:object) { described_class.new(raw) }
7
+ let(:value) { mock('Value') }
8
+
9
+ context 'when _source is present' do
10
+ let(:raw) { { 'to' => value } }
11
+
12
+ it { should be(value) }
13
+
14
+ it_should_behave_like 'an idempotent method'
15
+ end
16
+
17
+ context 'when _source is NOT present' do
18
+ let(:raw) { {} }
19
+
20
+ it { should be(nil) }
21
+
22
+ it_should_behave_like 'an idempotent method'
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Presenter, '.new' do
4
+ let(:object) { class_under_test }
5
+
6
+ subject { object.new(raw) }
7
+
8
+ let(:value) { mock('Value') }
9
+
10
+ class DummyPresenter
11
+ include Concord.new(:raw)
12
+ end
13
+
14
+ context 'with exposed tagged collection' do
15
+ let(:raw) { { 'foo' => { 'bar' => { 'baz' => 'bor' } } } }
16
+
17
+ let(:class_under_test) do
18
+ Class.new(described_class) do
19
+ expose_tagged_collection(:foo, DummyPresenter)
20
+ end
21
+ end
22
+
23
+ its(:foo) { should eql([DummyPresenter.new('baz' => 'bor', 'name' => 'bar')]) }
24
+ end
25
+
26
+ context 'with exposed primitive' do
27
+ let(:raw) { { 'foo' => value } }
28
+
29
+ let(:class_under_test) do
30
+ Class.new(described_class) do
31
+ expose_primitive :foo
32
+ end
33
+ end
34
+
35
+ its(:foo) { should be(value) }
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Presenter::Facet, '.build' do
4
+ subject { object.build(raw) }
5
+
6
+ let(:object) { described_class }
7
+
8
+ context 'when type is "terms"' do
9
+ let(:raw) { { '_type' => 'terms' } }
10
+ it { should eql(Esearch::Presenter::Facet::Terms.new(raw)) }
11
+ end
12
+
13
+ context 'when type is "range"' do
14
+ let(:raw) { { '_type' => 'range' } }
15
+ it { should eql(Esearch::Presenter::Facet::Range.new(raw)) }
16
+ end
17
+
18
+ context 'with unknown type' do
19
+ let(:raw) { { '_type' => 'foo' } }
20
+
21
+ it 'should raise error' do
22
+ expect { subject }.to raise_error('Facet with type "foo" is not known')
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Presenter::Facet, '.build' do
4
+ subject { object.build(raw) }
5
+
6
+ let(:object) { described_class }
7
+
8
+ context 'when type is "terms"' do
9
+ let(:raw) { { '_type' => 'terms' } }
10
+ it { should eql(Esearch::Presenter::Facet::Terms.new(raw)) }
11
+ end
12
+
13
+ context 'when type is "range"' do
14
+ let(:raw) { { '_type' => 'range' } }
15
+ it { should eql(Esearch::Presenter::Facet::Range.new(raw)) }
16
+ end
17
+
18
+ context 'with unknown type' do
19
+ let(:raw) { { '_type' => 'foo' } }
20
+
21
+ it 'should raise error' do
22
+ expect { subject }.to raise_error('Facet with type "foo" is not known')
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Presenter::Hit, '#fields' do
4
+ subject { object.fields }
5
+
6
+ let(:object) { described_class.new(raw) }
7
+ let(:value) { mock('Value') }
8
+
9
+ context 'when fields is present' do
10
+ let(:raw) { { 'fields' => value } }
11
+
12
+ it { should be(value) }
13
+
14
+ it_should_behave_like 'an idempotent method'
15
+ end
16
+
17
+ context 'when fields is NOT present' do
18
+ let(:raw) { {} }
19
+
20
+ it { should be(nil) }
21
+
22
+ it_should_behave_like 'an idempotent method'
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Presenter::Hit, '#source' do
4
+ subject { object.source }
5
+
6
+ let(:object) { described_class.new(raw) }
7
+ let(:value) { mock('Value') }
8
+
9
+ context 'when _source is present' do
10
+ let(:raw) { { '_source' => value } }
11
+
12
+ it { should be(value) }
13
+
14
+ it_should_behave_like 'an idempotent method'
15
+ end
16
+
17
+ context 'when _source is NOT present' do
18
+ let(:raw) { {} }
19
+
20
+ it { should be(nil) }
21
+
22
+ it_should_behave_like 'an idempotent method'
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Presenter::Hits, '#each' do
4
+ subject { object.each { |hit| yields << hit } }
5
+
6
+ let(:object) { described_class.new(raw) }
7
+ let(:yields) { [] }
8
+ let(:hit_a) { mock('Hit A') }
9
+ let(:hit_b) { mock('Hit B') }
10
+ let(:raw) { { 'hits' => [ hit_a, hit_b ] } }
11
+
12
+ it_should_behave_like 'an #each method'
13
+
14
+ its(:to_a) { should eql([Esearch::Presenter::Hit.new(hit_a), Esearch::Presenter::Hit.new(hit_b)]) }
15
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Presenter::Hits, '#size' do
4
+ subject { object.size }
5
+
6
+ let(:object) { described_class.new(raw) }
7
+ let(:size) { mock('Size') }
8
+ let(:raw) { { 'hits' => mock(:size => size)} }
9
+
10
+ it { should be(size) }
11
+
12
+ it_should_behave_like 'an idempotent method'
13
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Request, '.new' do
4
+ let(:object) { described_class }
5
+
6
+ subject { object.new(*arguments) }
7
+
8
+ let(:verb) { mock('Verb') }
9
+ let(:path) { '/some/path' }
10
+ let(:params) { mock('Params') }
11
+ let(:body) { mock('Body') }
12
+
13
+ context 'with two args' do
14
+ let(:arguments) { [ verb, path ] }
15
+
16
+ its(:verb) { should be(verb) }
17
+ its(:path) { should be(path) }
18
+ its(:body) { should be(described_class::EMPTY_HASH) }
19
+ its(:params) { should be(described_class::EMPTY_HASH) }
20
+ end
21
+
22
+ context 'with three args' do
23
+ let(:arguments) { [ verb, path, body ] }
24
+
25
+ its(:verb) { should be(verb) }
26
+ its(:path) { should be(path) }
27
+ its(:body) { should be(body) }
28
+ its(:params) { should be(described_class::EMPTY_HASH) }
29
+ end
30
+
31
+ context 'with four args' do
32
+ let(:arguments) { [ verb, path, body, params ] }
33
+
34
+ its(:verb) { should be(verb) }
35
+ its(:path) { should be(path) }
36
+ its(:body) { should be(body) }
37
+ its(:params) { should be(params) }
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Request, '#run' do
4
+ let(:object) { described_class.new(verb, path, body, params) }
5
+
6
+ subject { object.run(connection) }
7
+
8
+ let(:verb) { :get }
9
+ let(:path) { '/some/random/path' }
10
+ let(:body) { { 'foo' => 'bar' } }
11
+ let(:params) { { 'baz' => 'buz' } }
12
+
13
+ let(:response_status) { mock('Status') }
14
+ let(:response_headers) { {} }
15
+ let(:response_body) { mock('Body') }
16
+
17
+ let(:connection) do
18
+ Faraday.new do |builder|
19
+ builder.adapter :test, stubs
20
+ end
21
+ end
22
+
23
+ let(:stubs) do
24
+ Faraday::Adapter::Test::Stubs.new do |stub|
25
+ stub.get('/some/random/path') do |env|
26
+ env.fetch(:request_headers).fetch('Content-Type').should eql('application/json; charset=UTF-8')
27
+ env.fetch(:method).should be(:get)
28
+ env.fetch(:params).should eql(params)
29
+ env.fetch(:url).should eql(URI.parse('http:/some/random/path?baz=buz'))
30
+ env.fetch(:body).should eql('{"foo":"bar"}')
31
+ [ response_status, response_headers, response_body ]
32
+ end
33
+ end
34
+ end
35
+
36
+ its(:status) { should be(response_status) }
37
+ its(:headers) { should eql(Faraday::Utils::Headers.new(response_headers)) }
38
+ its(:body) { should be(response_body) }
39
+ end