activesupport 4.0.13 → 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.

Files changed (166) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +406 -418
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +7 -2
  5. data/lib/active_support/backtrace_cleaner.rb +8 -8
  6. data/lib/active_support/benchmarkable.rb +0 -10
  7. data/lib/active_support/cache/file_store.rb +32 -22
  8. data/lib/active_support/cache/mem_cache_store.rb +5 -7
  9. data/lib/active_support/cache/memory_store.rb +1 -0
  10. data/lib/active_support/cache/strategy/local_cache.rb +11 -30
  11. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  12. data/lib/active_support/cache.rb +75 -41
  13. data/lib/active_support/callbacks.rb +482 -261
  14. data/lib/active_support/concern.rb +23 -7
  15. data/lib/active_support/configurable.rb +1 -1
  16. data/lib/active_support/core_ext/array/access.rb +11 -1
  17. data/lib/active_support/core_ext/array/conversions.rb +2 -17
  18. data/lib/active_support/core_ext/array/grouping.rb +29 -12
  19. data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -2
  20. data/lib/active_support/core_ext/array.rb +0 -1
  21. data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -15
  22. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +16 -0
  23. data/lib/active_support/core_ext/class/attribute.rb +1 -2
  24. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -170
  25. data/lib/active_support/core_ext/class/delegating_attributes.rb +13 -8
  26. data/lib/active_support/core_ext/class/subclasses.rb +0 -2
  27. data/lib/active_support/core_ext/class.rb +0 -1
  28. data/lib/active_support/core_ext/date/calculations.rb +10 -0
  29. data/lib/active_support/core_ext/date/conversions.rb +9 -1
  30. data/lib/active_support/core_ext/date/zones.rb +2 -33
  31. data/lib/active_support/core_ext/date_and_time/calculations.rb +41 -11
  32. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  33. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  34. data/lib/active_support/core_ext/date_time/calculations.rb +45 -22
  35. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  36. data/lib/active_support/core_ext/date_time/conversions.rb +4 -2
  37. data/lib/active_support/core_ext/date_time/zones.rb +3 -21
  38. data/lib/active_support/core_ext/date_time.rb +1 -0
  39. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  40. data/lib/active_support/core_ext/enumerable.rb +17 -1
  41. data/lib/active_support/core_ext/file/atomic.rb +1 -1
  42. data/lib/active_support/core_ext/hash/compact.rb +24 -0
  43. data/lib/active_support/core_ext/hash/conversions.rb +9 -8
  44. data/lib/active_support/core_ext/hash/except.rb +8 -2
  45. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -0
  46. data/lib/active_support/core_ext/hash/keys.rb +25 -19
  47. data/lib/active_support/core_ext/hash/slice.rb +8 -2
  48. data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
  49. data/lib/active_support/core_ext/hash.rb +2 -1
  50. data/lib/active_support/core_ext/integer/time.rb +0 -15
  51. data/lib/active_support/core_ext/kernel/concern.rb +10 -0
  52. data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
  53. data/lib/active_support/core_ext/kernel/reporting.rb +13 -2
  54. data/lib/active_support/core_ext/kernel.rb +3 -2
  55. data/lib/active_support/core_ext/load_error.rb +4 -1
  56. data/lib/active_support/core_ext/marshal.rb +8 -5
  57. data/lib/active_support/core_ext/module/aliasing.rb +2 -2
  58. data/lib/active_support/core_ext/module/attr_internal.rb +2 -1
  59. data/lib/active_support/core_ext/module/attribute_accessors.rb +160 -14
  60. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  61. data/lib/active_support/core_ext/module/delegation.rb +53 -25
  62. data/lib/active_support/core_ext/module/deprecation.rb +0 -2
  63. data/lib/active_support/core_ext/module/introspection.rb +0 -16
  64. data/lib/active_support/core_ext/module/method_transplanting.rb +13 -0
  65. data/lib/active_support/core_ext/module.rb +1 -0
  66. data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
  67. data/lib/active_support/core_ext/numeric/time.rb +4 -29
  68. data/lib/active_support/core_ext/object/blank.rb +44 -18
  69. data/lib/active_support/core_ext/object/deep_dup.rb +6 -6
  70. data/lib/active_support/core_ext/object/duplicable.rb +72 -33
  71. data/lib/active_support/core_ext/object/inclusion.rb +16 -15
  72. data/lib/active_support/core_ext/object/itself.rb +15 -0
  73. data/lib/active_support/core_ext/object/json.rb +197 -0
  74. data/lib/active_support/core_ext/object/to_query.rb +14 -6
  75. data/lib/active_support/core_ext/object/try.rb +36 -14
  76. data/lib/active_support/core_ext/object/with_options.rb +30 -3
  77. data/lib/active_support/core_ext/object.rb +2 -1
  78. data/lib/active_support/core_ext/string/access.rb +35 -35
  79. data/lib/active_support/core_ext/string/conversions.rb +10 -9
  80. data/lib/active_support/core_ext/string/exclude.rb +3 -3
  81. data/lib/active_support/core_ext/string/filters.rb +51 -3
  82. data/lib/active_support/core_ext/string/inflections.rb +15 -10
  83. data/lib/active_support/core_ext/string/output_safety.rb +97 -33
  84. data/lib/active_support/core_ext/string/zones.rb +1 -0
  85. data/lib/active_support/core_ext/thread.rb +12 -5
  86. data/lib/active_support/core_ext/time/calculations.rb +47 -68
  87. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  88. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  89. data/lib/active_support/core_ext/time/zones.rb +2 -20
  90. data/lib/active_support/core_ext/time.rb +1 -0
  91. data/lib/active_support/core_ext.rb +0 -1
  92. data/lib/active_support/dependencies/autoload.rb +1 -1
  93. data/lib/active_support/dependencies.rb +64 -25
  94. data/lib/active_support/deprecation/behaviors.rb +4 -4
  95. data/lib/active_support/deprecation.rb +4 -4
  96. data/lib/active_support/duration.rb +55 -11
  97. data/lib/active_support/file_update_checker.rb +1 -1
  98. data/lib/active_support/gem_version.rb +15 -0
  99. data/lib/active_support/hash_with_indifferent_access.rb +39 -11
  100. data/lib/active_support/i18n.rb +4 -4
  101. data/lib/active_support/i18n_railtie.rb +1 -7
  102. data/lib/active_support/inflections.rb +6 -1
  103. data/lib/active_support/inflector/inflections.rb +19 -19
  104. data/lib/active_support/inflector/methods.rb +66 -25
  105. data/lib/active_support/json/decoding.rb +15 -22
  106. data/lib/active_support/json/encoding.rb +125 -286
  107. data/lib/active_support/key_generator.rb +8 -10
  108. data/lib/active_support/lazy_load_hooks.rb +1 -1
  109. data/lib/active_support/log_subscriber/test_helper.rb +1 -1
  110. data/lib/active_support/logger.rb +51 -1
  111. data/lib/active_support/logger_silence.rb +7 -4
  112. data/lib/active_support/logger_thread_safe_level.rb +32 -0
  113. data/lib/active_support/message_encryptor.rb +14 -6
  114. data/lib/active_support/message_verifier.rb +16 -12
  115. data/lib/active_support/multibyte/chars.rb +2 -3
  116. data/lib/active_support/multibyte/unicode.rb +46 -58
  117. data/lib/active_support/notifications/fanout.rb +12 -7
  118. data/lib/active_support/notifications/instrumenter.rb +2 -1
  119. data/lib/active_support/notifications.rb +11 -6
  120. data/lib/active_support/number_helper/number_converter.rb +182 -0
  121. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  122. data/lib/active_support/number_helper/number_to_delimited_converter.rb +23 -0
  123. data/lib/active_support/number_helper/number_to_human_converter.rb +66 -0
  124. data/lib/active_support/number_helper/number_to_human_size_converter.rb +58 -0
  125. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  126. data/lib/active_support/number_helper/number_to_phone_converter.rb +49 -0
  127. data/lib/active_support/number_helper/number_to_rounded_converter.rb +87 -0
  128. data/lib/active_support/number_helper.rb +32 -324
  129. data/lib/active_support/ordered_options.rb +8 -0
  130. data/lib/active_support/per_thread_registry.rb +13 -10
  131. data/lib/active_support/security_utils.rb +27 -0
  132. data/lib/active_support/subscriber.rb +35 -3
  133. data/lib/active_support/test_case.rb +52 -19
  134. data/lib/active_support/testing/assertions.rb +1 -31
  135. data/lib/active_support/testing/autorun.rb +2 -2
  136. data/lib/active_support/testing/constant_lookup.rb +1 -5
  137. data/lib/active_support/testing/declarative.rb +7 -21
  138. data/lib/active_support/testing/isolation.rb +29 -69
  139. data/lib/active_support/testing/setup_and_teardown.rb +17 -2
  140. data/lib/active_support/testing/tagged_logging.rb +2 -2
  141. data/lib/active_support/testing/time_helpers.rb +134 -0
  142. data/lib/active_support/time.rb +0 -2
  143. data/lib/active_support/time_with_zone.rb +60 -40
  144. data/lib/active_support/values/time_zone.rb +101 -101
  145. data/lib/active_support/values/unicode_tables.dat +0 -0
  146. data/lib/active_support/version.rb +4 -7
  147. data/lib/active_support/xml_mini/jdom.rb +6 -5
  148. data/lib/active_support/xml_mini/libxml.rb +1 -3
  149. data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
  150. data/lib/active_support/xml_mini/nokogiri.rb +1 -3
  151. data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
  152. data/lib/active_support/xml_mini/rexml.rb +7 -8
  153. data/lib/active_support/xml_mini.rb +33 -15
  154. data/lib/active_support.rb +27 -2
  155. metadata +43 -43
  156. data/lib/active_support/basic_object.rb +0 -11
  157. data/lib/active_support/buffered_logger.rb +0 -21
  158. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  159. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  160. data/lib/active_support/core_ext/logger.rb +0 -67
  161. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  162. data/lib/active_support/core_ext/proc.rb +0 -17
  163. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  164. data/lib/active_support/file_watcher.rb +0 -36
  165. data/lib/active_support/json/variable.rb +0 -18
  166. data/lib/active_support/testing/pending.rb +0 -14
