activesearch 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,46 +1,40 @@
1
- require 'mongoid'
2
- require 'activesearch/mongoid'
3
-
4
- Mongoid.configure do |config|
5
- config.sessions = {:default => {:hosts => ["localhost"], :database => "activesearch_test"}}
6
- end
7
-
8
1
  class MongoidModel
9
2
  include Mongoid::Document
10
3
  include ActiveSearch::Mongoid
11
-
12
- field :title, type: String
13
- field :text, type: String
14
- field :junk, type: String
15
- field :special, type: Boolean, default: false
16
- field :scope_id, type: Integer
17
- field :tags, type: Array
18
-
19
- search_by [:title, :text, :tags, store: [:title, :junk, :scope_id]], unless: :special
4
+
5
+ field :title, type: String
6
+ field :text, type: String
7
+ field :junk, type: String
8
+ field :special, type: Boolean, default: false
9
+ field :scope_id, type: Integer
10
+ field :color, type: String, localize: true
11
+ field :tags, type: Array
12
+
13
+ search_by [:title, :text, :tags, :color, store: [:title, :junk, :scope_id]], unless: :special?
20
14
  end
21
15
 
22
16
  class AnotherMongoidModel
23
17
  include Mongoid::Document
24
18
  include ActiveSearch::Mongoid
25
-
19
+
26
20
  field :title, type: String
27
21
  field :scope_id, type: Integer
22
+ field :color, localize: true
28
23
  search_by :options_for_search
29
-
24
+
30
25
  def options_for_search
31
- [:title, :text, store: [:title, :virtual, :scope_id]]
26
+ [:title, store: [:title, :virtual, :scope_id, :color]]
32
27
  end
33
-
28
+
34
29
  def virtual
35
30
  "virtual"
36
31
  end
37
32
  end
38
33
 
39
-
40
34
  class LocalizedMongoidModel
41
35
  include Mongoid::Document
42
36
  include ActiveSearch::Mongoid
43
-
37
+
44
38
  field :title, localize: true
45
39
  field :special_type
46
40
  search_by [:title, store: [:title]]
data/spec/spec_helper.rb CHANGED
@@ -1,61 +1,51 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup
4
+ Bundler.require
5
+
6
+ require 'rspec'
7
+
8
+ require 'activesearch/base'
1
9
  require 'active_model'
2
10
  require 'active_attr'
3
11
  require 'sucker_punch'
4
12
  require 'sucker_punch/testing/inline'
5
13
 
6
- class ActiveMimic
7
- extend ActiveModel::Callbacks
8
- extend ActiveModel::Naming
9
- include ActiveModel::Serialization
10
- include ActiveAttr::Attributes
11
- include ActiveAttr::MassAssignment
12
-
13
- attribute :id
14
- attribute :type
15
-
16
- define_model_callbacks :save
17
- define_model_callbacks :destroy
18
-
19
- def self.create(attrs)
20
- new(attrs).tap(&:save)
21
- end
22
-
23
- def indexable_id
24
- "#{self.class.to_s}_#{self.id}"
25
- end
26
-
27
- def type
28
- self.class.to_s
29
- end
30
-
31
- def save
32
- self.id ||= self.class.next_id
33
- run_callbacks :save do
34
- true
35
- end
36
- end
37
-
38
- def destroy
39
- run_callbacks :destroy do
40
- true
41
- end
14
+ # Requires supporting ruby files with custom matchers and macros, etc,
15
+ # in spec/support/ and its subdirectories.
16
+ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each { |f| require f }
17
+
18
+ RSpec.configure do |config|
19
+
20
+ require 'database_cleaner'
21
+ require 'database_cleaner/mongoid/truncation'
22
+
23
+ config.backtrace_clean_patterns = [
24
+ /\/lib\d*\/ruby\//,
25
+ /bin\//,
26
+ /gems/,
27
+ /spec\/spec_helper\.rb/,
28
+ /lib\/rspec\/(core|expectations|matchers|mocks)/
29
+ ]
30
+
31
+ config.before(:suite) do
32
+ DatabaseCleaner['mongoid'].strategy = :truncation
42
33
  end
