ransack 1.7.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/SECURITY.md +12 -0
  4. data/.github/workflows/test.yml +120 -0
  5. data/.gitignore +3 -0
  6. data/CHANGELOG.md +463 -27
  7. data/CONTRIBUTING.md +52 -22
  8. data/Gemfile +24 -24
  9. data/README.md +453 -126
  10. data/Rakefile +6 -25
  11. data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +24 -0
  12. data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +79 -0
  13. data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +11 -0
  14. data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +1 -0
  15. data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +80 -0
  16. data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +1 -0
  17. data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +74 -0
  18. data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +93 -0
  19. data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +1 -0
  20. data/lib/polyamorous/join.rb +70 -0
  21. data/lib/polyamorous/polyamorous.rb +24 -0
  22. data/lib/polyamorous/swapping_reflection_class.rb +11 -0
  23. data/lib/polyamorous/tree_node.rb +7 -0
  24. data/lib/ransack/adapters/active_record/base.rb +27 -2
  25. data/lib/ransack/adapters/active_record/context.rb +213 -139
  26. data/lib/ransack/adapters/active_record/ransack/constants.rb +70 -55
  27. data/lib/ransack/adapters/active_record/ransack/context.rb +10 -18
  28. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +42 -32
  29. data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -5
  30. data/lib/ransack/adapters/active_record/ransack/visitor.rb +23 -0
  31. data/lib/ransack/adapters/active_record.rb +11 -10
  32. data/lib/ransack/adapters.rb +45 -23
  33. data/lib/ransack/configuration.rb +107 -4
  34. data/lib/ransack/constants.rb +13 -26
  35. data/lib/ransack/context.rb +45 -33
  36. data/lib/ransack/helpers/form_builder.rb +21 -12
  37. data/lib/ransack/helpers/form_helper.rb +75 -70
  38. data/lib/ransack/locale/ar.yml +70 -0
  39. data/lib/ransack/locale/az.yml +70 -0
  40. data/lib/ransack/locale/bg.yml +70 -0
  41. data/lib/ransack/locale/ca.yml +70 -0
  42. data/lib/ransack/locale/da.yml +70 -0
  43. data/lib/ransack/locale/el.yml +70 -0
  44. data/lib/ransack/locale/es.yml +22 -22
  45. data/lib/ransack/locale/fa.yml +70 -0
  46. data/lib/ransack/locale/fi.yml +71 -0
  47. data/lib/ransack/locale/id.yml +70 -0
  48. data/lib/ransack/locale/it.yml +70 -0
  49. data/lib/ransack/locale/ja.yml +70 -0
  50. data/lib/ransack/locale/nl.yml +4 -4
  51. data/lib/ransack/locale/pt-BR.yml +70 -0
  52. data/lib/ransack/locale/ru.yml +70 -0
  53. data/lib/ransack/locale/sk.yml +70 -0
  54. data/lib/ransack/locale/tr.yml +70 -0
  55. data/lib/ransack/locale/{zh.yml → zh-CN.yml} +13 -13
  56. data/lib/ransack/locale/zh-TW.yml +70 -0
  57. data/lib/ransack/nodes/attribute.rb +5 -2
  58. data/lib/ransack/nodes/bindable.rb +18 -6
  59. data/lib/ransack/nodes/condition.rb +85 -28
  60. data/lib/ransack/nodes/grouping.rb +17 -11
  61. data/lib/ransack/nodes/sort.rb +9 -5
  62. data/lib/ransack/nodes/value.rb +74 -68
  63. data/lib/ransack/nodes.rb +1 -1
  64. data/lib/ransack/predicate.rb +17 -20
  65. data/lib/ransack/search.rb +17 -8
  66. data/lib/ransack/translate.rb +115 -115
  67. data/lib/ransack/version.rb +1 -1
  68. data/lib/ransack/visitor.rb +1 -12
  69. data/lib/ransack.rb +9 -9
  70. data/logo/ransack-h.png +0 -0
  71. data/logo/ransack-h.svg +34 -0
  72. data/logo/ransack-v.png +0 -0
  73. data/logo/ransack-v.svg +34 -0
  74. data/logo/ransack.png +0 -0
  75. data/logo/ransack.svg +21 -0
  76. data/ransack.gemspec +7 -24
  77. data/spec/console.rb +4 -0
  78. data/spec/helpers/polyamorous_helper.rb +19 -0
  79. data/spec/polyamorous/join_association_spec.rb +35 -0
  80. data/spec/polyamorous/join_dependency_spec.rb +97 -0
  81. data/spec/polyamorous/join_spec.rb +19 -0
  82. data/spec/ransack/adapters/active_record/base_spec.rb +370 -75
  83. data/spec/ransack/adapters/active_record/context_spec.rb +72 -34
  84. data/spec/ransack/configuration_spec.rb +97 -14
  85. data/spec/ransack/helpers/form_builder_spec.rb +2 -11
  86. data/spec/ransack/helpers/form_helper_spec.rb +481 -113
  87. data/spec/ransack/nodes/condition_spec.rb +24 -0
  88. data/spec/ransack/nodes/grouping_spec.rb +56 -0
  89. data/spec/ransack/predicate_spec.rb +79 -5
  90. data/spec/ransack/search_spec.rb +207 -81
  91. data/spec/spec_helper.rb +8 -0
  92. data/spec/support/schema.rb +100 -42
  93. metadata +57 -184
  94. data/.travis.yml +0 -69
  95. data/lib/ransack/adapters/active_record/3.0/compat.rb +0 -179
  96. data/lib/ransack/adapters/active_record/3.0/context.rb +0 -201
  97. data/lib/ransack/adapters/active_record/3.1/context.rb +0 -215
  98. data/lib/ransack/adapters/active_record/3.2/context.rb +0 -44
  99. data/lib/ransack/adapters/active_record/compat.rb +0 -14
  100. data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
  101. data/lib/ransack/adapters/mongoid/attributes/attribute.rb +0 -37
  102. data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +0 -17
  103. data/lib/ransack/adapters/mongoid/attributes/predications.rb +0 -141
  104. data/lib/ransack/adapters/mongoid/base.rb +0 -130
  105. data/lib/ransack/adapters/mongoid/context.rb +0 -208
  106. data/lib/ransack/adapters/mongoid/inquiry_hash.rb +0 -23
  107. data/lib/ransack/adapters/mongoid/ransack/constants.rb +0 -88
  108. data/lib/ransack/adapters/mongoid/ransack/context.rb +0 -60
  109. data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +0 -27
  110. data/lib/ransack/adapters/mongoid/ransack/translate.rb +0 -13
  111. data/lib/ransack/adapters/mongoid/ransack/visitor.rb +0 -24
  112. data/lib/ransack/adapters/mongoid/table.rb +0 -35
  113. data/lib/ransack/adapters/mongoid.rb +0 -13
  114. data/spec/mongoid/adapters/mongoid/base_spec.rb +0 -276
  115. data/spec/mongoid/adapters/mongoid/context_spec.rb +0 -56
  116. data/spec/mongoid/configuration_spec.rb +0 -102
  117. data/spec/mongoid/dependencies_spec.rb +0 -8
  118. data/spec/mongoid/helpers/ransack_helper.rb +0 -11
  119. data/spec/mongoid/nodes/condition_spec.rb +0 -34
  120. data/spec/mongoid/nodes/grouping_spec.rb +0 -13
  121. data/spec/mongoid/predicate_spec.rb +0 -155
  122. data/spec/mongoid/search_spec.rb +0 -446
  123. data/spec/mongoid/support/mongoid.yml +0 -6
  124. data/spec/mongoid/support/schema.rb +0 -128
  125. data/spec/mongoid/translate_spec.rb +0 -14
  126. data/spec/mongoid_spec_helper.rb +0 -59
  127. data/spec/ransack/dependencies_spec.rb +0 -12
