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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +22 -0
  3. data/README.md +7 -9
  4. data/lib/shoulda/matchers/action_controller/callback_matcher.rb +4 -2
  5. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +3 -2
  6. data/lib/shoulda/matchers/action_controller/permit_matcher.rb +26 -21
  7. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +6 -8
  8. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +6 -8
  9. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +16 -13
  10. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +2 -1
  11. data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -6
  12. data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
  13. data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +19 -13
  14. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +18 -16
  15. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +29 -27
  16. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +1 -1
  17. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +5 -5
  18. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +2 -2
  19. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +1 -1
  20. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +1 -1
  21. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +1 -1
  22. data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +51 -25
  23. data/lib/shoulda/matchers/active_model/helpers.rb +1 -1
  24. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +32 -34
  25. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +1 -1
  26. data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +1 -1
  27. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +9 -1
  28. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +2 -2
  29. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +8 -7
  30. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +26 -25
  31. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +6 -6
  32. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +39 -26
  33. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +2 -2
  34. data/lib/shoulda/matchers/active_model/validation_matcher.rb +6 -6
  35. data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +2 -4
  36. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -4
  37. data/lib/shoulda/matchers/active_model/validator.rb +3 -3
  38. data/lib/shoulda/matchers/active_record.rb +26 -26
  39. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
  40. data/lib/shoulda/matchers/active_record/association_matcher.rb +80 -40
  41. data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +5 -2
  42. data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -4
  43. data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +1 -1
  44. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +11 -6
  45. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +2 -9
  46. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +12 -7
  47. data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +23 -5
  48. data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +3 -3
  49. data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +1 -1
  50. data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +3 -3
  51. data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +3 -2
  52. data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +7 -5
  53. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +8 -8
  54. data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +46 -8
  55. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +39 -17
  56. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
  57. data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +7 -7
  58. data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +12 -10
  59. data/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +11 -7
  60. data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +2 -0
  61. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +13 -9
  62. data/lib/shoulda/matchers/active_record/uniqueness.rb +1 -1
  63. data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +1 -3
  64. data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +0 -2
  65. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +78 -71
  66. data/lib/shoulda/matchers/doublespeak.rb +2 -1
  67. data/lib/shoulda/matchers/doublespeak/double.rb +1 -1
  68. data/lib/shoulda/matchers/doublespeak/double_collection.rb +3 -3
  69. data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +8 -5
  70. data/lib/shoulda/matchers/doublespeak/object_double.rb +1 -1
  71. data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +1 -5
  72. data/lib/shoulda/matchers/doublespeak/world.rb +2 -2
  73. data/lib/shoulda/matchers/error.rb +1 -1
  74. data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +14 -13
  75. data/lib/shoulda/matchers/integrations/configuration.rb +1 -1
  76. data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
  77. data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -2
  78. data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +1 -1
  79. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +1 -1
  80. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +1 -1
  81. data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +1 -1
  82. data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +1 -1
  83. data/lib/shoulda/matchers/rails_shim.rb +5 -3
  84. data/lib/shoulda/matchers/util.rb +7 -2
  85. data/lib/shoulda/matchers/util/word_wrap.rb +7 -7
  86. data/lib/shoulda/matchers/version.rb +1 -1
  87. data/lib/shoulda/matchers/warn.rb +3 -3
  88. data/shoulda-matchers.gemspec +10 -7
  89. metadata +11 -10
@@ -1,4 +1,5 @@
1
1
  require 'forwardable'
2
+ require 'logger'
2
3
 
3
4
  module Shoulda
4
5
  module Matchers
@@ -20,7 +21,7 @@ module Shoulda
20
21
 
21
22
  def debug(&block)
22
23
  if debugging_enabled?
23
- puts block.call
24
+ puts block.call # rubocop:disable Rails/Output
24
25
  end
25
26
  end
26
27
  end
@@ -82,7 +82,7 @@ module Shoulda
82
82
  method_name: _method_name,
83
83
  args: args,
84
84
  block: block,
85
- caller: caller
85
+ caller: caller,
86
86
  )
87
87
  implementation.call(call)
88
88
  end
@@ -18,19 +18,19 @@ module Shoulda
18
18
  end
19
19
 
20
20
  def activate
21
- doubles_by_method_name.each do |method_name, double|
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 |method_name, double|
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.reduce({}) do |hash, (method_name, double)|
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
- REGISTRY[type] = klass
12
+ registry[type] = klass
15
13
  end
16
14
 
17
15
  private
18
16
 
19
17
  def find_class!(type)
20
- REGISTRY.fetch(type) do
21
- raise ArgumentError, "No double implementation class found for '#{type}'"
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
@@ -27,7 +27,7 @@ module Shoulda
27
27
  method_name: method_name,
28
28
  args: args,
29
29
  block: block,
30
- caller: ::Kernel.caller
30
+ caller: ::Kernel.caller,
31
31
  )
32
32
  calls << call
33
33
  (calls_by_method_name[method_name] ||= []) << call
@@ -14,11 +14,7 @@ module Shoulda
14
14
  end
15
15
 
16
16
  def returns(value = nil, &block)
17
- if block
18
- @implementation = block
19
- else
20
- @implementation = proc { value }
21
- end
17
+ @implementation = block || proc { value }
22
18
  end
23
19
 
24
20
  def call(call)