@@ -1,3 +1,5 @@
1
+ require 'tzinfo'
2
+ require 'thread_safe'
1
3
  require 'active_support/core_ext/object/blank'
2
4
  require 'active_support/core_ext/object/try'
3
5
 
@@ -109,9 +111,11 @@ module ActiveSupport
109
111
  "Jerusalem" => "Asia/Jerusalem",
110
112
  "Harare" => "Africa/Harare",
111
113
  "Pretoria" => "Africa/Johannesburg",
114
+ "Kaliningrad" => "Europe/Kaliningrad",
112
115
  "Moscow" => "Europe/Moscow",
113
116
  "St. Petersburg" => "Europe/Moscow",
114
- "Volgograd" => "Europe/Moscow",
117
+ "Volgograd" => "Europe/Volgograd",
118
+ "Samara" => "Europe/Samara",
115
119
  "Kuwait" => "Asia/Kuwait",
116
120
  "Riyadh" => "Asia/Riyadh",
117
121
  "Nairobi" => "Africa/Nairobi",
@@ -168,6 +172,7 @@ module ActiveSupport
168
172
  "Guam" => "Pacific/Guam",
169
173
  "Port Moresby" => "Pacific/Port_Moresby",
170
174
  "Magadan" => "Asia/Magadan",
175
+ "Srednekolymsk" => "Asia/Srednekolymsk",
171
176
  "Solomon Is." => "Pacific/Guadalcanal",
