shoulda-matchers 3.0.0.rc1 → 3.0.0
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.
- checksums.yaml +4 -4
- data/Gemfile +2 -3
- data/Gemfile.lock +12 -41
- data/NEWS.md +118 -26
- data/README.md +34 -11
- data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +0 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/style.css +4 -0
- data/gemfiles/4.0.0.gemfile +2 -3
- data/gemfiles/4.0.0.gemfile.lock +47 -77
- data/gemfiles/4.0.1.gemfile +2 -3
- data/gemfiles/4.0.1.gemfile.lock +51 -79
- data/gemfiles/4.1.gemfile +2 -3
- data/gemfiles/4.1.gemfile.lock +73 -103
- data/gemfiles/4.2.gemfile +2 -3
- data/gemfiles/4.2.gemfile.lock +90 -124
- data/lib/shoulda/matchers.rb +1 -0
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +6 -8
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +1 -3
- data/lib/shoulda/matchers/action_controller/flash_store.rb +1 -8
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +140 -88
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +2 -5
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +5 -10
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +2 -4
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +1 -3
- data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +3 -5
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -7
- data/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +35 -9
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model.rb +57 -1
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +2 -5
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +162 -54
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +5 -2
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +1 -3
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +24 -11
- data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +0 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +2 -1
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +15 -13
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +8 -8
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +8 -8
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +12 -14
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +10 -4
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +0 -3
- data/lib/shoulda/matchers/active_model/validator.rb +0 -8
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +4 -6
- data/lib/shoulda/matchers/active_record/association_matcher.rb +58 -43
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +3 -5
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +3 -5
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +1 -4
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +3 -5
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +7 -7
- data/lib/shoulda/matchers/doublespeak/double.rb +10 -1
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +13 -5
- data/lib/shoulda/matchers/doublespeak/method_call.rb +10 -1
- data/lib/shoulda/matchers/doublespeak/object_double.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/world.rb +10 -0
- data/lib/shoulda/matchers/error.rb +4 -0
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +11 -10
- data/lib/shoulda/matchers/integrations/libraries.rb +1 -0
- data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/active_model.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/active_record.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -1
- data/lib/shoulda/matchers/integrations/libraries/routing.rb +27 -0
- data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/rspec.rb +2 -2
- data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +1 -1
- data/lib/shoulda/matchers/routing.rb +10 -0
- data/lib/shoulda/matchers/version.rb +1 -1
- data/script/SUPPORTED_VERSIONS +1 -1
- data/spec/acceptance/independent_matchers_spec.rb +103 -42
- data/spec/doublespeak_spec_helper.rb +5 -1
- data/spec/support/acceptance/adds_shoulda_matchers_to_project.rb +34 -11
- data/spec/support/acceptance/helpers/rspec_helpers.rb +9 -13
- data/spec/support/acceptance/helpers/step_helpers.rb +13 -0
- data/spec/support/acceptance/matchers/have_output.rb +1 -1
- data/spec/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +1 -1
- data/spec/support/tests/command_runner.rb +5 -1
- data/spec/support/unit/helpers/active_record_versions.rb +0 -4
- data/spec/support/unit/shared_examples/set_session_or_flash.rb +8 -3
- data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +198 -39
- data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +269 -102
- data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +24 -0
- data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +118 -101
- data/spec/unit/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +0 -82
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +148 -121
- data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +20 -8
- data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +64 -183
- data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +14 -0
- data/spec/unit/shoulda/matchers/doublespeak/double_collection_spec.rb +60 -0
- data/spec/unit/shoulda/matchers/doublespeak/double_spec.rb +23 -7
- data/spec/unit/shoulda/matchers/routing/route_matcher_spec.rb +242 -0
- data/spec/unit_spec_helper.rb +4 -0
- data/tasks/documentation.rb +35 -0
- metadata +9 -8
- data/Guardfile +0 -5
- data/cucumber.yml +0 -1
- data/lib/shoulda/matchers/active_model/validator_with_captured_range_error.rb +0 -12
data/lib/shoulda/matchers.rb
CHANGED
@@ -14,7 +14,7 @@ module Shoulda
|
|
14
14
|
# it { should_not use_before_filter(:prevent_ssl) }
|
15
15
|
# end
|
16
16
|
#
|
17
|
-
# #
|
17
|
+
# # Minitest (Shoulda)
|
18
18
|
# class UsersControllerTest < ActionController::TestCase
|
19
19
|
# should use_before_filter(:authenticate_user!)
|
20
20
|
# should_not use_before_filter(:prevent_ssl)
|
@@ -39,7 +39,7 @@ module Shoulda
|
|
39
39
|
# it { should_not use_after_filter(:destroy_user) }
|
40
40
|
# end
|
41
41
|
#
|
42
|
-
# #
|
42
|
+
# # Minitest (Shoulda)
|
43
43
|
# class IssuesControllerTest < ActionController::TestCase
|
44
44
|
# should use_after_filter(:log_activity)
|
45
45
|
# should_not use_after_filter(:destroy_user)
|
@@ -64,7 +64,7 @@ module Shoulda
|
|
64
64
|
# it { should_not use_before_action(:prevent_ssl) }
|
65
65
|
# end
|
66
66
|
#
|
67
|
-
# #
|
67
|
+
# # Minitest (Shoulda)
|
68
68
|
# class UsersControllerTest < ActionController::TestCase
|
69
69
|
# should use_before_action(:authenticate_user!)
|
70
70
|
# should_not use_before_action(:prevent_ssl)
|
@@ -89,7 +89,7 @@ module Shoulda
|
|
89
89
|
# it { should_not use_after_action(:destroy_user) }
|
90
90
|
# end
|
91
91
|
#
|
92
|
-
# #
|
92
|
+
# # Minitest (Shoulda)
|
93
93
|
# class IssuesControllerTest < ActionController::TestCase
|
94
94
|
# should use_after_action(:log_activity)
|
95
95
|
# should_not use_after_action(:destroy_user)
|
@@ -114,7 +114,7 @@ module Shoulda
|
|
114
114
|
# it { should_not use_around_filter(:save_view_context) }
|
115
115
|
# end
|
116
116
|
#
|
117
|
-
# #
|
117
|
+
# # Minitest (Shoulda)
|
118
118
|
# class ChangesControllerTest < ActionController::TestCase
|
119
119
|
# should use_around_filter(:wrap_in_transaction)
|
120
120
|
# should_not use_around_filter(:save_view_context)
|
@@ -139,7 +139,7 @@ module Shoulda
|
|
139
139
|
# it { should_not use_around_action(:save_view_context) }
|
140
140
|
# end
|
141
141
|
#
|
142
|
-
# #
|
142
|
+
# # Minitest (Shoulda)
|
143
143
|
# class ChangesControllerTest < ActionController::TestCase
|
144
144
|
# should use_around_action(:wrap_in_transaction)
|
145
145
|
# should_not use_around_action(:save_view_context)
|
@@ -169,12 +169,10 @@ module Shoulda
|
|
169
169
|
def failure_message
|
170
170
|
"Expected that #{controller_class.name} would have :#{method_name} as a #{kind}_#{callback_type}"
|
171
171
|
end
|
172
|
-
alias failure_message_for_should failure_message
|
173
172
|
|
174
173
|
def failure_message_when_negated
|
175
174
|
"Expected that #{controller_class.name} would not have :#{method_name} as a #{kind}_#{callback_type}"
|
176
175
|
end
|
177
|
-
alias failure_message_for_should_not failure_message_when_negated
|
178
176
|
|
179
177
|
def description
|
180
178
|
"have :#{method_name} as a #{kind}_#{callback_type}"
|
@@ -14,7 +14,7 @@ module Shoulda
|
|
14
14
|
# it { should filter_param(:secret_key) }
|
15
15
|
# end
|
16
16
|
#
|
17
|
-
# #
|
17
|
+
# # Minitest (Shoulda)
|
18
18
|
# class ApplicationControllerTest < ActionController::TestCase
|
19
19
|
# should filter_param(:secret_key)
|
20
20
|
# end
|
@@ -38,12 +38,10 @@ module Shoulda
|
|
38
38
|
def failure_message
|
39
39
|
"Expected #{@key} to be filtered; filtered keys: #{filtered_keys.join(', ')}"
|
40
40
|
end
|
41
|
-
alias failure_message_for_should failure_message
|
42
41
|
|
43
42
|
def failure_message_when_negated
|
44
43
|
"Did not expect #{@key} to be filtered"
|
45
44
|
end
|
46
|
-
alias failure_message_for_should_not failure_message_when_negated
|
47
45
|
|
48
46
|
def description
|
49
47
|
"filter #{@key}"
|
@@ -26,7 +26,7 @@ module Shoulda
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def has_key?(key)
|
29
|
-
values_to_check.include?(key)
|
29
|
+
values_to_check.include?(key.to_s)
|
30
30
|
end
|
31
31
|
|
32
32
|
def has_value?(expected_value)
|
@@ -54,7 +54,6 @@ module Shoulda
|
|
54
54
|
controller.flash.dup.tap do |flash|
|
55
55
|
copy_flashes(controller.flash, flash)
|
56
56
|
copy_discard_if_necessary(controller.flash, flash)
|
57
|
-
# sweep_flash_if_necessary(flash)
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
@@ -68,12 +67,6 @@ module Shoulda
|
|
68
67
|
new_flash.instance_variable_set('@discard', discard)
|
69
68
|
end
|
70
69
|
|
71
|
-
def sweep_flash_if_necessary(flash)
|
72
|
-
unless @use_now
|
73
|
-
flash.sweep
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
70
|
def set_values
|
78
71
|
flash.instance_variable_get('@flashes')
|
79
72
|
end
|
@@ -37,17 +37,35 @@ module Shoulda
|
|
37
37
|
# # RSpec
|
38
38
|
# describe UsersController do
|
39
39
|
# it do
|
40
|
+
# params = {
|
41
|
+
# user: {
|
42
|
+
# first_name: 'John',
|
43
|
+
# last_name: 'Doe',
|
44
|
+
# email: 'johndoe@example.com',
|
45
|
+
# password: 'password'
|
46
|
+
# }
|
47
|
+
# }
|
40
48
|
# should permit(:first_name, :last_name, :email, :password).
|
41
|
-
# for(:create).
|
49
|
+
# for(:create, params: params).
|
42
50
|
# on(:user)
|
43
51
|
# end
|
44
52
|
# end
|
45
53
|
#
|
46
|
-
# #
|
54
|
+
# # Minitest (Shoulda)
|
47
55
|
# class UsersControllerTest < ActionController::TestCase
|
48
|
-
# should
|
49
|
-
#
|
50
|
-
#
|
56
|
+
# should "(for POST #create) restrict parameters on :user to first_name, last_name, email, and password" do
|
57
|
+
# params = {
|
58
|
+
# user: {
|
59
|
+
# first_name: 'John',
|
60
|
+
# last_name: 'Doe',
|
61
|
+
# email: 'johndoe@example.com',
|
62
|
+
# password: 'password'
|
63
|
+
# }
|
64
|
+
# }
|
65
|
+
# should permit(:first_name, :last_name, :email, :password).
|
66
|
+
# for(:create, params: params).
|
67
|
+
# on(:user)
|
68
|
+
# end
|
51
69
|
# end
|
52
70
|
#
|
53
71
|
# If your action requires query parameters in order to work, then you'll
|
@@ -83,21 +101,41 @@ module Shoulda
|
|
83
101
|
# end
|
84
102
|
#
|
85
103
|
# it do
|
104
|
+
# params = {
|
105
|
+
# id: 1,
|
106
|
+
# user: {
|
107
|
+
# first_name: 'Jon',
|
108
|
+
# last_name: 'Doe',
|
109
|
+
# email: 'jondoe@example.com',
|
110
|
+
# password: 'password'
|
111
|
+
# }
|
112
|
+
# }
|
86
113
|
# should permit(:first_name, :last_name, :email, :password).
|
87
|
-
# for(:update, params:
|
114
|
+
# for(:update, params: params).
|
88
115
|
# on(:user)
|
89
116
|
# end
|
90
117
|
# end
|
91
118
|
#
|
92
|
-
# #
|
119
|
+
# # Minitest (Shoulda)
|
93
120
|
# class UsersControllerTest < ActionController::TestCase
|
94
121
|
# setup do
|
95
122
|
# create(:user, id: 1)
|
96
123
|
# end
|
97
124
|
#
|
98
|
-
# should
|
99
|
-
#
|
100
|
-
#
|
125
|
+
# should "(for PATCH #update) restrict parameters on :user to :first_name, :last_name, :email, and :password" do
|
126
|
+
# params = {
|
127
|
+
# id: 1,
|
128
|
+
# user: {
|
129
|
+
# first_name: 'Jon',
|
130
|
+
# last_name: 'Doe',
|
131
|
+
# email: 'jondoe@example.com',
|
132
|
+
# password: 'password'
|
133
|
+
# }
|
134
|
+
# }
|
135
|
+
# should permit(:first_name, :last_name, :email, :password).
|
136
|
+
# for(:update, params: params).
|
137
|
+
# on(:user)
|
138
|
+
# end
|
101
139
|
# end
|
102
140
|
#
|
103
141
|
# Finally, if you have an action that isn't one of the seven resourceful
|
@@ -136,21 +174,25 @@ module Shoulda
|
|
136
174
|
# end
|
137
175
|
#
|
138
176
|
# it do
|
177
|
+
# params = { id: 1, user: { activated: true } }
|
139
178
|
# should permit(:activated).
|
140
|
-
# for(:toggle, params:
|
179
|
+
# for(:toggle, params: params, verb: :put).
|
141
180
|
# on(:user)
|
142
181
|
# end
|
143
182
|
# end
|
144
183
|
#
|
145
|
-
# #
|
184
|
+
# # Minitest (Shoulda)
|
146
185
|
# class UsersControllerTest < ActionController::TestCase
|
147
186
|
# setup do
|
148
187
|
# create(:user, id: 1)
|
149
188
|
# end
|
150
189
|
#
|
151
|
-
# should
|
152
|
-
#
|
153
|
-
#
|
190
|
+
# should "(for PUT #toggle) restrict parameters on :user to :activated" do
|
191
|
+
# params = { id: 1, user: { activated: true } }
|
192
|
+
# should permit(:activated).
|
193
|
+
# for(:toggle, params: params, verb: :put).
|
194
|
+
# on(:user)
|
195
|
+
# end
|
154
196
|
# end
|
155
197
|
#
|
156
198
|
# @return [PermitMatcher]
|
@@ -163,13 +205,13 @@ module Shoulda
|
|
163
205
|
class PermitMatcher
|
164
206
|
attr_writer :stubbed_params
|
165
207
|
|
166
|
-
def initialize(
|
167
|
-
@
|
208
|
+
def initialize(expected_permitted_parameter_names)
|
209
|
+
@expected_permitted_parameter_names = expected_permitted_parameter_names
|
168
210
|
@action = nil
|
169
211
|
@verb = nil
|
170
212
|
@request_params = {}
|
171
|
-
@
|
172
|
-
@
|
213
|
+
@subparameter_name = nil
|
214
|
+
@parameters_double_registry = CompositeParametersDoubleRegistry.new
|
173
215
|
end
|
174
216
|
|
175
217
|
def for(action, options = {})
|
@@ -184,9 +226,8 @@ module Shoulda
|
|
184
226
|
self
|
185
227
|
end
|
186
228
|
|
187
|
-
def on(
|
188
|
-
@
|
189
|
-
@parameters_doubles = SliceOfParametersDoubles.new(subparameter)
|
229
|
+
def on(subparameter_name)
|
230
|
+
@subparameter_name = subparameter_name
|
190
231
|
self
|
191
232
|
end
|
192
233
|
|
@@ -196,78 +237,84 @@ module Shoulda
|
|
196
237
|
end
|
197
238
|
|
198
239
|
def description
|
199
|
-
"(
|
240
|
+
"(for #{verb.upcase} ##{action}) " + expectation
|
200
241
|
end
|
201
242
|
|
202
243
|
def matches?(controller)
|
203
244
|
@controller = controller
|
204
245
|
ensure_action_and_verb_present!
|
205
246
|
|
206
|
-
|
247
|
+
parameters_double_registry.register
|
207
248
|
|
208
249
|
Doublespeak.with_doubles_activated do
|
209
250
|
context.__send__(verb, action, request_params)
|
210
251
|
end
|
211
252
|
|
212
|
-
|
253
|
+
unpermitted_parameter_names.empty?
|
213
254
|
end
|
214
255
|
|
215
256
|
def failure_message
|
216
257
|
"Expected #{verb.upcase} ##{action} to #{expectation},\nbut #{reality}."
|
217
258
|
end
|
218
|
-
alias failure_message_for_should failure_message
|
219
259
|
|
220
260
|
def failure_message_when_negated
|
221
261
|
"Expected #{verb.upcase} ##{action} not to #{expectation},\nbut it did."
|
222
262
|
end
|
223
|
-
alias failure_message_for_should_not failure_message_when_negated
|
224
263
|
|
225
264
|
protected
|
226
265
|
|
227
|
-
attr_reader :controller, :
|
228
|
-
:request_params, :
|
229
|
-
:
|
266
|
+
attr_reader :controller, :double_collections_by_parameter_name, :action, :verb,
|
267
|
+
:request_params, :expected_permitted_parameter_names, :context, :subparameter_name,
|
268
|
+
:parameters_double_registry
|
230
269
|
|
231
270
|
def expectation
|
232
271
|
message = 'restrict parameters '
|
233
272
|
|
234
|
-
if
|
235
|
-
message << "
|
273
|
+
if subparameter_name
|
274
|
+
message << "on #{subparameter_name.inspect} "
|
236
275
|
end
|
237
276
|
|
238
|
-
message << 'to ' +
|
277
|
+
message << 'to ' + format_parameter_names(expected_permitted_parameter_names)
|
239
278
|
|
240
279
|
message
|
241
280
|
end
|
242
281
|
|
243
282
|
def reality
|
244
|
-
if
|
283
|
+
if actual_permitted_parameter_names.empty?
|
245
284
|
'it did not restrict any parameters'
|
246
285
|
else
|
247
286
|
'the restricted parameters were ' +
|
248
|
-
|
287
|
+
format_parameter_names(actual_permitted_parameter_names) +
|
249
288
|
' instead'
|
250
289
|
end
|
251
290
|
end
|
252
291
|
|
253
|
-
def
|
254
|
-
|
292
|
+
def format_parameter_names(parameter_names)
|
293
|
+
parameter_names.map(&:inspect).to_sentence
|
255
294
|
end
|
256
295
|
|
257
|
-
def
|
258
|
-
|
296
|
+
def actual_permitted_parameter_names
|
297
|
+
@_actual_permitted_parameter_names ||= begin
|
298
|
+
if subparameter_name
|
299
|
+
options = { for: subparameter_name }
|
300
|
+
else
|
301
|
+
options = {}
|
302
|
+
end
|
303
|
+
|
304
|
+
parameters_double_registry.permitted_parameter_names(options)
|
305
|
+
end
|
259
306
|
end
|
260
307
|
|
261
308
|
def permit_called?
|
262
|
-
|
309
|
+
actual_permitted_parameter_names.any?
|
263
310
|
end
|
264
311
|
|
265
|
-
def
|
266
|
-
|
312
|
+
def unpermitted_parameter_names
|
313
|
+
expected_permitted_parameter_names - actual_permitted_parameter_names
|
267
314
|
end
|
268
315
|
|
269
|
-
def
|
270
|
-
|
316
|
+
def verified_permitted_parameter_names
|
317
|
+
expected_permitted_parameter_names & actual_permitted_parameter_names
|
271
318
|
end
|
272
319
|
|
273
320
|
def ensure_action_and_verb_present!
|
@@ -287,57 +334,63 @@ module Shoulda
|
|
287
334
|
end
|
288
335
|
end
|
289
336
|
|
290
|
-
def
|
291
|
-
|
337
|
+
def parameter_names_as_sentence
|
338
|
+
expected_permitted_parameter_names.map(&:inspect).to_sentence
|
292
339
|
end
|
293
340
|
|
294
341
|
# @private
|
295
|
-
class
|
296
|
-
def self.permitted_params_within(double_collection)
|
297
|
-
double_collection.calls_to(:permit).map(&:args).flatten
|
298
|
-
end
|
299
|
-
|
342
|
+
class CompositeParametersDoubleRegistry
|
300
343
|
def initialize
|
301
|
-
|
302
|
-
@double_collection = Doublespeak.double_collection_for(klass)
|
344
|
+
@parameters_double_registries_by_params = {}
|
303
345
|
end
|
304
346
|
|
305
347
|
def register
|
306
|
-
double_collection.
|
348
|
+
double_collection = Doublespeak.double_collection_for(
|
349
|
+
::ActionController::Parameters.singleton_class
|
350
|
+
)
|
351
|
+
double_collection.register_proxy(:new).to_return do |call|
|
352
|
+
params = call.return_value
|
353
|
+
parameters_double_registry = ParametersDoubleRegistry.new(params)
|
354
|
+
parameters_double_registry.register
|
355
|
+
parameters_double_registries_by_params[params] =
|
356
|
+
parameters_double_registry
|
357
|
+
end
|
307
358
|
end
|
308
359
|
|
309
|
-
def
|
310
|
-
|
360
|
+
def permitted_parameter_names(options = {})
|
361
|
+
parameters_double_registries_by_params.flat_map do |params, double_registry|
|
362
|
+
double_registry.permitted_parameter_names(options)
|
363
|
+
end
|
311
364
|
end
|
312
365
|
|
313
366
|
protected
|
314
367
|
|
315
|
-
attr_reader :
|
368
|
+
attr_reader :parameters_double_registries_by_params
|
316
369
|
end
|
317
370
|
|
318
371
|
# @private
|
319
|
-
class
|
372
|
+
class ParametersDoubleRegistry
|
320
373
|
TOP_LEVEL = Object.new
|
321
374
|
|
322
|
-
def
|
323
|
-
|
375
|
+
def self.permitted_parameter_names_within(double_collection)
|
376
|
+
double_collection.calls_to(:permit).map(&:args).flatten
|
377
|
+
end
|
324
378
|
|
325
|
-
|
326
|
-
@
|
327
|
-
|
328
|
-
}
|
379
|
+
def initialize(params)
|
380
|
+
@params = params
|
381
|
+
@double_collections_by_parameter_name = {}
|
329
382
|
end
|
330
383
|
|
331
384
|
def register
|
332
|
-
|
333
|
-
double_permit_on(top_level_collection)
|
334
|
-
double_require_on(top_level_collection)
|
385
|
+
register_double_for_permit_against(params, TOP_LEVEL)
|
335
386
|
end
|
336
387
|
|
337
|
-
def
|
338
|
-
|
339
|
-
|
340
|
-
|
388
|
+
def permitted_parameter_names(args = {})
|
389
|
+
subparameter_name = args.fetch(:for, TOP_LEVEL)
|
390
|
+
|
391
|
+
if double_collections_by_parameter_name.key?(subparameter_name)
|
392
|
+
self.class.permitted_parameter_names_within(
|
393
|
+
double_collections_by_parameter_name[subparameter_name]
|
341
394
|
)
|
342
395
|
else
|
343
396
|
[]
|
@@ -346,31 +399,30 @@ module Shoulda
|
|
346
399
|
|
347
400
|
protected
|
348
401
|
|
349
|
-
attr_reader :
|
402
|
+
attr_reader :params, :double_collections_by_parameter_name
|
350
403
|
|
351
404
|
private
|
352
405
|
|
353
|
-
def
|
354
|
-
|
355
|
-
end
|
406
|
+
def register_double_for_permit_against(params, subparameter_name)
|
407
|
+
klass = params.singleton_class
|
356
408
|
|
357
|
-
|
358
|
-
|
359
|
-
|
409
|
+
double_collection = Doublespeak.double_collection_for(klass)
|
410
|
+
register_double_for_permit_on(double_collection)
|
411
|
+
register_double_for_require_on(double_collection)
|
360
412
|
|
361
|
-
|
362
|
-
|
363
|
-
params = call.return_value
|
364
|
-
double_collections_by_param[param_name] ||=
|
365
|
-
double_permit_against(params)
|
366
|
-
end
|
413
|
+
double_collections_by_parameter_name[subparameter_name] =
|
414
|
+
double_collection
|
367
415
|
end
|
368
416
|
|
369
|
-
def
|
370
|
-
|
417
|
+
def register_double_for_permit_on(double_collection)
|
418
|
+
double_collection.register_proxy(:permit)
|
419
|
+
end
|
371
420
|
|
372
|
-
|
373
|
-
|
421
|
+
def register_double_for_require_on(double_collection)
|
422
|
+
double_collection.register_proxy(:require).to_return do |call|
|
423
|
+
params = call.return_value
|
424
|
+
subparameter_name = call.args.first
|
425
|
+
register_double_for_permit_against(params, subparameter_name)
|
374
426
|
end
|
375
427
|
end
|
376
428
|
end
|