ultra-fast-box 0.0.1
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 +7 -0
- data/shoulda-matchers-8.0.1/LICENSE +22 -0
- data/shoulda-matchers-8.0.1/README.md +567 -0
- data/shoulda-matchers-8.0.1/docs/errors/NonCaseSwappableValueError.md +111 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/callback_matcher.rb +121 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +70 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/flash_store.rb +86 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/permit_matcher.rb +445 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +96 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/render_template_matcher.rb +84 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +145 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +115 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +148 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/route_matcher.rb +207 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/route_params.rb +62 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/session_store.rb +34 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +228 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/set_session_matcher.rb +163 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +107 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller.rb +24 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +45 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb +23 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +232 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +62 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +40 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +48 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/successful_check.rb +14 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/successful_setting.rb +14 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher.rb +695 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/comparison_matcher.rb +157 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +78 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/errors.rb +52 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +125 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/helpers.rb +37 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +45 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +67 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +45 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +44 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/range_matcher.rb +71 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/submatchers.rb +53 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers.rb +9 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/allow_blank.rb +26 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/allow_nil.rb +26 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/ignore_interference_by_writer.rb +101 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +21 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers.rb +14 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +180 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +128 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_comparison_of_matcher.rb +567 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +185 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +272 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +664 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +575 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +711 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +428 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +62 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validation_matcher.rb +195 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validation_message_finder.rb +63 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validator.rb +127 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model.rb +96 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +217 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matcher.rb +2134 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +74 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +62 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +41 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +105 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +101 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +89 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +142 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +71 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +41 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +76 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +42 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +65 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers.rb +9 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +784 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/encrypt_matcher.rb +174 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_attached_matcher.rb +343 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +366 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +287 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +104 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +95 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +83 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +132 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/normalize_matcher.rb +151 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/serialize_matcher.rb +203 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/model.rb +58 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/namespace.rb +39 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +49 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +55 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness.rb +14 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +1197 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record.rb +37 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/configuration.rb +31 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/double.rb +103 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/double_collection.rb +60 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +31 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/method_call.rb +44 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/object_double.rb +43 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/proxy_implementation.rb +32 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/stub_implementation.rb +31 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/world.rb +63 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak.rb +38 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/error.rb +29 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/independent/delegate_method_matcher/target_not_defined_error.rb +15 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/independent/delegate_method_matcher.rb +540 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/independent.rb +11 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/configuration.rb +70 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/configuration_error.rb +9 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/inclusion.rb +20 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/action_controller.rb +33 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/active_model.rb +26 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/active_record.rb +26 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/missing_library.rb +19 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/rails.rb +31 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/routing.rb +29 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries.rb +16 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/rails.rb +12 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/registry.rb +28 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +37 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +36 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +37 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +40 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/rspec.rb +29 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +36 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks.rb +16 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations.rb +43 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/matcher_collection.rb +99 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/matcher_context.rb +36 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/rails_shim.rb +190 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/routing.rb +10 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/util/word_wrap.rb +211 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/util.rb +110 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/version.rb +6 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/warn.rb +28 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers.rb +25 -0
- data/shoulda-matchers-8.0.1/lib/shoulda-matchers.rb +1 -0
- data/shoulda-matchers-8.0.1/shoulda-matchers.gemspec +43 -0
- data/ultra-fast-box.gemspec +12 -0
- metadata +179 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Shoulda
|
|
2
|
+
module Matchers
|
|
3
|
+
module ActiveModel
|
|
4
|
+
# @private
|
|
5
|
+
class ValidationMessageFinder
|
|
6
|
+
include Helpers
|
|
7
|
+
|
|
8
|
+
def initialize(instance, attribute, context = nil)
|
|
9
|
+
@instance = instance
|
|
10
|
+
@attribute = attribute
|
|
11
|
+
@context = context
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def allow_description(allowed_values)
|
|
15
|
+
"allow #{@attribute} to be set to #{allowed_values}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def expected_message_from(attribute_message)
|
|
19
|
+
attribute_message
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def has_messages?
|
|
23
|
+
errors.present?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def source_description
|
|
27
|
+
'errors'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def messages_description
|
|
31
|
+
if errors.empty?
|
|
32
|
+
' no errors'
|
|
33
|
+
else
|
|
34
|
+
" errors:\n#{pretty_error_messages(validated_instance)}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def messages
|
|
39
|
+
Array(messages_for_attribute)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def messages_for_attribute
|
|
45
|
+
errors[@attribute]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def errors
|
|
49
|
+
validated_instance.errors
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def validated_instance
|
|
53
|
+
@_validated_instance ||= validate_instance
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def validate_instance
|
|
57
|
+
@instance.valid?(*@context)
|
|
58
|
+
@instance
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
module Shoulda
|
|
2
|
+
module Matchers
|
|
3
|
+
module ActiveModel
|
|
4
|
+
# @private
|
|
5
|
+
class Validator
|
|
6
|
+
include Helpers
|
|
7
|
+
|
|
8
|
+
def initialize(record, attribute, options = {})
|
|
9
|
+
@record = record
|
|
10
|
+
@attribute = attribute
|
|
11
|
+
@context = options[:context]
|
|
12
|
+
@expects_strict = options[:expects_strict]
|
|
13
|
+
@expected_message = options[:expected_message]
|
|
14
|
+
|
|
15
|
+
@_validation_result = nil
|
|
16
|
+
@captured_validation_exception = false
|
|
17
|
+
@captured_range_error = false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call
|
|
21
|
+
!messages_match? && !captured_range_error?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def has_messages?
|
|
25
|
+
messages.any?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def has_any_errors?
|
|
29
|
+
record.errors.any?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def captured_validation_exception?
|
|
33
|
+
@captured_validation_exception
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def type_of_message_matched?
|
|
37
|
+
expects_strict? == captured_validation_exception?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def all_formatted_validation_error_messages
|
|
41
|
+
format_validation_errors(all_validation_errors)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def validation_exception_message
|
|
45
|
+
validation_result[:validation_exception_message]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def formatted_validation_error_messages
|
|
49
|
+
format_validation_errors(all_validation_errors, attribute)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
protected
|
|
53
|
+
|
|
54
|
+
attr_reader :attribute, :context, :record
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def expects_strict?
|
|
59
|
+
@expects_strict
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def messages_match?
|
|
63
|
+
has_messages? &&
|
|
64
|
+
type_of_message_matched? &&
|
|
65
|
+
matched_messages.compact.any?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def messages
|
|
69
|
+
if expects_strict?
|
|
70
|
+
[validation_exception_message]
|
|
71
|
+
else
|
|
72
|
+
validation_error_messages
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def matched_messages
|
|
77
|
+
if @expected_message
|
|
78
|
+
messages.grep(@expected_message)
|
|
79
|
+
else
|
|
80
|
+
messages
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def captured_range_error?
|
|
85
|
+
!!@captured_range_error
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def all_validation_errors
|
|
89
|
+
validation_result[:all_validation_errors]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def validation_error_messages
|
|
93
|
+
validation_result[:validation_error_messages]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def validation_result
|
|
97
|
+
@_validation_result ||= perform_validation
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def perform_validation
|
|
101
|
+
if context
|
|
102
|
+
record.valid?(context)
|
|
103
|
+
else
|
|
104
|
+
record.valid?
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
all_validation_errors = record.errors.dup
|
|
108
|
+
|
|
109
|
+
validation_error_messages = record.errors[attribute]
|
|
110
|
+
|
|
111
|
+
{
|
|
112
|
+
all_validation_errors:,
|
|
113
|
+
validation_error_messages:,
|
|
114
|
+
validation_exception_message: nil,
|
|
115
|
+
}
|
|
116
|
+
rescue ::ActiveModel::StrictValidationFailed => e
|
|
117
|
+
@captured_validation_exception = true
|
|
118
|
+
{
|
|
119
|
+
all_validation_errors: nil,
|
|
120
|
+
validation_error_messages: [],
|
|
121
|
+
validation_exception_message: e.message,
|
|
122
|
+
}
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require 'shoulda/matchers/active_model/helpers'
|
|
2
|
+
require 'shoulda/matchers/active_model/qualifiers'
|
|
3
|
+
require 'shoulda/matchers/active_model/validation_matcher'
|
|
4
|
+
require 'shoulda/matchers/active_model/validation_matcher/build_description'
|
|
5
|
+
require 'shoulda/matchers/active_model/validator'
|
|
6
|
+
require 'shoulda/matchers/active_model/allow_value_matcher'
|
|
7
|
+
require 'shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error'
|
|
8
|
+
require 'shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error'
|
|
9
|
+
require 'shoulda/matchers/active_model/allow_value_matcher/attribute_setter'
|
|
10
|
+
require 'shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator'
|
|
11
|
+
require 'shoulda/matchers/active_model/allow_value_matcher/attribute_setters'
|
|
12
|
+
require 'shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators'
|
|
13
|
+
require 'shoulda/matchers/active_model/allow_value_matcher/successful_check'
|
|
14
|
+
require 'shoulda/matchers/active_model/allow_value_matcher/successful_setting'
|
|
15
|
+
require 'shoulda/matchers/active_model/disallow_value_matcher'
|
|
16
|
+
require 'shoulda/matchers/active_model/validate_length_of_matcher'
|
|
17
|
+
require 'shoulda/matchers/active_model/validate_inclusion_of_matcher'
|
|
18
|
+
require 'shoulda/matchers/active_model/validate_exclusion_of_matcher'
|
|
19
|
+
require 'shoulda/matchers/active_model/validate_absence_of_matcher'
|
|
20
|
+
require 'shoulda/matchers/active_model/validate_presence_of_matcher'
|
|
21
|
+
require 'shoulda/matchers/active_model/validate_acceptance_of_matcher'
|
|
22
|
+
require 'shoulda/matchers/active_model/validate_confirmation_of_matcher'
|
|
23
|
+
require 'shoulda/matchers/active_model/validate_numericality_of_matcher'
|
|
24
|
+
require 'shoulda/matchers/active_model/validate_comparison_of_matcher'
|
|
25
|
+
require 'shoulda/matchers/active_model/comparison_matcher'
|
|
26
|
+
require 'shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher'
|
|
27
|
+
require 'shoulda/matchers/active_model/numericality_matchers/odd_number_matcher'
|
|
28
|
+
require 'shoulda/matchers/active_model/numericality_matchers/even_number_matcher'
|
|
29
|
+
require 'shoulda/matchers/active_model/numericality_matchers/only_integer_matcher'
|
|
30
|
+
require 'shoulda/matchers/active_model/numericality_matchers/range_matcher'
|
|
31
|
+
require 'shoulda/matchers/active_model/numericality_matchers/submatchers'
|
|
32
|
+
require 'shoulda/matchers/active_model/errors'
|
|
33
|
+
require 'shoulda/matchers/active_model/have_secure_password_matcher'
|
|
34
|
+
|
|
35
|
+
module Shoulda
|
|
36
|
+
module Matchers
|
|
37
|
+
# This module provides matchers that are used to test behavior within
|
|
38
|
+
# ActiveModel or ActiveRecord classes.
|
|
39
|
+
#
|
|
40
|
+
# ### Testing conditional validations
|
|
41
|
+
#
|
|
42
|
+
# If your model defines a validation conditionally -- meaning that the
|
|
43
|
+
# validation is declared with an `:if` or `:unless` option -- how do you
|
|
44
|
+
# test it? You might expect the validation matchers here to have
|
|
45
|
+
# corresponding `if` or `unless` qualifiers, but this isn't what you use.
|
|
46
|
+
# Instead, before using the matcher in question, you place the record
|
|
47
|
+
# you're testing in a state such that the validation you're also testing
|
|
48
|
+
# will be run. A common way to do this is to make a new `context` and
|
|
49
|
+
# override the subject to populate the record accordingly. You'll also want
|
|
50
|
+
# to make sure to test that the validation is *not* run when the
|
|
51
|
+
# conditional fails.
|
|
52
|
+
#
|
|
53
|
+
# Here's an example to illustrate what we mean:
|
|
54
|
+
#
|
|
55
|
+
# class User
|
|
56
|
+
# include ActiveModel::Model
|
|
57
|
+
#
|
|
58
|
+
# attr_accessor :role, :admin
|
|
59
|
+
#
|
|
60
|
+
# validates_presence_of :role, if: :admin
|
|
61
|
+
# end
|
|
62
|
+
#
|
|
63
|
+
# # RSpec
|
|
64
|
+
# RSpec.describe User, type: :model do
|
|
65
|
+
# context "when an admin" do
|
|
66
|
+
# subject { User.new(admin: true) }
|
|
67
|
+
#
|
|
68
|
+
# it { should validate_presence_of(:role) }
|
|
69
|
+
# end
|
|
70
|
+
#
|
|
71
|
+
# context "when not an admin" do
|
|
72
|
+
# subject { User.new(admin: false) }
|
|
73
|
+
#
|
|
74
|
+
# it { should_not validate_presence_of(:role) }
|
|
75
|
+
# end
|
|
76
|
+
# end
|
|
77
|
+
#
|
|
78
|
+
# # Minitest (Shoulda)
|
|
79
|
+
# class UserTest < ActiveSupport::TestCase
|
|
80
|
+
# context "when an admin" do
|
|
81
|
+
# subject { User.new(admin: true) }
|
|
82
|
+
#
|
|
83
|
+
# should validate_presence_of(:role)
|
|
84
|
+
# end
|
|
85
|
+
#
|
|
86
|
+
# context "when not an admin" do
|
|
87
|
+
# subject { User.new(admin: false) }
|
|
88
|
+
#
|
|
89
|
+
# should_not validate_presence_of(:role)
|
|
90
|
+
# end
|
|
91
|
+
# end
|
|
92
|
+
#
|
|
93
|
+
module ActiveModel
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
module Shoulda
|
|
2
|
+
module Matchers
|
|
3
|
+
module ActiveRecord
|
|
4
|
+
# The `accept_nested_attributes_for` matcher tests usage of the
|
|
5
|
+
# `accepts_nested_attributes_for` macro.
|
|
6
|
+
#
|
|
7
|
+
# class Car < ActiveRecord::Base
|
|
8
|
+
# accepts_nested_attributes_for :doors
|
|
9
|
+
# end
|
|
10
|
+
#
|
|
11
|
+
# # RSpec
|
|
12
|
+
# RSpec.describe Car, type: :model do
|
|
13
|
+
# it { should accept_nested_attributes_for(:doors) }
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# # Minitest (Shoulda) (using Shoulda)
|
|
17
|
+
# class CarTest < ActiveSupport::TestCase
|
|
18
|
+
# should accept_nested_attributes_for(:doors)
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# #### Qualifiers
|
|
22
|
+
#
|
|
23
|
+
# ##### allow_destroy
|
|
24
|
+
#
|
|
25
|
+
# Use `allow_destroy` to assert that the `:allow_destroy` option was
|
|
26
|
+
# specified.
|
|
27
|
+
#
|
|
28
|
+
# class Car < ActiveRecord::Base
|
|
29
|
+
# accepts_nested_attributes_for :mirrors, allow_destroy: true
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# # RSpec
|
|
33
|
+
# RSpec.describe Car, type: :model do
|
|
34
|
+
# it do
|
|
35
|
+
# should accept_nested_attributes_for(:mirrors).
|
|
36
|
+
# allow_destroy(true)
|
|
37
|
+
# end
|
|
38
|
+
# end
|
|
39
|
+
#
|
|
40
|
+
# # Minitest (Shoulda)
|
|
41
|
+
# class CarTest < ActiveSupport::TestCase
|
|
42
|
+
# should accept_nested_attributes_for(:mirrors).
|
|
43
|
+
# allow_destroy(true)
|
|
44
|
+
# end
|
|
45
|
+
#
|
|
46
|
+
# ##### limit
|
|
47
|
+
#
|
|
48
|
+
# Use `limit` to assert that the `:limit` option was specified.
|
|
49
|
+
#
|
|
50
|
+
# class Car < ActiveRecord::Base
|
|
51
|
+
# accepts_nested_attributes_for :windows, limit: 3
|
|
52
|
+
# end
|
|
53
|
+
#
|
|
54
|
+
# # RSpec
|
|
55
|
+
# RSpec.describe Car, type: :model do
|
|
56
|
+
# it do
|
|
57
|
+
# should accept_nested_attributes_for(:windows).
|
|
58
|
+
# limit(3)
|
|
59
|
+
# end
|
|
60
|
+
# end
|
|
61
|
+
#
|
|
62
|
+
# # Minitest (Shoulda)
|
|
63
|
+
# class CarTest < ActiveSupport::TestCase
|
|
64
|
+
# should accept_nested_attributes_for(:windows).
|
|
65
|
+
# limit(3)
|
|
66
|
+
# end
|
|
67
|
+
#
|
|
68
|
+
# ##### update_only
|
|
69
|
+
#
|
|
70
|
+
# Use `update_only` to assert that the `:update_only` option was
|
|
71
|
+
# specified.
|
|
72
|
+
#
|
|
73
|
+
# class Car < ActiveRecord::Base
|
|
74
|
+
# accepts_nested_attributes_for :engine, update_only: true
|
|
75
|
+
# end
|
|
76
|
+
#
|
|
77
|
+
# # RSpec
|
|
78
|
+
# RSpec.describe Car, type: :model do
|
|
79
|
+
# it do
|
|
80
|
+
# should accept_nested_attributes_for(:engine).
|
|
81
|
+
# update_only(true)
|
|
82
|
+
# end
|
|
83
|
+
# end
|
|
84
|
+
#
|
|
85
|
+
# # Minitest (Shoulda)
|
|
86
|
+
# class CarTest < ActiveSupport::TestCase
|
|
87
|
+
# should accept_nested_attributes_for(:engine).
|
|
88
|
+
# update_only(true)
|
|
89
|
+
# end
|
|
90
|
+
#
|
|
91
|
+
# @return [AcceptNestedAttributesForMatcher]
|
|
92
|
+
#
|
|
93
|
+
def accept_nested_attributes_for(name)
|
|
94
|
+
AcceptNestedAttributesForMatcher.new(name)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @private
|
|
98
|
+
class AcceptNestedAttributesForMatcher
|
|
99
|
+
def initialize(name)
|
|
100
|
+
@name = name
|
|
101
|
+
@options = {}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def allow_destroy(allow_destroy)
|
|
105
|
+
@options[:allow_destroy] = allow_destroy
|
|
106
|
+
self
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def limit(limit)
|
|
110
|
+
@options[:limit] = limit
|
|
111
|
+
self
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def update_only(update_only)
|
|
115
|
+
@options[:update_only] = update_only
|
|
116
|
+
self
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def matches?(subject)
|
|
120
|
+
@subject = subject
|
|
121
|
+
exists? &&
|
|
122
|
+
allow_destroy_correct? &&
|
|
123
|
+
limit_correct? &&
|
|
124
|
+
update_only_correct?
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def failure_message
|
|
128
|
+
"Expected #{expectation} (#{@problem})"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def failure_message_when_negated
|
|
132
|
+
"Did not expect #{expectation}"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def description
|
|
136
|
+
description = "accepts_nested_attributes_for :#{@name}"
|
|
137
|
+
if @options.key?(:allow_destroy)
|
|
138
|
+
description += " allow_destroy => #{@options[:allow_destroy]}"
|
|
139
|
+
end
|
|
140
|
+
if @options.key?(:limit)
|
|
141
|
+
description += " limit => #{@options[:limit]}"
|
|
142
|
+
end
|
|
143
|
+
if @options.key?(:update_only)
|
|
144
|
+
description += " update_only => #{@options[:update_only]}"
|
|
145
|
+
end
|
|
146
|
+
description
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
protected
|
|
150
|
+
|
|
151
|
+
def exists?
|
|
152
|
+
if config
|
|
153
|
+
true
|
|
154
|
+
else
|
|
155
|
+
@problem = 'is not declared'
|
|
156
|
+
false
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def allow_destroy_correct?
|
|
161
|
+
failure_message = "#{should_or_should_not(@options[:allow_destroy])}"\
|
|
162
|
+
' allow destroy'
|
|
163
|
+
verify_option_is_correct(:allow_destroy, failure_message)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def limit_correct?
|
|
167
|
+
failure_message = "limit should be #{@options[:limit]},"\
|
|
168
|
+
" got #{config[:limit]}"
|
|
169
|
+
verify_option_is_correct(:limit, failure_message)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def update_only_correct?
|
|
173
|
+
failure_message = "#{should_or_should_not(@options[:update_only])}"\
|
|
174
|
+
' be update only'
|
|
175
|
+
verify_option_is_correct(:update_only, failure_message)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def verify_option_is_correct(option, failure_message)
|
|
179
|
+
if @options.key?(option)
|
|
180
|
+
if @options[option] == config[option]
|
|
181
|
+
true
|
|
182
|
+
else
|
|
183
|
+
@problem = failure_message
|
|
184
|
+
false
|
|
185
|
+
end
|
|
186
|
+
else
|
|
187
|
+
true
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def config
|
|
192
|
+
model_config[@name]
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def model_config
|
|
196
|
+
model_class.nested_attributes_options
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def model_class
|
|
200
|
+
@subject.class
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def expectation
|
|
204
|
+
"#{model_class.name} to accept nested attributes for #{@name}"
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def should_or_should_not(value)
|
|
208
|
+
if value
|
|
209
|
+
'should'
|
|
210
|
+
else
|
|
211
|
+
'should not'
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|