172
177
  "New Caledonia" => "Pacific/Noumea",
173
178
  "Fiji" => "Pacific/Fiji",
@@ -182,18 +187,76 @@ module ActiveSupport
182
187
  }
183
188
 
184
189
  UTC_OFFSET_WITH_COLON = '%s%02d:%02d'
185
- UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.sub(':', '')
190
+ UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.tr(':', '')
186
191
 
187
- # Assumes self represents an offset from UTC in seconds (as returned from
188
- # Time#utc_offset) and turns this into an +HH:MM formatted string.
189
- #
190
- # TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00"
191
- def self.seconds_to_utc_offset(seconds, colon = true)
192
- format = colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON
193
- sign = (seconds < 0 ? '-' : '+')
194
- hours = seconds.abs / 3600
195
- minutes = (seconds.abs % 3600) / 60
196
- format % [sign, hours, minutes]
192
+ @lazy_zones_map = ThreadSafe::Cache.new
193
+
194
+ class << self
195
+ # Assumes self represents an offset from UTC in seconds (as returned from
196
+ # Time#utc_offset) and turns this into an +HH:MM formatted string.
197
+ #
198
+ # TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00"
199
+ def seconds_to_utc_offset(seconds, colon = true)
200
+ format = colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON
201
+ sign = (seconds < 0 ? '-' : '+')
202
+ hours = seconds.abs / 3600
203
+ minutes = (seconds.abs % 3600) / 60
204
+ format % [sign, hours, minutes]
205
+ end
206
+
207
+ def find_tzinfo(name)
208
+ TZInfo::TimezoneProxy.new(MAPPING[name] || name)
209
+ end
210
+
211
+ alias_method :create, :new
212
+
213
+ # Returns a TimeZone instance with the given name, or +nil+ if no
214
+ # such TimeZone instance exists. (This exists to support the use of
215
+ # this class with the +composed_of+ macro.)
216
+ def new(name)
217
+ self[name]
218
+ end
219
+
220
+ # Returns an array of all TimeZone objects. There are multiple
221
+ # TimeZone objects per time zone, in many cases, to make it easier
222
+ # for users to find their own time zone.
223
+ def all
224
+ @zones ||= zones_map.values.sort
225
+ end
226
+
227
+ def zones_map #:nodoc:
228
+ @zones_map ||= begin
229
+ MAPPING.each_key {|place| self[place]} # load all the zones
230
+ @lazy_zones_map
231
+ end
232
+ end
233
+
234
+ # Locate a specific time zone object. If the argument is a string, it
235
+ # is interpreted to mean the name of the timezone to locate. If it is a
236
+ # numeric value it is either the hour offset, or the second offset, of the
237
+ # timezone to find. (The first one with that offset will be returned.)
238
+ # Returns +nil+ if no such time zone is known to the system.
239
+ def [](arg)
240
+ case arg
241
+ when String
242
+ begin
243
+ @lazy_zones_map[arg] ||= create(arg).tap { |tz| tz.utc_offset }
244
+ rescue TZInfo::InvalidTimezoneIdentifier
245
+ nil
246
+ end
247
+ when Numeric, ActiveSupport::Duration
248
+ arg *= 3600 if arg.abs <= 13
249
+ all.find { |z| z.utc_offset == arg.to_i }
250
+ else
251
+ raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}"
252
+ end
253
+ end
254
+
255
+ # A convenience method for returning a collection of TimeZone objects
256
+ # for time zones in the USA.
257
+ def us_zones
258
+ @us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }
259
+ end
197
260
  end
