shoulda-matchers 4.1.2 → 4.5.0
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 +168 -86
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +4 -2
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +3 -2
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +26 -21
- 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/allow_mass_assignment_of_matcher.rb +18 -16
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +31 -29
- 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 +9 -1
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +9 -8
- 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 +71 -26
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +2 -2
- 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 +3 -3
- data/lib/shoulda/matchers/active_record.rb +26 -23
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
- data/lib/shoulda/matchers/active_record/association_matcher.rb +100 -44
- 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 +3 -3
- 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 +8 -8
- data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +185 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +40 -18
- 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 +83 -0
- 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 +10 -21
- 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 +10 -7
- metadata +11 -9
- data/lib/shoulda/matchers/independent/delegate_method_matcher/stubbed_target.rb +0 -37
@@ -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,12 +1,8 @@
|
|
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_4_1?
|
7
|
-
Gem::Requirement.new('>= 4.1').satisfied_by?(action_pack_version)
|
8
|
-
end
|
9
|
-
|
10
6
|
def action_pack_gte_5?
|
11
7
|
Gem::Requirement.new('>= 5').satisfied_by?(action_pack_version)
|
12
8
|
end
|
@@ -25,6 +21,10 @@ module Shoulda
|
|
25
21
|
Gem::Requirement.new('>= 5').satisfied_by?(active_record_version)
|
26
22
|
end
|
27
23
|
|
24
|
+
def active_record_gte_6?
|
25
|
+
Gem::Requirement.new('>= 6').satisfied_by?(active_record_version)
|
26
|
+
end
|
27
|
+
|
28
28
|
def active_record_version
|
29
29
|
Gem::Version.new(::ActiveRecord::VERSION::STRING)
|
30
30
|
rescue NameError
|
@@ -85,15 +85,6 @@ module Shoulda
|
|
85
85
|
serialized_attributes_for(model)[attribute_name.to_s]
|
86
86
|
end
|
87
87
|
|
88
|
-
def type_cast_default_for(model, column)
|
89
|
-
if model.respond_to?(:column_defaults)
|
90
|
-
# Rails 4.2
|
91
|
-
model.column_defaults[column.name]
|
92
|
-
else
|
93
|
-
column.default
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
88
|
def tables_and_views(connection)
|
98
89
|
if active_record_gte_5?
|
99
90
|
connection.data_sources
|
@@ -103,11 +94,7 @@ module Shoulda
|
|
103
94
|
end
|
104
95
|
|
105
96
|
def verb_for_update
|
106
|
-
|
107
|
-
:patch
|
108
|
-
else
|
109
|
-
:put
|
110
|
-
end
|
97
|
+
:patch
|
111
98
|
end
|
112
99
|
|
113
100
|
def validation_message_key_for_association_required_option
|
@@ -193,10 +180,12 @@ module Shoulda
|
|
193
180
|
options
|
194
181
|
)
|
195
182
|
default_translation_keys = [
|
196
|
-
:"activemodel.errors.models.#{model_name}.attributes.#{attribute}
|
183
|
+
:"activemodel.errors.models.#{model_name}.attributes.#{attribute}
|
184
|
+
.#{type}",
|
197
185
|
:"activemodel.errors.models.#{model_name}.#{type}",
|
198
186
|
:"activemodel.errors.messages.#{type}",
|
199
|
-
:"activerecord.errors.models.#{model_name}.attributes.#{attribute}
|
187
|
+
:"activerecord.errors.models.#{model_name}.attributes.#{attribute}
|
188
|
+
.#{type}",
|
200
189
|
:"activerecord.errors.models.#{model_name}.#{type}",
|
201
190
|
:"activerecord.errors.messages.#{type}",
|
202
191
|
:"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..-1]
|
189
189
|
end
|
190
190
|
|
191
191
|
{ fitted_line: fitted_line, leftover: leftover }
|
@@ -5,13 +5,13 @@ module Shoulda
|
|
5
5
|
|
6
6
|
# @private
|
7
7
|
def self.warn(message)
|
8
|
-
header =
|
9
|
-
divider =
|
8
|
+
header = 'Warning from shoulda-matchers:'
|
9
|
+
divider = '*' * TERMINAL_MAX_WIDTH
|
10
10
|
wrapped_message = word_wrap(message)
|
11
11
|
full_message = [
|
12
12
|
divider,
|
13
13
|
[header, wrapped_message.strip].join("\n\n"),
|
14
|
-
divider
|
14
|
+
divider,
|
15
15
|
].join("\n")
|
16
16
|
|
17
17
|
Kernel.warn(full_message)
|
data/shoulda-matchers.gemspec
CHANGED
@@ -18,19 +18,22 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.homepage = 'https://matchers.shoulda.io/'
|
19
19
|
s.summary = 'Simple one-liner tests for common Rails functionality'
|
20
20
|
s.license = 'MIT'
|
21
|
-
s.description =
|
22
|
-
|
21
|
+
s.description = <<~DESC.tr("\n", ' ').squeeze(' ')
|
22
|
+
Shoulda Matchers provides RSpec- and Minitest-compatible one-liners to test
|
23
|
+
common Rails functionality that, if written by hand, would be much
|
24
|
+
longer, more complex, and error-prone.
|
25
|
+
DESC
|
26
|
+
|
27
|
+
s.metadata = {
|
23
28
|
'bug_tracker_uri' => 'https://github.com/thoughtbot/shoulda-matchers/issues',
|
24
|
-
'changelog_uri' => 'https://github.com/thoughtbot/shoulda-matchers/blob/master/
|
29
|
+
'changelog_uri' => 'https://github.com/thoughtbot/shoulda-matchers/blob/master/CHANGELOG.md',
|
25
30
|
'documentation_uri' => 'https://matchers.shoulda.io/docs',
|
26
31
|
'homepage_uri' => 'https://matchers.shoulda.io',
|
27
32
|
'source_code_uri' => 'https://github.com/thoughtbot/shoulda-matchers',
|
28
33
|
}
|
29
34
|
|
30
|
-
s.files = Dir.
|
31
|
-
|
32
|
-
split("\x0")
|
33
|
-
end
|
35
|
+
s.files = Dir['{docs,lib}/**/*', 'README.md', 'LICENSE',
|
36
|
+
'shoulda-matchers.gemspec']
|
34
37
|
s.require_paths = ['lib']
|
35
38
|
|
36
39
|
s.required_ruby_version = '>= 2.4.0'
|