shoulda-matchers 4.4.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +22 -0
  3. data/README.md +18 -18
  4. data/lib/shoulda/matchers.rb +12 -13
  5. data/lib/shoulda/matchers/action_controller.rb +13 -13
  6. data/lib/shoulda/matchers/action_controller/callback_matcher.rb +4 -89
  7. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +3 -2
  8. data/lib/shoulda/matchers/action_controller/flash_store.rb +2 -4
  9. data/lib/shoulda/matchers/action_controller/permit_matcher.rb +29 -27
  10. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +6 -8
  11. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +6 -8
  12. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +16 -13
  13. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +2 -1
  14. data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -6
  15. data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
  16. data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +19 -13
  17. data/lib/shoulda/matchers/active_model.rb +25 -15
  18. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +29 -36
  19. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +1 -1
  20. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +5 -5
  21. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +2 -2
  22. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +1 -1
  23. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +1 -1
  24. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +1 -1
  25. data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +51 -25
  26. data/lib/shoulda/matchers/active_model/helpers.rb +2 -2
  27. data/lib/shoulda/matchers/active_model/numericality_matchers.rb +0 -5
  28. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +32 -34
  29. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +1 -1
  30. data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +1 -1
  31. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +10 -2
  32. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +2 -2
  33. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +8 -7
  34. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +26 -25
  35. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +6 -6
  36. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +40 -27
  37. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +4 -4
  38. data/lib/shoulda/matchers/active_model/validation_matcher.rb +6 -8
  39. data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +2 -4
  40. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -4
  41. data/lib/shoulda/matchers/active_model/validator.rb +4 -9
  42. data/lib/shoulda/matchers/active_record.rb +26 -14
  43. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
  44. data/lib/shoulda/matchers/active_record/association_matcher.rb +101 -48
  45. data/lib/shoulda/matchers/active_record/association_matchers.rb +0 -12
  46. data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +5 -2
  47. data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -4
  48. data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +1 -1
  49. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +11 -6
  50. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +2 -9
  51. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +12 -7
  52. data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +23 -5
  53. data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +3 -3
  54. data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +1 -1
  55. data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +4 -4
  56. data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +3 -2
  57. data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +7 -5
  58. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +18 -9
  59. data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +46 -8
  60. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +39 -17
  61. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
  62. data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +7 -7
  63. data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +12 -10
  64. data/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +11 -7
  65. data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +2 -0
  66. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +13 -9
  67. data/lib/shoulda/matchers/active_record/uniqueness.rb +4 -4
  68. data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +1 -3
  69. data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +0 -2
  70. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +78 -71
  71. data/lib/shoulda/matchers/doublespeak.rb +9 -9
  72. data/lib/shoulda/matchers/doublespeak/double.rb +1 -1
  73. data/lib/shoulda/matchers/doublespeak/double_collection.rb +3 -3
  74. data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +8 -5
  75. data/lib/shoulda/matchers/doublespeak/object_double.rb +1 -1
  76. data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +1 -5
  77. data/lib/shoulda/matchers/doublespeak/world.rb +2 -2
  78. data/lib/shoulda/matchers/error.rb +1 -1
  79. data/lib/shoulda/matchers/independent.rb +1 -0
  80. data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +14 -16
  81. data/lib/shoulda/matchers/integrations.rb +6 -6
  82. data/lib/shoulda/matchers/integrations/configuration.rb +1 -1
  83. data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
  84. data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -2
  85. data/lib/shoulda/matchers/integrations/test_frameworks.rb +2 -4
  86. data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +1 -1
  87. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +1 -1
  88. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +1 -1
  89. data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +1 -1
  90. data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +1 -1
  91. data/lib/shoulda/matchers/rails_shim.rb +5 -42
  92. data/lib/shoulda/matchers/util.rb +9 -2
  93. data/lib/shoulda/matchers/util/word_wrap.rb +7 -7
  94. data/lib/shoulda/matchers/version.rb +1 -1
  95. data/lib/shoulda/matchers/warn.rb +3 -3
  96. data/shoulda-matchers.gemspec +12 -9
  97. metadata +14 -14
  98. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +0 -159
@@ -1,3 +1,5 @@
1
+ require 'shoulda/matchers/util/word_wrap'
2
+
1
3
  module Shoulda
2
4
  module Matchers
3
5
  # @private
@@ -5,8 +7,10 @@ module Shoulda
5
7
  MAXIMUM_LENGTH_OF_VALUE_TO_DISPLAY = 500
6
8
 
7
9
  def self.deconstantize(path)
8
- if defined?(ActiveSupport::Inflector) &&
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 defined?(ActiveSupport::Inflector) &&
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
@@ -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..]
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.0'.freeze
4
+ VERSION = '5.0.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,21 +18,24 @@ 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
- s.required_ruby_version = '>= 2.4.0'
37
- s.add_dependency('activesupport', '>= 4.2.0')
39
+ s.required_ruby_version = '>= 2.6.0'
40
+ s.add_dependency('activesupport', '>= 5.2.0')
38
41
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shoulda-matchers
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tammer Saleh
@@ -11,10 +11,10 @@ authors:
11
11
  - Matt Jankowski
12
12
  - Stafford Brunk
13
13
  - Elliot Winkler
14
- autorequire:
14
+ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2020-08-25 00:00:00.000000000 Z
17
+ date: 2021-07-10 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: activesupport
@@ -22,22 +22,23 @@ dependencies:
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 4.2.0
25
+ version: 5.2.0
26
26
  type: :runtime
27
27
  prerelease: false
28
28
  version_requirements: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 4.2.0
33
- description: Shoulda Matchers provides RSpec- and Minitest-compatible one-liners to
34
- test common Rails functionality that, if written by hand, would be much longer,
35
- more complex, and error-prone.
32
+ version: 5.2.0
33
+ description: 'Shoulda Matchers provides RSpec- and Minitest-compatible one-liners
34
+ to test common Rails functionality that, if written by hand, would be much longer,
35
+ more complex, and error-prone. '
36
36
  email: support@thoughtbot.com
37
37
  executables: []
38
38
  extensions: []
39
39
  extra_rdoc_files: []
40
40
  files:
41
+ - LICENSE
41
42
  - README.md
42
43
  - docs/errors/NonCaseSwappableValueError.md
43
44
  - lib/shoulda-matchers.rb
@@ -59,7 +60,6 @@ files:
59
60
  - lib/shoulda/matchers/action_controller/set_session_matcher.rb
60
61
  - lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb
61
62
  - lib/shoulda/matchers/active_model.rb
62
- - lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb
63
63
  - lib/shoulda/matchers/active_model/allow_value_matcher.rb
64
64
  - lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb
65
65
  - lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb
@@ -173,11 +173,11 @@ licenses:
173
173
  - MIT
174
174
  metadata:
175
175
  bug_tracker_uri: https://github.com/thoughtbot/shoulda-matchers/issues
176
- changelog_uri: https://github.com/thoughtbot/shoulda-matchers/blob/master/NEWS.md
176
+ changelog_uri: https://github.com/thoughtbot/shoulda-matchers/blob/master/CHANGELOG.md
177
177
  documentation_uri: https://matchers.shoulda.io/docs
178
178
  homepage_uri: https://matchers.shoulda.io
179
179
  source_code_uri: https://github.com/thoughtbot/shoulda-matchers
180
- post_install_message:
180
+ post_install_message:
181
181
  rdoc_options: []
182
182
  require_paths:
183
183
  - lib
@@ -185,15 +185,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
185
185
  requirements:
186
186
  - - ">="
187
187
  - !ruby/object:Gem::Version
188
- version: 2.4.0
188
+ version: 2.6.0
189
189
  required_rubygems_version: !ruby/object:Gem::Requirement
190
190
  requirements:
191
191
  - - ">="
192
192
  - !ruby/object:Gem::Version
193
193
  version: '0'
194
194
  requirements: []
195
- rubygems_version: 3.1.2
196
- signing_key:
195
+ rubygems_version: 3.2.15
196
+ signing_key:
197
197
  specification_version: 4
198
198
  summary: Simple one-liner tests for common Rails functionality
199
199
  test_files: []
@@ -1,159 +0,0 @@
1
- module Shoulda
2
- module Matchers
3
- module ActiveModel
4
- # The `allow_mass_assignment_of` matcher tests usage of Rails 3's
5
- # `attr_accessible` and `attr_protected` macros, asserting that an
6
- # attribute in your model is contained in either the whitelist or
7
- # blacklist and thus can or cannot be set via mass assignment.
8
- #
9
- # class Post
10
- # include ActiveModel::Model
11
- # include ActiveModel::MassAssignmentSecurity
12
- # attr_accessor :title
13
- #
14
- # attr_accessible :title
15
- # end
16
- #
17
- # class User
18
- # include ActiveModel::Model
19
- # include ActiveModel::MassAssignmentSecurity
20
- # attr_accessor :encrypted_password
21
- #
22
- # attr_protected :encrypted_password
23
- # end
24
- #
25
- # # RSpec
26
- # RSpec.describe Post, type: :model do
27
- # it { should allow_mass_assignment_of(:title) }
28
- # end
29
- #
30
- # RSpec.describe User, type: :model do
31
- # it { should_not allow_mass_assignment_of(:encrypted_password) }
32
- # end
33
- #
34
- # # Minitest (Shoulda)
35
- # class PostTest < ActiveSupport::TestCase
36
- # should allow_mass_assignment_of(:title)
37
- # end
38
- #
39
- # class UserTest < ActiveSupport::TestCase
40
- # should_not allow_mass_assignment_of(:encrypted_password)
41
- # end
42
- #
43
- # #### Optional qualifiers
44
- #
45
- # ##### as
46
- #
47
- # Use `as` if your mass-assignment rules apply only under a certain role
48
- # *(Rails >= 3.1 only)*.
49
- #
50
- # class Post
51
- # include ActiveModel::Model
52
- # include ActiveModel::MassAssignmentSecurity
53
- # attr_accessor :title
54
- #
55
- # attr_accessible :title, as: :admin
56
- # end
57
- #
58
- # # RSpec
59
- # RSpec.describe Post, type: :model do
60
- # it { should allow_mass_assignment_of(:title).as(:admin) }
61
- # end
62
- #
63
- # # Minitest (Shoulda)
64
- # class PostTest < ActiveSupport::TestCase
65
- # should allow_mass_assignment_of(:title).as(:admin)
66
- # end
67
- #
68
- # @return [AllowMassAssignmentOfMatcher]
69
- #
70
- def allow_mass_assignment_of(value)
71
- AllowMassAssignmentOfMatcher.new(value)
72
- end
73
-
74
- # @private
75
- class AllowMassAssignmentOfMatcher
76
- attr_reader :failure_message, :failure_message_when_negated
77
-
78
- def initialize(attribute)
79
- @attribute = attribute.to_s
80
- @options = {}
81
- end
82
-
83
- def as(role)
84
- @options[:role] = role
85
- self
86
- end
87
-
88
- def matches?(subject)
89
- @subject = subject
90
- if attr_mass_assignable?
91
- if whitelisting?
92
- @failure_message_when_negated = "#{@attribute} was made accessible"
93
- else
94
- if protected_attributes.empty?
95
- @failure_message_when_negated = 'no attributes were protected'
96
- else
97
- @failure_message_when_negated = "#{class_name} is protecting " <<
98
- "#{protected_attributes.to_a.to_sentence}, " <<
99
- "but not #{@attribute}."
100
- end
101
- end
102
- true
103
- else
104
- if whitelisting?
105
- @failure_message = "Expected #{@attribute} to be accessible"
106
- else
107
- @failure_message = "Did not expect #{@attribute} to be protected"
108
- end
109
- false
110
- end
111
- end
112
-
113
- def description
114
- [base_description, role_description].compact.join(' ')
115
- end
116
-
117
- private
118
-
119
- def base_description
120
- "allow mass assignment of #{@attribute}"
121
- end
122
-
123
- def role_description
124
- if role != :default
125
- "as #{role}"
126
- end
127
- end
128
-
129
- def role
130
- @options[:role] || :default
131
- end
132
-
133
- def protected_attributes
134
- @protected_attributes ||= (@subject.class.protected_attributes || [])
135
- end
136
-
137
- def accessible_attributes
138
- @accessible_attributes ||= (@subject.class.accessible_attributes || [])
139
- end
140
-
141
- def whitelisting?
142
- authorizer.kind_of?(::ActiveModel::MassAssignmentSecurity::WhiteList)
143
- end
144
-
145
- def attr_mass_assignable?
146
- !authorizer.deny?(@attribute)
147
- end
148
-
149
- def authorizer
150
- @subject.class.active_authorizer[role]
151
- end
152
-
153
- def class_name
154
- @subject.class.name
155
- end
156
- end
157
- end
158
- end
159
- end