198
261
 
199
262
  include Comparable
@@ -205,12 +268,13 @@ module ActiveSupport
205
268
  # (GMT). Seconds were chosen as the offset unit because that is the unit
206
269
  # that Ruby uses to represent time zone offsets (see Time#utc_offset).
207
270
  def initialize(name, utc_offset = nil, tzinfo = nil)
208
- self.class.send(:require_tzinfo)
209
-
210
271
  @name = name
211
272
  @utc_offset = utc_offset
212
273
  @tzinfo = tzinfo || TimeZone.find_tzinfo(name)
213
- @current_period = nil
274
+ end
275
+
276
+ def init_with(coder) #:nodoc:
277
+ initialize(coder['name'])
214
278
  end
215
279
 
216
280
  # Returns the offset of this time zone from UTC in seconds.
@@ -218,8 +282,7 @@ module ActiveSupport
218
282
  if @utc_offset
219
283
  @utc_offset
220
284
  else
221
- @current_period ||= tzinfo.try(:current_period)
222
- @current_period.try(:utc_offset)
285
+ tzinfo.current_period.utc_offset if tzinfo && tzinfo.current_period
223
286
  end
224
287
  end
225
288
 
@@ -280,6 +343,11 @@ module ActiveSupport
280
343
  #
281
344
  # Time.zone.now # => Fri, 31 Dec 1999 14:00:00 HST -10:00
