mini-fast-sys 0.0.1

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 (94) hide show
  1. checksums.yaml +7 -0
  2. data/mini-fast-sys.gemspec +12 -0
  3. data/ransack-4.4.1/LICENSE +20 -0
  4. data/ransack-4.4.1/README.md +101 -0
  5. data/ransack-4.4.1/lib/polyamorous/activerecord/join_association.rb +70 -0
  6. data/ransack-4.4.1/lib/polyamorous/activerecord/join_association_7_2.rb +55 -0
  7. data/ransack-4.4.1/lib/polyamorous/activerecord/join_dependency.rb +102 -0
  8. data/ransack-4.4.1/lib/polyamorous/activerecord/reflection.rb +11 -0
  9. data/ransack-4.4.1/lib/polyamorous/join.rb +70 -0
  10. data/ransack-4.4.1/lib/polyamorous/polyamorous.rb +27 -0
  11. data/ransack-4.4.1/lib/polyamorous/swapping_reflection_class.rb +11 -0
  12. data/ransack-4.4.1/lib/polyamorous/tree_node.rb +7 -0
  13. data/ransack-4.4.1/lib/ransack/active_record.rb +14 -0
  14. data/ransack-4.4.1/lib/ransack/adapters/active_record/base.rb +152 -0
  15. data/ransack-4.4.1/lib/ransack/adapters/active_record/context.rb +373 -0
  16. data/ransack-4.4.1/lib/ransack/configuration.rb +209 -0
  17. data/ransack-4.4.1/lib/ransack/constants.rb +176 -0
  18. data/ransack-4.4.1/lib/ransack/context.rb +190 -0
  19. data/ransack-4.4.1/lib/ransack/helpers/form_builder.rb +277 -0
  20. data/ransack-4.4.1/lib/ransack/helpers/form_helper.rb +311 -0
  21. data/ransack-4.4.1/lib/ransack/helpers.rb +2 -0
  22. data/ransack-4.4.1/lib/ransack/invalid_search_error.rb +3 -0
  23. data/ransack-4.4.1/lib/ransack/locale/ar.yml +70 -0
  24. data/ransack-4.4.1/lib/ransack/locale/az.yml +70 -0
  25. data/ransack-4.4.1/lib/ransack/locale/bg.yml +70 -0
  26. data/ransack-4.4.1/lib/ransack/locale/ca.yml +70 -0
  27. data/ransack-4.4.1/lib/ransack/locale/cs.yml +70 -0
  28. data/ransack-4.4.1/lib/ransack/locale/da.yml +70 -0
  29. data/ransack-4.4.1/lib/ransack/locale/de.yml +70 -0
  30. data/ransack-4.4.1/lib/ransack/locale/el.yml +70 -0
  31. data/ransack-4.4.1/lib/ransack/locale/en.yml +70 -0
  32. data/ransack-4.4.1/lib/ransack/locale/es.yml +70 -0
  33. data/ransack-4.4.1/lib/ransack/locale/fa.yml +70 -0
  34. data/ransack-4.4.1/lib/ransack/locale/fi.yml +71 -0
  35. data/ransack-4.4.1/lib/ransack/locale/fr.yml +70 -0
  36. data/ransack-4.4.1/lib/ransack/locale/hu.yml +70 -0
  37. data/ransack-4.4.1/lib/ransack/locale/id.yml +70 -0
  38. data/ransack-4.4.1/lib/ransack/locale/it.yml +70 -0
  39. data/ransack-4.4.1/lib/ransack/locale/ja.yml +70 -0
  40. data/ransack-4.4.1/lib/ransack/locale/ko.yml +70 -0
  41. data/ransack-4.4.1/lib/ransack/locale/nl.yml +70 -0
  42. data/ransack-4.4.1/lib/ransack/locale/pt-BR.yml +70 -0
  43. data/ransack-4.4.1/lib/ransack/locale/ro.yml +70 -0
  44. data/ransack-4.4.1/lib/ransack/locale/ru.yml +70 -0
  45. data/ransack-4.4.1/lib/ransack/locale/sk.yml +70 -0
  46. data/ransack-4.4.1/lib/ransack/locale/sv.yml +70 -0
  47. data/ransack-4.4.1/lib/ransack/locale/tr.yml +70 -0
  48. data/ransack-4.4.1/lib/ransack/locale/uk.yml +72 -0
  49. data/ransack-4.4.1/lib/ransack/locale/zh-CN.yml +70 -0
  50. data/ransack-4.4.1/lib/ransack/locale/zh-TW.yml +70 -0
  51. data/ransack-4.4.1/lib/ransack/naming.rb +58 -0
  52. data/ransack-4.4.1/lib/ransack/nodes/attribute.rb +59 -0
  53. data/ransack-4.4.1/lib/ransack/nodes/bindable.rb +52 -0
  54. data/ransack-4.4.1/lib/ransack/nodes/condition.rb +399 -0
  55. data/ransack-4.4.1/lib/ransack/nodes/grouping.rb +206 -0
  56. data/ransack-4.4.1/lib/ransack/nodes/node.rb +34 -0
  57. data/ransack-4.4.1/lib/ransack/nodes/sort.rb +54 -0
  58. data/ransack-4.4.1/lib/ransack/nodes/value.rb +115 -0
  59. data/ransack-4.4.1/lib/ransack/predicate.rb +75 -0
  60. data/ransack-4.4.1/lib/ransack/ransacker.rb +24 -0
  61. data/ransack-4.4.1/lib/ransack/search.rb +195 -0
  62. data/ransack-4.4.1/lib/ransack/translate.rb +156 -0
  63. data/ransack-4.4.1/lib/ransack/version.rb +3 -0
  64. data/ransack-4.4.1/lib/ransack/visitor.rb +87 -0
  65. data/ransack-4.4.1/lib/ransack.rb +33 -0
  66. data/ransack-4.4.1/spec/console.rb +13 -0
  67. data/ransack-4.4.1/spec/factories/articles.rb +7 -0
  68. data/ransack-4.4.1/spec/factories/comments.rb +7 -0
  69. data/ransack-4.4.1/spec/factories/notes.rb +13 -0
  70. data/ransack-4.4.1/spec/factories/people.rb +10 -0
  71. data/ransack-4.4.1/spec/factories/tags.rb +5 -0
  72. data/ransack-4.4.1/spec/helpers/polyamorous_helper.rb +13 -0
  73. data/ransack-4.4.1/spec/helpers/ransack_helper.rb +9 -0
  74. data/ransack-4.4.1/spec/polyamorous/activerecord_compatibility_spec.rb +15 -0
  75. data/ransack-4.4.1/spec/polyamorous/join_association_spec.rb +29 -0
  76. data/ransack-4.4.1/spec/polyamorous/join_dependency_spec.rb +80 -0
  77. data/ransack-4.4.1/spec/polyamorous/join_spec.rb +19 -0
  78. data/ransack-4.4.1/spec/ransack/adapters/active_record/base_spec.rb +943 -0
  79. data/ransack-4.4.1/spec/ransack/adapters/active_record/context_spec.rb +219 -0
  80. data/ransack-4.4.1/spec/ransack/configuration_spec.rb +201 -0
  81. data/ransack-4.4.1/spec/ransack/helpers/form_builder_spec.rb +169 -0
  82. data/ransack-4.4.1/spec/ransack/helpers/form_helper_spec.rb +1075 -0
  83. data/ransack-4.4.1/spec/ransack/invalid_search_error_spec.rb +27 -0
  84. data/ransack-4.4.1/spec/ransack/nodes/condition_spec.rb +333 -0
  85. data/ransack-4.4.1/spec/ransack/nodes/grouping_spec.rb +111 -0
  86. data/ransack-4.4.1/spec/ransack/nodes/value_spec.rb +126 -0
  87. data/ransack-4.4.1/spec/ransack/predicate_spec.rb +504 -0
  88. data/ransack-4.4.1/spec/ransack/ransacker_spec.rb +69 -0
  89. data/ransack-4.4.1/spec/ransack/search_spec.rb +821 -0
  90. data/ransack-4.4.1/spec/ransack/translate_spec.rb +16 -0
  91. data/ransack-4.4.1/spec/spec_helper.rb +52 -0
  92. data/ransack-4.4.1/spec/support/en.yml +18 -0
  93. data/ransack-4.4.1/spec/support/schema.rb +419 -0
  94. metadata +133 -0
