Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

392 lines (331 sloc) 13.305 kB
require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
describe "Search" do
context "implementation" do
it "should create a search proxy" do
User.search(:username => "joe").should be_kind_of(Searchlogic::Search)
end
it "should create a search proxy using the same class" do
User.search.klass.should == User
end
it "should pass on the current scope to the proxy" do
company = Company.create
user = company.users.create
search = company.users.search
search.current_scope.should == company.users.scope(:find)
end
end
context "initialization" do
it "should require a class" do
lambda { Searchlogic::Search.new }.should raise_error(ArgumentError)
end
it "should set the conditions" do
search = User.search(:username => "bjohnson")
search.conditions.should == {:username => "bjohnson"}
end
end
it "should clone properly" do
company = Company.create
user1 = company.users.create(:age => 5)
user2 = company.users.create(:age => 25)
search1 = company.users.search(:age_gt => 10)
search2 = search1.clone
search2.age_gt = 1
search2.all.should == User.all
search1.all.should == [user2]
end
it "should clone properly without scope" do
user1 = User.create(:age => 5)
user2 = User.create(:age => 25)
search1 = User.search(:age_gt => 10)
search2 = search1.clone
search2.age_gt = 1
search2.all.should == User.all
search1.all.should == [user2]
end
it "should delete the condition" do
search = User.search(:username_like => "bjohnson")
search.delete("username_like")
search.username_like.should be_nil
end
context "conditions" do
it "should set the conditions and be accessible individually" do
search = User.search
search.conditions = {:username => "bjohnson"}
search.username.should == "bjohnson"
end
it "should set the conditions and allow string keys" do
search = User.search
search.conditions = {"username" => "bjohnson"}
search.username.should == "bjohnson"
end
it "should ignore blank values" do
search = User.search
search.conditions = {"username" => ""}
search.username.should be_nil
end
it "should use custom scopes before normalizing" do
User.create(:username => "bjohnson")
User.named_scope :username, lambda { |value| {:conditions => {:username => value.reverse}} }
search1 = User.search(:username => "bjohnson")
search2 = User.search(:username => "nosnhojb")
search1.count.should == 0
search2.count.should == 1
end
it "should ignore blank values in arrays" do
search = User.search
search.conditions = {"username_equals_any" => [""]}
search.username_equals_any.should be_blank
end
end
context "condition accessors" do
it "should allow setting exact columns individually" do
search = User.search
search.username = "bjohnson"
search.username.should == "bjohnson"
end
it "should allow setting local column conditions individually" do
search = User.search
search.username_gt = "bjohnson"
search.username_gt.should == "bjohnson"
end
it "should allow chaining conditions" do
user = User.create(:username => "bjohnson", :age => 20)
User.create(:username => "bjohnson", :age => 5)
search = User.search
search.username_equals("bjohnson").age_gt(10)
search.all.should == [user]
end
it "should allow setting association conditions" do
search = User.search
search.orders_total_gt = 10
search.orders_total_gt.should == 10
end
it "should allow setting pre-existing association conditions" do
User.named_scope :uname, lambda { |value| {:conditions => ["users.username = ?", value]} }
search = Company.search
search.users_uname = "bjohnson"
search.users_uname.should == "bjohnson"
end
it "should allow setting pre-existing association alias conditions" do
User.alias_scope :username_has, lambda { |value| User.username_like(value) }
search = Company.search
search.users_username_has = "bjohnson"
search.users_username_has.should == "bjohnson"
end
it "should allow using custom conditions" do
User.named_scope(:four_year_olds, { :conditions => { :age => 4 } })
search = User.search
search.four_year_olds = true
search.four_year_olds.should == true
search.proxy_options.should == User.four_year_olds.proxy_options
end
it "should not merge conflicting conditions into one value" do
# This class should JUST be a proxy. It should not do anything more than that.
# A user would be allowed to call both named scopes if they wanted.
search = User.search
search.username_greater_than = "bjohnson1"
search.username_gt = "bjohnson2"
search.username_greater_than.should == "bjohnson1"
search.username_gt.should == "bjohnson2"
end
it "should allow setting custom conditions individually with an arity of 0" do
User.named_scope(:four_year_olds, :conditions => {:age => 4})
search = User.search
search.four_year_olds = true
search.four_year_olds.should == true
end
it "should allow setting custom conditions individually with an arity of 1" do
User.named_scope(:username_should_be, lambda { |u| {:conditions => {:username => u}} })
search = User.search
search.username_should_be = "bjohnson"
search.username_should_be.should == "bjohnson"
end
it "should not allow setting conditions that are not scopes" do
search = User.search
lambda { search.unknown = true }.should raise_error(Searchlogic::Search::UnknownConditionError)
end
it "should not allow setting conditions on sensitive methods" do
search = User.search
lambda { search.destroy = true }.should raise_error(Searchlogic::Search::UnknownConditionError)
end
it "should not use the ruby implementation of the id method" do
search = User.search
search.id.should be_nil
end
context "type casting" do
it "should be a Boolean given true" do
search = User.search
search.id_nil = true
search.id_nil.should == true
end
it "should be a Boolean given 'true'" do
search = User.search
search.id_nil = "true"
search.id_nil.should == true
end
it "should be a Boolean given '1'" do
search = User.search
search.id_nil = "1"
search.id_nil.should == true
end
it "should be a Boolean given false" do
search = User.search
search.id_nil = false
search.id_nil.should == false
end
it "should be a Boolean given 'false'" do
search = User.search
search.id_nil = "false"
search.id_nil.should == false
end
it "should be a Boolean given '0'" do
search = User.search
search.id_nil = "0"
search.id_nil.should == false
end
it "should be an Integer given 1" do
search = User.search
search.id_gt = 1
search.id_gt.should == 1
end
it "should be an Integer given '1'" do
search = User.search
search.id_gt = "1"
search.id_gt.should == 1
end
it "should be a Float given 1.0" do
search = Order.search
search.total_gt = 1.0
search.total_gt.should == 1.0
end
it "should be a Float given '1'" do
search = Order.search
search.total_gt = "1"
search.total_gt.should == 1.0
end
it "should be a Float given '1.5'" do
search = Order.search
search.total_gt = "1.5"
search.total_gt.should == 1.5
end
it "should be a Range given 1..3" do
search = Order.search
search.total_eq = (1..3)
search.total_eq.should == (1..3)
end
it "should be a Date given 'Jan 1, 2009'" do
search = Order.search
search.shipped_on_after = "Jan 1, 2009"
search.shipped_on_after.should == Date.parse("Jan 1, 2009")
end
it "should be a Time given 'Jan 1, 2009'" do
search = Order.search
search.created_at_after = "Jan 1, 2009"
search.created_at_after.should == Time.parse("Jan 1, 2009")
end
it "should be a Time given 'Jan 1, 2009 9:33AM'" do
search = Order.search
search.created_at_after = "Jan 1, 2009 9:33AM"
search.created_at_after.should == Time.parse("Jan 1, 2009 9:33AM")
end
it "should convert the time to the current zone" do
search = Order.search
now = Time.now
search.created_at_after = now
search.created_at_after.should == now.in_time_zone
end
it "should be an Array and cast it's values given ['1', '2', '3']" do
search = Order.search
search.id_equals_any = ["1", "2", "3"]
search.id_equals_any.should == [1, 2, 3]
end
it "should type cast association conditions" do
search = User.search
search.orders_total_gt = "10"
search.orders_total_gt.should == 10
end
it "should type cast deep association conditions" do
search = Company.search
search.users_orders_total_gt = "10"
search.users_orders_total_gt.should == 10
end
end
end
context "taking action" do
it "should return all when not given any conditions" do
3.times { User.create }
User.search.all.length.should == 3
end
it "should implement the current scope based on an association" do
User.create
company = Company.create
user = company.users.create
company.users.search.all.should == [user]
end
it "should implement the current scope based on a named scope" do
User.named_scope(:four_year_olds, :conditions => {:age => 4})
(3..5).each { |age| User.create(:age => age) }
User.four_year_olds.search.all.should == User.find_all_by_age(4)
end
it "should call named scopes for conditions" do
User.search(:age_less_than => 5).proxy_options.should == User.age_less_than(5).proxy_options
end
it "should alias exact column names to use equals" do
User.search(:username => "joe").proxy_options.should == User.username_equals("joe").proxy_options
end
it "should recognize conditions with a value of true where the named scope has an arity of 0" do
User.search(:username_nil => true).proxy_options.should == User.username_nil.proxy_options
end
it "should ignore conditions with a value of false where the named scope has an arity of 0" do
User.search(:username_nil => false).proxy_options.should == {}
end
it "should not ignore conditions with a value of false where the named scope does not have an arity of 0" do
User.search(:username_is => false).proxy_options.should == User.username_is(false).proxy_options
end
it "should recognize the order condition" do
User.search(:order => "ascend_by_username").proxy_options.should == User.ascend_by_username.proxy_options
end
it "should pass array values as multiple arguments with arity -1" do
User.named_scope(:multiple_args, lambda { |*args|
raise "This should not be an array, it should be 1" if args.first.is_a?(Array)
{:conditions => ["id IN (?)", args]}
})
User.search(:multiple_args => [1,2]).proxy_options.should == User.multiple_args(1,2).proxy_options
end
it "should pass array as a single value with arity >= 0" do
User.named_scope(:multiple_args, lambda { |args|
raise "This should be an array" if !args.is_a?(Array)
{:conditions => ["id IN (?)", args]}
})
User.search(:multiple_args => [1,2]).proxy_options.should == User.multiple_args(1,2).proxy_options
end
it "should not split out dates or times (big fix)" do
s = User.search
s.created_at_after = Time.now
lambda { s.count }.should_not raise_error
end
end
context "method delegation" do
it "should respond to count" do
User.create(:username => "bjohnson")
search1 = User.search(:username => "bjohnson")
search2 = User.search(:username => "nosnhojb")
search1.count.should == 1
search2.count.should == 0
end
it "should respond to empty?" do
User.create(:username => "bjohnson")
search1 = User.search(:username => "bjohnson")
search2 = User.search(:username => "nosnhojb")
search1.empty?.should == false
search2.empty?.should == true
end
it "should delegate to named scopes with arity > 1" do
User.named_scope :paged, lambda {|start, limit| { :limit => limit, :offset => start }}
User.create(:username => "bjohnson")
search = User.search(:username => "bjohnson")
search.paged(0, 1).count.should == 1
search.paged(0, 0).count.should == 0
end
end
end
Jump to Line
Something went wrong with that request. Please try again.