activesupport 4.2.11.3 → 5.0.0.beta1

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.

Files changed (174) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +309 -485
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/active_support.rb +8 -15
  6. data/lib/active_support/array_inquirer.rb +44 -0
  7. data/lib/active_support/backtrace_cleaner.rb +1 -1
  8. data/lib/active_support/cache.rb +59 -72
  9. data/lib/active_support/cache/file_store.rb +27 -19
  10. data/lib/active_support/cache/mem_cache_store.rb +71 -60
  11. data/lib/active_support/cache/memory_store.rb +16 -21
  12. data/lib/active_support/cache/null_store.rb +1 -4
  13. data/lib/active_support/cache/strategy/local_cache.rb +31 -20
  14. data/lib/active_support/callbacks.rb +107 -111
  15. data/lib/active_support/concern.rb +1 -1
  16. data/lib/active_support/concurrency/latch.rb +7 -15
  17. data/lib/active_support/concurrency/share_lock.rb +142 -0
  18. data/lib/active_support/configurable.rb +1 -0
  19. data/lib/active_support/core_ext.rb +2 -1
  20. data/lib/active_support/core_ext/array.rb +1 -0
  21. data/lib/active_support/core_ext/array/access.rb +13 -1
  22. data/lib/active_support/core_ext/array/conversions.rb +6 -4
  23. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  24. data/lib/active_support/core_ext/array/wrap.rb +5 -4
  25. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
  26. data/lib/active_support/core_ext/class.rb +0 -1
  27. data/lib/active_support/core_ext/class/attribute.rb +10 -9
  28. data/lib/active_support/core_ext/class/subclasses.rb +5 -2
  29. data/lib/active_support/core_ext/date.rb +1 -1
  30. data/lib/active_support/core_ext/date/blank.rb +12 -0
  31. data/lib/active_support/core_ext/date/calculations.rb +1 -1
  32. data/lib/active_support/core_ext/date/conversions.rb +3 -3
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +93 -27
  34. data/lib/active_support/core_ext/date_and_time/zones.rb +1 -2
  35. data/lib/active_support/core_ext/date_time.rb +1 -1
  36. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  37. data/lib/active_support/core_ext/date_time/calculations.rb +7 -23
  38. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  39. data/lib/active_support/core_ext/enumerable.rb +27 -17
  40. data/lib/active_support/core_ext/file/atomic.rb +30 -25
  41. data/lib/active_support/core_ext/hash/compact.rb +15 -19
  42. data/lib/active_support/core_ext/hash/conversions.rb +21 -2
  43. data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
  44. data/lib/active_support/core_ext/hash/except.rb +9 -8
  45. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  46. data/lib/active_support/core_ext/hash/keys.rb +22 -18
  47. data/lib/active_support/core_ext/hash/slice.rb +1 -1
  48. data/lib/active_support/core_ext/hash/transform_values.rb +13 -7
  49. data/lib/active_support/core_ext/integer/time.rb +1 -1
  50. data/lib/active_support/core_ext/kernel.rb +0 -1
  51. data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
  52. data/lib/active_support/core_ext/kernel/reporting.rb +0 -84
  53. data/lib/active_support/core_ext/load_error.rb +4 -2
  54. data/lib/active_support/core_ext/marshal.rb +8 -13
  55. data/lib/active_support/core_ext/module.rb +1 -0
  56. data/lib/active_support/core_ext/module/aliasing.rb +6 -1
  57. data/lib/active_support/core_ext/module/anonymous.rb +10 -1
  58. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  59. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -7
  60. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  61. data/lib/active_support/core_ext/module/concerning.rb +4 -4
  62. data/lib/active_support/core_ext/module/delegation.rb +7 -14
  63. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
  64. data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
  65. data/lib/active_support/core_ext/module/remove_method.rb +23 -0
  66. data/lib/active_support/core_ext/name_error.rb +15 -2
  67. data/lib/active_support/core_ext/numeric.rb +1 -0
  68. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  69. data/lib/active_support/core_ext/numeric/conversions.rb +12 -23
  70. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  71. data/lib/active_support/core_ext/numeric/time.rb +20 -0
  72. data/lib/active_support/core_ext/object.rb +0 -1
  73. data/lib/active_support/core_ext/object/blank.rb +11 -2
  74. data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
  75. data/lib/active_support/core_ext/object/duplicable.rb +39 -70
  76. data/lib/active_support/core_ext/object/inclusion.rb +2 -2
  77. data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
  78. data/lib/active_support/core_ext/object/json.rb +9 -7
  79. data/lib/active_support/core_ext/object/to_query.rb +1 -1
  80. data/lib/active_support/core_ext/object/try.rb +67 -21
  81. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  82. data/lib/active_support/core_ext/range/conversions.rb +18 -6
  83. data/lib/active_support/core_ext/range/each.rb +16 -18
  84. data/lib/active_support/core_ext/range/include_range.rb +20 -20
  85. data/lib/active_support/core_ext/securerandom.rb +23 -0
  86. data/lib/active_support/core_ext/string/access.rb +1 -1
  87. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  88. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  89. data/lib/active_support/core_ext/string/filters.rb +1 -2
  90. data/lib/active_support/core_ext/string/inflections.rb +23 -5
  91. data/lib/active_support/core_ext/string/multibyte.rb +11 -7
  92. data/lib/active_support/core_ext/string/output_safety.rb +8 -9
  93. data/lib/active_support/core_ext/string/strip.rb +3 -6
  94. data/lib/active_support/core_ext/struct.rb +3 -6
  95. data/lib/active_support/core_ext/time.rb +0 -2
  96. data/lib/active_support/core_ext/time/calculations.rb +18 -16
  97. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  98. data/lib/active_support/core_ext/time/marshal.rb +2 -29
  99. data/lib/active_support/core_ext/time/zones.rb +19 -3
  100. data/lib/active_support/core_ext/uri.rb +1 -3
  101. data/lib/active_support/dependencies.rb +79 -44
  102. data/lib/active_support/dependencies/interlock.rb +47 -0
  103. data/lib/active_support/deprecation/behaviors.rb +12 -0
  104. data/lib/active_support/deprecation/method_wrappers.rb +42 -16
  105. data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
  106. data/lib/active_support/deprecation/reporting.rb +13 -2
  107. data/lib/active_support/duration.rb +5 -8
  108. data/lib/active_support/evented_file_update_checker.rb +150 -0
  109. data/lib/active_support/file_update_checker.rb +1 -1
  110. data/lib/active_support/gem_version.rb +5 -5
  111. data/lib/active_support/hash_with_indifferent_access.rb +15 -17
  112. data/lib/active_support/i18n_railtie.rb +25 -4
  113. data/lib/active_support/inflector/inflections.rb +36 -5
  114. data/lib/active_support/inflector/methods.rb +87 -89
  115. data/lib/active_support/inflector/transliterate.rb +36 -21
  116. data/lib/active_support/json/decoding.rb +2 -8
  117. data/lib/active_support/json/encoding.rb +0 -50
  118. data/lib/active_support/key_generator.rb +4 -4
  119. data/lib/active_support/log_subscriber.rb +1 -1
  120. data/lib/active_support/log_subscriber/test_helper.rb +3 -3
  121. data/lib/active_support/logger.rb +4 -52
  122. data/lib/active_support/logger_silence.rb +3 -5
  123. data/lib/active_support/message_encryptor.rb +4 -11
  124. data/lib/active_support/message_verifier.rb +64 -8
  125. data/lib/active_support/multibyte/chars.rb +12 -3
  126. data/lib/active_support/multibyte/unicode.rb +6 -8
  127. data/lib/active_support/notifications.rb +2 -2
  128. data/lib/active_support/notifications/fanout.rb +5 -5
  129. data/lib/active_support/notifications/instrumenter.rb +19 -2
  130. data/lib/active_support/number_helper.rb +21 -15
  131. data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -4
  132. data/lib/active_support/number_helper/number_to_delimited_converter.rb +7 -2
  133. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
  134. data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -1
  135. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  136. data/lib/active_support/number_helper/number_to_rounded_converter.rb +28 -25
  137. data/lib/active_support/ordered_options.rb +15 -1
  138. data/lib/active_support/per_thread_registry.rb +3 -0
  139. data/lib/active_support/rails.rb +2 -2
  140. data/lib/active_support/railtie.rb +6 -1
  141. data/lib/active_support/rescuable.rb +4 -4
  142. data/lib/active_support/security_utils.rb +0 -7
  143. data/lib/active_support/string_inquirer.rb +1 -1
  144. data/lib/active_support/subscriber.rb +5 -10
  145. data/lib/active_support/tagged_logging.rb +3 -1
  146. data/lib/active_support/test_case.rb +13 -25
  147. data/lib/active_support/testing/assertions.rb +15 -13
  148. data/lib/active_support/testing/autorun.rb +8 -1
  149. data/lib/active_support/testing/composite_filter.rb +54 -0
  150. data/lib/active_support/testing/deprecation.rb +9 -8
  151. data/lib/active_support/testing/file_fixtures.rb +34 -0
  152. data/lib/active_support/testing/isolation.rb +22 -8
  153. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  154. data/lib/active_support/testing/stream.rb +42 -0
  155. data/lib/active_support/testing/time_helpers.rb +6 -6
  156. data/lib/active_support/time_with_zone.rb +135 -53
  157. data/lib/active_support/values/time_zone.rb +80 -46
  158. data/lib/active_support/values/unicode_tables.dat +0 -0
  159. data/lib/active_support/xml_mini.rb +15 -30
  160. data/lib/active_support/xml_mini/jdom.rb +1 -1
  161. data/lib/active_support/xml_mini/libxml.rb +5 -3
  162. data/lib/active_support/xml_mini/libxmlsax.rb +4 -1
  163. data/lib/active_support/xml_mini/nokogiri.rb +5 -3
  164. data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
  165. data/lib/active_support/xml_mini/rexml.rb +3 -1
  166. metadata +57 -21
  167. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  168. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  169. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -15
  170. data/lib/active_support/core_ext/date_time/compatibility.rb +0 -16
  171. data/lib/active_support/core_ext/object/itself.rb +0 -15
  172. data/lib/active_support/core_ext/thread.rb +0 -86
  173. data/lib/active_support/core_ext/time/compatibility.rb +0 -14
  174. data/lib/active_support/logger_thread_safe_level.rb +0 -32
