activesupport 4.1.15 → 4.2.11.3
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 +395 -574
- data/README.rdoc +7 -2
- data/lib/active_support.rb +19 -0
- data/lib/active_support/backtrace_cleaner.rb +4 -4
- data/lib/active_support/cache.rb +17 -19
- data/lib/active_support/cache/file_store.rb +5 -0
- data/lib/active_support/cache/mem_cache_store.rb +1 -1
- data/lib/active_support/cache/strategy/local_cache.rb +5 -4
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +5 -0
- data/lib/active_support/callbacks.rb +41 -33
- data/lib/active_support/concern.rb +10 -2
- data/lib/active_support/core_ext/array/access.rb +9 -1
- data/lib/active_support/core_ext/array/grouping.rb +5 -0
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +2 -0
- data/lib/active_support/core_ext/class/delegating_attributes.rb +4 -0
- data/lib/active_support/core_ext/class/subclasses.rb +0 -2
- data/lib/active_support/core_ext/date/conversions.rb +6 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +11 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +34 -4
- data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -2
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/enumerable.rb +16 -0
- data/lib/active_support/core_ext/file/atomic.rb +1 -1
- data/lib/active_support/core_ext/hash.rb +1 -0
- data/lib/active_support/core_ext/hash/compact.rb +20 -16
- data/lib/active_support/core_ext/hash/conversions.rb +3 -5
- data/lib/active_support/core_ext/hash/except.rb +8 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +10 -6
- data/lib/active_support/core_ext/hash/slice.rb +8 -2
- data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
- data/lib/active_support/core_ext/integer/time.rb +0 -15
- data/lib/active_support/core_ext/kernel.rb +3 -2
- data/lib/active_support/core_ext/kernel/concern.rb +10 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +15 -0
- data/lib/active_support/core_ext/load_error.rb +4 -1
- data/lib/active_support/core_ext/marshal.rb +8 -5
- data/lib/active_support/core_ext/module/aliasing.rb +2 -2
- data/lib/active_support/core_ext/module/delegation.rb +34 -18
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
- data/lib/active_support/core_ext/numeric/time.rb +1 -34
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/duplicable.rb +62 -33
- data/lib/active_support/core_ext/object/itself.rb +15 -0
- data/lib/active_support/core_ext/object/json.rb +2 -2
- data/lib/active_support/core_ext/object/to_query.rb +2 -1
- data/lib/active_support/core_ext/object/try.rb +35 -13
- data/lib/active_support/core_ext/object/with_options.rb +30 -3
- data/lib/active_support/core_ext/string/access.rb +5 -5
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +44 -6
- data/lib/active_support/core_ext/string/inflections.rb +4 -1
- data/lib/active_support/core_ext/string/output_safety.rb +33 -14
- data/lib/active_support/core_ext/thread.rb +7 -0
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/time/calculations.rb +31 -7
- data/lib/active_support/core_ext/time/compatibility.rb +14 -0
- data/lib/active_support/core_ext/time/conversions.rb +1 -1
- data/lib/active_support/dependencies.rb +32 -18
- data/lib/active_support/dependencies/autoload.rb +1 -1
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/deprecation/behaviors.rb +1 -1
- data/lib/active_support/duration.rb +47 -5
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +35 -7
- data/lib/active_support/i18n_railtie.rb +1 -7
- data/lib/active_support/inflector/inflections.rb +2 -2
- data/lib/active_support/inflector/methods.rb +43 -19
- data/lib/active_support/json/decoding.rb +1 -1
- data/lib/active_support/json/encoding.rb +3 -2
- data/lib/active_support/logger.rb +36 -0
- data/lib/active_support/logger_silence.rb +4 -22
- data/lib/active_support/logger_thread_safe_level.rb +32 -0
- data/lib/active_support/message_encryptor.rb +10 -2
- data/lib/active_support/message_verifier.rb +11 -12
- data/lib/active_support/multibyte/chars.rb +1 -1
- data/lib/active_support/multibyte/unicode.rb +5 -4
- data/lib/active_support/notifications.rb +8 -3
- data/lib/active_support/notifications/fanout.rb +12 -7
- data/lib/active_support/number_helper.rb +12 -13
- data/lib/active_support/number_helper/number_to_currency_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +1 -1
- data/lib/active_support/per_thread_registry.rb +5 -3
- data/lib/active_support/test_case.rb +46 -12
- data/lib/active_support/testing/assertions.rb +1 -1
- data/lib/active_support/testing/constant_lookup.rb +1 -5
- data/lib/active_support/testing/declarative.rb +1 -25
- data/lib/active_support/testing/isolation.rb +16 -6
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +23 -16
- data/lib/active_support/time.rb +0 -2
- data/lib/active_support/time_with_zone.rb +48 -29
- data/lib/active_support/values/time_zone.rb +81 -75
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini.rb +30 -15
- data/lib/active_support/xml_mini/libxml.rb +1 -3
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
- data/lib/active_support/xml_mini/nokogiri.rb +1 -3
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
- data/lib/active_support/xml_mini/rexml.rb +1 -3
- metadata +21 -36
- data/lib/active_support/core_ext/object/to_json.rb +0 -5
- data/lib/active_support/file_watcher.rb +0 -36
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'base64'
|
2
2
|
require 'active_support/core_ext/object/blank'
|
3
|
+
require 'active_support/security_utils'
|
3
4
|
|
4
5
|
module ActiveSupport
|
5
6
|
# +MessageVerifier+ makes it easy to generate and verify messages which are
|
@@ -27,18 +28,19 @@ module ActiveSupport
|
|
27
28
|
class InvalidSignature < StandardError; end
|
28
29
|
|
29
30
|
def initialize(secret, options = {})
|
31
|
+
raise ArgumentError, 'Secret should not be nil.' unless secret
|
30
32
|
@secret = secret
|
31
33
|
@digest = options[:digest] || 'SHA1'
|
32
34
|
@serializer = options[:serializer] || Marshal
|
33
35
|
end
|
34
36
|
|
35
37
|
def verify(signed_message)
|
36
|
-
raise InvalidSignature if signed_message.blank?
|
38
|
+
raise InvalidSignature if signed_message.nil? || !signed_message.valid_encoding? || signed_message.blank?
|
37
39
|
|
38
40
|
data, digest = signed_message.split("--")
|
39
|
-
if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
|
41
|
+
if data.present? && digest.present? && ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(data))
|
40
42
|
begin
|
41
|
-
@serializer.load(
|
43
|
+
@serializer.load(decode(data))
|
42
44
|
rescue ArgumentError => argument_error
|
43
45
|
raise InvalidSignature if argument_error.message =~ %r{invalid base64}
|
44
46
|
raise
|
@@ -49,20 +51,17 @@ module ActiveSupport
|
|
49
51
|
end
|
50
52
|
|
51
53
|
def generate(value)
|
52
|
-
data =
|
54
|
+
data = encode(@serializer.dump(value))
|
53
55
|
"#{data}--#{generate_digest(data)}"
|
54
56
|
end
|
55
57
|
|
56
58
|
private
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
l = a.unpack "C#{a.bytesize}"
|
59
|
+
def encode(data)
|
60
|
+
::Base64.strict_encode64(data)
|
61
|
+
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
res == 0
|
63
|
+
def decode(data)
|
64
|
+
::Base64.strict_decode64(data)
|
66
65
|
end
|
67
66
|
|
68
67
|
def generate_digest(data)
|
@@ -86,7 +86,7 @@ module ActiveSupport #:nodoc:
|
|
86
86
|
@wrapped_string.split(*args).map { |i| self.class.new(i) }
|
87
87
|
end
|
88
88
|
|
89
|
-
# Works like
|
89
|
+
# Works like <tt>String#slice!</tt>, but returns an instance of
|
90
90
|
# Chars, or nil if the string was not modified.
|
91
91
|
def slice!(*args)
|
92
92
|
chars(@wrapped_string.slice!(*args))
|
@@ -11,7 +11,7 @@ module ActiveSupport
|
|
11
11
|
NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
|
12
12
|
|
13
13
|
# The Unicode version that is supported by the implementation
|
14
|
-
UNICODE_VERSION = '
|
14
|
+
UNICODE_VERSION = '7.0.0'
|
15
15
|
|
16
16
|
# The default normalization used for operations that require
|
17
17
|
# normalization. It can be set to any of the normalizations
|
@@ -212,7 +212,8 @@ module ActiveSupport
|
|
212
212
|
end
|
213
213
|
|
214
214
|
# Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1.
|
215
|
-
|
215
|
+
# Rubinius' String#scrub, however, doesn't support ASCII-incompatible chars.
|
216
|
+
if '<3'.respond_to?(:scrub) && !defined?(Rubinius)
|
216
217
|
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
|
217
218
|
# resulting in a valid UTF-8 string.
|
218
219
|
#
|
@@ -334,7 +335,7 @@ module ActiveSupport
|
|
334
335
|
begin
|
335
336
|
@codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
|
336
337
|
rescue => e
|
337
|
-
|
338
|
+
raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
|
338
339
|
end
|
339
340
|
|
340
341
|
# Redefine the === method so we can write shorter rules for grapheme cluster breaks
|
@@ -366,6 +367,7 @@ module ActiveSupport
|
|
366
367
|
private
|
367
368
|
|
368
369
|
def apply_mapping(string, mapping) #:nodoc:
|
370
|
+
database.codepoints
|
369
371
|
string.each_codepoint.map do |codepoint|
|
370
372
|
cp = database.codepoints[codepoint]
|
371
373
|
if cp and (ncp = cp.send(mapping)) and ncp > 0
|
@@ -383,7 +385,6 @@ module ActiveSupport
|
|
383
385
|
def database
|
384
386
|
@database ||= UnicodeDatabase.new
|
385
387
|
end
|
386
|
-
|
387
388
|
end
|
388
389
|
end
|
389
390
|
end
|
@@ -16,7 +16,7 @@ module ActiveSupport
|
|
16
16
|
# render text: 'Foo'
|
17
17
|
# end
|
18
18
|
#
|
19
|
-
# That executes the block
|
19
|
+
# That first executes the block and then notifies all subscribers once done.
|
20
20
|
#
|
21
21
|
# In the example above +render+ is the name of the event, and the rest is called
|
22
22
|
# the _payload_. The payload is a mechanism that allows instrumenters to pass
|
@@ -141,6 +141,11 @@ module ActiveSupport
|
|
141
141
|
#
|
142
142
|
# ActiveSupport::Notifications.unsubscribe(subscriber)
|
143
143
|
#
|
144
|
+
# You can also unsubscribe by passing the name of the subscriber object. Note
|
145
|
+
# that this will unsubscribe all subscriptions with the given name:
|
146
|
+
#
|
147
|
+
# ActiveSupport::Notifications.unsubscribe("render")
|
148
|
+
#
|
144
149
|
# == Default Queue
|
145
150
|
#
|
146
151
|
# Notifications ships with a queue implementation that consumes and publishes events
|
@@ -173,8 +178,8 @@ module ActiveSupport
|
|
173
178
|
unsubscribe(subscriber)
|
174
179
|
end
|
175
180
|
|
176
|
-
def unsubscribe(
|
177
|
-
notifier.unsubscribe(
|
181
|
+
def unsubscribe(subscriber_or_name)
|
182
|
+
notifier.unsubscribe(subscriber_or_name)
|
178
183
|
end
|
179
184
|
|
180
185
|
def instrumenter
|
@@ -25,9 +25,15 @@ module ActiveSupport
|
|
25
25
|
subscriber
|
26
26
|
end
|
27
27
|
|
28
|
-
def unsubscribe(
|
28
|
+
def unsubscribe(subscriber_or_name)
|
29
29
|
synchronize do
|
30
|
-
|
30
|
+
case subscriber_or_name
|
31
|
+
when String
|
32
|
+
@subscribers.reject! { |s| s.matches?(subscriber_or_name) }
|
33
|
+
else
|
34
|
+
@subscribers.delete(subscriber_or_name)
|
35
|
+
end
|
36
|
+
|
31
37
|
@listeners_for.clear
|
32
38
|
end
|
33
39
|
end
|
@@ -97,16 +103,15 @@ module ActiveSupport
|
|
97
103
|
end
|
98
104
|
|
99
105
|
def subscribed_to?(name)
|
100
|
-
@pattern === name
|
106
|
+
@pattern === name
|
101
107
|
end
|
102
108
|
|
103
|
-
def matches?(
|
104
|
-
|
105
|
-
@pattern && @pattern === subscriber_or_name
|
109
|
+
def matches?(name)
|
110
|
+
@pattern && @pattern === name
|
106
111
|
end
|
107
112
|
end
|
108
113
|
|
109
|
-
class Timed < Evented
|
114
|
+
class Timed < Evented # :nodoc:
|
110
115
|
def publish(name, *args)
|
111
116
|
@delegate.call name, *args
|
112
117
|
end
|
@@ -232,12 +232,8 @@ module ActiveSupport
|
|
232
232
|
# number_to_human_size(1234567, precision: 2) # => 1.2 MB
|
233
233
|
# number_to_human_size(483989, precision: 2) # => 470 KB
|
234
234
|
# number_to_human_size(1234567, precision: 2, separator: ',') # => 1,2 MB
|
235
|
-
#
|
236
|
-
#
|
237
|
-
# default (set <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
|
238
|
-
#
|
239
|
-
# number_to_human_size(1234567890123, precision: 5) # => "1.1229 TB"
|
240
|
-
# number_to_human_size(524288000, precision: 5) # => "500 MB"
|
235
|
+
# number_to_human_size(1234567890123, precision: 5) # => "1.1228 TB"
|
236
|
+
# number_to_human_size(524288000, precision: 5) # => "500 MB"
|
241
237
|
def number_to_human_size(number, options = {})
|
242
238
|
NumberToHumanSizeConverter.convert(number, options)
|
243
239
|
end
|
@@ -276,12 +272,12 @@ module ActiveSupport
|
|
276
272
|
# string containing an i18n scope where to find this hash. It
|
277
273
|
# might have the following keys:
|
278
274
|
# * *integers*: <tt>:unit</tt>, <tt>:ten</tt>,
|
279
|
-
#
|
280
|
-
#
|
281
|
-
#
|
275
|
+
# <tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>,
|
276
|
+
# <tt>:billion</tt>, <tt>:trillion</tt>,
|
277
|
+
# <tt>:quadrillion</tt>
|
282
278
|
# * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>,
|
283
|
-
#
|
284
|
-
#
|
279
|
+
# <tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>,
|
280
|
+
# <tt>:pico</tt>, <tt>:femto</tt>
|
285
281
|
# * <tt>:format</tt> - Sets the format of the output string
|
286
282
|
# (defaults to "%n %u"). The field types are:
|
287
283
|
# * %u - The quantifier (ex.: 'thousand')
|
@@ -305,12 +301,15 @@ module ActiveSupport
|
|
305
301
|
# separator: ',',
|
306
302
|
# significant: false) # => "1,2 Million"
|
307
303
|
#
|
304
|
+
# number_to_human(500000000, precision: 5) # => "500 Million"
|
305
|
+
# number_to_human(12345012345, significant: false) # => "12.345 Billion"
|
306
|
+
#
|
308
307
|
# Non-significant zeros after the decimal separator are stripped
|
309
308
|
# out by default (set <tt>:strip_insignificant_zeros</tt> to
|
310
309
|
# +false+ to change that):
|
311
310
|
#
|
312
|
-
#
|
313
|
-
#
|
311
|
+
# number_to_human(12.00001) # => "12"
|
312
|
+
# number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0"
|
314
313
|
#
|
315
314
|
# ==== Custom Unit Quantifiers
|
316
315
|
#
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
# This module is used to encapsulate access to thread local variables.
|
3
5
|
#
|
@@ -43,9 +45,9 @@ module ActiveSupport
|
|
43
45
|
protected
|
44
46
|
def method_missing(name, *args, &block) # :nodoc:
|
45
47
|
# Caches the method definition as a singleton method of the receiver.
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
#
|
49
|
+
# By letting #delegate handle it, we avoid an enclosure that'll capture args.
|
50
|
+
singleton_class.delegate name, to: :instance
|
49
51
|
|
50
52
|
send(name, *args, &block)
|
51
53
|
end
|
@@ -11,25 +11,59 @@ require 'active_support/testing/time_helpers'
|
|
11
11
|
require 'active_support/core_ext/kernel/reporting'
|
12
12
|
require 'active_support/deprecation'
|
13
13
|
|
14
|
-
begin
|
15
|
-
silence_warnings { require 'mocha/setup' }
|
16
|
-
rescue LoadError
|
17
|
-
end
|
18
|
-
|
19
14
|
module ActiveSupport
|
20
15
|
class TestCase < ::Minitest::Test
|
21
16
|
Assertion = Minitest::Assertion
|
22
17
|
|
23
|
-
|
18
|
+
class << self
|
19
|
+
# Sets the order in which test cases are run.
|
20
|
+
#
|
21
|
+
# ActiveSupport::TestCase.test_order = :random # => :random
|
22
|
+
#
|
23
|
+
# Valid values are:
|
24
|
+
# * +:random+ (to run tests in random order)
|
25
|
+
# * +:parallel+ (to run tests in parallel)
|
26
|
+
# * +:sorted+ (to run tests alphabetically by method name)
|
27
|
+
# * +:alpha+ (equivalent to +:sorted+)
|
28
|
+
def test_order=(new_order)
|
29
|
+
ActiveSupport.test_order = new_order
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the order in which test cases are run.
|
33
|
+
#
|
34
|
+
# ActiveSupport::TestCase.test_order # => :sorted
|
35
|
+
#
|
36
|
+
# Possible values are +:random+, +:parallel+, +:alpha+, +:sorted+.
|
37
|
+
# Defaults to +:sorted+.
|
38
|
+
def test_order
|
39
|
+
test_order = ActiveSupport.test_order
|
24
40
|
|
25
|
-
|
26
|
-
|
27
|
-
|
41
|
+
if test_order.nil?
|
42
|
+
ActiveSupport::Deprecation.warn "You did not specify a value for the " \
|
43
|
+
"configuration option `active_support.test_order`. In Rails 5, " \
|
44
|
+
"the default value of this option will change from `:sorted` to " \
|
45
|
+
"`:random`.\n" \
|
46
|
+
"To disable this warning and keep the current behavior, you can add " \
|
47
|
+
"the following line to your `config/environments/test.rb`:\n" \
|
48
|
+
"\n" \
|
49
|
+
" Rails.application.configure do\n" \
|
50
|
+
" config.active_support.test_order = :sorted\n" \
|
51
|
+
" end\n" \
|
52
|
+
"\n" \
|
53
|
+
"Alternatively, you can opt into the future behavior by setting this " \
|
54
|
+
"option to `:random`."
|
55
|
+
|
56
|
+
test_order = :sorted
|
57
|
+
self.test_order = test_order
|
58
|
+
end
|
59
|
+
|
60
|
+
test_order
|
61
|
+
end
|
62
|
+
|
63
|
+
alias :my_tests_are_order_dependent! :i_suck_and_my_tests_are_order_dependent!
|
28
64
|
end
|
29
65
|
|
30
|
-
|
31
|
-
# remove this method call.
|
32
|
-
self.i_suck_and_my_tests_are_order_dependent!
|
66
|
+
alias_method :method_name, :name
|
33
67
|
|
34
68
|
include ActiveSupport::Testing::TaggedLogging
|
35
69
|
include ActiveSupport::Testing::SetupAndTeardown
|
@@ -36,12 +36,8 @@ module ActiveSupport
|
|
36
36
|
while names.size > 0 do
|
37
37
|
names.last.sub!(/Test$/, "")
|
38
38
|
begin
|
39
|
-
constant = names.join("::").
|
39
|
+
constant = names.join("::").safe_constantize
|
40
40
|
break(constant) if yield(constant)
|
41
|
-
rescue NoMethodError # subclass of NameError
|
42
|
-
raise
|
43
|
-
rescue NameError
|
44
|
-
# Constant wasn't found, move on
|
45
41
|
ensure
|
46
42
|
names.pop
|
47
43
|
end
|
@@ -1,30 +1,6 @@
|
|
1
1
|
module ActiveSupport
|
2
2
|
module Testing
|
3
3
|
module Declarative
|
4
|
-
|
5
|
-
def self.extended(klass) #:nodoc:
|
6
|
-
klass.class_eval do
|
7
|
-
|
8
|
-
unless method_defined?(:describe)
|
9
|
-
def self.describe(text)
|
10
|
-
if block_given?
|
11
|
-
super
|
12
|
-
else
|
13
|
-
message = "`describe` without a block is deprecated, please switch to: `def self.name; #{text.inspect}; end`\n"
|
14
|
-
ActiveSupport::Deprecation.warn message
|
15
|
-
|
16
|
-
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
17
|
-
def self.name
|
18
|
-
"#{text}"
|
19
|
-
end
|
20
|
-
RUBY_EVAL
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
4
|
unless defined?(Spec)
|
29
5
|
# Helper to define a test method using a String. Under the hood, it replaces
|
30
6
|
# spaces with underscores and defines the test method.
|
@@ -34,7 +10,7 @@ module ActiveSupport
|
|
34
10
|
# end
|
35
11
|
def test(name, &block)
|
36
12
|
test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
|
37
|
-
defined =
|
13
|
+
defined = method_defined? test_name
|
38
14
|
raise "#{test_name} is already defined in #{self}" if defined
|
39
15
|
if block_given?
|
40
16
|
define_method(test_name, &block)
|
@@ -70,14 +70,24 @@ module ActiveSupport
|
|
70
70
|
exit!
|
71
71
|
else
|
72
72
|
Tempfile.open("isolation") do |tmpfile|
|
73
|
-
|
74
|
-
|
73
|
+
env = {
|
74
|
+
ISOLATION_TEST: self.class.name,
|
75
|
+
ISOLATION_OUTPUT: tmpfile.path
|
76
|
+
}
|
75
77
|
|
76
78
|
load_paths = $-I.map {|p| "-I\"#{File.expand_path(p)}\"" }.join(" ")
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
79
|
+
orig_args = ORIG_ARGV.join(" ")
|
80
|
+
test_opts = "-n#{self.class.name}##{self.name}"
|
81
|
+
command = "#{Gem.ruby} #{load_paths} #{$0} #{orig_args} #{test_opts}"
|
82
|
+
|
83
|
+
# IO.popen lets us pass env in a cross-platform way
|
84
|
+
child = IO.popen([env, command])
|
85
|
+
|
86
|
+
begin
|
87
|
+
Process.wait(child.pid)
|
88
|
+
rescue Errno::ECHILD # The child process may exit before we wait
|
89
|
+
nil
|
90
|
+
end
|
81
91
|
|
82
92
|
return tmpfile.read.unpack("m")[0]
|
83
93
|
end
|