43
-
44
- def self.next_id
45
- @next_id ||= 0
46
- @next_id += 1
34
+
35
+ config.before(:each) do
36
+ DatabaseCleaner.start
47
37
  end
48
-
49
- def self.localized_attribute(name)
50
- attribute "#{name}_translations", type: Hash
51
-
52
- define_method name do
53
- send("#{name}_translations") && send("#{name}_translations")[I18n.locale.to_s]
54
- end
55
-
56
- define_method "#{name}=" do |value|
57
- send("#{name}_translations=", {}) if send("#{name}_translations").nil?
58
- send("#{name}_translations").merge!(I18n.locale.to_s => value)
59
- end
38
+
39
+ config.after(:each) do
40
+ # ElasticSearch engine
41
+ # Tire::Configuration.client.delete "#{Tire::Configuration.url}/_all"
42
+
43
+ # Algolia engine
44
+ # ActiveSearch::Algolia::Client.new.delete_index
45
+
46
+ # Mongoid engine
47
+ # DatabaseCleaner.clean
48
+
49
+ ::I18n.locale = 'en'
60
50
  end
61
- end
51
+ end
@@ -0,0 +1,56 @@
1
+ class ActiveMimic
2
+ extend ActiveModel::Callbacks
3
+ extend ActiveModel::Naming
4
+ include ActiveModel::Serialization
5
+ include ActiveAttr::Attributes
6
+ include ActiveAttr::MassAssignment
7
+
8
+ attribute :id
9
+ attribute :type
10
+
11
+ define_model_callbacks :save
12
+ define_model_callbacks :destroy
13
+
14
+ def self.create(attrs)
15
+ new(attrs).tap(&:save)
16
+ end
17
+
18
+ def indexable_id
19
+ "#{self.class.to_s}_#{self.id}"
20
+ end
21
+
22
+ def type
23
+ self.class.to_s
24
+ end
25
+
26
+ def save
27
+ self.id ||= self.class.next_id
28
+ run_callbacks :save do
29
+ true
30
+ end
31
+ end
32
+
33
+ def destroy
34
+ run_callbacks :destroy do
35
+ true
36
+ end
37
+ end
38
+
39
+ def self.next_id
40
+ @next_id ||= 0
41
+ @next_id += 1
42
+ end
43
+
44
+ def self.localized_attribute(name)
45
+ attribute "#{name}_translations", type: Hash
46
+
47
+ define_method name do
48
+ send("#{name}_translations") && send("#{name}_translations")[I18n.locale.to_s]
49
+ end
50
+
51
+ define_method "#{name}=" do |value|
52
+ send("#{name}_translations=", {}) if send("#{name}_translations").nil?
53
+ send("#{name}_translations").merge!(I18n.locale.to_s => value)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,53 @@
1
+ module SetupEngine
2
+
3
+ def self.setup(name)
4
+ # 1. set up the engine (connection)
5
+ case name
6
+ when :algolia then setup_algolia
7
+ when :mongoid then setup_mongoid
8
+ when :elastic_search then setup_elastic_search
9
+ end
10
+
11
+ # 2. load the test models depending on the engine
12
+ require File.join(File.dirname(__FILE__), '..', 'models', "#{name}.rb")
13
+ end
14
+
15
+ protected
16
+
17
+ def self.setup_algolia
18
+ require 'yaml'
19
+ require 'activesearch/algolia'
20
+
21
+ YAML.load_file(File.dirname(__FILE__) + '/../../config/algolia.yml').tap do |config|
22
+ ActiveSearch::Algolia::Client.configure(config["api_key"], config["app_id"])
23
+ end
24
+
25
+ ActiveSearch::Algolia::Client.new.delete_index
26
+ end
27
+
28
+ def self.setup_mongoid
29
+ require 'mongoid'
30
+
31
+ Mongoid.configure do |config|
32
+ config.sessions = {
33
+ :default => {
34
+ :hosts => ["localhost"],
35
+ :database => "activesearch_test"
36
+ }
37
+ }
38
+ end
39
+
40
+ require 'activesearch/mongoid'
41
+
42
+ ActiveSearch::Mongoid::Index.create_indexes
43
+
44
+ DatabaseCleaner.clean
45
+ end
46
+
47
+ def self.elastic_search
48
+ # TODO
49
+
50
+ # Tire::Configuration.client.delete "#{Tire::Configuration.url}/_all"
51
+ end
52
+
53
+ end
@@ -0,0 +1,63 @@
1
+ shared_examples 'an engine' do
2
+
3
+ before(:all) do
4
+ @findable = @model.create(title: "Findable Findable", junk: "Junk field", scope_id: 1)
5
+ @quite_findable = @model.create(title: "Some title", text: "Findable text", scope_id: 1)
6
+ @another = @another_model.create(title: "Another <strong>findable</strong> title with tags", scope_id: 1)
7
+ @junk = @model.create(title: "Junk", junk: "Not Findable junk", scope_id: 1)
8
+ @special = @model.create(title: "Not findable because it's special", special: true, scope_id: 1)
9
+ @foreign = @model.create(title: "Findable", scope_id: 2)
10
+ @tagged = @model.create(title: "Tagged document", tags: ['findable'], scope_id: 1)
11
+ @localized = @model.create(title: "Localized", color: "Red")
12
+ I18n.with_locale :es do
13
+ @localized.color = "Rojo"
14
+ @localized.save
15
+ end
16
+ end
17
+
18
+ it "should find the expected documents" do
19
+ results = ActiveSearch.search("findable", scope_id: 1).map { |doc| doc.select { |k,v| %w[title junk virtual].include?(k.to_s) } }
20
+ results.sort_by { |result| result["title"] }.should == [
21
+ {
22
+ "title" => "Another findable title with tags",
23
+ "virtual" => "virtual"
24
+ },
25
+ {
26
+ "title" => "Findable Findable",
27
+ "junk" => "Junk field"
28
+ },
29
+ {
30
+ "title" => "Some title"
31
+ },
32
+ {
33
+ "title" => "Tagged document"
34
+ }
35
+ ]
36
+ ActiveSearch.search("some text").first["title"].should == "Some title"
37
+ ActiveSearch.search("junk").first["title"].should == "Junk"
38
+ end
39
+
40
+ it "should handle localized fields" do
41
+ ActiveSearch.search("Localized").first["color"].should == "Red"
42
+ I18n.with_locale :es do
43
+ ActiveSearch.search("Localized").first["color"].should == "Rojo"
44
+ end
45
+ end
46
+
47
+ it "should find docs even with upcase searches" do
48
+ ActiveSearch.search("FINDABLE").count.should == 5
49
+ end
50
+
51
+ it "should remove destroyed documents from index" do
52
+ @findable.destroy
53
+ ActiveSearch.search("findable").count.should == 4
54
+ end
55
+
56
+ it "should excerpt and highlight" do
57
+ @model.create(title: <<-LIPSUM, junk: "Junk field", scope_id: 1)
58
+ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy findable text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
59
+ LIPSUM
60
+ ActiveSearch.search("dummy findable").first["highlighted"]["title"].should == "Lorem Ipsum is simply <em>dummy</em> text of the printing and typesetting industry. Lo..."
61
+ end
62
+
63
+ end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activesearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Alvarez
8
+ - Didier Lafforgue
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-11-11 00:00:00.000000000 Z
12
+ date: 2014-04-01 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: activesupport
@@ -108,6 +109,20 @@ dependencies:
108
109
  - - ~>