@@ -6,6 +6,7 @@ module ActiveSupport
6
6
  # h[:girl] = 'Mary'
7
7
  # h[:boy] # => 'John'
8
8
  # h[:girl] # => 'Mary'
9
+ # h[:dog] # => nil
9
10
  #
10
11
  # Using +OrderedOptions+, the above code could be reduced to:
11
12
  #
@@ -14,6 +15,13 @@ module ActiveSupport
14
15
  # h.girl = 'Mary'
15
16
  # h.boy # => 'John'
16
17
  # h.girl # => 'Mary'
18
+ # h.dog # => nil
19
+ #
20
+ # To raise an exception when the value is blank, append a
21
+ # bang to the key name, like:
22
+ #
23
+ # h.dog! # => raises KeyError: key not found: :dog
24
+ #
17
25
  class OrderedOptions < Hash
18
26
  alias_method :_get, :[] # preserve the original #[] method
19
27
  protected :_get # make it protected
@@ -31,7 +39,13 @@ module ActiveSupport
31
39
  if name_string.chomp!('=')
32
40
  self[name_string] = args.first
33
41
  else
34
- self[name]
42
+ bangs = name_string.chomp!('!')
43
+
44
+ if bangs
45
+ fetch(name_string.to_sym).presence || raise(KeyError.new("#{name_string} is blank."))
46
+ else
47
+ self[name_string]
48
+ end
35
49
  end
