acts_as_indexed 0.8.1 → 0.8.2

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 (33) hide show
  1. data/CHANGELOG +9 -0
  2. data/Gemfile +3 -3
  3. data/Gemfile.lock +13 -15
  4. data/MIT-LICENSE +1 -1
  5. data/README.rdoc +2 -2
  6. data/Rakefile +24 -12
  7. data/VERSION +1 -1
  8. data/acts_as_indexed.gemspec +18 -13
  9. data/gemfiles/rails2_3.gemfile +7 -6
  10. data/gemfiles/rails3_0.gemfile +7 -5
  11. data/gemfiles/rails3_1.gemfile +7 -5
  12. data/gemfiles/rails3_2.gemfile +7 -5
  13. data/lib/acts_as_indexed/class_methods.rb +1 -1
  14. data/lib/acts_as_indexed/search_atom.rb +8 -1
  15. data/lib/acts_as_indexed/search_index.rb +25 -4
  16. data/lib/acts_as_indexed/storage.rb +2 -0
  17. data/test/{database.yml → config/database.yml} +0 -0
  18. data/test/{schema.rb → db/schema.rb} +0 -0
  19. data/test/{acts_as_indexed_test.rb → integration/acts_as_indexed_test.rb} +47 -43
  20. data/test/{will_paginate_search_test.rb → integration/will_paginate_search_test.rb} +4 -4
  21. data/test/{abstract_unit.rb → integration_test_helper.rb} +4 -2
  22. data/test/performance/query_performance_test.rb +47 -0
  23. data/test/performance/record_addition_performance_test.rb +23 -0
  24. data/test/performance/record_removal_performance_test.rb +23 -0
  25. data/test/performance/record_update_performance_test.rb +42 -0
  26. data/test/{configuration_test.rb → unit/configuration_test.rb} +1 -1
  27. data/test/{pre_tokenizer_test.rb → unit/pre_tokenizer_test.rb} +1 -1
  28. data/test/{search_atom_test.rb → unit/search_atom_test.rb} +1 -1
  29. data/test/{search_index_test.rb → unit/search_index_test.rb} +1 -1
  30. data/test/{token_normalizer_test.rb → unit/token_normalizer_test.rb} +1 -1
  31. data/test/{tokenizer_test.rb → unit/tokenizer_test.rb} +1 -1
  32. data/test/unit_test_helper.rb +20 -0
  33. metadata +18 -13
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ ===0.8.2 [27 January 2013]
2
+ - Full review and update of test examples.
3
+ - Fixed bug where all records matching resulted in an ID rather than scored order. [phurni - Pascal Hurni]
4
+ - Fixed bug where records were returned in order of lowest-score first. [phurni - Pascal Hurni]
5
+ - Fixed bug where 1.8.7 would fail CI tests. [parndt - Philip Arndt]
6
+ - 70x performance improvement for non-changed record updates.
7
+ - Added a benchmark suite.
8
+ - Updated README install instructions. [gudata - Ivaylo Bardarov]
9
+
1
10
  ===0.8.1 [21 December 2012]
2
11
  - Fixed bug where record count was not correctly updated on bulk add. [phurni - Pascal Hurni]
3
12
 
data/Gemfile CHANGED
@@ -1,9 +1,9 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  group :test do
4
- gem "mocha"
4
+ gem "rake"
5
+ gem "mocha", "~> 0.9.11"
5
6
  gem "sqlite3", "~> 1.3.5"
6
- gem "rcov"
7
- gem "activerecord"
7
+ gem "activerecord", "~> 3.2.9"
8
8
  gem "will_paginate", "~> 3.0.3"
9
9
  end
data/Gemfile.lock CHANGED
@@ -1,35 +1,33 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activemodel (3.2.8)
5
- activesupport (= 3.2.8)
4
+ activemodel (3.2.11)
5
+ activesupport (= 3.2.11)
6
6
  builder (~> 3.0.0)
7
- activerecord (3.2.8)
8
- activemodel (= 3.2.8)
9
- activesupport (= 3.2.8)
7
+ activerecord (3.2.11)
8
+ activemodel (= 3.2.11)
9
+ activesupport (= 3.2.11)
10
10
  arel (~> 3.0.2)
11
11
  tzinfo (~> 0.3.29)
12
- activesupport (3.2.8)
12
+ activesupport (3.2.11)
13
13
  i18n (~> 0.6)
14
14
  multi_json (~> 1.0)
15
15
  arel (3.0.2)
16
16
  builder (3.0.4)
17
17
  i18n (0.6.1)