109
110
  - !ruby/object:Gem::Version
110
111
  version: '3'
112
+ - !ruby/object:Gem::Dependency
113
+ name: database_cleaner
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ~>
117
+ - !ruby/object:Gem::Version
118
+ version: 0.9.1
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 0.9.1
111
126
  - !ruby/object:Gem::Dependency
112
127
  name: tire
113
128
  requirement: !ruby/object:Gem::Requirement
@@ -167,11 +182,13 @@ dependencies:
167
182
  description: ORM agnostic full text search
168
183
  email:
169
184
  - papipo@gmail.com
185
+ - didier.lafforgue@gmail.com
170
186
  executables: []
171
187
  extensions: []
172
188
  extra_rdoc_files: []
173
189
  files:
174
190
  - .gitignore
191
+ - .rspec
175
192
  - Gemfile
176
193
  - LICENSE.txt
177
194
  - README.md
@@ -186,19 +203,21 @@ files:
186
203
  - lib/activesearch/base.rb
187
204
  - lib/activesearch/elastic_search.rb
188
205
  - lib/activesearch/mongoid.rb
189
- - lib/activesearch/mongoid/model.rb
206
+ - lib/activesearch/mongoid/index.rb
190
207
  - lib/activesearch/proxy.rb
191
208
  - lib/activesearch/result.rb