36
50
  end
37
51
 
@@ -1,6 +1,9 @@
1
1
  require 'active_support/core_ext/module/delegation'
2
2
 
3
3
  module ActiveSupport
4
+ # NOTE: This approach has been deprecated for end-user code in favor of thread_mattr_accessor and friends.
5
+ # Please use that approach instead.
6
+ #
4
7
  # This module is used to encapsulate access to thread local variables.
5
8
  #
6
9
  # Instead of polluting the thread locals namespace:
@@ -1,8 +1,8 @@
1
1
  # This is private interface.
2
2
  #
3
3
  # Rails components cherry pick from Active Support as needed, but there are a
4
- # few features that are used for sure some way or another and it is not worth
5
- # to put individual requires absolutely everywhere. Think blank? for example.
4
+ # few features that are used for sure in some way or another and it is not worth
5
+ # putting individual requires absolutely everywhere. Think blank? for example.
6
6
  #
7
7
  # This file is loaded by every Rails component except Active Support itself,
8
8
  # but it does not belong to the Rails public interface. It is internal to
@@ -16,12 +16,17 @@ module ActiveSupport
16
16
  # Sets the default value for Time.zone
17
17
  # If assigned value cannot be matched to a TimeZone, an exception will be raised.
18
18
  initializer "active_support.initialize_time_zone" do |app|