@@ -10,7 +10,6 @@ module Ransack
10
10
  namespace :admin do
11
11
  resources :comments
12
12
  end
13
- get ':controller(/:action(/:id(.:format)))'
14
13
  end
15
14
 
16
15
  include router.url_helpers
@@ -19,109 +18,124 @@ module Ransack
19
18
  before do
20
19
  @controller = ActionView::TestCase::TestController.new
21
20
  @controller.instance_variable_set(:@_routes, router)
22
- @controller.class_eval do
23
- include router.url_helpers
24
- end
25
-
26
- @controller.view_context_class.class_eval do
27
- include router.url_helpers
28
- end
21
+ @controller.class_eval { include router.url_helpers }
22
+ @controller.view_context_class.class_eval { include router.url_helpers }
29
23
  end
30
24
 
31
25
  describe '#sort_link with default search_key' do
32
26
  subject { @controller.view_context
33
27
  .sort_link(
34
- [:main_app, Person.search(sorts: ['name desc'])],
28
+ [:main_app, Person.ransack(sorts: ['name desc'])],
35
29
  :name,
36
30
  controller: 'people'
37
31
  )
38
32
  }
39
- it {
40
- should match(
41
- if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
42
- /people\?q%5Bs%5D=name\+asc/
43
- else
44
- /people\?q(%5B|\[)s(%5D|\])=name\+asc/
45
- end
46
- )
47
- }
33
+ it { should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/ }
48
34
  it { should match /sort_link desc/ }
