shoulda-matchers 4.5.0 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -10
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +0 -87
- data/lib/shoulda/matchers/action_controller/flash_store.rb +2 -4
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +3 -6
- data/lib/shoulda/matchers/active_model/helpers.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +12 -1
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validator.rb +1 -6
- data/lib/shoulda/matchers/active_model.rb +0 -1
- data/lib/shoulda/matchers/active_record/association_matcher.rb +27 -14
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +10 -1
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +21 -3
- data/lib/shoulda/matchers/rails_shim.rb +0 -39
- data/lib/shoulda/matchers/util/word_wrap.rb +1 -1
- data/lib/shoulda/matchers/version.rb +1 -1
- data/shoulda-matchers.gemspec +2 -2
- metadata +6 -7
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +0 -161
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 188abbfbc6cac3e26997733b3d88b34ea74e9747e25f137738190bf15d033751
|
4
|
+
data.tar.gz: 73136b35573cffac784cadd7e3193e8e9a0934f0e69fa751f536ed589db01024
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55f3ccad9ce3d4affcb6ccc38020872bc000710f887765d7b78962bcdd339d79a2a1316e3a9d2cb33c62887e66bab9e54801d79c872f6cab7a2459a32ddce4bf
|
7
|
+
data.tar.gz: e5a862e62f25dfe284f0325f20600bbc4a3567ef78a0b7742685d1a9af9d03147ab650a259be287bd4566719444c7d998c0106874b7c3ac43efbd79996191838
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# Shoulda Matchers [![Gem Version][version-badge]][rubygems] [![Build Status][
|
1
|
+
# Shoulda Matchers [![Gem Version][version-badge]][rubygems] [![Build Status][github-actions-badge]][github-actions] [![Total Downloads][downloads-total]][rubygems] [![Downloads][downloads-badge]][rubygems]
|
2
2
|
|
3
3
|
[version-badge]: https://img.shields.io/gem/v/shoulda-matchers.svg
|
4
4
|
[rubygems]: https://rubygems.org/gems/shoulda-matchers
|
5
|
-
[
|
6
|
-
[
|
5
|
+
[github-actions-badge]: https://img.shields.io/github/workflow/status/thoughtbot/shoulda-matchers/Test
|
6
|
+
[github-actions]: https://github.com/thoughtbot/shoulda-matchers/actions
|
7
7
|
[downloads-total]: https://img.shields.io/gem/dt/shoulda-matchers.svg
|
8
8
|
[downloads-badge]: https://img.shields.io/gem/dtv/shoulda-matchers.svg
|
9
9
|
[downloads-badge]: https://img.shields.io/gem/dtv/shoulda-matchers.svg
|
@@ -55,7 +55,7 @@ Start by including `shoulda-matchers` in your Gemfile:
|
|
55
55
|
|
56
56
|
```ruby
|
57
57
|
group :test do
|
58
|
-
gem 'shoulda-matchers', '~>
|
58
|
+
gem 'shoulda-matchers', '~> 5.0'
|
59
59
|
end
|
60
60
|
```
|
61
61
|
|
@@ -430,11 +430,11 @@ about any of them, make sure to [consult the documentation][rubydocs]!
|
|
430
430
|
makes assertions on the `session` hash.
|
431
431
|
* **[set_flash](lib/shoulda/matchers/action_controller/set_flash_matcher.rb)**
|
432
432
|
makes assertions on the `flash` hash.
|
433
|
-
* **[use_after_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#
|
433
|
+
* **[use_after_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L29)**
|
434
434
|
tests that an `after_action` callback is defined in your controller.
|
435
|
-
* **[use_around_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#
|
435
|
+
* **[use_around_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L75)**
|
436
436
|
tests that an `around_action` callback is defined in your controller.
|
437
|
-
* **[use_before_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#
|
437
|
+
* **[use_before_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L4)**
|
438
438
|
tests that a `before_action` callback is defined in your controller.
|
439
439
|
|
440
440
|
### Routing matchers
|
@@ -468,12 +468,14 @@ machine, understanding the codebase, and creating a good pull request.
|
|
468
468
|
|
469
469
|
## Compatibility
|
470
470
|
|
471
|
-
Shoulda Matchers is
|
472
|
-
|
471
|
+
Shoulda Matchers is tested and supported against Ruby 2.6+, Rails
|
472
|
+
5.2+, RSpec 3.x, and Minitest 5.x.
|
473
473
|
|
474
|
-
For Ruby < 2.4 and Rails < 4.1 compatibility, please use [v3.1.3][v3.1.3].
|
474
|
+
- For Ruby < 2.4 and Rails < 4.1 compatibility, please use [v3.1.3][v3.1.3].
|
475
|
+
- For Ruby < 3.0 and Rails < 6.1 compatibility, please use [v4.5.1][v4.5.1].
|
475
476
|
|
476
477
|
[v3.1.3]: https://github.com/thoughtbot/shoulda-matchers/tree/v3.1.3
|
478
|
+
[v4.5.1]: https://github.com/thoughtbot/shoulda-matchers/tree/v4.5.1
|
477
479
|
|
478
480
|
## Versioning
|
479
481
|
|
@@ -1,64 +1,6 @@
|
|
1
1
|
module Shoulda
|
2
2
|
module Matchers
|
3
3
|
module ActionController
|
4
|
-
# The `use_before_filter` matcher is used to test that a before_filter
|
5
|
-
# callback is defined within your controller.
|
6
|
-
#
|
7
|
-
# class UsersController < ApplicationController
|
8
|
-
# before_filter :authenticate_user!
|
9
|
-
# end
|
10
|
-
#
|
11
|
-
# # RSpec
|
12
|
-
# RSpec.describe UsersController, type: :controller do
|
13
|
-
# it { should use_before_filter(:authenticate_user!) }
|
14
|
-
# it { should_not use_before_filter(:prevent_ssl) }
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# # Minitest (Shoulda)
|
18
|
-
# class UsersControllerTest < ActionController::TestCase
|
19
|
-
# should use_before_filter(:authenticate_user!)
|
20
|
-
# should_not use_before_filter(:prevent_ssl)
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# @note This method is only available when using shoulda-matchers under
|
24
|
-
# Rails 4.x.
|
25
|
-
# @return [CallbackMatcher]
|
26
|
-
#
|
27
|
-
if RailsShim.action_pack_lt_5?
|
28
|
-
def use_before_filter(callback)
|
29
|
-
CallbackMatcher.new(callback, :before, :filter)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# The `use_after_filter` matcher is used to test that an after_filter
|
34
|
-
# callback is defined within your controller.
|
35
|
-
#
|
36
|
-
# class IssuesController < ApplicationController
|
37
|
-
# after_filter :log_activity
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# # RSpec
|
41
|
-
# RSpec.describe IssuesController, type: :controller do
|
42
|
-
# it { should use_after_filter(:log_activity) }
|
43
|
-
# it { should_not use_after_filter(:destroy_user) }
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# # Minitest (Shoulda)
|
47
|
-
# class IssuesControllerTest < ActionController::TestCase
|
48
|
-
# should use_after_filter(:log_activity)
|
49
|
-
# should_not use_after_filter(:destroy_user)
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# @note This method is only available when using shoulda-matchers under
|
53
|
-
# Rails 4.x.
|
54
|
-
# @return [CallbackMatcher]
|
55
|
-
#
|
56
|
-
if RailsShim.action_pack_lt_5?
|
57
|
-
def use_after_filter(callback)
|
58
|
-
CallbackMatcher.new(callback, :after, :filter)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
4
|
# The `use_before_action` matcher is used to test that a before_action
|
63
5
|
# callback is defined within your controller.
|
64
6
|
#
|
@@ -109,35 +51,6 @@ module Shoulda
|
|
109
51
|
CallbackMatcher.new(callback, :after, :action)
|
110
52
|
end
|
111
53
|
|
112
|
-
# The `use_around_filter` matcher is used to test that an around_filter
|
113
|
-
# callback is defined within your controller.
|
114
|
-
#
|
115
|
-
# class ChangesController < ApplicationController
|
116
|
-
# around_filter :wrap_in_transaction
|
117
|
-
# end
|
118
|
-
#
|
119
|
-
# # RSpec
|
120
|
-
# RSpec.describe ChangesController, type: :controller do
|
121
|
-
# it { should use_around_filter(:wrap_in_transaction) }
|
122
|
-
# it { should_not use_around_filter(:save_view_context) }
|
123
|
-
# end
|
124
|
-
#
|
125
|
-
# # Minitest (Shoulda)
|
126
|
-
# class ChangesControllerTest < ActionController::TestCase
|
127
|
-
# should use_around_filter(:wrap_in_transaction)
|
128
|
-
# should_not use_around_filter(:save_view_context)
|
129
|
-
# end
|
130
|
-
#
|
131
|
-
# @note This method is only available when using shoulda-matchers under
|
132
|
-
# Rails 4.x.
|
133
|
-
# @return [CallbackMatcher]
|
134
|
-
#
|
135
|
-
if RailsShim.action_pack_lt_5?
|
136
|
-
def use_around_filter(callback)
|
137
|
-
CallbackMatcher.new(callback, :around, :filter)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
54
|
# The `use_around_action` matcher is used to test that an around_action
|
142
55
|
# callback is defined within your controller.
|
143
56
|
#
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
1
2
|
module Shoulda
|
2
3
|
module Matchers
|
3
4
|
module ActionController
|
@@ -34,10 +35,7 @@ module Shoulda
|
|
34
35
|
expected_value === actual_value
|
35
36
|
end
|
36
37
|
end
|
37
|
-
|
38
|
-
def empty?
|
39
|
-
flash.empty?
|
40
|
-
end
|
38
|
+
delegate :empty?, to: :flash
|
41
39
|
|
42
40
|
def use_now!
|
43
41
|
@use_now = true
|
@@ -251,12 +251,9 @@ module Shoulda
|
|
251
251
|
parameters_double_registry.register
|
252
252
|
|
253
253
|
Doublespeak.with_doubles_activated do
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
action,
|
258
|
-
request_params,
|
259
|
-
)
|
254
|
+
params = { params: request_params }
|
255
|
+
|
256
|
+
context.__send__(verb, action, **params)
|
260
257
|
end
|
261
258
|
|
262
259
|
unpermitted_parameter_names.empty?
|
@@ -109,11 +109,13 @@ module Shoulda
|
|
109
109
|
end
|
110
110
|
elsif array_column?
|
111
111
|
['an arbitary value']
|
112
|
+
elsif enum_column?
|
113
|
+
enum_values.first
|
112
114
|
else
|
113
115
|
case column_type
|
114
116
|
when :integer, :float then 1
|
115
117
|
when :decimal then BigDecimal(1, 0)
|
116
|
-
when :datetime, :time, :timestamp then Time.
|
118
|
+
when :datetime, :time, :timestamp then Time.current
|
117
119
|
when :date then Date.new
|
118
120
|
when :binary then '0'
|
119
121
|
else 'an arbitrary value'
|
@@ -145,6 +147,15 @@ module Shoulda
|
|
145
147
|
@subject.class.columns_hash[@attribute.to_s].respond_to?(:array) &&
|
146
148
|
@subject.class.columns_hash[@attribute.to_s].array
|
147
149
|
end
|
150
|
+
|
151
|
+
def enum_column?
|
152
|
+
@subject.class.respond_to?(:defined_enums) &&
|
153
|
+
@subject.class.defined_enums.key?(@attribute.to_s)
|
154
|
+
end
|
155
|
+
|
156
|
+
def enum_values
|
157
|
+
@subject.class.defined_enums[@attribute.to_s].values
|
158
|
+
end
|
148
159
|
end
|
149
160
|
end
|
150
161
|
end
|
@@ -643,7 +643,7 @@ module Shoulda
|
|
643
643
|
if number_of_submatchers_for_failure_message > 1
|
644
644
|
"In checking that #{model.name} #{submatcher_description}, " +
|
645
645
|
failure_message[0].downcase +
|
646
|
-
failure_message[1
|
646
|
+
failure_message[1..]
|
647
647
|
else
|
648
648
|
failure_message
|
649
649
|
end
|
@@ -327,8 +327,8 @@ validation for you? Instead of using `validate_presence_of`, try
|
|
327
327
|
end
|
328
328
|
|
329
329
|
def collection_association?
|
330
|
-
association? &&
|
331
|
-
|
330
|
+
association? && [:has_many, :has_and_belongs_to_many].include?(
|
331
|
+
association_reflection.macro,
|
332
332
|
)
|
333
333
|
end
|
334
334
|
|
@@ -98,12 +98,7 @@ module Shoulda
|
|
98
98
|
|
99
99
|
all_validation_errors = record.errors.dup
|
100
100
|
|
101
|
-
validation_error_messages =
|
102
|
-
if record.errors.respond_to?(:[])
|
103
|
-
record.errors[attribute]
|
104
|
-
else
|
105
|
-
record.errors.on(attribute)
|
106
|
-
end
|
101
|
+
validation_error_messages = record.errors[attribute]
|
107
102
|
|
108
103
|
{
|
109
104
|
all_validation_errors: all_validation_errors,
|
@@ -26,7 +26,6 @@ require 'shoulda/matchers/active_model/numericality_matchers/comparison_matcher'
|
|
26
26
|
require 'shoulda/matchers/active_model/numericality_matchers/odd_number_matcher'
|
27
27
|
require 'shoulda/matchers/active_model/numericality_matchers/even_number_matcher'
|
28
28
|
require 'shoulda/matchers/active_model/numericality_matchers/only_integer_matcher'
|
29
|
-
require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher'
|
30
29
|
require 'shoulda/matchers/active_model/errors'
|
31
30
|
require 'shoulda/matchers/active_model/have_secure_password_matcher'
|
32
31
|
|
@@ -1004,7 +1004,7 @@ module Shoulda
|
|
1004
1004
|
@submatchers = []
|
1005
1005
|
@missing = ''
|
1006
1006
|
|
1007
|
-
if macro == :belongs_to
|
1007
|
+
if macro == :belongs_to
|
1008
1008
|
required(belongs_to_required_by_default?)
|
1009
1009
|
end
|
1010
1010
|
end
|
@@ -1394,14 +1394,25 @@ module Shoulda
|
|
1394
1394
|
end
|
1395
1395
|
|
1396
1396
|
def class_has_foreign_key?(klass)
|
1397
|
+
@missing = validate_foreign_key(klass)
|
1398
|
+
|
1399
|
+
@missing.nil?
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
def validate_foreign_key(klass)
|
1397
1403
|
if options.key?(:foreign_key) && !foreign_key_correct?
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1404
|
+
foreign_key_failure_message(klass, options[:foreign_key])
|
1405
|
+
elsif !has_column?(klass, actual_foreign_key)
|
1406
|
+
foreign_key_failure_message(klass, actual_foreign_key)
|
1407
|
+
end
|
1408
|
+
end
|
1409
|
+
|
1410
|
+
def has_column?(klass, column)
|
1411
|
+
case column
|
1412
|
+
when Array
|
1413
|
+
column.all? { |c| has_column?(klass, c.to_s) }
|
1403
1414
|
else
|
1404
|
-
|
1415
|
+
column_names_for(klass).include?(column.to_s)
|
1405
1416
|
end
|
1406
1417
|
end
|
1407
1418
|
|
@@ -1433,13 +1444,15 @@ module Shoulda
|
|
1433
1444
|
end
|
1434
1445
|
end
|
1435
1446
|
|
1436
|
-
def
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1447
|
+
def actual_foreign_key
|
1448
|
+
return unless foreign_key_reflection
|
1449
|
+
|
1450
|
+
if foreign_key_reflection.options[:foreign_key]
|
1451
|
+
foreign_key_reflection.options[:foreign_key]
|
1452
|
+
elsif foreign_key_reflection.respond_to?(:foreign_key)
|
1453
|
+
foreign_key_reflection.foreign_key
|
1454
|
+
else
|
1455
|
+
foreign_key_reflection.primary_key_name
|
1443
1456
|
end
|
1444
1457
|
end
|
1445
1458
|
|
@@ -6,16 +6,22 @@ module Shoulda
|
|
6
6
|
#
|
7
7
|
# class Process < ActiveRecord::Base
|
8
8
|
# enum status: [:running, :stopped, :suspended]
|
9
|
+
#
|
10
|
+
# alias_attribute :kind, :SomeLegacyField
|
11
|
+
#
|
12
|
+
# enum kind: [:foo, :bar]
|
9
13
|
# end
|
10
14
|
#
|
11
15
|
# # RSpec
|
12
16
|
# RSpec.describe Process, type: :model do
|
13
17
|
# it { should define_enum_for(:status) }
|
18
|
+
# it { should define_enum_for(:kind) }
|
14
19
|
# end
|
15
20
|
#
|
16
21
|
# # Minitest (Shoulda)
|
17
22
|
# class ProcessTest < ActiveSupport::TestCase
|
18
23
|
# should define_enum_for(:status)
|
24
|
+
# should define_enum_for(:kind)
|
19
25
|
# end
|
20
26
|
#
|
21
27
|
# #### Qualifiers
|
@@ -370,7 +376,10 @@ module Shoulda
|
|
370
376
|
end
|
371
377
|
|
372
378
|
def column
|
373
|
-
|
379
|
+
key = attribute_name.to_s
|
380
|
+
column_name = model.attribute_alias(key) || key
|
381
|
+
|
382
|
+
model.columns_hash[column_name]
|
374
383
|
end
|
375
384
|
|
376
385
|
def model
|
@@ -52,7 +52,7 @@ module Shoulda
|
|
52
52
|
#
|
53
53
|
# Use `with_options` to assert that a column has been defined with
|
54
54
|
# certain options (`:precision`, `:limit`, `:default`, `:null`, `:scale`,
|
55
|
-
# or `:
|
55
|
+
# `:primary` or `:array`).
|
56
56
|
#
|
57
57
|
# class CreatePhones < ActiveRecord::Migration
|
58
58
|
# def change
|
@@ -84,7 +84,7 @@ module Shoulda
|
|
84
84
|
|
85
85
|
# @private
|
86
86
|
class HaveDbColumnMatcher
|
87
|
-
OPTIONS = %i(precision limit default null scale primary).freeze
|
87
|
+
OPTIONS = %i(precision limit default null scale primary array).freeze
|
88
88
|
|
89
89
|
def initialize(column)
|
90
90
|
@column = column
|
@@ -115,7 +115,8 @@ module Shoulda
|
|
115
115
|
correct_default? &&
|
116
116
|
correct_null? &&
|
117
117
|
correct_scale? &&
|
118
|
-
correct_primary?
|
118
|
+
correct_primary? &&
|
119
|
+
correct_array?
|
119
120
|
end
|
120
121
|
|
121
122
|
def failure_message
|
@@ -258,6 +259,23 @@ module Shoulda
|
|
258
259
|
end
|
259
260
|
end
|
260
261
|
|
262
|
+
def correct_array?
|
263
|
+
return true unless @options.key?(:array)
|
264
|
+
|
265
|
+
if matched_column.array? == @options[:array]
|
266
|
+
true
|
267
|
+
else
|
268
|
+
@missing = "#{model_class} has a db column named #{@column} "
|
269
|
+
@missing <<
|
270
|
+
if @options[:primary]
|
271
|
+
'that is not array, but should be'
|
272
|
+
else
|
273
|
+
'that is array, but should not be'
|
274
|
+
end
|
275
|
+
false
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
261
279
|
def matched_column
|
262
280
|
@_matched_column ||= begin
|
263
281
|
column = model_class.columns.detect do |each|
|
@@ -3,24 +3,12 @@ module Shoulda
|
|
3
3
|
# @private
|
4
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 active_record_gte_5?
|
21
|
-
Gem::Requirement.new('>= 5').satisfied_by?(active_record_version)
|
22
|
-
end
|
23
|
-
|
24
12
|
def active_record_gte_6?
|
25
13
|
Gem::Requirement.new('>= 6').satisfied_by?(active_record_version)
|
26
14
|
end
|
@@ -57,17 +45,6 @@ module Shoulda
|
|
57
45
|
)
|
58
46
|
end
|
59
47
|
|
60
|
-
def make_controller_request(context, verb, action, request_params)
|
61
|
-
params =
|
62
|
-
if action_pack_gte_5?
|
63
|
-
{ params: request_params }
|
64
|
-
else
|
65
|
-
request_params
|
66
|
-
end
|
67
|
-
|
68
|
-
context.__send__(verb, action, params)
|
69
|
-
end
|
70
|
-
|
71
48
|
def serialized_attributes_for(model)
|
72
49
|
attribute_types_for(model).
|
73
50
|
inject({}) do |hash, (attribute_name, attribute_type)|
|
@@ -85,26 +62,10 @@ module Shoulda
|
|
85
62
|
serialized_attributes_for(model)[attribute_name.to_s]
|
86
63
|
end
|
87
64
|
|
88
|
-
def tables_and_views(connection)
|
89
|
-
if active_record_gte_5?
|
90
|
-
connection.data_sources
|
91
|
-
else
|
92
|
-
connection.tables
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
65
|
def verb_for_update
|
97
66
|
:patch
|
98
67
|
end
|
99
68
|
|
100
|
-
def validation_message_key_for_association_required_option
|
101
|
-
if active_record_gte_5?
|
102
|
-
:required
|
103
|
-
else
|
104
|
-
:blank
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
69
|
def parent_of(mod)
|
109
70
|
if mod.respond_to?(:module_parent)
|
110
71
|
mod.module_parent
|
data/shoulda-matchers.gemspec
CHANGED
@@ -36,6 +36,6 @@ Gem::Specification.new do |s|
|
|
36
36
|
'shoulda-matchers.gemspec']
|
37
37
|
s.require_paths = ['lib']
|
38
38
|
|
39
|
-
s.required_ruby_version = '>= 2.
|
40
|
-
s.add_dependency('activesupport', '>=
|
39
|
+
s.required_ruby_version = '>= 2.6.0'
|
40
|
+
s.add_dependency('activesupport', '>= 5.2.0')
|
41
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
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tammer Saleh
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2021-
|
17
|
+
date: 2021-12-22 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activesupport
|
@@ -22,14 +22,14 @@ dependencies:
|
|
22
22
|
requirements:
|
23
23
|
- - ">="
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version:
|
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:
|
32
|
+
version: 5.2.0
|
33
33
|
description: 'Shoulda Matchers provides RSpec- and Minitest-compatible one-liners
|
34
34
|
to test common Rails functionality that, if written by hand, would be much longer,
|
35
35
|
more complex, and error-prone. '
|
@@ -60,7 +60,6 @@ files:
|
|
60
60
|
- lib/shoulda/matchers/action_controller/set_session_matcher.rb
|
61
61
|
- lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb
|
62
62
|
- lib/shoulda/matchers/active_model.rb
|
63
|
-
- lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb
|
64
63
|
- lib/shoulda/matchers/active_model/allow_value_matcher.rb
|
65
64
|
- lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb
|
66
65
|
- lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb
|
@@ -186,14 +185,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
186
185
|
requirements:
|
187
186
|
- - ">="
|
188
187
|
- !ruby/object:Gem::Version
|
189
|
-
version: 2.
|
188
|
+
version: 2.6.0
|
190
189
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
190
|
requirements:
|
192
191
|
- - ">="
|
193
192
|
- !ruby/object:Gem::Version
|
194
193
|
version: '0'
|
195
194
|
requirements: []
|
196
|
-
rubygems_version: 3.
|
195
|
+
rubygems_version: 3.2.32
|
197
196
|
signing_key:
|
198
197
|
specification_version: 4
|
199
198
|
summary: Simple one-liner tests for common Rails functionality
|
@@ -1,161 +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 "\
|
93
|
-
'accessible'
|
94
|
-
elsif protected_attributes.empty?
|
95
|
-
@failure_message_when_negated = 'no attributes were protected'
|
96
|
-
else
|
97
|
-
@failure_message_when_negated =
|
98
|
-
"#{class_name} is protecting " <<
|
99
|
-
"#{protected_attributes.to_a.to_sentence}, " <<
|
100
|
-
"but not #{@attribute}."
|
101
|
-
end
|
102
|
-
true
|
103
|
-
else
|
104
|
-
@failure_message =
|
105
|
-
if whitelisting?
|
106
|
-
"Expected #{@attribute} to be accessible"
|
107
|
-
else
|
108
|
-
"Did not expect #{@attribute} to be protected"
|
109
|
-
end
|
110
|
-
false
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def description
|
115
|
-
[base_description, role_description].compact.join(' ')
|
116
|
-
end
|
117
|
-
|
118
|
-
private
|
119
|
-
|
120
|
-
def base_description
|
121
|
-
"allow mass assignment of #{@attribute}"
|
122
|
-
end
|
123
|
-
|
124
|
-
def role_description
|
125
|
-
if role != :default
|
126
|
-
"as #{role}"
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def role
|
131
|
-
@options[:role] || :default
|
132
|
-
end
|
133
|
-
|
134
|
-
def protected_attributes
|
135
|
-
@_protected_attributes ||= (@subject.class.protected_attributes || [])
|
136
|
-
end
|
137
|
-
|
138
|
-
def accessible_attributes
|
139
|
-
@_accessible_attributes ||=
|
140
|
-
(@subject.class.accessible_attributes || [])
|
141
|
-
end
|
142
|
-
|
143
|
-
def whitelisting?
|
144
|
-
authorizer.is_a?(::ActiveModel::MassAssignmentSecurity::WhiteList)
|
145
|
-
end
|
146
|
-
|
147
|
-
def attr_mass_assignable?
|
148
|
-
!authorizer.deny?(@attribute)
|
149
|
-
end
|
150
|
-
|
151
|
-
def authorizer
|
152
|
-
@subject.class.active_authorizer[role]
|
153
|
-
end
|
154
|
-
|
155
|
-
def class_name
|
156
|
-
@subject.class.name
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|