elasticsearch-model-queryable 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG.md +26 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +13 -0
  6. data/README.md +695 -0
  7. data/Rakefile +59 -0
  8. data/elasticsearch-model.gemspec +57 -0
  9. data/examples/activerecord_article.rb +77 -0
  10. data/examples/activerecord_associations.rb +162 -0
  11. data/examples/couchbase_article.rb +66 -0
  12. data/examples/datamapper_article.rb +71 -0
  13. data/examples/mongoid_article.rb +68 -0
  14. data/examples/ohm_article.rb +70 -0
  15. data/examples/riak_article.rb +52 -0
  16. data/gemfiles/3.0.gemfile +12 -0
  17. data/gemfiles/4.0.gemfile +11 -0
  18. data/lib/elasticsearch/model/adapter.rb +145 -0
  19. data/lib/elasticsearch/model/adapters/active_record.rb +104 -0
  20. data/lib/elasticsearch/model/adapters/default.rb +50 -0
  21. data/lib/elasticsearch/model/adapters/mongoid.rb +92 -0
  22. data/lib/elasticsearch/model/callbacks.rb +35 -0
  23. data/lib/elasticsearch/model/client.rb +61 -0
  24. data/lib/elasticsearch/model/ext/active_record.rb +14 -0
  25. data/lib/elasticsearch/model/hash_wrapper.rb +15 -0
  26. data/lib/elasticsearch/model/importing.rb +144 -0
  27. data/lib/elasticsearch/model/indexing.rb +472 -0
  28. data/lib/elasticsearch/model/naming.rb +101 -0
  29. data/lib/elasticsearch/model/proxy.rb +127 -0
  30. data/lib/elasticsearch/model/response/base.rb +44 -0
  31. data/lib/elasticsearch/model/response/pagination.rb +173 -0
  32. data/lib/elasticsearch/model/response/records.rb +69 -0
  33. data/lib/elasticsearch/model/response/result.rb +63 -0
  34. data/lib/elasticsearch/model/response/results.rb +31 -0
  35. data/lib/elasticsearch/model/response.rb +71 -0
  36. data/lib/elasticsearch/model/searching.rb +107 -0
  37. data/lib/elasticsearch/model/serializing.rb +35 -0
  38. data/lib/elasticsearch/model/version.rb +5 -0
  39. data/lib/elasticsearch/model.rb +157 -0
  40. data/test/integration/active_record_associations_parent_child.rb +139 -0
  41. data/test/integration/active_record_associations_test.rb +307 -0
  42. data/test/integration/active_record_basic_test.rb +179 -0
  43. data/test/integration/active_record_custom_serialization_test.rb +62 -0
  44. data/test/integration/active_record_import_test.rb +100 -0
  45. data/test/integration/active_record_namespaced_model_test.rb +49 -0
  46. data/test/integration/active_record_pagination_test.rb +132 -0
  47. data/test/integration/mongoid_basic_test.rb +193 -0
  48. data/test/test_helper.rb +63 -0
  49. data/test/unit/adapter_active_record_test.rb +140 -0
  50. data/test/unit/adapter_default_test.rb +41 -0
  51. data/test/unit/adapter_mongoid_test.rb +102 -0
  52. data/test/unit/adapter_test.rb +69 -0
  53. data/test/unit/callbacks_test.rb +31 -0
  54. data/test/unit/client_test.rb +27 -0
  55. data/test/unit/importing_test.rb +176 -0
  56. data/test/unit/indexing_test.rb +478 -0
  57. data/test/unit/module_test.rb +57 -0
  58. data/test/unit/naming_test.rb +76 -0
  59. data/test/unit/proxy_test.rb +89 -0
  60. data/test/unit/response_base_test.rb +40 -0
  61. data/test/unit/response_pagination_kaminari_test.rb +189 -0
  62. data/test/unit/response_pagination_will_paginate_test.rb +208 -0
  63. data/test/unit/response_records_test.rb +91 -0
  64. data/test/unit/response_result_test.rb +90 -0
  65. data/test/unit/response_results_test.rb +31 -0
  66. data/test/unit/response_test.rb +67 -0
  67. data/test/unit/searching_search_request_test.rb +78 -0
  68. data/test/unit/searching_test.rb +41 -0
  69. data/test/unit/serializing_test.rb +17 -0
  70. metadata +466 -0
@@ -0,0 +1,193 @@
1
+ require 'test_helper'
2
+
3
+ begin
4
+ require 'mongoid'
5
+ session = Moped::Connection.new("localhost", 27017, 0.5)
6
+ session.connect
7
+ ENV["MONGODB_AVAILABLE"] = 'yes'
8
+ rescue LoadError, Moped::Errors::ConnectionFailure => e
9
+ $stderr.puts "MongoDB not installed or running: #{e}"
10
+ end
11
+
12
+ if ENV["MONGODB_AVAILABLE"]
13
+ $stderr.puts "Mongoid #{Mongoid::VERSION}", '-'*80
14
+
15
+ logger = ::Logger.new($stderr)
16
+ logger.formatter = lambda { |s, d, p, m| " #{m.ansi(:faint, :cyan)}\n" }
17
+ logger.level = ::Logger::DEBUG
18
+
19
+ Mongoid.logger = logger unless ENV['QUIET']
20
+ Moped.logger = logger unless ENV['QUIET']
21
+
22
+ Mongoid.connect_to 'mongoid_articles'
23
+
24
+ module Elasticsearch
25
+ module Model
26
+ class MongoidBasicIntegrationTest < Elasticsearch::Test::IntegrationTestCase
27
+
28
+ class ::MongoidArticle
29
+ include Mongoid::Document
30
+ include Elasticsearch::Model
31
+ include Elasticsearch::Model::Callbacks
32
+
33
+ field :id, type: String
34
+ field :title, type: String
35
+ attr_accessible :title if respond_to? :attr_accessible
36
+
37
+ settings index: { number_of_shards: 1, number_of_replicas: 0 } do
38
+ mapping do
39
+ indexes :title, type: 'string', analyzer: 'snowball'
40
+ indexes :created_at, type: 'date'
41
+ end
42
+ end
43
+
44
+ def as_indexed_json(options={})
45
+ as_json(except: [:id, :_id])
46
+ end
47
+ end
48
+
49
+ context "Mongoid integration" do
50
+ setup do
51
+ Elasticsearch::Model::Adapter.register \
52
+ Elasticsearch::Model::Adapter::Mongoid,
53
+ lambda { |klass| !!defined?(::Mongoid::Document) && klass.ancestors.include?(::Mongoid::Document) }
54
+
55
+ MongoidArticle.__elasticsearch__.create_index! force: true
56
+
57
+ MongoidArticle.delete_all
58
+
59
+ MongoidArticle.create! title: 'Test'
60
+ MongoidArticle.create! title: 'Testing Coding'
61
+ MongoidArticle.create! title: 'Coding'
62
+
63
+ MongoidArticle.__elasticsearch__.refresh_index!
64
+ MongoidArticle.__elasticsearch__.client.cluster.health wait_for_status: 'yellow'
65
+ end
66
+
67
+ should "index and find a document" do
68
+ response = MongoidArticle.search('title:test')
69
+
70
+ assert response.any?
71
+
72
+ assert_equal 2, response.results.size
73
+ assert_equal 2, response.records.size
74
+
75
+ assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
76
+ assert_instance_of MongoidArticle, response.records.first
77
+
78
+ assert_equal 'Test', response.results.first.title
79
+ assert_equal 'Test', response.records.first.title
80
+ end
81
+
82
+ should "iterate over results" do
83
+ response = MongoidArticle.search('title:test')
84
+
85
+ assert_equal ['Test', 'Testing Coding'], response.results.map(&:title)
86
+ assert_equal ['Test', 'Testing Coding'], response.records.map(&:title)
87
+ end
88
+
89
+ should "access results from records" do
90
+ response = MongoidArticle.search('title:test')
91
+
92
+ response.records.each_with_hit do |r, h|
93
+ assert_not_nil h._score
94
+ assert_not_nil h._source.title
95
+ end
96
+ end
97
+
98
+ should "preserve the search results order for records" do
99
+ response = MongoidArticle.search('title:code')
100
+
101
+ response.records.each_with_hit do |r, h|
102
+ assert_equal h._id, r.id.to_s
103
+ end
104
+
105
+ response.records.map_with_hit do |r, h|
106
+ assert_equal h._id, r.id.to_s
107
+ end
108
+ end
109
+
110
+ should "remove document from index on destroy" do
111
+ article = MongoidArticle.first
112
+
113
+ article.destroy
114
+ assert_equal 2, MongoidArticle.count
115
+
116
+ MongoidArticle.__elasticsearch__.refresh_index!
117
+
118
+ response = MongoidArticle.search 'title:test'
119
+
120
+ assert_equal 1, response.results.size
121
+ assert_equal 1, response.records.size
122
+ end
123
+
124
+ should "index updates to the document" do
125
+ article = MongoidArticle.first
126
+
127
+ article.title = 'Writing'
128
+ article.save
129
+
130
+ MongoidArticle.__elasticsearch__.refresh_index!
131
+
132
+ response = MongoidArticle.search 'title:write'
133
+
134
+ assert_equal 1, response.results.size
135
+ assert_equal 1, response.records.size
136
+ end
137
+
138
+ should "return results for a DSL search" do
139
+ response = MongoidArticle.search query: { match: { title: { query: 'test' } } }
140
+
141
+ assert_equal 2, response.results.size
142
+ assert_equal 2, response.records.size
143
+ end
144
+
145
+ should "return a paged collection" do
146
+ response = MongoidArticle.search query: { match: { title: { query: 'test' } } },
147
+ size: 2,
148
+ from: 1
149
+
150
+ assert_equal 1, response.results.size
151
+ assert_equal 1, response.records.size
152
+
153
+ assert_equal 'Testing Coding', response.results.first.title
154
+ assert_equal 'Testing Coding', response.records.first.title
155
+ end
156
+
157
+
158
+ context "importing" do
159
+ setup do
160
+ MongoidArticle.delete_all
161
+ 97.times { |i| MongoidArticle.create! title: "Test #{i}" }
162
+ MongoidArticle.__elasticsearch__.create_index! force: true
163
+ MongoidArticle.__elasticsearch__.client.cluster.health wait_for_status: 'yellow'
164
+ end
165
+
166
+ should "import all the documents" do
167
+ assert_equal 97, MongoidArticle.count
168
+
169
+ MongoidArticle.__elasticsearch__.refresh_index!
170
+ assert_equal 0, MongoidArticle.search('*').results.total
171
+
172
+ batches = 0
173
+ errors = MongoidArticle.import(batch_size: 10) do |response|
174
+ batches += 1
175
+ end
176
+
177
+ assert_equal 0, errors
178
+ assert_equal 10, batches
179
+
180
+ MongoidArticle.__elasticsearch__.refresh_index!
181
+ assert_equal 97, MongoidArticle.search('*').results.total
182
+
183
+ response = MongoidArticle.search('test')
184
+ assert response.results.any?, "Search has not returned results: #{response.to_a}"
185
+ end
186
+ end
187
+ end
188
+
189
+ end
190
+ end
191
+ end
192
+
193
+ end
@@ -0,0 +1,63 @@
1
+ RUBY_1_8 = defined?(RUBY_VERSION) && RUBY_VERSION < '1.9'
2
+
3
+ exit(0) if RUBY_1_8
4
+
5
+ require 'simplecov' and SimpleCov.start { add_filter "/test|test_/" } if ENV["COVERAGE"]
6
+
7
+ # Register `at_exit` handler for integration tests shutdown.
8
+ # MUST be called before requiring `test/unit`.
9
+ at_exit { Elasticsearch::Test::IntegrationTestCase.__run_at_exit_hooks }
10
+
11
+ puts '-'*80
12
+
13
+ if defined?(RUBY_VERSION) && RUBY_VERSION > '2.2'
14
+ require 'test-unit'
15
+ require 'mocha/test_unit'
16
+ else
17
+ require 'minitest/autorun'
18
+ require 'mocha/mini_test'
19
+ end
20
+
21
+ require 'shoulda-context'
22
+
23
+ require 'turn' unless ENV["TM_FILEPATH"] || ENV["NOTURN"] || defined?(RUBY_VERSION) && RUBY_VERSION > '2.2'
24
+
25
+ require 'ansi'
26
+ require 'oj'
27
+
28
+ require 'active_model'
29
+
30
+ require 'kaminari'
31
+
32
+ require 'elasticsearch/model'
33
+
34
+ require 'elasticsearch/extensions/test/cluster'
35
+ require 'elasticsearch/extensions/test/startup_shutdown'
36
+
37
+ module Elasticsearch
38
+ module Test
39
+ class IntegrationTestCase < ::Test::Unit::TestCase
40
+ extend Elasticsearch::Extensions::Test::StartupShutdown
41
+
42
+ startup { Elasticsearch::Extensions::Test::Cluster.start(nodes: 1) if ENV['SERVER'] and not Elasticsearch::Extensions::Test::Cluster.running? }
43
+ shutdown { Elasticsearch::Extensions::Test::Cluster.stop if ENV['SERVER'] && started? }
44
+ context "IntegrationTest" do; should "noop on Ruby 1.8" do; end; end if RUBY_1_8
45
+
46
+ def setup
47
+ ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => ":memory:" )
48
+ logger = ::Logger.new(STDERR)
49
+ logger.formatter = lambda { |s, d, p, m| "\e[2;36m#{m}\e[0m\n" }
50
+ ActiveRecord::Base.logger = logger unless ENV['QUIET']
51
+
52
+ ActiveRecord::LogSubscriber.colorize_logging = false
53
+ ActiveRecord::Migration.verbose = false
54
+
55
+ tracer = ::Logger.new(STDERR)
56
+ tracer.formatter = lambda { |s, d, p, m| "#{m.gsub(/^.*$/) { |n| ' ' + n }.ansi(:faint)}\n" }
57
+
58
+ Elasticsearch::Model.client = Elasticsearch::Client.new host: "localhost:#{(ENV['TEST_CLUSTER_PORT'] || 9250)}",
59
+ tracer: (ENV['QUIET'] ? nil : tracer)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,140 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::AdapterActiveRecordTest < Test::Unit::TestCase
4
+ context "Adapter ActiveRecord module: " do
5
+ class ::DummyClassForActiveRecord
6
+ RESPONSE = Struct.new('DummyActiveRecordResponse') do
7
+ def response
8
+ { 'hits' => {'hits' => [ {'_id' => 2}, {'_id' => 1} ]} }
9
+ end
10
+ end.new
11
+
12
+ def response
13
+ RESPONSE
14
+ end
15
+
16
+ def ids
17
+ [2, 1]
18
+ end
19
+ end
20
+
21
+ RESPONSE = { 'hits' => { 'total' => 123, 'max_score' => 456, 'hits' => [] } }
22
+
23
+ setup do
24
+ @records = [ stub(id: 1, inspect: '<Model-1>'), stub(id: 2, inspect: '<Model-2>') ]
25
+ @records.stubs(:load).returns(true)
26
+ @records.stubs(:exec_queries).returns(true)
27
+ end
28
+
29
+ should "have the register condition" do
30
+ assert_not_nil Elasticsearch::Model::Adapter.adapters[Elasticsearch::Model::Adapter::ActiveRecord]
31
+ assert_equal false, Elasticsearch::Model::Adapter.adapters[Elasticsearch::Model::Adapter::ActiveRecord].call(DummyClassForActiveRecord)
32
+ end
33
+
34
+ context "Records" do
35
+ setup do
36
+ DummyClassForActiveRecord.__send__ :include, Elasticsearch::Model::Adapter::ActiveRecord::Records
37
+ end
38
+
39
+ should "have the implementation" do
40
+ assert_instance_of Module, Elasticsearch::Model::Adapter::ActiveRecord::Records
41
+
42
+ instance = DummyClassForActiveRecord.new
43
+ instance.expects(:klass).returns(mock('class', primary_key: :some_key, where: @records)).at_least_once
44
+
45
+ assert_equal @records, instance.records
46
+ end
47
+
48
+ should "load the records" do
49
+ instance = DummyClassForActiveRecord.new
50
+ instance.expects(:records).returns(@records)
51
+ instance.load
52
+ end
53
+
54
+ should "reorder the records based on hits order" do
55
+ @records.instance_variable_set(:@records, @records)
56
+
57
+ instance = DummyClassForActiveRecord.new
58
+ instance.expects(:klass).returns(mock('class', primary_key: :some_key, where: @records)).at_least_once
59
+
60
+ assert_equal [1, 2], @records. to_a.map(&:id)
61
+ assert_equal [2, 1], instance.records.to_a.map(&:id)
62
+ end
63
+
64
+ should "not reorder records when SQL order is present" do
65
+ @records.instance_variable_set(:@records, @records)
66
+
67
+ instance = DummyClassForActiveRecord.new
68
+ instance.expects(:klass).returns(stub('class', primary_key: :some_key, where: @records)).at_least_once
69
+ instance.records.expects(:order).returns(@records)
70
+
71
+ assert_equal [2, 1], instance.records. to_a.map(&:id)
72
+ assert_equal [1, 2], instance.order(:foo).to_a.map(&:id)
73
+ end
74
+ end
75
+
76
+ context "Callbacks" do
77
+ should "register hooks for automatically updating the index" do
78
+ DummyClassForActiveRecord.expects(:after_commit).times(3)
79
+
80
+ Elasticsearch::Model::Adapter::ActiveRecord::Callbacks.included(DummyClassForActiveRecord)
81
+ end
82
+ end
83
+
84
+ context "Importing" do
85
+ setup do
86
+ DummyClassForActiveRecord.__send__ :extend, Elasticsearch::Model::Adapter::ActiveRecord::Importing
87
+ end
88
+
89
+ should "raise an exception when passing an invalid scope" do
90
+ assert_raise NoMethodError do
91
+ DummyClassForActiveRecord.__find_in_batches(scope: :not_found_method) do; end
92
+ end
93
+ end
94
+
95
+ should "implement the __find_in_batches method" do
96
+ DummyClassForActiveRecord.expects(:find_in_batches).returns([])
97
+ DummyClassForActiveRecord.__find_in_batches do; end
98
+ end
99
+
100
+ should "limit the relation to a specific scope" do
101
+ DummyClassForActiveRecord.expects(:find_in_batches).returns([])
102
+ DummyClassForActiveRecord.expects(:published).returns(DummyClassForActiveRecord)
103
+
104
+ DummyClassForActiveRecord.__find_in_batches(scope: :published) do; end
105
+ end
106
+
107
+ should "preprocess the batch if option provided" do
108
+ class << DummyClassForActiveRecord
109
+ # Updates/transforms the batch while fetching it from the database
110
+ # (eg. with information from an external system)
111
+ #
112
+ def update_batch(batch)
113
+ batch.collect { |b| b.to_s + '!' }
114
+ end
115
+ end
116
+
117
+ DummyClassForActiveRecord.expects(:__find_in_batches).returns( [:a, :b] )
118
+
119
+ DummyClassForActiveRecord.__find_in_batches(preprocess: :update_batch) do |batch|
120
+ assert_same_elements ["a!", "b!"], batch
121
+ end
122
+ end
123
+
124
+ context "when transforming models" do
125
+ setup do
126
+ @transform = DummyClassForActiveRecord.__transform
127
+ end
128
+
129
+ should "provide an object that responds to #call" do
130
+ assert_respond_to @transform, :call
131
+ end
132
+
133
+ should "provide default transformation" do
134
+ model = mock("model", id: 1, __elasticsearch__: stub(as_indexed_json: {}))
135
+ assert_equal @transform.call(model), { index: { _id: 1, data: {} } }
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::AdapterDefaultTest < Test::Unit::TestCase
4
+ context "Adapter default module" do
5
+ class ::DummyClassForDefaultAdapter; end
6
+
7
+ should "have the default Records implementation" do
8
+ assert_instance_of Module, Elasticsearch::Model::Adapter::Default::Records
9
+
10
+ DummyClassForDefaultAdapter.__send__ :include, Elasticsearch::Model::Adapter::Default::Records
11
+
12
+ instance = DummyClassForDefaultAdapter.new
13
+ klass = mock('class', find: [1])
14
+ instance.expects(:klass).returns(klass)
15
+ instance.records
16
+ end
17
+
18
+ should "have the default Callbacks implementation" do
19
+ assert_instance_of Module, Elasticsearch::Model::Adapter::Default::Callbacks
20
+ end
21
+
22
+ context "concerning abstract methods" do
23
+ setup do
24
+ DummyClassForDefaultAdapter.__send__ :include, Elasticsearch::Model::Adapter::Default::Importing
25
+ end
26
+
27
+ should "have the default Importing implementation" do
28
+ assert_raise Elasticsearch::Model::NotImplemented do
29
+ DummyClassForDefaultAdapter.new.__find_in_batches
30
+ end
31
+ end
32
+
33
+ should "have the default transform implementation" do
34
+ assert_raise Elasticsearch::Model::NotImplemented do
35
+ DummyClassForDefaultAdapter.new.__transform
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,102 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::AdapterMongoidTest < Test::Unit::TestCase
4
+ context "Adapter Mongoid module: " do
5
+ class ::DummyClassForMongoid
6
+ RESPONSE = Struct.new('DummyMongoidResponse') do
7
+ def response
8
+ { 'hits' => {'hits' => [ {'_id' => 2}, {'_id' => 1} ]} }
9
+ end
10
+ end.new
11
+
12
+ def response
13
+ RESPONSE
14
+ end
15
+
16
+ def ids
17
+ [2, 1]
18
+ end
19
+ end
20
+
21
+ setup do
22
+ @records = [ stub(id: 1, inspect: '<Model-1>'), stub(id: 2, inspect: '<Model-2>') ]
23
+ ::Symbol.any_instance.stubs(:in).returns(@records)
24
+ end
25
+
26
+ should "have the register condition" do
27
+ assert_not_nil Elasticsearch::Model::Adapter.adapters[Elasticsearch::Model::Adapter::Mongoid]
28
+ assert_equal false, Elasticsearch::Model::Adapter.adapters[Elasticsearch::Model::Adapter::Mongoid].call(DummyClassForMongoid)
29
+ end
30
+
31
+ context "Records" do
32
+ setup do
33
+ DummyClassForMongoid.__send__ :include, Elasticsearch::Model::Adapter::Mongoid::Records
34
+ end
35
+
36
+ should "have the implementation" do
37
+ assert_instance_of Module, Elasticsearch::Model::Adapter::Mongoid::Records
38
+
39
+ instance = DummyClassForMongoid.new
40
+ instance.expects(:klass).returns(mock('class', where: @records))
41
+
42
+ assert_equal @records, instance.records
43
+ end
44
+
45
+ should "reorder the records based on hits order" do
46
+ @records.instance_variable_set(:@records, @records)
47
+
48
+ instance = DummyClassForMongoid.new
49
+ instance.expects(:klass).returns(mock('class', where: @records))
50
+
51
+ assert_equal [1, 2], @records. to_a.map(&:id)
52
+ assert_equal [2, 1], instance.records.to_a.map(&:id)
53
+ end
54
+
55
+ should "not reorder records when SQL order is present" do
56
+ @records.instance_variable_set(:@records, @records)
57
+
58
+ instance = DummyClassForMongoid.new
59
+ instance.expects(:klass).returns(stub('class', where: @records)).at_least_once
60
+ instance.records.expects(:asc).returns(@records)
61
+
62
+ assert_equal [2, 1], instance.records.to_a.map(&:id)
63
+ assert_equal [1, 2], instance.asc.to_a.map(&:id)
64
+ end
65
+ end
66
+
67
+ context "Callbacks" do
68
+ should "register hooks for automatically updating the index" do
69
+ DummyClassForMongoid.expects(:after_create)
70
+ DummyClassForMongoid.expects(:after_update)
71
+ DummyClassForMongoid.expects(:after_destroy)
72
+
73
+ Elasticsearch::Model::Adapter::Mongoid::Callbacks.included(DummyClassForMongoid)
74
+ end
75
+ end
76
+
77
+ context "Importing" do
78
+ should "implement the __find_in_batches method" do
79
+ DummyClassForMongoid.expects(:all).returns([])
80
+
81
+ DummyClassForMongoid.__send__ :extend, Elasticsearch::Model::Adapter::Mongoid::Importing
82
+ DummyClassForMongoid.__find_in_batches do; end
83
+ end
84
+
85
+ context "when transforming models" do
86
+ setup do
87
+ @transform = DummyClassForMongoid.__transform
88
+ end
89
+
90
+ should "provide an object that responds to #call" do
91
+ assert_respond_to @transform, :call
92
+ end
93
+
94
+ should "provide basic transformation" do
95
+ model = mock("model", id: 1, as_indexed_json: {})
96
+ assert_equal @transform.call(model), { index: { _id: "1", data: {} } }
97
+ end
98
+ end
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,69 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::AdapterTest < Test::Unit::TestCase
4
+ context "Adapter module" do
5
+ class ::DummyAdapterClass; end
6
+ class ::DummyAdapterClassWithAdapter; end
7
+ class ::DummyAdapter
8
+ Records = Module.new
9
+ Callbacks = Module.new
10
+ Importing = Module.new
11
+ end
12
+
13
+ should "return an Adapter instance" do
14
+ assert_instance_of Elasticsearch::Model::Adapter::Adapter,
15
+ Elasticsearch::Model::Adapter.from_class(DummyAdapterClass)
16
+ end
17
+
18
+ should "return a list of adapters" do
19
+ Elasticsearch::Model::Adapter::Adapter.expects(:adapters)
20
+ Elasticsearch::Model::Adapter.adapters
21
+ end
22
+
23
+ should "register an adapter" do
24
+ begin
25
+ Elasticsearch::Model::Adapter::Adapter.expects(:register)
26
+ Elasticsearch::Model::Adapter.register(:foo, lambda { |c| false })
27
+ ensure
28
+ Elasticsearch::Model::Adapter::Adapter.instance_variable_set(:@adapters, {})
29
+ end
30
+ end
31
+ end
32
+
33
+ context "Adapter class" do
34
+ should "register an adapter" do
35
+ begin
36
+ Elasticsearch::Model::Adapter::Adapter.register(:foo, lambda { |c| false })
37
+ assert Elasticsearch::Model::Adapter::Adapter.adapters[:foo]
38
+ ensure
39
+ Elasticsearch::Model::Adapter::Adapter.instance_variable_set(:@adapters, {})
40
+ end
41
+ end
42
+
43
+ should "return the default adapter" do
44
+ adapter = Elasticsearch::Model::Adapter::Adapter.new(DummyAdapterClass)
45
+ assert_equal Elasticsearch::Model::Adapter::Default, adapter.adapter
46
+ end
47
+
48
+ should "return a specific adapter" do
49
+ Elasticsearch::Model::Adapter::Adapter.register(DummyAdapter,
50
+ lambda { |c| c == DummyAdapterClassWithAdapter })
51
+
52
+ adapter = Elasticsearch::Model::Adapter::Adapter.new(DummyAdapterClassWithAdapter)
53
+ assert_equal DummyAdapter, adapter.adapter
54
+ end
55
+
56
+ should "return the modules" do
57
+ assert_nothing_raised do
58
+ Elasticsearch::Model::Adapter::Adapter.register(DummyAdapter,
59
+ lambda { |c| c == DummyAdapterClassWithAdapter })
60
+
61
+ adapter = Elasticsearch::Model::Adapter::Adapter.new(DummyAdapterClassWithAdapter)
62
+
63
+ assert_instance_of Module, adapter.records_mixin
64
+ assert_instance_of Module, adapter.callbacks_mixin
65
+ assert_instance_of Module, adapter.importing_mixin
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::CallbacksTest < Test::Unit::TestCase
4
+ context "Callbacks module" do
5
+ class ::DummyCallbacksModel
6
+ end
7
+
8
+ module DummyCallbacksAdapter
9
+ module CallbacksMixin
10
+ end
11
+
12
+ def callbacks_mixin
13
+ CallbacksMixin
14
+ end; module_function :callbacks_mixin
15
+ end
16
+
17
+ should "include the callbacks mixin from adapter" do
18
+ Elasticsearch::Model::Adapter.expects(:from_class)
19
+ .with(DummyCallbacksModel)
20
+ .returns(DummyCallbacksAdapter)
21
+
22
+ ::DummyCallbacksModel.expects(:__send__).with do |method, parameter|
23
+ assert_equal :include, method
24
+ assert_equal DummyCallbacksAdapter::CallbacksMixin, parameter
25
+ true
26
+ end
27
+
28
+ Elasticsearch::Model::Callbacks.included(DummyCallbacksModel)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::ClientTest < Test::Unit::TestCase
4
+ context "Client module" do
5
+ class ::DummyClientModel
6
+ extend Elasticsearch::Model::Client::ClassMethods
7
+ include Elasticsearch::Model::Client::InstanceMethods
8
+ end
9
+
10
+ should "have the default client method" do
11
+ assert_instance_of Elasticsearch::Transport::Client, DummyClientModel.client
12
+ assert_instance_of Elasticsearch::Transport::Client, DummyClientModel.new.client
13
+ end
14
+
15
+ should "set the client for the model" do
16
+ DummyClientModel.client = 'foobar'
17
+ assert_equal 'foobar', DummyClientModel.client
18
+ assert_equal 'foobar', DummyClientModel.new.client
19
+ end
20
+
21
+ should "set the client for a model instance" do
22
+ instance = DummyClientModel.new
23
+ instance.client = 'moobam'
24
+ assert_equal 'moobam', instance.client
25
+ end
26
+ end
27
+ end