49
35
  it { should match /Full Name ▼/ }
50
36
  end
51
37
 
52
- describe '#sort_link with default search_key defined as symbol' do
38
+ describe '#sort_url with default search_key' do
53
39
  subject { @controller.view_context
54
- .sort_link(
55
- Person.search(
56
- { sorts: ['name desc'] }, search_key: :people_search
57
- ),
40
+ .sort_url(
41
+ [:main_app, Person.ransack(sorts: ['name desc'])],
58
42
  :name,
59
43
  controller: 'people'
60
44
  )
61
45
  }
62
- it {
63
- should match(
64
- if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
65
- /people\?people_search%5Bs%5D=name\+asc/
66
- else
67
- /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/
68
- end
46
+ it { should match /people\?q(%5B|\[)s(%5D|\])=name\+asc/ }
47
+ end
48
+
49
+ describe '#sort_link with default search_key defined as symbol' do
50
+ subject { @controller.view_context
51
+ .sort_link(
52
+ Person.ransack({ sorts: ['name desc'] }, search_key: :people_search),
53
+ :name, controller: 'people'
69
54
  )
70
55
  }
56
+ it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ }
71
57
  end
72
58
 
73
- describe '#sort_link desc through association table defined as a symbol' do
59
+ describe '#sort_url with default search_key defined as symbol' do
60
+ subject { @controller.view_context
61
+ .sort_url(
62
+ Person.ransack({ sorts: ['name desc'] }, search_key: :people_search),
63
+ :name, controller: 'people'
64
+ )
65
+ }
66
+ it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ }
67
+ end
68
+
69
+ describe '#sort_link desc through association table defined as symbol' do
74
70
  subject { @controller.view_context
75
71
  .sort_link(
76
- Person.search({ sorts: 'comments_body asc' }),
72
+ Person.ransack({ sorts: 'comments_body asc' }),
77
73
  :comments_body,
78
74
  controller: 'people'
79
75
  )
80
76
  }
81
- it {
82
- should match(
83
- if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
84
- /people\?q%5Bs%5D=comments.body\+desc/
85
- else
86
- /people\?q(%5B|\[)s(%5D|\])=comments.body\+desc/
87
- end
88
- )
89
- }
77
+ it { should match /people\?q(%5B|\[)s(%5D|\])=comments.body\+desc/ }
90
78
  it { should match /sort_link asc/ }
91
79
  it { should match /Body ▲/ }
92
80
  end
93
81
 
82
+ describe '#sort_url desc through association table defined as symbol' do
83
+ subject { @controller.view_context
84
+ .sort_url(
85
+ Person.ransack({ sorts: 'comments_body asc' }),
86
+ :comments_body,
87
+ controller: 'people'
88
+ )
89
+ }
90
+ it { should match /people\?q(%5B|\[)s(%5D|\])=comments.body\+desc/ }
91
+ end
92
+
94
93
  describe '#sort_link through association table defined as a string' do
95
94
  subject { @controller.view_context
96
95
  .sort_link(
97
- Person.search({ sorts: 'comments.body desc' }),
96
+ Person.ransack({ sorts: 'comments.body desc' }),
98
97
  'comments.body',
99
98
  controller: 'people'
100
99
  )
101
100
  }
102
- it {
103
- should match(
104
- if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
105
- /people\?q%5Bs%5D=comments.body\+asc/
106
- else
107
- /people\?q(%5B|\[)s(%5D|\])=comments.body\+asc/
108
- end
109
- )
110
- }
101
+ it { should match /people\?q(%5B|\[)s(%5D|\])=comments.body\+asc/ }
111
102
  it { should match /sort_link desc/ }
112
103
  it { should match /Comments.body ▼/ }
113
104
  end
114
105
 
106
+ describe '#sort_url through association table defined as a string' do
107
+ subject { @controller.view_context
108
+ .sort_url(
109
+ Person.ransack({ sorts: 'comments.body desc' }),
110
+ 'comments.body',
111
+ controller: 'people'
112
+ )
113
+ }
114
+ it { should match /people\?q(%5B|\[)s(%5D|\])=comments.body\+asc/ }
115
+ end
116
+
115
117
  describe '#sort_link works even if search params are a blank string' do
116
118
  before { @controller.view_context.params[:q] = '' }
117
119
  specify {
118
120
  expect { @controller.view_context
119
121
  .sort_link(
120
- Person.search(
121
- @controller.view_context.params[:q]),
122
- :name,
123
- controller: 'people'
124
- )
122
+ Person.ransack(@controller.view_context.params[:q]),
123
+ :name,
124
+ controller: 'people'
125
+ )
126
+ }.not_to raise_error
127
+ }
128
+ end
129
+
130
+ describe '#sort_url works even if search params are a blank string' do
131
+ before { @controller.view_context.params[:q] = '' }
132
+ specify {
133
+ expect { @controller.view_context
134
+ .sort_url(
135
+ Person.ransack(@controller.view_context.params[:q]),
136
+ :name,
137
+ controller: 'people'
138
+ )
125
139
  }.not_to raise_error
126
140
  }