@@ -39,13 +39,13 @@ module Shoulda
39
39
  private
40
40
 
41
41
  def activate
42
- double_collections_by_class.each do |klass, double_collection|
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 |klass, double_collection|
48
+ double_collections_by_class.each do |_klass, double_collection|
49
49
  double_collection.deactivate
50
50
  end
51
51
  end
@@ -18,7 +18,7 @@ module Shoulda
18
18
  end
19
19
 
20
20
  def message
21
- ""
21
+ ''
22
22
  end
23
23
 
24
24
  def inspect
@@ -219,9 +219,9 @@ module Shoulda
219
219
  end
220
220
 
221
221
  if expects_to_allow_nil_delegate_object?
222
- string << ", allowing "
222
+ string << ', allowing '
223
223
  string << formatted_delegate_object_reader_method_name
224
- string << " to return nil"
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
- delegate_method
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
- when true, nil then delegate_object_reader_method
260
- else prefix
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 => error
402
- if error.message =~ /undefined method `#{delegate_method}' for nil:NilClass/
401
+ rescue NoMethodError => e
402
+ if e.message =~
403
+ /undefined method `#{delegate_method}' for nil:NilClass/
403
404
  false
404
405
  else
405
- raise error
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 { |arg| arg.inspect }.join(', ')
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 << " (none)"
453
+ string << ' (none)'
453
454
  end
454
455
 
455
456
  string.rstrip!
@@ -60,7 +60,7 @@ EOT
60
60
  end
61
61
 
62
62
  def no_test_frameworks_added?
63
- @test_frameworks.empty? || !@test_frameworks.any?(&:present?)
63
+ @test_frameworks.empty? || @test_frameworks.none?(&:present?)
64
64
  end
65
65
 
66
66
  def no_libraries_added?
@@ -13,7 +13,7 @@ module Shoulda
13
13
  test_framework.include(matchers_module, type: :controller)
14
14
 
15
15
  include_into(::ActionController::TestCase, matchers_module) do
16
- def subject
16
+ def subject # rubocop:disable Lint/NestedMethodDefinition
17
17
  @controller
18
18
  end
19
19
  end
@@ -12,8 +12,8 @@ module Shoulda
12
12
  :active_model,
13
13
  :active_record,
14
14
  :action_controller,
15
- :routing
16
- ]
15
+ :routing,
16
+ ].freeze
17
17
 
18
18
  def integrate_with(test_framework)
19
19
  Shoulda::Matchers.assertion_exception_class =
@@ -9,7 +9,7 @@ module Shoulda
9
9
  def validate!
10
10
  end
11
11
 
12
- def include(*modules, **options)
12
+ def include(*modules, **_options)
13
13
  test_case_class.include(*modules)
14
14
  end
15
15
 
@@ -9,7 +9,7 @@ module Shoulda
9
9
  def validate!
10
10
  end
11
11
 
12
- def include(*modules, **options)
12
+ def include(*modules, **_options)
13
13
  test_case_class.class_eval do
14
14
  include(*modules)
15
15
  extend(*modules)
@@ -10,7 +10,7 @@ module Shoulda
10
10
  def validate!
11
11
  end
12
12
 
13
- def include(*modules, **options)
13
+ def include(*modules, **_options)
14
14
  test_case_class.class_eval do
15
15
  include(*modules)
16
16
  extend(*modules)
@@ -20,7 +20,7 @@ Shoulda::Matchers.configure do |config|
20
20
  with.test_framework :test_unit
21
21
  end
22
22
  end
23
- EOT
23
+ EOT
24
24
  end
25
25
 
26
26
  def include(*modules, **options)
@@ -9,7 +9,7 @@ module Shoulda
9
9
  def validate!
10
10
  end
11
11
 
12
- def include(*modules, **options)
12
+ def include(*modules, **_options)
13
13
  test_case_class.class_eval do
14
14
  include(*modules)
15
15
  extend(*modules)
@@ -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}.#{type}",
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}.#{type}",
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 defined?(ActiveSupport::Inflector) &&
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 defined?(ActiveSupport::Inflector) &&
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.reduce([]) do |combined_lines, line|
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 << (' ' + line).squeeze(' ')
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, direction: :left)
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 .. -1]
188
+ leftover = line[index + 1..-1]
189
189
  end
190
190
 
191
191
  { fitted_line: fitted_line, leftover: leftover }
@@ -1,6 +1,6 @@
1
1
  module Shoulda
2
2
  module Matchers
3
3
  # @private
4
- VERSION = '4.4.1'.freeze
4
+ VERSION = '4.5.0'.freeze
5
5
  end
6
6
  end
@@ -5,13 +5,13 @@ module Shoulda
5
5
 
6
6
  # @private
7
7
  def self.warn(message)
8
- header = "Warning from shoulda-matchers:"
9
- divider = "*" * TERMINAL_MAX_WIDTH
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)
@@ -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 = 'Shoulda Matchers provides RSpec- and Minitest-compatible one-liners to test common Rails functionality that, if written by hand, would be much longer, more complex, and error-prone.'
22
- s.metadata = {
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/NEWS.md',
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.chdir(File.expand_path(__dir__)) do
31
- `git ls-files -z -- {docs,lib,README.md,MIT-LICENSE,shoulda-matchers.gemspec}`.
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'