To edit pages or tickets please login with username/password: aaf/aaf

root/trunk/demo/test/unit/multi_index_test.rb

Revision 320, 13.5 kB (checked in by jk, 8 months ago)

local mode works

Line 
1 require File.dirname(__FILE__) + '/../test_helper'
2 require 'pp'
3 require 'fileutils'
4
5 class MultiIndexTest < 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
31   # weiter: single index / multisearch lazy loading
32 #  def test_lazy_loading
33 #    results = Content.find_with_ferret 'description', :lazy => true
34 #    assert_equal 1, results.size
35 #    result = results.first
36 #    class << result
37 #      attr_accessor :ar_record # so we have a chance to check if it's been loaded...
38 #    end
39 #    assert ActsAsFerret::FerretResult === result
40 #    assert_equal 'A useless description', result.description
41 #    assert_nil result.instance_variable_get(:@ar_record)
42 #    assert_equal 'My Title', result.title
43 #    assert_not_nil result.ar_record
44 #  end
45
46  
47   def test_total_hits
48     q = '*:title OR *:comment'
49     assert_equal 3, Comment.total_hits(q)
50     assert_equal 2, Content.total_hits(q)
51     assert_equal 5, ActsAsFerret::total_hits(q, [ Comment, Content ])
52   end
53
54   def test_sorting
55     sorting = [ Ferret::Search::SortField.new(:id) ]
56     result = ActsAsFerret::find('*:title OR *:comment', [Content, Comment], :sort => sorting)
57     assert_equal result.map(&:id).sort, result.map(&:id)
58
59     sorting = [ Ferret::Search::SortField.new(:title) ]
60     result = ActsAsFerret::find('*:title OR *:comment', [Content, Comment], :sort => sorting)
61     sorting = [ Ferret::Search::SortField.new(:title, :reverse => true) ]
62     result2 = ActsAsFerret::find('*:title OR *:comment', [Content, Comment], :sort => sorting)
63     assert result.any?
64     assert result.map(&:id) != result2.map(&:id)
65
66     result = ActsAsFerret::find('*:title OR *:comment', [Content, Comment ])
67     assert result.any?
68     assert_equal result.map(&:ferret_score).sort.reverse, result.map(&:ferret_score)
69
70     sorting = [ Ferret::Search::SortField::SCORE ]
71     result = ActsAsFerret::find('*:title OR *:comment', [Content, Comment ], :sort => sorting)
72     assert result.any?
73     assert_equal result.map(&:ferret_score).sort.reverse, result.map(&:ferret_score)
74
75     sorting = [ Ferret::Search::SortField::SCORE_REV ]
76     result2 = ActsAsFerret::find('*:title OR *:comment', [Content, Comment], :sort => sorting)
77     assert_equal result2.map(&:ferret_score).sort, result2.map(&:ferret_score)
78     assert_equal result.map(&:ferret_score), result2.map(&:ferret_score).reverse
79   end
80
81  
82   # remote index rebuilds will create an index in a directory with a timestamped name.
83   # the local MultiIndex instance doesn't know about this (because it's running in
84   # another interpreter instance than the server) and therefore fails to use the
85   # correct index directories.
86   # TODO strange, still doesn't work but it should now...
87   unless Content.aaf_configuration[:remote]
88     def test_multi_index
89       i =  ActsAsFerret::get_index_for Content, Comment
90       assert ActsAsFerret::MultiIndex === i
91       hits = i.search(TermQuery.new(:title,"title"))
92       assert_equal 1, hits.total_hits
93
94       qp = Ferret::QueryParser.new(:default_field => "title",
95                                   :analyzer => Ferret::Analysis::WhiteSpaceAnalyzer.new)
96       hits = i.search(qp.parse("title"))
97       assert_equal 1, hits.total_hits
98      
99       qp = Ferret::QueryParser.new(:fields => ['title', 'content', 'description'],
100                         :analyzer => Ferret::Analysis::WhiteSpaceAnalyzer.new)
101       hits = i.search(qp.parse("title"))
102       assert_equal 2, hits.total_hits
103       hits = i.search(qp.parse("title:title OR description:title"))
104       assert_equal 2, hits.total_hits
105
106       hits = i.search("title:title OR description:title OR title:comment OR description:comment OR content:comment")
107       assert_equal 5, hits.total_hits
108
109       hits = i.search("title OR comment")
110       assert_equal 5, hits.total_hits
111
112       hits = i.search("title OR comment", :limit => 2)
113       count = 0
114       hits.hits.each { |hit, score| count += 1 }
115       assert_equal 2, count
116
117       hits = i.search("title OR comment", :offset => 2)
118       count = 0
119       hits.hits.each { |hit, score| count += 1 }
120       assert_equal 3, count
121     end
122   end
123
124   def test_search_rebuilds_index
125     remove_index Content
126     contents_from_ferret = ActsAsFerret::find('description:title', [Content, Comment])
127     assert_equal 1, contents_from_ferret.size
128   end
129
130   # remote index rebuilds will create an index in a directory with a timestamped name...
131   unless Content.aaf_configuration[:remote]
132     def test_rebuilds_index
133       remove_index Content
134       idx = ActsAsFerret.get_index_for( Content )
135       i =  ActsAsFerret::MultiIndex.new([idx])
136       assert File.exists?("#{idx.index_definition[:index_dir]}/segments")
137       hits = i.search("description:title")
138       assert_equal 1, hits.total_hits, hits.inspect
139     end
140   end
141
142   def test_find_options
143     contents_from_ferret = ActsAsFerret::find('title', [Content, Comment ], { }, :order => 'id desc')
144     assert_equal 2, contents_from_ferret.size
145     assert contents_from_ferret.first.id > contents_from_ferret.last.id
146     contents_from_ferret = ActsAsFerret::find('title', [Content, Comment ], { }, :order => 'id asc')
147     assert contents_from_ferret.first.id < contents_from_ferret.last.id
148
149     contents_from_ferret = ActsAsFerret::find('title', [Content, Comment], :limit => 1)
150     assert_equal 1, contents_from_ferret.size
151     contents_from_ferret = ActsAsFerret::find('title', [Content, Comment ], { }, :limit => 1)
152     assert_equal 1, contents_from_ferret.size
153
154
155     more_contents(true)
156     r = ActsAsFerret::find('title OR comment', [Content, Comment], { :limit => :all } )
157     assert_equal 60, r.size
158     assert_equal 60, r.total_hits
159
160     id = Content.find_with_ferret('title').first.id
161     r = ActsAsFerret::find('title OR comment', [Content, Comment], { :limit => :all },
162                                                      { :conditions => { :content => ["id != ?", id] }})
163     assert_equal 59, r.size
164     assert_equal 59, r.total_hits
165
166     r = ActsAsFerret::find('title OR comment', [Content, Comment], { :limit => 20 },
167                                                      { :conditions => { :content => ["id != ?", id] }})
168     assert_equal 20, r.size
169     assert_equal 59, r.total_hits
170
171     r = ActsAsFerret::find('title OR comment', [Content, Comment], { :limit => 20 },
172                                                      { :conditions => { :comment => 'content is null',
173                                                                         :content => ["id != ?", id] }})
174     assert_equal 20, r.size
175     assert_equal 29, r.total_hits
176
177     r = ActsAsFerret::find('title OR comment', [Content, Comment ], { },
178                                                      { :conditions => { :content => ["id != ?", id] }, :limit => 20 })
179     assert_equal 20, r.size
180     assert_equal 59, r.total_hits
181   end
182
183   def test_multi_search
184     assert_equal 4, ContentBase.find(:all).size
185    
186     Content.aaf_index.ferret_index.flush
187     contents_from_ferret = ActsAsFerret::find('description:title', [Content])
188     assert_equal 1, contents_from_ferret.size
189     contents_from_ferret = ActsAsFerret::find('title:title OR description:title', [Content])
190     assert_equal 2, contents_from_ferret.size
191     contents_from_ferret = ActsAsFerret::find('title:title', [Content])
192     assert_equal 1, contents_from_ferret.size
193     contents_from_ferret = ActsAsFerret::find('*:title', [Content])
194     assert_equal 2, contents_from_ferret.size
195     contents_from_ferret = ActsAsFerret::find('title', [Content])
196     assert_equal 2, contents_from_ferret.size
197    
198     assert_equal contents(:first).id, contents_from_ferret.first.id
199     assert_equal @another_content.id, contents_from_ferret.last.id
200    
201     contents_from_ferret = ActsAsFerret::find('title', [Content])
202     assert_equal 2, contents_from_ferret.size
203     contents_from_ferret = ActsAsFerret::find('title', [Content], :limit => 1)
204     assert_equal 1, contents_from_ferret.size
205     contents_from_ferret = ActsAsFerret::find('title', [Content], :offset => 1)
206     assert_equal 1, contents_from_ferret.size
207
208     contents_from_ferret = ActsAsFerret::find('title:title OR content:comment OR description:title', [Content, Comment])
209     assert_equal 5, contents_from_ferret.size
210     contents_from_ferret = ActsAsFerret::find('title:title OR content:comment OR description:title', [Content, Comment], :limit => 2)
211     assert_equal 2, contents_from_ferret.size
212
213     contents_from_ferret = ActsAsFerret::find('*:title OR *:comment', [Content, Comment])
214     assert_equal 5, contents_from_ferret.size
215     contents_from_ferret = ActsAsFerret::find('*:title OR *:comment', [Content, Comment])
216     assert_equal 5, contents_from_ferret.size
217     contents_from_ferret = ActsAsFerret::find('title:(title OR comment) OR description:(title OR comment) OR content:(title OR comment)', [Content, Comment])
218     assert_equal 5, contents_from_ferret.size
219   end
220
221   def test_lazy_search
222     contents_from_ferret = ActsAsFerret.find('title', [Content, Comment], :lazy => true)
223     assert_equal 2, contents_from_ferret.size
224     contents_from_ferret.each do |record|
225       assert ActsAsFerret::FerretResult === record, record.inspect
226       assert !record.description.blank?
227       assert_nil record.instance_variable_get(:"@ar_record")
228     end
229   end
230
231   def test_find_ids
232     assert_equal 4, ContentBase.find(:all).size
233    
234     [ 'title:title OR description:title OR content:title', 'title', '*:title'].each do |query|
235       total_hits, contents_from_ferret = ActsAsFerret.find_ids(query, Content)
236       assert_equal 2, contents_from_ferret.size, query
237       assert_equal 2, total_hits, query
238       assert_equal contents(:first).id, contents_from_ferret.first[:id].to_i
239       assert_equal @another_content.id, contents_from_ferret.last[:id].to_i
240     end
241
242     ContentBase.rebuild_index
243     Comment.rebuild_index
244     ['title OR comment', 'title:(title OR comment) OR description:(title OR comment) OR content:(title OR comment)'].each do |query|
245       total_hits, contents_from_ferret = ActsAsFerret.find_ids(query, [Comment, Content])
246       assert_equal 5, contents_from_ferret.size, query
247       assert_equal 5, total_hits
248     end
249   end
250
251   def test_find_ids_lazy
252     total_hits, contents_from_ferret = ActsAsFerret.find_ids('title', [Comment, Content], :lazy => true)
253     assert_equal 2, contents_from_ferret.size
254     assert_equal 2, total_hits
255     found = 0
256     contents_from_ferret.each do |data|
257       next if data[:model] != 'Content'
258       found += 1
259       assert !data[:data][:description].blank?
260     end
261     assert_equal 2, found
262   end
263
264   def test_pagination
265     more_contents(true)
266
267     r = ActsAsFerret.find 'title OR comment', [ Content, Comment ], :per_page => 10, :sort => 'title'
268     assert_equal 60, r.total_hits
269     assert_equal 10, r.size
270     assert_equal "0", r.first.description
271     assert_equal "9", r.last.description
272     assert_equal 1, r.current_page
273     assert_equal 6, r.page_count
274
275     r = ActsAsFerret.find 'title OR comment', [ Content, Comment ], :page => '2', :per_page => 10, :sort => 'title'
276     assert_equal 60, r.total_hits
277     assert_equal 10, r.size
278     assert_equal "10", r.first.description
279     assert_equal "19", r.last.description
280     assert_equal 2, r.current_page
281     assert_equal 6, r.page_count
282
283     r = ActsAsFerret.find 'title OR comment', [ Content, Comment ], :page => 7, :per_page => 10, :sort => 'title'
284     assert_equal 60, r.total_hits
285     assert_equal 0, r.size
286   end
287
288   def test_pagination_with_ar_conditions
289     more_contents(true)
290     id = Content.find_with_ferret('title').first.id
291     r = ActsAsFerret.find 'title OR comment', [Content, Comment], { :page => 1, :per_page => 10 },
292                                           { :conditions => { :content => ["id != ?", id] }, :order => 'id ASC' }
293     assert_equal 59, r.total_hits
294     assert_equal 10, r.size
295     assert_equal "Comment for content 00", r.first.content
296     assert_equal "Comment for content 09", r.last.content
297     assert_equal 1, r.current_page
298     assert_equal 6, r.page_count
299
300     r = ActsAsFerret.find 'title OR comment', [Content, Comment], { :page => 6, :per_page => 10 },
301                                           { :conditions => { :content => [ "id != ?", id ] }, :order => 'id ASC' }
302     assert_equal 59, r.total_hits
303     assert_equal 9, r.size
304     assert_equal "21", r.first.description
305     assert_equal "29", r.last.description
306     assert_equal 6, r.current_page
307     assert_equal 6, r.page_count
308   end
309
310   protected
311
312   def more_contents(with_comments = false)
313     Comment.destroy_all if with_comments
314     Content.destroy_all
315     SpecialContent.destroy_all
316     30.times do |i|
317       c = Content.create! :title => sprintf("title of Content %02d", i), :description => "#{i}"
318       c.comments.create! :content => sprintf("Comment for content %02d", i) if with_comments
319     end
320   end
321
322   def remove_index(clazz)
323     clazz.aaf_index.close # avoid io error when deleting the open index
324     FileUtils.rm_rf clazz.aaf_configuration[:index_dir]
325     assert !File.exists?("#{clazz.aaf_configuration[:index_dir]}/segments")
326   end
327
328 end
329
Note: See TracBrowser for help on using the browser.

To edit pages or tickets please login with username/password: aaf/aaf