127
141
  end
@@ -129,28 +143,32 @@ module Ransack
129
143
  describe '#sort_link with search_key defined as a string' do
130
144
  subject { @controller.view_context
131
145
  .sort_link(
132
- Person.search(
146
+ Person.ransack(
133
147
  { sorts: ['name desc'] }, search_key: 'people_search'
134
148
  ),
135
149
  :name,
136
150
  controller: 'people'
137
151
  )
138
152
  }
139
- it {
140
- should match(
141
- if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
142
- /people\?people_search%5Bs%5D=name\+asc/
143
- else
144
- /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/
145
- end
146
- )
147
- }
153
+ it { should match /people\?people_search(%5B|\[)s(%5D|\])=name\+asc/ }
148
154
  end
149
155
 
150
156
  describe '#sort_link with default_order defined with a string key' do
151
157
  subject { @controller.view_context
152
158
  .sort_link(
153
- [:main_app, Person.search()],
159
+ [:main_app, Person.ransack()],
160
+ :name,
161
+ controller: 'people',
162
+ default_order: 'desc'
163
+ )
164
+ }
165
+ it { should_not match /default_order/ }
166
+ end
167
+
168
+ describe '#sort_url with default_order defined with a string key' do
169
+ subject { @controller.view_context
170
+ .sort_url(
171
+ [:main_app, Person.ransack()],
154
172
  :name,
155
173
  controller: 'people',
156
174
  default_order: 'desc'
@@ -162,41 +180,67 @@ module Ransack
162
180
  describe '#sort_link with multiple search_keys defined as an array' do
163
181
  subject { @controller.view_context
164
182
  .sort_link(
165
- [:main_app, Person.search(sorts: ['name desc', 'email asc'])],
183
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
166
184
  :name, [:name, 'email DESC'],
167
185
  controller: 'people'
168
186
  )
169
187
  }
170
188
  it {
171
- should match(
172
- /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
189
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
173
190
  )
174
191
  }
175
192
  it { should match /sort_link desc/ }
176
193
  it { should match /Full Name ▼/ }
177
194
  end
178
195
 
196
+ describe '#sort_url with multiple search_keys defined as an array' do
197
+ subject { @controller.view_context
198
+ .sort_url(
199
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
200
+ :name, [:name, 'email DESC'],
201
+ controller: 'people'
202
+ )
203
+ }
204
+ it {
205
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
206
+ )
207
+ }
208
+ end
209
+
179
210
  describe '#sort_link with multiple search_keys does not break on nil values & ignores them' do
180
211
  subject { @controller.view_context
181
212
  .sort_link(
182
- [:main_app, Person.search(sorts: ['name desc', nil, 'email', nil])],
213
+ [:main_app, Person.ransack(sorts: ['name desc', nil, 'email', nil])],
183
214
  :name, [nil, :name, nil, 'email DESC', nil],
184
215
  controller: 'people'
185
216
  )
186
217
  }
187
218
  it {
188
- should match(
189
- /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
219
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
190
220
  )
191
221
  }
192
222
  it { should match /sort_link desc/ }
193
223
  it { should match /Full Name ▼/ }
194
224
  end
195
225
 
226
+ describe '#sort_url with multiple search_keys does not break on nil values & ignores them' do
227
+ subject { @controller.view_context
228
+ .sort_url(
229
+ [:main_app, Person.ransack(sorts: ['name desc', nil, 'email', nil])],
230
+ :name, [nil, :name, nil, 'email DESC', nil],
231
+ controller: 'people'
232
+ )
233
+ }
234
+ it {
235
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
236
+ )
237
+ }
238
+ end
239
+
196
240
  describe '#sort_link with multiple search_keys should allow a label to be specified' do
197
241
  subject { @controller.view_context
198
242
  .sort_link(
199
- [:main_app, Person.search(sorts: ['name desc', 'email asc'])],
243
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
200
244
  :name, [:name, 'email DESC'],
201
245
  'Property Name',
202
246
  controller: 'people'
@@ -208,121 +252,194 @@ module Ransack
208
252
  describe '#sort_link with multiple search_keys should flip multiple fields specified without a direction' do
209
253
  subject { @controller.view_context
210
254
  .sort_link(
211
- [:main_app, Person.search(sorts: ['name desc', 'email asc'])],
255
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
212
256
  :name, [:name, :email],
213
257
  controller: 'people'
214
258
  )
215
259
  }
216
260
  it {
217
- should match(
218
- /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
261
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
219
262
  )
220
263
  }
221
264
  it { should match /sort_link desc/ }
222
265
  it { should match /Full Name ▼/ }
223
266
  end
224
267
 
268
+ describe '#sort_url with multiple search_keys should flip multiple fields specified without a direction' do
269
+ subject { @controller.view_context
270
+ .sort_url(
271
+ [:main_app, Person.ransack(sorts: ['name desc', 'email asc'])],
272
+ :name, [:name, :email],
273
+ controller: 'people'
274
+ )
275
+ }
276
+ it {
277
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+asc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
278
+ )
279
+ }
280
+ end
281
+
225
282
  describe '#sort_link with multiple search_keys and default_order specified as a string' do
226
283
  subject { @controller.view_context
227
284
  .sort_link(
228
- [:main_app, Person.search()],
285
+ [:main_app, Person.ransack()],
229
286
  :name, [:name, :email],
230
287
  controller: 'people',
231
288
  default_order: 'desc'
232
289
  )
233
290
  }
234
291
  it {
235
- should match(
236
- /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
292
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
237
293
  )
238
294
  }
239
295
  it { should match /sort_link/ }
240
296
  it { should match /Full Name/ }
241
297
  end
242
298
 
299
+ describe '#sort_url with multiple search_keys and default_order specified as a string' do
300
+ subject { @controller.view_context
301
+ .sort_url(
302
+ [:main_app, Person.ransack()],
303
+ :name, [:name, :email],
304
+ controller: 'people',
305
+ default_order: 'desc'
306
+ )
307
+ }
308
+ it {
309
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
310
+ )
311
+ }
312
+ end
313
+
243
314
  describe '#sort_link with multiple search_keys and default_order specified as a symbol' do
244
315
  subject { @controller.view_context
245
316
  .sort_link(
246
- [:main_app, Person.search()],
317
+ [:main_app, Person.ransack()],
247
318
  :name, [:name, :email],
248
319
  controller: 'people',
249
320
  default_order: :desc
250
321
  )
251
322
  }
252
323
  it {
253
- should match(
254
- /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
324
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
255
325
  )
256
326
  }
257
327
  it { should match /sort_link/ }
258
328
  it { should match /Full Name/ }
259
329
  end
260
330
 
331
+ describe '#sort_url with multiple search_keys and default_order specified as a symbol' do
332
+ subject { @controller.view_context
333
+ .sort_url(
334
+ [:main_app, Person.ransack],
335
+ :name, [:name, :email],
336
+ controller: 'people',
337
+ default_order: :desc
338
+ )
339
+ }
340
+ it {
341
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
342
+ )
343
+ }
344
+ end
345
+
261
346
  describe '#sort_link with multiple search_keys should allow multiple default_orders to be specified' do