18
- mocha (0.9.11)
19
- rake
20
- multi_json (1.3.7)
21
- rake (0.8.7)
22
- rcov (0.9.9)
18
+ mocha (0.9.12)
19
+ multi_json (1.5.0)
20
+ rake (10.0.3)
23
21
  sqlite3 (1.3.6)
24
- tzinfo (0.3.33)
22
+ tzinfo (0.3.35)
25
23
  will_paginate (3.0.3)
26
24
 
27
25
  PLATFORMS
28
26
  ruby
29
27
 
30
28
  DEPENDENCIES
31
- activerecord
32
- mocha
33
- rcov
29
+ activerecord (~> 3.2.9)
30
+ mocha (~> 0.9.11)
31
+ rake
34
32
  sqlite3 (~> 1.3.5)
35
33
  will_paginate (~> 3.0.3)
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007 - 2012 Douglas Shearer
1
+ Copyright (c) 2007 - 2013 Douglas Shearer
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -18,9 +18,9 @@ app with no dependencies and minimal setup.
18
18
 
19
19
  === Installation
20
20
 
21
- ==== Add to your gemfile
21
+ ==== Add to your Gemfile
22
22
 
23
- gem install acts_as_indexed
23
+ gem 'acts_as_indexed'
24
24
 
25
25
  Run <tt>bundle install</tt>. Done.
26
26
 
data/Rakefile CHANGED
@@ -1,27 +1,39 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
3
 
4
- desc 'Default: run unit tests.'
4
+ desc 'Default: run all tests.'
5
5
  task :default => :test
6
6
 
7
- desc 'Test the acts_as_indexed plugin.'
7
+ desc 'Run all tests.'
8
8
  Rake::TestTask.new(:test) do |t|
9
9
  t.libs << 'test'
10
10
  t.libs << 'lib'
11
- t.pattern = 'test/**/*_test.rb'
11
+ t.test_files = FileList['test/integration/*_test.rb', 'test/unit/*_test.rb']
12
12
  t.verbose = true
13
13
  end
14
14
 
15
- namespace :rcov do
16
- desc "Generate a coverage report in coverage/"
17
- task :gen do
18
- sh "rcov --output coverage test/*_test.rb"
19
- end
15
+ desc 'Run unit tests.'
16
+ Rake::TestTask.new('test:unit') do |t|
17
+ t.libs << 'test'
18
+ t.libs << 'lib'
19
+ t.pattern = 'test/unit/*_test.rb'
20
+ t.verbose = true
21
+ end
20
22
 
21
- desc "Remove generated coverage files."
22
- task :clobber do
23
- sh "rm -rdf coverage"
24
- end
23
+ desc 'Run integration tests.'
24
+ Rake::TestTask.new('test:integration') do |t|
25
+ t.libs << 'test'
26
+ t.libs << 'lib'
27
+ t.pattern = 'test/integration/*_test.rb'
28
+ t.verbose = true
29
+ end
30
+
31
+ desc 'Run performance tests.'
32
+ Rake::TestTask.new('test:performance') do |t|
33
+ t.libs << 'test'
34
+ t.libs << 'lib'
35
+ t.pattern = 'test/performance/*_test.rb'
36
+ t.verbose = true
25
37
  end
26
38
 
27
39
  begin
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.1
1
+ 0.8.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "acts_as_indexed"
8
- s.version = "0.8.1"
8
+ s.version = "0.8.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Douglas F Shearer"]
12
- s.date = "2012-12-21"
12
+ s.date = "2013-01-27"
13
13
  s.description = "Acts As Indexed is a plugin which provides a pain-free way to add fulltext search to your Ruby on Rails app"
14
14
  s.email = "dougal.s@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -42,19 +42,24 @@ Gem::Specification.new do |s|
42
42
  "lib/acts_as_indexed/tokenizer.rb",
43
43
  "lib/will_paginate_search.rb",
44
44
  "rails/init.rb",
45
- "test/abstract_unit.rb",
46
- "test/acts_as_indexed_test.rb",
47
- "test/configuration_test.rb",
48
- "test/database.yml",
45
+ "test/config/database.yml",
46
+ "test/db/schema.rb",
49
47
  "test/fixtures/post.rb",
50
48
  "test/fixtures/posts.yml",
