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