JezK
Edit File: scope_examples.rb
shared_examples_for "scoped query" do it 'scopes by exact match with a string' do search do with :title, 'My Pet Post' end connection.should have_last_search_including(:fq, 'title_ss:My\ Pet\ Post') end it 'scopes by exact match with a special string' do search do with :title, 'OR' end connection.should have_last_search_including(:fq, 'title_ss:"OR"') end it 'scopes by exact match with time' do time = Time.parse('1983-07-08 05:00:00 -0400') search do with :published_at, time end connection.should have_last_search_including( :fq, 'published_at_dt:1983\-07\-08T09\:00\:00Z' ) end it 'scopes by exact match with date' do date = Date.new(1983, 7, 8) search do with :expire_date, date end connection.should have_last_search_including( :fq, 'expire_date_d:1983\-07\-08T00\:00\:00Z' ) end it 'scopes by exact match with boolean' do search do with :featured, false end connection.should have_last_search_including(:fq, 'featured_bs:false') end it 'scopes by less than match with float' do search do with(:average_rating).less_than 3.0 end connection.should have_last_search_including(:fq, 'average_rating_ft:{* TO 3\.0}') end it 'should quote string with space in a less than match' do search do with(:title).less_than('test value') end connection.should have_last_search_including(:fq, 'title_ss:{* TO "test\ value"}') end it 'scopes by greater than match with float' do search do with(:average_rating).greater_than 3.0 end connection.should have_last_search_including(:fq, 'average_rating_ft:{3\.0 TO *}') end it 'scopes by short-form between match with integers' do search do with :blog_id, 2..4 end connection.should have_last_search_including(:fq, 'blog_id_i:[2 TO 4]') end it 'scopes by between match with float' do search do with(:average_rating).between 2.0..4.0 end connection.should have_last_search_including(:fq, 'average_rating_ft:[2\.0 TO 4\.0]') end it 'scopes by any match with integer' do search do with(:category_ids).any_of [2, 7, 12] end connection.should have_last_search_including(:fq, 'category_ids_im:(2 OR 7 OR 12)') end it 'scopes by short-form any-of match with integers' do search do with :category_ids, [2, 7, 12] end connection.should have_last_search_including(:fq, 'category_ids_im:(2 OR 7 OR 12)') end it 'scopes by all match with integer' do search do with(:category_ids).all_of [2, 7, 12] end connection.should have_last_search_including(:fq, 'category_ids_im:(2 AND 7 AND 12)') end it 'scopes by prefix match with string' do search do with(:title).starting_with('tes') end connection.should have_last_search_including(:fq, 'title_ss:tes*') end it 'scopes by not equal match with string' do search do without :title, 'Bad Post' end connection.should have_last_search_including(:fq, '-title_ss:Bad\ Post') end it 'scopes by not less than match with float' do search do without(:average_rating).less_than 3.0 end connection.should have_last_search_including(:fq, '-average_rating_ft:{* TO 3\.0}') end it 'scopes by not greater than match with float' do search do without(:average_rating).greater_than 3.0 end connection.should have_last_search_including(:fq, '-average_rating_ft:{3\.0 TO *}') end it 'scopes by not between match with shorthand' do search do without(:blog_id, 2..4) end connection.should have_last_search_including(:fq, '-blog_id_i:[2 TO 4]') end it 'scopes by not between match with float' do search do without(:average_rating).between 2.0..4.0 end connection.should have_last_search_including(:fq, '-average_rating_ft:[2\.0 TO 4\.0]') end it 'scopes by not any match with integer' do search do without(:category_ids).any_of [2, 7, 12] end connection.should have_last_search_including(:fq, '-category_ids_im:(2 OR 7 OR 12)') end it 'scopes by not all match with integer' do search do without(:category_ids).all_of [2, 7, 12] end connection.should have_last_search_including(:fq, '-category_ids_im:(2 AND 7 AND 12)') end it 'scopes by empty field' do search do with :average_rating, nil end connection.should have_last_search_including(:fq, '-average_rating_ft:[* TO *]') end it 'scopes by non-empty field' do search do without :average_rating, nil end connection.should have_last_search_including(:fq, 'average_rating_ft:[* TO *]') end it 'includes by object identity' do post = Post.new search do with post end connection.should have_last_search_including(:fq, "id:(Post\\ #{post.id})") end it 'includes multiple objects passed as varargs by object identity' do post1, post2 = Post.new, Post.new search do with post1, post2 end connection.should have_last_search_including( :fq, "id:(Post\\ #{post1.id} OR Post\\ #{post2.id})" ) end it 'includes multiple objects passed as array by object identity' do posts = [Post.new, Post.new] search do with posts end connection.should have_last_search_including( :fq, "id:(Post\\ #{posts.first.id} OR Post\\ #{posts.last.id})" ) end it 'excludes by object identity' do post = Post.new search do without post end connection.should have_last_search_including(:fq, "-id:(Post\\ #{post.id})") end it 'excludes multiple objects passed as varargs by object identity' do post1, post2 = Post.new, Post.new search do without post1, post2 end connection.should have_last_search_including( :fq, "-id:(Post\\ #{post1.id} OR Post\\ #{post2.id})" ) end it 'excludes multiple objects passed as array by object identity' do posts = [Post.new, Post.new] search do without posts end connection.should have_last_search_including( :fq, "-id:(Post\\ #{posts.first.id} OR Post\\ #{posts.last.id})" ) end it 'allows scoping on fields common to all types' do time = Time.parse('1983-07-08 05:00:00 -0400') search Post, Namespaced::Comment do with :published_at, time end connection.should have_last_search_including(:fq, 'published_at_dt:1983\-07\-08T09\:00\:00Z') end it 'allows scoping on field not common to all types' do search Post, Namespaced::Comment do with :blog_id, 1 end connection.should have_last_search_including(:fq, 'blog_id_i:1') end it 'raises Sunspot::UnrecognizedFieldError if search scoped to field configured differently between types' do lambda do search Post, Namespaced::Comment do with :average_rating, 2.2 # this is a float in Post but an integer in Comment end end.should raise_error(Sunspot::UnrecognizedFieldError) end it 'raises Sunspot::UnrecognizedFieldError for nonexistant fields in block scope' do lambda do search do with :bogus, 'Field' end end.should raise_error(Sunspot::UnrecognizedFieldError) end it 'raises NoMethodError if bogus operator referenced' do lambda do search do with(:category_ids).resembling :bogus_condition end end.should raise_error(NoMethodError) end it 'should raise ArgumentError if more than two arguments passed to scope method' do lambda do search do with(:category_ids, 4, 5) end end.should raise_error(ArgumentError) end end