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,1075 @@
1
+ require 'spec_helper'
2
+
3
+ module Ransack
4
+ module Helpers
5
+ describe FormHelper do
6
+ router = ActionDispatch::Routing::RouteSet.new
7
+ router.draw do
8
+ resources :people, :notes
9
+ namespace :admin do
10
+ resources :comments
11
+ end
12
+ end
13
+
14
+ include router.url_helpers
15
+
16
+ # FIXME: figure out a cleaner way to get this behavior
17
+ before do
18
+ @controller = ActionView::TestCase::TestController.new
19
+ @controller.instance_variable_set(:@_routes, router)
20
+ @controller.class_eval { include router.url_helpers }
21
+ @controller.view_context_class.class_eval { include router.url_helpers }
22
+ end
23
+
24
+ describe '#sort_link with default search_key' do
25
+ subject { @controller.view_context
26
+ .sort_link(
27
+ [:main_app, Person.ransack(sorts: ['name desc'])],
28
+ :name,
29
+ controller: 'people'
30
+ )
31
+ }
32
+ it { should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/ }
33
+ it { should match /sort_link desc/ }
34
+ it { should match /Full Name ▼/ }
35
+ end
36
+
37
+ describe '#sort_url with default search_key' do
38
+ subject { @controller.view_context
39
+ .sort_url(
40
+ [:main_app, Person.ransack(sorts: ['name desc'])],
41
+ :name,
42
+ controller: 'people'
43
+ )
44
+ }
45
+ it { should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/ }
46
+ end
47
+
48
+ describe '#sort_link with default search_key defined as symbol' do
49
+ subject { @controller.view_context
50
+ .sort_link(
51
+ Person.ransack({ sorts: ['name desc'] }, search_key: :people_search),
52
+ :name, controller: 'people'
53
+ )
54
+ }
55
+ it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ }
56
+ end
57
+
58
+ describe '#sort_url with default search_key defined as symbol' do
59
+ subject { @controller.view_context
60
+ .sort_url(
61
+ Person.ransack({ sorts: ['name desc'] }, search_key: :people_search),
62
+ :name, controller: 'people'
63
+ )
64
+ }
65
+ it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ }
66
+ end
67
+
68
+ describe '#sort_link desc through association table defined as symbol' do
69
+ subject { @controller.view_context
70
+ .sort_link(
71
+ Person.ransack({ sorts: 'comments_body asc' }),
72
+ :comments_body,
73
+ controller: 'people'
74
+ )
75
+ }
76
+ it { should match /people\?q(%5B|\[)s(%5D|\])=comments.body\+desc/ }
77
+ it { should match /sort_link asc/ }
78
+ it { should match /Body ▲/ }
79
+ end
80
+
81
+ describe '#sort_url desc through association table defined as symbol' do
82
+ subject { @controller.view_context
83
+ .sort_url(
84
+ Person.ransack({ sorts: 'comments_body asc' }),
85
+ :comments_body,
86
+ controller: 'people'
87
+ )
88
+ }
89
+ it { should match /people\?q(%5B|\[)s(%5D|\])=comments.body\+desc/ }
90
+ end
91
+
92
+ describe '#sort_link through association table defined as a string' do
93
+ subject { @controller.view_context
94
+ .sort_link(
95
+ Person.ransack({ sorts: 'comments.body desc' }),
96
+ 'comments.body',
97
+ controller: 'people'
98
+ )
99
+ }
100
+ it { should match /people\?q(%5B|\[)s(%5D|\])=comments.body\+asc/ }
101
+ it { should match /sort_link desc/ }
102
+ it { should match /Comments.body ▼/ }
103
+ end
104
+
105
+ describe '#sort_url through association table defined as a string' do
106
+ subject { @controller.view_context
107
+ .sort_url(
108
+ Person.ransack({ sorts: 'comments.body desc' }),
109
+ 'comments.body',
110
+ controller: 'people'
111
+ )
112
+ }
113
+ it { should match /people\?q(%5B|\[)s(%5D|\])=comments.body\+asc/ }
114
+ end
115
+
116
+ describe '#sort_link works even if search params are a blank string' do
117
+ before { @controller.view_context.params[:q] = '' }
118
+ specify {
119
+ expect { @controller.view_context
120
+ .sort_link(
121
+ Person.ransack(@controller.view_context.params[:q]),
122
+ :name,
123
+ controller: 'people'
124
+ )
125
+ }.not_to raise_error
126
+ }
127
+ end
128
+
129
+ describe '#sort_url works even if search params are a blank string' do
130
+ before { @controller.view_context.params[:q] = '' }
131
+ specify {
132
+ expect { @controller.view_context
133
+ .sort_url(
134
+ Person.ransack(@controller.view_context.params[:q]),
135
+ :name,
136
+ controller: 'people'
137
+ )
138
+ }.not_to raise_error
139
+ }
140
+ end
141
+
142
+ describe '#sort_link works even if search params are a string' do
143
+ before { @controller.view_context.params[:q] = 'input error' }
144
+ specify {
145
+ expect { @controller.view_context
146
+ .sort_link(
147
+ Person.ransack({}),
148
+ :name,
149
+ controller: 'people'
150
+ )
151
+ }.not_to raise_error
152
+ }
153
+ end
154
+
155
+ describe '#sort_url works even if search params are a string' do
156
+ before { @controller.view_context.params[:q] = 'input error' }
157
+ specify {
158
+ expect { @controller.view_context
159
+ .sort_url(
160
+ Person.ransack({}),
161
+ :name,
162
+ controller: 'people'
163
+ )
164
+ }.not_to raise_error
165
+ }
166
+ end
167
+
168
+ describe '#sort_link with search_key defined as a string' do
169
+ subject { @controller.view_context
170
+ .sort_link(
171
+ Person.ransack(
172
+ { sorts: ['name desc'] }, search_key: 'people_search'
173
+ ),
174
+ :name,
175
+ controller: 'people'
176
+ )
177
+ }
178
+ it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ }
179
+ end
180
+
181
+ describe '#sort_link with default_order defined with a string key' do
182
+ subject { @controller.view_context
183
+ .sort_link(
184
+ [:main_app, Person.ransack()],
185
+ :name,
186
+ controller: 'people',
187
+ default_order: 'desc'
188
+ )
189
+ }
190
+ it { should_not match /default_order/ }
191
+ end
192
+
193
+ describe '#sort_url with default_order defined with a string key' do
194
+ subject { @controller.view_context
195
+ .sort_url(
196
+ [:main_app, Person.ransack()],
197
+ :name,
198
+ controller: 'people',
199
+ default_order: 'desc'
200
+ )
201
+ }
202
+ it { should_not match /default_order/ }
203
+ end
204
+
205
+ describe '#sort_link with multiple search_keys defined as an array' do
206
+ subject { @controller.view_context
207
+ .sort_link(
208
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
209
+ :name, [:name, 'email DESC'],
210
+ controller: 'people'
211
+ )
212
+ }
213
+ it {
214
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
215
+ )
216
+ }
217
+ it { should match /sort_link desc/ }
218
+ it { should match /Full Name ▼/ }
219
+ end
220
+
221
+ describe '#sort_url with multiple search_keys defined as an array' do
222
+ subject { @controller.view_context
223
+ .sort_url(
224
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
225
+ :name, [:name, 'email DESC'],
226
+ controller: 'people'
227
+ )
228
+ }
229
+ it {
230
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
231
+ )
232
+ }
233
+ end
234
+
235
+ describe '#sort_link with multiple search_keys does not break on nil values & ignores them' do
236
+ subject { @controller.view_context
237
+ .sort_link(
238
+ [:main_app, Person.ransack(sorts: ['name desc', nil, 'email', nil])],
239
+ :name, [nil, :name, nil, 'email DESC', nil],
240
+ controller: 'people'
241
+ )
242
+ }
243
+ it {
244
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
245
+ )
246
+ }
247
+ it { should match /sort_link desc/ }
248
+ it { should match /Full Name ▼/ }
249
+ end
250
+
251
+ describe '#sort_url with multiple search_keys does not break on nil values & ignores them' do
252
+ subject { @controller.view_context
253
+ .sort_url(
254
+ [:main_app, Person.ransack(sorts: ['name desc', nil, 'email', nil])],
255
+ :name, [nil, :name, nil, 'email DESC', nil],
256
+ controller: 'people'
257
+ )
258
+ }
259
+ it {
260
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
261
+ )
262
+ }
263
+ end
264
+
265
+ describe '#sort_link with multiple search_keys should allow a label to be specified' do
266
+ subject { @controller.view_context
267
+ .sort_link(
268
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
269
+ :name, [:name, 'email DESC'],
270
+ 'Property Name',
271
+ controller: 'people'
272
+ )
273
+ }
274
+ it { should match /Property Name ▼/ }
275
+ end
276
+
277
+ describe '#sort_link with multiple search_keys should flip multiple fields specified without a direction' do
278
+ subject { @controller.view_context
279
+ .sort_link(
280
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
281
+ :name, [:name, :email],
282
+ controller: 'people'
283
+ )
284
+ }
285
+ it {
286
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
287
+ )
288
+ }
289
+ it { should match /sort_link desc/ }
290
+ it { should match /Full Name ▼/ }
291
+ end
292
+
293
+ describe '#sort_url with multiple search_keys should flip multiple fields specified without a direction' do
294
+ subject { @controller.view_context
295
+ .sort_url(
296
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
297
+ :name, [:name, :email],
298
+ controller: 'people'
299
+ )
300
+ }
301
+ it {
302
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
303
+ )
304
+ }
305
+ end
306
+
307
+ describe '#sort_link with multiple search_keys and default_order specified as a string' do
308
+ subject { @controller.view_context
309
+ .sort_link(
310
+ [:main_app, Person.ransack()],
311
+ :name, [:name, :email],
312
+ controller: 'people',
313
+ default_order: 'desc'
314
+ )
315
+ }
316
+ it {
317
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
318
+ )
319
+ }
320
+ it { should match /sort_link/ }
321
+ it { should match /Full Name/ }
322
+ end
323
+
324
+ describe '#sort_url with multiple search_keys and default_order specified as a string' do
325
+ subject { @controller.view_context
326
+ .sort_url(
327
+ [:main_app, Person.ransack()],
328
+ :name, [:name, :email],
329
+ controller: 'people',
330
+ default_order: 'desc'
331
+ )
332
+ }
333
+ it {
334
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
335
+ )
336
+ }
337
+ end
338
+
339
+ describe '#sort_link with multiple search_keys and default_order specified as a symbol' do
340
+ subject { @controller.view_context
341
+ .sort_link(
342
+ [:main_app, Person.ransack()],
343
+ :name, [:name, :email],
344
+ controller: 'people',
345
+ default_order: :desc
346
+ )
347
+ }
348
+ it {
349
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
350
+ )
351
+ }
352
+ it { should match /sort_link/ }
353
+ it { should match /Full Name/ }
354
+ end
355
+
356
+ describe '#sort_url with multiple search_keys and default_order specified as a symbol' do
357
+ subject { @controller.view_context
358
+ .sort_url(
359
+ [:main_app, Person.ransack],
360
+ :name, [:name, :email],
361
+ controller: 'people',
362
+ default_order: :desc
363
+ )
364
+ }
365
+ it {
366
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
367
+ )
368
+ }
369
+ end
370
+
371
+ describe '#sort_link with multiple search_keys should allow multiple default_orders to be specified' do
372
+ subject { @controller.view_context
373
+ .sort_link(
374
+ [:main_app, Person.ransack],
375
+ :name, [:name, :email],
376
+ controller: 'people',
377
+ default_order: { name: 'desc', email: 'asc' }
378
+ )
379
+ }
380
+ it {
381
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+asc/
382
+ )
383
+ }
384
+ it { should match /sort_link/ }
385
+ it { should match /Full Name/ }
386
+ end
387
+
388
+ describe '#sort_url with multiple search_keys should allow multiple default_orders to be specified' do
389
+ subject { @controller.view_context
390
+ .sort_url(
391
+ [:main_app, Person.ransack],
392
+ :name, [:name, :email],
393
+ controller: 'people',
394
+ default_order: { name: 'desc', email: 'asc' }
395
+ )
396
+ }
397
+ it {
398
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+asc/
399
+ )
400
+ }
401
+ end
402
+
403
+ describe '#sort_link with multiple search_keys with multiple default_orders should not override a specified order' do
404
+ subject { @controller.view_context
405
+ .sort_link(
406
+ [:main_app, Person.ransack],
407
+ :name, [:name, 'email desc'],
408
+ controller: 'people',
409
+ default_order: { name: 'desc', email: 'asc' }
410
+ )
411
+ }
412
+ it {
413
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
414
+ )
415
+ }
416
+ it { should match /sort_link/ }
417
+ it { should match /Full Name/ }
418
+ end
419
+
420
+ describe '#sort_url with multiple search_keys with multiple default_orders should not override a specified order' do
421
+ subject { @controller.view_context
422
+ .sort_url(
423
+ [:main_app, Person.ransack],
424
+ :name, [:name, 'email desc'],
425
+ controller: 'people',
426
+ default_order: { name: 'desc', email: 'asc' }
427
+ )
428
+ }
429
+ it {
430
+ should match(/people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
431
+ )
432
+ }
433
+ end
434
+
435
+ describe "#sort_link on polymorphic association should preserve association model name case" do
436
+ subject { @controller.view_context
437
+ .sort_link(
438
+ [:main_app, Note.ransack],
439
+ :notable_of_Person_type_name, "Notable",
440
+ controller: 'notes'
441
+ )
442
+ }
443
+ it { should match /notes\?q(%5B|\[)s(%5D|\])=notable_of_Person_type_name\+asc/ }
444
+ it { should match /sort_link/ }
445
+ it { should match /Notable/ }
446
+ end
447
+
448
+ describe "#sort_url on polymorphic association should preserve association model name case" do
449
+ subject { @controller.view_context
450
+ .sort_link(
451
+ [:main_app, Note.ransack],
452
+ :notable_of_Person_type_name, "Notable",
453
+ controller: 'notes'
454
+ )
455
+ }
456
+ it { should match /notes\?q(%5B|\[)s(%5D|\])=notable_of_Person_type_name\+asc/ }
457
+ end
458
+
459
+ context 'view has existing parameters' do
460
+ describe '#sort_link should not remove existing params' do
461
+ before { @controller.view_context.params[:exist] = 'existing' }
462
+
463
+ subject {
464
+ @controller.view_context.sort_link(
465
+ Person.ransack(
466
+ { sorts: ['name desc'] },
467
+ search_key: 'people_search'
468
+ ),
469
+ :name,
470
+ controller: 'people'
471
+ )
472
+ }
473
+
474
+ it { should match /exist\=existing/ }
475
+ end
476
+
477
+ describe '#sort_url should not remove existing params' do
478
+ before { @controller.view_context.params[:exist] = 'existing' }
479
+
480
+ subject {
481
+ @controller.view_context.sort_url(
482
+ Person.ransack(
483
+ { sorts: ['name desc'] },
484
+ search_key: 'people_search'
485
+ ),
486
+ :name,
487
+ controller: 'people'
488
+ )
489
+ }
490
+
491
+ it { should match /exist\=existing/ }
492
+ end
493
+
494
+ context 'using a real ActionController::Parameter object' do
495
+ describe 'with symbol q:, #sort_link should include search params' do
496
+ subject { @controller.view_context.sort_link(Person.ransack, :name) }
497
+ let(:params) { ActionController::Parameters.new(
498
+ { q: { name_eq: 'TEST' }, controller: 'people' }
499
+ ) }
500
+
501
+ before { @controller.instance_variable_set(:@params, params) }
502
+
503
+ it {
504
+ should match(
505
+ /people\?q(%5B|\[)name_eq(%5D|\])=TEST&q(%5B|\[)s(%5D|\])
506
+ =name\+asc/x,
507
+ )
508
+ }
509
+ end
510
+
511
+ describe 'with symbol q:, #sort_url should include search params' do
512
+ subject { @controller.view_context.sort_url(Person.ransack, :name) }
513
+ let(:params) { ActionController::Parameters.new(
514
+ { q: { name_eq: 'TEST' }, controller: 'people' }
515
+ ) }
516
+
517
+ before { @controller.instance_variable_set(:@params, params) }
518
+
519
+ it {
520
+ should match(
521
+ /people\?q(%5B|\[)name_eq(%5D|\])=TEST&q(%5B|\[)s(%5D|\])
522
+ =name\+asc/x,
523
+ )
524
+ }
525
+ end
526
+
527
+ describe "with string 'q', #sort_link should include search params" do
528
+ subject { @controller.view_context.sort_link(Person.ransack, :name) }
529
+ let(:params) {
530
+ ActionController::Parameters.new(
531
+ { 'q' => { name_eq: 'Test2' }, controller: 'people' }
532
+ ) }
533
+
534
+ before { @controller.instance_variable_set(:@params, params) }
535
+
536
+ it {
537
+ should match(
538
+ /people\?q(%5B|\[)name_eq(%5D|\])=Test2&q(%5B|\[)s(%5D|\])
539
+ =name\+asc/x,
540
+ )
541
+ }
542
+ end
543
+
544
+ describe "with string 'q', #sort_url should include search params" do
545
+ subject { @controller.view_context.sort_url(Person.ransack, :name) }
546
+ let(:params) {
547
+ ActionController::Parameters.new(
548
+ { 'q' => { name_eq: 'Test2' }, controller: 'people' }
549
+ ) }
550
+
551
+ before { @controller.instance_variable_set(:@params, params) }
552
+
553
+ it {
554
+ should match(
555
+ /people\?q(%5B|\[)name_eq(%5D|\])=Test2&q(%5B|\[)s(%5D|\])
556
+ =name\+asc/x,
557
+ )
558
+ }
559
+ end
560
+ end
561
+ end
562
+
563
+ describe '#sort_link with hide order indicator set to true' do
564
+ subject { @controller.view_context
565
+ .sort_link(
566
+ [:main_app, Person.ransack(sorts: ['name desc'])],
567
+ :name,
568
+ controller: 'people',
569
+ hide_indicator: true
570
+ )
571
+ }
572
+ it { should match /Full Name/ }
573
+ it { should_not match /▼|▲/ }
574
+ end
575
+
576
+ describe '#sort_link with hide order indicator set to false' do
577
+ subject { @controller.view_context
578
+ .sort_link(
579
+ [:main_app, Person.ransack(sorts: ['name desc'])],
580
+ :name,
581
+ controller: 'people',
582
+ hide_indicator: false
583
+ )
584
+ }
585
+ it { should match /Full Name ▼/ }
586
+ end
587
+
588
+ describe '#sort_link with config set with custom up_arrow' do
589
+ before do
590
+ Ransack.configure { |c| c.custom_arrows = { up_arrow: "\u{1F446}" } }
591
+ end
592
+
593
+ after do
594
+ Ransack.configure { |c| c.custom_arrows = { up_arrow: "▼" } }
595
+ end
596
+
597
+ subject { @controller.view_context
598
+ .sort_link(
599
+ [:main_app, Person.ransack(sorts: ['name desc'])],
600
+ :name,
601
+ controller: 'people',
602
+ hide_indicator: false
603
+ )
604
+ }
605
+
606
+ it { should match /Full Name \u{1F446}/ }
607
+ end
608
+
609
+ describe '#sort_link with config set with custom down_arrow' do
610
+ before do
611
+ Ransack.configure { |c| c.custom_arrows = { down_arrow: "\u{1F447}" } }
612
+ end
613
+
614
+ after do
615
+ Ransack.configure { |c| c.custom_arrows = { down_arrow: "▲" } }
616
+ end
617
+
618
+ subject { @controller.view_context
619
+ .sort_link(
620
+ [:main_app, Person.ransack(sorts: ['name asc'])],
621
+ :name,
622
+ controller: 'people',
623
+ hide_indicator: false
624
+ )
625
+ }
626
+
627
+ it { should match /Full Name \u{1F447}/ }
628
+ end
629
+
630
+ describe '#sort_link with config set to hide arrows' do
631
+ before do
632
+ Ransack.configure { |c| c.hide_sort_order_indicators = true }
633
+ end
634
+
635
+ after do
636
+ Ransack.configure { |c| c.hide_sort_order_indicators = false }
637
+ end
638
+
639
+ subject { @controller.view_context
640
+ .sort_link(
641
+ [:main_app, Person.ransack(sorts: ['name desc'])],
642
+ :name,
643
+ controller: 'people'
644
+ )
645
+ }
646
+
647
+ it { should_not match /▼|▲/ }
648
+ end
649
+
650
+ describe '#sort_link with config set to show arrows (default setting)' do
651
+ before do
652
+ Ransack.configure { |c| c.hide_sort_order_indicators = false }
653
+ end
654
+
655
+ subject { @controller.view_context
656
+ .sort_link(
657
+ [:main_app, Person.ransack(sorts: ['name desc'])],
658
+ :name,
659
+ controller: 'people'
660
+ )
661
+ }
662
+
663
+ it { should match /Full Name ▼/ }
664
+ end
665
+
666
+ describe '#sort_link with config set to show arrows and a default arrow set' do
667
+ before do
668
+ Ransack.configure do |c|
669
+ c.hide_sort_order_indicators = false
670
+ c.custom_arrows = { default_arrow: "defaultarrow" }
671
+ end
672
+ end
673
+
674
+ after do
675
+ Ransack.configure do |c|
676
+ c.custom_arrows = { default_arrow: nil }
677
+ end
678
+ end
679
+
680
+ subject { @controller.view_context
681
+ .sort_link(
682
+ [:main_app, Person.ransack],
683
+ :name,
684
+ controller: 'people'
685
+ )
686
+ }
687
+
688
+ it { should match /Full Name defaultarrow/ }
689
+ end
690
+
691
+ describe '#sort_link w/config to hide arrows + custom arrow, hides all' do
692
+ before do
693
+ Ransack.configure do |c|
694
+ c.hide_sort_order_indicators = true
695
+ c.custom_arrows = { down_arrow: 'down', default_arrow: "defaultarrow" }
696
+ end
697
+ end
698
+
699
+ after do
700
+ Ransack.configure do |c|
701
+ c.hide_sort_order_indicators = false
702
+ c.custom_arrows = { down_arrow: '▲' }
703
+ end
704
+ end
705
+
706
+ subject { @controller.view_context
707
+ .sort_link(
708
+ [:main_app, Person.ransack(sorts: ['name desc'])],
709
+ :name,
710
+ controller: 'people'
711
+ )
712
+ }
713
+
714
+ it { should_not match /▼|down|defaultarrow/ }
715
+ end
716
+
717
+ describe '#sort_link with config set to show arrows + custom arrow' do
718
+ before do
719
+ Ransack.configure do |c|
720
+ c.hide_sort_order_indicators = false
721
+ c.custom_arrows = { up_arrow: 'up-value' }
722
+ end
723
+ end
724
+
725
+ after do
726
+ Ransack.configure do |c|
727
+ c.hide_sort_order_indicators = false
728
+ c.custom_arrows = { up_arrow: '▼' }
729
+ end
730
+ end
731
+
732
+ subject { @controller.view_context
733
+ .sort_link(
734
+ [:main_app, Person.ransack(sorts: ['name desc'])],
735
+ :name,
736
+ controller: 'people'
737
+ )
738
+ }
739
+
740
+ it { should match /▲|up-value/ }
741
+ end
742
+
743
+ describe '#sort_link with a block' do
744
+ subject { @controller.view_context
745
+ .sort_link(
746
+ [:main_app, Person.ransack(sorts: ['name desc'])],
747
+ :name,
748
+ controller: 'people'
749
+ ) { 'Block label' }
750
+ }
751
+ it { should match /Block label ▼/ }
752
+ end
753
+
754
+ describe '#sort_link with class option' do
755
+ subject { @controller.view_context
756
+ .sort_link(
757
+ [:main_app, Person.ransack(sorts: ['name desc'])],
758
+ :name,
759
+ class: 'people', controller: 'people'
760
+ )
761
+ }
762
+ it { should match /class="sort_link desc people"/ }
763
+ it { should_not match /people\?class=people/ }
764
+ end
765
+
766
+ describe '#sort_link with class option workaround' do
767
+ it "generates a correct link and prints a deprecation" do
768
+ expect do
769
+ link = @controller.view_context
770
+ .sort_link(
771
+ [:main_app, Person.ransack(sorts: ['name desc'])],
772
+ :name,
773
+ 'name',
774
+ { controller: 'people' },
775
+ class: 'people'
776
+ )
777
+
778
+ expect(link).to match(/class="sort_link desc people"/)
779
+ expect(link).not_to match(/people\?class=people/)
780
+ end.to output(
781
+ /Passing two trailing hashes to `sort_link` is deprecated, merge the trailing hashes into a single one\. \(called at #{Regexp.escape(__FILE__)}:/
782
+ ).to_stderr
783
+ end
784
+ end
785
+
786
+ describe '#sort_link with data option' do
787
+ subject { @controller.view_context
788
+ .sort_link(
789
+ [:main_app, Person.ransack(sorts: ['name desc'])],
790
+ :name,
791
+ data: { turbo_action: :advance }, controller: 'people'
792
+ )
793
+ }
794
+ it { should match /data-turbo-action="advance"/ }
795
+ it { should_not match /people\?data%5Bturbo_action%5D=advance/ }
796
+ end
797
+
798
+ describe "#sort_link with host option" do
799
+ subject { @controller.view_context
800
+ .sort_link(
801
+ [:main_app, Person.ransack(sorts: ['name desc'])],
802
+ :name,
803
+ host: 'foo', controller: 'people'
804
+ )
805
+ }
806
+ it { should match /href="\/people\?q/ }
807
+ it { should_not match /href=".*foo/ }
808
+ end
809
+
810
+ describe "#sort_link ignores host in params" do
811
+ before { @controller.view_context.params[:host] = 'other_domain' }
812
+ subject { @controller.view_context.sort_link(Person.ransack, :name, controller: 'people') }
813
+
814
+ it { should match /href="\/people\?q/ }
815
+ it { should_not match /href=".*other_domain/ }
816
+ end
817
+
818
+ describe '#search_form_for with default format' do
819
+ subject { @controller.view_context
820
+ .search_form_for(Person.ransack) {} }
821
+ it { should match /action="\/people"/ }
822
+ end
823
+
824
+ describe '#search_form_for with pdf format' do
825
+ subject {
826
+ @controller.view_context
827
+ .search_form_for(Person.ransack, format: :pdf) {}
828
+ }
829
+ it { should match /action="\/people.pdf"/ }
830
+ end
831
+
832
+ describe '#search_form_for with json format' do
833
+ subject {
834
+ @controller.view_context
835
+ .search_form_for(Person.ransack, format: :json) {}
836
+ }
837
+ it { should match /action="\/people.json"/ }
838
+ end
839
+
840
+ describe '#search_form_for with an array of routes' do
841
+ subject {
842
+ @controller.view_context
843
+ .search_form_for([:admin, Comment.ransack]) {}
844
+ }
845
+ it { should match /action="\/admin\/comments"/ }
846
+ end
847
+
848
+ describe '#search_form_for with custom default search key' do
849
+ before do
850
+ Ransack.configure { |c| c.search_key = :example }
851
+ end
852
+ after do
853
+ Ransack.configure { |c| c.search_key = :q }
854
+ end
855
+ subject {
856
+ @controller.view_context
857
+ .search_form_for(Person.ransack) { |f| f.text_field :name_eq }
858
+ }
859
+ it { should match /example_name_eq/ }
860
+ end
861
+
862
+ describe '#search_form_with with default format' do
863
+ subject { @controller.view_context
864
+ .search_form_with(model: Person.ransack) {} }
865
+ it { should match /action="\/people"/ }
866
+ end
867
+
868
+ describe '#search_form_with with pdf format' do
869
+ subject {
870
+ @controller.view_context
871
+ .search_form_with(model: Person.ransack, format: :pdf) {}
872
+ }
873
+ it { should match /action="\/people.pdf"/ }
874
+ end
875
+
876
+ describe '#search_form_with with json format' do
877
+ subject {
878
+ @controller.view_context
879
+ .search_form_with(model: Person.ransack, format: :json) {}
880
+ }
881
+ it { should match /action="\/people.json"/ }
882
+ end
883
+
884
+ describe '#search_form_with with an array of routes' do
885
+ subject {
886
+ @controller.view_context
887
+ .search_form_with(model: [:admin, Comment.ransack]) {}
888
+ }
889
+ it { should match /action="\/admin\/comments"/ }
890
+ end
891
+
892
+ describe '#search_form_with with custom default search key' do
893
+ before do
894
+ Ransack.configure { |c| c.search_key = :example }
895
+ end
896
+ after do
897
+ Ransack.configure { |c| c.search_key = :q }
898
+ end
899
+ subject {
900
+ @controller.view_context
901
+ .search_form_with(model: Person.ransack) { |f| f.text_field :name_eq }
902
+ }
903
+ it { should match /example\[name_eq\]/ }
904
+ end
905
+
906
+ describe '#search_form_with without Ransack::Search object' do
907
+ it 'raises ArgumentError' do
908
+ expect {
909
+ @controller.view_context.search_form_with(model: "not a search object") {}
910
+ }.to raise_error(ArgumentError, 'No Ransack::Search object was provided to search_form_with!')
911
+ end
912
+ end
913
+
914
+ describe '#turbo_search_form_for with default options' do
915
+ subject {
916
+ @controller.view_context
917
+ .turbo_search_form_for(Person.ransack) {}
918
+ }
919
+ it { should match /action="\/people"/ }
920
+ it { should match /method="post"/ }
921
+ it { should match /data-turbo-action="advance"/ }
922
+ end
923
+
924
+ describe '#turbo_search_form_for with custom method' do
925
+ subject {
926
+ @controller.view_context
927
+ .turbo_search_form_for(Person.ransack, method: :patch) {}
928
+ }
929
+ it { should match /method="post"/ }
930
+ it { should match /name="_method" value="patch"/ }
931
+ it { should match /data-turbo-action="advance"/ }
932
+ end
933
+
934
+ describe '#turbo_search_form_for with turbo_frame' do
935
+ subject {
936
+ @controller.view_context
937
+ .turbo_search_form_for(Person.ransack, turbo_frame: 'search_results') {}
938
+ }
939
+ it { should match /data-turbo-frame="search_results"/ }
940
+ end
941
+
942
+ describe '#turbo_search_form_for with custom turbo_action' do
943
+ subject {
944
+ @controller.view_context
945
+ .turbo_search_form_for(Person.ransack, turbo_action: 'replace') {}
946
+ }
947
+ it { should match /data-turbo-action="replace"/ }
948
+ end
949
+
950
+ describe '#turbo_search_form_for with format' do
951
+ subject {
952
+ @controller.view_context
953
+ .turbo_search_form_for(Person.ransack, format: :json) {}
954
+ }
955
+ it { should match /action="\/people.json"/ }
956
+ end
957
+
958
+ describe '#turbo_search_form_for with array of routes' do
959
+ subject {
960
+ @controller.view_context
961
+ .turbo_search_form_for([:admin, Comment.ransack]) {}
962
+ }
963
+ it { should match /action="\/admin\/comments"/ }
964
+ end
965
+
966
+ describe '#turbo_search_form_for with custom search key' do
967
+ before do
968
+ Ransack.configure { |c| c.search_key = :example }
969
+ end
970
+ after do
971
+ Ransack.configure { |c| c.search_key = :q }
972
+ end
973
+ subject {
974
+ @controller.view_context
975
+ .turbo_search_form_for(Person.ransack) { |f| f.text_field :name_eq }
976
+ }
977
+ it { should match /example_name_eq/ }
978
+ end
979
+
980
+ describe '#turbo_search_form_for without Ransack::Search object' do
981
+ it 'raises ArgumentError' do
982
+ expect {
983
+ @controller.view_context.turbo_search_form_for("not a search object") {}
984
+ }.to raise_error(ArgumentError, 'No Ransack::Search object was provided to turbo_search_form_for!')
985
+ end
986
+ end
987
+
988
+ describe 'private helper methods' do
989
+ let(:helper) { @controller.view_context }
990
+ let(:search) { Person.ransack }
991
+
992
+ describe '#build_turbo_options' do
993
+ it 'builds turbo options with frame' do
994
+ options = { turbo_frame: 'results', turbo_action: 'replace' }
995
+ result = helper.send(:build_turbo_options, options)
996
+ expect(result).to eq({
997
+ data: {
998
+ turbo_frame: 'results',
999
+ turbo_action: 'replace'
1000
+ }
1001
+ })
1002
+ expect(options).to be_empty
1003
+ end
1004
+
1005
+ it 'builds turbo options without frame' do
1006
+ options = { turbo_action: 'advance' }
1007
+ result = helper.send(:build_turbo_options, options)
1008
+ expect(result).to eq({ data: { turbo_action: 'advance' } })
1009
+ end
1010
+
1011
+ it 'uses default turbo action' do
1012
+ options = {}
1013
+ result = helper.send(:build_turbo_options, options)
1014
+ expect(result).to eq({ data: { turbo_action: 'advance' } })
1015
+ end
1016
+ end
1017
+
1018
+ describe '#build_html_options' do
1019
+ it 'builds HTML options with correct method' do
1020
+ options = { class: 'custom' }
1021
+ result = helper.send(:build_html_options, search, options, :post)
1022
+ expect(result[:method]).to eq(:post)
1023
+ expect(result[:class]).to include('custom')
1024
+ end
1025
+ end
1026
+
1027
+ describe '#extract_search_and_set_url' do
1028
+ it 'extracts search from Ransack::Search object' do
1029
+ options = {}
1030
+ result = helper.send(:extract_search_and_set_url, search, options, 'search_form_for')
1031
+ expect(result).to eq(search)
1032
+ expect(options[:url]).to match(/people/)
1033
+ end
1034
+
1035
+ it 'extracts search from array with Search object' do
1036
+ options = {}
1037
+ comment_search = Comment.ransack
1038
+ result = helper.send(:extract_search_and_set_url, [:admin, comment_search], options, 'search_form_for')
1039
+ expect(result).to eq(comment_search)
1040
+ expect(options[:url]).to match(/admin/)
1041
+ end
1042
+
1043
+ it 'raises error for invalid record with correct method name' do
1044
+ options = {}
1045
+ expect {
1046
+ helper.send(:extract_search_and_set_url, "invalid", options, 'turbo_search_form_for')
1047
+ }.to raise_error(ArgumentError, 'No Ransack::Search object was provided to turbo_search_form_for!')
1048
+ end
1049
+
1050
+ it 'extracts search from Ransack::Search object for search_form_with' do
1051
+ options = {}
1052
+ result = helper.send(:extract_search_and_set_url, search, options, 'search_form_with')
1053
+ expect(result).to eq(search)
1054
+ expect(options[:url]).to match(/people/)
1055
+ end
1056
+
1057
+ it 'extracts search from array with Search object for search_form_with' do
1058
+ options = {}
1059
+ comment_search = Comment.ransack
1060
+ result = helper.send(:extract_search_and_set_url, [:admin, comment_search], options, 'search_form_with')
1061
+ expect(result).to eq(comment_search)
1062
+ expect(options[:url]).to match(/admin/)
1063
+ end
1064
+
1065
+ it 'raises error for invalid record with correct method name for search_form_with' do
1066
+ options = {}
1067
+ expect {
1068
+ helper.send(:extract_search_and_set_url, "invalid", options, 'search_form_with')
1069
+ }.to raise_error(ArgumentError, 'No Ransack::Search object was provided to search_form_with!')
1070
+ end
1071
+ end
1072
+ end
1073
+ end
1074
+ end
1075
+ end