19
+ begin
20
+ TZInfo::DataSource.get
21
+ rescue TZInfo::DataSourceNotFound => e
22
+ raise e.exception "tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install"
23
+ end
19
24
  require 'active_support/core_ext/time/zones'
20
25
  zone_default = Time.find_zone!(app.config.time_zone)
21
26
 
22
27
  unless zone_default
23
28
  raise 'Value assigned to config.time_zone not recognized. ' \
24
- 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
29
+ 'Run "rake time:zones:all" for a time zone names list.'
25
30
  end
26
31
 
27
32
  Time.zone_default = zone_default
@@ -60,7 +60,7 @@ module ActiveSupport
60
60
  end
61
61
 
62
62
  klasses.each do |klass|
63
- key = if klass.is_a?(Class) && klass <= Exception
63
+ key = if klass.is_a?(Module) && klass.respond_to?(:===)
64
64
  klass.name
65
65
  elsif klass.is_a?(String)
66
66
  klass
@@ -68,7 +68,7 @@ module ActiveSupport
68
68
  raise ArgumentError, "#{klass} is neither an Exception nor a String"
69
69
  end
70
70
 
71
- # put the new handler at the end because the list is read in reverse
71
+ # Put the new handler at the end because the list is read in reverse.
72
72
  self.rescue_handlers += [[key, options[:with]]]
73
73
  end
74
74
  end
@@ -100,8 +100,8 @@ module ActiveSupport
100
100
  # a string, otherwise a NameError will be raised by the interpreter
101
101
  # itself when rescue_from CONSTANT is executed.
102
102
  klass = self.class.const_get(klass_name) rescue nil
103
- klass ||= klass_name.constantize rescue nil
104
- exception.is_a?(klass) if klass
103
+ klass ||= (klass_name.constantize rescue nil)
104
+ klass === exception if klass
105
105
  end
106
106
 
107
107
  case rescuer
@@ -1,5 +1,3 @@
1
- require 'digest'
2
-
3
1
  module ActiveSupport
4
2
  module SecurityUtils
5
3
  # Constant time string comparison.
@@ -18,10 +16,5 @@ module ActiveSupport
18
16
  res == 0
19
17
  end
20
18
  module_function :secure_compare
21
-
22
- def variable_size_secure_compare(a, b) # :nodoc:
23
- secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b))
24
- end
25
- module_function :variable_size_secure_compare
26
19
  end
27
20
  end
@@ -1,7 +1,7 @@
1
1
  module ActiveSupport
2
2
  # Wrapping a string in this class gives you a prettier way to test
3
3
  # for equality. The value returned by <tt>Rails.env</tt> is wrapped
4
- # in a StringInquirer object so instead of calling this:
4
+ # in a StringInquirer object, so instead of calling this:
5
5
  #
6
6
  # Rails.env == 'production'
7
7
  #
@@ -5,24 +5,19 @@ module ActiveSupport
5
5
  # ActiveSupport::Notifications. The subscriber dispatches notifications to
6
6
  # a registered object based on its given namespace.
7
7
  #
