watson-acts_as_ferret 0.4.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/LICENSE +20 -0
  2. data/README +104 -0
  3. data/acts_as_ferret.gemspec +58 -0
  4. data/bin/aaf_install +29 -0
  5. data/config/ferret_server.yml +24 -0
  6. data/doc/README.win32 +23 -0
  7. data/doc/demo/README +154 -0
  8. data/doc/demo/README_DEMO +23 -0
  9. data/doc/demo/Rakefile +10 -0
  10. data/doc/demo/app/controllers/admin/backend_controller.rb +14 -0
  11. data/doc/demo/app/controllers/admin_area_controller.rb +4 -0
  12. data/doc/demo/app/controllers/application.rb +5 -0
  13. data/doc/demo/app/controllers/contents_controller.rb +49 -0
  14. data/doc/demo/app/controllers/searches_controller.rb +8 -0
  15. data/doc/demo/app/helpers/admin/backend_helper.rb +2 -0
  16. data/doc/demo/app/helpers/application_helper.rb +3 -0
  17. data/doc/demo/app/helpers/content_helper.rb +2 -0
  18. data/doc/demo/app/helpers/search_helper.rb +2 -0
  19. data/doc/demo/app/models/comment.rb +48 -0
  20. data/doc/demo/app/models/content.rb +12 -0
  21. data/doc/demo/app/models/content_base.rb +28 -0
  22. data/doc/demo/app/models/search.rb +19 -0
  23. data/doc/demo/app/models/shared_index1.rb +3 -0
  24. data/doc/demo/app/models/shared_index2.rb +3 -0
  25. data/doc/demo/app/models/special_content.rb +3 -0
  26. data/doc/demo/app/models/stats.rb +20 -0
  27. data/doc/demo/app/views/admin/backend/search.rhtml +18 -0
  28. data/doc/demo/app/views/contents/_form.rhtml +10 -0
  29. data/doc/demo/app/views/contents/edit.rhtml +9 -0
  30. data/doc/demo/app/views/contents/index.rhtml +24 -0
  31. data/doc/demo/app/views/contents/new.rhtml +8 -0
  32. data/doc/demo/app/views/contents/show.rhtml +8 -0
  33. data/doc/demo/app/views/layouts/application.html.erb +17 -0
  34. data/doc/demo/app/views/searches/_content.html.erb +2 -0
  35. data/doc/demo/app/views/searches/search.html.erb +20 -0
  36. data/doc/demo/config/boot.rb +109 -0
  37. data/doc/demo/config/database.yml +38 -0
  38. data/doc/demo/config/environment.rb +69 -0
  39. data/doc/demo/config/environments/development.rb +16 -0
  40. data/doc/demo/config/environments/production.rb +19 -0
  41. data/doc/demo/config/environments/test.rb +21 -0
  42. data/doc/demo/config/ferret_server.yml +18 -0
  43. data/doc/demo/config/lighttpd.conf +40 -0
  44. data/doc/demo/config/routes.rb +9 -0
  45. data/doc/demo/db/development_structure.sql +15 -0
  46. data/doc/demo/db/migrate/001_initial_migration.rb +18 -0
  47. data/doc/demo/db/migrate/002_add_type_to_contents.rb +9 -0
  48. data/doc/demo/db/migrate/003_create_shared_index1s.rb +11 -0
  49. data/doc/demo/db/migrate/004_create_shared_index2s.rb +11 -0
  50. data/doc/demo/db/migrate/005_special_field.rb +9 -0
  51. data/doc/demo/db/migrate/006_create_stats.rb +15 -0
  52. data/doc/demo/db/schema.sql +18 -0
  53. data/doc/demo/db/schema.sqlite +14 -0
  54. data/doc/demo/doc/README_FOR_APP +2 -0
  55. data/doc/demo/doc/howto.txt +70 -0
  56. data/doc/demo/public/404.html +8 -0
  57. data/doc/demo/public/500.html +8 -0
  58. data/doc/demo/public/dispatch.cgi +10 -0
  59. data/doc/demo/public/dispatch.fcgi +24 -0
  60. data/doc/demo/public/dispatch.rb +10 -0
  61. data/doc/demo/public/favicon.ico +0 -0
  62. data/doc/demo/public/images/rails.png +0 -0
  63. data/doc/demo/public/index.html +277 -0
  64. data/doc/demo/public/robots.txt +1 -0
  65. data/doc/demo/public/stylesheets/scaffold.css +74 -0
  66. data/doc/demo/script/about +3 -0
  67. data/doc/demo/script/breakpointer +3 -0
  68. data/doc/demo/script/console +3 -0
  69. data/doc/demo/script/destroy +3 -0
  70. data/doc/demo/script/ferret_server +10 -0
  71. data/doc/demo/script/generate +3 -0
  72. data/doc/demo/script/performance/benchmarker +3 -0
  73. data/doc/demo/script/performance/profiler +3 -0
  74. data/doc/demo/script/plugin +3 -0
  75. data/doc/demo/script/process/inspector +3 -0
  76. data/doc/demo/script/process/reaper +3 -0
  77. data/doc/demo/script/process/spawner +3 -0
  78. data/doc/demo/script/process/spinner +3 -0
  79. data/doc/demo/script/runner +3 -0
  80. data/doc/demo/script/server +3 -0
  81. data/doc/demo/test/fixtures/comments.yml +12 -0
  82. data/doc/demo/test/fixtures/contents.yml +13 -0
  83. data/doc/demo/test/fixtures/remote_contents.yml +9 -0
  84. data/doc/demo/test/fixtures/shared_index1s.yml +7 -0
  85. data/doc/demo/test/fixtures/shared_index2s.yml +7 -0
  86. data/doc/demo/test/functional/admin/backend_controller_test.rb +35 -0
  87. data/doc/demo/test/functional/contents_controller_test.rb +81 -0
  88. data/doc/demo/test/functional/searches_controller_test.rb +71 -0
  89. data/doc/demo/test/smoke/drb_smoke_test.rb +321 -0
  90. data/doc/demo/test/smoke/process_stats.rb +21 -0
  91. data/doc/demo/test/test_helper.rb +30 -0
  92. data/doc/demo/test/unit/comment_test.rb +217 -0
  93. data/doc/demo/test/unit/content_test.rb +705 -0
  94. data/doc/demo/test/unit/ferret_result_test.rb +24 -0
  95. data/doc/demo/test/unit/multi_index_test.rb +329 -0
  96. data/doc/demo/test/unit/remote_index_test.rb +23 -0
  97. data/doc/demo/test/unit/shared_index1_test.rb +108 -0
  98. data/doc/demo/test/unit/shared_index2_test.rb +13 -0
  99. data/doc/demo/test/unit/sort_test.rb +21 -0
  100. data/doc/demo/test/unit/special_content_test.rb +25 -0
  101. data/doc/demo/vendor/plugins/will_paginate/LICENSE +18 -0
  102. data/doc/demo/vendor/plugins/will_paginate/README +108 -0
  103. data/doc/demo/vendor/plugins/will_paginate/Rakefile +23 -0
  104. data/doc/demo/vendor/plugins/will_paginate/init.rb +21 -0
  105. data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/collection.rb +45 -0
  106. data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/core_ext.rb +44 -0
  107. data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/finder.rb +159 -0
  108. data/doc/demo/vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb +95 -0
  109. data/doc/demo/vendor/plugins/will_paginate/test/array_pagination_test.rb +23 -0
  110. data/doc/demo/vendor/plugins/will_paginate/test/boot.rb +27 -0
  111. data/doc/demo/vendor/plugins/will_paginate/test/console +10 -0
  112. data/doc/demo/vendor/plugins/will_paginate/test/finder_test.rb +219 -0
  113. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/admin.rb +3 -0
  114. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/companies.yml +24 -0
  115. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/company.rb +23 -0
  116. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/developer.rb +11 -0
  117. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/developers_projects.yml +13 -0
  118. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/project.rb +4 -0
  119. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/projects.yml +7 -0
  120. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/replies.yml +20 -0
  121. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/reply.rb +5 -0
  122. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/schema.sql +44 -0
  123. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/topic.rb +19 -0
  124. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/topics.yml +30 -0
  125. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/user.rb +2 -0
  126. data/doc/demo/vendor/plugins/will_paginate/test/fixtures/users.yml +35 -0
  127. data/doc/demo/vendor/plugins/will_paginate/test/helper.rb +42 -0
  128. data/doc/demo/vendor/plugins/will_paginate/test/lib/activerecord_test_connector.rb +64 -0
  129. data/doc/demo/vendor/plugins/will_paginate/test/lib/load_fixtures.rb +10 -0
  130. data/doc/demo/vendor/plugins/will_paginate/test/pagination_test.rb +136 -0
  131. data/doc/monit-example +22 -0
  132. data/init.rb +24 -0
  133. data/install.rb +18 -0
  134. data/lib/act_methods.rb +147 -0
  135. data/lib/acts_as_ferret.rb +593 -0
  136. data/lib/ar_mysql_auto_reconnect_patch.rb +41 -0
  137. data/lib/blank_slate.rb +54 -0
  138. data/lib/bulk_indexer.rb +56 -0
  139. data/lib/class_methods.rb +279 -0
  140. data/lib/ferret_extensions.rb +192 -0
  141. data/lib/ferret_find_methods.rb +142 -0
  142. data/lib/ferret_result.rb +58 -0
  143. data/lib/ferret_server.rb +238 -0
  144. data/lib/index.rb +99 -0
  145. data/lib/instance_methods.rb +172 -0
  146. data/lib/local_index.rb +202 -0
  147. data/lib/more_like_this.rb +217 -0
  148. data/lib/multi_index.rb +133 -0
  149. data/lib/rdig_adapter.rb +149 -0
  150. data/lib/remote_functions.rb +43 -0
  151. data/lib/remote_index.rb +54 -0
  152. data/lib/remote_multi_index.rb +20 -0
  153. data/lib/search_results.rb +50 -0
  154. data/lib/server_manager.rb +71 -0
  155. data/lib/unix_daemon.rb +86 -0
  156. data/lib/without_ar.rb +52 -0
  157. data/recipes/aaf_recipes.rb +116 -0
  158. data/script/ferret_daemon +94 -0
  159. data/script/ferret_server +12 -0
  160. data/script/ferret_service +178 -0
  161. data/tasks/ferret.rake +39 -0
  162. metadata +246 -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