elasticsearch-model-queryable 0.1.5

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 (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