282
345
  # Time.zone.parse('22:30:00') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
346
+ #
347
+ # However, if the date component is not provided, but any other upper
348
+ # components are supplied, then the day of the month defaults to 1:
349
+ #
350
+ # Time.zone.parse('Mar 2000') # => Wed, 01 Mar 2000 00:00:00 HST -10:00
283
351
  def parse(str, now=now())
284
352
  parts = Date._parse(str, false)
285
353
  return if parts.empty?
@@ -287,7 +355,7 @@ module ActiveSupport
287
355
  time = Time.new(
288
356
  parts.fetch(:year, now.year),
289
357
  parts.fetch(:mon, now.month),
290
- parts.fetch(:mday, now.day),
358
+ parts.fetch(:mday, parts[:year] || parts[:mon] ? 1 : now.day),
291
359
  parts.fetch(:hour, 0),
292
360
  parts.fetch(:min, 0),
293
361
  parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
@@ -315,6 +383,16 @@ module ActiveSupport
315
383
  tzinfo.now.to_date
316
384
  end
317
385
 
386
+ # Returns the next date in this time zone.
387
+ def tomorrow
388
+ today + 1
389
+ end
390
+
391
+ # Returns the previous date in this time zone.
392
+ def yesterday
393
+ today - 1
394
+ end
395
+
318
396
  # Adjust the given time to the simultaneous time in the time zone
319
397
  # represented by +self+. Returns a Time.utc() instance -- if you want an
320
398
  # ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead.
@@ -340,91 +418,13 @@ module ActiveSupport
340
418
  tzinfo.period_for_local(time, dst)
341
419
  end
342
420
 
343
- def self.find_tzinfo(name)
344
- TZInfo::TimezoneProxy.new(MAPPING[name] || name)
345
- end
346
-
347
- class << self
348
- alias_method :create, :new
349
-
350
- # Return a TimeZone instance with the given name, or +nil+ if no
351
- # such TimeZone instance exists. (This exists to support the use of
352
- # this class with the +composed_of+ macro.)
353
- def new(name)
354
- self[name]
355
- end
356
-
357
- # Return an array of all TimeZone objects. There are multiple
358
- # TimeZone objects per time zone, in many cases, to make it easier
359
- # for users to find their own time zone.
360
- def all
361
- @zones ||= zones_map.values.sort
362
- end
363
-
364
- def zones_map
365
- @zones_map ||= begin
366
- new_zones_names = MAPPING.keys - lazy_zones_map.keys
367
- new_zones = Hash[new_zones_names.map { |place| [place, create(place)] }]
368
-
369
- lazy_zones_map.merge(new_zones)
370
- end
371
- end
372
-
373
- # Locate a specific time zone object. If the argument is a string, it
374
- # is interpreted to mean the name of the timezone to locate. If it is a
375
- # numeric value it is either the hour offset, or the second offset, of the
376
- # timezone to find. (The first one with that offset will be returned.)
377
- # Returns +nil+ if no such time zone is known to the system.
378
- def [](arg)
379
- case arg
380
- when String
381
- begin
382
- lazy_zones_map[arg] ||= lookup(arg).tap { |tz| tz.utc_offset }
383
- rescue TZInfo::InvalidTimezoneIdentifier
384
- nil
385
- end
386
- when Numeric, ActiveSupport::Duration
387
- arg *= 3600 if arg.abs <= 13
388
- all.find { |z| z.utc_offset == arg.to_i }
389
- else
390
- raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}"
391
- end
392
- end
393
-
394
- # A convenience method for returning a collection of TimeZone objects
395
- # for time zones in the USA.
396
- def us_zones
397
- @us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }
398
- end
399
-
400
- protected
401
-
402
- def require_tzinfo
403
- require 'tzinfo' unless defined?(::TZInfo)
404
- rescue LoadError
405
- $stderr.puts "You don't have tzinfo installed in your application. Please add it to your Gemfile and run bundle install"
406
- raise
407
- end
408
-
409
- private
410
-
411
- def lookup(name)
412
- (tzinfo = find_tzinfo(name)) && create(tzinfo.name.freeze)
413
- end
414
-
415
- def lazy_zones_map
416
- require_tzinfo
417
-
418
- @lazy_zones_map ||= Hash.new do |hash, place|
419
- hash[place] = create(place) if MAPPING.has_key?(place)
420
- end
421
- end
421
+ def periods_for_local(time) #:nodoc:
422
+ tzinfo.periods_for_local(time)
422
423
  end
