elasticsearch-model 6.0.0 → 6.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.
- checksums.yaml +4 -4
- data/Gemfile +5 -0
- data/README.md +14 -7
- data/Rakefile +27 -36
- data/elasticsearch-model.gemspec +1 -1
- data/examples/activerecord_mapping_completion.rb +2 -15
- data/gemfiles/3.0.gemfile +6 -1
- data/gemfiles/4.0.gemfile +7 -1
- data/gemfiles/5.0.gemfile +6 -0
- data/lib/elasticsearch/model.rb +15 -8
- data/lib/elasticsearch/model/adapters/active_record.rb +7 -26
- data/lib/elasticsearch/model/indexing.rb +5 -3
- data/lib/elasticsearch/model/naming.rb +6 -1
- data/lib/elasticsearch/model/response.rb +2 -2
- data/lib/elasticsearch/model/response/pagination.rb +2 -192
- data/lib/elasticsearch/model/response/pagination/kaminari.rb +109 -0
- data/lib/elasticsearch/model/response/pagination/will_paginate.rb +95 -0
- data/lib/elasticsearch/model/response/result.rb +1 -1
- data/lib/elasticsearch/model/version.rb +1 -1
- data/spec/elasticsearch/model/adapter_spec.rb +119 -0
- data/spec/elasticsearch/model/adapters/active_record/associations_spec.rb +334 -0
- data/spec/elasticsearch/model/adapters/active_record/basic_spec.rb +340 -0
- data/spec/elasticsearch/model/adapters/active_record/dynamic_index_name_spec.rb +18 -0
- data/spec/elasticsearch/model/adapters/active_record/import_spec.rb +187 -0
- data/spec/elasticsearch/model/adapters/active_record/multi_model_spec.rb +110 -0
- data/spec/elasticsearch/model/adapters/active_record/namespaced_model_spec.rb +38 -0
- data/spec/elasticsearch/model/adapters/active_record/pagination_spec.rb +315 -0
- data/spec/elasticsearch/model/adapters/active_record/parent_child_spec.rb +75 -0
- data/spec/elasticsearch/model/adapters/active_record/serialization_spec.rb +61 -0
- data/spec/elasticsearch/model/adapters/active_record_spec.rb +207 -0
- data/spec/elasticsearch/model/adapters/default_spec.rb +41 -0
- data/spec/elasticsearch/model/adapters/mongoid/basic_spec.rb +267 -0
- data/spec/elasticsearch/model/adapters/mongoid/multi_model_spec.rb +66 -0
- data/spec/elasticsearch/model/adapters/mongoid_spec.rb +235 -0
- data/spec/elasticsearch/model/adapters/multiple_spec.rb +125 -0
- data/spec/elasticsearch/model/callbacks_spec.rb +33 -0
- data/spec/elasticsearch/model/client_spec.rb +66 -0
- data/spec/elasticsearch/model/hash_wrapper_spec.rb +12 -0
- data/spec/elasticsearch/model/importing_spec.rb +214 -0
- data/spec/elasticsearch/model/indexing_spec.rb +918 -0
- data/spec/elasticsearch/model/module_spec.rb +101 -0
- data/spec/elasticsearch/model/multimodel_spec.rb +55 -0
- data/spec/elasticsearch/model/naming_inheritance_spec.rb +184 -0
- data/spec/elasticsearch/model/naming_spec.rb +186 -0
- data/spec/elasticsearch/model/proxy_spec.rb +107 -0
- data/spec/elasticsearch/model/response/aggregations_spec.rb +66 -0
- data/spec/elasticsearch/model/response/base_spec.rb +90 -0
- data/spec/elasticsearch/model/response/pagination/kaminari_spec.rb +410 -0
- data/spec/elasticsearch/model/response/pagination/will_paginate_spec.rb +262 -0
- data/spec/elasticsearch/model/response/records_spec.rb +118 -0
- data/spec/elasticsearch/model/response/response_spec.rb +131 -0
- data/spec/elasticsearch/model/response/result_spec.rb +122 -0
- data/spec/elasticsearch/model/response/results_spec.rb +56 -0
- data/spec/elasticsearch/model/searching_search_request_spec.rb +112 -0
- data/spec/elasticsearch/model/searching_spec.rb +49 -0
- data/spec/elasticsearch/model/serializing_spec.rb +22 -0
- data/spec/spec_helper.rb +161 -0
- data/spec/support/app.rb +21 -0
- data/spec/support/app/answer.rb +33 -0
- data/spec/support/app/article.rb +22 -0
- data/spec/support/app/article_for_pagination.rb +12 -0
- data/spec/support/app/article_with_custom_serialization.rb +13 -0
- data/spec/support/app/article_with_dynamic_index_name.rb +15 -0
- data/spec/support/app/author.rb +9 -0
- data/spec/support/app/authorship.rb +4 -0
- data/spec/support/app/category.rb +3 -0
- data/spec/support/app/comment.rb +3 -0
- data/spec/support/app/episode.rb +11 -0
- data/spec/support/app/image.rb +19 -0
- data/spec/support/app/import_article.rb +12 -0
- data/spec/support/app/mongoid_article.rb +21 -0
- data/spec/support/app/namespaced_book.rb +10 -0
- data/spec/support/app/parent_and_child_searchable.rb +24 -0
- data/spec/support/app/post.rb +14 -0
- data/spec/support/app/question.rb +27 -0
- data/spec/support/app/searchable.rb +48 -0
- data/spec/support/app/series.rb +11 -0
- data/spec/support/model.json +1 -0
- data/{test → spec}/support/model.yml +0 -0
- metadata +129 -86
- data/test/integration/active_record_associations_parent_child_test.rb +0 -188
- data/test/integration/active_record_associations_test.rb +0 -339
- data/test/integration/active_record_basic_test.rb +0 -255
- data/test/integration/active_record_custom_serialization_test.rb +0 -67
- data/test/integration/active_record_import_test.rb +0 -168
- data/test/integration/active_record_namespaced_model_test.rb +0 -56
- data/test/integration/active_record_pagination_test.rb +0 -149
- data/test/integration/dynamic_index_name_test.rb +0 -52
- data/test/integration/mongoid_basic_test.rb +0 -240
- data/test/integration/multiple_models_test.rb +0 -176
- data/test/support/model.json +0 -1
- data/test/test_helper.rb +0 -92
- data/test/unit/adapter_active_record_test.rb +0 -157
- data/test/unit/adapter_default_test.rb +0 -41
- data/test/unit/adapter_mongoid_test.rb +0 -161
- data/test/unit/adapter_multiple_test.rb +0 -106
- data/test/unit/adapter_test.rb +0 -69
- data/test/unit/callbacks_test.rb +0 -31
- data/test/unit/client_test.rb +0 -27
- data/test/unit/hash_wrapper_test.rb +0 -13
- data/test/unit/importing_test.rb +0 -224
- data/test/unit/indexing_test.rb +0 -720
- data/test/unit/module_test.rb +0 -68
- data/test/unit/multimodel_test.rb +0 -38
- data/test/unit/naming_inheritance_test.rb +0 -94
- data/test/unit/naming_test.rb +0 -103
- data/test/unit/proxy_test.rb +0 -98
- data/test/unit/response_aggregations_test.rb +0 -46
- data/test/unit/response_base_test.rb +0 -40
- data/test/unit/response_pagination_kaminari_test.rb +0 -433
- data/test/unit/response_pagination_will_paginate_test.rb +0 -398
- data/test/unit/response_records_test.rb +0 -91
- data/test/unit/response_result_test.rb +0 -90
- data/test/unit/response_results_test.rb +0 -34
- data/test/unit/response_test.rb +0 -104
- data/test/unit/searching_search_request_test.rb +0 -78
- data/test/unit/searching_test.rb +0 -41
- data/test/unit/serializing_test.rb +0 -17
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_support/json/encoding'
|
3
|
+
|
4
|
+
describe Elasticsearch::Model::Response::Result do
|
5
|
+
|
6
|
+
let(:result) do
|
7
|
+
described_class.new(foo: 'bar', bar: { bam: 'baz' })
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'provides access to the properties' do
|
11
|
+
expect(result.foo).to eq('bar')
|
12
|
+
expect(result.bar.bam).to eq('baz')
|
13
|
+
expect { result.xoxo }.to raise_exception(NoMethodError)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#id' do
|
17
|
+
|
18
|
+
let(:result) do
|
19
|
+
described_class.new(foo: 'bar', _id: 42, _source: { id: 12 })
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns the _id field' do
|
23
|
+
expect(result.id).to eq(42)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'provides access to the source id field' do
|
27
|
+
expect(result._source.id).to eq(12)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#type' do
|
32
|
+
|
33
|
+
let(:result) do
|
34
|
+
described_class.new(foo: 'bar', _type: 'baz', _source: { type: 'BAM' })
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'returns the _type field' do
|
38
|
+
expect(result.type).to eq('baz')
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'provides access to the source type field' do
|
42
|
+
expect(result._source.type).to eq('BAM')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'method delegation' do
|
47
|
+
|
48
|
+
let(:result) do
|
49
|
+
described_class.new(foo: 'bar', _source: { bar: { bam: 'baz' } })
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'provides access to the _source field via a method' do
|
53
|
+
expect(result._source).to eq('bar' => { 'bam' => 'baz' })
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'is recognized by #method' do
|
57
|
+
expect(result.method :bar).to be_a Method
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'respond_to? still works' do
|
61
|
+
expect(result.respond_to? :bar).to be true
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when methods map to keys in subdocuments of the response from Elasticsearch' do
|
65
|
+
|
66
|
+
it 'provides access to top level fields via a method' do
|
67
|
+
expect(result.foo).to eq('bar')
|
68
|
+
expect(result.fetch(:foo)).to eq('bar')
|
69
|
+
expect(result.fetch(:does_not_exist, 'moo')).to eq('moo')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'responds to hash methods' do
|
73
|
+
expect(result.keys).to eq(['foo', '_source'])
|
74
|
+
expect(result.to_hash).to eq('foo' => 'bar', '_source' => { 'bar' => { 'bam' => 'baz' } })
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'provides access to fields in the _source subdocument via a method' do
|
78
|
+
expect(result.bar).to eq('bam' => 'baz')
|
79
|
+
expect(result.bar.bam).to eq('baz')
|
80
|
+
expect(result._source.bar).to eq('bam' => 'baz')
|
81
|
+
expect(result._source.bar.bam).to eq('baz')
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'when boolean methods are called' do
|
85
|
+
|
86
|
+
it 'provides access to top level fields via a method' do
|
87
|
+
expect(result.foo?).to eq(true)
|
88
|
+
expect(result.boo?).to eq(false)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'delegates to fields in the _source subdocument via a method' do
|
92
|
+
expect(result.bar?).to eq(true)
|
93
|
+
expect(result.bar.bam?).to eq(true)
|
94
|
+
expect(result.boo?).to eq(false)
|
95
|
+
expect(result.bar.boo?).to eq(false)
|
96
|
+
expect(result._source.bar?).to eq(true)
|
97
|
+
expect(result._source.bar.bam?).to eq(true)
|
98
|
+
expect(result._source.boo?).to eq(false)
|
99
|
+
expect(result._source.bar.boo?).to eq(false)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when methods do not map to keys in subdocuments of the response from Elasticsearch' do
|
105
|
+
|
106
|
+
it 'raises a NoMethodError' do
|
107
|
+
expect { result.does_not_exist }.to raise_exception(NoMethodError)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#as_json' do
|
113
|
+
|
114
|
+
let(:result) do
|
115
|
+
described_class.new(foo: 'bar', _source: { bar: { bam: 'baz' } })
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'returns a json string' do
|
119
|
+
expect(result.as_json(except: 'foo')).to eq({'_source'=>{'bar'=>{'bam'=>'baz'}}})
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Elasticsearch::Model::Response::Results do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
class OriginClass
|
7
|
+
def self.index_name; 'foo'; end
|
8
|
+
def self.document_type; 'bar'; end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:all) do
|
13
|
+
remove_classes(OriginClass)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:response_document) do
|
17
|
+
{ 'hits' => { 'total' => 123, 'max_score' => 456, 'hits' => [{'foo' => 'bar'}] } }
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:search) do
|
21
|
+
Elasticsearch::Model::Searching::SearchRequest.new(OriginClass, '*').tap do |request|
|
22
|
+
allow(request).to receive(:execute!).and_return(response_document)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:response) do
|
27
|
+
Elasticsearch::Model::Response::Response.new(OriginClass, search)
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:results) do
|
31
|
+
response.results
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#results' do
|
35
|
+
|
36
|
+
it 'provides access to the results' do
|
37
|
+
expect(results.results.size).to be(1)
|
38
|
+
expect(results.results.first.foo).to eq('bar')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'Enumerable' do
|
43
|
+
|
44
|
+
it 'deletebates enumerable methods to the results' do
|
45
|
+
expect(results.empty?).to be(false)
|
46
|
+
expect(results.first.foo).to eq('bar')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#raw_response' do
|
51
|
+
|
52
|
+
it 'returns the raw response document' do
|
53
|
+
expect(response.raw_response).to eq(response_document)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Elasticsearch::Model::Serializing do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
class ::DummySearchingModel
|
7
|
+
extend Elasticsearch::Model::Searching::ClassMethods
|
8
|
+
def self.index_name; 'foo'; end
|
9
|
+
def self.document_type; 'bar'; end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:all) do
|
14
|
+
remove_classes(DummySearchingModel)
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
allow(DummySearchingModel).to receive(:client).and_return(client)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:client) do
|
22
|
+
double('client')
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#initialize' do
|
26
|
+
|
27
|
+
context 'when the search definition is a simple query' do
|
28
|
+
|
29
|
+
before do
|
30
|
+
expect(client).to receive(:search).with(index: 'foo', type: 'bar', q: 'foo').and_return({})
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:search) do
|
34
|
+
Elasticsearch::Model::Searching::SearchRequest.new(DummySearchingModel, 'foo')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'passes the query to the client' do
|
38
|
+
expect(search.execute!).to eq({})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when the search definition is a hash' do
|
43
|
+
|
44
|
+
before do
|
45
|
+
expect(client).to receive(:search).with(index: 'foo', type: 'bar', body: { foo: 'bar' }).and_return({})
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:search) do
|
49
|
+
Elasticsearch::Model::Searching::SearchRequest.new(DummySearchingModel, foo: 'bar')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'passes the hash to the client' do
|
53
|
+
expect(search.execute!).to eq({})
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when the search definition is a json string' do
|
58
|
+
|
59
|
+
before do
|
60
|
+
expect(client).to receive(:search).with(index: 'foo', type: 'bar', body: '{"foo":"bar"}').and_return({})
|
61
|
+
end
|
62
|
+
|
63
|
+
let(:search) do
|
64
|
+
Elasticsearch::Model::Searching::SearchRequest.new(DummySearchingModel, '{"foo":"bar"}')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'passes the json string to the client' do
|
68
|
+
expect(search.execute!).to eq({})
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when the search definition is a custom object' do
|
73
|
+
|
74
|
+
before(:all) do
|
75
|
+
class MySpecialQueryBuilder
|
76
|
+
def to_hash; {foo: 'bar'}; end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
after(:all) do
|
81
|
+
Object.send(:remove_const, :MySpecialQueryBuilder) if defined?(MySpecialQueryBuilder)
|
82
|
+
end
|
83
|
+
|
84
|
+
before do
|
85
|
+
expect(client).to receive(:search).with(index: 'foo', type: 'bar', body: {foo: 'bar'}).and_return({})
|
86
|
+
end
|
87
|
+
|
88
|
+
let(:search) do
|
89
|
+
Elasticsearch::Model::Searching::SearchRequest.new(DummySearchingModel, MySpecialQueryBuilder.new)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'passes the query builder to the client and calls #to_hash on it' do
|
93
|
+
expect(search.execute!).to eq({})
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when extra options are specified' do
|
98
|
+
|
99
|
+
before do
|
100
|
+
expect(client).to receive(:search).with(index: 'foo', type: 'bar', q: 'foo', size: 15).and_return({})
|
101
|
+
end
|
102
|
+
|
103
|
+
let(:search) do
|
104
|
+
Elasticsearch::Model::Searching::SearchRequest.new(DummySearchingModel, 'foo', size: 15)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'passes the extra options to the client as part of the request' do
|
108
|
+
expect(search.execute!).to eq({})
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Elasticsearch::Model::Searching::ClassMethods do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
class ::DummySearchingModel
|
7
|
+
extend Elasticsearch::Model::Searching::ClassMethods
|
8
|
+
|
9
|
+
def self.index_name; 'foo'; end
|
10
|
+
def self.document_type; 'bar'; end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:all) do
|
15
|
+
remove_classes(DummySearchingModel)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'has the search method' do
|
19
|
+
expect(DummySearchingModel).to respond_to(:search)
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#search' do
|
23
|
+
|
24
|
+
let(:response) do
|
25
|
+
double('search', execute!: { 'hits' => {'hits' => [ {'_id' => 2 }, {'_id' => 1 } ]} })
|
26
|
+
end
|
27
|
+
|
28
|
+
before do
|
29
|
+
expect(Elasticsearch::Model::Searching::SearchRequest).to receive(:new).with(DummySearchingModel, 'foo', { default_operator: 'AND' }).and_return(response)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'creates a search object' do
|
33
|
+
expect(DummySearchingModel.search('foo', default_operator: 'AND')).to be_a(Elasticsearch::Model::Response::Response)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'lazy execution' do
|
38
|
+
|
39
|
+
let(:response) do
|
40
|
+
double('search').tap do |r|
|
41
|
+
expect(r).to receive(:execute!).never
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'does not execute the search until the results are accessed' do
|
46
|
+
DummySearchingModel.search('foo')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Elasticsearch::Model::Serializing do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
class DummyClass
|
7
|
+
include Elasticsearch::Model::Serializing::InstanceMethods
|
8
|
+
|
9
|
+
def as_json(options={})
|
10
|
+
'HASH'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:all) do
|
16
|
+
remove_classes(DummyClass)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'delegates to #as_json by default' do
|
20
|
+
expect(DummyClass.new.as_indexed_json).to eq('HASH')
|
21
|
+
end
|
22
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'pry-nav'
|
2
|
+
require 'kaminari'
|
3
|
+
require 'kaminari/version'
|
4
|
+
require 'will_paginate'
|
5
|
+
require 'will_paginate/collection'
|
6
|
+
require 'elasticsearch/model'
|
7
|
+
require 'hashie/version'
|
8
|
+
require 'active_model'
|
9
|
+
require 'mongoid'
|
10
|
+
require 'yaml'
|
11
|
+
require 'active_record'
|
12
|
+
|
13
|
+
unless defined?(ELASTICSEARCH_URL)
|
14
|
+
ELASTICSEARCH_URL = ENV['ELASTICSEARCH_URL'] || "localhost:#{(ENV['TEST_CLUSTER_PORT'] || 9200)}"
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.formatter = 'documentation'
|
19
|
+
config.color = true
|
20
|
+
|
21
|
+
config.before(:suite) do
|
22
|
+
require 'ansi'
|
23
|
+
tracer = ::Logger.new(STDERR)
|
24
|
+
tracer.formatter = lambda { |s, d, p, m| "#{m.gsub(/^.*$/) { |n| ' ' + n }.ansi(:faint)}\n" }
|
25
|
+
Elasticsearch::Model.client = Elasticsearch::Client.new host: ELASTICSEARCH_URL,
|
26
|
+
tracer: (ENV['QUIET'] ? nil : tracer)
|
27
|
+
|
28
|
+
unless ActiveRecord::Base.connected?
|
29
|
+
ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => ":memory:" )
|
30
|
+
end
|
31
|
+
require 'support/app'
|
32
|
+
|
33
|
+
if ::ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks) && ::ActiveRecord::VERSION::MAJOR.to_s < '5'
|
34
|
+
::ActiveRecord::Base.raise_in_transactional_callbacks = true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
config.after(:all) do
|
39
|
+
drop_all_tables!
|
40
|
+
delete_all_indices!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Is the ActiveRecord version at least 4.0?
|
45
|
+
#
|
46
|
+
# @return [ true, false ] Whether the ActiveRecord version is at least 4.0.
|
47
|
+
#
|
48
|
+
# @since 6.0.1
|
49
|
+
def active_record_at_least_4?
|
50
|
+
defined?(::ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 4
|
51
|
+
end
|
52
|
+
|
53
|
+
# Delete all documents from the indices of the provided list of models.
|
54
|
+
#
|
55
|
+
# @param [ Array<ActiveRecord::Base> ] models The list of models.
|
56
|
+
#
|
57
|
+
# @return [ true ]
|
58
|
+
#
|
59
|
+
# @since 6.0.1
|
60
|
+
def clear_indices(*models)
|
61
|
+
models.each do |model|
|
62
|
+
begin; Elasticsearch::Model.client.delete_by_query(index: model.index_name, q: '*'); rescue; end
|
63
|
+
end and true
|
64
|
+
end
|
65
|
+
|
66
|
+
# Delete all documents from the tables of the provided list of models.
|
67
|
+
#
|
68
|
+
# @param [ Array<ActiveRecord::Base> ] models The list of models.
|
69
|
+
#
|
70
|
+
# @return [ true ]
|
71
|
+
#
|
72
|
+
# @since 6.0.1
|
73
|
+
def clear_tables(*models)
|
74
|
+
begin; models.map(&:delete_all); rescue; end and true
|
75
|
+
end
|
76
|
+
|
77
|
+
# Drop all tables of models registered as subclasses of ActiveRecord::Base.
|
78
|
+
#
|
79
|
+
# @return [ true ]
|
80
|
+
#
|
81
|
+
# @since 6.0.1
|
82
|
+
def drop_all_tables!
|
83
|
+
ActiveRecord::Base.descendants.each do |model|
|
84
|
+
begin
|
85
|
+
ActiveRecord::Schema.define do
|
86
|
+
drop_table model
|
87
|
+
end if model.table_exists?
|
88
|
+
rescue
|
89
|
+
end
|
90
|
+
end and true
|
91
|
+
end
|
92
|
+
|
93
|
+
# Drop all indices of models registered as subclasses of ActiveRecord::Base.
|
94
|
+
#
|
95
|
+
# @return [ true ]
|
96
|
+
#
|
97
|
+
# @since 6.0.1
|
98
|
+
def delete_all_indices!
|
99
|
+
client = Elasticsearch::Model.client
|
100
|
+
ActiveRecord::Base.descendants.each do |model|
|
101
|
+
begin
|
102
|
+
client.indices.delete(index: model.index_name) if model.__elasticsearch__.index_exists?
|
103
|
+
rescue
|
104
|
+
end
|
105
|
+
end and true
|
106
|
+
end
|
107
|
+
|
108
|
+
# Remove all classes.
|
109
|
+
#
|
110
|
+
# @param [ Array<Class> ] classes The list of classes to remove.
|
111
|
+
#
|
112
|
+
# @return [ true ]
|
113
|
+
#
|
114
|
+
# @since 6.0.1
|
115
|
+
def remove_classes(*classes)
|
116
|
+
classes.each do |_class|
|
117
|
+
Object.send(:remove_const, _class.name.to_sym) if defined?(_class)
|
118
|
+
end and true
|
119
|
+
end
|
120
|
+
|
121
|
+
# Determine whether the tests with Mongoid should be run.
|
122
|
+
# Depends on whether MongoDB is running on the default host and port, `localhost:27017`.
|
123
|
+
#
|
124
|
+
# @return [ true, false ]
|
125
|
+
#
|
126
|
+
# @since 6.0.1
|
127
|
+
def test_mongoid?
|
128
|
+
$mongoid_available ||= begin
|
129
|
+
require 'mongoid'
|
130
|
+
if defined?(Mongo) # older versions of Mongoid use the driver, Moped
|
131
|
+
client = Mongo::Client.new(['localhost:27017'])
|
132
|
+
Timeout.timeout(1) do
|
133
|
+
client.database.command(ping: 1) && true
|
134
|
+
end
|
135
|
+
end and true
|
136
|
+
rescue Timeout::Error, LoadError, Mongo::Error => e
|
137
|
+
client.close
|
138
|
+
$stderr.puts("MongoDB not installed or running: #{e}")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Connect Mongoid and set up its Logger if Mongoid tests should be run.
|
143
|
+
#
|
144
|
+
# @since 6.0.1
|
145
|
+
def connect_mongoid(source)
|
146
|
+
if test_mongoid?
|
147
|
+
$stderr.puts "Mongoid #{Mongoid::VERSION}", '-'*80
|
148
|
+
|
149
|
+
if !ENV['QUIET'] == 'true'
|
150
|
+
logger = ::Logger.new($stderr)
|
151
|
+
logger.formatter = lambda { |s, d, p, m| " #{m.ansi(:faint, :cyan)}\n" }
|
152
|
+
logger.level = ::Logger::DEBUG
|
153
|
+
Mongoid.logger = logger
|
154
|
+
Mongo::Logger.logger = logger
|
155
|
+
else
|
156
|
+
Mongo::Logger.logger.level = ::Logger::WARN
|
157
|
+
end
|
158
|
+
|
159
|
+
Mongoid.connect_to(source)
|
160
|
+
end
|
161
|
+
end
|