shoulda-matchers 3.0.0.rc1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|