acts_as_indexed 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
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: