yoomee-searchlogic 2.4.27

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 (44) hide show
  1. data/.gitignore +6 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +308 -0
  4. data/Rakefile +35 -0
  5. data/VERSION.yml +5 -0
  6. data/init.rb +1 -0
  7. data/lib/searchlogic.rb +56 -0
  8. data/lib/searchlogic/active_record/association_proxy.rb +19 -0
  9. data/lib/searchlogic/active_record/consistency.rb +49 -0
  10. data/lib/searchlogic/active_record/named_scope_tools.rb +101 -0
  11. data/lib/searchlogic/core_ext/object.rb +43 -0
  12. data/lib/searchlogic/core_ext/proc.rb +17 -0
  13. data/lib/searchlogic/named_scopes/alias_scope.rb +67 -0
  14. data/lib/searchlogic/named_scopes/association_conditions.rb +132 -0
  15. data/lib/searchlogic/named_scopes/association_ordering.rb +44 -0
  16. data/lib/searchlogic/named_scopes/conditions.rb +232 -0
  17. data/lib/searchlogic/named_scopes/or_conditions.rb +141 -0
  18. data/lib/searchlogic/named_scopes/ordering.rb +48 -0
  19. data/lib/searchlogic/rails_helpers.rb +79 -0
  20. data/lib/searchlogic/search.rb +26 -0
  21. data/lib/searchlogic/search/base.rb +26 -0
  22. data/lib/searchlogic/search/conditions.rb +58 -0
  23. data/lib/searchlogic/search/date_parts.rb +23 -0
  24. data/lib/searchlogic/search/implementation.rb +14 -0
  25. data/lib/searchlogic/search/method_missing.rb +123 -0
  26. data/lib/searchlogic/search/ordering.rb +10 -0
  27. data/lib/searchlogic/search/scopes.rb +19 -0
  28. data/lib/searchlogic/search/to_yaml.rb +38 -0
  29. data/lib/searchlogic/search/unknown_condition_error.rb +15 -0
  30. data/rails/init.rb +1 -0
  31. data/searchlogic.gemspec +98 -0
  32. data/spec/searchlogic/active_record/association_proxy_spec.rb +23 -0
  33. data/spec/searchlogic/active_record/consistency_spec.rb +28 -0
  34. data/spec/searchlogic/core_ext/object_spec.rb +9 -0
  35. data/spec/searchlogic/core_ext/proc_spec.rb +8 -0
  36. data/spec/searchlogic/named_scopes/alias_scope_spec.rb +23 -0
  37. data/spec/searchlogic/named_scopes/association_conditions_spec.rb +203 -0
  38. data/spec/searchlogic/named_scopes/association_ordering_spec.rb +27 -0
  39. data/spec/searchlogic/named_scopes/conditions_spec.rb +319 -0
  40. data/spec/searchlogic/named_scopes/or_conditions_spec.rb +66 -0
  41. data/spec/searchlogic/named_scopes/ordering_spec.rb +34 -0
  42. data/spec/searchlogic/search_spec.rb +497 -0
  43. data/spec/spec_helper.rb +132 -0
  44. metadata +136 -0
@@ -0,0 +1,66 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe Searchlogic::NamedScopes::OrConditions do
4
+ it "should define a scope by the exact same name as requested by the code" do
5
+ User.name_or_username_like('Test')
6
+ User.respond_to?(:name_or_username_like).should be_true
7
+ end
8
+
9
+ it "should match username or name" do
10
+ User.username_or_name_like("ben").proxy_options.should == {:conditions => "(users.username LIKE '%ben%') OR (users.name LIKE '%ben%')"}
11
+ end
12
+
13
+ it "should use the specified condition" do
14
+ User.username_begins_with_or_name_like("ben").proxy_options.should == {:conditions => "(users.username LIKE 'ben%') OR (users.name LIKE '%ben%')"}
15
+ end
16
+
17
+ it "should use the last specified condition" do
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
+ end
20
+
21
+ it "should raise an error on unknown conditions" do
22
+ lambda { User.usernme_begins_with_or_name_like("ben") }.should raise_error(Searchlogic::NamedScopes::OrConditions::UnknownConditionError)
23
+ end
24
+
25
+ it "should work well with _or_equal_to" do
26
+ User.id_less_than_or_equal_to_or_age_gt(10).proxy_options.should == {:conditions => "(users.id <= 10) OR (users.age > 10)"}
27
+ end
28
+
29
+ it "should work well with _or_equal_to_any" do
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
+ end
32
+
33
+ it "should work well with _or_equal_to_all" do
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
+ end
36
+
37
+ it "should play nice with other scopes" do
38
+ User.username_begins_with("ben").id_gt(10).age_not_nil.username_or_name_ends_with("ben").scope(:find).should ==
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
+ end
41
+
42
+ it "should play nice with scopes on associations" do
43
+ 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%')"}
47
+ end
48
+
49
+ it "should not get confused by the 'or' in find_or_create_by_* methods" do
50
+ User.create(:name => "Fred")
51
+ User.find_or_create_by_name("Fred").should be_a_kind_of User
52
+ end
53
+
54
+ it "should not get confused by the 'or' in compound find_or_create_by_* methods" do
55
+ User.create(:name => "Fred", :username => "fredb")
56
+ User.find_or_create_by_name_and_username("Fred", "fredb").should be_a_kind_of User
57
+ end
58
+
59
+ it "should work with User.search(conditions) method" do
60
+ User.search(:username_or_name_like => 'ben').proxy_options.should == {:conditions => "(users.username LIKE '%ben%') OR (users.name LIKE '%ben%')"}
61
+ end
62
+
63
+ it "should convert types properly when used with User.search(conditions) method" do
64
+ User.search(:id_or_age_lte => '10').proxy_options.should == {:conditions => "(users.id <= 10) OR (users.age <= 10)"}
65
+ end
66
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
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
+ it "should have ascending" do
11
+ %w(bjohnson thunt).each { |username| User.create(:username => username) }
12
+ User.ascend_by_username.all.should == User.all(:order => "username ASC")
13
+ end
14
+
15
+ it "should have descending" do
16
+ %w(bjohnson thunt).each { |username| User.create(:username => username) }
17
+ User.descend_by_username.all.should == User.all(:order => "username DESC")
18
+ end
19
+
20
+ it "should have order" do
21
+ User.order("ascend_by_username").proxy_options.should == User.ascend_by_username.proxy_options
22
+ end
23
+
24
+ it "should have order by custom scope" do
25
+ User.column_names.should_not include("custom")
26
+ %w(bjohnson thunt fisons).each { |username| User.create(:username => username) }
27
+ User.named_scope(:ascend_by_custom, :order => "username ASC, name DESC")
28
+ User.order("ascend_by_custom").proxy_options.should == User.ascend_by_custom.proxy_options
29
+ end
30
+
31
+ it "should have priorty to columns over conflicting association columns" do
32
+ Company.ascend_by_users_count
33
+ end
34
+ end
@@ -0,0 +1,497 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Searchlogic::Search do
4
+ describe "Implementation" do
5
+ context "#searchlogic" do
6
+ it "should create a search proxy" do
7
+ User.search(:username => "joe").should be_kind_of(Searchlogic::Search)
8
+ end
9
+
10
+ it "should create a search proxy using the same class" do
11
+ User.search.klass.should == User
12
+ end
13
+
14
+ it "should pass on the current scope to the proxy" do
15
+ company = Company.create
16
+ user = company.users.create
17
+ search = company.users.search
18
+ search.current_scope.should == company.users.scope(:find)
19
+ end
20
+ end
21
+ end
22
+
23
+ context "#initialize" do
24
+ it "should require a class" do
25
+ lambda { Searchlogic::Search.new }.should raise_error(ArgumentError)
26
+ end
27
+
28
+ it "should set the conditions" do
29
+ search = User.search(:username => "bjohnson")
30
+ search.conditions.should == {:username => "bjohnson"}
31
+ end
32
+ end
33
+
34
+ context "#clone" do
35
+ it "should clone properly" do
36
+ company = Company.create
37
+ user1 = company.users.create(:age => 5)
38
+ user2 = company.users.create(:age => 25)
39
+ search1 = company.users.search(:age_gt => 10)
40
+ search2 = search1.clone
41
+ search2.age_gt = 1
42
+ search2.all.should == User.all
43
+ search1.all.should == [user2]
44
+ end
45
+
46
+ it "should clone properly without scope" do
47
+ user1 = User.create(:age => 5)
48
+ user2 = User.create(:age => 25)
49
+ search1 = User.search(:age_gt => 10)
50
+ search2 = search1.clone
51
+ search2.age_gt = 1
52
+ search2.all.should == User.all
53
+ search1.all.should == [user2]
54
+ end
55
+ end
56
+
57
+ context "#conditions" do
58
+ it "should set the conditions and be accessible individually" do
59
+ search = User.search
60
+ search.conditions = {:username => "bjohnson"}
61
+ search.username.should == "bjohnson"
62
+ end
63
+
64
+ it "should set the conditions and allow string keys" do
65
+ search = User.search
66
+ search.conditions = {"username" => "bjohnson"}
67
+ search.username.should == "bjohnson"
68
+ end
69
+
70
+ it "should use custom scopes before normalizing" do
71
+ User.create(:username => "bjohnson")
72
+ User.named_scope :username, lambda { |value| {:conditions => {:username => value.reverse}} }
73
+ search1 = User.search(:username => "bjohnson")
74
+ search2 = User.search(:username => "nosnhojb")
75
+ search1.count.should == 0
76
+ search2.count.should == 1
77
+ end
78
+
79
+ # We ignore them upon execution. But we still want to accept the condition so that returning the conditions
80
+ # preserves the values.
81
+ it "should ignore blank values but still return on conditions" do
82
+ search = User.search
83
+ search.conditions = {"username" => ""}
84
+ search.username.should be_nil
85
+ search.conditions.should == {:username => ""}
86
+ end
87
+
88
+ it "should not ignore blank values and should not cast them" do
89
+ search = User.search
90
+ search.conditions = {"id_equals" => ""}
91
+ search.id_equals.should be_nil
92
+ search.conditions.should == {:id_equals => ""}
93
+ end
94
+
95
+ it "should ignore blank values in arrays" do
96
+ search = User.search
97
+ search.conditions = {"username_equals_any" => [""]}
98
+ search.username_equals_any.should be_nil
99
+
100
+ search.conditions = {"id_equals_any" => ["", "1"]}
101
+ search.id_equals_any.should == [1]
102
+ end
103
+ end
104
+
105
+ context "#compact_conditions" do
106
+ it "should remove conditions with blank values" do
107
+ search = User.search
108
+ search.conditions = {"id_equals" => "", "name_equals" => "Ben"}
109
+ search.compact_conditions.should == {:name_equals => "Ben"}
110
+ end
111
+ end
112
+
113
+ context "condition accessors" do
114
+ it "should allow setting exact columns individually" do
115
+ search = User.search
116
+ search.username = "bjohnson"
117
+ search.username.should == "bjohnson"
118
+ end
119
+
120
+ it "should allow setting local column conditions individually" do
121
+ search = User.search
122
+ search.username_gt = "bjohnson"
123
+ search.username_gt.should == "bjohnson"
124
+ end
125
+
126
+ it "should allow chaining conditions" do
127
+ user = User.create(:username => "bjohnson", :age => 20)
128
+ User.create(:username => "bjohnson", :age => 5)
129
+ search = User.search
130
+ search.username_equals("bjohnson").age_gt(10)
131
+ search.all.should == [user]
132
+ end
133
+
134
+ it "should allow setting association conditions" do
135
+ search = User.search
136
+ search.orders_total_gt = 10
137
+ search.orders_total_gt.should == 10
138
+ end
139
+
140
+ it "should allow setting pre-existing association conditions" do
141
+ User.named_scope :uname, lambda { |value| {:conditions => ["users.username = ?", value]} }
142
+ search = Company.search
143
+ search.users_uname = "bjohnson"
144
+ search.users_uname.should == "bjohnson"
145
+ end
146
+
147
+ it "should allow setting pre-existing association alias conditions" do
148
+ User.alias_scope :username_has, lambda { |value| User.username_like(value) }
149
+ search = Company.search
150
+ search.users_username_has = "bjohnson"
151
+ search.users_username_has.should == "bjohnson"
152
+ end
153
+
154
+ it "should allow using custom conditions" do
155
+ User.named_scope(:four_year_olds, { :conditions => { :age => 4 } })
156
+ search = User.search
157
+ search.four_year_olds = true
158
+ search.four_year_olds.should == true
159
+ search.proxy_options.should == User.four_year_olds.proxy_options
160
+ end
161
+
162
+ it "should not merge conflicting conditions into one value" do
163
+ # This class should JUST be a proxy. It should not do anything more than that.
164
+ # A user would be allowed to call both named scopes if they wanted.
165
+ search = User.search
166
+ search.username_greater_than = "bjohnson1"
167
+ search.username_gt = "bjohnson2"
168
+ search.username_greater_than.should == "bjohnson1"
169
+ search.username_gt.should == "bjohnson2"
170
+ end
171
+
172
+ it "should allow setting custom conditions individually with an arity of 0" do
173
+ User.named_scope(:four_year_olds, :conditions => {:age => 4})
174
+ search = User.search
175
+ search.four_year_olds = true
176
+ search.four_year_olds.should == true
177
+ end
178
+
179
+ it "should allow setting custom conditions individually with an arity of 1" do
180
+ User.named_scope(:username_should_be, lambda { |u| {:conditions => {:username => u}} })
181
+ search = User.search
182
+ search.username_should_be = "bjohnson"
183
+ search.username_should_be.should == "bjohnson"
184
+ end
185
+
186
+ it "should not allow setting conditions that are not scopes" do
187
+ search = User.search
188
+ lambda { search.unknown = true }.should raise_error(Searchlogic::Search::UnknownConditionError)
189
+ end
190
+
191
+ it "should not allow setting conditions on sensitive methods" do
192
+ search = User.search
193
+ lambda { search.destroy = true }.should raise_error(Searchlogic::Search::UnknownConditionError)
194
+ end
195
+
196
+ it "should not use the ruby implementation of the id method" do
197
+ search = User.search
198
+ search.id.should be_nil
199
+ end
200
+
201
+ context "type casting" do
202
+ it "should be a Boolean given true" do
203
+ search = User.search
204
+ search.id_nil = true
205
+ search.id_nil.should == true
206
+ end
207
+
208
+ it "should be a Boolean given 'true'" do
209
+ search = User.search
210
+ search.id_nil = "true"
211
+ search.id_nil.should == true
212
+ end
213
+
214
+ it "should be a Boolean given '1'" do
215
+ search = User.search
216
+ search.id_nil = "1"
217
+ search.id_nil.should == true
218
+ end
219
+
220
+ it "should be a Boolean given false" do
221
+ search = User.search
222
+ search.id_nil = false
223
+ search.id_nil.should == false
224
+ end
225
+
226
+ it "should be a Boolean given 'false'" do
227
+ search = User.search
228
+ search.id_nil = "false"
229
+ search.id_nil.should == false
230
+ end
231
+
232
+ it "should be a Boolean given '0'" do
233
+ search = User.search
234
+ search.id_nil = "0"
235
+ search.id_nil.should == false
236
+ end
237
+
238
+ it "should be an Integer given ''" do
239
+ search = User.search
240
+ search.id_gt = ''
241
+ search.id_gt.should == 0
242
+ end
243
+
244
+ it "should be an Integer given 1" do
245
+ search = User.search
246
+ search.id_gt = 1
247
+ search.id_gt.should == 1
248
+ end
249
+
250
+ it "should be an Integer given '1'" do
251
+ search = User.search
252
+ search.id_gt = "1"
253
+ search.id_gt.should == 1
254
+ end
255
+
256
+ it "should be a Float given 1.0" do
257
+ search = Order.search
258
+ search.total_gt = 1.0
259
+ search.total_gt.should == 1.0
260
+ end
261
+
262
+ it "should be a Float given '1'" do
263
+ search = Order.search
264
+ search.total_gt = "1"
265
+ search.total_gt.should == 1.0
266
+ end
267
+
268
+ it "should be a Float given '1.5'" do
269
+ search = Order.search
270
+ search.total_gt = "1.5"
271
+ search.total_gt.should == 1.5
272
+ end
273
+
274
+ it "should be a Range given 1..3" do
275
+ search = Order.search
276
+ search.total_eq = (1..3)
277
+ search.total_eq.should == (1..3)
278
+ end
279
+
280
+ it "should be a Date given 'Jan 1, 2009'" do
281
+ search = Order.search
282
+ search.shipped_on_after = "Jan 1, 2009"
283
+ search.shipped_on_after.should == Date.parse("Jan 1, 2009")
284
+ end
285
+
286
+ it "should be a Time given 'Jan 1, 2009'" do
287
+ search = Order.search
288
+ search.created_at_after = "Jan 1, 2009"
289
+ search.created_at_after.should == Time.zone.parse("Jan 1, 2009")
290
+ end
291
+
292
+ it "should be a Time given 'Jan 1, 2009 9:33AM'" do
293
+ search = Order.search
294
+ search.created_at_after = "Jan 1, 2009 9:33AM"
295
+ search.created_at_after.should == Time.zone.parse("Jan 1, 2009 9:33AM")
296
+ end
297
+
298
+ it "should skip time zone conversion for attributes skipped" do
299
+ search = User.search
300
+ search.whatever_at_after = "Jan 1, 2009 9:33AM"
301
+ search.whatever_at_after.should == Time.parse("Jan 1, 2009 9:33AM").utc
302
+ end
303
+
304
+ it "should convert the time to the current zone" do
305
+ search = Order.search
306
+ now = Time.now
307
+ search.created_at_after = now
308
+ search.created_at_after.should == now.in_time_zone
309
+ end
310
+
311
+ it "should be an Array and cast it's values given ['1', '2', '3']" do
312
+ search = Order.search
313
+ search.id_equals_any = ["1", "2", "3"]
314
+ search.id_equals_any.should == [1, 2, 3]
315
+ end
316
+
317
+ it "should type cast association conditions" do
318
+ search = User.search
319
+ search.orders_total_gt = "10"
320
+ search.orders_total_gt.should == 10
321
+ end
322
+
323
+ it "should type cast deep association conditions" do
324
+ search = Company.search
325
+ search.users_orders_total_gt = "10"
326
+ search.users_orders_total_gt.should == 10
327
+ end
328
+
329
+ it "should support Rails' date_select and datetime_select out of the box" do
330
+ search = Company.search('created_at_after(1i)' => 2000, 'created_at_after(2i)' => 1, 'created_at_after(3i)' => 1)
331
+ search.created_at_after.should_not be_nil
332
+ search.created_at_after.should == Time.zone.local(2000, 1, 1)
333
+ end
334
+ end
335
+ end
336
+
337
+ context "#delete" do
338
+ it "should delete the condition" do
339
+ search = User.search(:username_like => "bjohnson")
340
+ search.delete("username_like")
341
+ search.username_like.should be_nil
342
+ search.conditions["username_like"].should be_nil
343
+ end
344
+ end
345
+
346
+ context "#ordering_by" do
347
+ it "should return nil if we aren't ordering" do
348
+ search = User.search
349
+ search.ordering_by.should be_nil
350
+ end
351
+
352
+ it "should return the column name for ascending" do
353
+ search = User.search(:order => "ascend_by_first_name")
354
+ search.ordering_by.should == "first_name"
355
+ end
356
+
357
+ it "should return the column name for descending" do
358
+ search = User.search(:order => "descend_by_first_name")
359
+ search.ordering_by.should == "first_name"
360
+ end
361
+
362
+ it "should handle symbols" do
363
+ search = User.search(:order => :descend_by_first_name)
364
+ search.ordering_by.should == "first_name"
365
+ end
366
+ end
367
+
368
+ context "#method_missing" do
369
+ context "setting" do
370
+ it "should call named scopes for conditions" do
371
+ User.search(:age_less_than => 5).proxy_options.should == User.age_less_than(5).proxy_options
372
+ end
373
+
374
+ it "should alias exact column names to use equals" do
375
+ User.search(:username => "joe").proxy_options.should == User.username_equals("joe").proxy_options
376
+ end
377
+
378
+ it "should recognize conditions with a value of true where the named scope has an arity of 0" do
379
+ User.search(:username_nil => true).proxy_options.should == User.username_nil.proxy_options
380
+ end
381
+
382
+ it "should ignore conditions with a value of false where the named scope has an arity of 0" do
383
+ User.search(:username_nil => false).proxy_options.should == {}
384
+ end
385
+
386
+ it "should not ignore conditions with a value of false where the named scope does not have an arity of 0" do
387
+ User.search(:username_is => false).proxy_options.should == User.username_is(false).proxy_options
388
+ end
389
+
390
+ it "should recognize the order condition" do
391
+ User.search(:order => "ascend_by_username").proxy_options.should == User.ascend_by_username.proxy_options
392
+ end
393
+
394
+ it "should pass array values as multiple arguments with arity -1" do
395
+ User.named_scope(:multiple_args, lambda { |*args|
396
+ raise "This should not be an array, it should be 1" if args.first.is_a?(Array)
397
+ {:conditions => ["id IN (?)", args]}
398
+ })
399
+ User.search(:multiple_args => [1,2]).proxy_options.should == User.multiple_args(1,2).proxy_options
400
+ end
401
+
402
+ it "should pass array as a single value with arity >= 0" do
403
+ User.named_scope(:multiple_args, lambda { |args|
404
+ raise "This should be an array" if !args.is_a?(Array)
405
+ {:conditions => ["id IN (?)", args]}
406
+ })
407
+ User.search(:multiple_args => [1,2]).proxy_options.should == User.multiple_args([1,2]).proxy_options
408
+ end
409
+
410
+ it "should not split out dates or times (big fix)" do
411
+ s = User.search
412
+ s.created_at_after = Time.now
413
+ lambda { s.count }.should_not raise_error
414
+ end
415
+
416
+ it "should not include blank values" do
417
+ s = User.search
418
+ s.conditions = {"id_equals" => ""}
419
+ s.proxy_options.should == {}
420
+ end
421
+ end
422
+ end
423
+
424
+ context "#respond_to?" do
425
+ it "should respond to created_at_lte" do
426
+ s = User.search
427
+ s.respond_to?(:created_at_lte).should == true
428
+ end
429
+
430
+ it "should respond to created_at" do
431
+ s = User.search
432
+ s.respond_to?(:created_at).should == true
433
+ end
434
+
435
+ it "should not respond to created_at_or_whatever" do
436
+ s = User.search
437
+ s.respond_to?(:created_at_or_whatever)
438
+ end
439
+ end
440
+
441
+ context "delegation" do
442
+ it "should return all when not given any conditions" do
443
+ 3.times { User.create }
444
+ User.search.all.length.should == 3
445
+ end
446
+
447
+ it "should implement the current scope based on an association" do
448
+ User.create
449
+ company = Company.create
450
+ user = company.users.create
451
+ company.users.search.all.should == [user]
452
+ end
453
+
454
+ it "should implement the current scope based on a named scope" do
455
+ User.named_scope(:four_year_olds, :conditions => {:age => 4})
456
+ (3..5).each { |age| User.create(:age => age) }
457
+ User.four_year_olds.search.all.should == User.find_all_by_age(4)
458
+ end
459
+
460
+ it "should respond to count" do
461
+ User.create(:username => "bjohnson")
462
+ search1 = User.search(:username => "bjohnson")
463
+ search2 = User.search(:username => "nosnhojb")
464
+ search1.count.should == 1
465
+ search2.count.should == 0
466
+ end
467
+
468
+ it "should respond to empty?" do
469
+ User.create(:username => "bjohnson")
470
+ search1 = User.search(:username => "bjohnson")
471
+ search2 = User.search(:username => "nosnhojb")
472
+ search1.empty?.should == false
473
+ search2.empty?.should == true
474
+ end
475
+
476
+ it "should delegate to named scopes with arity > 1" do
477
+ User.named_scope :paged, lambda {|start, limit| { :limit => limit, :offset => start }}
478
+ User.create(:username => "bjohnson")
479
+ search = User.search(:username => "bjohnson")
480
+ search.paged(0, 1).count.should == 1
481
+ search.paged(0, 0).count.should == 0
482
+ end
483
+ end
484
+
485
+ context "yaml" do
486
+ it "should load yaml" do
487
+ time = Time.now
488
+ search = User.search(:name_like => "Ben", :created_at_after => time)
489
+ search.current_scope = {:conditions => "1=1"}
490
+ yaml = search.to_yaml
491
+ loaded_search = YAML.load(yaml)
492
+ loaded_search.current_scope.should == {:conditions => "1=1"}
493
+ loaded_search.name_like.should == "Ben"
494
+ loaded_search.created_at_after.should == time
495
+ end
496
+ end
497
+ end