192
209
  - lib/activesearch/version.rb
193
- - spec/algolia_spec.rb
194
- - spec/base_spec.rb
195
210
  - spec/config/mongoid.yml
196
- - spec/engines_spec.rb
211
+ - spec/engines/algolia_spec.rb
212
+ - spec/engines/base_spec.rb
213
+ - spec/engines/mongoid_spec.rb
197
214
  - spec/models/algolia.rb
198
215
  - spec/models/elastic_search.rb
199
216
  - spec/models/mongoid.rb
200
- - spec/mongoid_spec.rb
201
217
  - spec/spec_helper.rb
218
+ - spec/support/active_mimic.rb
219
+ - spec/support/setup_engine.rb
220
+ - spec/support/shared_examples_for_engines.rb
202
221
  homepage: ''
203
222
  licenses: []
204
223
  metadata: {}
@@ -218,18 +237,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
237
  version: '0'
219
238
  requirements: []
220
239
  rubyforge_project:
221
- rubygems_version: 2.0.3
240
+ rubygems_version: 2.0.7
222
241
  signing_key:
223
242
  specification_version: 4
224
243
  summary: ActiveSearch lets you plug in a ruby module in any class that will allow
225
244
  you to do full text searches.
226
245
  test_files:
227
- - spec/algolia_spec.rb
228
- - spec/base_spec.rb
229
246
  - spec/config/mongoid.yml
230
- - spec/engines_spec.rb
247
+ - spec/engines/algolia_spec.rb
248
+ - spec/engines/base_spec.rb
249
+ - spec/engines/mongoid_spec.rb
231
250
  - spec/models/algolia.rb
232
251
  - spec/models/elastic_search.rb
233
252
  - spec/models/mongoid.rb
234
- - spec/mongoid_spec.rb
235
253
  - spec/spec_helper.rb
