elasticsearch-model 5.1.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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/README.md +18 -11
  4. data/Rakefile +27 -36
  5. data/elasticsearch-model.gemspec +5 -5
  6. data/examples/activerecord_custom_analyzer.rb +135 -0
  7. data/examples/activerecord_mapping_completion.rb +3 -18
  8. data/examples/datamapper_article.rb +11 -1
  9. data/gemfiles/3.0.gemfile +6 -1
  10. data/gemfiles/4.0.gemfile +7 -1
  11. data/gemfiles/5.0.gemfile +7 -1
  12. data/lib/elasticsearch/model/adapters/active_record.rb +7 -23
  13. data/lib/elasticsearch/model/adapters/mongoid.rb +10 -3
  14. data/lib/elasticsearch/model/importing.rb +1 -1
  15. data/lib/elasticsearch/model/indexing.rb +6 -4
  16. data/lib/elasticsearch/model/naming.rb +9 -2
  17. data/lib/elasticsearch/model/response/aggregations.rb +1 -1
  18. data/lib/elasticsearch/model/response/base.rb +3 -2
  19. data/lib/elasticsearch/model/response/pagination/kaminari.rb +109 -0
  20. data/lib/elasticsearch/model/response/pagination/will_paginate.rb +95 -0
  21. data/lib/elasticsearch/model/response/pagination.rb +2 -192
  22. data/lib/elasticsearch/model/response/result.rb +1 -1
  23. data/lib/elasticsearch/model/response/suggestions.rb +1 -1
  24. data/lib/elasticsearch/model/response.rb +11 -10
  25. data/lib/elasticsearch/model/version.rb +1 -1
  26. data/lib/elasticsearch/model.rb +15 -8
  27. data/spec/elasticsearch/model/adapter_spec.rb +119 -0
  28. data/spec/elasticsearch/model/adapters/active_record/associations_spec.rb +334 -0
  29. data/spec/elasticsearch/model/adapters/active_record/basic_spec.rb +340 -0
  30. data/spec/elasticsearch/model/adapters/active_record/dynamic_index_name_spec.rb +18 -0
  31. data/spec/elasticsearch/model/adapters/active_record/import_spec.rb +187 -0
  32. data/spec/elasticsearch/model/adapters/active_record/multi_model_spec.rb +110 -0
  33. data/spec/elasticsearch/model/adapters/active_record/namespaced_model_spec.rb +38 -0
  34. data/spec/elasticsearch/model/adapters/active_record/pagination_spec.rb +315 -0
  35. data/spec/elasticsearch/model/adapters/active_record/parent_child_spec.rb +75 -0
  36. data/spec/elasticsearch/model/adapters/active_record/serialization_spec.rb +61 -0
  37. data/spec/elasticsearch/model/adapters/active_record_spec.rb +207 -0
  38. data/spec/elasticsearch/model/adapters/default_spec.rb +41 -0
  39. data/spec/elasticsearch/model/adapters/mongoid/basic_spec.rb +267 -0
  40. data/spec/elasticsearch/model/adapters/mongoid/multi_model_spec.rb +66 -0
  41. data/spec/elasticsearch/model/adapters/mongoid_spec.rb +235 -0
  42. data/spec/elasticsearch/model/adapters/multiple_spec.rb +125 -0
  43. data/spec/elasticsearch/model/callbacks_spec.rb +33 -0
  44. data/spec/elasticsearch/model/client_spec.rb +66 -0
  45. data/spec/elasticsearch/model/hash_wrapper_spec.rb +12 -0
  46. data/spec/elasticsearch/model/importing_spec.rb +214 -0
  47. data/spec/elasticsearch/model/indexing_spec.rb +918 -0
  48. data/spec/elasticsearch/model/module_spec.rb +101 -0
  49. data/spec/elasticsearch/model/multimodel_spec.rb +55 -0
  50. data/spec/elasticsearch/model/naming_inheritance_spec.rb +184 -0
  51. data/spec/elasticsearch/model/naming_spec.rb +186 -0
  52. data/spec/elasticsearch/model/proxy_spec.rb +107 -0
  53. data/spec/elasticsearch/model/response/aggregations_spec.rb +66 -0
  54. data/spec/elasticsearch/model/response/base_spec.rb +90 -0
  55. data/spec/elasticsearch/model/response/pagination/kaminari_spec.rb +410 -0
  56. data/spec/elasticsearch/model/response/pagination/will_paginate_spec.rb +262 -0
  57. data/spec/elasticsearch/model/response/records_spec.rb +118 -0
  58. data/spec/elasticsearch/model/response/response_spec.rb +131 -0
  59. data/spec/elasticsearch/model/response/result_spec.rb +122 -0
  60. data/spec/elasticsearch/model/response/results_spec.rb +56 -0
  61. data/spec/elasticsearch/model/searching_search_request_spec.rb +112 -0
  62. data/spec/elasticsearch/model/searching_spec.rb +49 -0
  63. data/spec/elasticsearch/model/serializing_spec.rb +22 -0
  64. data/spec/spec_helper.rb +161 -0
  65. data/spec/support/app/answer.rb +33 -0
  66. data/spec/support/app/article.rb +22 -0
  67. data/spec/support/app/article_for_pagination.rb +12 -0
  68. data/spec/support/app/article_with_custom_serialization.rb +13 -0
  69. data/spec/support/app/article_with_dynamic_index_name.rb +15 -0
  70. data/spec/support/app/author.rb +9 -0
  71. data/spec/support/app/authorship.rb +4 -0
  72. data/spec/support/app/category.rb +3 -0
  73. data/spec/support/app/comment.rb +3 -0
  74. data/spec/support/app/episode.rb +11 -0
  75. data/spec/support/app/image.rb +19 -0
  76. data/spec/support/app/import_article.rb +12 -0
  77. data/spec/support/app/mongoid_article.rb +21 -0
  78. data/spec/support/app/namespaced_book.rb +10 -0
  79. data/spec/support/app/parent_and_child_searchable.rb +24 -0
  80. data/spec/support/app/post.rb +14 -0
  81. data/spec/support/app/question.rb +27 -0
  82. data/spec/support/app/searchable.rb +48 -0
  83. data/spec/support/app/series.rb +11 -0
  84. data/spec/support/app.rb +21 -0
  85. data/spec/support/model.json +1 -0
  86. metadata +134 -90
  87. data/test/integration/active_record_associations_parent_child_test.rb +0 -147
  88. data/test/integration/active_record_associations_test.rb +0 -339
  89. data/test/integration/active_record_basic_test.rb +0 -251
  90. data/test/integration/active_record_custom_serialization_test.rb +0 -67
  91. data/test/integration/active_record_import_test.rb +0 -115
  92. data/test/integration/active_record_namespaced_model_test.rb +0 -54
  93. data/test/integration/active_record_pagination_test.rb +0 -149
  94. data/test/integration/dynamic_index_name_test.rb +0 -52
  95. data/test/integration/mongoid_basic_test.rb +0 -176
  96. data/test/integration/multiple_models_test.rb +0 -176
  97. data/test/support/model.json +0 -1
  98. data/test/test_helper.rb +0 -92
  99. data/test/unit/adapter_active_record_test.rb +0 -157
  100. data/test/unit/adapter_default_test.rb +0 -41
  101. data/test/unit/adapter_mongoid_test.rb +0 -104
  102. data/test/unit/adapter_multiple_test.rb +0 -106
  103. data/test/unit/adapter_test.rb +0 -69
  104. data/test/unit/callbacks_test.rb +0 -31
  105. data/test/unit/client_test.rb +0 -27
  106. data/test/unit/hash_wrapper_test.rb +0 -13
  107. data/test/unit/importing_test.rb +0 -203
  108. data/test/unit/indexing_test.rb +0 -687
  109. data/test/unit/module_test.rb +0 -68
  110. data/test/unit/multimodel_test.rb +0 -38
  111. data/test/unit/naming_inheritance_test.rb +0 -94
  112. data/test/unit/naming_test.rb +0 -103
  113. data/test/unit/proxy_test.rb +0 -98
  114. data/test/unit/response_aggregations_test.rb +0 -46
  115. data/test/unit/response_base_test.rb +0 -40
  116. data/test/unit/response_pagination_kaminari_test.rb +0 -433
  117. data/test/unit/response_pagination_will_paginate_test.rb +0 -398
  118. data/test/unit/response_records_test.rb +0 -91
  119. data/test/unit/response_result_test.rb +0 -90
  120. data/test/unit/response_results_test.rb +0 -31
  121. data/test/unit/response_test.rb +0 -104
  122. data/test/unit/searching_search_request_test.rb +0 -78
  123. data/test/unit/searching_test.rb +0 -41
  124. data/test/unit/serializing_test.rb +0 -17
  125. /data/{test → spec}/support/model.yml +0 -0