@@ -0,0 +1,504 @@
1
+ require 'spec_helper'
2
+
3
+ module Ransack
4
+ TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
5
+ FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
6
+
7
+ describe Predicate do
8
+ before do
9
+ @s = Search.new(Person)
10
+ end
11
+
12
+ shared_examples 'wildcard escaping' do |method, regexp|
13
+ it 'automatically converts integers to strings' do
14
+ subject.parent_id_cont = 1
15
+ expect { subject.result }.to_not raise_error
16
+ end
17
+
18
+ it "escapes '%', '.', '_' and '\\\\' in value" do
19
+ subject.send(:"#{method}=", '%._\\')
20
+ expect(subject.result.to_sql).to match(regexp)
21
+ end
22
+ end
23
+
24
+ describe 'eq' do
25
+ it 'generates an equality condition for boolean true values' do
26
+ test_boolean_equality_for(true)
27
+ end
28
+
29
+ it 'generates an equality condition for boolean false values' do
30
+ test_boolean_equality_for(false)
31
+ end
32
+
33
+ it 'does not generate a condition for nil' do
34
+ @s.awesome_eq = nil
35
+ expect(@s.result.to_sql).not_to match /WHERE/
36
+ end
37
+
38
+ it 'generates a = condition with a huge integer value' do
39
+ val = 123456789012345678901
40
+ @s.salary_eq = val
41
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
42
+ expect(@s.result.to_sql).to match /#{field} = #{val}/
43
+ end
44
+ end
45
+
46
+ describe 'lteq' do
47
+ it 'generates a <= condition with an integer column' do
48
+ val = 1000
49
+ @s.salary_lteq = val
50
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
51
+ expect(@s.result.to_sql).to match /#{field} <= #{val}/
52
+ end
53
+
54
+ it 'generates a <= condition with a string column' do
55
+ val = 'jane@doe.com'
56
+ @s.email_lteq = val
57
+ field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
58
+ expect(@s.result.to_sql).to match /#{field} <= '#{val}'/
59
+ end
60
+
61
+ it 'does not generate a condition for nil' do
62
+ @s.salary_lteq = nil
63
+ expect(@s.result.to_sql).not_to match /WHERE/
64
+ end
65
+
66
+ it 'generates a <= condition with a huge integer value' do
67
+ val = 123456789012345678901
68
+ @s.salary_lteq = val
69
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
70
+ expect(@s.result.to_sql).to match /#{field} <= #{val}/
71
+ end
72
+ end
73
+
74
+ describe 'lt' do
75
+ it 'generates a < condition with an integer column' do
76
+ val = 2000
77
+ @s.salary_lt = val
78
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
79
+ expect(@s.result.to_sql).to match /#{field} < #{val}/
80
+ end
81
+
82
+ it 'generates a < condition with a string column' do
83
+ val = 'jane@doe.com'
84
+ @s.email_lt = val
85
+ field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
86
+ expect(@s.result.to_sql).to match /#{field} < '#{val}'/
87
+ end
88
+
89
+ it 'does not generate a condition for nil' do
90
+ @s.salary_lt = nil
91
+ expect(@s.result.to_sql).not_to match /WHERE/
92
+ end
93
+
94
+ it 'generates a = condition with a huge integer value' do
95
+ val = 123456789012345678901
96
+ @s.salary_lt = val
97
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
98
+ expect(@s.result.to_sql).to match /#{field} < #{val}/
99
+ end
100
+ end
101
+
102
+ describe 'gteq' do
103
+ it 'generates a >= condition with an integer column' do
104
+ val = 300
105
+ @s.salary_gteq = val
106
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
107
+ expect(@s.result.to_sql).to match /#{field} >= #{val}/
108
+ end
109
+
110
+ it 'generates a >= condition with a string column' do
111
+ val = 'jane@doe.com'
112
+ @s.email_gteq = val
113
+ field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
114
+ expect(@s.result.to_sql).to match /#{field} >= '#{val}'/
115
+ end
116
+
117
+ it 'does not generate a condition for nil' do
118
+ @s.salary_gteq = nil
119
+ expect(@s.result.to_sql).not_to match /WHERE/
120
+ end
121
+
122
+ it 'generates a >= condition with a huge integer value' do
123
+ val = 123456789012345678901
124
+ @s.salary_gteq = val
125
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
126
+ expect(@s.result.to_sql).to match /#{field} >= #{val}/
127
+ end
128
+ end
129
+
130
+ describe 'gt' do
131
+ it 'generates a > condition with an integer column' do
132
+ val = 400
133
+ @s.salary_gt = val
134
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
135
+ expect(@s.result.to_sql).to match /#{field} > #{val}/
136
+ end
137
+
138
+ it 'generates a > condition with a string column' do
139
+ val = 'jane@doe.com'
140
+ @s.email_gt = val
141
+ field = "#{quote_table_name("people")}.#{quote_column_name("email")}"
142
+ expect(@s.result.to_sql).to match /#{field} > '#{val}'/
143
+ end
144
+
145
+ it 'does not generate a condition for nil' do
146
+ @s.salary_gt = nil
147
+ expect(@s.result.to_sql).not_to match /WHERE/
148
+ end
149
+
150
+ it 'generates a > condition with a huge integer value' do
151
+ val = 123456789012345678901
152
+ @s.salary_gt = val
153
+ field = "#{quote_table_name("people")}.#{quote_column_name("salary")}"
154
+ expect(@s.result.to_sql).to match /#{field} > #{val}/
155
+ end
156
+ end
157
+
158
+ describe 'cont' do
159
+ it_has_behavior 'wildcard escaping', :name_cont,
160
+ (case ActiveRecord::Base.connection.adapter_name
161
+ when "PostGIS", "PostgreSQL"
162
+ /"people"."name" ILIKE '%\\%\\.\\_\\\\%'/
163
+ when "Mysql2"
164
+ /`people`.`name` LIKE '%\\\\%.\\\\_\\\\\\\\%'/
165
+ else
166
+ /"people"."name" LIKE '%%._\\%'/
167
+ end) do
168
+ subject { @s }
169
+ end
170
+
171
+ it 'generates a LIKE query with value surrounded by %' do
172
+ @s.name_cont = 'ric'
173
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
174
+ expect(@s.result.to_sql).to match /#{field} I?LIKE '%ric%'/
175
+ end
176
+ end
177
+
178
+ describe 'not_cont' do
179
+ it_has_behavior 'wildcard escaping', :name_not_cont,
180
+ (case ActiveRecord::Base.connection.adapter_name
181
+ when "PostGIS", "PostgreSQL"
182
+ /"people"."name" NOT ILIKE '%\\%\\.\\_\\\\%'/
183
+ when "Mysql2"
184
+ /`people`.`name` NOT LIKE '%\\\\%.\\\\_\\\\\\\\%'/
185
+ else
186
+ /"people"."name" NOT LIKE '%%._\\%'/
187
+ end) do
188
+ subject { @s }
189
+ end
190
+
191
+ it 'generates a NOT LIKE query with value surrounded by %' do
192
+ @s.name_not_cont = 'ric'
193
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
194
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%ric%'/
195
+ end
196
+ end
197
+
198
+ describe 'i_cont' do
199
+ it_has_behavior 'wildcard escaping', :name_i_cont,
200
+ (case ActiveRecord::Base.connection.adapter_name
201
+ when "PostGIS"
202
+ /LOWER\("people"."name"\) ILIKE '%\\%\\.\\_\\\\%'/
203
+ when "PostgreSQL"
204
+ /"people"."name" ILIKE '%\\%\\.\\_\\\\%'/
205
+ when "Mysql2"
206
+ /LOWER\(`people`.`name`\) LIKE '%\\\\%.\\\\_\\\\\\\\%'/
207
+ else
208
+ /LOWER\("people"."name"\) LIKE '%%._\\%'/
209
+ end) do
210
+ subject { @s }
211
+ end
212
+
213
+ it 'generates a LIKE query with LOWER(column) and value surrounded by %' do
214
+ @s.name_i_cont = 'Ric'
215
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
216
+ expect(@s.result.to_sql).to match /[LOWER\(]?#{field}\)? I?LIKE '%ric%'/
217
+ end
218
+ end
219
+
220
+ describe 'not_i_cont' do
221
+ it_has_behavior 'wildcard escaping', :name_not_i_cont,
222
+ (case ActiveRecord::Base.connection.adapter_name
223
+ when "PostGIS"
224
+ /LOWER\("people"."name"\) NOT ILIKE '%\\%\\.\\_\\\\%'/
225
+ when "PostgreSQL"
226
+ /"people"."name" NOT ILIKE '%\\%\\.\\_\\\\%'/
227
+ when "Mysql2"
228
+ /LOWER\(`people`.`name`\) NOT LIKE '%\\\\%.\\\\_\\\\\\\\%'/
229
+ else
230
+ /LOWER\("people"."name"\) NOT LIKE '%%._\\%'/
231
+ end) do
232
+ subject { @s }
233
+ end
234
+
235
+ it 'generates a NOT LIKE query with LOWER(column) and value surrounded by %' do
236
+ @s.name_not_i_cont = 'Ric'
237
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
238
+ expect(@s.result.to_sql).to match /[LOWER\(]?#{field}\)? NOT I?LIKE '%ric%'/
239
+ end
240
+ end
241
+
242
+ describe 'start' do
243
+ it 'generates a LIKE query with value followed by %' do
244
+ @s.name_start = 'Er'
245
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
246
+ expect(@s.result.to_sql).to match /#{field} I?LIKE 'Er%'/
247
+ end
248
+
249
+ it "works with attribute names ending with '_start'" do
250
+ @s.new_start_start = 'hEy'
251
+ field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
252
+ expect(@s.result.to_sql).to match /#{field} I?LIKE 'hEy%'/
253
+ end
254
+
255
+ it "works with attribute names ending with '_end'" do
256
+ @s.stop_end_start = 'begin'
257
+ field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
258
+ expect(@s.result.to_sql).to match /#{field} I?LIKE 'begin%'/
259
+ end
260
+ end
261
+
262
+ describe 'not_start' do
263
+ it 'generates a NOT LIKE query with value followed by %' do
264
+ @s.name_not_start = 'Eri'
265
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
266
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE 'Eri%'/
267
+ end
268
+
269
+ it "works with attribute names ending with '_start'" do
270
+ @s.new_start_not_start = 'hEy'
271
+ field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
272
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE 'hEy%'/
273
+ end
274
+
275
+ it "works with attribute names ending with '_end'" do
276
+ @s.stop_end_not_start = 'begin'
277
+ field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
278
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE 'begin%'/
279
+ end
280
+ end
281
+
282
+ describe 'end' do
283
+ it 'generates a LIKE query with value preceded by %' do
284
+ @s.name_end = 'Miller'
285
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
286
+ expect(@s.result.to_sql).to match /#{field} I?LIKE '%Miller'/
287
+ end
288
+
289
+ it "works with attribute names ending with '_start'" do
290
+ @s.new_start_end = 'finish'
291
+ field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
292
+ expect(@s.result.to_sql).to match /#{field} I?LIKE '%finish'/
293
+ end
294
+
295
+ it "works with attribute names ending with '_end'" do
296
+ @s.stop_end_end = 'Ending'
297
+ field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
298
+ expect(@s.result.to_sql).to match /#{field} I?LIKE '%Ending'/
299
+ end
300
+ end
301
+
302
+ describe 'not_end' do
303
+ it 'generates a NOT LIKE query with value preceded by %' do
304
+ @s.name_not_end = 'Miller'
305
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
306
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%Miller'/
307
+ end
308
+
309
+ it "works with attribute names ending with '_start'" do
310
+ @s.new_start_not_end = 'finish'
311
+ field = "#{quote_table_name("people")}.#{quote_column_name("new_start")}"
312
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%finish'/
313
+ end
314
+
315
+ it "works with attribute names ending with '_end'" do
316
+ @s.stop_end_not_end = 'Ending'
317
+ field = "#{quote_table_name("people")}.#{quote_column_name("stop_end")}"
318
+ expect(@s.result.to_sql).to match /#{field} NOT I?LIKE '%Ending'/
319
+ end
320
+ end
321
+
322
+ describe 'true' do
323
+ it 'generates an equality condition for boolean true' do
324
+ @s.awesome_true = true
325
+ field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
326
+ expect(@s.result.to_sql).to match /#{field} = #{
327
+ ActiveRecord::Base.connection.quoted_true}/
328
+ end
329
+
330
+ it 'generates an inequality condition for boolean true' do
331
+ @s.awesome_true = false
332
+ field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
333
+ expect(@s.result.to_sql).to match /#{field} != #{
334
+ ActiveRecord::Base.connection.quoted_true}/
335
+ end
336
+ end
337
+
338
+ describe 'not_true' do
339
+ it 'generates an inequality condition for boolean true' do
340
+ @s.awesome_not_true = true
341
+ field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
342
+ expect(@s.result.to_sql).to match /#{field} != #{
343
+ ActiveRecord::Base.connection.quoted_true}/
344
+ end
345
+
346
+ it 'generates an equality condition for boolean true' do
347
+ @s.awesome_not_true = false
348
+ field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
349
+ expect(@s.result.to_sql).to match /#{field} = #{
350
+ ActiveRecord::Base.connection.quoted_true}/
351
+ end
352
+ end
353
+
354
+ describe 'false' do
355
+ it 'generates an equality condition for boolean false' do
356
+ @s.awesome_false = true
357
+ field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
358
+ expect(@s.result.to_sql).to match /#{field} = #{
359
+ ActiveRecord::Base.connection.quoted_false}/
360
+ end
361
+
362
+ it 'generates an inequality condition for boolean false' do
363
+ @s.awesome_false = false
364
+ field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
365
+ expect(@s.result.to_sql).to match /#{field} != #{
366
+ ActiveRecord::Base.connection.quoted_false}/
367
+ end
368
+ end
369
+
370
+ describe 'not_false' do
371
+ it 'generates an inequality condition for boolean false' do
372
+ @s.awesome_not_false = true
373
+ field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
374
+ expect(@s.result.to_sql).to match /#{field} != #{
375
+ ActiveRecord::Base.connection.quoted_false}/
376
+ end
377
+
378
+ it 'generates an equality condition for boolean false' do
379
+ @s.awesome_not_false = false
380
+ field = "#{quote_table_name("people")}.#{quote_column_name("awesome")}"
381
+ expect(@s.result.to_sql).to match /#{field} = #{
382
+ ActiveRecord::Base.connection.quoted_false}/
383
+ end
384
+ end
385
+
386
+ describe 'null' do
387
+ it 'generates a value IS NULL query' do
388
+ @s.name_null = true
389
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
390
+ expect(@s.result.to_sql).to match /#{field} IS NULL/
391
+ end
392
+
393
+ it 'generates a value IS NOT NULL query when assigned false' do
394
+ @s.name_null = false
395
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
396
+ expect(@s.result.to_sql).to match /#{field} IS NOT NULL/
397
+ end
398
+ end
399
+
400
+ describe 'not_null' do
401
+ it 'generates a value IS NOT NULL query' do
402
+ @s.name_not_null = true
403
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
404
+ expect(@s.result.to_sql).to match /#{field} IS NOT NULL/
405
+ end
406
+
407
+ it 'generates a value IS NULL query when assigned false' do
408
+ @s.name_not_null = false
409
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
410
+ expect(@s.result.to_sql).to match /#{field} IS NULL/
411
+ end
412
+
413
+ describe 'with association query' do
414
+ it 'generates a value IS NOT NULL query' do
415
+ @s.comments_id_not_null = true
416
+ sql = @s.result.to_sql
417
+ parent_field = "#{quote_table_name("people")}.#{quote_column_name("id")}"
418
+ expect(sql).to match /#{parent_field} IN/
419
+ field = "#{quote_table_name("comments")}.#{quote_column_name("id")}"
420
+ expect(sql).to match /#{field} IS NOT NULL/
421
+ expect(sql).not_to match /AND NOT/
422
+ end
423
+
424
+ it 'generates a value IS NULL query when assigned false' do
425
+ @s.comments_id_not_null = false
426
+ sql = @s.result.to_sql
427
+ parent_field = "#{quote_table_name("people")}.#{quote_column_name("id")}"
428
+ expect(sql).to match /#{parent_field} NOT IN/
429
+ field = "#{quote_table_name("comments")}.#{quote_column_name("id")}"
430
+ expect(sql).to match /#{field} IS NULL/
431
+ expect(sql).to match /AND NOT/
432
+ end
433
+ end
434
+ end
435
+
436
+ describe 'present' do
437
+ it %q[generates a value IS NOT NULL AND value != '' query] do
438
+ @s.name_present = true
439
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
440
+ expect(@s.result.to_sql).to match /#{field} IS NOT NULL AND #{field} != ''/
441
+ end
442
+
443
+ it %q[generates a value IS NULL OR value = '' query when assigned false] do
444
+ @s.name_present = false
445
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
446
+ expect(@s.result.to_sql).to match /#{field} IS NULL OR #{field} = ''/
447
+ end
448
+ end
449
+
450
+ describe 'blank' do
451
+ it %q[generates a value IS NULL OR value = '' query] do
452
+ @s.name_blank = true
453
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
454
+ expect(@s.result.to_sql).to match /#{field} IS NULL OR #{field} = ''/
455
+ end
456
+
457
+ it %q[generates a value IS NOT NULL AND value != '' query when assigned false] do
458
+ @s.name_blank = false
459
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
460
+ expect(@s.result.to_sql).to match /#{field} IS NOT NULL AND #{field} != ''/
461
+ end
462
+ end
463
+
464
+ context "defining custom predicates" do
465
+ describe "with 'not_in' arel predicate" do
466
+ before do
467
+ Ransack.configure { |c| c.add_predicate "not_in_csv", arel_predicate: "not_in", formatter: proc { |v| v.split(",") } }
468
+ end
469
+
470
+ it 'generates a value IS NOT NULL query' do
471
+ @s.name_not_in_csv = ["a", "b"]
472
+ field = "#{quote_table_name("people")}.#{quote_column_name("name")}"
473
+ expect(@s.result.to_sql).to match /#{field} NOT IN \('a', 'b'\)/
474
+ end
475
+ end
476
+ end
477
+
478
+ private
479
+
480
+ def test_boolean_equality_for(boolean_value)
481
+ query = expected_query(boolean_value)
482
+ test_values_for(boolean_value).each do |value|
483
+ s = Search.new(Person, awesome_eq: value)
484
+ expect(s.result.to_sql).to match query
485
+ end
486
+ end
487
+
488
+ def test_values_for(boolean_value)
489
+ case boolean_value
490
+ when true
491
+ TRUE_VALUES
492
+ when false
493
+ FALSE_VALUES
494
+ end
495
+ end
496
+
497
+ def expected_query(value, attribute = 'awesome', operator = '=')
498
+ field = "#{quote_table_name("people")}.#{quote_column_name(attribute)}"
499
+ quoted_value = ActiveRecord::Base.connection.quote(value)
500
+ /#{field} #{operator} #{quoted_value}/
501
+ end
502
+ end
503
+
504
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ module Ransack
4
+ describe Ransacker do
5
+ let(:klass) { Person }
6
+ let(:name) { :test_ransacker }
7
+ let(:opts) { {} }
8
+
9
+ describe '#initialize' do
10
+ context 'with minimal options' do
11
+ subject { Ransacker.new(klass, name, opts) }
12
+
13
+ it 'sets the name' do
14
+ expect(subject.name).to eq(name)
15
+ end
16
+
17
+ it 'sets default type to string' do
18
+ expect(subject.type).to eq(:string)
19
+ end
20
+
21
+ it 'sets default args to [:parent]' do
22
+ expect(subject.args).to eq([:parent])
23
+ end
24
+ end
25
+
26
+ context 'with custom options' do
27
+ let(:opts) { { type: :integer, args: [:parent, :custom_arg], formatter: proc { |v| v.to_i } } }
28
+
29
+ subject { Ransacker.new(klass, name, opts) }
30
+
31
+ it 'sets the custom type' do
32
+ expect(subject.type).to eq(:integer)
33
+ end
34
+
35
+ it 'sets the custom args' do
36
+ expect(subject.args).to eq([:parent, :custom_arg])
37
+ end
38
+
39
+ it 'sets the formatter' do
40
+ expect(subject.formatter).to eq(opts[:formatter])
41
+ end
42
+ end
43
+
44
+ context 'with callable option' do
45
+ let(:callable) { proc { |parent| parent.table[:id] } }
46
+ let(:opts) { { callable: callable } }
47
+
48
+ subject { Ransacker.new(klass, name, opts) }
49
+
50
+ it 'initializes successfully' do
51
+ expect(subject).to be_a(Ransacker)
52
+ end
53
+ end
54
+ end
55
+
56
+ describe 'basic functionality' do
57
+ subject { Ransacker.new(klass, name, opts) }
58
+
59
+ it 'responds to required methods' do
60
+ expect(subject).to respond_to(:name)
61
+ expect(subject).to respond_to(:type)
62
+ expect(subject).to respond_to(:args)
63
+ expect(subject).to respond_to(:formatter)
64
+ expect(subject).to respond_to(:attr_from)
65
+ expect(subject).to respond_to(:call)
66
+ end
67
+ end
68
+ end
69
+ end