shoulda-matchers 4.4.1 → 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/LICENSE +22 -0
- data/README.md +7 -9
- 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 +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 -34
- 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 +8 -7
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +26 -25
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +6 -6
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +39 -26
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +6 -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 -26
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
- data/lib/shoulda/matchers/active_record/association_matcher.rb +80 -40
- 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 +2 -9
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +12 -7
- 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 +46 -8
- 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 +7 -7
- 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 +2 -0
- 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 +78 -71
- 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/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 +5 -3
- data/lib/shoulda/matchers/util.rb +7 -2
- data/lib/shoulda/matchers/util/word_wrap.rb +7 -7
- data/lib/shoulda/matchers/version.rb +1 -1
- data/lib/shoulda/matchers/warn.rb +3 -3
- data/shoulda-matchers.gemspec +10 -7
- metadata +11 -10
@@ -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,7 +1,7 @@
|
|
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
6
|
def action_pack_gte_5?
|
7
7
|
Gem::Requirement.new('>= 5').satisfied_by?(action_pack_version)
|
@@ -180,10 +180,12 @@ module Shoulda
|
|
180
180
|
options
|
181
181
|
)
|
182
182
|
default_translation_keys = [
|
183
|
-
:"activemodel.errors.models.#{model_name}.attributes.#{attribute}
|
183
|
+
:"activemodel.errors.models.#{model_name}.attributes.#{attribute}
|
184
|
+
.#{type}",
|
184
185
|
:"activemodel.errors.models.#{model_name}.#{type}",
|
185
186
|
:"activemodel.errors.messages.#{type}",
|
186
|
-
:"activerecord.errors.models.#{model_name}.attributes.#{attribute}
|
187
|
+
:"activerecord.errors.models.#{model_name}.attributes.#{attribute}
|
188
|
+
.#{type}",
|
187
189
|
:"activerecord.errors.models.#{model_name}.#{type}",
|
188
190
|
:"activerecord.errors.messages.#{type}",
|
189
191
|
:"errors.attributes.#{attribute}.#{type}",
|
@@ -7,8 +7,10 @@ module Shoulda
|
|
7
7
|
MAXIMUM_LENGTH_OF_VALUE_TO_DISPLAY = 500
|
8
8
|
|
9
9
|
def self.deconstantize(path)
|
10
|
-
if
|
10
|
+
if (
|
11
|
+
defined?(ActiveSupport::Inflector) &&
|
11
12
|
ActiveSupport::Inflector.respond_to?(:deconstantize)
|
13
|
+
)
|
12
14
|
ActiveSupport::Inflector.deconstantize(path)
|
13
15
|
else
|
14
16
|
path.to_s[0...(path.to_s.rindex('::') || 0)]
|
@@ -16,8 +18,10 @@ module Shoulda
|
|
16
18
|
end
|
17
19
|
|
18
20
|
def self.safe_constantize(camel_cased_word)
|
19
|
-
if
|
21
|
+
if (
|
22
|
+
defined?(ActiveSupport::Inflector) &&
|
20
23
|
ActiveSupport::Inflector.respond_to?(:safe_constantize)
|
24
|
+
)
|
21
25
|
ActiveSupport::Inflector.safe_constantize(camel_cased_word)
|
22
26
|
else
|
23
27
|
begin
|
@@ -30,6 +34,7 @@ module Shoulda
|
|
30
34
|
|
31
35
|
def self.indent(string, width)
|
32
36
|
return if !string
|
37
|
+
|
33
38
|
indentation = ' ' * width
|
34
39
|
string.split(/[\n\r]/).map { |line| indentation + line }.join("\n")
|
35
40
|
end
|
@@ -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'
|