searchlogic 2.4.32 → 2.5.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.ruby-version +1 -0
  4. data/Appraisals +6 -0
  5. data/Gemfile +2 -10
  6. data/Gemfile.lock +29 -29
  7. data/README.rdoc +2 -0
  8. data/Rakefile +4 -21
  9. data/gemfiles/ar2.3.10.gemfile +7 -0
  10. data/gemfiles/ar2.3.10.gemfile.lock +28 -0
  11. data/gemfiles/ar2.3.11.gemfile +7 -0
  12. data/gemfiles/ar2.3.11.gemfile.lock +28 -0
  13. data/gemfiles/ar2.3.12.gemfile +7 -0
  14. data/gemfiles/ar2.3.12.gemfile.lock +28 -0
  15. data/gemfiles/ar2.3.14.gemfile +7 -0
  16. data/gemfiles/ar2.3.14.gemfile.lock +28 -0
  17. data/gemfiles/ar2.3.9.gemfile +7 -0
  18. data/gemfiles/ar2.3.9.gemfile.lock +28 -0
  19. data/lib/searchlogic/active_record/consistency.rb +4 -4
  20. data/lib/searchlogic/active_record/named_scope_tools.rb +7 -7
  21. data/lib/searchlogic/active_record/scope.rb +30 -0
  22. data/lib/searchlogic/core_ext/proc.rb +1 -1
  23. data/lib/searchlogic/named_scopes/alias_scope.rb +15 -14
  24. data/lib/searchlogic/named_scopes/association_conditions.rb +16 -16
  25. data/lib/searchlogic/named_scopes/association_ordering.rb +8 -9
  26. data/lib/searchlogic/named_scopes/base.rb +16 -0
  27. data/lib/searchlogic/named_scopes/{conditions.rb → column_conditions.rb} +47 -28
  28. data/lib/searchlogic/named_scopes/or_conditions.rb +65 -37
  29. data/lib/searchlogic/named_scopes/ordering.rb +9 -10
  30. data/lib/searchlogic/rails_helpers.rb +5 -1
  31. data/lib/searchlogic/search/conditions.rb +4 -4
  32. data/lib/searchlogic/search/method_missing.rb +7 -12
  33. data/lib/searchlogic/search/ordering.rb +5 -1
  34. data/lib/searchlogic/search/to_yaml.rb +2 -2
  35. data/lib/searchlogic/version.rb +3 -0
  36. data/lib/searchlogic.rb +9 -9
  37. data/searchlogic.gemspec +21 -92
  38. data/spec/searchlogic/active_record/association_proxy_spec.rb +1 -1
  39. data/spec/searchlogic/active_record/consistency_spec.rb +1 -1
  40. data/spec/searchlogic/core_ext/object_spec.rb +1 -1
  41. data/spec/searchlogic/core_ext/proc_spec.rb +1 -1
  42. data/spec/searchlogic/named_scopes/alias_scope_spec.rb +9 -2
  43. data/spec/searchlogic/named_scopes/association_conditions_spec.rb +34 -1
  44. data/spec/searchlogic/named_scopes/association_ordering_spec.rb +1 -1
  45. data/spec/searchlogic/named_scopes/{conditions_spec.rb → column_conditions_spec.rb} +16 -5
  46. data/spec/searchlogic/named_scopes/or_conditions_spec.rb +33 -15
  47. data/spec/searchlogic/named_scopes/ordering_spec.rb +4 -10
  48. data/spec/searchlogic/search_spec.rb +105 -74
  49. data/spec/spec_helper.rb +10 -12
  50. metadata +136 -60
  51. data/VERSION.yml +0 -5
  52. data/lib/searchlogic/active_record/association_proxy.rb +0 -20
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  describe Searchlogic::ActiveRecord::Consistency do
4
4
  it "should merge joins with consistent conditions" do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  describe Searchlogic::CoreExt::Object do
4
4
  it "should accept and pass the argument to the searchlogic_options" do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  describe Searchlogic::CoreExt::Proc do
4
4
  it "should have a searchlogic_options accessor" do
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  describe Searchlogic::NamedScopes::AliasScope do
4
4
  before(:each) do
@@ -11,6 +11,13 @@ describe Searchlogic::NamedScopes::AliasScope do
11
11
  User.username_has("bjohnson").all.should == User.find_all_by_username("bjohnson")
12
12
  end
13
13
 