423
424
 
424
425
  private
425
-
426
- def time_now
427
- Time.now
428
- end
426
+ def time_now
427
+ Time.now
428
+ end
429
429
  end
430
430
  end
@@ -1,11 +1,8 @@
1
+ require_relative 'gem_version'
2
+
1
3
  module ActiveSupport
2
- # Returns the version of the currently loaded ActiveSupport as a Gem::Version
4
+ # Returns the version of the currently loaded ActiveSupport as a <tt>Gem::Version</tt>
3
5
  def self.version
4
- Gem::Version.new "4.0.13"
5
- end
6
-
7
- module VERSION #:nodoc:
8
- MAJOR, MINOR, TINY, PRE = ActiveSupport.version.segments
9
- STRING = ActiveSupport.version.to_s
6
+ gem_version
10
7
  end
11
8
  end
@@ -46,7 +46,7 @@ module ActiveSupport
46
46
  xml_string_reader = StringReader.new(data)
47
47
  xml_input_source = InputSource.new(xml_string_reader)
48
48
  doc = @dbf.new_document_builder.parse(xml_input_source)
49
- merge_element!({CONTENT_KEY => ''}, doc.document_element)
49
+ merge_element!({CONTENT_KEY => ''}, doc.document_element, XmlMini.depth)
50
50
  end
51
51
  end
52
52
 
@@ -58,9 +58,10 @@ module ActiveSupport
58
58
  # Hash to merge the converted element into.
59
59
  # element::
60
60
  # XML element to merge into hash
61
- def merge_element!(hash, element)
61
+ def merge_element!(hash, element, depth)
62
+ raise 'Document too deep!' if depth == 0
62
63
  delete_empty(hash)
63
- merge!(hash, element.tag_name, collapse(element))
64
+ merge!(hash, element.tag_name, collapse(element, depth))
64
65
  end
65
66
 
66
67
  def delete_empty(hash)
@@ -71,14 +72,14 @@ module ActiveSupport
71
72
  #
72
73
  # element::
73
74
  # The document element to be collapsed.
74
- def collapse(element)
75
+ def collapse(element, depth)
75
76
  hash = get_attributes(element)
76
77
 
77
78
  child_nodes = element.child_nodes
78
79
  if child_nodes.length > 0
79
80
  (0...child_nodes.length).each do |i|
80
81
  child = child_nodes.item(i)
81
- merge_element!(hash, child) unless child.node_type == Node.TEXT_NODE
82
+ merge_element!(hash, child, depth - 1) unless child.node_type == Node.TEXT_NODE
82
83
  end
83
84
  merge_texts!(hash, element) unless empty_content?(element)
84
85
  hash
@@ -14,11 +14,9 @@ module ActiveSupport
14
14
  data = StringIO.new(data || '')
15
15
  end
16
16
 
17
- char = data.getc
18
- if char.nil?
17
+ if data.eof?
19
18
  {}