262
347
  subject { @controller.view_context
263
348
  .sort_link(
264
- [:main_app, Person.search()],
349
+ [:main_app, Person.ransack],
265
350
  :name, [:name, :email],
266
351
  controller: 'people',
267
352
  default_order: { name: 'desc', email: 'asc' }
268
353
  )
269
354
  }
270
355
  it {
271
- should match(
272
- /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+asc/
356
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+asc/
273
357
  )
274
358
  }
275
359
  it { should match /sort_link/ }
276
360
  it { should match /Full Name/ }
277
361
  end
278
362
 
363
+ describe '#sort_url with multiple search_keys should allow multiple default_orders to be specified' do
364
+ subject { @controller.view_context
365
+ .sort_url(
366
+ [:main_app, Person.ransack],
367
+ :name, [:name, :email],
368
+ controller: 'people',
369
+ default_order: { name: 'desc', email: 'asc' }
370
+ )
371
+ }
372
+ it {
373
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+asc/
374
+ )
375
+ }
376
+ end
377
+
279
378
  describe '#sort_link with multiple search_keys with multiple default_orders should not override a specified order' do
280
379
  subject { @controller.view_context
281
380
  .sort_link(
282
- [:main_app, Person.search()],
381
+ [:main_app, Person.ransack],
283
382
  :name, [:name, 'email desc'],
284
383
  controller: 'people',
285
384
  default_order: { name: 'desc', email: 'asc' }
286
385
  )
287
386
  }
288
387
  it {
289
- should match(
290
- /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
388
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
291
389
  )
292
390
  }
293
391
  it { should match /sort_link/ }
294
392
  it { should match /Full Name/ }
295
393
  end
296
394
 
