ransack 1.7.0 → 2.4.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 (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