8
- # An example would be Active Record subscriber responsible for collecting
8
+ # An example would be an Active Record subscriber responsible for collecting
9
9
  # statistics about queries:
10
10
  #
11
11
  # module ActiveRecord
12
12
  # class StatsSubscriber < ActiveSupport::Subscriber
13
+ # attach_to :active_record
14
+ #
13
15
  # def sql(event)
14
16
  # Statsd.timing("sql.#{event.payload[:name]}", event.duration)
15
17
  # end
16
18
  # end
17
19
  # end
18
20
  #
19
- # And it's finally registered as:
20
- #
21
- # ActiveRecord::StatsSubscriber.attach_to :active_record
22
- #
23
- # Since we need to know all instance methods before attaching the log
24
- # subscriber, the line above should be called after your subscriber definition.
25
- #
26
21
  # After configured, whenever a "sql.active_record" notification is published,
27
22
  # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
28
23
  # the +sql+ method.
@@ -66,7 +61,7 @@ module ActiveSupport
66
61
 
67
62
  pattern = "#{event}.#{namespace}"
68
63
 
69
- # don't add multiple subscribers (eg. if methods are redefined)
64
+ # Don't add multiple subscribers (eg. if methods are redefined).
70
65
  return if subscriber.patterns.include?(pattern)
71
66
 
72
67
  subscriber.patterns << pattern
@@ -96,7 +91,7 @@ module ActiveSupport
96
91
  event.end = finished
97
92
  event.payload.merge!(payload)
98
93
 
99
- method = name.split('.').first
94
+ method = name.split('.'.freeze).first
100
95
  send(method, event)
101
96
  end
102
97
 
@@ -43,7 +43,9 @@ module ActiveSupport
43
43
  end
44
44
 
45
45
  def current_tags
46
- Thread.current[:activesupport_tagged_logging_tags] ||= []
46
+ # We use our object ID here to avoid conflicting with other instances
47
+ thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}".freeze
48
+ Thread.current[thread_key] ||= []
47
49
  end
48
50
 
49
51
  private
@@ -8,8 +8,9 @@ require 'active_support/testing/declarative'
8
8
  require 'active_support/testing/isolation'
9
9
  require 'active_support/testing/constant_lookup'
10
10
  require 'active_support/testing/time_helpers'
11
+ require 'active_support/testing/file_fixtures'
12
+ require 'active_support/testing/composite_filter'
11
13
  require 'active_support/core_ext/kernel/reporting'
12
- require 'active_support/deprecation'
13
14
 
14
15
  module ActiveSupport
15
16
  class TestCase < ::Minitest::Test
@@ -31,36 +32,22 @@ module ActiveSupport
31
32
 
32
33
  # Returns the order in which test cases are run.
33
34
  #
34
- # ActiveSupport::TestCase.test_order # => :sorted
35
+ # ActiveSupport::TestCase.test_order # => :random
35
36
  #
36
37
  # Possible values are +:random+, +:parallel+, +:alpha+, +:sorted+.
37
- # Defaults to +:sorted+.
38
+ # Defaults to +:random+.
38
39
  def test_order