@@ -1,176 +0,0 @@
1
- require 'test_helper'
2
- require 'active_record'
3
-
4
- # Needed for ActiveRecord 3.x ?
5
- ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => ":memory:" ) unless ActiveRecord::Base.connected?
6
-
7
- ::ActiveRecord::Base.raise_in_transactional_callbacks = true if ::ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks) && ::ActiveRecord::VERSION::MAJOR.to_s < '5'
8
-
9
- MongoDB.setup!
10
-
11
- module Elasticsearch
12
- module Model
13
- class MultipleModelsIntegration < Elasticsearch::Test::IntegrationTestCase
14
- module ::NameSearch
15
- extend ActiveSupport::Concern
16
-
17
- included do
18
- include Elasticsearch::Model
19
- include Elasticsearch::Model::Callbacks
20
-
21
- settings index: {number_of_shards: 1, number_of_replicas: 0} do
22
- mapping do
23
- indexes :name, type: 'text', analyzer: 'snowball'
24
- indexes :created_at, type: 'date'
25
- end
26
- end
27
- end
28
- end
29
-
30
- class ::Episode < ActiveRecord::Base
31
- include NameSearch
32
- end
33
-
34
- class ::Series < ActiveRecord::Base
35
- include NameSearch
36
- end
37
-
38
- context "Multiple models" do
39
- setup do
40
- ActiveRecord::Schema.define(:version => 1) do
41
- create_table :episodes do |t|
42
- t.string :name
43
- t.datetime :created_at, :default => 'NOW()'
44
- end
45
-
46
- create_table :series do |t|
47
- t.string :name
48
- t.datetime :created_at, :default => 'NOW()'
49
- end
50
- end
51
-
52
- [::Episode, ::Series].each do |model|
53
- model.delete_all
54
- model.__elasticsearch__.create_index! force: true
55
- model.create name: "The #{model.name}"
56
- model.create name: "A great #{model.name}"
57
- model.create name: "The greatest #{model.name}"
58
- model.__elasticsearch__.refresh_index!
59
- end
60
- end
61
-
62
- should "find matching documents across multiple models" do
63
- response = Elasticsearch::Model.search(%q<"The greatest Episode"^2 OR "The greatest Series">, [Series, Episode])
64
-
65
- assert response.any?, "Response should not be empty: #{response.to_a.inspect}"
66
-
67
- assert_equal 2, response.results.size
68
- assert_equal 2, response.records.size
69
-
70
- assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
71
- assert_instance_of Episode, response.records.first
72
- assert_instance_of Series, response.records.last
73
-
74
- assert_equal 'The greatest Episode', response.results[0].name
75
- assert_equal 'The greatest Episode', response.records[0].name
76
-
77
- assert_equal 'The greatest Series', response.results[1].name
78
- assert_equal 'The greatest Series', response.records[1].name
79
- end
80
-
81
- should "provide access to results" do
82
- response = Elasticsearch::Model.search(%q<"A great Episode"^2 OR "A great Series">, [Series, Episode])
83
-
84
- assert_equal 'A great Episode', response.results[0].name
85
- assert_equal true, response.results[0].name?
86
- assert_equal false, response.results[0].boo?
87
-
88
- assert_equal 'A great Series', response.results[1].name
89
- assert_equal true, response.results[1].name?
90
- assert_equal false, response.results[1].boo?
91
- end
92
-
93
- should "only retrieve records for existing results" do
94
- ::Series.find_by_name("The greatest Series").delete
95
- ::Series.__elasticsearch__.refresh_index!
96
- response = Elasticsearch::Model.search(%q<"The greatest Episode"^2 OR "The greatest Series">, [Series, Episode])
97
-
98
- assert response.any?, "Response should not be empty: #{response.to_a.inspect}"
99
-
100
- assert_equal 2, response.results.size
101
- assert_equal 1, response.records.size
102
-
103
- assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
104
- assert_instance_of Episode, response.records.first
105
-
106
- assert_equal 'The greatest Episode', response.results[0].name
107
- assert_equal 'The greatest Episode', response.records[0].name
108
- end
109
-
110
- should "paginate the results" do
111
- response = Elasticsearch::Model.search('series OR episode', [Series, Episode])
112
-
113
- assert_equal 3, response.page(1).per(3).results.size
114
- assert_equal 3, response.page(2).per(3).results.size
115
- assert_equal 0, response.page(3).per(3).results.size
116
- end
117
-
118
- if MongoDB.available?
119
- MongoDB.connect_to 'mongoid_collections'
120
-
121
- context "Across mongoid models" do
122
- setup do
123
- class ::Image
124
- include Mongoid::Document
125
- include Elasticsearch::Model
126
- include Elasticsearch::Model::Callbacks
127
-
128
- field :name, type: String
129
- attr_accessible :name if respond_to? :attr_accessible
130
-
131
- settings index: {number_of_shards: 1, number_of_replicas: 0} do
132
- mapping do
133
- indexes :name, type: 'text', analyzer: 'snowball'
134
- indexes :created_at, type: 'date'
135
- end
136
- end
137
-
138
- def as_indexed_json(options={})
139
- as_json(except: [:_id])
140
- end
141
- end
142
-
143
- Image.delete_all
144
- Image.__elasticsearch__.create_index! force: true
145
- Image.create! name: "The Image"
146
- Image.create! name: "A great Image"
147
- Image.create! name: "The greatest Image"
148
- Image.__elasticsearch__.refresh_index!
149
- Image.__elasticsearch__.client.cluster.health wait_for_status: 'yellow'
150
- end
151
-
152
- should "find matching documents across multiple models" do
153
- response = Elasticsearch::Model.search(%q<"greatest Episode" OR "greatest Image"^2>, [Episode, Image])
154
-
155
- assert response.any?, "Response should not be empty: #{response.to_a.inspect}"
156
-
157
- assert_equal 2, response.results.size
158
- assert_equal 2, response.records.size
159
-
160
- assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
161
- assert_instance_of Image, response.records.first
162
- assert_instance_of Episode, response.records.last
163
-
164
- assert_equal 'The greatest Image', response.results[0].name
165
- assert_equal 'The greatest Image', response.records[0].name
166
-
167
- assert_equal 'The greatest Episode', response.results[1].name
168
- assert_equal 'The greatest Episode', response.records[1].name
169
- end
170
- end
171
- end
172
-
173
- end
174
- end
175
- end
176
- end
@@ -1 +0,0 @@
1
- { "baz": "qux" }
data/test/test_helper.rb DELETED
@@ -1,92 +0,0 @@
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
64
-
65
- class MongoDB
66
- def self.setup!
67
- begin
68
- require 'mongoid'
69
- Mongo::Client.new(["localhost:27017"])
70
- ENV['MONGODB_AVAILABLE'] = 'yes'
71
- rescue LoadError, Mongo::Error => e
72
- $stderr.puts "MongoDB not installed or running: #{e}"
73
- end
74
- end
75
-
76
- def self.available?
77
- !!ENV['MONGODB_AVAILABLE']
78
- end
79
-
80
- def self.connect_to(source)
81
- $stderr.puts "Mongoid #{Mongoid::VERSION}", '-'*80
82
-
83
- logger = ::Logger.new($stderr)
84
- logger.formatter = lambda { |s, d, p, m| " #{m.ansi(:faint, :cyan)}\n" }
85
- logger.level = ::Logger::DEBUG
86
-
87
- Mongoid.logger = logger unless ENV['QUIET']
88
- Mongo::Logger.logger = logger unless ENV['QUIET']
89
-
90
- Mongoid.connect_to source
91
- end
92
- end
@@ -1,157 +0,0 @@
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 "load the records with its submodels when using :includes" do
55
- klass = mock('class', primary_key: :some_key, where: @records)
56
- @records.expects(:includes).with([:submodel]).at_least_once
57
-
58
- instance = DummyClassForActiveRecord.new
59
- instance.expects(:klass).returns(klass).at_least_once
60
- instance.options[:includes] = [:submodel]
61
- instance.records
62
- end
63
-
64
- should "reorder the records based on hits order" do
65
- @records.instance_variable_set(:@records, @records)
66
-
67
- instance = DummyClassForActiveRecord.new
68
- instance.expects(:klass).returns(mock('class', primary_key: :some_key, where: @records)).at_least_once
69
-
70
- assert_equal [1, 2], @records. to_a.map(&:id)
71
- assert_equal [2, 1], instance.records.to_a.map(&:id)
72
- end
73
-
74
- should "not reorder records when SQL order is present" do
75
- @records.instance_variable_set(:@records, @records)
76
-
77
- instance = DummyClassForActiveRecord.new
78
- instance.expects(:klass).returns(stub('class', primary_key: :some_key, where: @records)).at_least_once
79
- instance.records.expects(:order).returns(@records)
80
-
81
- assert_equal [2, 1], instance.records. to_a.map(&:id)
82
- assert_equal [1, 2], instance.order(:foo).to_a.map(&:id)
83
- end
84
- end
85
-
86
- context "Callbacks" do
87
- should "register hooks for automatically updating the index" do
88
- DummyClassForActiveRecord.expects(:after_commit).times(3)
89
-
90
- Elasticsearch::Model::Adapter::ActiveRecord::Callbacks.included(DummyClassForActiveRecord)
91
- end
92
- end
93
-
94
- context "Importing" do
95
- setup do
96
- DummyClassForActiveRecord.__send__ :extend, Elasticsearch::Model::Adapter::ActiveRecord::Importing
97
- end
98
-
99
- should "raise an exception when passing an invalid scope" do
100
- assert_raise NoMethodError do
101
- DummyClassForActiveRecord.__find_in_batches(scope: :not_found_method) do; end
102
- end
103
- end
104
-
105
- should "implement the __find_in_batches method" do
106
- DummyClassForActiveRecord.expects(:find_in_batches).returns([])
107
- DummyClassForActiveRecord.__find_in_batches do; end
108
- end
109
-
110
- should "limit the relation to a specific scope" do
111
- DummyClassForActiveRecord.expects(:find_in_batches).returns([])
112
- DummyClassForActiveRecord.expects(:published).returns(DummyClassForActiveRecord)
113
-
114
- DummyClassForActiveRecord.__find_in_batches(scope: :published) do; end
115
- end
116
-
117
- should "limit the relation to a specific query" do
118
- DummyClassForActiveRecord.expects(:find_in_batches).returns([])
119
- DummyClassForActiveRecord.expects(:where).returns(DummyClassForActiveRecord)
120
-
121
- DummyClassForActiveRecord.__find_in_batches(query: -> { where(color: "red") }) do; end
122
- end
123
-
124
- should "preprocess the batch if option provided" do
125
- class << DummyClassForActiveRecord
126
- # Updates/transforms the batch while fetching it from the database
127
- # (eg. with information from an external system)
128
- #
129
- def update_batch(batch)
130
- batch.collect { |b| b.to_s + '!' }
131
- end
132
- end
133
-
134
- DummyClassForActiveRecord.expects(:__find_in_batches).returns( [:a, :b] )
135
-
136
- DummyClassForActiveRecord.__find_in_batches(preprocess: :update_batch) do |batch|
137
- assert_same_elements ["a!", "b!"], batch
138
- end
139
- end
140
-
141
- context "when transforming models" do
142
- setup do
143
- @transform = DummyClassForActiveRecord.__transform
144
- end
145
-
146
- should "provide an object that responds to #call" do
147
- assert_respond_to @transform, :call
148
- end
149
-
150
- should "provide default transformation" do
151
- model = mock("model", id: 1, __elasticsearch__: stub(as_indexed_json: {}))
152
- assert_equal @transform.call(model), { index: { _id: 1, data: {} } }
153
- end
154
- end
155
- end
156
- end
157
- end
@@ -1,41 +0,0 @@
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
@@ -1,104 +0,0 @@
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
- relation = mock()
80
- relation.stubs(:no_timeout).returns([])
81
- DummyClassForMongoid.expects(:all).returns(relation)
82
-
83
- DummyClassForMongoid.__send__ :extend, Elasticsearch::Model::Adapter::Mongoid::Importing
84
- DummyClassForMongoid.__find_in_batches do; end
85
- end
86
-
87
- context "when transforming models" do
88
- setup do
89
- @transform = DummyClassForMongoid.__transform
90
- end
91
-
92
- should "provide an object that responds to #call" do
93
- assert_respond_to @transform, :call
94
- end
95
-
96
- should "provide basic transformation" do
97
- model = mock("model", id: 1, as_indexed_json: {})
98
- assert_equal @transform.call(model), { index: { _id: "1", data: {} } }
99
- end
100
- end
101
- end
102
-
103
- end
104
- end
@@ -1,106 +0,0 @@
1
- require 'test_helper'
2
-
3
- class Elasticsearch::Model::MultipleTest < Test::Unit::TestCase
4
-
5
- context "Adapter for multiple models" do
6
-
7
- class ::DummyOne
8
- include Elasticsearch::Model
9
-
10
- index_name 'dummy'
11
- document_type 'dummy_one'
12
-
13
- def self.find(ids)
14
- ids.map { |id| new(id) }
15
- end
16
-
17
- attr_reader :id
18
-
19
- def initialize(id)
20
- @id = id.to_i
21
- end
22
- end
23
-
24
- module ::Namespace
25
- class DummyTwo
26
- include Elasticsearch::Model
27
-
28
- index_name 'dummy'
29
- document_type 'dummy_two'
30
-
31
- def self.find(ids)
32
- ids.map { |id| new(id) }
33
- end
34
-
35
- attr_reader :id
36
-
37
- def initialize(id)
38
- @id = id.to_i
39
- end
40
- end
41
- end
42
-
43
- class ::DummyTwo
44
- include Elasticsearch::Model
45
-
46
- index_name 'other_index'
47
- document_type 'dummy_two'
48
-
49
- def self.find(ids)
50
- ids.map { |id| new(id) }
51
- end
52
-
53
- attr_reader :id
54
-
55
- def initialize(id)
56
- @id = id.to_i
57
- end
58
- end
59
-
60
- HITS = [{_index: 'dummy',
61
- _type: 'dummy_two',
62
- _id: '2',
63
- }, {
64
- _index: 'dummy',
65
- _type: 'dummy_one',
66
- _id: '2',
67
- }, {
68
- _index: 'other_index',
69
- _type: 'dummy_two',
70
- _id: '1',
71
- }, {
72
- _index: 'dummy',
73
- _type: 'dummy_two',
74
- _id: '1',
75
- }, {
76
- _index: 'dummy',
77
- _type: 'dummy_one',
78
- _id: '3'}]
79
-
80
- setup do
81
- @multimodel = Elasticsearch::Model::Multimodel.new(DummyOne, DummyTwo, Namespace::DummyTwo)
82
- end
83
-
84
- context "when returning records" do
85
- setup do
86
- @multimodel.class.send :include, Elasticsearch::Model::Adapter::Multiple::Records
87
- @multimodel.expects(:response).at_least_once.returns(stub(response: { 'hits' => { 'hits' => HITS } }))
88
- end
89
-
90
- should "keep the order from response" do
91
- assert_instance_of Module, Elasticsearch::Model::Adapter::Multiple::Records
92
- records = @multimodel.records
93
-
94
- assert_equal 5, records.count
95
-
96
- assert_kind_of ::Namespace::DummyTwo, records[0]
97
- assert_kind_of ::DummyOne, records[1]
98
- assert_kind_of ::DummyTwo, records[2]
99
- assert_kind_of ::Namespace::DummyTwo, records[3]
100
- assert_kind_of ::DummyOne, records[4]
101
-
102
- assert_equal [2, 2, 1, 1, 3], records.map(&:id)
103
- end
104
- end
105
- end
106
- end