254
+ - spec/support/active_mimic.rb
255
+ - spec/support/setup_engine.rb
256
+ - spec/support/shared_examples_for_engines.rb
@@ -1,67 +0,0 @@
1
- module ActiveSearch
2
- module Mongoid
3
- class Model
4
- include ::Mongoid::Document
5
-
6
- field :_original_type, type: String
7
- field :_original_id, type: Moped::BSON::ObjectId
8
- field :_keywords
9
- field :_stored, type: Hash, default: {}
10
- alias_method :to_hash, :_stored
11
-
12
- index({_keywords: 1})
13
- index({_original_type: 1, _original_id: 1}, unique: true)
14
-
15
- def store_fields(original, fields, options)
16
- if options && options[:store]
17
- self._stored = {}
18
- options[:store].each do |f|
19
-
20
- if original.fields[f.to_s] && original.fields[f.to_s].localized?
21
- self._stored[f] = original.send("#{f}_translations")
22
- else
23
- self._stored[f] = original.send(f) if original.send(f).present?
24
- end
25
- end
26
- end
27
- end
28
-
29
- def refresh_keywords(original, fields)
30
- self._keywords = fields.select { |f| original.fields[f.to_s] }.inject([]) do |memo,f|
31
-
32
- if original.fields[f.to_s].localized?
33
- memo += original.send("#{f}_translations").map do |locale,translation|
34
- next if translation.nil?
35
- translation.downcase.split.map { |word| "#{locale}:#{word}"}
36
- end.flatten
37
- else
38
- if original[f]
39
- memo += if original[f].is_a?(Array)
40
- original[f].map { |value| value.nil? ? nil : value.downcase }
41
- else
42
- original[f].downcase.split
43
- end
44
-
45
- else
46
- memo
47
- end
48
- end
49
- end
50
-
51
- self._keywords = self._keywords.map! { |k| ActiveSearch.strip_tags(k) }
52
- self._keywords.uniq!
53
- end
54
-
55
- def self.deindex(original)
56
- ActiveSearch::Mongoid::Model.where(_original_type: original.class.to_s, _original_id: original.id).destroy
57
- end
58
-
59
- def self.reindex(original, fields, options)
60
- doc = find_or_initialize_by(_original_type: original.class.to_s, _original_id: original.id)
61
- doc.store_fields(original, fields, options)
62
- doc.refresh_keywords(original, fields)
63
- doc.save
64
- end
65
- end
66
- end
67
- end
data/spec/algolia_spec.rb DELETED
@@ -1,29 +0,0 @@
1
- #encoding: utf-8
2
- require File.join(File.dirname(__FILE__), 'spec_helper')
3
- require 'activesearch/algolia'
4
- require_relative 'models/algolia'
5
-
6
- YAML.load_file(File.dirname(__FILE__) + '/../config/algolia.yml').tap do |config|
7
- ActiveSearch::Algolia::Client.configure(config["api_key"], config["app_id"])
8
- end
9
-
10
- describe ActiveSearch::Algolia do
11
- before do
12
- ActiveSearch::Algolia::Client.new.delete_index
13
- end
14
-
15
- context "retry on errors" do
16
- before do
17
- times_called = 0
18
- @instance = AlgoliaModel.new(title: "Example")
19
- ActiveSearch::Algolia::Client.should_receive(:put).exactly(3).times.and_return do
20
- times_called += 1
21
- raise Errno::ECONNRESET if times_called <= 2
22
- end
23
- end
24
-
25
- subject { -> { @instance.save } }
26
-
27
- it { should_not raise_error }
28
- end
29
- end
data/spec/engines_spec.rb DELETED
@@ -1,90 +0,0 @@
1
- #encoding: utf-8
2
-
3
- require File.join(File.dirname(__FILE__), 'spec_helper')
4
-
5
- def cleanup(engine)
6
- case engine
7
- when "Algolia"
8
- YAML.load_file(File.dirname(__FILE__) + '/../config/algolia.yml').tap do |config|
9
- ActiveSearch::Algolia::Client.configure(config["api_key"], config["app_id"])
10
- end
11
- ActiveSearch::Algolia::Client.new.delete_index
12
- when "ElasticSearch"
13
- Tire::Configuration.client.delete "#{Tire::Configuration.url}/_all"
14
- load File.join(File.dirname(__FILE__), 'models', 'elastic_search.rb')
15
- when "Mongoid"
16
- Mongoid.purge!
17
- end
18
- end
19
-
20
- Dir[File.join(File.dirname(__FILE__), 'models', '*.rb')].map { |f| File.basename(f, '.rb') }.each do |filename|
21
- engine = filename.split('_').collect { |w| w.capitalize }.join
22
- next unless engine == "Algolia"
23
- describe "ActiveSearch::#{engine}" do
24
- before(:all) do
25
- I18n.locale = :en
26
- require File.join(File.dirname(__FILE__), 'models', filename)
27
- end
28
-
29
- before do
30
- cleanup(engine)
31
- @findable = Object.const_get("#{engine}Model").create(title: "Findable Findable", junk: "Junk field", scope_id: 1)
32
- @quite_findable = Object.const_get("#{engine}Model").create(title: "Some title", text: "Findable text", scope_id: 1)
33
- @another = Object.const_get("Another#{engine}Model").create(title: "Another <strong>findable</strong> title with tags", scope_id: 1)
34
- @junk = Object.const_get("#{engine}Model").create(title: "Junk", junk: "Not Findable junk", scope_id: 1)
35
- @special = Object.const_get("#{engine}Model").create(title: "Not findable because it's special", special: true, scope_id: 1)
36
- @foreign = Object.const_get("#{engine}Model").create(title: "Findable", scope_id: 2)
37
- @tagged = Object.const_get("#{engine}Model").create(title: "Tagged document", tags: ['findable'], scope_id: 1)
38
- @localized = Object.const_get("#{engine}Model").create(title: "Localized", color: "Red")
39
- I18n.with_locale :es do
40
- @localized.color = "Rojo"
41
- @localized.save
42
- end
43
- end
44
-
45
- it "should find the expected documents" do
46
- results = ActiveSearch.search("findable", scope_id: 1).map { |doc| doc.select { |k,v| %w[title junk virtual].include?(k.to_s) } }
47
- results.sort_by { |result| result["title"] }.should == [
48
- {
49
- "title" => "Another findable title with tags",
50
- "virtual" => "virtual"
51
- },
52
- {
53
- "title" => "Findable Findable",
54
- "junk" => "Junk field"
55
- },
56
- {
57
- "title" => "Some title"
58
- },
59
- {
60
- "title" => "Tagged document"
61
- }
62
- ]
63
- ActiveSearch.search("some text").first["title"].should == "Some title"
64
- ActiveSearch.search("junk").first["title"].should == "Junk"
65
- end
66
-
67
- it "should handle localized fields" do
68
- ActiveSearch.search("Localized").first["color"].should == "Red"
69
- I18n.with_locale :es do
70
- ActiveSearch.search("Localized").first["color"].should == "Rojo"
71
- end
72
- end
73
-
74
- it "should find docs even with upcase searches" do
75
- ActiveSearch.search("FINDABLE").count.should == 5
76
- end
77
-
78
- it "should remove destroyed documents from index" do
79
- @findable.destroy
80
- ActiveSearch.search("findable").count.should == 4
81
- end
82
-
83
- it "should excerpt and highlight" do
84
- Object.const_get("#{engine}Model").create(title: <<-LIPSUM, junk: "Junk field", scope_id: 1)
85
- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy findable text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
86
- LIPSUM
87
- ActiveSearch.search("dummy findable").first["highlighted"]["title"].should == "Lorem Ipsum is simply <em>dummy</em> text of the printing and typesetting industry. Lo..."
88
- end
89
- end
90
- end
data/spec/mongoid_spec.rb DELETED
@@ -1,52 +0,0 @@
1
- #encoding: utf-8
2
- require File.join(File.dirname(__FILE__), 'spec_helper')
3
- require 'mongoid'
4
- require 'activesearch/mongoid'
5
-
6
- Mongoid.load!("config/mongoid.yml", :test)
7
-
8
- class LocalizedMongoidModel
9
- include Mongoid::Document
10
- include ActiveSearch::Mongoid
11
-
12
- field :title, localize: true
13
- field :not_localized
14
- field :array, type: Array
15
- search_by [:title, :not_localized, :array, store: [:title]]
16
- end
17
-
18
-
19
- describe ActiveSearch::Mongoid do
20
- before do
21
- Mongoid.purge!
22
- I18n.locale = :en
23
- @localized = LocalizedMongoidModel.create!(title: "<strong>English</strong> English")
24
- I18n.with_locale(:es) do
25
- @localized.title = "Español Español"
26
- @localized.save!
27
- end
28
- end
29
-
30
- it "should be able to find by different locales" do
31
- ActiveSearch.search("english").first["title"].should == "<strong>English</strong> English"
32
- I18n.with_locale(:es) do
33
- ActiveSearch.search("español").first["title"].should == "Español Español"
34
- end
35
- end
36
-
37
- it "should store localized keywords with tags stripped" do
38
- ActiveSearch::Mongoid::Model.where(_original_type: "LocalizedMongoidModel", _original_id: @localized.id).first._keywords.should == ["en:english", "es:español"]
39
- end
40
-
41
- it "handles empty translations" do
42
- lambda { LocalizedMongoidModel.create!(title: nil, not_localized: "example") }.should_not raise_error
43
- end
44
-
45
- it "handles empty fields" do
46
- lambda { LocalizedMongoidModel.create!(title: "Example", not_localized: nil) }.should_not raise_error
47
- end
48
-
49
- it "handles nil values in arrays" do
50
- lambda { LocalizedMongoidModel.create!(title: "Example", not_localized: "example", array: [nil]) }.should_not raise_error
51
- end
52
- end