cehoffman-acts_as_ferret 0.4.4

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 (162) hide show
  1. data/LICENSE +20 -0
  2. data/README +68 -0
  3. data/bin/aaf_install +23 -0
  4. data/config/ferret_server.yml +24 -0
  5. data/doc/README.win32 +23 -0
  6. data/doc/demo/README +154 -0
  7. data/doc/demo/README_DEMO +23 -0
  8. data/doc/demo/Rakefile +10 -0
  9. data/doc/demo/app/controllers/admin/backend_controller.rb +14 -0
  10. data/doc/demo/app/controllers/admin_area_controller.rb +4 -0
  11. data/doc/demo/app/controllers/application.rb +5 -0
  12. data/doc/demo/app/controllers/contents_controller.rb +49 -0
  13. data/doc/demo/app/controllers/searches_controller.rb +8 -0
  14. data/doc/demo/app/helpers/admin/backend_helper.rb +2 -0
  15. data/doc/demo/app/helpers/application_helper.rb +3 -0
  16. data/doc/demo/app/helpers/content_helper.rb +2 -0
  17. data/doc/demo/app/helpers/search_helper.rb +2 -0
  18. data/doc/demo/app/models/comment.rb +48 -0
  19. data/doc/demo/app/models/content.rb +12 -0
  20. data/doc/demo/app/models/content_base.rb +28 -0
  21. data/doc/demo/app/models/search.rb +19 -0
  22. data/doc/demo/app/models/shared_index1.rb +3 -0
  23. data/doc/demo/app/models/shared_index2.rb +3 -0
  24. data/doc/demo/app/models/special_content.rb +3 -0
  25. data/doc/demo/app/models/stats.rb +20 -0
  26. data/doc/demo/app/views/admin/backend/search.rhtml +18 -0
  27. data/doc/demo/app/views/contents/_form.rhtml +10 -0
  28. data/doc/demo/app/views/contents/edit.rhtml +9 -0
  29. data/doc/demo/app/views/contents/index.rhtml +24 -0
  30. data/doc/demo/app/views/contents/new.rhtml +8 -0
  31. data/doc/demo/app/views/contents/show.rhtml +8 -0
  32. data/doc/demo/app/views/layouts/application.html.erb +17 -0
  33. data/doc/demo/app/views/searches/_content.html.erb +2 -0
  34. data/doc/demo/app/views/searches/search.html.erb +20 -0
  35. data/doc/demo/config/boot.rb +109 -0
  36. data/doc/demo/config/database.yml +38 -0
  37. data/doc/demo/config/environment.rb +69 -0
  38. data/doc/demo/config/environments/development.rb +16 -0
  39. data/doc/demo/config/environments/production.rb +19 -0
  40. data/doc/demo/config/environments/test.rb +21 -0
  41. data/doc/demo/config/ferret_server.yml +18 -0
  42. data/doc/demo/config/lighttpd.conf +40 -0
  43. data/doc/demo/config/routes.rb +9 -0
  44. data/doc/demo/db/development_structure.sql +15 -0
  45. data/doc/demo/db/migrate/001_initial_migration.rb +18 -0
  46. data/doc/demo/db/migrate/002_add_type_to_contents.rb +9 -0
  47. data/doc/demo/db/migrate/003_create_shared_index1s.rb +11 -0
  48. data/doc/demo/db/migrate/004_create_shared_index2s.rb +11 -0
  49. data/doc/demo/db/migrate/005_special_field.rb +9 -0
  50. data/doc/demo/db/migrate/006_create_stats.rb +15 -0
  51. data/doc/demo/db/schema.sql +18 -0
  52. data/doc/demo/doc/README_FOR_APP +2 -0
  53. data/doc/demo/doc/howto.txt +70 -0
  54. data/doc/demo/public/.htaccess +40 -0
  55. data/doc/demo/public/404.html +8 -0
  56. data/doc/demo/public/500.html +8 -0
  57. data/doc/demo/public/dispatch.cgi +10 -0
  58. data/doc/demo/public/dispatch.fcgi +24 -0
  59. data/doc/demo/public/dispatch.rb +10 -0
  60. data/doc/demo/public/favicon.ico +0 -0
  61. data/doc/demo/public/images/rails.png +0 -0
  62. data/doc/demo/public/index.html +277 -0
  63. data/doc/demo/public/robots.txt +1 -0
  64. data/doc/demo/public/stylesheets/scaffold.css +74 -0
  65. data/doc/demo/script/about +3 -0
  66. data/doc/demo/script/breakpointer +3 -0
  67. data/doc/demo/script/console +3 -0
  68. data/doc/demo/script/destroy +3 -0
  69. data/doc/demo/script/ferret_server +10 -0
  70. data/doc/demo/script/generate +3 -0
  71. data/doc/demo/script/performance/benchmarker +3 -0
  72. data/doc/demo/script/performance/profiler +3 -0
  73. data/doc/demo/script/plugin +3 -0
  74. data/doc/demo/script/process/inspector +3 -0
  75. data/doc/demo/script/process/reaper +3 -0
  76. data/doc/demo/script/process/spawner +3 -0
  77. data/doc/demo/script/process/spinner +3 -0
  78. data/doc/demo/script/runner +3 -0
  79. data/doc/demo/script/server +3 -0
  80. data/doc/demo/test/fixtures/comments.yml +12 -0
  81. data/doc/demo/test/fixtures/contents.yml +13 -0
  82. data/doc/demo/test/fixtures/remote_contents.yml +9 -0
  83. data/doc/demo/test/fixtures/shared_index1s.yml +7 -0
  84. data/doc/demo/test/fixtures/shared_index2s.yml +7 -0
  85. data/doc/demo/test/functional/admin/backend_controller_test.rb +35 -0
  86. data/doc/demo/test/functional/contents_controller_test.rb +81 -0
  87. data/doc/demo/test/functional/searches_controller_test.rb +71 -0
  88. data/doc/demo/test/smoke/drb_smoke_test.rb +321 -0
  89. data/doc/demo/test/smoke/process_stats.rb +21 -0
  90. data/doc/demo/test/test_helper.rb +30 -0
  91. data/doc/demo/test/unit/comment_test.rb +217 -0
  92. data/doc/demo/test/unit/content_test.rb +705 -0
  93. data/doc/demo/test/unit/ferret_result_test.rb +24 -0
  94. data/doc/demo/test/unit/multi_index_test.rb +329 -0
  95. data/doc/demo/test/unit/remote_index_test.rb +23 -0
  96. data/doc/demo/test/unit/shared_index1_test.rb +108 -0
  97. data/doc/demo/test/unit/shared_index2_test.rb +13 -0
  98. data/doc/demo/test/unit/sort_test.rb +21 -0
  99. data/doc/demo/test/unit/special_content_test.rb +25 -0
  100. data/doc/demo/vendor/plugins/will_paginate/LICENSE +18 -0
  101. data/doc/demo/vendor/plugins/will_paginate/README +108 -0
  102. data/doc/demo/vendor/plugins/will_paginate/Rakefile +23 -0
  103. data/doc/demo/vendor/plugins/will_paginate/init.rb +21 -0
  104. data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/collection.rb +45 -0
  105. data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/core_ext.rb +44 -0
  106. data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/finder.rb +159 -0
  107. data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb +95 -0
  108. data/doc/demo/vendor/plugins/will_paginate/test/array_pagination_test.rb +23 -0
  109. data/doc/demo/vendor/plugins/will_paginate/test/boot.rb +27 -0
  110. data/doc/demo/vendor/plugins/will_paginate/test/console +10 -0
  111. data/doc/demo/vendor/plugins/will_paginate/test/finder_test.rb +219 -0
  112. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/admin.rb +3 -0
  113. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/companies.yml +24 -0
  114. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/company.rb +23 -0
  115. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/developer.rb +11 -0
  116. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/developers_projects.yml +13 -0
  117. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/project.rb +4 -0
  118. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/projects.yml +7 -0
  119. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/replies.yml +20 -0
  120. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/reply.rb +5 -0
  121. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/schema.sql +44 -0
  122. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/topic.rb +19 -0
  123. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/topics.yml +30 -0
  124. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/user.rb +2 -0
  125. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/users.yml +35 -0
  126. data/doc/demo/vendor/plugins/will_paginate/test/helper.rb +42 -0
  127. data/doc/demo/vendor/plugins/will_paginate/test/lib/activerecord_test_connector.rb +64 -0
  128. data/doc/demo/vendor/plugins/will_paginate/test/lib/load_fixtures.rb +10 -0
  129. data/doc/demo/vendor/plugins/will_paginate/test/pagination_test.rb +136 -0
  130. data/doc/monit-example +22 -0
  131. data/init.rb +24 -0
  132. data/install.rb +18 -0
  133. data/lib/act_methods.rb +147 -0
  134. data/lib/acts_as_ferret.rb +584 -0
  135. data/lib/ar_mysql_auto_reconnect_patch.rb +41 -0
  136. data/lib/blank_slate.rb +53 -0
  137. data/lib/bulk_indexer.rb +38 -0
  138. data/lib/class_methods.rb +270 -0
  139. data/lib/ferret_extensions.rb +188 -0
  140. data/lib/ferret_find_methods.rb +141 -0
  141. data/lib/ferret_result.rb +53 -0
  142. data/lib/ferret_server.rb +238 -0
  143. data/lib/index.rb +99 -0
  144. data/lib/instance_methods.rb +171 -0
  145. data/lib/local_index.rb +205 -0
  146. data/lib/more_like_this.rb +217 -0
  147. data/lib/multi_index.rb +126 -0
  148. data/lib/rdig_adapter.rb +148 -0
  149. data/lib/remote_functions.rb +23 -0
  150. data/lib/remote_index.rb +54 -0
  151. data/lib/remote_multi_index.rb +20 -0
  152. data/lib/search_results.rb +50 -0
  153. data/lib/server_manager.rb +58 -0
  154. data/lib/unix_daemon.rb +64 -0
  155. data/lib/without_ar.rb +52 -0
  156. data/rakefile +141 -0
  157. data/recipes/aaf_recipes.rb +114 -0
  158. data/script/ferret_daemon +94 -0
  159. data/script/ferret_server +10 -0
  160. data/script/ferret_service +178 -0
  161. data/tasks/ferret.rake +22 -0
  162. metadata +258 -0
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'gruff'
3
+
4
+ search = Stats.compute :search
5
+ write = Stats.compute :write
6
+
7
+
8
+ g = chart "aaf DRb (write performance)"
9
+ g.data :avg, write.map{|r| r[:avg]}
10
+ g.data :stddev, write.map{|r| r[:stddev]}
11
+ g.write "write_averages.png"
12
+
13
+ g = chart "aaf DRb (search performance)"
14
+ g.data :average, search.map{ |r| r[:avg] }
15
+ g.data :stddev, search.map{ |r| r[:stddev] }
16
+ g.write "search_averages.png"
17
+
18
+ g = chart "aaf DRb (search performance (medians))"
19
+ g.data :search_median, search.map{ |r| r[:median] }
20
+ g.write "search_medians.png"
21
+
@@ -0,0 +1,30 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
3
+ require 'test_help'
4
+
5
+ class Test::Unit::TestCase
6
+ # Transactional fixtures accelerate your tests by wrapping each test method
7
+ # in a transaction that's rolled back on completion. This ensures that the
8
+ # test database remains unchanged so your fixtures don't have to be reloaded
9
+ # between every test method. Fewer database queries means faster tests.
10
+ #
11
+ # Read Mike Clark's excellent walkthrough at
12
+ # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
13
+ #
14
+ # Every Active Record database supports transactions except MyISAM tables
15
+ # in MySQL. Turn off transactional fixtures in this case; however, if you
16
+ # don't care one way or the other, switching from MyISAM to InnoDB tables
17
+ # is recommended.
18
+ #self.use_transactional_fixtures = true
19
+ self.use_transactional_fixtures = false
20
+
21
+ # Instantiated fixtures are slow, but give you @david where otherwise you
22
+ # would need people(:david). If you don't want to migrate your existing
23
+ # test cases which use the @david style and don't mind the speed hit (each
24
+ # instantiated fixtures translates to a database query per test method),
25
+ # then set this back to true.
26
+ self.use_instantiated_fixtures = false
27
+
28
+ # Add more helper methods to be used by all tests here...
29
+ end
30
+
@@ -0,0 +1,217 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class CommentTest < Test::Unit::TestCase
4
+ fixtures :comments
5
+
6
+ def setup
7
+ Comment.rebuild_index
8
+ end
9
+
10
+ # Replace this with your real tests.
11
+ def test_truth
12
+ assert_kind_of Comment, comments(:first)
13
+ end
14
+
15
+ def test_issue_220_index_false_as_false
16
+ c = Comment.new :content => false
17
+ assert_equal false, c.content
18
+ assert_equal 'false', c.content_for_field_name(:content)
19
+ assert_equal 'false', c.to_doc[:content]
20
+ c.save
21
+ assert_equal c, Comment.find_with_ferret('content:false').first
22
+ end
23
+
24
+ def test_if_option
25
+ c = Comment.new :content => 'do not index'
26
+ c.save
27
+ assert_equal 0, Comment.find_with_ferret('do not index').total_hits
28
+ end
29
+
30
+ def test_analyzer
31
+ c = Comment.create! :content => 'a fax modem'
32
+ assert_equal 0, Comment.find_with_ferret('fax').size
33
+ assert_equal 1, Comment.find_with_ferret('modem').size
34
+ end
35
+
36
+ def test_class_index_dir
37
+ assert Comment.aaf_configuration[:index_dir] =~ %r{^#{RAILS_ROOT}/index/test/comment}
38
+ end
39
+
40
+ def test_aliased_field
41
+ res = Comment.find_with_ferret 'aliased:regarding'
42
+ assert_equal 1, res.total_hits
43
+ assert_equal comments(:comment_for_c2), res.first
44
+ end
45
+
46
+ def test_search_for_id
47
+ # don't search the id field by default:
48
+ assert Comment.find_with_ferret('3').empty?
49
+ # explicit query for id field works:
50
+ assert_equal 3, Comment.find_with_ferret('id:3').first.id
51
+ end
52
+
53
+ #def test_reloadable
54
+ # assert ! Comment.reloadable?
55
+ #end
56
+
57
+ # tests the automatic building of an index when none exists
58
+ # delete index/test/* before running rake to make this useful
59
+ def test_automatic_index_build
60
+ # TODO: check why this fails, but querying for 'comment fixture' works.
61
+ # maybe different analyzers at index creation and searching time ?
62
+ #comments_from_ferret = Comment.find_with_ferret('"comment from fixture"')
63
+ comments_from_ferret = Comment.find_with_ferret('comment fixture')
64
+ assert_equal 2, comments_from_ferret.size
65
+ assert comments_from_ferret.include?(comments(:first))
66
+ assert comments_from_ferret.include?(comments(:another))
67
+ end
68
+
69
+ def test_rebuild_index
70
+ Comment.aaf_index.ferret_index.query_delete('comment')
71
+ comments_from_ferret = Comment.find_with_ferret('comment AND fixture')
72
+ assert comments_from_ferret.empty?
73
+ Comment.rebuild_index
74
+ comments_from_ferret = Comment.find_with_ferret('comment AND fixture')
75
+ assert_equal 2, comments_from_ferret.size
76
+ end
77
+
78
+ def test_total_hits
79
+ comments_from_ferret = Comment.find_with_ferret('comment AND fixture', :limit => 1)
80
+ assert_equal 1, comments_from_ferret.size
81
+ assert_equal 2, comments_from_ferret.total_hits
82
+
83
+ comments_from_ferret = Comment.find_with_ferret('comment AND fixture', {}, :conditions => 'id != 1')
84
+ assert_equal 1, comments_from_ferret.size
85
+ assert_equal 1, comments_from_ferret.total_hits
86
+ end
87
+
88
+ def test_score
89
+ comments_from_ferret = Comment.find_with_ferret('comment AND fixture', :limit => 1)
90
+ assert comments_from_ferret.first
91
+ assert comments_from_ferret.first.ferret_score > 0
92
+ end
93
+
94
+ def test_find_all
95
+ 20.times do |i|
96
+ Comment.create( :author => 'multi-commenter', :content => "This is multicomment no #{i}" )
97
+ end
98
+ assert_equal 10, (res = Comment.find_with_ferret('multicomment')).size
99
+ assert_equal 20, res.total_hits
100
+ assert_equal 15, (res = Comment.find_with_ferret('multicomment', :limit => 15)).size
101
+ assert_equal 20, res.total_hits
102
+ assert_equal 20, (res = Comment.find_with_ferret('multicomment', :limit => :all)).size
103
+ assert_equal 20, res.total_hits
104
+ end
105
+
106
+ # tests the custom to_doc method defined in comment.rb
107
+ def test_custom_to_doc
108
+ top_docs = Comment.aaf_index.ferret_index.search('"from fixture"')
109
+ #top_docs = Comment.ferret_index.search('"comment from fixture"')
110
+ assert_equal 2, top_docs.total_hits
111
+ doc = Comment.aaf_index.ferret_index.doc(top_docs.hits[0].doc)
112
+ # check for the special field added by the custom to_doc method
113
+ assert_not_nil doc[:added]
114
+ # still a valid int ?
115
+ assert doc[:added].to_i > 0
116
+ end
117
+
118
+ def test_find_with_ferret
119
+ comment = Comment.create( :author => 'john doe', :content => 'This is a useless comment' )
120
+ comment2 = Comment.create( :author => 'another', :content => 'content' )
121
+
122
+ comments_from_ferret = Comment.find_with_ferret('anoth* OR jo*')
123
+ assert_equal 2, comments_from_ferret.size
124
+ assert comments_from_ferret.include?(comment)
125
+ assert comments_from_ferret.include?(comment2)
126
+
127
+ # find options
128
+ comments_from_ferret = Comment.find_with_ferret('anoth* OR jo*', {}, :conditions => ["id=?",comment2.id])
129
+ assert_equal 1, comments_from_ferret.size
130
+ assert comments_from_ferret.include?(comment2)
131
+
132
+ comments_from_ferret = Comment.find_with_ferret('lorem ipsum not here')
133
+ assert comments_from_ferret.empty?
134
+
135
+ comments_from_ferret = Comment.find_with_ferret('another')
136
+ assert_equal 1, comments_from_ferret.size
137
+ assert_equal comment2.id, comments_from_ferret.first.id
138
+
139
+ comments_from_ferret = Comment.find_with_ferret('doe')
140
+ assert_equal 1, comments_from_ferret.size
141
+ assert_equal comment.id, comments_from_ferret.first.id
142
+
143
+ comments_from_ferret = Comment.find_with_ferret('useless')
144
+ assert_equal 1, comments_from_ferret.size
145
+ assert_equal comment.id, comments_from_ferret.first.id
146
+
147
+ # no monkeys here
148
+ comments_from_ferret = Comment.find_with_ferret('monkey')
149
+ assert comments_from_ferret.empty?
150
+
151
+ # multiple terms are ANDed by default...
152
+ comments_from_ferret = Comment.find_with_ferret('monkey comment')
153
+ assert comments_from_ferret.empty?
154
+ # ...unless you connect them by OR
155
+ comments_from_ferret = Comment.find_with_ferret('monkey OR comment')
156
+ assert_equal 3, comments_from_ferret.size
157
+ assert comments_from_ferret.include?(comment)
158
+ assert comments_from_ferret.include?(comments(:first))
159
+ assert comments_from_ferret.include?(comments(:another))
160
+
161
+ # multiple terms, each term has to occur in a document to be found,
162
+ # but they may occur in different fields
163
+ comments_from_ferret = Comment.find_with_ferret('useless john')
164
+ assert_equal 1, comments_from_ferret.size
165
+ assert_equal comment.id, comments_from_ferret.first.id
166
+
167
+
168
+ # search for an exact string by enclosing it in "
169
+ comments_from_ferret = Comment.find_with_ferret('"useless john"')
170
+ assert comments_from_ferret.empty?
171
+ comments_from_ferret = Comment.find_with_ferret('"useless comment"')
172
+ assert_equal 1, comments_from_ferret.size
173
+ assert_equal comment.id, comments_from_ferret.first.id
174
+
175
+ comment.destroy
176
+ comment2.destroy
177
+ end
178
+
179
+ # fixed with Ferret 0.9.6
180
+ def test_stopwords_ferret_bug
181
+ i = Ferret::I.new(:or_default => false, :default_field => '*' )
182
+ d = Ferret::Document.new
183
+ d[:id] = '1'
184
+ d[:content] = 'Move or shake'
185
+ i << d
186
+ hits = i.search 'move AND or AND shake'
187
+ assert_equal 1, hits.total_hits
188
+ hits = i.search 'move AND nothere AND shake'
189
+ assert_equal 0, hits.total_hits
190
+ hits = i.search 'move AND shake'
191
+ assert_equal 1, hits.total_hits
192
+ hits = i.search 'move OR shake'
193
+ assert_equal 1, hits.total_hits
194
+ hits = i.search '+move +the +shake'
195
+ assert_equal 1, hits.total_hits
196
+
197
+ hits = i.search 'move nothere'
198
+ assert_equal 0, hits.total_hits
199
+ end
200
+
201
+ def test_stopwords
202
+ comment = Comment.create( :author => 'john doe', :content => 'Move or shake' )
203
+ ['move shake', 'Move shake', 'move Shake', 'move or shake', 'move the shake'].each do |q|
204
+ comments_from_ferret = Comment.find_with_ferret(q)
205
+ assert_equal comment, comments_from_ferret.first, "query #{q} failed"
206
+ end
207
+ comment.destroy
208
+ end
209
+
210
+ def test_array_conditions_combining
211
+ comments_from_ferret = Comment.find_with_ferret('comment AND fixture', {}, :conditions => [ 'id IN (?)', [ 2, 3 ] ])
212
+ assert_equal 1, comments_from_ferret.size
213
+ assert_equal 1, comments_from_ferret.total_hits
214
+ end
215
+
216
+
217
+ end
@@ -0,0 +1,705 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'pp'
3
+ require 'fileutils'
4
+
5
+ class ContentTest < Test::Unit::TestCase
6
+ include Ferret::Index
7
+ include Ferret::Search
8
+ fixtures :contents, :comments
9
+
10
+ def setup
11
+ #make sure the fixtures are in the index
12
+ FileUtils.rm_f 'index/test/'
13
+ Comment.rebuild_index
14
+ ContentBase.rebuild_index
15
+ raise "missing fixtures" unless ContentBase.count > 2
16
+
17
+ @another_content = Content.new( :title => 'Another Content item',
18
+ :description => 'this is not the title' )
19
+ @another_content.save
20
+ @comment = @another_content.comments.create(:author => 'john doe', :content => 'This is a useless comment')
21
+ @comment2 = @another_content.comments.create(:author => 'another', :content => 'content')
22
+ @another_content.save # to update comment_count in ferret-index
23
+ end
24
+
25
+ def teardown
26
+ ContentBase.find(:all).each { |c| c.destroy }
27
+ Comment.find(:all).each { |c| c.destroy }
28
+ end
29
+
30
+ def test_limit_all
31
+ res = Content.find_with_ferret '*', { :limit => :all }, :conditions => ['lower(title) like ?', 'content'], :order => 'contents.description'
32
+ end
33
+
34
+ def test_find_with_ferret_on_has_many_assoc
35
+ c = contents(:first)
36
+ comments = c.comments.find_with_ferret 'second'
37
+ assert_equal 1, comments.size
38
+ assert_equal comments(:another), comments.first
39
+ end
40
+
41
+ def test_total_hits_on_has_many_assoc
42
+ c = contents(:first)
43
+ assert_equal 2, Comment.find_with_ferret('second OR regarding').total_hits
44
+ assert_equal 1, c.comments.find_with_ferret('second OR regarding').total_hits
45
+ end
46
+
47
+ def test_include_option
48
+ assert_equal 1, Content.find_with_ferret('description', {}, :include => :comments).size
49
+ end
50
+
51
+ def test_lazy_loading
52
+ results = Content.find_with_ferret 'description', :lazy => true
53
+ assert_equal 1, results.size
54
+ result = results.first
55
+ class << result
56
+ attr_accessor :ar_record # so we have a chance to check if it's been loaded...
57
+ end
58
+ assert ActsAsFerret::FerretResult === result
59
+ assert_equal 'A useless description', result.description
60
+ assert_nil result.instance_variable_get(:@ar_record)
61
+ assert_equal 'My Title', result.title
62
+ assert_not_nil result.ar_record
63
+ end
64
+
65
+ def test_ticket_69
66
+ content = Content.create(:title => 'aksjeselskap test',
67
+ :description => 'content about various norwegian companies. A.s. Haakon, Åmot Håndverksenter A/S, Øye Trelast AS')
68
+
69
+ # these still fail: 'A\S', 'AS'
70
+ [ '"A.s. Haakon"', 'A.s. Haakon', 'Åmot A/S', 'A/S' ].each do |query|
71
+ assert_equal content, Content.find_with_ferret(query).first, query
72
+ end
73
+ end
74
+
75
+ def test_highlight
76
+ highlight = @another_content.highlight('title')
77
+ assert_equal 1, highlight.size
78
+ assert_equal "this is not the <em>title</em>", highlight.first
79
+
80
+ highlight = @another_content.highlight('title', :field => :description)
81
+ assert_equal 1, highlight.size
82
+ assert_equal "this is not the <em>title</em>", highlight.first
83
+ end
84
+
85
+ def test_highlight_new_record
86
+ c = Content.create :title => 'the title', :description => 'the new description'
87
+ highlight = c.highlight('new')
88
+ assert_equal 1, highlight.size
89
+ assert_equal "the <em>new</em> description", highlight.first
90
+
91
+ c1 = Content.find_with_ferret('new description').first
92
+ assert_equal c, c1
93
+ highlight = c1.highlight('new')
94
+ assert_equal 1, highlight.size
95
+ assert_equal "the <em>new</em> description", highlight.first
96
+ end
97
+
98
+ def test_disable_ferret_once
99
+ content = Content.new(:title => 'should not get saved', :description => 'do not find me')
100
+ assert_raises (ArgumentError) do
101
+ content.disable_ferret(:wrong)
102
+ end
103
+ assert content.ferret_enabled?
104
+ content.disable_ferret
105
+ assert !content.ferret_enabled?
106
+ content.save
107
+ assert content.ferret_enabled?
108
+ assert Content.find_with_ferret('"find me"').empty?
109
+
110
+ content.save
111
+ assert content.ferret_enabled?
112
+ assert_equal content, Content.find_with_ferret('"find me"').first
113
+ end
114
+
115
+ def test_ferret_disable_always
116
+ content = Content.new(:title => 'should not get saved', :description => 'do not find me')
117
+ assert content.ferret_enabled?
118
+ content.disable_ferret(:always)
119
+ assert !content.ferret_enabled?
120
+ 2.times do
121
+ content.save
122
+ assert Content.find_with_ferret('"find me"').empty?
123
+ assert !content.ferret_enabled?
124
+ end
125
+ content.ferret_enable
126
+ assert content.ferret_enabled?
127
+ content.save
128
+ assert content.ferret_enabled?
129
+ assert_equal content, Content.find_with_ferret('"find me"').first
130
+ end
131
+
132
+ def test_disable_ferret_on_class_level
133
+ Content.disable_ferret
134
+ content = Content.new(:title => 'should not get saved', :description => 'do not find me')
135
+ assert !content.ferret_enabled?
136
+ assert !Content.ferret_enabled?
137
+ 2.times do
138
+ content.save
139
+ assert Content.find_with_ferret('"find me"').empty?
140
+ assert !Content.ferret_enabled?
141
+ assert !content.ferret_enabled?
142
+ end
143
+ content.enable_ferret # record level enabling should have no effect on class level
144
+ assert !Content.ferret_enabled?
145
+ assert !content.ferret_enabled?
146
+ Content.enable_ferret
147
+ assert Content.ferret_enabled?
148
+ assert content.ferret_enabled?
149
+
150
+ content.save
151
+ assert content.ferret_enabled?
152
+ assert Content.ferret_enabled?
153
+ assert_equal content, Content.find_with_ferret('"find me"').first
154
+ end
155
+
156
+ def test_disable_ferret_block
157
+ content = Content.new(:title => 'should not get saved', :description => 'do not find me')
158
+ content.disable_ferret do
159
+ 2.times do
160
+ content.save
161
+ assert Content.find_with_ferret('"find me"').empty?
162
+ assert !content.ferret_enabled?
163
+ end
164
+ end
165
+ assert content.ferret_enabled?
166
+ assert Content.find_with_ferret('"find me"').empty?
167
+
168
+ content.disable_ferret(:index_when_finished) do
169
+ 2.times do
170
+ content.save
171
+ assert Content.find_with_ferret('"find me"').empty?
172
+ assert !content.ferret_enabled?
173
+ end
174
+ end
175
+ assert content.ferret_enabled?
176
+ assert_equal content, Content.find_with_ferret('"find me"').first
177
+ end
178
+
179
+ def test_disable_ferret_on_class_level_block
180
+ content = Content.new(:title => 'should not get saved', :description => 'do not find me')
181
+ Content.disable_ferret do
182
+ 2.times do
183
+ content.save
184
+ assert Content.find_with_ferret('"find me"').empty?
185
+ assert !content.ferret_enabled?
186
+ assert !Content.ferret_enabled?
187
+ end
188
+ end
189
+ assert content.ferret_enabled?
190
+ assert Content.ferret_enabled?
191
+ assert Content.find_with_ferret('"find me"').empty?
192
+ content.save
193
+ assert_equal content, Content.find_with_ferret('"find me"').first
194
+ end
195
+
196
+ # ticket 178
197
+ def test_records_for_rebuild_works_with_includes
198
+ size = Content.count
199
+ Content.send( :with_scope, :find => { :include => :comments } ) do
200
+ Content.records_for_rebuild do |records, offset|
201
+ assert_equal size, records.size
202
+ end
203
+ end
204
+ end
205
+
206
+ def test_records_for_bulk_index
207
+ Content.disable_ferret do
208
+ more_contents
209
+ end
210
+ min = Content.find(:all, :order => 'id asc').first.id
211
+ Content.records_for_bulk_index([min, min+1, min+2, min+3, min+4, min+6], 10) do |records, offset|
212
+ assert_equal 6, records.size
213
+ end
214
+ end
215
+
216
+ def test_bulk_index_no_optimize
217
+ Content.disable_ferret do
218
+ more_contents
219
+ end
220
+
221
+ assert Content.find_with_ferret('title').empty?
222
+ min = Content.find(:all, :order => 'id asc').first.id
223
+ Content.bulk_index(min, min+1, min+2, min+3, min+4, min+6, :optimize => false)
224
+ assert_equal 6, Content.find_with_ferret('title').size
225
+ end
226
+
227
+ def test_bulk_index
228
+ Content.disable_ferret do
229
+ more_contents
230
+ end
231
+
232
+ assert Content.find_with_ferret('title').empty?
233
+ min = Content.find(:all, :order => 'id asc').first.id
234
+ Content.bulk_index([min, min+1, min+2, min+3, min+4, min+6])
235
+ assert_equal 6, Content.find_with_ferret('title').size
236
+ end
237
+
238
+
239
+ def test_unicode
240
+ content = Content.new(:title => 'Title with some Ümläuts - äöü',
241
+ :description => 'look - an ß')
242
+ content.save
243
+ result = Content.find_with_ferret('äöü')
244
+ assert_equal content, result.first
245
+ result = Content.find_with_ferret('üml*')
246
+ assert_equal content, result.first
247
+ result = Content.find_with_ferret('ß')
248
+ assert_equal content, result.first
249
+ end
250
+
251
+ def test_content_for_field_name
252
+ c = 'lorem ipsum dolor sit amet. lorem.'
253
+ @c1 = Content.new( :title => 'Content item 1',
254
+ :description => c )
255
+ assert_equal c, @c1.content_for_field_name(:description)
256
+ end
257
+
258
+ def test_document_number
259
+ c = 'lorem ipsum dolor sit amet. lorem.'
260
+ c1 = Content.new( :title => 'Content item 1',
261
+ :description => c )
262
+ c1.save
263
+ fi = Content.aaf_index.ferret_index
264
+ assert fi
265
+ hits = fi.search('title:"Content item 1"')
266
+ assert_equal 1, hits.total_hits
267
+ expected_doc_num = hits.hits.first.doc
268
+ assert_equal c, fi[expected_doc_num][:description]
269
+ doc_num = c1.document_number
270
+ assert_equal expected_doc_num, doc_num
271
+ assert_equal c, fi[doc_num][:description]
272
+ end
273
+
274
+ def test_more_like_this
275
+ assert Content.find_with_ferret('lorem ipsum').empty?
276
+ @c1 = Content.new( :title => 'Content item 1',
277
+ :description => 'lorem ipsum dolor sit amet. lorem.' )
278
+ @c1.save
279
+ @c2 = Content.new( :title => 'Content item 2',
280
+ :description => 'lorem ipsum dolor sit amet. lorem ipsum.' )
281
+ @c2.save
282
+ assert_equal 2, Content.find_with_ferret('lorem ipsum').size
283
+ similar = @c1.more_like_this(:field_names => [:description], :min_doc_freq => 1, :min_term_freq => 1)
284
+ assert_equal 1, similar.size
285
+ assert_equal @c2, similar.first
286
+ end
287
+
288
+ def test_more_like_this_new_record
289
+ assert Content.find_with_ferret('lorem ipsum').empty?
290
+ @c1 = Content.new( :title => 'Content item 1',
291
+ :description => 'lorem ipsum dolor sit amet. lorem.' )
292
+ @c2 = Content.new( :title => 'Content item 2',
293
+ :description => 'lorem ipsum dolor sit amet. lorem ipsum.' )
294
+ @c2.save
295
+ assert_equal 1, Content.find_with_ferret('lorem ipsum').size
296
+ similar = @c1.more_like_this(:field_names => [:description], :min_doc_freq => 1, :min_term_freq => 1)
297
+ assert_equal 1, similar.size
298
+ assert_equal @c2, similar.first
299
+ end
300
+
301
+ def test_class_index_dir
302
+ assert Content.aaf_configuration[:index_dir] =~ %r{^#{RAILS_ROOT}/index/test/content_base}
303
+ end
304
+
305
+ def test_update
306
+ contents_from_ferret = Content.find_with_ferret('useless')
307
+ assert_equal 1, contents_from_ferret.size
308
+ assert_equal contents(:first).id, contents_from_ferret.first.id
309
+ contents(:first).description = 'Updated description, still useless'
310
+ contents(:first).save
311
+ contents_from_ferret = Content.find_with_ferret('useless')
312
+ assert_equal 1, contents_from_ferret.size
313
+ assert_equal contents(:first).id, contents_from_ferret.first.id
314
+ contents_from_ferret = Content.find_with_ferret('updated AND description')
315
+ assert_equal 1, contents_from_ferret.size
316
+ assert_equal contents(:first).id, contents_from_ferret.first.id
317
+ contents_from_ferret = Content.find_with_ferret('updated OR description')
318
+ assert_equal 1, contents_from_ferret.size
319
+ assert_equal contents(:first).id, contents_from_ferret.first.id
320
+ end
321
+
322
+ def test_indexed_method
323
+ assert_equal 2, @another_content.comment_count
324
+ assert_equal 2, contents(:first).comment_count
325
+ assert_equal 1, contents(:another).comment_count
326
+ # retrieve all content objects having 2 comments
327
+ result = Content.find_with_ferret('comment_count:2')
328
+ # TODO check why this range query returns 3 results
329
+ #result = Content.find_with_ferret('comment_count:[2 TO 1000]')
330
+ # p result
331
+ assert_equal 2, result.size
332
+ assert result.include?(@another_content)
333
+ assert result.include?(contents(:first))
334
+ end
335
+
336
+ def test_sorting
337
+ sorting = [ Ferret::Search::SortField.new(:id, :reverse => true) ]
338
+ result = Content.find_with_ferret('comment_count:2', :sort => sorting)
339
+ assert !result.empty?
340
+ assert result.first.id > result.last.id
341
+
342
+ sorting = [ Ferret::Search::SortField.new(:id) ]
343
+ result = Content.find_with_ferret('comment_count:2', :sort => sorting)
344
+ assert result.first.id < result.last.id
345
+
346
+ sorting = Ferret::Search::Sort.new([ Ferret::Search::SortField.new(:id),
347
+ Ferret::Search::SortField::SCORE ],
348
+ :reverse => true)
349
+
350
+
351
+ result = Content.find_with_ferret('comment_count:2', :sort => sorting)
352
+ assert result.first.id > result.last.id
353
+ end
354
+
355
+ def test_sort_class
356
+ sorting = Ferret::Search::Sort.new(Ferret::Search::SortField.new(:id, :reverse => true))
357
+ result = Content.find_with_ferret('comment_count:2 OR comment_count:1', :sort => sorting)
358
+ assert result.size > 2
359
+ assert result.first.id > result.last.id
360
+ result = Content.find_with_ferret('comment_count:2 OR comment_count:1', :sort => sorting, :limit => 2)
361
+ assert_equal 2, result.size
362
+ assert result.first.id > result.last.id
363
+ end
364
+
365
+ def test_sort_with_limit
366
+ sorting = [ Ferret::Search::SortField.new(:id) ]
367
+ result = Content.find_with_ferret('comment_count:2 OR comment_count:1', :sort => sorting)
368
+ assert result.size > 2
369
+ assert result.first.id < result.last.id
370
+ result = Content.find_with_ferret('comment_count:2 OR comment_count:1', :sort => sorting, :limit => 2)
371
+ assert_equal 2, result.size
372
+ assert result.first.id < result.last.id
373
+
374
+ sorting = [ Ferret::Search::SortField.new(:id, :reverse => true) ]
375
+ result = Content.find_with_ferret('comment_count:2 OR comment_count:1', :sort => sorting)
376
+ assert result.size > 2
377
+ assert result.first.id > result.last.id
378
+ result = Content.find_with_ferret('comment_count:2 OR comment_count:1', :sort => sorting, :limit => 2)
379
+ assert_equal 2, result.size
380
+ assert result.first.id > result.last.id
381
+ end
382
+
383
+
384
+ def test_add_rebuilds_index
385
+ remove_index Content
386
+ Content.create(:title => 'another one', :description => 'description')
387
+ contents_from_ferret = Content.find_with_ferret('description:title')
388
+ assert_equal 1, contents_from_ferret.size
389
+ end
390
+ def test_find_rebuilds_index
391
+ remove_index Content
392
+ contents_from_ferret = Content.find_with_ferret('description:title')
393
+ assert_equal 1, contents_from_ferret.size
394
+ end
395
+
396
+ def test_total_hits
397
+ assert_equal 2, Content.total_hits('title:title OR description:title')
398
+ assert_equal 2, Content.total_hits('title:title OR description:title', :limit => 1)
399
+ end
400
+
401
+ def test_find_ids_with_ferret
402
+ total_hits, contents_from_ferret = Content.find_ids_with_ferret('title:title OR description:title')
403
+ assert_equal 2, contents_from_ferret.size
404
+ assert_equal 2, total_hits
405
+ #puts "first (id=#{contents_from_ferret.first[:id]}): #{contents_from_ferret.first[:score]}"
406
+ #puts "last (id=#{contents_from_ferret.last[:id]}): #{contents_from_ferret.last[:score]}"
407
+ assert_equal contents(:first).id, contents_from_ferret.first[:id].to_i
408
+ assert_equal @another_content.id, contents_from_ferret.last[:id].to_i
409
+ assert contents_from_ferret.first[:score] >= contents_from_ferret.last[:score]
410
+
411
+ # give description field higher boost:
412
+ total_hits, contents_from_ferret = Content.find_ids_with_ferret('title:title OR description:title^200')
413
+ assert_equal 2, contents_from_ferret.size
414
+ assert_equal 2, total_hits
415
+ #puts "first (id=#{contents_from_ferret.first[:id]}): #{contents_from_ferret.first[:score]}"
416
+ #puts "last (id=#{contents_from_ferret.last[:id]}): #{contents_from_ferret.last[:score]}"
417
+ assert_equal @another_content.id, contents_from_ferret.first[:id].to_i
418
+ assert_equal contents(:first).id, contents_from_ferret.last[:id].to_i
419
+ assert contents_from_ferret.first[:score] > contents_from_ferret.last[:score]
420
+
421
+ end
422
+
423
+ def test_find_with_ferret_boost
424
+ # give description field higher boost:
425
+ contents_from_ferret = Content.find_with_ferret('title:title OR description:title^200')
426
+ assert_equal 2, contents_from_ferret.size
427
+ assert_equal @another_content.id, contents_from_ferret.first.id
428
+ assert_equal contents(:first).id, contents_from_ferret.last.id
429
+ end
430
+
431
+ def test_default_and_queries
432
+ # multiple terms are ANDed by default...
433
+ contents_from_ferret = Content.find_with_ferret('monkey description')
434
+ assert contents_from_ferret.empty?
435
+ # ...unless you connect them by OR
436
+ contents_from_ferret = Content.find_with_ferret('monkey OR description')
437
+ assert_equal 1, contents_from_ferret.size
438
+ assert_equal contents(:first).id, contents_from_ferret.first.id
439
+
440
+ # multiple terms, each term has to occur in a document to be found,
441
+ # but they may occur in different fields
442
+ contents_from_ferret = Content.find_with_ferret('useless title')
443
+ assert_equal 1, contents_from_ferret.size
444
+ assert_equal contents(:first).id, contents_from_ferret.first.id
445
+ end
446
+
447
+ def test_find_with_ferret
448
+
449
+ contents_from_ferret = Content.find_with_ferret('lorem ipsum not here')
450
+ assert contents_from_ferret.empty?
451
+
452
+ contents_from_ferret = Content.find_with_ferret('title')
453
+ assert_equal 2, contents_from_ferret.size
454
+ # the title field has a higher boost value, so contents(:first) must be first in the list
455
+ assert_equal contents(:first).id, contents_from_ferret.first.id
456
+ assert_equal @another_content.id, contents_from_ferret.last.id
457
+
458
+
459
+
460
+ contents_from_ferret = Content.find_with_ferret('useless')
461
+ assert_equal 1, contents_from_ferret.size
462
+ assert_equal contents(:first).id, contents_from_ferret.first.id
463
+
464
+ # no monkeys here
465
+ contents_from_ferret = Content.find_with_ferret('monkey')
466
+ assert contents_from_ferret.empty?
467
+
468
+
469
+
470
+ # search for an exact string by enclosing it in "
471
+ contents_from_ferret = Content.find_with_ferret('"useless title"')
472
+ assert contents_from_ferret.empty?
473
+ contents_from_ferret = Content.find_with_ferret('"useless description"')
474
+ assert_equal 1, contents_from_ferret.size
475
+ assert_equal contents(:first).id, contents_from_ferret.first.id
476
+
477
+ # wildcard query
478
+ contents_from_ferret = Content.find_with_ferret('use*')
479
+ assert_equal 1, contents_from_ferret.size
480
+
481
+ # ferret-bug ? wildcard queries don't seem to get lowercased even when
482
+ # using StandardAnalyzer:
483
+ # contents_from_ferret = Content.find_with_ferret('Ti*')
484
+ # we should find both 'Title' and 'title'
485
+ # assert_equal 2, contents_from_ferret.size
486
+ # theory: :wild_lower parser option isn't used
487
+
488
+ contents_from_ferret = Content.find_with_ferret('ti*')
489
+ # this time we find both 'Title' and 'title'
490
+ assert_equal 2, contents_from_ferret.size
491
+
492
+ contents(:first).destroy
493
+ contents_from_ferret = Content.find_with_ferret('ti*')
494
+ # should find only one now
495
+ assert_equal 1, contents_from_ferret.size
496
+ assert_equal @another_content.id, contents_from_ferret.first.id
497
+ end
498
+
499
+ def test_find_with_ferret_options
500
+ # find options
501
+ contents_from_ferret = Content.find_with_ferret('title', {}, :conditions => ["id=?",contents(:first).id])
502
+ assert_equal 1, contents_from_ferret.size
503
+ assert_equal contents(:first), contents_from_ferret.first
504
+
505
+ # limit result set size to 1
506
+ contents_from_ferret = Content.find_with_ferret('title', :limit => 1)
507
+ assert_equal 1, contents_from_ferret.size
508
+ assert_equal contents(:first), contents_from_ferret.first
509
+
510
+ # limit result set size to 1, starting with the second result
511
+ contents_from_ferret = Content.find_with_ferret('title', :limit => 1, :offset => 1)
512
+ assert_equal 1, contents_from_ferret.size
513
+ assert_equal @another_content.id, contents_from_ferret.first.id
514
+
515
+ end
516
+
517
+ def test_pagination
518
+ more_contents
519
+
520
+ r = Content.find_with_ferret 'title', :per_page => 10, :sort => 'title'
521
+ assert_equal 30, r.total_hits
522
+ assert_equal 10, r.size
523
+ assert_equal "0", r.first.description
524
+ assert_equal "9", r.last.description
525
+ assert_equal 1, r.current_page
526
+ assert_equal 3, r.page_count
527
+
528
+ r = Content.find_with_ferret 'title', :page => '2', :per_page => 10, :sort => 'title'
529
+ assert_equal 30, r.total_hits
530
+ assert_equal 10, r.size
531
+ assert_equal "10", r.first.description
532
+ assert_equal "19", r.last.description
533
+ assert_equal 2, r.current_page
534
+ assert_equal 3, r.page_count
535
+
536
+ r = Content.find_with_ferret 'title', :page => 4, :per_page => 10, :sort => 'title'
537
+ assert_equal 30, r.total_hits
538
+ assert_equal 0, r.size
539
+ end
540
+
541
+ def test_limits_and_offsets
542
+ more_contents
543
+ r = Content.find_with_ferret 'title'
544
+ assert_equal 30, r.total_hits
545
+ assert_equal 10, r.size
546
+
547
+ r = Content.find_with_ferret 'title', :limit => :all
548
+ assert_equal 30, r.total_hits
549
+ assert_equal 30, r.size
550
+ end
551
+
552
+ def test_limits_and_offsets_with_ar_conditions
553
+ more_contents
554
+
555
+ r = Content.find_with_ferret 'title', { :limit => 10, :offset => 0 },
556
+ { :conditions => "description != '0'", :order => 'title ASC' }
557
+ assert_equal 29, r.total_hits
558
+ assert_equal 10, r.size
559
+ assert_equal "1", r.first.description
560
+ assert_equal "10", r.last.description
561
+
562
+ r = Content.find_with_ferret 'title', { :limit => 10, :offset => 10 },
563
+ { :conditions => "description != '0'", :order => 'title ASC' }
564
+ assert_equal 29, r.total_hits
565
+ assert_equal 10, r.size
566
+ assert_equal "11", r.first.description
567
+ assert_equal "20", r.last.description
568
+
569
+ r = Content.find_with_ferret 'title', { },
570
+ { :conditions => "description != '0'", :order => 'title ASC',
571
+ :limit => 10, :offset => 0 }
572
+ assert_equal 29, r.total_hits
573
+ assert_equal 10, r.size
574
+ assert_equal "1", r.first.description
575
+ assert_equal "10", r.last.description
576
+
577
+ r = Content.find_with_ferret 'title', { },
578
+ { :conditions => "description != '0'", :order => 'title ASC',
579
+ :limit => 10, :offset => 10 }
580
+ assert_equal 29, r.total_hits
581
+ assert_equal 10, r.size
582
+ assert_equal "11", r.first.description
583
+ assert_equal "20", r.last.description
584
+ end
585
+
586
+ def test_pagination_with_ar_conditions
587
+ more_contents
588
+
589
+ r = Content.find_with_ferret 'title', { :page => 1, :per_page => 10 },
590
+ { :conditions => "description != '0'", :order => 'title ASC' }
591
+ assert_equal 29, r.total_hits
592
+ assert_equal 10, r.size
593
+ assert_equal "1", r.first.description
594
+ assert_equal "10", r.last.description
595
+ assert_equal 1, r.current_page
596
+ assert_equal 3, r.page_count
597
+
598
+ r = Content.find_with_ferret 'title', { :page => 3, :per_page => 10 },
599
+ { :conditions => "description != '0'", :order => 'title ASC' }
600
+ assert_equal 9, r.size
601
+ assert_equal 29, r.total_hits
602
+ assert_equal "21", r.first.description
603
+ assert_equal "29", r.last.description
604
+ assert_equal 3, r.current_page
605
+ assert_equal 3, r.page_count
606
+ end
607
+
608
+ def test_pagination_with_ar_conditions_and_ferret_sort
609
+ more_contents
610
+
611
+ # r = Content.find_with_ferret 'title', { :page => 1, :per_page => 10,
612
+ # :sort => Ferret::Search::SortField.new(:id,
613
+ # :type => :integer,
614
+ # :reverse => true ) },
615
+ # { :conditions => "description != '0'" }
616
+ r = ActsAsFerret::find 'title', Content, { :page => 1, :per_page => 10,
617
+ :sort => Ferret::Search::SortField.new(:id,
618
+ :type => :integer,
619
+ :reverse => true ) },
620
+ { :conditions => "description != '29'" }
621
+ assert_equal 29, r.total_hits
622
+ assert_equal 10, r.size
623
+ assert_equal "28", r.first.description
624
+ assert_equal "19", r.last.description
625
+ assert_equal 1, r.current_page
626
+ assert_equal 3, r.page_count
627
+
628
+ r = Content.find_with_ferret 'title', { :page => 3, :per_page => 10 },
629
+ { :conditions => "description != '0'", :order => 'title ASC' }
630
+ assert_equal 9, r.size
631
+ assert_equal 29, r.total_hits
632
+ assert_equal "21", r.first.description
633
+ assert_equal "29", r.last.description
634
+ assert_equal 3, r.current_page
635
+ assert_equal 3, r.page_count
636
+ end
637
+
638
+ def test_pagination_with_more_conditions
639
+ more_contents
640
+
641
+ r = Content.find_with_ferret 'title -description:0', { :page => 1, :per_page => 10 },
642
+ { :conditions => "contents.description != '9'", :order => 'title ASC' }
643
+ assert_equal 28, r.total_hits
644
+ assert_equal 10, r.size
645
+ assert_equal "1", r.first.description
646
+ assert_equal "11", r.last.description
647
+ assert_equal 1, r.current_page
648
+ assert_equal 3, r.page_count
649
+ end
650
+
651
+ def test_reconnect_in_drb_mode
652
+ if ENV['AAF_REMOTE'] && Content.connection.is_a?(ActiveRecord::ConnectionAdapters::MysqlAdapter)
653
+ puts "have DRb and MySQL - doing db reconnect test"
654
+ Content.aaf_index.send(:db_disconnect!)
655
+ c = Content.create! :title => 'another one', :description => 'description'
656
+ assert_equal c, Content.find_with_ferret('another').first
657
+ else
658
+ assert true
659
+ end
660
+ end
661
+
662
+ def test_per_field_boost
663
+ Content.destroy_all
664
+ Content.create! :title => 'the title'
665
+ boosted = Content.new :title => 'the title'
666
+ boosted.title_boost = 100
667
+ boosted.save!
668
+ Content.create! :title => 'the title'
669
+ results = Content.find_with_ferret 'title:title'
670
+ assert_equal 3, results.size
671
+ assert_equal boosted.id, results.first.id
672
+ end
673
+
674
+ def test_per_document_boost
675
+ Content.destroy_all
676
+ Content.create! :title => 'the title'
677
+ boosted = Content.new :title => 'the title'
678
+ boosted.record_boost = 10
679
+ boosted.save!
680
+ Content.create! :title => 'the title'
681
+ results = Content.find_with_ferret 'title'
682
+ assert_equal 3, results.size
683
+ assert_equal boosted.id, results.first.id
684
+ end
685
+
686
+
687
+ protected
688
+
689
+ def more_contents(with_comments = false)
690
+ Comment.destroy_all if with_comments
691
+ Content.destroy_all
692
+ SpecialContent.destroy_all
693
+ 30.times do |i|
694
+ c = Content.create! :title => sprintf("title of Content %02d", i), :description => "#{i}"
695
+ c.comments.create! :content => sprintf("Comment for content %02d", i) if with_comments
696
+ end
697
+ end
698
+
699
+ def remove_index(clazz)
700
+ clazz.aaf_index.close # avoid io error when deleting the open index
701
+ FileUtils.rm_rf clazz.aaf_configuration[:index_dir]
702
+ assert !File.exists?("#{clazz.aaf_configuration[:index_dir]}/segments")
703
+ end
704
+
705
+ end