activesupport 4.2.11.1 → 5.2.8.1

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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +441 -399
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +4 -5
  5. data/lib/active_support/all.rb +5 -3
  6. data/lib/active_support/array_inquirer.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +7 -5
  8. data/lib/active_support/benchmarkable.rb +6 -4
  9. data/lib/active_support/builder.rb +3 -1
  10. data/lib/active_support/cache/file_store.rb +41 -35
  11. data/lib/active_support/cache/mem_cache_store.rb +91 -91
  12. data/lib/active_support/cache/memory_store.rb +27 -30
  13. data/lib/active_support/cache/null_store.rb +7 -8
  14. data/lib/active_support/cache/redis_cache_store.rb +466 -0
  15. data/lib/active_support/cache/strategy/local_cache.rb +67 -34
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  17. data/lib/active_support/cache.rb +287 -196
  18. data/lib/active_support/callbacks.rb +640 -590
  19. data/lib/active_support/concern.rb +11 -5
  20. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  21. data/lib/active_support/concurrency/share_lock.rb +227 -0
  22. data/lib/active_support/configurable.rb +8 -5
  23. data/lib/active_support/core_ext/array/access.rb +29 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +22 -18
  25. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  27. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
  29. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  30. data/lib/active_support/core_ext/array.rb +9 -6
  31. data/lib/active_support/core_ext/benchmark.rb +3 -1
  32. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  33. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  34. data/lib/active_support/core_ext/class/attribute.rb +41 -22
  35. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  36. data/lib/active_support/core_ext/class/subclasses.rb +20 -6
  37. data/lib/active_support/core_ext/class.rb +4 -3
  38. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  39. data/lib/active_support/core_ext/date/blank.rb +14 -0
  40. data/lib/active_support/core_ext/date/calculations.rb +11 -9
  41. data/lib/active_support/core_ext/date/conversions.rb +25 -23
  42. data/lib/active_support/core_ext/date/zones.rb +4 -2
  43. data/lib/active_support/core_ext/date.rb +6 -4
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
  47. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  48. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  49. data/lib/active_support/core_ext/date_time/calculations.rb +36 -18
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  51. data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
  52. data/lib/active_support/core_ext/date_time.rb +7 -5
  53. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  54. data/lib/active_support/core_ext/digest.rb +3 -0
  55. data/lib/active_support/core_ext/enumerable.rb +101 -33
  56. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  57. data/lib/active_support/core_ext/file.rb +3 -1
  58. data/lib/active_support/core_ext/hash/compact.rb +14 -9
  59. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  61. data/lib/active_support/core_ext/hash/except.rb +11 -8
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  63. data/lib/active_support/core_ext/hash/keys.rb +33 -27
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +8 -8
  66. data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
  67. data/lib/active_support/core_ext/hash.rb +11 -9
  68. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  69. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  70. data/lib/active_support/core_ext/integer/time.rb +11 -18
  71. data/lib/active_support/core_ext/integer.rb +5 -3
  72. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  74. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +6 -5
  77. data/lib/active_support/core_ext/load_error.rb +3 -22
  78. data/lib/active_support/core_ext/marshal.rb +8 -8
  79. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  80. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  81. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +11 -12
  85. data/lib/active_support/core_ext/module/delegation.rb +99 -29
  86. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  87. data/lib/active_support/core_ext/module/introspection.rb +9 -9
  88. data/lib/active_support/core_ext/module/reachable.rb +5 -2
  89. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  90. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  91. data/lib/active_support/core_ext/module.rb +14 -11
  92. data/lib/active_support/core_ext/name_error.rb +22 -2
  93. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  94. data/lib/active_support/core_ext/numeric/conversions.rb +78 -81
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  97. data/lib/active_support/core_ext/numeric.rb +6 -3
  98. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  99. data/lib/active_support/core_ext/object/blank.rb +27 -2
  100. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  101. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  102. data/lib/active_support/core_ext/object/duplicable.rb +41 -14
  103. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  104. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  105. data/lib/active_support/core_ext/object/json.rb +49 -19
  106. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  107. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  108. data/lib/active_support/core_ext/object/try.rb +69 -21
  109. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  110. data/lib/active_support/core_ext/object.rb +14 -13
  111. data/lib/active_support/core_ext/range/compare_range.rb +61 -0
  112. data/lib/active_support/core_ext/range/conversions.rb +27 -7
  113. data/lib/active_support/core_ext/range/each.rb +19 -17
  114. data/lib/active_support/core_ext/range/include_range.rb +2 -22
  115. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  116. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  117. data/lib/active_support/core_ext/range.rb +7 -4
  118. data/lib/active_support/core_ext/regexp.rb +6 -0
  119. data/lib/active_support/core_ext/securerandom.rb +25 -0
  120. data/lib/active_support/core_ext/string/access.rb +8 -6
  121. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  122. data/lib/active_support/core_ext/string/conversions.rb +7 -4
  123. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  124. data/lib/active_support/core_ext/string/filters.rb +6 -5
  125. data/lib/active_support/core_ext/string/indent.rb +6 -4
  126. data/lib/active_support/core_ext/string/inflections.rb +61 -24
  127. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  128. data/lib/active_support/core_ext/string/multibyte.rb +15 -7
  129. data/lib/active_support/core_ext/string/output_safety.rb +62 -38
  130. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  131. data/lib/active_support/core_ext/string/strip.rb +4 -5
  132. data/lib/active_support/core_ext/string/zones.rb +4 -2
  133. data/lib/active_support/core_ext/string.rb +15 -13
  134. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  135. data/lib/active_support/core_ext/time/calculations.rb +85 -51
  136. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  137. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  138. data/lib/active_support/core_ext/time/zones.rb +41 -7
  139. data/lib/active_support/core_ext/time.rb +7 -6
  140. data/lib/active_support/core_ext/uri.rb +6 -8
  141. data/lib/active_support/core_ext.rb +3 -1
  142. data/lib/active_support/current_attributes.rb +195 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies.rb +152 -161
  146. data/lib/active_support/deprecation/behaviors.rb +44 -11
  147. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  149. data/lib/active_support/deprecation/method_wrappers.rb +66 -20
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
  151. data/lib/active_support/deprecation/reporting.rb +32 -12
  152. data/lib/active_support/deprecation.rb +12 -9
  153. data/lib/active_support/descendants_tracker.rb +2 -0
  154. data/lib/active_support/digest.rb +20 -0
  155. data/lib/active_support/duration/iso8601_parser.rb +125 -0
  156. data/lib/active_support/duration/iso8601_serializer.rb +55 -0
  157. data/lib/active_support/duration.rb +314 -38
  158. data/lib/active_support/encrypted_configuration.rb +49 -0
  159. data/lib/active_support/encrypted_file.rb +99 -0
  160. data/lib/active_support/evented_file_update_checker.rb +205 -0
  161. data/lib/active_support/execution_wrapper.rb +131 -0
  162. data/lib/active_support/executor.rb +8 -0
  163. data/lib/active_support/file_update_checker.rb +63 -37
  164. data/lib/active_support/gem_version.rb +5 -3
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +123 -28
  167. data/lib/active_support/i18n.rb +8 -6
  168. data/lib/active_support/i18n_railtie.rb +37 -13
  169. data/lib/active_support/inflections.rb +13 -11
  170. data/lib/active_support/inflector/inflections.rb +61 -12
  171. data/lib/active_support/inflector/methods.rb +163 -136
  172. data/lib/active_support/inflector/transliterate.rb +48 -27
  173. data/lib/active_support/inflector.rb +7 -5
  174. data/lib/active_support/json/decoding.rb +16 -13
  175. data/lib/active_support/json/encoding.rb +11 -58
  176. data/lib/active_support/json.rb +4 -2
  177. data/lib/active_support/key_generator.rb +25 -25
  178. data/lib/active_support/lazy_load_hooks.rb +50 -20
  179. data/lib/active_support/locale/en.yml +2 -0
  180. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  181. data/lib/active_support/log_subscriber.rb +13 -10
  182. data/lib/active_support/logger.rb +8 -7
  183. data/lib/active_support/logger_silence.rb +6 -4
  184. data/lib/active_support/logger_thread_safe_level.rb +7 -5
  185. data/lib/active_support/message_encryptor.rb +168 -53
  186. data/lib/active_support/message_verifier.rb +150 -17
  187. data/lib/active_support/messages/metadata.rb +71 -0
  188. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  189. data/lib/active_support/messages/rotator.rb +56 -0
  190. data/lib/active_support/multibyte/chars.rb +36 -23
  191. data/lib/active_support/multibyte/unicode.rb +100 -96
  192. data/lib/active_support/multibyte.rb +4 -2
  193. data/lib/active_support/notifications/fanout.rb +11 -9
  194. data/lib/active_support/notifications/instrumenter.rb +27 -7
  195. data/lib/active_support/notifications.rb +11 -7
  196. data/lib/active_support/number_helper/number_converter.rb +13 -11
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/number_helper.rb +94 -68
  206. data/lib/active_support/option_merger.rb +3 -1
  207. data/lib/active_support/ordered_hash.rb +6 -4
  208. data/lib/active_support/ordered_options.rb +23 -5
  209. data/lib/active_support/per_thread_registry.rb +9 -4
  210. data/lib/active_support/proxy_object.rb +2 -0
  211. data/lib/active_support/rails.rb +16 -8
  212. data/lib/active_support/railtie.rb +43 -9
  213. data/lib/active_support/reloader.rb +131 -0
  214. data/lib/active_support/rescuable.rb +108 -53
  215. data/lib/active_support/security_utils.rb +15 -11
  216. data/lib/active_support/string_inquirer.rb +11 -3
  217. data/lib/active_support/subscriber.rb +21 -16
  218. data/lib/active_support/tagged_logging.rb +14 -11
  219. data/lib/active_support/test_case.rb +19 -47
  220. data/lib/active_support/testing/assertions.rb +137 -20
  221. data/lib/active_support/testing/autorun.rb +4 -2
  222. data/lib/active_support/testing/constant_lookup.rb +2 -1
  223. data/lib/active_support/testing/declarative.rb +3 -1
  224. data/lib/active_support/testing/deprecation.rb +14 -10
  225. data/lib/active_support/testing/file_fixtures.rb +36 -0
  226. data/lib/active_support/testing/isolation.rb +34 -25
  227. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  228. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  229. data/lib/active_support/testing/stream.rb +44 -0
  230. data/lib/active_support/testing/tagged_logging.rb +3 -1
  231. data/lib/active_support/testing/time_helpers.rb +81 -15
  232. data/lib/active_support/time.rb +14 -12
  233. data/lib/active_support/time_with_zone.rb +169 -39
  234. data/lib/active_support/values/time_zone.rb +196 -61
  235. data/lib/active_support/values/unicode_tables.dat +0 -0
  236. data/lib/active_support/version.rb +3 -1
  237. data/lib/active_support/xml_mini/jdom.rb +116 -114
  238. data/lib/active_support/xml_mini/libxml.rb +16 -13
  239. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  240. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  241. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  242. data/lib/active_support/xml_mini/rexml.rb +11 -9
  243. data/lib/active_support/xml_mini.rb +37 -37
  244. data/lib/active_support.rb +12 -11
  245. metadata +57 -27
  246. data/lib/active_support/concurrency/latch.rb +0 -27
  247. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  248. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  249. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  250. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  251. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  252. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  253. data/lib/active_support/core_ext/object/itself.rb +0 -15
  254. data/lib/active_support/core_ext/struct.rb +0 -6
  255. data/lib/active_support/core_ext/thread.rb +0 -86
  256. data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,34 +1,40 @@