20
19
  else
21
- data.ungetc(char)
22
20
  LibXML::XML::Parser.io(data).parse.to_hash
23
21
  end
24
22
  end
@@ -66,12 +66,9 @@ module ActiveSupport
66
66
  data = StringIO.new(data || '')
67
67
  end
68
68
 
69
- char = data.getc
70
- if char.nil?
69
+ if data.eof?
71
70
  {}
72
71
  else
73
- data.ungetc(char)
74
-
75
72
  LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER)
76
73
  parser = LibXML::XML::SaxParser.io(data)
77
74
  document = self.document_class.new
@@ -19,11 +19,9 @@ module ActiveSupport
19
19
  data = StringIO.new(data || '')
20
20
  end
21
21
 
22
- char = data.getc
23
- if char.nil?
22
+ if data.eof?
24
23
  {}
25
24
  else
26
- data.ungetc(char)
27
25
  doc = Nokogiri::XML(data)
28
26
  raise doc.errors.first if doc.errors.length > 0
29
27
  doc.to_hash
@@ -72,11 +72,9 @@ module ActiveSupport
72
72
  data = StringIO.new(data || '')
73
73
  end
74
74
 
75
- char = data.getc
76
- if char.nil?
75
+ if data.eof?
77
76
  {}
78
77
  else
79
- data.ungetc(char)
80
78
  document = self.document_class.new
81
79
  parser = Nokogiri::XML::SAX::Parser.new(document)
82
80
  parser.parse(data)
@@ -20,16 +20,14 @@ module ActiveSupport
20
20
  data = StringIO.new(data || '')
21
21
  end
22
22
 
23
- char = data.getc
24
- if char.nil?
23
+ if data.eof?
25
24
  {}
26
25
  else
27
- data.ungetc(char)
28
26
  silence_warnings { require 'rexml/document' } unless defined?(REXML::Document)
29
27
  doc = REXML::Document.new(data)
30
28
 
31
29
  if doc.root
32
- merge_element!({}, doc.root)
30
+ merge_element!({}, doc.root, XmlMini.depth)
33
31
  else
34
32
  raise REXML::ParseException,
35
33
  "The document #{doc.to_s.inspect} does not have a valid root"
@@ -44,19 +42,20 @@ module ActiveSupport
44
42
  # Hash to merge the converted element into.
45
43
  # element::
46
44
  # XML element to merge into hash
47
- def merge_element!(hash, element)
48
- merge!(hash, element.name, collapse(element))
45
+ def merge_element!(hash, element, depth)
46
+ raise REXML::ParseException, "The document is too deep" if depth == 0
47
+ merge!(hash, element.name, collapse(element, depth))
49
48
  end
50
49
 
51
50
  # Actually converts an XML document element into a data structure.
52
51
  #
53
52
  # element::
54
53
  # The document element to be collapsed.
55
- def collapse(element)
54
+ def collapse(element, depth)
56
55
  hash = get_attributes(element)
57
56
 
58
57
  if element.has_elements?
59
- element.each_element {|child| merge_element!(hash, child) }
58
+ element.each_element {|child| merge_element!(hash, child, depth - 1) }
60
59
  merge_texts!(hash, element) unless empty_content?(element)
61
60
  hash
62
61
  else
@@ -32,20 +32,25 @@ module ActiveSupport
32
32
  "binary" => "base64"
33
33
  } unless defined?(DEFAULT_ENCODINGS)
34
34
 