39
- test_order = ActiveSupport.test_order
40
-
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`."
40
+ ActiveSupport.test_order ||= :random
41
+ end
55
42
 
56
- test_order = :sorted
57
- self.test_order = test_order
43
+ def run(reporter, options = {})
44
+ if options[:patterns] && options[:patterns].any? { |p| p =~ /:\d+/ }
45
+ options[:filter] = \
46
+ Testing::CompositeFilter.new(self, options[:filter], options[:patterns])
58
47
  end
59
48
 
60
- test_order
49
+ super
61
50
  end
62
-
63
- alias :my_tests_are_order_dependent! :i_suck_and_my_tests_are_order_dependent!
64
51
  end
65
52
 
66
53
  alias_method :method_name, :name
@@ -70,6 +57,7 @@ module ActiveSupport
70
57
  include ActiveSupport::Testing::Assertions
71
58
  include ActiveSupport::Testing::Deprecation
72
59
  include ActiveSupport::Testing::TimeHelpers
60
+ include ActiveSupport::Testing::FileFixtures
73
61
  extend ActiveSupport::Testing::Declarative
74
62
 
75
63
  # test/unit backwards compatibility methods
@@ -88,7 +76,7 @@ module ActiveSupport
88
76
  alias :assert_not_respond_to :refute_respond_to
89
77
  alias :assert_not_same :refute_same
90
78
 
91
- # Fails if the block raises an exception.
79
+ # Reveals the intention that the block should not raise any exception.
92
80
  #
93
81
  # assert_nothing_raised do
94
82
  # ...
@@ -3,7 +3,7 @@ require 'active_support/core_ext/object/blank'
3
3
  module ActiveSupport
4
4
  module Testing
5
5
  module Assertions
6
- # Assert that an expression is not truthy. Passes if <tt>object</tt> is
6
+ # Asserts that an expression is not truthy. Passes if <tt>object</tt> is
7
7
  # +nil+ or +false+. "Truthy" means "considered true in a conditional"
8
8
  # like <tt>if foo</tt>.
9
9
  #
@@ -23,42 +23,42 @@ module ActiveSupport
23
23
  # result of what is evaluated in the yielded block.
24
24
  #
25
25
  # assert_difference 'Article.count' do
26
- # post :create, article: {...}
26
+ # post :create, params: { article: {...} }
27
27
  # end
28
28
  #
29
29
  # An arbitrary expression is passed in and evaluated.
30
30
  #
31
- # assert_difference 'assigns(:article).comments(:reload).size' do
32
- # post :create, comment: {...}
31
+ # assert_difference 'Article.last.comments(:reload).size' do
32
+ # post :create, params: { comment: {...} }
33
33
  # end
34
34
  #
35
35
  # An arbitrary positive or negative difference can be specified.
36
36
  # The default is <tt>1</tt>.
37
37
  #
38
38
  # assert_difference 'Article.count', -1 do
39
- # post :delete, id: ...
39
+ # post :delete, params: { id: ... }
40
40
  # end
41
41
  #
42
42
  # An array of expressions can also be passed in and evaluated.
43
43
  #
44
44
  # assert_difference [ 'Article.count', 'Post.count' ], 2 do
45
- # post :create, article: {...}
45
+ # post :create, params: { article: {...} }
46
46
  # end
47
47
  #
48
48
  # A lambda or a list of lambdas can be passed in and evaluated:
49
49
  #
50
50
  # assert_difference ->{ Article.count }, 2 do
51
- # post :create, article: {...}
51
+ # post :create, params: { article: {...} }
52
52
  # end
53
53
  #
54
54
  # assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
55
- # post :create, article: {...}
55
+ # post :create, params: { article: {...} }
56
56
  # end
57
57
  #
58
58
  # An error message can be specified.
59
59
  #
60
60
  # assert_difference 'Article.count', -1, 'An Article should be destroyed' do
61
- # post :delete, id: ...
61
+ # post :delete, params: { id: ... }
62
62
  # end
63
63
  def assert_difference(expression, difference = 1, message = nil, &block)
64
64
  expressions = Array(expression)
@@ -66,28 +66,30 @@ module ActiveSupport
66
66
  exps = expressions.map { |e|
67
67
  e.respond_to?(:call) ? e : lambda { eval(e, block.binding) }
68
68
  }
69
- before = exps.map { |e| e.call }
69
+ before = exps.map(&:call)
70
70
 
71
- yield
71
+ retval = yield
72
72
 
73
73
  expressions.zip(exps).each_with_index do |(code, e), i|
74
74
  error = "#{code.inspect} didn't change by #{difference}"
75
75
  error = "#{message}.\n#{error}" if message
76
76
  assert_equal(before[i] + difference, e.call, error)
77
77
  end
78
+
79
+ retval
78
80
  end
79
81
 
80
82
  # Assertion that the numeric result of evaluating an expression is not
81
83
  # changed before and after invoking the passed in block.
82
84
  #
83
85
  # assert_no_difference 'Article.count' do
84
- # post :create, article: invalid_attributes
86
+ # post :create, params: { article: invalid_attributes }
85
87
  # end
86
88
  #
87
89
  # An error message can be specified.
88
90
  #
89
91
  # assert_no_difference 'Article.count', 'An Article should not be created' do
90
- # post :create, article: invalid_attributes
92
+ # post :create, params: { article: invalid_attributes }
91
93
  # end
92
94
  def assert_no_difference(expression, message = nil, &block)
93
95
  assert_difference expression, 0, message, &block
@@ -2,4 +2,11 @@ gem 'minitest'
2
2
 
3
3
  require 'minitest'
4
4
 
5
- Minitest.autorun
5
+ if Minitest.respond_to?(:run_with_rails_extension)
6
+ unless Minitest.run_with_rails_extension
7
+ Minitest.run_with_autorun = true
8
+ Minitest.autorun
9
+ end
10
+ else
11
+ Minitest.autorun
12
+ end
@@ -0,0 +1,54 @@
1
+ require 'method_source'
2
+
3
+ module ActiveSupport
4
+ module Testing
5
+ class CompositeFilter # :nodoc:
6
+ def initialize(runnable, filter, patterns)
7
+ @runnable = runnable
8
+ @filters = [ derive_regexp(filter), *derive_line_filters(patterns) ].compact
9
+ end
10
+
11
+ def ===(method)
12
+ @filters.any? { |filter| filter === method }
13
+ end
14
+
15
+ private
16
+ def derive_regexp(filter)
17
+ filter =~ %r%/(.*)/% ? Regexp.new($1) : filter
18
+ end
19
+
20
+ def derive_line_filters(patterns)
21
+ patterns.map do |file_and_line|
22
+ file, line = file_and_line.split(':')
23
+ Filter.new(@runnable, file, line) if file
24
+ end
25
+ end
26
+
27
+ class Filter # :nodoc:
28
+ def initialize(runnable, file, line)
29
+ @runnable, @file = runnable, File.expand_path(file)
30
+ @line = line.to_i if line
31
+ end
32
+
33
+ def ===(method)
34
+ return unless @runnable.method_defined?(method)
35
+
36
+ if @line
37
+ test_file, test_range = definition_for(@runnable.instance_method(method))
38
+ test_file == @file && test_range.include?(@line)
39
+ else
40
+ @runnable.instance_method(method).source_location.first == @file
41
+ end
42
+ end
43
+
44
+ private
45
+ def definition_for(method)
46
+ file, start_line = method.source_location
47
+ end_line = method.source.count("\n") + start_line - 1
48
+
49
+ return file, start_line..end_line
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -3,8 +3,8 @@ require 'active_support/deprecation'
3
3
  module ActiveSupport
4
4
  module Testing
5
5
  module Deprecation #:nodoc:
6
- def assert_deprecated(match = nil, &block)
7
- result, warnings = collect_deprecations(&block)
6
+ def assert_deprecated(match = nil, deprecator = nil, &block)
7
+ result, warnings = collect_deprecations(deprecator, &block)
8
8
  assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
9
9
  if match
10
10
  match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
@@ -13,22 +13,23 @@ module ActiveSupport
13
13
  result
14
14
  end
15
15
 
16
- def assert_not_deprecated(&block)
17
- result, deprecations = collect_deprecations(&block)
16
+ def assert_not_deprecated(deprecator = nil, &block)
17
+ result, deprecations = collect_deprecations(deprecator, &block)
18
18
  assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
19
19
  result
20
20
  end
21
21
 
22
- def collect_deprecations
23
- old_behavior = ActiveSupport::Deprecation.behavior
22
+ def collect_deprecations(deprecator = nil)
23
+ deprecator ||= ActiveSupport::Deprecation
24
+ old_behavior = deprecator.behavior
24
25
  deprecations = []
25
- ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
26
+ deprecator.behavior = Proc.new do |message, callstack|
26
27
  deprecations << message
27
28
  end
28
29
  result = yield
29
30
  [result, deprecations]
30
31
  ensure
31
- ActiveSupport::Deprecation.behavior = old_behavior
32
+ deprecator.behavior = old_behavior
32
33
  end
33
34
  end
34
35
  end