1
- require 'erb'
2
- require 'active_support/core_ext/kernel/singleton_class'
3
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
2
+
3
+ require "erb"
4
+ require "active_support/core_ext/kernel/singleton_class"
5
+ require "active_support/core_ext/module/redefine_method"
6
+ require "active_support/multibyte/unicode"
4
7
 
5
8
  class ERB
6
9
  module Util
7
- HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
8
- JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
9
- HTML_ESCAPE_REGEXP = /[&"'><]/
10
+ HTML_ESCAPE = { "&" => "&amp;", ">" => "&gt;", "<" => "&lt;", '"' => "&quot;", "'" => "&#39;" }
11
+ JSON_ESCAPE = { "&" => '\u0026', ">" => '\u003e', "<" => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
10
12
  HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
11
13
  JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
12
14
 
15
+ # Following XML requirements: https://www.w3.org/TR/REC-xml/#NT-Name
16
+ TAG_NAME_START_REGEXP_SET = "@:A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \
17
+ "\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \
18
+ "\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}"
19
+ TAG_NAME_START_REGEXP = /[^#{TAG_NAME_START_REGEXP_SET}]/
20
+ TAG_NAME_FOLLOWING_REGEXP = /[^#{TAG_NAME_START_REGEXP_SET}\-.0-9\u{B7}\u{0300}-\u{036F}\u{203F}-\u{2040}]/
21
+ TAG_NAME_REPLACEMENT_CHAR = "_"
22
+
13
23
  # A utility method for escaping HTML tag characters.
14
24
  # This method is also aliased as <tt>h</tt>.
15
25
  #
16
- # In your ERB templates, use this method to escape any unsafe content. For example:
17
- # <%=h @person.name %>
18
- #
19
26
  # puts html_escape('is a > 0 & a < 10?')
20
27
  # # => is a &gt; 0 &amp; a &lt; 10?
21
28
  def html_escape(s)
22
29
  unwrapped_html_escape(s).html_safe
23
30
  end
24
31
 
25
- # Aliasing twice issues a warning "discarding old...". Remove first to avoid it.
26
- remove_method(:h)
32
+ silence_redefinition_of_method :h
27
33
  alias h html_escape
28
34
 
29
35
  module_function :h
30
36
 
31
- singleton_class.send(:remove_method, :html_escape)
37
+ singleton_class.silence_redefinition_of_method :html_escape
32
38
  module_function :html_escape
33
39
 
34
40
  # HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
@@ -38,7 +44,7 @@ class ERB
38
44
  if s.html_safe?
39
45
  s
40
46
  else
41
- s.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE)
47
+ CGI.escapeHTML(ActiveSupport::Multibyte::Unicode.tidy_bytes(s))
42
48
  end
43
49
  end
44
50
  module_function :unwrapped_html_escape
@@ -51,7 +57,7 @@ class ERB
51
57
  # html_escape_once('&lt;&lt; Accept & Checkout')
52
58
  # # => "&lt;&lt; Accept &amp; Checkout"
53
59
  def html_escape_once(s)
54
- result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
60
+ result = ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
55
61
  s.html_safe? ? result.html_safe : result
56
62
  end
57
63
 
@@ -86,6 +92,11 @@ class ERB
86
92
  # automatically flag the result as HTML safe, since the raw value is unsafe to
87
93
  # use inside HTML attributes.
88
94
  #
95
+ # If your JSON is being used downstream for insertion into the DOM, be aware of
96
+ # whether or not it is being inserted via +html()+. Most jQuery plugins do this.
97
+ # If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
98
+ # content returned by your JSON.
99
+ #
89
100
  # If you need to output JSON elsewhere in your HTML, you can just do something
90
101
  # like this, as any unsafe characters (including quotation marks) will be
91
102
  # automatically escaped for you:
@@ -113,6 +124,26 @@ class ERB
113
124
  end
114
125
 
115
126
  module_function :json_escape
127
+
128
+ # A utility method for escaping XML names of tags and names of attributes.
129
+ #
130
+ # xml_name_escape('1 < 2 & 3')
131
+ # # => "1___2___3"
132
+ #
133
+ # It follows the requirements of the specification: https://www.w3.org/TR/REC-xml/#NT-Name
134
+ def xml_name_escape(name)
135
+ name = name.to_s
136
+ return "" if name.blank?
137
+
138
+ starting_char = name[0].gsub(TAG_NAME_START_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
139
+
140
+ return starting_char if name.size == 1
141
+
142
+ following_chars = name[1..-1].gsub(TAG_NAME_FOLLOWING_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
143
+
144
+ starting_char + following_chars
145
+ end
146
+ module_function :xml_name_escape
116
147
  end
117
148
  end
118
149
 
@@ -138,27 +169,26 @@ module ActiveSupport #:nodoc:
138
169
  alias_method :original_concat, :concat
139
170
  private :original_concat
140
171
 
172
+ # Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
141
173
  class SafeConcatError < StandardError
142
174
  def initialize
143
- super 'Could not concatenate to the buffer because it is not html safe.'
175
+ super "Could not concatenate to the buffer because it is not html safe."
144
176
  end
145
177
  end
146
178
 
147
179
  def [](*args)
148
180
  if args.size < 2
149
181
  super
150
- else
151
- if html_safe?
152
- new_safe_buffer = super
182
+ elsif html_safe?
183
+ new_safe_buffer = super
153
184
 
154
- if new_safe_buffer
155
- new_safe_buffer.instance_variable_set :@html_safe, true
156
- end
157
-
158
- new_safe_buffer
159
- else
160
- to_str[*args]
185
+ if new_safe_buffer
186
+ new_safe_buffer.instance_variable_set :@html_safe, true
161
187
  end
188
+
189
+ new_safe_buffer
190
+ else
191
+ to_str[*args]
162
192
  end
163
193
  end
164
194
 
@@ -167,7 +197,7 @@ module ActiveSupport #:nodoc:
167
197
  original_concat(value)
168
198
  end
169
199
 
170
- def initialize(*)
200
+ def initialize(str = "")
171
201
  @html_safe = true
172
202
  super
173
203
  end
@@ -190,11 +220,6 @@ module ActiveSupport #:nodoc:
190
220
  super(html_escape_interpolated_argument(value))
191
221
  end
192
222
 
193
- def prepend!(value)
194
- ActiveSupport::Deprecation.deprecation_warning "ActiveSupport::SafeBuffer#prepend!", :prepend
195
- prepend value
196
- end
197
-
198
223
  def +(other)
199
224
  dup.concat(other)
200
225
  end
@@ -202,7 +227,7 @@ module ActiveSupport #:nodoc:
202
227
  def %(args)
203
228
  case args
204
229
  when Hash
205
- escaped_args = Hash[args.map { |k,arg| [k, html_escape_interpolated_argument(arg)] }]
230
+ escaped_args = Hash[args.map { |k, arg| [k, html_escape_interpolated_argument(arg)] }]
206
231
  else
207
232
  escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
208
233
  end
@@ -243,18 +268,17 @@ module ActiveSupport #:nodoc:
243
268
 
244
269
  private
245
270
 
246
- def html_escape_interpolated_argument(arg)
247
- (!html_safe? || arg.html_safe?) ? arg :
248
- arg.to_s.gsub(ERB::Util::HTML_ESCAPE_REGEXP, ERB::Util::HTML_ESCAPE)
249
- end
271
+ def html_escape_interpolated_argument(arg)
272
+ (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
273
+ end
250
274
  end
251
275
  end
252
276
 
253
277
  class String
254
278
  # Marks a string as trusted safe. It will be inserted into HTML with no
255
- # additional escaping performed. It is your responsibilty to ensure that the
279
+ # additional escaping performed. It is your responsibility to ensure that the
256
280
  # string contains no malicious content. This method is equivalent to the
257
- # `raw` helper in views. It is recommended that you use `sanitize` instead of
281
+ # +raw+ helper in views. It is recommended that you use +sanitize+ instead of
258
282
  # this method. It should never be called on user input.
259
283
  def html_safe
260
284
  ActiveSupport::SafeBuffer.new(self)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  alias_method :starts_with?, :start_with?
3
5
  alias_method :ends_with?, :end_with?
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/object/try'
1
+ # frozen_string_literal: true
2
2
 
3
3
  class String
4
4
  # Strips indentation in heredocs.
@@ -17,10 +17,9 @@ class String
17
17
  #
18
18
  # the user would see the usage message aligned against the left margin.
19
19
  #
20
- # Technically, it looks for the least indented line in the whole string, and removes
21
- # that amount of leading whitespace.
20
+ # Technically, it looks for the least indented non-empty line
21
+ # in the whole string, and removes that amount of leading whitespace.
22
22
  def strip_heredoc
23
- indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
24
- gsub(/^[ \t]{#{indent}}/, '')
23
+ gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "".freeze)
25
24
  end
26
25
  end
@@ -1,5 +1,7 @@
1
- require 'active_support/core_ext/string/conversions'
2
- require 'active_support/core_ext/time/zones'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/conversions"
4
+ require "active_support/core_ext/time/zones"
3
5
 
4
6
  class String
5
7
  # Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
@@ -1,13 +1,15 @@
1
- require 'active_support/core_ext/string/conversions'
2
- require 'active_support/core_ext/string/filters'
3
- require 'active_support/core_ext/string/multibyte'
4
- require 'active_support/core_ext/string/starts_ends_with'
5
- require 'active_support/core_ext/string/inflections'
6
- require 'active_support/core_ext/string/access'
7
- require 'active_support/core_ext/string/behavior'
8
- require 'active_support/core_ext/string/output_safety'
9
- require 'active_support/core_ext/string/exclude'
10
- require 'active_support/core_ext/string/strip'
11
- require 'active_support/core_ext/string/inquiry'
12
- require 'active_support/core_ext/string/indent'
13
- require 'active_support/core_ext/string/zones'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/conversions"
4
+ require "active_support/core_ext/string/filters"
5
+ require "active_support/core_ext/string/multibyte"
6
+ require "active_support/core_ext/string/starts_ends_with"
7
+ require "active_support/core_ext/string/inflections"
8
+ require "active_support/core_ext/string/access"
9
+ require "active_support/core_ext/string/behavior"
10
+ require "active_support/core_ext/string/output_safety"
11
+ require "active_support/core_ext/string/exclude"
12
+ require "active_support/core_ext/string/strip"
13
+ require "active_support/core_ext/string/inquiry"
14
+ require "active_support/core_ext/string/indent"
15
+ require "active_support/core_ext/string/zones"
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/object/acts_like'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/acts_like"
2
4
 
3
5
  class Time
4
6
  # Duck-types as a Time-like class. See Object#acts_like?.
@@ -1,9 +1,11 @@
1
- require 'active_support/duration'
2
- require 'active_support/core_ext/time/conversions'
3
- require 'active_support/time_with_zone'
4
- require 'active_support/core_ext/time/zones'
5
- require 'active_support/core_ext/date_and_time/calculations'
6
- require 'active_support/core_ext/date/calculations'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/duration"
4
+ require "active_support/core_ext/time/conversions"
5
+ require "active_support/time_with_zone"
6
+ require "active_support/core_ext/time/zones"
7
+ require "active_support/core_ext/date_and_time/calculations"
8
+ require "active_support/core_ext/date/calculations"
7
9
 
8
10
  class Time
9
11
  include DateAndTime::Calculations
@@ -16,9 +18,9 @@ class Time
16
18
  super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
17
19
  end
18
20
 
19
- # Return the number of days in the given month.
21
+ # Returns the number of days in the given month.
20
22
  # If no year is specified, it will use the current year.
21
- def days_in_month(month, year = now.year)
23
+ def days_in_month(month, year = current.year)
22
24
  if month == 2 && ::Date.gregorian_leap?(year)
23
25
  29
24
26
  else
@@ -26,6 +28,12 @@ class Time
26
28
  end
27
29
  end
28
30
 
31
+ # Returns the number of days in the given year.
32
+ # If no year is specified, it will use the current year.
33
+ def days_in_year(year = current.year)
34
+ days_in_month(2, year) + 337
35
+ end
36
+
29
37
  # Returns <tt>Time.zone.now</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns <tt>Time.now</tt>.
30
38
  def current
31
39
  ::Time.zone ? ::Time.zone.now : ::Time.now
@@ -47,11 +55,38 @@ class Time
47
55
  end
48
56
  alias_method :at_without_coercion, :at
49
57
  alias_method :at, :at_with_coercion
58
+
59
+ # Creates a +Time+ instance from an RFC 3339 string.
60
+ #
61
+ # Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
62
+ #
63
+ # If the time or offset components are missing then an +ArgumentError+ will be raised.
64
+ #
65
+ # Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
66
+ def rfc3339(str)
67
+ parts = Date._rfc3339(str)
68
+
69
+ raise ArgumentError, "invalid date" if parts.empty?
70
+
71
+ Time.new(
72
+ parts.fetch(:year),
73
+ parts.fetch(:mon),
74
+ parts.fetch(:mday),
75
+ parts.fetch(:hour),
76
+ parts.fetch(:min),
77
+ parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
78
+ parts.fetch(:offset)
79
+ )
80
+ end
50
81
  end
51
82
 
52
- # Seconds since midnight: Time.now.seconds_since_midnight
83
+ # Returns the number of seconds since 00:00:00.
84
+ #
85
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
86
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
87
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
53
88
  def seconds_since_midnight
54
- to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
89
+ to_i - change(hour: 0).to_i + (usec / 1.0e+6)
55
90
  end
56
91
 
57
92
  # Returns the number of seconds until 23:59:59.
@@ -74,36 +109,42 @@ class Time
74
109
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
75
110
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
76
111
  # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
77
- # and minute is passed, then sec, usec and nsec is set to 0. The +options+
78
- # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
79
- # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
80
- # <tt>:nsec</tt>. Path either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
112
+ # and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
113
+ # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
114
+ # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
115
+ # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
81
116
  #
82
117
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
83
118
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
84
119
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
85
120
  def change(options)
86
- new_year = options.fetch(:year, year)
87
- new_month = options.fetch(:month, month)
88
- new_day = options.fetch(:day, day)
89
- new_hour = options.fetch(:hour, hour)
90
- new_min = options.fetch(:min, options[:hour] ? 0 : min)
91
- new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
121
+ new_year = options.fetch(:year, year)
122
+ new_month = options.fetch(:month, month)
123
+ new_day = options.fetch(:day, day)
124
+ new_hour = options.fetch(:hour, hour)
125
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
126
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
127
+ new_offset = options.fetch(:offset, nil)
92
128
 
93
129
  if new_nsec = options[:nsec]
94
130
  raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
95
131
  new_usec = Rational(new_nsec, 1000)
96
132
  else
97
- new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
133
+ new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
98
134
  end
99
135
 
100
- if utc?
101
- ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
136
+ raise ArgumentError, "argument out of range" if new_usec >= 1000000
137
+
138
+ new_sec += Rational(new_usec, 1000000)
139
+
140
+ if new_offset
141
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
142
+ elsif utc?
143
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
102
144
  elsif zone
103
- ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
145
+ ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
104
146
  else
105
- raise ArgumentError, 'argument out of range' if new_usec >= 1000000
106
- ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
147
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
107
148
  end
108
149
  end
109
150
 
@@ -131,7 +172,7 @@ class Time
131
172
 
132
173
  d = to_date.advance(options)
133
174
  d = d.gregorian if d.julian?
134
- time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
175
+ time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
135
176
  seconds_to_advance = \
136
177
  options.fetch(:seconds, 0) +
137
178
  options.fetch(:minutes, 0) * 60 +
@@ -159,8 +200,7 @@ class Time
159
200
 
160
201
  # Returns a new Time representing the start of the day (0:00)
161
202
  def beginning_of_day
162
- #(self - seconds_since_midnight).change(usec: 0)
163
- change(:hour => 0)
203
+ change(hour: 0)
164
204
  end
165
205
  alias :midnight :beginning_of_day
166
206
  alias :at_midnight :beginning_of_day
@@ -168,7 +208,7 @@ class Time
168
208
 
169
209
  # Returns a new Time representing the middle of the day (12:00)
170
210
  def middle_of_day
171
- change(:hour => 12)
211
+ change(hour: 12)
172
212
  end
173
213
  alias :midday :middle_of_day
174
214
  alias :noon :middle_of_day
@@ -176,53 +216,48 @@ class Time
176
216
  alias :at_noon :middle_of_day
177
217
  alias :at_middle_of_day :middle_of_day
178
218
 
179
- # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
219
+ # Returns a new Time representing the end of the day, 23:59:59.999999
180
220
  def end_of_day
181
221
  change(
182
- :hour => 23,
183
- :min => 59,
184
- :sec => 59,
185
- :usec => Rational(999999999, 1000)
222
+ hour: 23,
223
+ min: 59,
224
+ sec: 59,
225
+ usec: Rational(999999999, 1000)
186
226
  )
187
227
  end
188
228
  alias :at_end_of_day :end_of_day
189
229
 
190
230
  # Returns a new Time representing the start of the hour (x:00)
191
231
  def beginning_of_hour
192
- change(:min => 0)
232
+ change(min: 0)
193
233
  end
194
234
  alias :at_beginning_of_hour :beginning_of_hour
195
235
 
196
- # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
236
+ # Returns a new Time representing the end of the hour, x:59:59.999999
197
237
  def end_of_hour
198
238
  change(
199
- :min => 59,
200
- :sec => 59,
201
- :usec => Rational(999999999, 1000)
239
+ min: 59,
240
+ sec: 59,
241
+ usec: Rational(999999999, 1000)
202
242
  )
203
243
  end
204
244
  alias :at_end_of_hour :end_of_hour
205
245
 
206
246
  # Returns a new Time representing the start of the minute (x:xx:00)
207
247
  def beginning_of_minute
208
- change(:sec => 0)
248
+ change(sec: 0)
209
249
  end
210
250
  alias :at_beginning_of_minute :beginning_of_minute
211
251
 
212
- # Returns a new Time representing the end of the minute, x:xx:59.999999 (.999999999 in ruby1.9)
252
+ # Returns a new Time representing the end of the minute, x:xx:59.999999
213
253
  def end_of_minute
214
254
  change(
215
- :sec => 59,
216
- :usec => Rational(999999999, 1000)
255
+ sec: 59,
256
+ usec: Rational(999999999, 1000)
217
257
  )
218
258
  end
219
259
  alias :at_end_of_minute :end_of_minute
220
260
 
221
- # Returns a Range representing the whole day of the current time.
222
- def all_day
223
- beginning_of_day..end_of_day
224
- end
225
-
226
261
  def plus_with_duration(other) #:nodoc:
227
262
  if ActiveSupport::Duration === other
228
263
  other.since(self)
@@ -256,7 +291,7 @@ class Time
256
291
  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
257
292
  # can be chronologically compared with a Time
258
293
  def compare_with_coercion(other)
259
- # we're avoiding Time#to_datetime cause it's expensive
294
+ # we're avoiding Time#to_datetime and Time#to_time because they're expensive
260
295
  if other.class == Time
261
296
  compare_without_coercion(other)
262
297
  elsif other.is_a?(Time)
@@ -277,5 +312,4 @@ class Time
277
312
  end
278
313
  alias_method :eql_without_coercion, :eql?
279
314
  alias_method :eql?, :eql_with_coercion
280
-
281
315
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/date_and_time/compatibility"
2
- require "active_support/core_ext/module/remove_method"
4
+ require "active_support/core_ext/module/redefine_method"
3
5
 
4
6
  class Time
5
7
  include DateAndTime::Compatibility
6
8
 
7
- remove_possible_method :to_time
9
+ silence_redefinition_of_method :to_time
8
10
 
9
11
  # Either return +self+ or the time in the local system timezone depending
10
12
  # on the setting of +ActiveSupport.to_time_preserves_timezone+.
@@ -1,30 +1,33 @@
1
- require 'active_support/inflector/methods'
2
- require 'active_support/values/time_zone'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/inflector/methods"
4
+ require "active_support/values/time_zone"
3
5
 
4
6
  class Time
5
7
  DATE_FORMATS = {
6
- :db => '%Y-%m-%d %H:%M:%S',
7
- :number => '%Y%m%d%H%M%S',
8
- :nsec => '%Y%m%d%H%M%S%9N',
9
- :time => '%H:%M',
10
- :short => '%d %b %H:%M',
11
- :long => '%B %d, %Y %H:%M',
12
- :long_ordinal => lambda { |time|
8
+ db: "%Y-%m-%d %H:%M:%S",
9
+ number: "%Y%m%d%H%M%S",
10
+ nsec: "%Y%m%d%H%M%S%9N",
11
+ usec: "%Y%m%d%H%M%S%6N",
12
+ time: "%H:%M",
13
+ short: "%d %b %H:%M",
14
+ long: "%B %d, %Y %H:%M",
15
+ long_ordinal: lambda { |time|
13
16
  day_format = ActiveSupport::Inflector.ordinalize(time.day)
14
17
  time.strftime("%B #{day_format}, %Y %H:%M")
15
18
  },
16
- :rfc822 => lambda { |time|
19
+ rfc822: lambda { |time|
17
20
  offset_format = time.formatted_offset(false)
18
21
  time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
19
22
  },
20
- :iso8601 => lambda { |time| time.iso8601 }
23
+ iso8601: lambda { |time| time.iso8601 }
21
24
  }
22
25
 
23
26
  # Converts to a formatted string. See DATE_FORMATS for built-in formats.
24
27
  #
25
28
  # This method is aliased to <tt>to_s</tt>.
26
29
  #
27
- # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
30
+ # time = Time.now # => 2007-01-18 06:10:17 -06:00
28
31
  #
29
32
  # time.to_formatted_s(:time) # => "06:10"
30
33
  # time.to_s(:time) # => "06:10"
@@ -55,11 +58,15 @@ class Time
55
58
  alias_method :to_default_s, :to_s
56
59
  alias_method :to_s, :to_formatted_s
57
60
 
58
- # Returns the UTC offset as an +HH:MM formatted string.
61
+ # Returns a formatted string of the offset from UTC, or an alternative
62
+ # string if the time zone is already UTC.
59
63
  #
60
64
  # Time.local(2000).formatted_offset # => "-06:00"
61
65
  # Time.local(2000).formatted_offset(false) # => "-0600"
62
66
  def formatted_offset(colon = true, alternate_utc_string = nil)
63
67
  utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
64
68
  end
69
+
70
+ # Aliased to +xmlschema+ for compatibility with +DateTime+
71
+ alias_method :rfc3339, :xmlschema
65
72
  end