shoulda-matchers 4.3.0 → 5.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{MIT-LICENSE → LICENSE} +1 -1
- data/README.md +170 -90
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +4 -89
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +3 -2
- data/lib/shoulda/matchers/action_controller/flash_store.rb +2 -4
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +29 -27
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +6 -8
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +6 -8
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +16 -13
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +2 -1
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -6
- data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
- data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +19 -13
- data/lib/shoulda/matchers/active_model.rb +0 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +29 -27
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +5 -5
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +2 -2
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +1 -1
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +51 -25
- data/lib/shoulda/matchers/active_model/helpers.rb +1 -1
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +32 -30
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +10 -2
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +8 -7
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +28 -46
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +33 -9
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +72 -27
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +31 -6
- data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +2 -4
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -4
- data/lib/shoulda/matchers/active_model/validator.rb +4 -9
- data/lib/shoulda/matchers/active_record.rb +26 -24
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
- data/lib/shoulda/matchers/active_record/association_matcher.rb +119 -50
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +5 -2
- data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +11 -6
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +14 -15
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +30 -8
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +23 -5
- data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +3 -2
- data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +7 -5
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +18 -9
- data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +185 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +39 -17
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +106 -0
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +12 -10
- data/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +11 -7
- data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +30 -9
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +13 -9
- data/lib/shoulda/matchers/active_record/uniqueness.rb +1 -1
- data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +1 -3
- data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +0 -2
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +80 -73
- data/lib/shoulda/matchers/doublespeak.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/double.rb +1 -1
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +3 -3
- data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +8 -5
- data/lib/shoulda/matchers/doublespeak/object_double.rb +1 -1
- data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +1 -5
- data/lib/shoulda/matchers/doublespeak/world.rb +2 -2
- data/lib/shoulda/matchers/error.rb +1 -1
- data/lib/shoulda/matchers/independent.rb +0 -1
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +14 -13
- data/lib/shoulda/matchers/integrations/configuration.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -2
- 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/test_unit.rb +1 -1
- data/lib/shoulda/matchers/rails_shim.rb +7 -40
- data/lib/shoulda/matchers/util.rb +16 -4
- data/lib/shoulda/matchers/util/word_wrap.rb +8 -8
- data/lib/shoulda/matchers/version.rb +1 -1
- data/lib/shoulda/matchers/warn.rb +3 -3
- data/shoulda-matchers.gemspec +12 -9
- metadata +15 -15
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +0 -159
- data/lib/shoulda/matchers/independent/delegate_method_matcher/stubbed_target.rb +0 -37
@@ -18,19 +18,19 @@ module Shoulda
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def activate
|
21
|
-
doubles_by_method_name.each do |
|
21
|
+
doubles_by_method_name.each do |_method_name, double|
|
22
22
|
double.activate
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
def deactivate
|
27
|
-
doubles_by_method_name.each do |
|
27
|
+
doubles_by_method_name.each do |_method_name, double|
|
28
28
|
double.deactivate
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
def calls_by_method_name
|
33
|
-
doubles_by_method_name.
|
33
|
+
doubles_by_method_name.inject({}) do |hash, (method_name, double)|
|
34
34
|
hash.merge method_name => double.calls.map(&:args)
|
35
35
|
end
|
36
36
|
end
|
@@ -4,23 +4,26 @@ module Shoulda
|
|
4
4
|
# @private
|
5
5
|
module DoubleImplementationRegistry
|
6
6
|
class << self
|
7
|
-
REGISTRY = {}
|
8
|
-
|
9
7
|
def find(type)
|
10
8
|
find_class!(type).create
|
11
9
|
end
|
12
10
|
|
13
11
|
def register(klass, type)
|
14
|
-
|
12
|
+
registry[type] = klass
|
15
13
|
end
|
16
14
|
|
17
15
|
private
|
18
16
|
|
19
17
|
def find_class!(type)
|
20
|
-
|
21
|
-
raise ArgumentError,
|
18
|
+
registry.fetch(type) do
|
19
|
+
raise ArgumentError, 'No double implementation class found for'\
|
20
|
+
" '#{type}'"
|
22
21
|
end
|
23
22
|
end
|
23
|
+
|
24
|
+
def registry
|
25
|
+
@_registry ||= {}
|
26
|
+
end
|
24
27
|
end
|
25
28
|
end
|
26
29
|
end
|
@@ -39,13 +39,13 @@ module Shoulda
|
|
39
39
|
private
|
40
40
|
|
41
41
|
def activate
|
42
|
-
double_collections_by_class.each do |
|
42
|
+
double_collections_by_class.each do |_klass, double_collection|
|
43
43
|
double_collection.activate
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
def deactivate
|
48
|
-
double_collections_by_class.each do |
|
48
|
+
double_collections_by_class.each do |_klass, double_collection|
|
49
49
|
double_collection.deactivate
|
50
50
|
end
|
51
51
|
end
|
@@ -219,9 +219,9 @@ module Shoulda
|
|
219
219
|
end
|
220
220
|
|
221
221
|
if expects_to_allow_nil_delegate_object?
|
222
|
-
string <<
|
222
|
+
string << ', allowing '
|
223
223
|
string << formatted_delegate_object_reader_method_name
|
224
|
-
string <<
|
224
|
+
string << ' to return nil'
|
225
225
|
end
|
226
226
|
|
227
227
|
string
|
@@ -245,7 +245,7 @@ module Shoulda
|
|
245
245
|
def with_prefix(prefix = nil)
|
246
246
|
@delegating_method =
|
247
247
|
:"#{build_delegating_method_prefix(prefix)}_#{delegate_method}"
|
248
|
-
|
248
|
+
delegate_method
|
249
249
|
self
|
250
250
|
end
|
251
251
|
|
@@ -256,8 +256,8 @@ module Shoulda
|
|
256
256
|
|
257
257
|
def build_delegating_method_prefix(prefix)
|
258
258
|
case prefix
|
259
|
-
|
260
|
-
|
259
|
+
when true, nil then delegate_object_reader_method
|
260
|
+
else prefix
|
261
261
|
end
|
262
262
|
end
|
263
263
|
|
@@ -344,7 +344,7 @@ module Shoulda
|
|
344
344
|
if options[:include_module]
|
345
345
|
class_under_test.to_s
|
346
346
|
else
|
347
|
-
|
347
|
+
''
|
348
348
|
end
|
349
349
|
end
|
350
350
|
|
@@ -398,11 +398,12 @@ module Shoulda
|
|
398
398
|
true
|
399
399
|
rescue Module::DelegationError
|
400
400
|
false
|
401
|
-
rescue NoMethodError =>
|
402
|
-
if
|
401
|
+
rescue NoMethodError => e
|
402
|
+
if e.message =~
|
403
|
+
/undefined method `#{delegate_method}' for nil:NilClass/
|
403
404
|
false
|
404
405
|
else
|
405
|
-
raise
|
406
|
+
raise e
|
406
407
|
end
|
407
408
|
end
|
408
409
|
else
|
@@ -439,17 +440,17 @@ module Shoulda
|
|
439
440
|
end
|
440
441
|
|
441
442
|
def formatted_calls_on_delegate_object
|
442
|
-
string =
|
443
|
+
string = ''
|
443
444
|
|
444
445
|
if calls_on_delegate_object.any?
|
445
446
|
string << "\n\n"
|
446
447
|
calls_on_delegate_object.each_with_index do |call, i|
|
447
448
|
name = call.method_name
|
448
|
-
args = call.args.map
|
449
|
-
string << "#{i+1}) #{name}(#{args})\n"
|
449
|
+
args = call.args.map(&:inspect).join(', ')
|
450
|
+
string << "#{i + 1}) #{name}(#{args})\n"
|
450
451
|
end
|
451
452
|
else
|
452
|
-
string <<
|
453
|
+
string << ' (none)'
|
453
454
|
end
|
454
455
|
|
455
456
|
string.rstrip!
|
@@ -1,24 +1,16 @@
|
|
1
1
|
module Shoulda
|
2
2
|
module Matchers
|
3
3
|
# @private
|
4
|
-
module RailsShim
|
4
|
+
module RailsShim # rubocop:disable Metrics/ModuleLength
|
5
5
|
class << self
|
6
|
-
def action_pack_gte_5?
|
7
|
-
Gem::Requirement.new('>= 5').satisfied_by?(action_pack_version)
|
8
|
-
end
|
9
|
-
|
10
|
-
def action_pack_lt_5?
|
11
|
-
Gem::Requirement.new('< 5').satisfied_by?(action_pack_version)
|
12
|
-
end
|
13
|
-
|
14
6
|
def action_pack_version
|
15
7
|
Gem::Version.new(::ActionPack::VERSION::STRING)
|
16
8
|
rescue NameError
|
17
9
|
Gem::Version.new('0')
|
18
10
|
end
|
19
11
|
|
20
|
-
def
|
21
|
-
Gem::Requirement.new('>=
|
12
|
+
def active_record_gte_6?
|
13
|
+
Gem::Requirement.new('>= 6').satisfied_by?(active_record_version)
|
22
14
|
end
|
23
15
|
|
24
16
|
def active_record_version
|
@@ -53,17 +45,6 @@ module Shoulda
|
|
53
45
|
)
|
54
46
|
end
|
55
47
|
|
56
|
-
def make_controller_request(context, verb, action, request_params)
|
57
|
-
params =
|
58
|
-
if action_pack_gte_5?
|
59
|
-
{ params: request_params }
|
60
|
-
else
|
61
|
-
request_params
|
62
|
-
end
|
63
|
-
|
64
|
-
context.__send__(verb, action, params)
|
65
|
-
end
|
66
|
-
|
67
48
|
def serialized_attributes_for(model)
|
68
49
|
attribute_types_for(model).
|
69
50
|
inject({}) do |hash, (attribute_name, attribute_type)|
|
@@ -81,26 +62,10 @@ module Shoulda
|
|
81
62
|
serialized_attributes_for(model)[attribute_name.to_s]
|
82
63
|
end
|
83
64
|
|
84
|
-
def tables_and_views(connection)
|
85
|
-
if active_record_gte_5?
|
86
|
-
connection.data_sources
|
87
|
-
else
|
88
|
-
connection.tables
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
65
|
def verb_for_update
|
93
66
|
:patch
|
94
67
|
end
|
95
68
|
|
96
|
-
def validation_message_key_for_association_required_option
|
97
|
-
if active_record_gte_5?
|
98
|
-
:required
|
99
|
-
else
|
100
|
-
:blank
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
69
|
def parent_of(mod)
|
105
70
|
if mod.respond_to?(:module_parent)
|
106
71
|
mod.module_parent
|
@@ -176,10 +141,12 @@ module Shoulda
|
|
176
141
|
options
|
177
142
|
)
|
178
143
|
default_translation_keys = [
|
179
|
-
:"activemodel.errors.models.#{model_name}.attributes.#{attribute}
|
144
|
+
:"activemodel.errors.models.#{model_name}.attributes.#{attribute}
|
145
|
+
.#{type}",
|
180
146
|
:"activemodel.errors.models.#{model_name}.#{type}",
|
181
147
|
:"activemodel.errors.messages.#{type}",
|
182
|
-
:"activerecord.errors.models.#{model_name}.attributes.#{attribute}
|
148
|
+
:"activerecord.errors.models.#{model_name}.attributes.#{attribute}
|
149
|
+
.#{type}",
|
183
150
|
:"activerecord.errors.models.#{model_name}.#{type}",
|
184
151
|
:"activerecord.errors.messages.#{type}",
|
185
152
|
:"errors.attributes.#{attribute}.#{type}",
|
@@ -4,9 +4,13 @@ module Shoulda
|
|
4
4
|
module Matchers
|
5
5
|
# @private
|
6
6
|
module Util
|
7
|
+
MAXIMUM_LENGTH_OF_VALUE_TO_DISPLAY = 500
|
8
|
+
|
7
9
|
def self.deconstantize(path)
|
8
|
-
if
|
10
|
+
if (
|
11
|
+
defined?(ActiveSupport::Inflector) &&
|
9
12
|
ActiveSupport::Inflector.respond_to?(:deconstantize)
|
13
|
+
)
|
10
14
|
ActiveSupport::Inflector.deconstantize(path)
|
11
15
|
else
|
12
16
|
path.to_s[0...(path.to_s.rindex('::') || 0)]
|
@@ -14,8 +18,10 @@ module Shoulda
|
|
14
18
|
end
|
15
19
|
|
16
20
|
def self.safe_constantize(camel_cased_word)
|
17
|
-
if
|
21
|
+
if (
|
22
|
+
defined?(ActiveSupport::Inflector) &&
|
18
23
|
ActiveSupport::Inflector.respond_to?(:safe_constantize)
|
24
|
+
)
|
19
25
|
ActiveSupport::Inflector.safe_constantize(camel_cased_word)
|
20
26
|
else
|
21
27
|
begin
|
@@ -28,6 +34,7 @@ module Shoulda
|
|
28
34
|
|
29
35
|
def self.indent(string, width)
|
30
36
|
return if !string
|
37
|
+
|
31
38
|
indentation = ' ' * width
|
32
39
|
string.split(/[\n\r]/).map { |line| indentation + line }.join("\n")
|
33
40
|
end
|
@@ -47,7 +54,12 @@ module Shoulda
|
|
47
54
|
when Range
|
48
55
|
inspect_range(value)
|
49
56
|
else
|
50
|
-
|
57
|
+
inspected_value = value.inspect
|
58
|
+
if inspected_value.length > MAXIMUM_LENGTH_OF_VALUE_TO_DISPLAY
|
59
|
+
"‹#{inspected_value[0, MAXIMUM_LENGTH_OF_VALUE_TO_DISPLAY]}...›"
|
60
|
+
else
|
61
|
+
"‹#{inspected_value}›"
|
62
|
+
end
|
51
63
|
end
|
52
64
|
end
|
53
65
|
|
@@ -85,7 +97,7 @@ module Shoulda
|
|
85
97
|
when :datetime, :timestamp
|
86
98
|
DateTime.new(2100, 1, 1)
|
87
99
|
when :time
|
88
|
-
Time.new(
|
100
|
+
Time.new(2000, 1, 1)
|
89
101
|
when :uuid
|
90
102
|
SecureRandom.uuid
|
91
103
|
when :boolean
|
@@ -5,7 +5,7 @@ module Shoulda
|
|
5
5
|
TERMINAL_WIDTH = 72
|
6
6
|
|
7
7
|
def word_wrap(document, options = {})
|
8
|
-
Document.new(document, options).wrap
|
8
|
+
Document.new(document, **options).wrap
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -41,10 +41,10 @@ module Shoulda
|
|
41
41
|
|
42
42
|
# @private
|
43
43
|
class Text < ::String
|
44
|
-
LIST_ITEM_REGEXP = /\A((?:[a-z0-9]+(?:\)|\.)|\*) )
|
44
|
+
LIST_ITEM_REGEXP = /\A((?:[a-z0-9]+(?:\)|\.)|\*) )/.freeze
|
45
45
|
|
46
46
|
def indented?
|
47
|
-
self =~ /\A
|
47
|
+
self =~ /\A +/
|
48
48
|
end
|
49
49
|
|
50
50
|
def list_item?
|
@@ -88,11 +88,11 @@ module Shoulda
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def combine_list_item_lines(lines)
|
91
|
-
lines.
|
91
|
+
lines.inject([]) do |combined_lines, line|
|
92
92
|
if line.list_item?
|
93
93
|
combined_lines << line
|
94
94
|
else
|
95
|
-
combined_lines.last << (
|
95
|
+
combined_lines.last << (" #{line}").squeeze(' ')
|
96
96
|
end
|
97
97
|
|
98
98
|
combined_lines
|
@@ -114,7 +114,7 @@ module Shoulda
|
|
114
114
|
|
115
115
|
# @private
|
116
116
|
class Line
|
117
|
-
OFFSETS = { left: -1, right: +1 }
|
117
|
+
OFFSETS = { left: -1, right: +1 }.freeze
|
118
118
|
|
119
119
|
def initialize(line, indent: 0)
|
120
120
|
@indent = indent
|
@@ -169,7 +169,7 @@ module Shoulda
|
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
|
-
def wrap_line(line
|
172
|
+
def wrap_line(line)
|
173
173
|
index = nil
|
174
174
|
|
175
175
|
if line.length > Shoulda::Matchers::WordWrap::TERMINAL_WIDTH
|
@@ -185,7 +185,7 @@ module Shoulda
|
|
185
185
|
leftover = ''
|
186
186
|
else
|
187
187
|
fitted_line = line[0..index].rstrip
|
188
|
-
leftover = line[index + 1
|
188
|
+
leftover = line[index + 1..]
|
189
189
|
end
|
190
190
|
|
191
191
|
{ fitted_line: fitted_line, leftover: leftover }
|