searchlogic 2.4.32 → 2.5.19

Sign up to get free protection for your applications and to get access to all the features.
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