activesupport 4.2.0 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +366 -232
- data/MIT-LICENSE +2 -2
- data/README.rdoc +4 -5
- data/lib/active_support.rb +17 -7
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +7 -5
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache.rb +271 -177
- data/lib/active_support/cache/file_store.rb +41 -35
- data/lib/active_support/cache/mem_cache_store.rb +97 -88
- data/lib/active_support/cache/memory_store.rb +27 -30
- data/lib/active_support/cache/null_store.rb +7 -8
- data/lib/active_support/cache/redis_cache_store.rb +454 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -34
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/callbacks.rb +654 -560
- data/lib/active_support/concern.rb +5 -3
- 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 +8 -5
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/array/access.rb +29 -1
- data/lib/active_support/core_ext/array/conversions.rb +22 -18
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/class/attribute.rb +41 -22
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -8
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +11 -9
- data/lib/active_support/core_ext/date/conversions.rb +31 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +179 -56
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
- data/lib/active_support/core_ext/date_time.rb +7 -4
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +58 -20
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/enumerable.rb +107 -28
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/hash.rb +11 -9
- data/lib/active_support/core_ext/hash/compact.rb +24 -15
- data/lib/active_support/core_ext/hash/conversions.rb +63 -43
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/except.rb +11 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +33 -27
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -8
- data/lib/active_support/core_ext/hash/transform_values.rb +16 -7
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +11 -33
- data/lib/active_support/core_ext/kernel.rb +6 -5
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -83
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +13 -10
- data/lib/active_support/core_ext/module.rb +14 -11
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +121 -39
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +9 -9
- data/lib/active_support/core_ext/module/reachable.rb +5 -2
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -38
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +29 -4
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +98 -45
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +49 -19
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +6 -4
- data/lib/active_support/core_ext/object/try.rb +70 -22
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/range/conversions.rb +27 -7
- data/lib/active_support/core_ext/range/each.rb +19 -17
- data/lib/active_support/core_ext/range/include_range.rb +21 -19
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/regexp.rb +6 -0
- data/lib/active_support/core_ext/securerandom.rb +25 -0
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/string/access.rb +9 -7
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +8 -5
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +10 -8
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +61 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +15 -7
- data/lib/active_support/core_ext/string/output_safety.rb +35 -35
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +4 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/time.rb +7 -5
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +101 -51
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/uri.rb +5 -4
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies.rb +143 -160
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/deprecation/behaviors.rb +41 -12
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +54 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration.rb +326 -30
- data/lib/active_support/duration/iso8601_parser.rb +125 -0
- data/lib/active_support/duration/iso8601_serializer.rb +55 -0
- data/lib/active_support/encrypted_configuration.rb +49 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +205 -0
- data/lib/active_support/execution_wrapper.rb +128 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +63 -37
- data/lib/active_support/gem_version.rb +4 -2
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +130 -30
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +34 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/inflector/inflections.rb +61 -12
- data/lib/active_support/inflector/methods.rb +161 -136
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/json/decoding.rb +16 -13
- data/lib/active_support/json/encoding.rb +15 -57
- data/lib/active_support/key_generator.rb +25 -25
- data/lib/active_support/lazy_load_hooks.rb +50 -20
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber.rb +13 -10
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/logger.rb +54 -3
- data/lib/active_support/logger_silence.rb +12 -7
- data/lib/active_support/logger_thread_safe_level.rb +33 -0
- data/lib/active_support/message_encryptor.rb +173 -51
- data/lib/active_support/message_verifier.rb +150 -17
- 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 +4 -2
- data/lib/active_support/multibyte/chars.rb +37 -24
- data/lib/active_support/multibyte/unicode.rb +100 -96
- data/lib/active_support/notifications.rb +11 -7
- data/lib/active_support/notifications/fanout.rb +10 -8
- data/lib/active_support/notifications/instrumenter.rb +27 -7
- data/lib/active_support/number_helper.rb +94 -68
- data/lib/active_support/number_helper/number_converter.rb +13 -11
- data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/option_merger.rb +3 -1
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +22 -4
- data/lib/active_support/per_thread_registry.rb +13 -6
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +16 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +131 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +17 -6
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +15 -14
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +18 -46
- data/lib/active_support/testing/assertions.rb +137 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +14 -10
- data/lib/active_support/testing/file_fixtures.rb +36 -0
- data/lib/active_support/testing/isolation.rb +34 -25
- data/lib/active_support/testing/method_call_assertions.rb +43 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -3
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +96 -27
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +195 -53
- data/lib/active_support/values/time_zone.rb +200 -61
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini.rb +69 -51
- data/lib/active_support/xml_mini/jdom.rb +116 -113
- data/lib/active_support/xml_mini/libxml.rb +17 -16
- data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
- data/lib/active_support/xml_mini/nokogiri.rb +15 -15
- data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
- data/lib/active_support/xml_mini/rexml.rb +17 -16
- metadata +55 -43
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -14
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -11
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module Testing
|
3
5
|
module Declarative
|
@@ -9,7 +11,7 @@ module ActiveSupport
|
|
9
11
|
# ...
|
10
12
|
# end
|
11
13
|
def test(name, &block)
|
12
|
-
test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
|
14
|
+
test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym
|
13
15
|
defined = method_defined? test_name
|
14
16
|
raise "#{test_name} is already defined in #{self}" if defined
|
15
17
|
if block_given?
|
@@ -1,34 +1,38 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/deprecation"
|
4
|
+
require "active_support/core_ext/regexp"
|
2
5
|
|
3
6
|
module ActiveSupport
|
4
7
|
module Testing
|
5
8
|
module Deprecation #:nodoc:
|
6
|
-
def assert_deprecated(match = nil, &block)
|
7
|
-
result, warnings = collect_deprecations(&block)
|
9
|
+
def assert_deprecated(match = nil, deprecator = nil, &block)
|
10
|
+
result, warnings = collect_deprecations(deprecator, &block)
|
8
11
|
assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
|
9
12
|
if match
|
10
13
|
match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
|
11
|
-
assert warnings.any? { |w| w
|
14
|
+
assert warnings.any? { |w| match.match?(w) }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
|
12
15
|
end
|
13
16
|
result
|
14
17
|
end
|
15
18
|
|
16
|
-
def assert_not_deprecated(&block)
|
17
|
-
result, deprecations = collect_deprecations(&block)
|
19
|
+
def assert_not_deprecated(deprecator = nil, &block)
|
20
|
+
result, deprecations = collect_deprecations(deprecator, &block)
|
18
21
|
assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
|
19
22
|
result
|
20
23
|
end
|
21
24
|
|
22
|
-
def collect_deprecations
|
23
|
-
|
25
|
+
def collect_deprecations(deprecator = nil)
|
26
|
+
deprecator ||= ActiveSupport::Deprecation
|
27
|
+
old_behavior = deprecator.behavior
|
24
28
|
deprecations = []
|
25
|
-
|
29
|
+
deprecator.behavior = Proc.new do |message, callstack|
|
26
30
|
deprecations << message
|
27
31
|
end
|
28
32
|
result = yield
|
29
33
|
[result, deprecations]
|
30
34
|
ensure
|
31
|
-
|
35
|
+
deprecator.behavior = old_behavior
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Testing
|
5
|
+
# Adds simple access to sample files called file fixtures.
|
6
|
+
# File fixtures are normal files stored in
|
7
|
+
# <tt>ActiveSupport::TestCase.file_fixture_path</tt>.
|
8
|
+
#
|
9
|
+
# File fixtures are represented as +Pathname+ objects.
|
10
|
+
# This makes it easy to extract specific information:
|
11
|
+
#
|
12
|
+
# file_fixture("example.txt").read # get the file's content
|
13
|
+
# file_fixture("example.mp3").size # get the file size
|
14
|
+
module FileFixtures
|
15
|
+
extend ActiveSupport::Concern
|
16
|
+
|
17
|
+
included do
|
18
|
+
class_attribute :file_fixture_path, instance_writer: false
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns a +Pathname+ to the fixture file named +fixture_name+.
|
22
|
+
#
|
23
|
+
# Raises +ArgumentError+ if +fixture_name+ can't be found.
|
24
|
+
def file_fixture(fixture_name)
|
25
|
+
path = Pathname.new(File.join(file_fixture_path, fixture_name))
|
26
|
+
|
27
|
+
if path.exist?
|
28
|
+
path
|
29
|
+
else
|
30
|
+
msg = "the directory '%s' does not contain a file named '%s'"
|
31
|
+
raise ArgumentError, msg % [file_fixture_path, fixture_name]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
4
|
module Testing
|
5
5
|
module Isolation
|
6
|
-
require
|
6
|
+
require "thread"
|
7
7
|
|
8
8
|
def self.included(klass) #:nodoc:
|
9
9
|
klass.class_eval do
|
@@ -12,18 +12,7 @@ module ActiveSupport
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.forking_env?
|
15
|
-
!ENV["NO_FORK"] && (
|
16
|
-
end
|
17
|
-
|
18
|
-
@@class_setup_mutex = Mutex.new
|
19
|
-
|
20
|
-
def _run_class_setup # class setup method should only happen in parent
|
21
|
-
@@class_setup_mutex.synchronize do
|
22
|
-
unless defined?(@@ran_class_setup) || ENV['ISOLATION_TEST']
|
23
|
-
self.class.setup if self.class.respond_to?(:setup)
|
24
|
-
@@ran_class_setup = true
|
25
|
-
end
|
26
|
-
end
|
15
|
+
!ENV["NO_FORK"] && Process.respond_to?(:fork)
|
27
16
|
end
|
28
17
|
|
29
18
|
def run
|
@@ -43,14 +32,31 @@ module ActiveSupport
|
|
43
32
|
pid = fork do
|
44
33
|
read.close
|
45
34
|
yield
|
46
|
-
|
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")
|
47
53
|
exit!
|
48
54
|
end
|
49
55
|
|
50
56
|
write.close
|
51
57
|
result = read.read
|
52
58
|
Process.wait2(pid)
|
53
|
-
|
59
|
+
result.unpack("m")[0]
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
@@ -64,24 +70,27 @@ module ActiveSupport
|
|
64
70
|
|
65
71
|
if ENV["ISOLATION_TEST"]
|
66
72
|
yield
|
73
|
+
test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
|
67
74
|
File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
|
68
|
-
file.puts [Marshal.dump(
|
75
|
+
file.puts [Marshal.dump(test_result)].pack("m")
|
69
76
|
end
|
70
77
|
exit!
|
71
78
|
else
|
72
79
|
Tempfile.open("isolation") do |tmpfile|
|
73
80
|
env = {
|
74
|
-
ISOLATION_TEST
|
75
|
-
ISOLATION_OUTPUT
|
81
|
+
"ISOLATION_TEST" => self.class.name,
|
82
|
+
"ISOLATION_OUTPUT" => tmpfile.path
|
76
83
|
}
|
77
84
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
82
92
|
|
83
|
-
|
84
|
-
child = IO.popen([env, command])
|
93
|
+
child = IO.popen([env, Gem.ruby, *load_path_args, $0, *ORIG_ARGV, test_opts])
|
85
94
|
|
86
95
|
begin
|
87
96
|
Process.wait(child.pid)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "minitest/mock"
|
4
|
+
|
5
|
+
module ActiveSupport
|
6
|
+
module Testing
|
7
|
+
module MethodCallAssertions # :nodoc:
|
8
|
+
private
|
9
|
+
def assert_called(object, method_name, message = nil, times: 1, returns: nil)
|
10
|
+
times_called = 0
|
11
|
+
|
12
|
+
object.stub(method_name, proc { times_called += 1; returns }) { yield }
|
13
|
+
|
14
|
+
error = "Expected #{method_name} to be called #{times} times, " \
|
15
|
+
"but was called #{times_called} times"
|
16
|
+
error = "#{message}.\n#{error}" if message
|
17
|
+
assert_equal times, times_called, error
|
18
|
+
end
|
19
|
+
|
20
|
+
def assert_called_with(object, method_name, args = [], returns: nil)
|
21
|
+
mock = Minitest::Mock.new
|
22
|
+
|
23
|
+
if args.all? { |arg| arg.is_a?(Array) }
|
24
|
+
args.each { |arg| mock.expect(:call, returns, arg) }
|
25
|
+
else
|
26
|
+
mock.expect(:call, returns, args)
|
27
|
+
end
|
28
|
+
|
29
|
+
object.stub(method_name, mock) { yield }
|
30
|
+
|
31
|
+
mock.verify
|
32
|
+
end
|
33
|
+
|
34
|
+
def assert_not_called(object, method_name, message = nil, &block)
|
35
|
+
assert_called(object, method_name, message, times: 0, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def stub_any_instance(klass, instance: klass.new)
|
39
|
+
klass.stub(:new, instance) { yield instance }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
require "active_support/callbacks"
|
3
5
|
|
4
6
|
module ActiveSupport
|
5
7
|
module Testing
|
@@ -42,8 +44,15 @@ module ActiveSupport
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def after_teardown # :nodoc:
|
45
|
-
|
47
|
+
begin
|
48
|
+
run_callbacks :teardown
|
49
|
+
rescue => e
|
50
|
+
error = e
|
51
|
+
end
|
52
|
+
|
46
53
|
super
|
54
|
+
ensure
|
55
|
+
raise error if error
|
47
56
|
end
|
48
57
|
end
|
49
58
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Testing
|
5
|
+
module Stream #:nodoc:
|
6
|
+
private
|
7
|
+
|
8
|
+
def silence_stream(stream)
|
9
|
+
old_stream = stream.dup
|
10
|
+
stream.reopen(IO::NULL)
|
11
|
+
stream.sync = true
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
stream.reopen(old_stream)
|
15
|
+
old_stream.close
|
16
|
+
end
|
17
|
+
|
18
|
+
def quietly
|
19
|
+
silence_stream(STDOUT) do
|
20
|
+
silence_stream(STDERR) do
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def capture(stream)
|
27
|
+
stream = stream.to_s
|
28
|
+
captured_stream = Tempfile.new(stream)
|
29
|
+
stream_io = eval("$#{stream}")
|
30
|
+
origin_stream = stream_io.dup
|
31
|
+
stream_io.reopen(captured_stream)
|
32
|
+
|
33
|
+
yield
|
34
|
+
|
35
|
+
stream_io.rewind
|
36
|
+
return captured_stream.read
|
37
|
+
ensure
|
38
|
+
captured_stream.close
|
39
|
+
captured_stream.unlink
|
40
|
+
stream_io.reopen(origin_stream)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module Testing
|
3
5
|
# Logs a "PostsControllerTest: test name" heading before each test to
|
@@ -8,7 +10,7 @@ module ActiveSupport
|
|
8
10
|
def before_setup
|
9
11
|
if tagged_logger && tagged_logger.info?
|
10
12
|
heading = "#{self.class}: #{name}"
|
11
|
-
divider =
|
13
|
+
divider = "-" * heading.size
|
12
14
|
tagged_logger.info divider
|
13
15
|
tagged_logger.info heading
|
14
16
|
tagged_logger.info divider
|
@@ -1,53 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/redefine_method"
|
4
|
+
require "active_support/core_ext/string/strip" # for strip_heredoc
|
5
|
+
require "active_support/core_ext/time/calculations"
|
6
|
+
require "concurrent/map"
|
7
|
+
|
1
8
|
module ActiveSupport
|
2
9
|
module Testing
|
3
10
|
class SimpleStubs # :nodoc:
|
4
11
|
Stub = Struct.new(:object, :method_name, :original_method)
|
5
12
|
|
6
13
|
def initialize
|
7
|
-
@stubs = {}
|
14
|
+
@stubs = Concurrent::Map.new { |h, k| h[k] = {} }
|
8
15
|
end
|
9
16
|
|
10
|
-
def stub_object(object, method_name,
|
11
|
-
|
12
|
-
|
13
|
-
if stub = @stubs[key]
|
17
|
+
def stub_object(object, method_name, &block)
|
18
|
+
if stub = stubbing(object, method_name)
|
14
19
|
unstub_object(stub)
|
15
20
|
end
|
16
21
|
|
17
22
|
new_name = "__simple_stub__#{method_name}"
|
18
23
|
|
19
|
-
@stubs[
|
24
|
+
@stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name)
|
20
25
|
|
21
26
|
object.singleton_class.send :alias_method, new_name, method_name
|
22
|
-
object.define_singleton_method(method_name)
|
27
|
+
object.define_singleton_method(method_name, &block)
|
23
28
|
end
|
24
29
|
|
25
30
|
def unstub_all!
|
26
|
-
@stubs.each_value do |
|
27
|
-
|
31
|
+
@stubs.each_value do |object_stubs|
|
32
|
+
object_stubs.each_value do |stub|
|
33
|
+
unstub_object(stub)
|
34
|
+
end
|
28
35
|
end
|
29
|
-
@stubs
|
36
|
+
@stubs.clear
|
37
|
+
end
|
38
|
+
|
39
|
+
def stubbing(object, method_name)
|
40
|
+
@stubs[object.object_id][method_name]
|
30
41
|
end
|
31
42
|
|
32
43
|
private
|
33
44
|
|
34
45
|
def unstub_object(stub)
|
35
46
|
singleton_class = stub.object.singleton_class
|
36
|
-
singleton_class.send :
|
47
|
+
singleton_class.send :silence_redefinition_of_method, stub.method_name
|
37
48
|
singleton_class.send :alias_method, stub.method_name, stub.original_method
|
38
49
|
singleton_class.send :undef_method, stub.original_method
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
42
|
-
#
|
53
|
+
# Contains helpers that help you test passage of time.
|
43
54
|
module TimeHelpers
|
55
|
+
def after_teardown
|
56
|
+
travel_back
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
44
60
|
# Changes current time to the time in the future or in the past by a given time difference by
|
45
|
-
# stubbing +Time.now+ and +
|
61
|
+
# stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed
|
62
|
+
# at the end of the test.
|
46
63
|
#
|
47
|
-
# Time.current
|
64
|
+
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
48
65
|
# travel 1.day
|
49
|
-
# Time.current
|
50
|
-
# Date.current
|
66
|
+
# Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
|
67
|
+
# Date.current # => Sun, 10 Nov 2013
|
68
|
+
# DateTime.current # => Sun, 10 Nov 2013 15:34:49 -0500
|
51
69
|
#
|
52
70
|
# This method also accepts a block, which will return the current time back to its original
|
53
71
|
# state at the end of the block:
|
@@ -61,13 +79,15 @@ module ActiveSupport
|
|
61
79
|
travel_to Time.now + duration, &block
|
62
80
|
end
|
63
81
|
|
64
|
-
# Changes current time to the given time by stubbing +Time.now
|
65
|
-
# +Date.today+ to return the time or date passed into this method.
|
82
|
+
# Changes current time to the given time by stubbing +Time.now+,
|
83
|
+
# +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
|
84
|
+
# The stubs are automatically removed at the end of the test.
|
66
85
|
#
|
67
|
-
# Time.current
|
68
|
-
# travel_to Time.
|
69
|
-
# Time.current
|
70
|
-
# Date.current
|
86
|
+
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
87
|
+
# travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
|
88
|
+
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
89
|
+
# Date.current # => Wed, 24 Nov 2004
|
90
|
+
# DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
|
71
91
|
#
|
72
92
|
# Dates are taken as their timestamp at the beginning of the day in the
|
73
93
|
# application time zone. <tt>Time.current</tt> returns said timestamp,
|
@@ -86,19 +106,48 @@ module ActiveSupport
|
|
86
106
|
# state at the end of the block:
|
87
107
|
#
|
88
108
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
89
|
-
# travel_to Time.
|
109
|
+
# travel_to Time.zone.local(2004, 11, 24, 01, 04, 44) do
|
90
110
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
91
111
|
# end
|
92
112
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
93
113
|
def travel_to(date_or_time)
|
114
|
+
if block_given? && simple_stubs.stubbing(Time, :now)
|
115
|
+
travel_to_nested_block_call = <<-MSG.strip_heredoc
|
116
|
+
|
117
|
+
Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing.
|
118
|
+
|
119
|
+
Instead of:
|
120
|
+
|
121
|
+
travel_to 2.days.from_now do
|
122
|
+
# 2 days from today
|
123
|
+
travel_to 3.days.from_now do
|
124
|
+
# 5 days from today
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
preferred way to achieve above is:
|
129
|
+
|
130
|
+
travel 2.days do
|
131
|
+
# 2 days from today
|
132
|
+
end
|
133
|
+
|
134
|
+
travel 5.days do
|
135
|
+
# 5 days from today
|
136
|
+
end
|
137
|
+
|
138
|
+
MSG
|
139
|
+
raise travel_to_nested_block_call
|
140
|
+
end
|
141
|
+
|
94
142
|
if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime)
|
95
143
|
now = date_or_time.midnight.to_time
|
96
144
|
else
|
97
145
|
now = date_or_time.to_time.change(usec: 0)
|
98
146
|
end
|
99
147
|
|
100
|
-
simple_stubs.stub_object(Time, :now
|
101
|
-
simple_stubs.stub_object(Date, :today
|
148
|
+
simple_stubs.stub_object(Time, :now) { at(now.to_i) }
|
149
|
+
simple_stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
|
150
|
+
simple_stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
|
102
151
|
|
103
152
|
if block_given?
|
104
153
|
begin
|
@@ -110,10 +159,10 @@ module ActiveSupport
|
|
110
159
|
end
|
111
160
|
|
112
161
|
# Returns the current time back to its original state, by removing the stubs added by
|
113
|
-
#
|
162
|
+
# +travel+ and +travel_to+.
|
114
163
|
#
|
115
164
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
116
|
-
# travel_to Time.
|
165
|
+
# travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
|
117
166
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
118
167
|
# travel_back
|
119
168
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
@@ -121,6 +170,26 @@ module ActiveSupport
|
|
121
170
|
simple_stubs.unstub_all!
|
122
171
|
end
|
123
172
|
|
173
|
+
# Calls +travel_to+ with +Time.now+.
|
174
|
+
#
|
175
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
176
|
+
# freeze_time
|
177
|
+
# sleep(1)
|
178
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
179
|
+
#
|
180
|
+
# This method also accepts a block, which will return the current time back to its original
|
181
|
+
# state at the end of the block:
|
182
|
+
#
|
183
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
184
|
+
# freeze_time do
|
185
|
+
# sleep(1)
|
186
|
+
# User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
187
|
+
# end
|
188
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
|
189
|
+
def freeze_time(&block)
|
190
|
+
travel_to Time.now, &block
|
191
|
+
end
|
192
|
+
|
124
193
|
private
|
125
194
|
|
126
195
|
def simple_stubs
|