35
- TYPE_NAMES = {
36
- "Symbol" => "symbol",
37
- "Fixnum" => "integer",
38
- "Bignum" => "integer",
39
- "BigDecimal" => "decimal",
40
- "Float" => "float",
41
- "TrueClass" => "boolean",
42
- "FalseClass" => "boolean",
43
- "Date" => "date",
44
- "DateTime" => "dateTime",
45
- "Time" => "dateTime",
46
- "Array" => "array",
47
- "Hash" => "hash"
48
- } unless defined?(TYPE_NAMES)
35
+ unless defined?(TYPE_NAMES)
36
+ TYPE_NAMES = {
37
+ "Symbol" => "symbol",
38
+ "Integer" => "integer",
39
+ "BigDecimal" => "decimal",
40
+ "Float" => "float",
41
+ "TrueClass" => "boolean",
42
+ "FalseClass" => "boolean",
43
+ "Date" => "date",
44
+ "DateTime" => "dateTime",
45
+ "Time" => "dateTime",
46
+ "Array" => "array",
47
+ "Hash" => "hash"
48
+ }
49
+
50
+ # No need to map these on Ruby 2.4+
51
+ TYPE_NAMES["Fixnum"] = "integer" unless 0.class == Integer
52
+ TYPE_NAMES["Bignum"] = "integer" unless 0.class == Integer
53
+ end
49
54
 
50
55
  FORMATTING = {
51
56
  "symbol" => Proc.new { |symbol| symbol.to_s },
@@ -63,7 +68,17 @@ module ActiveSupport
63
68
  "datetime" => Proc.new { |time| Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc },
64
69
  "integer" => Proc.new { |integer| integer.to_i },
65
70
  "float" => Proc.new { |float| float.to_f },
66
- "decimal" => Proc.new { |number| BigDecimal(number) },
71
+ "decimal" => Proc.new do |number|
72
+ if String === number
73
+ begin
74
+ BigDecimal(number)
75
+ rescue ArgumentError
76
+ BigDecimal('0')
77
+ end
78
+ else
79
+ BigDecimal(number)
80
+ end
81
+ end,
67
82
  "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) },
68
83
  "string" => Proc.new { |string| string.to_s },
69
84
  "yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
@@ -78,6 +93,9 @@ module ActiveSupport
78
93
  )
79
94
  end
80
95
 
96
+ attr_accessor :depth
97
+ self.depth = 100
98
+
81
99
  delegate :parse, :to => :backend
82
100
 
83
101
  def backend
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2013 David Heinemeier Hansson
2
+ # Copyright (c) 2005-2014 David Heinemeier Hansson
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -26,6 +26,7 @@ require "active_support/dependencies/autoload"
26
26
  require "active_support/version"
27
27
  require "active_support/logger"
28
28
  require "active_support/lazy_load_hooks"
29
+ require "active_support/core_ext/date_and_time/compatibility"
29
30
 
30
31
  module ActiveSupport
31
32
  extend ActiveSupport::Autoload
@@ -39,7 +40,6 @@ module ActiveSupport
39
40
 
40
41
  eager_autoload do
41
42
  autoload :BacktraceCleaner
42
- autoload :BasicObject
43
43
  autoload :ProxyObject
44
44
  autoload :Benchmarkable
45
45
  autoload :Cache
@@ -53,6 +53,7 @@ module ActiveSupport
53
53
  autoload :MessageEncryptor
54
54
  autoload :MessageVerifier
55
55
  autoload :Multibyte
56
+ autoload :NumberHelper
56
57
  autoload :OptionMerger
57
58
  autoload :OrderedHash
58
59
  autoload :OrderedOptions
@@ -64,6 +65,30 @@ module ActiveSupport
64
65
  autoload :Rescuable
65
66
  autoload :SafeBuffer, "active_support/core_ext/string/output_safety"
66
67
  autoload :TestCase
68
+
69
+ def self.eager_load!
70
+ super
71
+
72
+ NumberHelper.eager_load!
73
+ end
74
+
75
+ @@test_order = nil
76
+
77
+ def self.test_order=(new_order) # :nodoc:
78
+ @@test_order = new_order
79
+ end
80
+
81
+ def self.test_order # :nodoc:
82
+ @@test_order
83
+ end
84
+
85
+ def self.to_time_preserves_timezone
86
+ DateAndTime::Compatibility.preserve_timezone
87
+ end
88
+
89
+ def self.to_time_preserves_timezone=(value)
90
+ DateAndTime::Compatibility.preserve_timezone = value
91
+ end
67
92
  end
68
93
 
69
94
  autoload :I18n, "active_support/i18n"