14
+ it "should allow alias scopes with symbols" do
15
+ User.alias_scope :login_has, :username_has
16
+ User.create(:username => "bjohnson")
17
+ User.create(:username => "thunt")
18
+ User.login_has("bjohnson").all.should == User.find_all_by_username("bjohnson")
19
+ end
20
+
14
21
  it "should allow alias scopes from the search object" do
15
22
  search = User.search
16
23
  search.username_has = "bjohnson"
@@ -18,6 +25,6 @@ describe Searchlogic::NamedScopes::AliasScope do
18
25
  end
19
26
 
20
27
  it "should inherit alias scopes from superclasses" do
21
- Class.new(User).alias_scope?("username_has").should be_true
28
+ Class.new(User).condition?("username_has").should be_true
22
29
  end
23
30
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  describe Searchlogic::NamedScopes::AssociationConditions do
4
4
  it "should create a named scope" do
@@ -210,4 +210,37 @@ describe Searchlogic::NamedScopes::AssociationConditions do
210
210
  user.orders.shipped_on_not_null.shipped_on_greater_than(2.days.ago).count.should == 1
211
211
  end
212
212
 
213
+ it "should allow chained dynamic scopes without losing association scope conditions" do
214
+ user = User.create
215
+ order1 = Order.create :user => user, :shipped_on => Time.now, :total => 2
216
+ order2 = Order.create :shipped_on => Time.now, :total => 2
217
+ user.orders.id_equals(order1.id).count.should == 1
218
+ user.orders.id_equals(order1.id).total_equals(2).count.should == 1
219
+ end
220
+
221
+ it "shouldn't cache the lambda of a named_scope for a chained association" do
222
+ user = User.create
223
+ Order.create :user => user, :shipped_on => Time.current
224
+
225
+ # create the named_scope and use it through a chained association
226
+ Order.named_scope :shipped, lambda { {:conditions => ["shipped_on <= ?", Time.current]} }
227
+ User.orders_shipped
228
+
229
+ # simulate a day passing after the chained scope is first used
230
+ Timecop.travel(Date.tomorrow)
231
+
232
+ # make a new object that is active on our simulated day
233
+ Order.create :user => user, :shipped_on => Time.current
234
+
235
+ # we have 2 orders and both were shipped on or before the current time,
236
+ # so both should be included in the scope
237
+ user.orders.count.should == 2
238
+ User.orders_shipped.count.should == 2
239
+ end
240
+
241
+ it "should allow Marshal.dump on objects that only have polymorphic associations where a polymorphic association is loaded" do
242
+ audit = Audit.create
243
+ audit.auditable = User.create
244
+ lambda { Marshal.dump(audit) }.should_not raise_error
245
+ end
213
246
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  describe Searchlogic::NamedScopes::Ordering do
4
4
  it "should allow ascending" do
@@ -1,9 +1,13 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
- describe Searchlogic::NamedScopes::Conditions do
3
+ describe Searchlogic::NamedScopes::ColumnConditions do
4
4
  it "should be dynamically created and then cached" do
5
- User.should_not respond_to(:age_less_than)
5
+ User.scopes.key?(:age_less_than).should == false
6
6
  User.age_less_than(5)
7
+ User.scopes.key?(:age_less_than).should == true
8
+ end
9
+
10
+ it "should respond to the scope" do
7
11
  User.should respond_to(:age_less_than)
8
12
  end
9
13
 
@@ -14,14 +18,17 @@ describe Searchlogic::NamedScopes::Conditions do
14
18
  context "comparison conditions" do
15
19
  it "should have equals" do
16
20
  (5..7).each { |age| User.create(:age => age) }
21
+ nil_user = User.create
17
22
  User.age_equals(6).all.should == User.find_all_by_age(6)
18
- User.age_equals(5..6).all.should == User.find_all_by_age(5..6)
19
- User.age_equals([5, 7]).all.should == User.find_all_by_age([5, 7])
23
+ User.age_equals(nil).all.should == User.find_all_by_age(nil)
20
24
  end
21
25
 
22
26
  it "should have does not equal" do
23
27
  (5..7).each { |age| User.create(:age => age) }
24
28
  User.age_does_not_equal(6).all.should == User.find_all_by_age([5,7])
29
+
30
+ User.create!(:age => nil)
31
+ User.age_does_not_equal(nil).all.size.should == 3
25
32
  end
26
33
 
27
34
  it "should have less than" do