51
- "test/pre_tokenizer_test.rb",
52
- "test/schema.rb",
53
- "test/search_atom_test.rb",
54
- "test/search_index_test.rb",
55
- "test/token_normalizer_test.rb",
56
- "test/tokenizer_test.rb",
57
- "test/will_paginate_search_test.rb"
49
+ "test/integration/acts_as_indexed_test.rb",
50
+ "test/integration/will_paginate_search_test.rb",
51
+ "test/integration_test_helper.rb",
52
+ "test/performance/query_performance_test.rb",
53
+ "test/performance/record_addition_performance_test.rb",
54
+ "test/performance/record_removal_performance_test.rb",
55
+ "test/performance/record_update_performance_test.rb",
56
+ "test/unit/configuration_test.rb",
57
+ "test/unit/pre_tokenizer_test.rb",
58
+ "test/unit/search_atom_test.rb",
59
+ "test/unit/search_index_test.rb",
60
+ "test/unit/token_normalizer_test.rb",
61
+ "test/unit/tokenizer_test.rb",
62
+ "test/unit_test_helper.rb"
58
63
  ]
59
64
  s.homepage = "http://github.com/dougal/acts_as_indexed"
60
65
  s.require_paths = ["lib"]
@@ -1,8 +1,9 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "rake"
4
- gem "mocha", "~> 0.9.11"
5
- gem "sqlite3", "~> 1.3.5"
6
- gem "activerecord", "~> 2.3.14"
7
- gem "will_paginate", "~> 3.0.3"
8
-
3
+ group :test do
4
+ gem "rake"
5
+ gem "mocha", "~> 0.9.11"
6
+ gem "sqlite3", "~> 1.3.5"
7
+ gem "activerecord", "~> 2.3.14"
8
+ gem "will_paginate", "~> 3.0.3"
9
+ end
@@ -1,7 +1,9 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "rake"
4
- gem "mocha", "~> 0.9.11"
5
- gem "sqlite3", "~> 1.3.5"
6
- gem "activerecord", "~> 3.0.17"
7
- gem "will_paginate", "~> 3.0.3"
3
+ group :test do
4
+ gem "rake"
5
+ gem "mocha", "~> 0.9.11"
6
+ gem "sqlite3", "~> 1.3.5"
7
+ gem "activerecord", "~> 3.0.17"
8
+ gem "will_paginate", "~> 3.0.3"
9
+ end
@@ -1,7 +1,9 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "rake"
4
- gem "mocha", "~> 0.9.11"
5
- gem "sqlite3", "~> 1.3.5"
6
- gem "activerecord", "~> 3.1.8"
7
- gem "will_paginate", "~> 3.0.3"
3
+ group :test do
4
+ gem "rake"
5
+ gem "mocha", "~> 0.9.11"
6
+ gem "sqlite3", "~> 1.3.5"
7
+ gem "activerecord", "~> 3.1.8"
8
+ gem "will_paginate", "~> 3.0.3"
9
+ end
@@ -1,7 +1,9 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "rake"
4
- gem "mocha", "~> 0.9.11"
5
- gem "sqlite3", "~> 1.3.5"
6
- gem "activerecord", "~> 3.2.9"
7
- gem "will_paginate", "~> 3.0.3"
3
+ group :test do
4
+ gem "rake"
5
+ gem "mocha", "~> 0.9.11"
6
+ gem "sqlite3", "~> 1.3.5"
7
+ gem "activerecord", "~> 3.2.9"
8
+ gem "will_paginate", "~> 3.0.3"
9
+ end
@@ -182,7 +182,7 @@ module ActsAsIndexed
182
182
  if a_score == b_score
183
183
  a_id <=> b_id
184
184
  else
185
- a_score <=> b_score
185
+ b_score <=> a_score # We want the records with better relevance first.
186
186
  end
187
187
 
188
188
  }
@@ -87,6 +87,12 @@ module ActsAsIndexed #:nodoc:
87
87
  # atom.
88
88
  def weightings(records_size)
89
89
  out = ActiveSupport::OrderedHash.new
90
+
91
+ ## phurni 2012-09-21 when records_size is exactly the @records.size (all records are matches), the Math.log would
92
+ ## return 0 which means the frequency (pos.size) will have no effect. Cheat to make it like the matching
93
+ ## record is one less, so that we still can weight on frequency.
94
+ matching_records_size = (records_size == @records.size ? @records.size - 1 : @records.size)
95
+
90
96
  @records.each do |r_id, pos|
91
97
 
92
98
  # Fixes a bug when the records_size is zero. i.e. The only record
@@ -99,8 +105,9 @@ module ActsAsIndexed #:nodoc:
99
105
  # weighting = frequency * log (records.size / records_with_atom)
100
106
  ## parndt 2010/05/03 changed to records_size.to_f to avoid -Infinity Errno::ERANGE exceptions
101
107
  ## which would happen for example Math.log(1 / 20) == -Infinity but Math.log(1.0 / 20) == -2.99573227355399
102
- out[r_id] = pos.size * Math.log(records_size.to_f / @records.size)
108
+ out[r_id] = pos.size * Math.log(records_size.to_f / matching_records_size)
103
109
  end
110
+
104
111
  out
105
112
  end
106
113
 
@@ -15,7 +15,7 @@ module ActsAsIndexed #:nodoc:
15
15
 
16
16
  # Adds +record+ to the index.
17
17
  def add_record(record)
18
- return unless @if_proc.call(record)
18
+ return unless allow_indexing?(record)
19
19
 
20
20
  condensed_record = condense_record(record)
21
21
  atoms = add_occurences(condensed_record, record.id)
@@ -29,7 +29,7 @@ module ActsAsIndexed #:nodoc:
29
29
  records_count = 0
30
30
 
31
31
  records.each do |record|
32
- next unless @if_proc.call(record)
32
+ next unless allow_indexing?(record)
33
33
  records_count += 1
34
34
 
35
35
  condensed_record = condense_record(record)
@@ -48,8 +48,15 @@ module ActsAsIndexed #:nodoc:
48
48
  end
49
49
 
50
50
  def update_record(record_new, record_old)
51
- remove_record(record_old)
52
- add_record(record_new)
51
+ if !record_unchanged?(record_new, record_old)
52
+ remove_record(record_old)
53
+ add_record(record_new)
54
+
55
+ # Always try to remove the record if it is non-indexable, in case proc
56
+ # makes use of any methods or attributes exteral of the record.
57
+ elsif !allow_indexing?(record_new)
58
+ remove_record(record_old)
59
+ end
53
60
  end
54
61
 
55
62
  # Returns an array of IDs for records matching +query+.
@@ -90,6 +97,20 @@ module ActsAsIndexed #:nodoc:
90
97
 
91
98
  private
92
99
 
100
+ # The record is unchanged for our purposes if all the fields are the same
101
+ # and the if_proc returns the same result for both.
102
+ def record_unchanged?(record_new, record_old)
103
+ # NOTE: Using the dirty state would be great here, but it doesn't keep track of
104
+ # in-place changes.
105
+
106
+ allow_indexing?(record_old) == allow_indexing?(record_new) &&
107
+ !@fields.map { |field| record_old.send(field) == record_new.send(field) }.include?(false)
108
+ end
109
+
110
+ def allow_indexing?(record)
111
+ @if_proc.call(record)
112
+ end
113
+
93
114
  def merge_query_results(results1, results2)
94
115
  # Return the other if one is empty.
95
116
  return results1 if results2.empty?
@@ -1,3 +1,5 @@
1
+ require 'thread'
2
+
1
3
  module ActsAsIndexed #:nodoc:
2
4
  class Storage
3
5
 
File without changes
File without changes
@@ -1,4 +1,4 @@
1
- require 'abstract_unit'
1
+ require 'integration_test_helper.rb'
2
2
 
3
3
  class ActsAsIndexedTest < ActiveSupport::TestCase
4
4
  fixtures :posts
