esearch 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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