@@ -322,4 +329,8 @@ describe Searchlogic::NamedScopes::Conditions do
322
329
  count2 = User.id_ne(10).username_not_like("root").count
323
330
  count1.should == count2
324
331
  end
332
+
333
+ it "should produce left outer joins" do
334
+ User.left_outer_joins(:orders).should == [" LEFT OUTER JOIN \"orders\" ON orders.user_id = users.id "]
335
+ end
325
336
  end
@@ -1,51 +1,62 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  describe Searchlogic::NamedScopes::OrConditions do
4
4
  it "should define a scope by the exact same name as requested by the code" do
5
5
  User.name_or_username_like('Test')
6
6
  User.respond_to?(:name_or_username_like).should be_true
7
7
  end
8
-
8
+
9
9
  it "should match username or name" do
10
10
  User.username_or_name_like("ben").proxy_options.should == {:conditions => "(users.username LIKE '%ben%') OR (users.name LIKE '%ben%')"}
11
11
  end
12
-
12
+
13
13
  it "should use the specified condition" do
14
14
  User.username_begins_with_or_name_like("ben").proxy_options.should == {:conditions => "(users.username LIKE 'ben%') OR (users.name LIKE '%ben%')"}
15
15
  end
16
-
16
+
17
17
  it "should use the last specified condition" do
18
18
  User.username_or_name_like_or_id_or_age_lt(10).proxy_options.should == {:conditions => "(users.username LIKE '%10%') OR (users.name LIKE '%10%') OR (users.id < 10) OR (users.age < 10)"}
19
19
  end
20
-
20
+
21
21
  it "should raise an error on unknown conditions" do
22
22
  lambda { User.usernme_begins_with_or_name_like("ben") }.should raise_error(Searchlogic::NamedScopes::OrConditions::UnknownConditionError)
23
23
  end
24
-
24
+
25
25
  it "should work well with _or_equal_to" do
26
26
  User.id_less_than_or_equal_to_or_age_gt(10).proxy_options.should == {:conditions => "(users.id <= 10) OR (users.age > 10)"}
27
27
  end
28
-
28
+
29
29
  it "should work well with _or_equal_to_any" do
30
30
  User.id_less_than_or_equal_to_all_or_age_gt(10).proxy_options.should == {:conditions => "(users.id <= 10) OR (users.age > 10)"}
31
31
  end
32
-
32
+
33
33
  it "should work well with _or_equal_to_all" do
34
34
  User.id_less_than_or_equal_to_any_or_age_gt(10).proxy_options.should == {:conditions => "(users.id <= 10) OR (users.age > 10)"}
35
35
  end
36
-
36
+
37
37
  it "should play nice with other scopes" do
38
38
  User.username_begins_with("ben").id_gt(10).age_not_nil.username_or_name_ends_with("ben").scope(:find).should ==
39
39
  {:conditions => "((users.username LIKE '%ben') OR (users.name LIKE '%ben')) AND ((users.age IS NOT NULL) AND ((users.id > 10) AND (users.username LIKE 'ben%')))"}
40
40
  end
41
-
41
+
42
+ it "should work with boolean conditions" do
43
+ User.male_or_name_eq("susan").proxy_options.should == {:conditions => %Q{("users"."male" = 't') OR (users.name = 'susan')}}
44
+ User.not_male_or_name_eq("susan").proxy_options.should == {:conditions => %Q{("users"."male" = 'f') OR (users.name = 'susan')}}
45
+ lambda { User.male_or_name_eq("susan").all }.should_not raise_error
46
+ end
47
+
42
48
  it "should play nice with scopes on associations" do
43
49
  lambda { User.name_or_company_name_like("ben") }.should_not raise_error(Searchlogic::NamedScopes::OrConditions::NoConditionSpecifiedError)