@@ -52,8 +52,8 @@ class ActsAsIndexedTest < ActiveSupport::TestCase
52
52
  queries = {
53
53
  nil => [],
54
54
  '' => [],
55
- 'ship' => [6,5],
56
- 'crane' => [5,6],
55
+ 'ship' => [5, 6], # 5 has 3/4 occurences, 6 has 1/4.
56
+ 'crane' => [6, 5], # 6 has 2/3 occurences, 5 has 1/3.
57
57
  'foo' => [6],
58
58
  'foo ship' => [6],
59
59
  'ship foo' => [6]
@@ -93,28 +93,19 @@ class ActsAsIndexedTest < ActiveSupport::TestCase
93
93
  run_queries(queries)
94
94
  end
95
95
 
96
- def test_scoped_negative_quoted_queries
97
- queries = {
98
- 'crane -"crane ship"' => [6],
99
- '-"crane big"' => []
100
- }
101
-
102
- run_queries(queries)
103
- end
104
-
105
96
  def test_start_queries
106
97
  queries = {
107
- 'ship ^crane' => [6,5],
108
- '^crane ship' => [6,5],
109
- '^ship ^crane' => [6,5],
110
- '^crane ^ship' => [6,5],
111
- '^ship crane' => [6,5],
112
- 'crane ^ship' => [6,5],
113
- '^crane' => [5,6] ,
114
- '^cran' => [5,6],
115
- '^cra' => [5,6],
116
- '^cr' => [4,5,6],
117
- '^c' => [1,2,3,4,5,6],
98
+ 'ship ^crane' => [5, 6], # 5 has 3/4 + 2/3 = 17/12, 6 has 1/4 + 1/3 = 7/12
99
+ '^crane ship' => [5, 6], # 5 has 3/4 + 2/3 = 17/12, 6 has 1/4 + 1/3 = 7/12
100
+ '^ship ^crane' => [5, 6], # 5 has 3/4 + 2/3 = 17/12, 6 has 1/4 + 1/3 = 7/12
101
+ '^crane ^ship' => [5, 6], # 5 has 3/4 + 2/3 = 17/12, 6 has 1/4 + 1/3 = 7/12
102
+ '^ship crane' => [5, 6], # 5 has 3/4 + 2/3 = 17/12, 6 has 1/4 + 1/3 = 7/12
103
+ 'crane ^ship' => [5, 6], # 5 has 3/4 + 2/3 = 17/12, 6 has 1/4 + 1/3 = 7/12
104
+ '^crane' => [6, 5], # 6 has 2/3 occurences, 5 has 1/3.
105
+ '^cran' => [6, 5], # 6 has 2/3 occurences, 5 has 1/3.
106
+ '^cra' => [6, 5], # 6 has 2/3 occurences, 5 has 1/3.
107
+ '^cr' => [6, 4, 5], # 6 has 2/4, 4 has 1/4, 5 has 1/4.
108
+ '^c' => [5, 2, 1, 3, 6, 4], # 5 has 9/25, 2 has 8/25, 1 has 1/25, 3 has 2/25, 6 has 2/25, 5 has 1/25.
118
109
  '^notthere' => []
119
110
  }
120
111
 
@@ -123,18 +114,18 @@ class ActsAsIndexedTest < ActiveSupport::TestCase
123
114
 
124
115
  def test_start_quoted_queries
125
116
  queries = {
126
- '^"crane" ship' => [6,5],
127
- 'ship ^"crane"' => [6,5],
117
+ '^"crane" ship' => [5, 6], # 5 has 3/4 + 2/3 = 17/12, 6 has 1/4 + 1/3 = 7/12
118
+ 'ship ^"crane"' => [5, 6], # 5 has 3/4 + 2/3 = 17/12, 6 has 1/4 + 1/3 = 7/12
128
119
  '^"crane ship"' => [5],
129
120
  '^"crane shi"' => [5],
130
121
  '^"crane sh"' => [5],
131
122
  '^"crane s"' => [5],
132
- '^"crane "' => [5,6],
133
- '^"crane"' => [5,6],
134
- '^"cran"' => [5,6],
135
- '^"cra"' => [5,6],
136
- '^"cr"' => [4,5,6],
137
- '^"c"' => [1,2,3,4,5,6],
123
+ '^"crane "' => [6, 5], # 6 has 2/3 occurences, 5 has 1/3.
124
+ '^"crane"' => [6, 5], # 6 has 2/3 occurences, 5 has 1/3.
125
+ '^"cran"' => [6, 5], # 6 has 2/3 occurences, 5 has 1/3.
126
+ '^"cra"' => [6, 5], # 6 has 2/3 occurences, 5 has 1/3.
127
+ '^"cr"' => [6, 4, 5], # 6 has 2/4, 4 has 1/4, 5 has 1/4.
128
+ '^"c"' => [5, 2, 1, 3, 6, 4] # 5 has 9/25, 2 has 8/25, 1 has 1/25, 3 has 2/25, 6 has 2/25, 5 has 1/25.
138
129
  }
139
130
 
140
131
  run_queries(queries)
@@ -146,16 +137,16 @@ class ActsAsIndexedTest < ActiveSupport::TestCase
146
137
  # The offending assertions are not run in CI as a result.
147
138
  def test_find_options
148
139
  # limit.
149
- assert_equal [4], Post.find_with_index('^cr', { :limit => 1 }, :ids_only => true)
150
- assert_equal [4], Post.find_with_index('^cr', { :limit => 1 }).map{ |r| r.id }
140
+ assert_equal [6], Post.find_with_index('^cr', { :limit => 1 }, :ids_only => true)
141
+ assert_equal [6], Post.find_with_index('^cr', { :limit => 1 }).map{ |r| r.id }
151
142
 
152
143
  # offset
153
- assert_equal [5,6], Post.find_with_index('^cr', { :offset => 1 }, :ids_only => true)
154
- assert_equal [5,6], Post.find_with_index('^cr', { :offset => 1 }).map{ |r| r.id }
144
+ assert_equal [4, 5], Post.find_with_index('^cr', { :offset => 1 }, :ids_only => true)
145
+ assert_equal [4, 5], Post.find_with_index('^cr', { :offset => 1 }).map{ |r| r.id }
155
146
 
156
147
  # limit and offset
157
- assert_equal [5], Post.find_with_index('^cr', { :limit => 1, :offset => 1 }, :ids_only => true)
158
- assert_equal [5], Post.find_with_index('^cr', { :limit => 1, :offset => 1 }).map{ |r| r.id }
148
+ assert_equal [4], Post.find_with_index('^cr', { :limit => 1, :offset => 1 }, :ids_only => true)
149
+ assert_equal [4], Post.find_with_index('^cr', { :limit => 1, :offset => 1 }).map{ |r| r.id }
159
150
 
160
151
  # order
161
152
  assert_equal [6,5,4,3,2,1], Post.find_with_index('^c', { :order => 'id desc' }).map{ |r| r.id }
@@ -190,7 +181,7 @@ class ActsAsIndexedTest < ActiveSupport::TestCase
190
181
  assert_equal(expected_message, error.message)
191
182
  end
192
183
 
193
- # When a atom already in a record is duplicated, it removes
184
+ # When a atom already in a record is duplicated, it should not remove
194
185
  # all records with that same atom from the index.
195
186
  def test_update_record_bug
196
187
  p = Post.find(6)
@@ -251,15 +242,28 @@ class ActsAsIndexedTest < ActiveSupport::TestCase
251
242
  assert_equal 2, Post.find_with_index('crane',{},{ :no_query_cache => true, :ids_only => true}).size
252
243
  end
253
244
 
254
- # If an index doesn't exist, and an if proc is supplied, and the proc is false, then nothing happens
245
+ # If a record is not in the index, and is updated, it should still not be in the index.
255
246
  def test_update_if_not_in
256
247
  Post.acts_as_indexed :fields => [:title, :body], :if => Proc.new { |post| post.visible }
257
248
  destroy_index
258
249
 
259
- assert_equal 1, Post.find_with_index('crane', {}, { :no_query_cache => true, :ids_only => true}).size
260
- p = Post.find(5)
261
- assert p.update_attributes(:visible => false)
262
- assert_equal 1, Post.find_with_index('crane',{},{ :no_query_cache => true, :ids_only => true}).size
250
+ assert_equal [6], Post.find_with_index('crane', {}, { :no_query_cache => true, :ids_only => true})
251
+
252
+ posts(:wikipedia_article_5).update_attributes(:title => 'A new title')
253
+ assert_equal [6], Post.find_with_index('crane',{},{ :no_query_cache => true, :ids_only => true})
254
+ end
255
+
256
+ def test_update_if_with_external_proc
257
+ external_truth = true
258
+ Post.acts_as_indexed :fields => [:title, :body], :if => Proc.new { |post| external_truth }
259
+ destroy_index
260
+
261
+ assert_equal [6], Post.find_with_index('foo', {}, { :no_query_cache => true, :ids_only => true})
262
+
263
+ # When the proc returns false, on update, the post should be removed from the index.
264
+ external_truth = false
265
+ posts(:article_similar_to_5).save
266
+ assert_equal [], Post.find_with_index('foo', {}, { :no_query_cache => true, :ids_only => true})
263
267
  end
264
268
 
265
269
  def test_case_insensitive
@@ -1,4 +1,4 @@
1
- require 'abstract_unit'
1
+ require 'integration_test_helper.rb'
2
2
 
3
3
  class WillPaginateSearchTest < ActiveSupport::TestCase
4
4
  fixtures :posts
@@ -11,9 +11,9 @@ class WillPaginateSearchTest < ActiveSupport::TestCase
11
11
 
12
12
  def test_paginate_search
13
13
 
14
- assert_equal [1,2,3,4,5,6], paginate_search(1, 10)
15
- assert_equal [1,2,3], paginate_search(1, 3)
16
- assert_equal [4,5,6], paginate_search(2, 3)
14
+ assert_equal [5, 2, 1, 3, 6, 4], paginate_search(1, 10)
15
+ assert_equal [5, 2, 1], paginate_search(1, 3)
16
+ assert_equal [3, 6, 4], paginate_search(2, 3)
17
17
  end
18
18
 
19
19
  private
@@ -7,6 +7,8 @@ require 'active_record'
7
7
  require 'active_record/fixtures'
8
8
  require 'mocha'
9
9
 
10
+ puts "ActiveRecord version is #{ActiveRecord::VERSION::STRING}"
11
+
10
12
  # Mock out the required environment variables.
11
13
  # Do this before requiring AAI.
12
14
  class Rails
@@ -26,11 +28,11 @@ test_path = Pathname.new(File.expand_path('../', __FILE__))
26
28
  require test_path.parent.join('lib', 'acts_as_indexed').to_s
27
29
 
28
30
  ActiveRecord::Base.logger = Logger.new(test_path.join('test.log').to_s)
29
- ActiveRecord::Base.configurations = YAML::load(IO.read(test_path.join('database.yml').to_s))
31
+ ActiveRecord::Base.configurations = YAML::load(IO.read(test_path.join('config', 'database.yml').to_s))
30
32
  ActiveRecord::Base.establish_connection(ENV['DB'] || 'sqlite3')
31
33
 
32
34
  # Load Schema
33
- load(test_path.join('schema.rb').to_s)
35
+ load(test_path.join('db', 'schema.rb').to_s)
34
36
 
35
37
  # Load model.
36
38
  $LOAD_PATH.unshift(test_path.join('fixtures').to_s)
@@ -0,0 +1,47 @@
1
+ require 'integration_test_helper.rb'
2
+ require 'benchmark'
3
+
4
+ class RecordUpdatePerformanceTest < ActiveSupport::TestCase
5
+ fixtures :posts
6
+
7
+ QUERIES = [
8
+ ['crane', 10_000],
9
+ ['foo', 10_000],
10
+ ['-foo', 10_000],
11
+ ['-foo crane', 10_000],
12
+ ['foo "crane ship', 10_000],
13
+ ['crane -"crane ship"', 10_000],
14
+ ['^cran', 10_000],
15
+ ['ship ^cran', 10_000],
16
+ ['^"crane" ship', 10_000],
17
+ ['^"crane"', 10_000]
18
+ ]
19
+
20
+ def teardown
21
+ # need to do this to work with the :if Proc tests.
22
+ Post.acts_as_indexed :fields => [:title, :body]
23
+ destroy_index
24
+ end
25
+
26
+ def test_queries_without_cache
27
+ QUERIES.each do |query|
28
+ run_query(*query, true)
29
+ end
30
+ end
31
+
32
+ def test_queries_with_cache
33
+ QUERIES.each do |query|
34
+ run_query(query[0], query[1], false)
35
+ end
36
+ end
37
+
38
+ def run_query(query, iterations, no_query_cache)
39
+ puts "Benchmarking query #{query} with#{ 'out' if no_query_cache } cache (x #{iterations})"
40
+ puts Benchmark.measure {
41
+ iterations.times do
42
+ Post.find_with_index(query, {}, :ids_only => true, :no_query_cache => no_query_cache)
43
+ end
44
+ }
45
+ end
46
+
47
+ end
@@ -0,0 +1,23 @@
1
+ require 'integration_test_helper.rb'
2
+ require 'benchmark'
3
+
4
+ class RecordAdditionPerformanceTest < ActiveSupport::TestCase
5
+ fixtures :posts
6
+
7
+ def teardown
8
+ # need to do this to work with the :if Proc tests.
9
+ Post.acts_as_indexed :fields => [:title, :body]
10
+ destroy_index
11
+ end
12
+
13
+ def test_addition
14
+ iterations = 200
15
+ puts "Record addition (x #{ iterations })"
16
+
17
+ puts Benchmark.measure {
18
+ iterations.times do
19
+ posts(:wikipedia_article_1).dup.save
20
+ end
21
+ }
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require 'integration_test_helper.rb'
2
+ require 'benchmark'
3
+
4
+ class RecordRemovalPerformanceTest < ActiveSupport::TestCase
5
+ fixtures :posts
6
+
7
+ def teardown
8
+ # need to do this to work with the :if Proc tests.
9
+ Post.acts_as_indexed :fields => [:title, :body]
10
+ destroy_index
11
+ end
12
+
13
+ def test_removal
14
+ iterations = 200
15
+ puts "Record removal (x #{ iterations })"
16
+
17
+ (iterations - Post.count).times do
18
+ posts(:wikipedia_article_1).dup.save
19
+ end
20
+
21
+ puts Benchmark.measure { Post.destroy_all }
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ require 'integration_test_helper.rb'
2
+ require 'benchmark'
3
+
4
+ class RecordUpdatePerformanceTest < ActiveSupport::TestCase
5
+ fixtures :posts
6
+
7
+ def teardown
8
+ # need to do this to work with the :if Proc tests.
9
+ Post.acts_as_indexed :fields => [:title, :body]
10
+ destroy_index
11
+ end
12
+
13
+ def test_unchanged
14
+ iterations = 10_000
15
+ puts "Unchanged record update (x #{ iterations })"
16
+
17
+ puts Benchmark.measure { iterations.times { posts(:wikipedia_article_1).save } }
18
+ end
19
+
20
+ def test_changed
21
+ iterations = 200
22
+ puts "Changed record update (x #{ iterations })"
23
+
24
+ original_title = posts(:wikipedia_article_1).title
25
+
26
+ puts Benchmark.measure {
27
+ iterations.times do |index|
28
+ posts(:wikipedia_article_1).update_attribute(:title, "#{original_title} #{ index }")
29
+ end
30
+ }
31
+ end
32
+
33
+ def test_unchanged_with_false_if_proc
34
+ iterations = 200
35
+ puts "Unchanged record update with false if_proc (x #{ iterations })"
36
+
37
+ Post.acts_as_indexed :fields => [:title, :body], :if => Proc.new { |post| post.visible }
38
+
39
+
40
+ puts Benchmark.measure { iterations.times { posts(:wikipedia_article_5).save } }
41
+ end
42
+ end
@@ -1,4 +1,4 @@
1
- require 'abstract_unit'
1
+ require 'unit_test_helper.rb'
2
2
  include ActsAsIndexed
3
3
 
4
4
  class ConfigurationTest < ActiveSupport::TestCase
@@ -1,4 +1,4 @@
1
- require 'abstract_unit'
1
+ require 'unit_test_helper.rb'
2
2
  include ActsAsIndexed
3
3
 
4
4
  class PreTokenizerTest < ActiveSupport::TestCase
@@ -1,4 +1,4 @@
1
- require 'abstract_unit'
1
+ require 'unit_test_helper.rb'
2
2
  include ActsAsIndexed
3
3
 
4
4
  class SearchAtomTest < ActiveSupport::TestCase
@@ -1,4 +1,4 @@
1
- require 'abstract_unit'
1
+ require 'unit_test_helper.rb'
2
2
  include ActsAsIndexed
3
3
 
4
4
  class SearchIndexTest < ActiveSupport::TestCase
@@ -1,4 +1,4 @@
1
- require 'abstract_unit'
1
+ require 'unit_test_helper.rb'
2
2
  include ActsAsIndexed
3
3
 
4
4
  class TokenNormalizerTest < ActiveSupport::TestCase
@@ -1,4 +1,4 @@
1
- require 'abstract_unit'
1
+ require 'unit_test_helper.rb'
2
2
  include ActsAsIndexed
3
3
 
4
4
  class TokenizerTest < ActiveSupport::TestCase
@@ -0,0 +1,20 @@
1
+ require 'test/unit'
2
+ require 'fileutils'
3
+ require 'rubygems'
4
+
5
+ require 'bundler/setup'
6
+ require 'mocha'
7
+
8
+ # Mock out the required environment variables.
9
+ # Do this before requiring AAI.
10
+ class Rails
11
+ def self.root
12
+ Pathname.new(Dir.pwd)
13
+ end
14
+ def self.env
15
+ 'test'
16
+ end
17
+ end
18
+
19
+ test_path = Pathname.new(File.expand_path('../', __FILE__))
20
+ require test_path.parent.join('lib', 'acts_as_indexed').to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_indexed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-21 00:00:00.000000000 Z
12
+ date: 2013-01-27 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Acts As Indexed is a plugin which provides a pain-free way to add fulltext
15
15
  search to your Ruby on Rails app
@@ -45,19 +45,24 @@ files:
45
45
  - lib/acts_as_indexed/tokenizer.rb
46
46
  - lib/will_paginate_search.rb
47
47
  - rails/init.rb
48
- - test/abstract_unit.rb
49
- - test/acts_as_indexed_test.rb
50
- - test/configuration_test.rb
51
- - test/database.yml
48
+ - test/config/database.yml
49
+ - test/db/schema.rb
52
50
  - test/fixtures/post.rb
53
51
  - test/fixtures/posts.yml
54
- - test/pre_tokenizer_test.rb
55
- - test/schema.rb
56
- - test/search_atom_test.rb
57
- - test/search_index_test.rb
58
- - test/token_normalizer_test.rb
59
- - test/tokenizer_test.rb
60
- - test/will_paginate_search_test.rb
52
+ - test/integration/acts_as_indexed_test.rb
53
+ - test/integration/will_paginate_search_test.rb
54
+ - test/integration_test_helper.rb
55
+ - test/performance/query_performance_test.rb
56
+ - test/performance/record_addition_performance_test.rb
57
+ - test/performance/record_removal_performance_test.rb
58
+ - test/performance/record_update_performance_test.rb
59
+ - test/unit/configuration_test.rb
60
+ - test/unit/pre_tokenizer_test.rb
61
+ - test/unit/search_atom_test.rb
62
+ - test/unit/search_index_test.rb
63
+ - test/unit/token_normalizer_test.rb
64
+ - test/unit/tokenizer_test.rb
65
+ - test/unit_test_helper.rb
61
66
  homepage: http://github.com/dougal/acts_as_indexed
62
67
  licenses: []
63
68
  post_install_message: