shoulda-matchers 5.3.0 → 6.1.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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +26 -9
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +7 -9
- data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +13 -15
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +10 -1
- data/lib/shoulda/matchers/active_model/comparison_matcher.rb +157 -0
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +7 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/range_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/numericality_matchers/submatchers.rb +16 -6
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +0 -6
- data/lib/shoulda/matchers/active_model/validate_comparison_of_matcher.rb +532 -0
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +64 -9
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +40 -96
- data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +6 -7
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +6 -0
- data/lib/shoulda/matchers/active_model/validator.rb +4 -0
- data/lib/shoulda/matchers/active_model.rb +2 -1
- data/lib/shoulda/matchers/active_record/association_matcher.rb +31 -11
- data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +23 -19
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +27 -23
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +0 -8
- data/lib/shoulda/matchers/active_record/encrypt_matcher.rb +174 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +46 -6
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +24 -13
- data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +3 -5
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/normalize_matcher.rb +151 -0
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +82 -70
- data/lib/shoulda/matchers/active_record.rb +2 -0
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +2 -6
- data/lib/shoulda/matchers/doublespeak/world.rb +2 -6
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +13 -15
- data/lib/shoulda/matchers/rails_shim.rb +8 -6
- data/lib/shoulda/matchers/util/word_wrap.rb +1 -1
- data/lib/shoulda/matchers/util.rb +17 -19
- data/lib/shoulda/matchers/version.rb +1 -1
- data/lib/shoulda/matchers.rb +2 -2
- data/shoulda-matchers.gemspec +1 -1
- metadata +11 -8
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +0 -136
@@ -411,9 +411,29 @@ module Shoulda
|
|
411
411
|
if scopes_match?
|
412
412
|
true
|
413
413
|
else
|
414
|
-
@failure_reason = 'Expected the validation '
|
414
|
+
@failure_reason = String.new('Expected the validation ').tap do |failure_reason_string|
|
415
|
+
failure_reason_string <<
|
416
|
+
if expected_scopes.empty?
|
417
|
+
'not to be scoped to anything, '
|
418
|
+
else
|
419
|
+
"to be scoped to #{inspected_expected_scopes}, "
|
420
|
+
end
|
421
|
+
|
422
|
+
if actual_sets_of_scopes.any?
|
423
|
+
failure_reason_string << 'but it was scoped to '
|
424
|
+
failure_reason_string << "#{inspected_actual_scopes} instead."
|
425
|
+
else
|
426
|
+
failure_reason_string << 'but it was not scoped to anything.'
|
427
|
+
end
|
428
|
+
end
|
415
429
|
|
416
|
-
|
430
|
+
false
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def build_failure_reason
|
435
|
+
String.new('Expected the validation ').tap do |failure_reason_string|
|
436
|
+
failure_reason_string <<
|
417
437
|
if expected_scopes.empty?
|
418
438
|
'not to be scoped to anything, '
|
419
439
|
else
|
@@ -421,27 +441,25 @@ module Shoulda
|
|
421
441
|
end
|
422
442
|
|
423
443
|
if actual_sets_of_scopes.any?
|
424
|
-
|
425
|
-
|
444
|
+
failure_reason_string << 'but it was scoped to '
|
445
|
+
failure_reason_string << "#{inspected_actual_scopes} instead."
|
426
446
|
else
|
427
|
-
|
447
|
+
failure_reason_string << 'but it was not scoped to anything.'
|
428
448
|
end
|
429
|
-
|
430
|
-
false
|
431
449
|
end
|
432
450
|
end
|
433
451
|
|
434
452
|
def does_not_match_scopes_configuration?
|
435
453
|
if scopes_match?
|
436
|
-
@failure_reason = 'Expected the validation '
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
454
|
+
@failure_reason = String.new('Expected the validation ').tap do |failure_reason|
|
455
|
+
if expected_scopes.empty?
|
456
|
+
failure_reason << 'to be scoped to nothing, '
|
457
|
+
failure_reason << 'but it was scoped to '
|
458
|
+
failure_reason << "#{inspected_actual_scopes} instead."
|
459
|
+
else
|
460
|
+
failure_reason << 'not to be scoped to '
|
461
|
+
failure_reason << inspected_expected_scopes
|
462
|
+
end
|
445
463
|
end
|
446
464
|
|
447
465
|
false
|
@@ -618,20 +636,18 @@ module Shoulda
|
|
618
636
|
else
|
619
637
|
inspected_scopes = scopes_missing_on_model.map(&:inspect)
|
620
638
|
|
621
|
-
|
622
|
-
|
623
|
-
reason << inspected_scopes.to_sentence
|
624
|
-
|
625
|
-
reason <<
|
626
|
-
if inspected_scopes.many?
|
627
|
-
' do not seem to be attributes'
|
628
|
-
else
|
629
|
-
' does not seem to be an attribute'
|
630
|
-
end
|
639
|
+
@failure_reason = String.new.tap do |reason|
|
640
|
+
reason << inspected_scopes.to_sentence
|
631
641
|
|
632
|
-
|
642
|
+
reason <<
|
643
|
+
if inspected_scopes.many?
|
644
|
+
' do not seem to be attributes'
|
645
|
+
else
|
646
|
+
' does not seem to be an attribute'
|
647
|
+
end
|
633
648
|
|
634
|
-
|
649
|
+
reason << " on #{model.name}."
|
650
|
+
end
|
635
651
|
|
636
652
|
false
|
637
653
|
end
|
@@ -643,20 +659,18 @@ module Shoulda
|
|
643
659
|
else
|
644
660
|
inspected_scopes = scopes_present_on_model.map(&:inspect)
|
645
661
|
|
646
|
-
|
647
|
-
|
648
|
-
reason << inspected_scopes.to_sentence
|
649
|
-
|
650
|
-
reason <<
|
651
|
-
if inspected_scopes.many?
|
652
|
-
' seem to be attributes'
|
653
|
-
else
|
654
|
-
' seems to be an attribute'
|
655
|
-
end
|
662
|
+
@failure_reason = String.new.tap do |reason|
|
663
|
+
reason << inspected_scopes.to_sentence
|
656
664
|
|
657
|
-
|
665
|
+
reason <<
|
666
|
+
if inspected_scopes.many?
|
667
|
+
' seem to be attributes'
|
668
|
+
else
|
669
|
+
' seems to be an attribute'
|
670
|
+
end
|
658
671
|
|
659
|
-
|
672
|
+
reason << " on #{model.name}."
|
673
|
+
end
|
660
674
|
|
661
675
|
false
|
662
676
|
end
|
@@ -936,45 +950,43 @@ module Shoulda
|
|
936
950
|
end
|
937
951
|
|
938
952
|
def failure_message_preface # rubocop:disable Metrics/MethodLength
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
953
|
+
String.new.tap do |prefix|
|
954
|
+
if @existing_record_created
|
955
|
+
prefix << "After taking the given #{model.name}"
|
956
|
+
|
957
|
+
if attribute_setter_for_existing_record
|
958
|
+
prefix << ', setting '
|
959
|
+
prefix << description_for_attribute_setter(
|
960
|
+
attribute_setter_for_existing_record,
|
961
|
+
)
|
962
|
+
else
|
963
|
+
prefix << ", whose :#{attribute} is "
|
964
|
+
prefix << "‹#{existing_value_read.inspect}›"
|
965
|
+
end
|
943
966
|
|
944
|
-
|
945
|
-
|
967
|
+
prefix << ', and saving it as the existing record, then'
|
968
|
+
elsif attribute_setter_for_existing_record
|
969
|
+
prefix << "Given an existing #{model.name},"
|
970
|
+
prefix << ' after setting '
|
946
971
|
prefix << description_for_attribute_setter(
|
947
972
|
attribute_setter_for_existing_record,
|
948
973
|
)
|
974
|
+
prefix << ', then'
|
949
975
|
else
|
950
|
-
prefix << "
|
951
|
-
prefix <<
|
976
|
+
prefix << "Given an existing #{model.name} whose :#{attribute}"
|
977
|
+
prefix << ' is '
|
978
|
+
prefix << Shoulda::Matchers::Util.inspect_value(
|
979
|
+
existing_value_read,
|
980
|
+
)
|
981
|
+
prefix << ', after'
|
952
982
|
end
|
953
983
|
|
954
|
-
prefix <<
|
955
|
-
elsif attribute_setter_for_existing_record
|
956
|
-
prefix << "Given an existing #{model.name},"
|
957
|
-
prefix << ' after setting '
|
958
|
-
prefix << description_for_attribute_setter(
|
959
|
-
attribute_setter_for_existing_record,
|
960
|
-
)
|
961
|
-
prefix << ', then'
|
962
|
-
else
|
963
|
-
prefix << "Given an existing #{model.name} whose :#{attribute}"
|
964
|
-
prefix << ' is '
|
965
|
-
prefix << Shoulda::Matchers::Util.inspect_value(
|
966
|
-
existing_value_read,
|
967
|
-
)
|
968
|
-
prefix << ', after'
|
969
|
-
end
|
970
|
-
|
971
|
-
prefix << " making a new #{model.name} and setting "
|
984
|
+
prefix << " making a new #{model.name} and setting "
|
972
985
|
|
973
|
-
|
986
|
+
prefix << descriptions_for_attribute_setters_for_new_record
|
974
987
|
|
975
|
-
|
976
|
-
|
977
|
-
prefix
|
988
|
+
prefix << ", the matcher expected the new #{model.name} to be"
|
989
|
+
end
|
978
990
|
end
|
979
991
|
|
980
992
|
def attribute_changed_value_message
|
@@ -24,6 +24,8 @@ require 'shoulda/matchers/active_record/define_enum_for_matcher'
|
|
24
24
|
require 'shoulda/matchers/active_record/uniqueness'
|
25
25
|
require 'shoulda/matchers/active_record/validate_uniqueness_of_matcher'
|
26
26
|
require 'shoulda/matchers/active_record/have_attached_matcher'
|
27
|
+
require 'shoulda/matchers/active_record/normalize_matcher'
|
28
|
+
require 'shoulda/matchers/active_record/encrypt_matcher'
|
27
29
|
|
28
30
|
module Shoulda
|
29
31
|
module Matchers
|
@@ -18,15 +18,11 @@ module Shoulda
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def activate
|
21
|
-
doubles_by_method_name.
|
22
|
-
double.activate
|
23
|
-
end
|
21
|
+
doubles_by_method_name.each_value(&:activate)
|
24
22
|
end
|
25
23
|
|
26
24
|
def deactivate
|
27
|
-
doubles_by_method_name.
|
28
|
-
double.deactivate
|
29
|
-
end
|
25
|
+
doubles_by_method_name.each_value(&:deactivate)
|
30
26
|
end
|
31
27
|
|
32
28
|
def calls_by_method_name
|
@@ -39,15 +39,11 @@ module Shoulda
|
|
39
39
|
private
|
40
40
|
|
41
41
|
def activate
|
42
|
-
double_collections_by_class.
|
43
|
-
double_collection.activate
|
44
|
-
end
|
42
|
+
double_collections_by_class.each_value(&:activate)
|
45
43
|
end
|
46
44
|
|
47
45
|
def deactivate
|
48
|
-
double_collections_by_class.
|
49
|
-
double_collection.deactivate
|
50
|
-
end
|
46
|
+
double_collections_by_class.each_value(&:deactivate)
|
51
47
|
end
|
52
48
|
|
53
49
|
def double_collections_by_class
|
@@ -400,7 +400,7 @@ module Shoulda
|
|
400
400
|
false
|
401
401
|
rescue NoMethodError => e
|
402
402
|
if e.message =~
|
403
|
-
/undefined method `#{delegate_method}' for nil
|
403
|
+
/undefined method `#{delegate_method}' for nil/
|
404
404
|
false
|
405
405
|
else
|
406
406
|
raise e
|
@@ -440,22 +440,20 @@ module Shoulda
|
|
440
440
|
end
|
441
441
|
|
442
442
|
def formatted_calls_on_delegate_object
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
443
|
+
String.new.tap do |string|
|
444
|
+
if calls_on_delegate_object.any?
|
445
|
+
string << "\n\n"
|
446
|
+
calls_on_delegate_object.each_with_index do |call, i|
|
447
|
+
name = call.method_name
|
448
|
+
args = call.args.map(&:inspect).join(', ')
|
449
|
+
string << "#{i + 1}) #{name}(#{args})\n"
|
450
|
+
end
|
451
|
+
else
|
452
|
+
string << ' (none)'
|
451
453
|
end
|
452
|
-
else
|
453
|
-
string << ' (none)'
|
454
|
-
end
|
455
454
|
|
456
|
-
|
457
|
-
|
458
|
-
string
|
455
|
+
string.rstrip!
|
456
|
+
end
|
459
457
|
end
|
460
458
|
end
|
461
459
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Shoulda
|
2
2
|
module Matchers
|
3
3
|
# @private
|
4
|
-
module RailsShim
|
4
|
+
module RailsShim
|
5
5
|
class << self
|
6
6
|
def action_pack_version
|
7
7
|
Gem::Version.new(::ActionPack::VERSION::STRING)
|
@@ -9,10 +9,6 @@ module Shoulda
|
|
9
9
|
Gem::Version.new('0')
|
10
10
|
end
|
11
11
|
|
12
|
-
def active_record_gte_6?
|
13
|
-
Gem::Requirement.new('>= 6').satisfied_by?(active_record_version)
|
14
|
-
end
|
15
|
-
|
16
12
|
def active_record_version
|
17
13
|
Gem::Version.new(::ActiveRecord::VERSION::STRING)
|
18
14
|
rescue NameError
|
@@ -60,9 +56,10 @@ module Shoulda
|
|
60
56
|
end
|
61
57
|
|
62
58
|
def serialized_attributes_for(model)
|
59
|
+
type_serialized_defined = Object.const_defined?('ActiveRecord::Type::Serialized')
|
63
60
|
attribute_types_for(model).
|
64
61
|
inject({}) do |hash, (attribute_name, attribute_type)|
|
65
|
-
if attribute_type.is_a?(::ActiveRecord::Type::Serialized)
|
62
|
+
if type_serialized_defined && attribute_type.is_a?(::ActiveRecord::Type::Serialized)
|
66
63
|
hash.merge(attribute_name => attribute_type.coder)
|
67
64
|
else
|
68
65
|
hash
|
@@ -146,6 +143,10 @@ module Shoulda
|
|
146
143
|
model.respond_to?(:attribute_types)
|
147
144
|
end
|
148
145
|
|
146
|
+
def validates_column_options?
|
147
|
+
Gem::Requirement.new('>= 7.1.0').satisfied_by?(active_record_version)
|
148
|
+
end
|
149
|
+
|
149
150
|
private
|
150
151
|
|
151
152
|
def simply_generate_validation_message(
|
@@ -172,6 +173,7 @@ module Shoulda
|
|
172
173
|
I18n.translate(primary_translation_key, translate_options)
|
173
174
|
end
|
174
175
|
|
176
|
+
# @private
|
175
177
|
class FakeAttributeType
|
176
178
|
def initialize(model, attribute_name)
|
177
179
|
@model = model
|
@@ -7,10 +7,9 @@ module Shoulda
|
|
7
7
|
MAXIMUM_LENGTH_OF_VALUE_TO_DISPLAY = 500
|
8
8
|
|
9
9
|
def self.deconstantize(path)
|
10
|
-
if (
|
11
|
-
|
12
|
-
|
13
|
-
)
|
10
|
+
if defined?(ActiveSupport::Inflector) &&
|
11
|
+
ActiveSupport::Inflector.respond_to?(:deconstantize)
|
12
|
+
|
14
13
|
ActiveSupport::Inflector.deconstantize(path)
|
15
14
|
else
|
16
15
|
path.to_s[0...(path.to_s.rindex('::') || 0)]
|
@@ -18,10 +17,9 @@ module Shoulda
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def self.safe_constantize(camel_cased_word)
|
21
|
-
if (
|
22
|
-
|
23
|
-
|
24
|
-
)
|
20
|
+
if defined?(ActiveSupport::Inflector) &&
|
21
|
+
ActiveSupport::Inflector.respond_to?(:safe_constantize)
|
22
|
+
|
25
23
|
ActiveSupport::Inflector.safe_constantize(camel_cased_word)
|
26
24
|
else
|
27
25
|
begin
|
@@ -72,17 +70,17 @@ module Shoulda
|
|
72
70
|
end
|
73
71
|
|
74
72
|
def self.inspect_hash(hash)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
}.join(', ')
|
73
|
+
String.new('‹{').tap do |output|
|
74
|
+
output << hash.map { |key, value|
|
75
|
+
if key.is_a?(Symbol)
|
76
|
+
"#{key}: #{value.inspect}"
|
77
|
+
else
|
78
|
+
"#{key.inspect} => #{value.inspect}"
|
79
|
+
end
|
80
|
+
}.join(', ')
|
84
81
|
|
85
|
-
|
82
|
+
output << '}›'
|
83
|
+
end
|
86
84
|
end
|
87
85
|
|
88
86
|
def self.dummy_value_for(column_type, array: false)
|
@@ -94,7 +92,7 @@ module Shoulda
|
|
94
92
|
0
|
95
93
|
when :date
|
96
94
|
Date.new(2100, 1, 1)
|
97
|
-
when :datetime, :timestamp
|
95
|
+
when :datetime, :timestamp, :timestamptz
|
98
96
|
DateTime.new(2100, 1, 1)
|
99
97
|
when :time
|
100
98
|
Time.new(2000, 1, 1)
|
data/lib/shoulda/matchers.rb
CHANGED
@@ -14,8 +14,8 @@ require 'shoulda/matchers/active_model'
|
|
14
14
|
require 'shoulda/matchers/active_record'
|
15
15
|
require 'shoulda/matchers/routing'
|
16
16
|
|
17
|
-
module Shoulda
|
18
|
-
module Matchers
|
17
|
+
module Shoulda # :nodoc:
|
18
|
+
module Matchers # :nodoc:
|
19
19
|
class << self
|
20
20
|
# @private
|
21
21
|
attr_accessor :assertion_exception_class
|
data/shoulda-matchers.gemspec
CHANGED
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: 6.1.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:
|
17
|
+
date: 2024-01-19 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activesupport
|
@@ -69,12 +69,12 @@ files:
|
|
69
69
|
- lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb
|
70
70
|
- lib/shoulda/matchers/active_model/allow_value_matcher/successful_check.rb
|
71
71
|
- lib/shoulda/matchers/active_model/allow_value_matcher/successful_setting.rb
|
72
|
+
- lib/shoulda/matchers/active_model/comparison_matcher.rb
|
72
73
|
- lib/shoulda/matchers/active_model/disallow_value_matcher.rb
|
73
74
|
- lib/shoulda/matchers/active_model/errors.rb
|
74
75
|
- lib/shoulda/matchers/active_model/have_secure_password_matcher.rb
|
75
76
|
- lib/shoulda/matchers/active_model/helpers.rb
|
76
77
|
- lib/shoulda/matchers/active_model/numericality_matchers.rb
|
77
|
-
- lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb
|
78
78
|
- lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb
|
79
79
|
- lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb
|
80
80
|
- lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb
|
@@ -88,6 +88,7 @@ files:
|
|
88
88
|
- lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb
|
89
89
|
- lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb
|
90
90
|
- lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb
|
91
|
+
- lib/shoulda/matchers/active_model/validate_comparison_of_matcher.rb
|
91
92
|
- lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb
|
92
93
|
- lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb
|
93
94
|
- lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb
|
@@ -115,6 +116,7 @@ files:
|
|
115
116
|
- lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb
|
116
117
|
- lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb
|
117
118
|
- lib/shoulda/matchers/active_record/define_enum_for_matcher.rb
|
119
|
+
- lib/shoulda/matchers/active_record/encrypt_matcher.rb
|
118
120
|
- lib/shoulda/matchers/active_record/have_attached_matcher.rb
|
119
121
|
- lib/shoulda/matchers/active_record/have_db_column_matcher.rb
|
120
122
|
- lib/shoulda/matchers/active_record/have_db_index_matcher.rb
|
@@ -122,6 +124,7 @@ files:
|
|
122
124
|
- lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb
|
123
125
|
- lib/shoulda/matchers/active_record/have_rich_text_matcher.rb
|
124
126
|
- lib/shoulda/matchers/active_record/have_secure_token_matcher.rb
|
127
|
+
- lib/shoulda/matchers/active_record/normalize_matcher.rb
|
125
128
|
- lib/shoulda/matchers/active_record/serialize_matcher.rb
|
126
129
|
- lib/shoulda/matchers/active_record/uniqueness.rb
|
127
130
|
- lib/shoulda/matchers/active_record/uniqueness/model.rb
|
@@ -180,7 +183,7 @@ metadata:
|
|
180
183
|
documentation_uri: https://matchers.shoulda.io/docs
|
181
184
|
homepage_uri: https://matchers.shoulda.io
|
182
185
|
source_code_uri: https://github.com/thoughtbot/shoulda-matchers
|
183
|
-
post_install_message:
|
186
|
+
post_install_message:
|
184
187
|
rdoc_options: []
|
185
188
|
require_paths:
|
186
189
|
- lib
|
@@ -188,15 +191,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
188
191
|
requirements:
|
189
192
|
- - ">="
|
190
193
|
- !ruby/object:Gem::Version
|
191
|
-
version:
|
194
|
+
version: 3.0.5
|
192
195
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
196
|
requirements:
|
194
197
|
- - ">="
|
195
198
|
- !ruby/object:Gem::Version
|
196
199
|
version: '0'
|
197
200
|
requirements: []
|
198
|
-
rubygems_version: 3.3
|
199
|
-
signing_key:
|
201
|
+
rubygems_version: 3.5.3
|
202
|
+
signing_key:
|
200
203
|
specification_version: 4
|
201
204
|
summary: Simple one-liner tests for common Rails functionality
|
202
205
|
test_files: []
|
@@ -1,136 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/module/delegation'
|
2
|
-
|
3
|
-
module Shoulda
|
4
|
-
module Matchers
|
5
|
-
module ActiveModel
|
6
|
-
module NumericalityMatchers
|
7
|
-
# @private
|
8
|
-
class ComparisonMatcher < ValidationMatcher
|
9
|
-
ERROR_MESSAGES = {
|
10
|
-
:> => {
|
11
|
-
label: :greater_than,
|
12
|
-
assertions: [false, false, true],
|
13
|
-
},
|
14
|
-
:>= => {
|
15
|
-
label: :greater_than_or_equal_to,
|
16
|
-
assertions: [false, true, true],
|
17
|
-
},
|
18
|
-
:< => {
|
19
|
-
label: :less_than,
|
20
|
-
assertions: [true, false, false],
|
21
|
-
},
|
22
|
-
:<= => {
|
23
|
-
label: :less_than_or_equal_to,
|
24
|
-
assertions: [true, true, false],
|
25
|
-
},
|
26
|
-
:== => {
|
27
|
-
label: :equal_to,
|
28
|
-
assertions: [false, true, false],
|
29
|
-
},
|
30
|
-
:!= => {
|
31
|
-
label: :other_than,
|
32
|
-
assertions: [true, false, true],
|
33
|
-
},
|
34
|
-
}.freeze
|
35
|
-
|
36
|
-
delegate :failure_message, :failure_message_when_negated, to: :submatchers
|
37
|
-
|
38
|
-
def initialize(numericality_matcher, value, operator)
|
39
|
-
super(nil)
|
40
|
-
unless numericality_matcher.respond_to? :diff_to_compare
|
41
|
-
raise ArgumentError, 'numericality_matcher is invalid'
|
42
|
-
end
|
43
|
-
|
44
|
-
@numericality_matcher = numericality_matcher
|
45
|
-
@value = value
|
46
|
-
@operator = operator
|
47
|
-
@message = ERROR_MESSAGES[operator][:label]
|
48
|
-
end
|
49
|
-
|
50
|
-
def simple_description
|
51
|
-
description = ''
|
52
|
-
|
53
|
-
if expects_strict?
|
54
|
-
description << ' strictly'
|
55
|
-
end
|
56
|
-
|
57
|
-
description +
|
58
|
-
"disallow :#{attribute} from being a number that is not " +
|
59
|
-
"#{comparison_expectation} #{@value}"
|
60
|
-
end
|
61
|
-
|
62
|
-
def for(attribute)
|
63
|
-
@attribute = attribute
|
64
|
-
self
|
65
|
-
end
|
66
|
-
|
67
|
-
def with_message(message)
|
68
|
-
@expects_custom_validation_message = true
|
69
|
-
@message = message
|
70
|
-
self
|
71
|
-
end
|
72
|
-
|
73
|
-
def expects_custom_validation_message?
|
74
|
-
@expects_custom_validation_message
|
75
|
-
end
|
76
|
-
|
77
|
-
def matches?(subject)
|
78
|
-
@subject = subject
|
79
|
-
submatchers.matches?(subject)
|
80
|
-
end
|
81
|
-
|
82
|
-
def comparison_description
|
83
|
-
"#{comparison_expectation} #{@value}"
|
84
|
-
end
|
85
|
-
|
86
|
-
def submatchers
|
87
|
-
@_submatchers ||= NumericalityMatchers::Submatchers.new(build_submatchers)
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
def build_submatchers
|
93
|
-
comparison_combos.map do |diff, submatcher_method_name|
|
94
|
-
matcher = __send__(submatcher_method_name, diff, nil)
|
95
|
-
matcher.with_message(@message, values: { count: @value })
|
96
|
-
matcher
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def comparison_combos
|
101
|
-
diffs_to_compare.zip(submatcher_method_names)
|
102
|
-
end
|
103
|
-
|
104
|
-
def submatcher_method_names
|
105
|
-
assertions.map do |value|
|
106
|
-
if value
|
107
|
-
:allow_value_matcher
|
108
|
-
else
|
109
|
-
:disallow_value_matcher
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def assertions
|
115
|
-
ERROR_MESSAGES[@operator][:assertions]
|
116
|
-
end
|
117
|
-
|
118
|
-
def diffs_to_compare
|
119
|
-
diff_to_compare = @numericality_matcher.diff_to_compare
|
120
|
-
values = [-1, 0, 1].map { |sign| @value + (diff_to_compare * sign) }
|
121
|
-
|
122
|
-
if @numericality_matcher.given_numeric_column?
|
123
|
-
values
|
124
|
-
else
|
125
|
-
values.map(&:to_s)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def comparison_expectation
|
130
|
-
ERROR_MESSAGES[@operator][:label].to_s.tr('_', ' ')
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|