activesupport 6.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +572 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +40 -0
- data/lib/active_support.rb +96 -0
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -0
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +132 -0
- data/lib/active_support/benchmarkable.rb +51 -0
- data/lib/active_support/builder.rb +8 -0
- data/lib/active_support/cache.rb +830 -0
- data/lib/active_support/cache/file_store.rb +196 -0
- data/lib/active_support/cache/mem_cache_store.rb +212 -0
- data/lib/active_support/cache/memory_store.rb +174 -0
- data/lib/active_support/cache/null_store.rb +48 -0
- data/lib/active_support/cache/redis_cache_store.rb +488 -0
- data/lib/active_support/cache/strategy/local_cache.rb +194 -0
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/callbacks.rb +856 -0
- data/lib/active_support/concern.rb +171 -0
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
- data/lib/active_support/concurrency/share_lock.rb +227 -0
- data/lib/active_support/configurable.rb +146 -0
- data/lib/active_support/core_ext.rb +5 -0
- data/lib/active_support/core_ext/array.rb +9 -0
- data/lib/active_support/core_ext/array/access.rb +104 -0
- data/lib/active_support/core_ext/array/conversions.rb +213 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +31 -0
- data/lib/active_support/core_ext/array/grouping.rb +109 -0
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -0
- data/lib/active_support/core_ext/array/wrap.rb +48 -0
- data/lib/active_support/core_ext/benchmark.rb +16 -0
- data/lib/active_support/core_ext/big_decimal.rb +3 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
- data/lib/active_support/core_ext/class.rb +4 -0
- data/lib/active_support/core_ext/class/attribute.rb +141 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/class/subclasses.rb +54 -0
- data/lib/active_support/core_ext/date.rb +7 -0
- data/lib/active_support/core_ext/date/acts_like.rb +10 -0
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +146 -0
- data/lib/active_support/core_ext/date/conversions.rb +96 -0
- data/lib/active_support/core_ext/date/zones.rb +8 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +351 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
- data/lib/active_support/core_ext/date_time.rb +7 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +211 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +107 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/digest/uuid.rb +53 -0
- data/lib/active_support/core_ext/enumerable.rb +188 -0
- data/lib/active_support/core_ext/file.rb +3 -0
- data/lib/active_support/core_ext/file/atomic.rb +70 -0
- data/lib/active_support/core_ext/hash.rb +10 -0
- data/lib/active_support/core_ext/hash/compact.rb +5 -0
- data/lib/active_support/core_ext/hash/conversions.rb +263 -0
- data/lib/active_support/core_ext/hash/deep_merge.rb +34 -0
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +24 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +24 -0
- data/lib/active_support/core_ext/hash/keys.rb +143 -0
- data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
- data/lib/active_support/core_ext/hash/slice.rb +26 -0
- data/lib/active_support/core_ext/hash/transform_values.rb +5 -0
- data/lib/active_support/core_ext/integer.rb +5 -0
- data/lib/active_support/core_ext/integer/inflections.rb +31 -0
- data/lib/active_support/core_ext/integer/multiple.rb +12 -0
- data/lib/active_support/core_ext/integer/time.rb +22 -0
- data/lib/active_support/core_ext/kernel.rb +5 -0
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
- data/lib/active_support/core_ext/load_error.rb +9 -0
- data/lib/active_support/core_ext/marshal.rb +24 -0
- data/lib/active_support/core_ext/module.rb +13 -0
- data/lib/active_support/core_ext/module/aliasing.rb +31 -0
- data/lib/active_support/core_ext/module/anonymous.rb +30 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +38 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
- data/lib/active_support/core_ext/module/concerning.rb +134 -0
- data/lib/active_support/core_ext/module/delegation.rb +313 -0
- data/lib/active_support/core_ext/module/deprecation.rb +25 -0
- data/lib/active_support/core_ext/module/introspection.rb +86 -0
- data/lib/active_support/core_ext/module/reachable.rb +6 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +17 -0
- data/lib/active_support/core_ext/name_error.rb +38 -0
- data/lib/active_support/core_ext/numeric.rb +5 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +66 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +136 -0
- data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
- data/lib/active_support/core_ext/numeric/time.rb +66 -0
- data/lib/active_support/core_ext/object.rb +16 -0
- data/lib/active_support/core_ext/object/acts_like.rb +21 -0
- data/lib/active_support/core_ext/object/blank.rb +155 -0
- data/lib/active_support/core_ext/object/conversions.rb +6 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +55 -0
- data/lib/active_support/core_ext/object/duplicable.rb +49 -0
- data/lib/active_support/core_ext/object/inclusion.rb +29 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +30 -0
- data/lib/active_support/core_ext/object/json.rb +228 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -0
- data/lib/active_support/core_ext/object/to_query.rb +89 -0
- data/lib/active_support/core_ext/object/try.rb +156 -0
- data/lib/active_support/core_ext/object/with_options.rb +82 -0
- data/lib/active_support/core_ext/range.rb +7 -0
- data/lib/active_support/core_ext/range/compare_range.rb +70 -0
- data/lib/active_support/core_ext/range/conversions.rb +41 -0
- data/lib/active_support/core_ext/range/each.rb +25 -0
- data/lib/active_support/core_ext/range/include_range.rb +9 -0
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +10 -0
- data/lib/active_support/core_ext/regexp.rb +7 -0
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string.rb +15 -0
- data/lib/active_support/core_ext/string/access.rb +114 -0
- data/lib/active_support/core_ext/string/behavior.rb +8 -0
- data/lib/active_support/core_ext/string/conversions.rb +59 -0
- data/lib/active_support/core_ext/string/exclude.rb +13 -0
- data/lib/active_support/core_ext/string/filters.rb +145 -0
- data/lib/active_support/core_ext/string/indent.rb +45 -0
- data/lib/active_support/core_ext/string/inflections.rb +259 -0
- data/lib/active_support/core_ext/string/inquiry.rb +15 -0
- data/lib/active_support/core_ext/string/multibyte.rb +58 -0
- data/lib/active_support/core_ext/string/output_safety.rb +314 -0
- data/lib/active_support/core_ext/string/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/string/strip.rb +27 -0
- data/lib/active_support/core_ext/string/zones.rb +16 -0
- data/lib/active_support/core_ext/time.rb +7 -0
- data/lib/active_support/core_ext/time/acts_like.rb +10 -0
- data/lib/active_support/core_ext/time/calculations.rb +344 -0
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +72 -0
- data/lib/active_support/core_ext/time/zones.rb +113 -0
- data/lib/active_support/core_ext/uri.rb +25 -0
- data/lib/active_support/current_attributes.rb +203 -0
- data/lib/active_support/dependencies.rb +806 -0
- data/lib/active_support/dependencies/autoload.rb +79 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
- data/lib/active_support/deprecation.rb +46 -0
- data/lib/active_support/deprecation/behaviors.rb +109 -0
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +39 -0
- data/lib/active_support/deprecation/method_wrappers.rb +78 -0
- data/lib/active_support/deprecation/proxy_wrappers.rb +173 -0
- data/lib/active_support/deprecation/reporting.rb +114 -0
- data/lib/active_support/descendants_tracker.rb +109 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration.rb +433 -0
- data/lib/active_support/duration/iso8601_parser.rb +124 -0
- data/lib/active_support/duration/iso8601_serializer.rb +54 -0
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +100 -0
- data/lib/active_support/evented_file_update_checker.rb +235 -0
- data/lib/active_support/execution_wrapper.rb +129 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +163 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +38 -0
- data/lib/active_support/hash_with_indifferent_access.rb +399 -0
- data/lib/active_support/i18n.rb +16 -0
- data/lib/active_support/i18n_railtie.rb +126 -0
- data/lib/active_support/inflections.rb +72 -0
- data/lib/active_support/inflector.rb +9 -0
- data/lib/active_support/inflector/inflections.rb +257 -0
- data/lib/active_support/inflector/methods.rb +398 -0
- data/lib/active_support/inflector/transliterate.rb +147 -0
- data/lib/active_support/json.rb +4 -0
- data/lib/active_support/json/decoding.rb +76 -0
- data/lib/active_support/json/encoding.rb +134 -0
- data/lib/active_support/key_generator.rb +41 -0
- data/lib/active_support/lazy_load_hooks.rb +82 -0
- data/lib/active_support/locale/en.rb +31 -0
- data/lib/active_support/locale/en.yml +135 -0
- data/lib/active_support/log_subscriber.rb +135 -0
- data/lib/active_support/log_subscriber/test_helper.rb +106 -0
- data/lib/active_support/logger.rb +93 -0
- data/lib/active_support/logger_silence.rb +45 -0
- data/lib/active_support/logger_thread_safe_level.rb +56 -0
- data/lib/active_support/message_encryptor.rb +227 -0
- data/lib/active_support/message_verifier.rb +205 -0
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte.rb +23 -0
- data/lib/active_support/multibyte/chars.rb +216 -0
- data/lib/active_support/multibyte/unicode.rb +157 -0
- data/lib/active_support/notifications.rb +253 -0
- data/lib/active_support/notifications/fanout.rb +244 -0
- data/lib/active_support/notifications/instrumenter.rb +164 -0
- data/lib/active_support/number_helper.rb +378 -0
- data/lib/active_support/number_helper/number_converter.rb +184 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +31 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +70 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +61 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +56 -0
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/option_merger.rb +27 -0
- data/lib/active_support/ordered_hash.rb +50 -0
- data/lib/active_support/ordered_options.rb +85 -0
- data/lib/active_support/parameter_filter.rb +129 -0
- data/lib/active_support/per_thread_registry.rb +60 -0
- data/lib/active_support/proxy_object.rb +15 -0
- data/lib/active_support/rails.rb +29 -0
- data/lib/active_support/railtie.rb +80 -0
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +174 -0
- data/lib/active_support/security_utils.rb +31 -0
- data/lib/active_support/string_inquirer.rb +34 -0
- data/lib/active_support/subscriber.rb +169 -0
- data/lib/active_support/tagged_logging.rb +88 -0
- data/lib/active_support/test_case.rb +163 -0
- data/lib/active_support/testing/assertions.rb +228 -0
- data/lib/active_support/testing/autorun.rb +7 -0
- data/lib/active_support/testing/constant_lookup.rb +51 -0
- data/lib/active_support/testing/declarative.rb +28 -0
- data/lib/active_support/testing/deprecation.rb +38 -0
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +110 -0
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization.rb +128 -0
- data/lib/active_support/testing/setup_and_teardown.rb +55 -0
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +27 -0
- data/lib/active_support/testing/time_helpers.rb +200 -0
- data/lib/active_support/time.rb +20 -0
- data/lib/active_support/time_with_zone.rb +561 -0
- data/lib/active_support/values/time_zone.rb +570 -0
- data/lib/active_support/version.rb +10 -0
- data/lib/active_support/xml_mini.rb +202 -0
- data/lib/active_support/xml_mini/jdom.rb +183 -0
- data/lib/active_support/xml_mini/libxml.rb +80 -0
- data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
- data/lib/active_support/xml_mini/nokogiri.rb +83 -0
- data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
- data/lib/active_support/xml_mini/rexml.rb +130 -0
- metadata +385 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport
|
|
4
|
+
module Testing
|
|
5
|
+
module Assertions
|
|
6
|
+
UNTRACKED = Object.new # :nodoc:
|
|
7
|
+
|
|
8
|
+
# Asserts that an expression is not truthy. Passes if <tt>object</tt> is
|
|
9
|
+
# +nil+ or +false+. "Truthy" means "considered true in a conditional"
|
|
10
|
+
# like <tt>if foo</tt>.
|
|
11
|
+
#
|
|
12
|
+
# assert_not nil # => true
|
|
13
|
+
# assert_not false # => true
|
|
14
|
+
# assert_not 'foo' # => Expected "foo" to be nil or false
|
|
15
|
+
#
|
|
16
|
+
# An error message can be specified.
|
|
17
|
+
#
|
|
18
|
+
# assert_not foo, 'foo should be false'
|
|
19
|
+
def assert_not(object, message = nil)
|
|
20
|
+
message ||= "Expected #{mu_pp(object)} to be nil or false"
|
|
21
|
+
assert !object, message
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Assertion that the block should not raise an exception.
|
|
25
|
+
#
|
|
26
|
+
# Passes if evaluated code in the yielded block raises no exception.
|
|
27
|
+
#
|
|
28
|
+
# assert_nothing_raised do
|
|
29
|
+
# perform_service(param: 'no_exception')
|
|
30
|
+
# end
|
|
31
|
+
def assert_nothing_raised
|
|
32
|
+
yield
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Test numeric difference between the return value of an expression as a
|
|
36
|
+
# result of what is evaluated in the yielded block.
|
|
37
|
+
#
|
|
38
|
+
# assert_difference 'Article.count' do
|
|
39
|
+
# post :create, params: { article: {...} }
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# An arbitrary expression is passed in and evaluated.
|
|
43
|
+
#
|
|
44
|
+
# assert_difference 'Article.last.comments(:reload).size' do
|
|
45
|
+
# post :create, params: { comment: {...} }
|
|
46
|
+
# end
|
|
47
|
+
#
|
|
48
|
+
# An arbitrary positive or negative difference can be specified.
|
|
49
|
+
# The default is <tt>1</tt>.
|
|
50
|
+
#
|
|
51
|
+
# assert_difference 'Article.count', -1 do
|
|
52
|
+
# post :delete, params: { id: ... }
|
|
53
|
+
# end
|
|
54
|
+
#
|
|
55
|
+
# An array of expressions can also be passed in and evaluated.
|
|
56
|
+
#
|
|
57
|
+
# assert_difference [ 'Article.count', 'Post.count' ], 2 do
|
|
58
|
+
# post :create, params: { article: {...} }
|
|
59
|
+
# end
|
|
60
|
+
#
|
|
61
|
+
# A hash of expressions/numeric differences can also be passed in and evaluated.
|
|
62
|
+
#
|
|
63
|
+
# assert_difference ->{ Article.count } => 1, ->{ Notification.count } => 2 do
|
|
64
|
+
# post :create, params: { article: {...} }
|
|
65
|
+
# end
|
|
66
|
+
#
|
|
67
|
+
# A lambda or a list of lambdas can be passed in and evaluated:
|
|
68
|
+
#
|
|
69
|
+
# assert_difference ->{ Article.count }, 2 do
|
|
70
|
+
# post :create, params: { article: {...} }
|
|
71
|
+
# end
|
|
72
|
+
#
|
|
73
|
+
# assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
|
|
74
|
+
# post :create, params: { article: {...} }
|
|
75
|
+
# end
|
|
76
|
+
#
|
|
77
|
+
# An error message can be specified.
|
|
78
|
+
#
|
|
79
|
+
# assert_difference 'Article.count', -1, 'An Article should be destroyed' do
|
|
80
|
+
# post :delete, params: { id: ... }
|
|
81
|
+
# end
|
|
82
|
+
def assert_difference(expression, *args, &block)
|
|
83
|
+
expressions =
|
|
84
|
+
if expression.is_a?(Hash)
|
|
85
|
+
message = args[0]
|
|
86
|
+
expression
|
|
87
|
+
else
|
|
88
|
+
difference = args[0] || 1
|
|
89
|
+
message = args[1]
|
|
90
|
+
Hash[Array(expression).map { |e| [e, difference] }]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
exps = expressions.keys.map { |e|
|
|
94
|
+
e.respond_to?(:call) ? e : lambda { eval(e, block.binding) }
|
|
95
|
+
}
|
|
96
|
+
before = exps.map(&:call)
|
|
97
|
+
|
|
98
|
+
retval = yield
|
|
99
|
+
|
|
100
|
+
expressions.zip(exps, before) do |(code, diff), exp, before_value|
|
|
101
|
+
error = "#{code.inspect} didn't change by #{diff}"
|
|
102
|
+
error = "#{message}.\n#{error}" if message
|
|
103
|
+
assert_equal(before_value + diff, exp.call, error)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
retval
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Assertion that the numeric result of evaluating an expression is not
|
|
110
|
+
# changed before and after invoking the passed in block.
|
|
111
|
+
#
|
|
112
|
+
# assert_no_difference 'Article.count' do
|
|
113
|
+
# post :create, params: { article: invalid_attributes }
|
|
114
|
+
# end
|
|
115
|
+
#
|
|
116
|
+
# A lambda can be passed in and evaluated.
|
|
117
|
+
#
|
|
118
|
+
# assert_no_difference -> { Article.count } do
|
|
119
|
+
# post :create, params: { article: invalid_attributes }
|
|
120
|
+
# end
|
|
121
|
+
#
|
|
122
|
+
# An error message can be specified.
|
|
123
|
+
#
|
|
124
|
+
# assert_no_difference 'Article.count', 'An Article should not be created' do
|
|
125
|
+
# post :create, params: { article: invalid_attributes }
|
|
126
|
+
# end
|
|
127
|
+
#
|
|
128
|
+
# An array of expressions can also be passed in and evaluated.
|
|
129
|
+
#
|
|
130
|
+
# assert_no_difference [ 'Article.count', -> { Post.count } ] do
|
|
131
|
+
# post :create, params: { article: invalid_attributes }
|
|
132
|
+
# end
|
|
133
|
+
def assert_no_difference(expression, message = nil, &block)
|
|
134
|
+
assert_difference expression, 0, message, &block
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Assertion that the result of evaluating an expression is changed before
|
|
138
|
+
# and after invoking the passed in block.
|
|
139
|
+
#
|
|
140
|
+
# assert_changes 'Status.all_good?' do
|
|
141
|
+
# post :create, params: { status: { ok: false } }
|
|
142
|
+
# end
|
|
143
|
+
#
|
|
144
|
+
# You can pass the block as a string to be evaluated in the context of
|
|
145
|
+
# the block. A lambda can be passed for the block as well.
|
|
146
|
+
#
|
|
147
|
+
# assert_changes -> { Status.all_good? } do
|
|
148
|
+
# post :create, params: { status: { ok: false } }
|
|
149
|
+
# end
|
|
150
|
+
#
|
|
151
|
+
# The assertion is useful to test side effects. The passed block can be
|
|
152
|
+
# anything that can be converted to string with #to_s.
|
|
153
|
+
#
|
|
154
|
+
# assert_changes :@object do
|
|
155
|
+
# @object = 42
|
|
156
|
+
# end
|
|
157
|
+
#
|
|
158
|
+
# The keyword arguments :from and :to can be given to specify the
|
|
159
|
+
# expected initial value and the expected value after the block was
|
|
160
|
+
# executed.
|
|
161
|
+
#
|
|
162
|
+
# assert_changes :@object, from: nil, to: :foo do
|
|
163
|
+
# @object = :foo
|
|
164
|
+
# end
|
|
165
|
+
#
|
|
166
|
+
# An error message can be specified.
|
|
167
|
+
#
|
|
168
|
+
# assert_changes -> { Status.all_good? }, 'Expected the status to be bad' do
|
|
169
|
+
# post :create, params: { status: { incident: true } }
|
|
170
|
+
# end
|
|
171
|
+
def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block)
|
|
172
|
+
exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
|
|
173
|
+
|
|
174
|
+
before = exp.call
|
|
175
|
+
retval = yield
|
|
176
|
+
|
|
177
|
+
unless from == UNTRACKED
|
|
178
|
+
error = "#{expression.inspect} isn't #{from.inspect}"
|
|
179
|
+
error = "#{message}.\n#{error}" if message
|
|
180
|
+
assert from === before, error
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
after = exp.call
|
|
184
|
+
|
|
185
|
+
error = "#{expression.inspect} didn't change"
|
|
186
|
+
error = "#{error}. It was already #{to}" if before == to
|
|
187
|
+
error = "#{message}.\n#{error}" if message
|
|
188
|
+
assert before != after, error
|
|
189
|
+
|
|
190
|
+
unless to == UNTRACKED
|
|
191
|
+
error = "#{expression.inspect} didn't change to as expected\n"
|
|
192
|
+
error = "#{error}Expected: #{to.inspect}\n"
|
|
193
|
+
error = "#{error} Actual: #{after.inspect}"
|
|
194
|
+
error = "#{message}.\n#{error}" if message
|
|
195
|
+
assert to === after, error
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
retval
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Assertion that the result of evaluating an expression is not changed before
|
|
202
|
+
# and after invoking the passed in block.
|
|
203
|
+
#
|
|
204
|
+
# assert_no_changes 'Status.all_good?' do
|
|
205
|
+
# post :create, params: { status: { ok: true } }
|
|
206
|
+
# end
|
|
207
|
+
#
|
|
208
|
+
# An error message can be specified.
|
|
209
|
+
#
|
|
210
|
+
# assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do
|
|
211
|
+
# post :create, params: { status: { ok: false } }
|
|
212
|
+
# end
|
|
213
|
+
def assert_no_changes(expression, message = nil, &block)
|
|
214
|
+
exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
|
|
215
|
+
|
|
216
|
+
before = exp.call
|
|
217
|
+
retval = yield
|
|
218
|
+
after = exp.call
|
|
219
|
+
|
|
220
|
+
error = "#{expression.inspect} did change to #{after}"
|
|
221
|
+
error = "#{message}.\n#{error}" if message
|
|
222
|
+
assert before == after, error
|
|
223
|
+
|
|
224
|
+
retval
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/concern"
|
|
4
|
+
require "active_support/inflector"
|
|
5
|
+
|
|
6
|
+
module ActiveSupport
|
|
7
|
+
module Testing
|
|
8
|
+
# Resolves a constant from a minitest spec name.
|
|
9
|
+
#
|
|
10
|
+
# Given the following spec-style test:
|
|
11
|
+
#
|
|
12
|
+
# describe WidgetsController, :index do
|
|
13
|
+
# describe "authenticated user" do
|
|
14
|
+
# describe "returns widgets" do
|
|
15
|
+
# it "has a controller that exists" do
|
|
16
|
+
# assert_kind_of WidgetsController, @controller
|
|
17
|
+
# end
|
|
18
|
+
# end
|
|
19
|
+
# end
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# The test will have the following name:
|
|
23
|
+
#
|
|
24
|
+
# "WidgetsController::index::authenticated user::returns widgets"
|
|
25
|
+
#
|
|
26
|
+
# The constant WidgetsController can be resolved from the name.
|
|
27
|
+
# The following code will resolve the constant:
|
|
28
|
+
#
|
|
29
|
+
# controller = determine_constant_from_test_name(name) do |constant|
|
|
30
|
+
# Class === constant && constant < ::ActionController::Metal
|
|
31
|
+
# end
|
|
32
|
+
module ConstantLookup
|
|
33
|
+
extend ::ActiveSupport::Concern
|
|
34
|
+
|
|
35
|
+
module ClassMethods # :nodoc:
|
|
36
|
+
def determine_constant_from_test_name(test_name)
|
|
37
|
+
names = test_name.split "::"
|
|
38
|
+
while names.size > 0 do
|
|
39
|
+
names.last.sub!(/Test$/, "")
|
|
40
|
+
begin
|
|
41
|
+
constant = names.join("::").safe_constantize
|
|
42
|
+
break(constant) if yield(constant)
|
|
43
|
+
ensure
|
|
44
|
+
names.pop
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport
|
|
4
|
+
module Testing
|
|
5
|
+
module Declarative
|
|
6
|
+
unless defined?(Spec)
|
|
7
|
+
# Helper to define a test method using a String. Under the hood, it replaces
|
|
8
|
+
# spaces with underscores and defines the test method.
|
|
9
|
+
#
|
|
10
|
+
# test "verify something" do
|
|
11
|
+
# ...
|
|
12
|
+
# end
|
|
13
|
+
def test(name, &block)
|
|
14
|
+
test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym
|
|
15
|
+
defined = method_defined? test_name
|
|
16
|
+
raise "#{test_name} is already defined in #{self}" if defined
|
|
17
|
+
if block_given?
|
|
18
|
+
define_method(test_name, &block)
|
|
19
|
+
else
|
|
20
|
+
define_method(test_name) do
|
|
21
|
+
flunk "No implementation provided for #{name}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/deprecation"
|
|
4
|
+
|
|
5
|
+
module ActiveSupport
|
|
6
|
+
module Testing
|
|
7
|
+
module Deprecation #:nodoc:
|
|
8
|
+
def assert_deprecated(match = nil, deprecator = nil, &block)
|
|
9
|
+
result, warnings = collect_deprecations(deprecator, &block)
|
|
10
|
+
assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
|
|
11
|
+
if match
|
|
12
|
+
match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
|
|
13
|
+
assert warnings.any? { |w| match.match?(w) }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
|
|
14
|
+
end
|
|
15
|
+
result
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def assert_not_deprecated(deprecator = nil, &block)
|
|
19
|
+
result, deprecations = collect_deprecations(deprecator, &block)
|
|
20
|
+
assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
|
|
21
|
+
result
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def collect_deprecations(deprecator = nil)
|
|
25
|
+
deprecator ||= ActiveSupport::Deprecation
|
|
26
|
+
old_behavior = deprecator.behavior
|
|
27
|
+
deprecations = []
|
|
28
|
+
deprecator.behavior = Proc.new do |message, callstack|
|
|
29
|
+
deprecations << message
|
|
30
|
+
end
|
|
31
|
+
result = yield
|
|
32
|
+
[result, deprecations]
|
|
33
|
+
ensure
|
|
34
|
+
deprecator.behavior = old_behavior
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/concern"
|
|
4
|
+
|
|
5
|
+
module ActiveSupport
|
|
6
|
+
module Testing
|
|
7
|
+
# Adds simple access to sample files called file fixtures.
|
|
8
|
+
# File fixtures are normal files stored in
|
|
9
|
+
# <tt>ActiveSupport::TestCase.file_fixture_path</tt>.
|
|
10
|
+
#
|
|
11
|
+
# File fixtures are represented as +Pathname+ objects.
|
|
12
|
+
# This makes it easy to extract specific information:
|
|
13
|
+
#
|
|
14
|
+
# file_fixture("example.txt").read # get the file's content
|
|
15
|
+
# file_fixture("example.mp3").size # get the file size
|
|
16
|
+
module FileFixtures
|
|
17
|
+
extend ActiveSupport::Concern
|
|
18
|
+
|
|
19
|
+
included do
|
|
20
|
+
class_attribute :file_fixture_path, instance_writer: false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Returns a +Pathname+ to the fixture file named +fixture_name+.
|
|
24
|
+
#
|
|
25
|
+
# Raises +ArgumentError+ if +fixture_name+ can't be found.
|
|
26
|
+
def file_fixture(fixture_name)
|
|
27
|
+
path = Pathname.new(File.join(file_fixture_path, fixture_name))
|
|
28
|
+
|
|
29
|
+
if path.exist?
|
|
30
|
+
path
|
|
31
|
+
else
|
|
32
|
+
msg = "the directory '%s' does not contain a file named '%s'"
|
|
33
|
+
raise ArgumentError, msg % [file_fixture_path, fixture_name]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport
|
|
4
|
+
module Testing
|
|
5
|
+
module Isolation
|
|
6
|
+
require "thread"
|
|
7
|
+
|
|
8
|
+
def self.included(klass) #:nodoc:
|
|
9
|
+
klass.class_eval do
|
|
10
|
+
parallelize_me!
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.forking_env?
|
|
15
|
+
!ENV["NO_FORK"] && Process.respond_to?(:fork)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run
|
|
19
|
+
serialized = run_in_isolation do
|
|
20
|
+
super
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Marshal.load(serialized)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Forking
|
|
27
|
+
def run_in_isolation(&blk)
|
|
28
|
+
read, write = IO.pipe
|
|
29
|
+
read.binmode
|
|
30
|
+
write.binmode
|
|
31
|
+
|
|
32
|
+
pid = fork do
|
|
33
|
+
read.close
|
|
34
|
+
yield
|
|
35
|
+
begin
|
|
36
|
+
if error?
|
|
37
|
+
failures.map! { |e|
|
|
38
|
+
begin
|
|
39
|
+
Marshal.dump e
|
|
40
|
+
e
|
|
41
|
+
rescue TypeError
|
|
42
|
+
ex = Exception.new e.message
|
|
43
|
+
ex.set_backtrace e.backtrace
|
|
44
|
+
Minitest::UnexpectedError.new ex
|
|
45
|
+
end
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
|
|
49
|
+
result = Marshal.dump(test_result)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
write.puts [result].pack("m")
|
|
53
|
+
exit!
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
write.close
|
|
57
|
+
result = read.read
|
|
58
|
+
Process.wait2(pid)
|
|
59
|
+
result.unpack1("m")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
module Subprocess
|
|
64
|
+
ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV)
|
|
65
|
+
|
|
66
|
+
# Crazy H4X to get this working in windows / jruby with
|
|
67
|
+
# no forking.
|
|
68
|
+
def run_in_isolation(&blk)
|
|
69
|
+
require "tempfile"
|
|
70
|
+
|
|
71
|
+
if ENV["ISOLATION_TEST"]
|
|
72
|
+
yield
|
|
73
|
+
test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
|
|
74
|
+
File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
|
|
75
|
+
file.puts [Marshal.dump(test_result)].pack("m")
|
|
76
|
+
end
|
|
77
|
+
exit!
|
|
78
|
+
else
|
|
79
|
+
Tempfile.open("isolation") do |tmpfile|
|
|
80
|
+
env = {
|
|
81
|
+
"ISOLATION_TEST" => self.class.name,
|
|
82
|
+
"ISOLATION_OUTPUT" => tmpfile.path
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
test_opts = "-n#{self.class.name}##{name}"
|
|
86
|
+
|
|
87
|
+
load_path_args = []
|
|
88
|
+
$-I.each do |p|
|
|
89
|
+
load_path_args << "-I"
|
|
90
|
+
load_path_args << File.expand_path(p)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
child = IO.popen([env, Gem.ruby, *load_path_args, $0, *ORIG_ARGV, test_opts])
|
|
94
|
+
|
|
95
|
+
begin
|
|
96
|
+
Process.wait(child.pid)
|
|
97
|
+
rescue Errno::ECHILD # The child process may exit before we wait
|
|
98
|
+
nil
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
return tmpfile.read.unpack1("m")
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
include forking_env? ? Forking : Subprocess
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|