44
- User.name_or_company_name_like("ben").proxy_options.should == {:joins => :company, :conditions => "(users.name LIKE '%ben%') OR (companies.name LIKE '%ben%')"}
45
- User.company_name_or_name_like("ben").proxy_options.should == {:joins => :company, :conditions => "(companies.name LIKE '%ben%') OR (users.name LIKE '%ben%')"}
46
- User.company_name_or_company_description_like("ben").proxy_options.should == {:joins =>[:company], :conditions => "(companies.name LIKE '%ben%') OR (companies.description LIKE '%ben%')"}
50
+ User.name_or_company_name_like("ben").proxy_options.should == {:joins => ["LEFT OUTER JOIN \"companies\" ON \"companies\".id = \"users\".company_id"], :conditions => "(users.name LIKE '%ben%') OR (companies.name LIKE '%ben%')"}
51
+ User.company_name_or_name_like("ben").proxy_options.should == {:joins => ["LEFT OUTER JOIN \"companies\" ON \"companies\".id = \"users\".company_id"], :conditions => "(companies.name LIKE '%ben%') OR (users.name LIKE '%ben%')"}
52
+ User.company_name_or_company_description_like("ben").proxy_options.should == {:joins => ["LEFT OUTER JOIN \"companies\" ON \"companies\".id = \"users\".company_id"], :conditions => "(companies.name LIKE '%ben%') OR (companies.description LIKE '%ben%')"}
53
+ Cart.user_company_name_or_user_company_name_like("ben").proxy_options.should == {:joins => ["LEFT OUTER JOIN \"users\" ON \"carts\".user_id = \"users\".id", "LEFT OUTER JOIN \"companies\" ON \"companies\".id = \"users\".company_id"], :conditions => "(companies.name LIKE '%ben%') OR (companies.name LIKE '%ben%')"}
54
+ end
55
+
56
+ it "should raise an error on missing condition" do
57
+ lambda { User.id_or_age(123) }.should raise_error(Searchlogic::NamedScopes::OrConditions::NoConditionSpecifiedError)
47
58
  end
48
-
59
+
49
60
  it "should not get confused by the 'or' in find_or_create_by_* methods" do
50
61
  User.create(:name => "Fred")
51
62
  User.find_or_create_by_name("Fred").should be_a_kind_of User
@@ -55,7 +66,7 @@ describe Searchlogic::NamedScopes::OrConditions do
55
66
  User.create(:name => "Fred", :username => "fredb")
56
67
  User.find_or_create_by_name_and_username("Fred", "fredb").should be_a_kind_of User
57
68
  end
58
-
69
+
59
70
  it "should work with User.search(conditions) method" do
60
71
  User.search(:username_or_name_like => 'ben').proxy_options.should == {:conditions => "(users.username LIKE '%ben%') OR (users.name LIKE '%ben%')"}
61
72
  end
@@ -63,4 +74,11 @@ describe Searchlogic::NamedScopes::OrConditions do
63
74
  it "should convert types properly when used with User.search(conditions) method" do
64
75
  User.search(:id_or_age_lte => '10').proxy_options.should == {:conditions => "(users.id <= 10) OR (users.age <= 10)"}
65
76
  end
77
+
78
+ it "should converts inner joins to left out joins" do
79
+ scopes = []
80
+ scopes << User.orders_id_equals(1)
81
+ scopes << User.carts_id_equals(1)
82
+ User.send(:merge_scopes_with_or, scopes).should == {:conditions=>"(orders.id = 1) OR (carts.id = 1)", :joins=>["LEFT OUTER JOIN \"carts\" ON carts.user_id = users.id", "LEFT OUTER JOIN \"orders\" ON orders.user_id = users.id"]}
83
+ end
66
84
  end
@@ -1,22 +1,16 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  describe Searchlogic::NamedScopes::Ordering do
4
- it "should be dynamically created and then cached" do
5
- User.should_not respond_to(:ascend_by_username)
6
- User.ascend_by_username
7
- User.should respond_to(:ascend_by_username)
8
- end
9
-
10
4
  it "should have ascending" do
11
5
  %w(bjohnson thunt).each { |username| User.create(:username => username) }
12
6
  User.ascend_by_username.all.should == User.all(:order => "username ASC")
13
7
  end
14
-
8
+
15
9
  it "should have descending" do
16
10
  %w(bjohnson thunt).each { |username| User.create(:username => username) }
17
11
  User.descend_by_username.all.should == User.all(:order => "username DESC")
18
12
  end
19
-
13
+
20
14
  it "should have order" do
21
15
  User.order("ascend_by_username").proxy_options.should == User.ascend_by_username.proxy_options
22
16
  end
@@ -27,7 +21,7 @@ describe Searchlogic::NamedScopes::Ordering do
27
21
  User.named_scope(:ascend_by_custom, :order => "username ASC, name DESC")
28
22
  User.order("ascend_by_custom").proxy_options.should == User.ascend_by_custom.proxy_options
29
23
  end
30
-
24
+
31
25
  it "should have priorty to columns over conflicting association columns" do
32
26
  Company.ascend_by_users_count
33
27
  end