395
+ describe '#sort_url with multiple search_keys with multiple default_orders should not override a specified order' do
396
+ subject { @controller.view_context
397
+ .sort_url(
398
+ [:main_app, Person.ransack],
399
+ :name, [:name, 'email desc'],
400
+ controller: 'people',
401
+ default_order: { name: 'desc', email: 'asc' }
402
+ )
403
+ }
404
+ it {
405
+ should match( /people\?q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=name\+desc&q(%5B|\[)s(%5D|\])(%5B|\[)(%5D|\])=email\+desc/
406
+ )
407
+ }
408
+ end
409
+
297
410
  describe "#sort_link on polymorphic association should preserve association model name case" do
298
411
  subject { @controller.view_context
299
412
  .sort_link(
300
- [:main_app, Note.search()],
413
+ [:main_app, Note.ransack],
301
414
  :notable_of_Person_type_name, "Notable",
302
415
  controller: 'notes'
303
416
  )
304
417
  }
305
- it {
306
- should match(
307
- if ActiveRecord::VERSION::STRING =~ /^3\.[1-2]\./
308
- /notes\?q%5Bs%5D=notable_of_Person_type_name\+asc/
309
- else
310
- /notes\?q(%5B|\[)s(%5D|\])=notable_of_Person_type_name\+asc/
311
- end
312
- )
313
- }
418
+ it { should match /notes\?q(%5B|\[)s(%5D|\])=notable_of_Person_type_name\+asc/ }
314
419
  it { should match /sort_link/ }
315
420
  it { should match /Notable/ }
316
421
  end
317
422
 
423
+ describe "#sort_url on polymorphic association should preserve association model name case" do
424
+ subject { @controller.view_context
425
+ .sort_link(
426
+ [:main_app, Note.ransack],
427
+ :notable_of_Person_type_name, "Notable",
428
+ controller: 'notes'
429
+ )
430
+ }
431
+ it { should match /notes\?q(%5B|\[)s(%5D|\])=notable_of_Person_type_name\+asc/ }
432
+ end
433
+
318
434
  context 'view has existing parameters' do
319
- before do
320
- @controller.view_context.params.merge!({ exist: 'existing' })
321
- end
435
+
322
436
  describe '#sort_link should not remove existing params' do
