describe 'connective in scope', :type => :query do it 'creates a disjunction between two restrictions' do session.search Post do any_of do with :category_ids, 1 with :blog_id, 2 end end connection.should have_last_search_including( :fq, '(category_ids_im:1 OR blog_id_i:2)' ) end it 'creates a conjunction inside of a disjunction' do session.search Post do any_of do with :blog_id, 2 all_of do with :category_ids, 1 with(:average_rating).greater_than(3.0) end end end connection.should have_last_search_including( :fq, '(blog_id_i:2 OR (category_ids_im:1 AND average_rating_f:[3\.0 TO *]))' ) end it 'creates a disjunction with nested conjunction with negated restrictions' do session.search Post do any_of do with :category_ids, 1 all_of do without(:average_rating).greater_than(3.0) with(:blog_id, 1) end end end connection.should have_last_search_including( :fq, '(category_ids_im:1 OR (-average_rating_f:[3\.0 TO *] AND blog_id_i:1))' ) end it 'does nothing special if #all_of called from the top level' do session.search Post do all_of do with :blog_id, 2 with :category_ids, 1 end end connection.should have_last_search_including( :fq, 'blog_id_i:2', 'category_ids_im:1' ) end it 'creates a disjunction with negated restrictions' do session.search Post do any_of do with :category_ids, 1 without(:average_rating).greater_than(3.0) end end connection.should have_last_search_including( :fq, '-(-category_ids_im:1 AND average_rating_f:[3\.0 TO *])' ) end it 'creates a disjunction with a negated restriction and a nested disjunction in a conjunction with a negated restriction' do session.search(Post) do any_of do without(:title, 'Yes') all_of do with(:blog_id, 1) any_of do with(:category_ids, 4) without(:average_rating, 2.0) end end end end connection.should have_last_search_including( :fq, '-(title_ss:Yes AND -(blog_id_i:1 AND -(-category_ids_im:4 AND average_rating_f:2\.0)))' ) end it 'creates a disjunction with nested conjunction with nested disjunction with negated restriction' do session.search(Post) do any_of do with(:title, 'Yes') all_of do with(:blog_id, 1) any_of do with(:category_ids, 4) without(:average_rating, 2.0) end end end end connection.should have_last_search_including( :fq, '(title_ss:Yes OR (blog_id_i:1 AND -(-category_ids_im:4 AND average_rating_f:2\.0)))' ) end # # This is important because if a disjunction could be nested in another # disjunction, then the inner disjunction could denormalize (and thus # become negated) after the outer disjunction denormalized (checking to # see if the inner one is negated). Since conjunctions never need to # denormalize, if a disjunction can only contain conjunctions or restrictions, # we can guarantee that the negation state of a disjunction's components will # not change when #to_params is called on them. # # Since disjunction is associative, this behavior has no effect on the actual # logical semantics of the disjunction. # it 'creates a single disjunction when disjunctions nested' do session.search(Post) do any_of do with(:title, 'Yes') any_of do with(:blog_id, 1) with(:category_ids, 4) end end end connection.should have_last_search_including( :fq, '(title_ss:Yes OR blog_id_i:1 OR category_ids_im:4)' ) end it 'creates a disjunction with instance exclusion' do post = Post.new session.search Post do any_of do without(post) with(:category_ids, 1) end end connection.should have_last_search_including( :fq, "-(id:Post\\ #{post.id} AND -category_ids_im:1)" ) end it 'creates a disjunction with empty restriction' do session.search Post do any_of do with(:average_rating, nil) with(:average_rating).greater_than(3.0) end end connection.should have_last_search_including( :fq, '-(average_rating_f:[* TO *] AND -average_rating_f:[3\.0 TO *])' ) end it 'should ignore empty connectives' do session.search Post do any_of {} end connection.should_not have_last_search_including(:fq, '') end end