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,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Document::Index::Create, '.run' do
4
+ subject { object.run(context, document, options) }
5
+
6
+ let(:object) { described_class }
7
+ let(:document) { mock('Document') }
8
+ let(:options) { { :foo => :bar } }
9
+
10
+ let(:expected_request) do
11
+ Esearch::Request.new(:post, '/foo', document, { :foo => :bar, :op_type => :create })
12
+ end
13
+
14
+ expect_presenter(Esearch::Presenter::Document::Operation::Index) do
15
+ let(:status) { 201 }
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Document::Index, '.run' do
4
+ subject { object.run(context, document, options) }
5
+
6
+ let(:object) { described_class }
7
+ let(:document) { mock('Document') }
8
+ let(:options) { { :foo => :bar } }
9
+
10
+ let(:expected_request) do
11
+ Esearch::Request.new(:post, '/foo', document, options)
12
+ end
13
+
14
+ expect_presenter(Esearch::Presenter::Document::Operation::Index)
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Document::Index::Update, '.run' do
4
+ subject { object.run(context, document, options) }
5
+
6
+ let(:object) { described_class }
7
+ let(:document) { mock('Document') }
8
+ let(:options) { { :foo => :bar } }
9
+
10
+ let(:expected_request) do
11
+ Esearch::Request.new(:post, '/foo', document, { :foo => :bar, :op_type => :index })
12
+ end
13
+
14
+ expect_presenter(Esearch::Presenter::Document::Operation::Index)
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Document::Index::Update, '.run' do
4
+ subject { object.run(context, document, options) }
5
+
6
+ let(:object) { described_class }
7
+ let(:document) { mock('Document') }
8
+ let(:options) { { :foo => :bar } }
9
+
10
+ let(:expected_request) do
11
+ Esearch::Request.new(:post, '/foo', document, { :foo => :bar, :op_type => :index })
12
+ end
13
+
14
+ expect_presenter(Esearch::Presenter::Document::Operation::Index)
15
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Exist, '.run' do
4
+ subject { object.run(context) }
5
+
6
+ let(:object) { described_class }
7
+
8
+ let(:expected_request) do
9
+ Esearch::Request.new(:head, '/foo', {}, {})
10
+ end
11
+
12
+ before do
13
+ connection.should_receive(:run).with(expected_request).and_return(response)
14
+ end
15
+
16
+ let(:context) { mock('Context', :connection => connection, :path => Pathname.new('/foo')) }
17
+ let(:connection) { mock('Connection') }
18
+
19
+ let(:headers) { {'content-type' => 'application/json; charset=UTF-8'} }
20
+ let(:response) { mock('Response', :frozen? => true, :status => status, :headers => headers, :body => '{}') }
21
+
22
+ context 'with status 200' do
23
+ let(:status) { 200 }
24
+ it { should be(true) }
25
+ end
26
+
27
+ context 'with status 404' do
28
+ let(:status) { 404 }
29
+ it { should be(false) }
30
+ end
31
+
32
+ context 'with other status' do
33
+ let(:status) { 500 }
34
+
35
+ it 'should raise error' do
36
+ expect { subject }.to raise_error
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Index::Create, '.run' do
4
+ subject { object.run(context, settings) }
5
+
6
+ let(:object) { described_class }
7
+ let(:settings) { mock('Settings') }
8
+
9
+ let(:expected_request) do
10
+ Esearch::Request.new(:put, '/foo', settings, {})
11
+ end
12
+
13
+ expect_presenter(Esearch::Presenter::Index::Create)
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Index::Delete, '.run' do
4
+ subject { object.run(context) }
5
+
6
+ let(:object) { described_class }
7
+
8
+ let(:expected_request) do
9
+ Esearch::Request.new(:delete, '/foo', {}, {})
10
+ end
11
+
12
+ expect_presenter(Esearch::Presenter::Index::Delete)
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Index::Refresh, '.run' do
4
+ subject { object.run(context) }
5
+
6
+ let(:object) { described_class }
7
+
8
+ let(:expected_request) do
9
+ Esearch::Request.new(:post, '/foo/_refresh', {}, {})
10
+ end
11
+
12
+ expect_presenter(Esearch::Presenter::Index::Refresh)
13
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command, '#result' do
4
+ let(:object) { class_under_test.new(context) }
5
+
6
+ subject { object.result }
7
+
8
+ class DummyPresenter
9
+ include Concord.new(:raw)
10
+ end
11
+
12
+ let(:class_under_test) do
13
+ Class.new(described_class) do
14
+ const_set('PRESENTER', DummyPresenter)
15
+ def request
16
+ Esearch::Request.new(:get, context_path)
17
+ end
18
+ end
19
+ end
20
+
21
+
22
+ let(:context) { mock('Context', :connection => connection, :path => Pathname.new('/foo')) }
23
+ let(:connection) { mock('Connection') }
24
+
25
+ let(:headers) { {'content-type' => content_type } }
26
+ let(:content_type) { 'application/json; charset=UTF-8' }
27
+ let(:response) { mock('Response', :frozen? => true, :status => status, :headers => headers, :body => body) }
28
+ let(:body) { '{}' }
29
+
30
+ let(:status) { 200 }
31
+
32
+ let(:expected_request) do
33
+ Esearch::Request.new(:get, context.path)
34
+ end
35
+
36
+ before do
37
+ connection.should_receive(:run).with(expected_request).and_return(response)
38
+ end
39
+
40
+ it { should eql(DummyPresenter.new({})) }
41
+
42
+ context 'when content type is not expected' do
43
+ let(:content_type) { 'text/plain' }
44
+
45
+ it 'should raise error' do
46
+ expect { subject }.to raise_error(Esearch::ProtocolError, 'Expected json content type, but got: "text/plain"')
47
+ end
48
+ end
49
+
50
+ context 'when status code is not expected' do
51
+ let(:status) { 201 }
52
+
53
+ context 'with json body' do
54
+ it 'should raise error' do
55
+ expect { subject }.to raise_error(Esearch::ProtocolError, 'expected response stati: [200] but got: 201, remote message: {}')
56
+ end
57
+ end
58
+
59
+ context 'with other body' do
60
+ let(:content_type) { 'text/plain' }
61
+ let(:body) { 'message' }
62
+
63
+ it 'should raise error' do
64
+ expect { subject }.to raise_error(Esearch::ProtocolError, 'expected response stati: [200] but got: 201, remote message: "message"')
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Search, '.run' do
4
+ subject { object.run(context, query) }
5
+
6
+ let(:object) { described_class }
7
+ let(:query) { mock('Query') }
8
+
9
+ let(:expected_request) do
10
+ Esearch::Request.new(:get, '/foo/_search', query, {})
11
+ end
12
+
13
+ expect_presenter(Esearch::Presenter::Search)
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Command::Status, '.run' do
4
+ subject { object.run(context) }
5
+
6
+ let(:object) { described_class }
7
+
8
+ let(:expected_request) do
9
+ Esearch::Request.new(:get, '/foo/_status', {}, {})
10
+ end
11
+
12
+ expect_presenter(Esearch::Presenter::Status)
13
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Connection, '.build' do
4
+ let(:object) { described_class }
5
+
6
+ subject { object.build(*arguments) }
7
+
8
+ let(:url) { mock('URL') }
9
+ let(:logger) { mock('Logger') }
10
+ let(:connection) { mock('Connection') }
11
+
12
+ before do
13
+ Faraday.should_receive(:new).with(url).and_return(connection)
14
+ end
15
+
16
+ context 'with one argument' do
17
+ let(:arguments) { [url] }
18
+
19
+ its(:raw_connection) { should be(connection) }
20
+ its(:logger) { should be(NullLogger.instance) }
21
+ end
22
+
23
+ context 'with twi arguments' do
24
+ let(:arguments) { [url, logger] }
25
+
26
+ its(:raw_connection) { should be(connection) }
27
+ its(:logger) { should be(logger) }
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Connection, '#run' do
4
+ subject { object.run(request) }
5
+
6
+ let(:object) { described_class.new(connection, logger) }
7
+
8
+ let(:connection) { mock('Connection') }
9
+ let(:logger) { DummyLogger.new }
10
+ let(:request) { mock('Request', :log_string => 'the-logged-string') }
11
+ let(:response) { mock('Response', :status => 200) }
12
+
13
+ class DummyLogger
14
+ attr_reader :messages
15
+
16
+ def initialize
17
+ @messages = []
18
+ end
19
+
20
+ def debug
21
+ @messages << yield
22
+ end
23
+ end
24
+
25
+ before do
26
+ request.should_receive(:run).with(connection).and_return(response)
27
+ end
28
+
29
+ it { should be(response) }
30
+
31
+ it 'should log requests' do
32
+ subject
33
+ logger.messages.should eql(%w(the-logged-string 200))
34
+ end
35
+
36
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Document, '#connection' do
4
+ subject { object.connection }
5
+
6
+ let(:object) { described_class.new(type, id) }
7
+ let(:type) { mock('Type', :connection => connection) }
8
+ let(:connection) { mock('Connection') }
9
+ let(:id) { '1' }
10
+
11
+ it { should be(connection) }
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Document, '#delete' do
4
+ subject { object.delete}
5
+
6
+ let(:object) { described_class.new(type, id) }
7
+ let(:type) { mock('Type') }
8
+ let(:id) { '1' }
9
+ let(:expected_arguments) { [] }
10
+
11
+ expect_to_run_command(Esearch::Command::Document::Delete)
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Document, '#get' do
4
+ subject { object.get}
5
+
6
+ let(:object) { described_class.new(type, id) }
7
+ let(:type) { mock('Type') }
8
+ let(:id) { '1' }
9
+ let(:expected_arguments) { [] }
10
+
11
+ expect_to_run_command(Esearch::Command::Document::Get)
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Index, '#create' do
4
+ subject { object.create(settings) }
5
+
6
+ let(:object) { described_class.new(connection, index_name) }
7
+ let(:index_name) { 'foo' }
8
+ let(:settings) { { :my => :settings } }
9
+ let(:expected_arguments) { [settings] }
10
+
11
+ expect_to_run_command(Esearch::Command::Index::Create)
12
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Index, '#delete' do
4
+ subject { object.delete }
5
+
6
+ let(:object) { described_class.new(connection, index_name) }
7
+ let(:index_name) { 'foo' }
8
+ let(:expected_arguments) { [] }
9
+
10
+ expect_to_run_command(Esearch::Command::Index::Delete)
11
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Index, '#type' do
4
+ subject { object.type(name) }
5
+
6
+ let(:object) { described_class.new(connection, index_name) }
7
+ let(:connection) { mock('Connection') }
8
+ let(:index_name) { 'foo' }
9
+ let(:name) { 'bar' }
10
+
11
+ it { should eql(Esearch::Type.new(object, name)) }
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Indices::All, '#path' do
4
+ subject { object.path }
5
+
6
+ let(:object) { described_class.new(connection) }
7
+ let(:connection) { mock('Connection') }
8
+
9
+ it { should eql(Pathname.new('/_all')) }
10
+
11
+ it_should_behave_like 'an idempotent method'
12
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Esearch::Mixin::Document, '#index_create' 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_create(document) }
15
+ let(:document) { mock('Document') }
16
+
17
+ let(:expected_arguments) { [document, {}] }
18
+
19
+ expect_to_run_command(Esearch::Command::Document::Index::Create)
20
+ end
21
+
22
+ context 'with two args' do
23
+ subject { object.index_create(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::Create)
30
+ end
31
+ end