323
- subject { @controller.view_context
324
- .sort_link(
325
- Person.search(
437
+
438
+ before { @controller.view_context.params[:exist] = 'existing' }
439
+
440
+ subject {
441
+ @controller.view_context.sort_link(
442
+ Person.ransack(
326
443
  { sorts: ['name desc'] },
327
444
  search_key: 'people_search'
328
445
  ),
@@ -330,44 +447,296 @@ module Ransack
330
447
  controller: 'people'
331
448
  )
332
449
  }
450
+
333
451
  it { should match /exist\=existing/ }
334
452
  end
453
+
454
+ describe '#sort_url should not remove existing params' do
455
+
456
+ before { @controller.view_context.params[:exist] = 'existing' }
457
+
458
+ subject {
459
+ @controller.view_context.sort_url(
460
+ Person.ransack(
461
+ { sorts: ['name desc'] },
462
+ search_key: 'people_search'
463
+ ),
464
+ :name,
465
+ controller: 'people'
466
+ )
467
+ }
468
+
469
+ it { should match /exist\=existing/ }
470
+ end
471
+
472
+ context 'using a real ActionController::Parameter object',
473
+ if: ::ActiveRecord::VERSION::MAJOR > 3 do
474
+
475
+ describe 'with symbol q:, #sort_link should include search params' do
476
+ subject { @controller.view_context.sort_link(Person.ransack, :name) }
477
+ let(:params) { ActionController::Parameters.new(
478
+ { :q => { name_eq: 'TEST' }, controller: 'people' }
479
+ ) }
480
+ before { @controller.instance_variable_set(:@params, params) }
481
+
482
+ it {
483
+ should match(
484
+ /people\?q(%5B|\[)name_eq(%5D|\])=TEST&q(%5B|\[)s(%5D|\])
485
+ =name\+asc/x,
486
+ )
487
+ }
488
+ end
489
+
490
+ describe 'with symbol q:, #sort_url should include search params' do
491
+ subject { @controller.view_context.sort_url(Person.ransack, :name) }
492
+ let(:params) { ActionController::Parameters.new(
493
+ { :q => { name_eq: 'TEST' }, controller: 'people' }
494
+ ) }
495
+ before { @controller.instance_variable_set(:@params, params) }
496
+
497
+ it {
498
+ should match(
499
+ /people\?q(%5B|\[)name_eq(%5D|\])=TEST&q(%5B|\[)s(%5D|\])
500
+ =name\+asc/x,
501
+ )
502
+ }
503
+ end
504
+
505
+ describe "with string 'q', #sort_link should include search params" do
506
+ subject { @controller.view_context.sort_link(Person.ransack, :name) }
507
+ let(:params) {
508
+ ActionController::Parameters.new(
509
+ { 'q' => { name_eq: 'Test2' }, controller: 'people' }
510
+ ) }
511
+ before { @controller.instance_variable_set(:@params, params) }
512
+
513
+ it {
514
+ should match(
515
+ /people\?q(%5B|\[)name_eq(%5D|\])=Test2&q(%5B|\[)s(%5D|\])
516
+ =name\+asc/x,
517
+ )
518
+ }
519
+ end
520
+
521
+ describe "with string 'q', #sort_url should include search params" do
522
+ subject { @controller.view_context.sort_url(Person.ransack, :name) }
523
+ let(:params) {
524
+ ActionController::Parameters.new(
525
+ { 'q' => { name_eq: 'Test2' }, controller: 'people' }
526
+ ) }
527
+ before { @controller.instance_variable_set(:@params, params) }
528
+
529
+ it {
530
+ should match(
531
+ /people\?q(%5B|\[)name_eq(%5D|\])=Test2&q(%5B|\[)s(%5D|\])
532
+ =name\+asc/x,
533
+ )
534
+ }
535
+ end
536
+ end
335
537
  end
336
538
 
337
539
  describe '#sort_link with hide order indicator set to true' do
338
540
  subject { @controller.view_context
339
541
  .sort_link(
340
- [:main_app, Person.search(sorts: ['name desc'])],
542
+ [:main_app, Person.ransack(sorts: ['name desc'])],
341
543
  :name,
342
544
  controller: 'people',
343
545
  hide_indicator: true
344
546
  )
345
547
  }
346
548
  it { should match /Full Name/ }
549
+ it { should_not match /▼|▲/ }
347
550
  end
348
551
 
349
552
  describe '#sort_link with hide order indicator set to false' do
350
553
  subject { @controller.view_context
351
554
  .sort_link(
352
- [:main_app, Person.search(sorts: ['name desc'])],
555
+ [:main_app, Person.ransack(sorts: ['name desc'])],
556
+ :name,
557
+ controller: 'people',
558
+ hide_indicator: false
559
+ )
560
+ }
561
+ it { should match /Full Name ▼/ }
562
+ end
563
+
564
+ describe '#sort_link with config set with custom up_arrow' do
565
+ before do
566
+ Ransack.configure { |c| c.custom_arrows = { up_arrow: "\u{1F446}" } }
567
+ end
568
+
569
+ after do
570
+ Ransack.configure { |c| c.custom_arrows = { up_arrow: "▼" } }
571
+ end
572
+
573
+ subject { @controller.view_context
574
+ .sort_link(
575
+ [:main_app, Person.ransack(sorts: ['name desc'])],
576
+ :name,
577
+ controller: 'people',
578
+ hide_indicator: false
579
+ )
580
+ }
581
+
582
+ it { should match /Full Name \u{1F446}/ }
583
+ end
584
+
585
+ describe '#sort_link with config set with custom down_arrow' do
586
+ before do
587
+ Ransack.configure { |c| c.custom_arrows = { down_arrow: "\u{1F447}" } }
588
+ end
589
+
590
+ after do
591
+ Ransack.configure { |c| c.custom_arrows = { down_arrow: "▲" } }
592
+ end
593
+
594
+ subject { @controller.view_context
595
+ .sort_link(
596
+ [:main_app, Person.ransack(sorts: ['name asc'])],
353
597
  :name,
354
598
  controller: 'people',
355
599
  hide_indicator: false
356
600
  )
357
601
  }
602
+
603
+ it { should match /Full Name \u{1F447}/ }
604
+ end
605
+
606
+ describe '#sort_link with config set to hide arrows' do
607
+ before do
608
+ Ransack.configure { |c| c.hide_sort_order_indicators = true }
609
+ end
610
+
611
+ after do
612
+ Ransack.configure { |c| c.hide_sort_order_indicators = false }
613
+ end
614
+
615
+ subject { @controller.view_context
616
+ .sort_link(
617
+ [:main_app, Person.ransack(sorts: ['name desc'])],
618
+ :name,
619
+ controller: 'people'
620
+ )
621
+ }
622
+
623
+ it { should_not match /▼|▲/ }
624
+ end
625
+
626
+ describe '#sort_link with config set to show arrows (default setting)' do
627
+ before do
628
+ Ransack.configure { |c| c.hide_sort_order_indicators = false }
629
+ end
630
+
631
+ subject { @controller.view_context
632
+ .sort_link(
633
+ [:main_app, Person.ransack(sorts: ['name desc'])],
634
+ :name,
635
+ controller: 'people'
636
+ )
637
+ }
638
+
358
639
  it { should match /Full Name ▼/ }
359
640
  end
360
641
 
642
+ describe '#sort_link with config set to show arrows and a default arrow set' do
643
+ before do
644
+ Ransack.configure do |c|
645
+ c.hide_sort_order_indicators = false
646
+ c.custom_arrows = { default_arrow: "defaultarrow"}
647
+ end
648
+ end
649
+
650
+ after do
651
+ Ransack.configure do |c|
652
+ c.custom_arrows = { default_arrow: nil}
653
+ end
654
+ end
655
+
656
+ subject { @controller.view_context
657
+ .sort_link(
658
+ [:main_app, Person.ransack],
659
+ :name,
660
+ controller: 'people'
661
+ )
662
+ }
663
+
664
+ it { should match /Full Name defaultarrow/ }
665
+ end
666
+
667
+ describe '#sort_link w/config to hide arrows + custom arrow, hides all' do
668
+ before do
669
+ Ransack.configure do |c|
670
+ c.hide_sort_order_indicators = true
671
+ c.custom_arrows = { down_arrow: 'down', default_arrow: "defaultarrow" }
672
+ end
673
+ end
674
+
675
+ after do
676
+ Ransack.configure do |c|
677
+ c.hide_sort_order_indicators = false
678
+ c.custom_arrows = { down_arrow: '▲' }
679
+ end
680
+ end
681
+
682
+ subject { @controller.view_context
683
+ .sort_link(
684
+ [:main_app, Person.ransack(sorts: ['name desc'])],
685
+ :name,
686
+ controller: 'people'
687
+ )
688
+ }
689
+
690
+ it { should_not match /▼|down|defaultarrow/ }
691
+ end
692
+
693
+ describe '#sort_link with config set to show arrows + custom arrow' do
694
+ before do
695
+ Ransack.configure do |c|
696
+ c.hide_sort_order_indicators = false
697
+ c.custom_arrows = { up_arrow: 'up-value' }
698
+ end
699
+ end
700
+
701
+ after do
702
+ Ransack.configure do |c|
703
+ c.hide_sort_order_indicators = false
704
+ c.custom_arrows = { up_arrow: '▼' }
705
+ end
706
+ end
707
+
708
+ subject { @controller.view_context
709
+ .sort_link(
710
+ [:main_app, Person.ransack(sorts: ['name desc'])],
711
+ :name,
712
+ controller: 'people'
713
+ )
714
+ }
715
+
716
+ it { should match /▲|up-value/ }
717
+ end
718
+
719
+ describe '#sort_link with a block' do
720
+ subject { @controller.view_context
721
+ .sort_link(
722
+ [:main_app, Person.ransack(sorts: ['name desc'])],
723
+ :name,
724
+ controller: 'people'
725
+ ) { 'Block label' }
726
+ }
727
+ it { should match /Block label ▼/ }
728
+ end
729
+
361
730
  describe '#search_form_for with default format' do
362
731
  subject { @controller.view_context
363
- .search_form_for(Person.search) {} }
732
+ .search_form_for(Person.ransack) {} }
364
733
  it { should match /action="\/people"/ }
365
734
  end
366
735
 
367
736
  describe '#search_form_for with pdf format' do
368
737
  subject {
369
738
  @controller.view_context
370
- .search_form_for(Person.search, format: :pdf) {}
739
+ .search_form_for(Person.ransack, format: :pdf) {}
371
740
  }
372
741
  it { should match /action="\/people.pdf"/ }
373
742
  end
@@ -375,7 +744,7 @@ module Ransack
375
744
  describe '#search_form_for with json format' do
376
745
  subject {
377
746
  @controller.view_context
378
- .search_form_for(Person.search, format: :json) {}
747
+ .search_form_for(Person.ransack, format: :json) {}
379
748
  }
380
749
  it { should match /action="\/people.json"/ }
381
750
  end
@@ -383,7 +752,7 @@ module Ransack
383
752
  describe '#search_form_for with an array of routes' do
384
753
  subject {
385
754
  @controller.view_context
386
- .search_form_for([:admin, Comment.search]) {}
755
+ .search_form_for([:admin, Comment.ransack]) {}
387
756
  }
388
757
  it { should match /action="\/admin\/comments"/ }
389
758
  end
@@ -394,11 +763,10 @@ module Ransack
394
763
  end
395
764
  subject {
396
765
  @controller.view_context
397
- .search_form_for(Person.search) { |f| f.text_field :name_eq }
766
+ .search_form_for(Person.ransack) { |f| f.text_field :name_eq }
398
767
  }
399
768
  it { should match /example_name_eq/ }
400
769
  end
401
-
402
770
  end
403
771
  end
404
772
  end