activesupport 3.2.22.5 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +364 -135
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -4
  5. data/lib/active_support/backtrace_cleaner.rb +33 -25
  6. data/lib/active_support/basic_object.rb +7 -17
  7. data/lib/active_support/benchmarkable.rb +19 -15
  8. data/lib/active_support/buffered_logger.rb +9 -113
  9. data/lib/active_support/cache/file_store.rb +14 -14
  10. data/lib/active_support/cache/mem_cache_store.rb +24 -30
  11. data/lib/active_support/cache/memory_store.rb +2 -0
  12. data/lib/active_support/cache/strategy/local_cache.rb +48 -37
  13. data/lib/active_support/cache.rb +228 -183
  14. data/lib/active_support/callbacks.rb +201 -253
  15. data/lib/active_support/concern.rb +16 -23
  16. data/lib/active_support/concurrency/latch.rb +27 -0
  17. data/lib/active_support/configurable.rb +69 -12
  18. data/lib/active_support/core_ext/array/access.rb +17 -9
  19. data/lib/active_support/core_ext/array/conversions.rb +115 -55
  20. data/lib/active_support/core_ext/array/extract_options.rb +2 -2
  21. data/lib/active_support/core_ext/array/grouping.rb +21 -22
  22. data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
  23. data/lib/active_support/core_ext/array/wrap.rb +13 -16
  24. data/lib/active_support/core_ext/array.rb +0 -1
  25. data/lib/active_support/core_ext/benchmark.rb +7 -0
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -24
  27. data/lib/active_support/core_ext/class/attribute.rb +40 -32
  28. data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
  29. data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
  30. data/lib/active_support/core_ext/class/subclasses.rb +11 -5
  31. data/lib/active_support/core_ext/date/calculations.rb +44 -187
  32. data/lib/active_support/core_ext/date/conversions.rb +16 -38
  33. data/lib/active_support/core_ext/date/zones.rb +25 -2
  34. data/lib/active_support/core_ext/date.rb +5 -0
  35. data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
  36. data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
  37. data/lib/active_support/core_ext/date_time/calculations.rb +77 -62
  38. data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
  39. data/lib/active_support/core_ext/date_time/zones.rb +11 -8
  40. data/lib/active_support/core_ext/date_time.rb +4 -0
  41. data/lib/active_support/core_ext/enumerable.rb +26 -73
  42. data/lib/active_support/core_ext/file/atomic.rb +27 -11
  43. data/lib/active_support/core_ext/file.rb +0 -1
  44. data/lib/active_support/core_ext/hash/conversions.rb +145 -79
  45. data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
  46. data/lib/active_support/core_ext/hash/diff.rb +5 -4
  47. data/lib/active_support/core_ext/hash/except.rb +1 -9
  48. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
  49. data/lib/active_support/core_ext/hash/keys.rb +108 -24
  50. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
  51. data/lib/active_support/core_ext/hash/slice.rb +12 -12
  52. data/lib/active_support/core_ext/hash.rb +0 -1
  53. data/lib/active_support/core_ext/integer/inflections.rb +13 -1
  54. data/lib/active_support/core_ext/integer/time.rb +17 -12
  55. data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
  56. data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
  57. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
  58. data/lib/active_support/core_ext/load_error.rb +7 -5
  59. data/lib/active_support/core_ext/logger.rb +7 -23
  60. data/lib/active_support/core_ext/marshal.rb +21 -0
  61. data/lib/active_support/core_ext/module/aliasing.rb +8 -9
  62. data/lib/active_support/core_ext/module/anonymous.rb +2 -7
  63. data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
  64. data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
  65. data/lib/active_support/core_ext/module/delegation.rb +92 -49
  66. data/lib/active_support/core_ext/module/deprecation.rb +19 -3
  67. data/lib/active_support/core_ext/module/introspection.rb +17 -27
  68. data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
  69. data/lib/active_support/core_ext/module/remove_method.rb +1 -5
  70. data/lib/active_support/core_ext/module.rb +1 -3
  71. data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
  72. data/lib/active_support/core_ext/numeric/time.rb +6 -6
  73. data/lib/active_support/core_ext/numeric.rb +1 -0
  74. data/lib/active_support/core_ext/object/acts_like.rb +4 -4
  75. data/lib/active_support/core_ext/object/blank.rb +7 -23
  76. data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
  77. data/lib/active_support/core_ext/object/duplicable.rb +1 -30
  78. data/lib/active_support/core_ext/object/inclusion.rb +8 -7
  79. data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
  80. data/lib/active_support/core_ext/object/to_json.rb +8 -0
  81. data/lib/active_support/core_ext/object/to_param.rb +5 -2
  82. data/lib/active_support/core_ext/object/try.rb +46 -25
  83. data/lib/active_support/core_ext/object/with_options.rb +7 -8
  84. data/lib/active_support/core_ext/object.rb +1 -0
  85. data/lib/active_support/core_ext/proc.rb +3 -0
  86. data/lib/active_support/core_ext/range/conversions.rb +0 -2
  87. data/lib/active_support/core_ext/range/include_range.rb +3 -1
  88. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  89. data/lib/active_support/core_ext/range.rb +0 -2
  90. data/lib/active_support/core_ext/string/access.rb +95 -90
  91. data/lib/active_support/core_ext/string/conversions.rb +27 -38
  92. data/lib/active_support/core_ext/string/encoding.rb +6 -9
  93. data/lib/active_support/core_ext/string/filters.rb +24 -18
  94. data/lib/active_support/core_ext/string/indent.rb +43 -0
  95. data/lib/active_support/core_ext/string/inflections.rb +70 -60
  96. data/lib/active_support/core_ext/string/inquiry.rb +2 -2
  97. data/lib/active_support/core_ext/string/multibyte.rb +41 -64
  98. data/lib/active_support/core_ext/string/output_safety.rb +59 -51
  99. data/lib/active_support/core_ext/string/zones.rb +13 -0
  100. data/lib/active_support/core_ext/string.rb +2 -3
  101. data/lib/active_support/core_ext/struct.rb +6 -0
  102. data/lib/active_support/core_ext/thread.rb +74 -0
  103. data/lib/active_support/core_ext/time/calculations.rb +108 -184
  104. data/lib/active_support/core_ext/time/conversions.rb +27 -51
  105. data/lib/active_support/core_ext/time/marshal.rb +0 -27
  106. data/lib/active_support/core_ext/time/zones.rb +27 -17
  107. data/lib/active_support/core_ext/time.rb +5 -0
  108. data/lib/active_support/core_ext/uri.rb +13 -17
  109. data/lib/active_support/core_ext.rb +3 -2
  110. data/lib/active_support/dependencies/autoload.rb +47 -20
  111. data/lib/active_support/dependencies.rb +160 -141
  112. data/lib/active_support/deprecation/behaviors.rb +44 -30
  113. data/lib/active_support/deprecation/instance_delegator.rb +24 -0
  114. data/lib/active_support/deprecation/method_wrappers.rb +33 -18
  115. data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
  116. data/lib/active_support/deprecation/reporting.rb +40 -11
  117. data/lib/active_support/deprecation.rb +39 -14
  118. data/lib/active_support/descendants_tracker.rb +34 -19
  119. data/lib/active_support/duration.rb +6 -8
  120. data/lib/active_support/file_update_checker.rb +63 -47
  121. data/lib/active_support/gzip.rb +11 -5
  122. data/lib/active_support/hash_with_indifferent_access.rb +127 -42
  123. data/lib/active_support/i18n.rb +4 -0
  124. data/lib/active_support/i18n_railtie.rb +5 -22
  125. data/lib/active_support/inflections.rb +14 -12
  126. data/lib/active_support/inflector/inflections.rb +108 -71
  127. data/lib/active_support/inflector/methods.rb +181 -160
  128. data/lib/active_support/inflector/transliterate.rb +16 -17
  129. data/lib/active_support/json/decoding.rb +18 -17
  130. data/lib/active_support/json/encoding.rb +93 -39
  131. data/lib/active_support/json/variable.rb +10 -1
  132. data/lib/active_support/key_generator.rb +75 -0
  133. data/lib/active_support/lazy_load_hooks.rb +21 -19
  134. data/lib/active_support/locale/en.yml +100 -3
  135. data/lib/active_support/log_subscriber/test_helper.rb +18 -15
  136. data/lib/active_support/log_subscriber.rb +35 -52
  137. data/lib/active_support/logger.rb +57 -0
  138. data/lib/active_support/logger_silence.rb +24 -0
  139. data/lib/active_support/message_encryptor.rb +38 -35
  140. data/lib/active_support/message_verifier.rb +9 -15
  141. data/lib/active_support/multibyte/chars.rb +80 -333
  142. data/lib/active_support/multibyte/unicode.rb +74 -64
  143. data/lib/active_support/multibyte.rb +5 -28
  144. data/lib/active_support/notifications/fanout.rb +112 -18
  145. data/lib/active_support/notifications/instrumenter.rb +33 -14
  146. data/lib/active_support/notifications.rb +79 -26
  147. data/lib/active_support/number_helper.rb +637 -0
  148. data/lib/active_support/ordered_hash.rb +8 -190
  149. data/lib/active_support/ordered_options.rb +21 -23
  150. data/lib/active_support/per_thread_registry.rb +52 -0
  151. data/lib/active_support/proxy_object.rb +13 -0
  152. data/lib/active_support/rails.rb +27 -0
  153. data/lib/active_support/railtie.rb +12 -32
  154. data/lib/active_support/rescuable.rb +9 -4
  155. data/lib/active_support/string_inquirer.rb +13 -8
  156. data/lib/active_support/subscriber.rb +93 -0
  157. data/lib/active_support/tagged_logging.rb +51 -73
  158. data/lib/active_support/test_case.rb +46 -17
  159. data/lib/active_support/testing/assertions.rb +56 -26
  160. data/lib/active_support/testing/autorun.rb +5 -0
  161. data/lib/active_support/testing/constant_lookup.rb +54 -0
  162. data/lib/active_support/testing/declarative.rb +1 -1
  163. data/lib/active_support/testing/deprecation.rb +0 -19
  164. data/lib/active_support/testing/isolation.rb +29 -58
  165. data/lib/active_support/testing/pending.rb +5 -43
  166. data/lib/active_support/testing/setup_and_teardown.rb +6 -92
  167. data/lib/active_support/testing/tagged_logging.rb +25 -0
  168. data/lib/active_support/time.rb +6 -21
  169. data/lib/active_support/time_with_zone.rb +80 -43
  170. data/lib/active_support/values/time_zone.rb +81 -60
  171. data/lib/active_support/values/unicode_tables.dat +0 -0
  172. data/lib/active_support/version.rb +7 -6
  173. data/lib/active_support/xml_mini/jdom.rb +9 -11
  174. data/lib/active_support/xml_mini/libxml.rb +1 -2
  175. data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
  176. data/lib/active_support/xml_mini/nokogiri.rb +1 -2
  177. data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
  178. data/lib/active_support/xml_mini/rexml.rb +6 -8
  179. data/lib/active_support/xml_mini.rb +35 -17
  180. data/lib/active_support.rb +8 -21
  181. metadata +104 -72
  182. data/lib/active_support/base64.rb +0 -54
  183. data/lib/active_support/core_ext/array/random_access.rb +0 -30
  184. data/lib/active_support/core_ext/date/freeze.rb +0 -33
  185. data/lib/active_support/core_ext/exception.rb +0 -3
  186. data/lib/active_support/core_ext/file/path.rb +0 -5
  187. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  188. data/lib/active_support/core_ext/float.rb +0 -1
  189. data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
  190. data/lib/active_support/core_ext/io.rb +0 -15
  191. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  192. data/lib/active_support/core_ext/module/synchronization.rb +0 -45
  193. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  194. data/lib/active_support/core_ext/process.rb +0 -1
  195. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  196. data/lib/active_support/core_ext/range/cover.rb +0 -3
  197. data/lib/active_support/core_ext/rexml.rb +0 -46
  198. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  199. data/lib/active_support/core_ext/string/xchar.rb +0 -18
  200. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
  201. data/lib/active_support/memoizable.rb +0 -116
  202. data/lib/active_support/multibyte/exceptions.rb +0 -8
  203. data/lib/active_support/multibyte/utils.rb +0 -60
  204. data/lib/active_support/ruby/shim.rb +0 -22
  205. data/lib/active_support/security_utils.rb +0 -27
  206. data/lib/active_support/testing/mochaing.rb +0 -7
  207. data/lib/active_support/testing/performance/jruby.rb +0 -115
  208. data/lib/active_support/testing/performance/rubinius.rb +0 -113
  209. data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
  210. data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
  211. data/lib/active_support/testing/performance/ruby.rb +0 -152
  212. data/lib/active_support/testing/performance.rb +0 -317
  213. data/lib/active_support/time/autoload.rb +0 -5
  214. data/lib/active_support/whiny_nil.rb +0 -24
@@ -1,11 +1,9 @@
1
1
  require 'active_support/core_ext/object/to_json'
2
2
  require 'active_support/core_ext/module/delegation'
3
3
  require 'active_support/json/variable'
4
- require 'active_support/ordered_hash'
5
4
 
6
5
  require 'bigdecimal'
7
6
  require 'active_support/core_ext/big_decimal/conversions' # for #to_s
8
- require 'active_support/core_ext/array/wrap'
9
7
  require 'active_support/core_ext/hash/except'
10
8
  require 'active_support/core_ext/hash/slice'
11
9
  require 'active_support/core_ext/object/instance_variables'
@@ -19,6 +17,7 @@ module ActiveSupport
19
17
  class << self
20
18
  delegate :use_standard_json_time_format, :use_standard_json_time_format=,
21
19
  :escape_html_entities_in_json, :escape_html_entities_in_json=,
20
+ :encode_big_decimal_as_string, :encode_big_decimal_as_string=,
22
21
  :to => :'ActiveSupport::JSON::Encoding'
23
22
  end
24
23
 
@@ -26,7 +25,11 @@ module ActiveSupport
26
25
  # matches YAML-formatted dates
27
26
  DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
28
27
 
29
- # Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
28
+ # Dumps objects in JSON (JavaScript Object Notation).
29
+ # See www.json.org for more info.
30
+ #
31
+ # ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
32
+ # # => "{\"team\":\"rails\",\"players\":\"36\"}"
30
33
  def self.encode(value, options = nil)
31
34
  Encoding::Encoder.new(options).encode(value)
32
35
  end
@@ -49,7 +52,7 @@ module ActiveSupport
49
52
  end
50
53
  end
51
54
 
52
- # like encode, but only calls as_json, without encoding to string
55
+ # like encode, but only calls as_json, without encoding to string.
53
56
  def as_json(value, use_options = true)
54
57
  check_for_circular_references(value) do
55
58
  use_options ? value.as_json(options_for(value)) : value.as_json
@@ -58,7 +61,8 @@ module ActiveSupport
58
61
 
59
62
  def options_for(value)
60
63
  if value.is_a?(Array) || value.is_a?(Hash)
61
- # hashes and arrays need to get encoder in the options, so that they can detect circular references
64
+ # hashes and arrays need to get encoder in the options, so that
65
+ # they can detect circular references.
62
66
  options.merge(:encoder => self)
63
67
  else
64
68
  options.dup
@@ -103,9 +107,14 @@ module ActiveSupport
103
107
  '&' => '\u0026' }
104
108
 
105
109
  class << self
106
- # If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format.
110
+ # If true, use ISO 8601 format for dates and times. Otherwise, fall back
111
+ # to the Active Support legacy format.
107
112
  attr_accessor :use_standard_json_time_format
108
113
 
114
+ # If false, serializes BigDecimal objects as numeric instead of wrapping
115
+ # them in a string.
116
+ attr_accessor :encode_big_decimal_as_string
117
+
109
118
  attr_accessor :escape_regex
110
119
  attr_reader :escape_html_entities_in_json
111
120
 
@@ -119,24 +128,17 @@ module ActiveSupport
119
128
  end
120
129
 
121
130
  def escape(string)
122
- if string.respond_to?(:force_encoding)
123
- string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
124
- end
125
- json = string.
126
- gsub(escape_regex) { |s| ESCAPED_CHARS[s] }.
127
- gsub(/([\xC0-\xDF][\x80-\xBF]|
128
- [\xE0-\xEF][\x80-\xBF]{2}|
129
- [\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
130
- s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/n, '\\\\u\&')
131
- }
131
+ string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
132
+ json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] }
132
133
  json = %("#{json}")
133
- json.force_encoding(::Encoding::UTF_8) if json.respond_to?(:force_encoding)
134
+ json.force_encoding(::Encoding::UTF_8)
134
135
  json
135
136
  end
136
137
  end
137
138
 
138
139
  self.use_standard_json_time_format = true
139
- self.escape_html_entities_in_json = false
140
+ self.escape_html_entities_in_json = true
141
+ self.encode_big_decimal_as_string = true
140
142
  end
141
143
  end
142
144
  end
@@ -158,32 +160,67 @@ class Struct #:nodoc:
158
160
  end
159
161
 
160
162
  class TrueClass
161
- def as_json(options = nil) self end #:nodoc:
162
- def encode_json(encoder) to_s end #:nodoc:
163
+ def as_json(options = nil) #:nodoc:
164
+ self
165
+ end
166
+
167
+ def encode_json(encoder) #:nodoc:
168
+ to_s
169
+ end
163
170
  end
164
171
 
165
172
  class FalseClass
166
- def as_json(options = nil) self end #:nodoc:
167
- def encode_json(encoder) to_s end #:nodoc:
173
+ def as_json(options = nil) #:nodoc:
174
+ self
175
+ end
176
+
177
+ def encode_json(encoder) #:nodoc:
178
+ to_s
179
+ end
168
180
  end
169
181
 
170
182
  class NilClass
171
- def as_json(options = nil) self end #:nodoc:
172
- def encode_json(encoder) 'null' end #:nodoc:
183
+ def as_json(options = nil) #:nodoc:
184
+ self
185
+ end
186
+
187
+ def encode_json(encoder) #:nodoc:
188
+ 'null'
189
+ end
173
190
  end
174
191
 
175
192
  class String
176
- def as_json(options = nil) self end #:nodoc:
177
- def encode_json(encoder) encoder.escape(self) end #:nodoc:
193
+ def as_json(options = nil) #:nodoc:
194
+ self
195
+ end
196
+
197
+ def encode_json(encoder) #:nodoc:
198
+ encoder.escape(self)
199
+ end
178
200
  end
179
201
 
180
202
  class Symbol
181
- def as_json(options = nil) to_s end #:nodoc:
203
+ def as_json(options = nil) #:nodoc:
204
+ to_s
205
+ end
182
206
  end
183
207
 
184
208
  class Numeric
185
- def as_json(options = nil) self end #:nodoc:
186
- def encode_json(encoder) to_s end #:nodoc:
209
+ def as_json(options = nil) #:nodoc:
210
+ self
211
+ end
212
+
213
+ def encode_json(encoder) #:nodoc:
214
+ to_s
215
+ end
216
+ end
217
+
218
+ class Float
219
+ # Encoding Infinity or NaN to JSON should return "null". The default returns
220
+ # "Infinity" or "NaN" which breaks parsing the JSON. E.g. JSON.parse('[NaN]').
221
+ def as_json(options = nil) #:nodoc:
222
+ finite? ? self : nil
223
+ end
187
224
  end
188
225
 
189
226
  class BigDecimal
@@ -192,14 +229,26 @@ class BigDecimal
192
229
  # those libraries would get in general a wrong number and no way to recover
193
230
  # other than manually inspecting the string with the JSON code itself.
194
231
  #
195
- # That's why a JSON string is returned. The JSON literal is not numeric, but if
196
- # the other end knows by contract that the data is supposed to be a BigDecimal,
197
- # it still has the chance to post-process the string and get the real value.
198
- def as_json(options = nil) to_s end #:nodoc:
232
+ # That's why a JSON string is returned. The JSON literal is not numeric, but
233
+ # if the other end knows by contract that the data is supposed to be a
234
+ # BigDecimal, it still has the chance to post-process the string and get the
235
+ # real value.
236
+ #
237
+ # Use <tt>ActiveSupport.use_standard_json_big_decimal_format = true</tt> to
238
+ # override this behavior.
239
+ def as_json(options = nil) #:nodoc:
240
+ if finite?
241
+ ActiveSupport.encode_big_decimal_as_string ? to_s : self
242
+ else
243
+ nil
244
+ end
245
+ end
199
246
  end
200
247
 
201
248
  class Regexp
202
- def as_json(options = nil) to_s end #:nodoc:
249
+ def as_json(options = nil) #:nodoc:
250
+ to_s
251
+ end
203
252
  end
204
253
 
205
254
  module Enumerable
@@ -208,6 +257,12 @@ module Enumerable
208
257
  end
209
258
  end
210
259
 
260
+ class Range
261
+ def as_json(options = nil) #:nodoc:
262
+ to_s
263
+ end
264
+ end
265
+
211
266
  class Array
212
267
  def as_json(options = nil) #:nodoc:
213
268
  # use encoder as a proxy to call as_json on all elements, to protect from circular references
@@ -226,9 +281,9 @@ class Hash
226
281
  # create a subset of the hash by applying :only or :except
227
282
  subset = if options
228
283
  if attrs = options[:only]
229
- slice(*Array.wrap(attrs))
284
+ slice(*Array(attrs))
230
285
  elsif attrs = options[:except]
231
- except(*Array.wrap(attrs))
286
+ except(*Array(attrs))
232
287
  else
233
288
  self
234
289
  end
@@ -238,11 +293,10 @@ class Hash
238
293
 
239
294
  # use encoder as a proxy to call as_json on all values in the subset, to protect from circular references
240
295
  encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
241
- result = self.is_a?(ActiveSupport::OrderedHash) ? ActiveSupport::OrderedHash : Hash
242
- result[subset.map { |k, v| [k.to_s, encoder.as_json(v, options)] }]
296
+ Hash[subset.map { |k, v| [k.to_s, encoder.as_json(v, options)] }]
243
297
  end
244
298
 
245
- def encode_json(encoder)
299
+ def encode_json(encoder) #:nodoc:
246
300
  # values are encoded with use_options = false, because we don't want hash representations from ActiveModel to be
247
301
  # processed once again with as_json with options, as this could cause unexpected results (i.e. missing fields);
248
302
 
@@ -1,7 +1,16 @@
1
+ require 'active_support/deprecation'
2
+
1
3
  module ActiveSupport
2
4
  module JSON
3
- # A string that returns itself as its JSON-encoded form.
5
+ # Deprecated: A string that returns itself as its JSON-encoded form.
4
6
  class Variable < String
7
+ def initialize(*args)
8
+ message = 'ActiveSupport::JSON::Variable is deprecated and will be removed in Rails 4.1. ' \
9
+ 'For your own custom JSON literals, define #as_json and #encode_json yourself.'
10
+ ActiveSupport::Deprecation.warn message
11
+ super
12
+ end
13
+
5
14
  def as_json(options = nil) self end #:nodoc:
6
15
  def encode_json(encoder) self end #:nodoc:
7
16
  end
@@ -0,0 +1,75 @@
1
+ require 'thread_safe'
2
+ require 'openssl'
3
+
4
+ module ActiveSupport
5
+ # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
6
+ # It can be used to derive a number of keys for various purposes from a given secret.
7
+ # This lets rails applications have a single secure secret, but avoid reusing that
8
+ # key in multiple incompatible contexts.
9
+ class KeyGenerator
10
+ def initialize(secret, options = {})
11
+ @secret = secret
12
+ # The default iterations are higher than required for our key derivation uses
13
+ # on the off chance someone uses this for password storage
14
+ @iterations = options[:iterations] || 2**16
15
+ end
16
+
17
+ # Returns a derived key suitable for use. The default key_size is chosen
18
+ # to be compatible with the default settings of ActiveSupport::MessageVerifier.
19
+ # i.e. OpenSSL::Digest::SHA1#block_length
20
+ def generate_key(salt, key_size=64)
21
+ OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
22
+ end
23
+ end
24
+
25
+ # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
26
+ # re-executing the key generation process when it's called using the same salt and
27
+ # key_size
28
+ class CachingKeyGenerator
29
+ def initialize(key_generator)
30
+ @key_generator = key_generator
31
+ @cache_keys = ThreadSafe::Cache.new
32
+ end
33
+
34
+ # Returns a derived key suitable for use. The default key_size is chosen
35
+ # to be compatible with the default settings of ActiveSupport::MessageVerifier.
36
+ # i.e. OpenSSL::Digest::SHA1#block_length
37
+ def generate_key(salt, key_size=64)
38
+ @cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size)
39
+ end
40
+ end
41
+
42
+ class LegacyKeyGenerator # :nodoc:
43
+ SECRET_MIN_LENGTH = 30 # Characters
44
+
45
+ def initialize(secret)
46
+ ensure_secret_secure(secret)
47
+ @secret = secret
48
+ end
49
+
50
+ def generate_key(salt)
51
+ @secret
52
+ end
53
+
54
+ private
55
+
56
+ # To prevent users from using something insecure like "Password" we make sure that the
57
+ # secret they've provided is at least 30 characters in length.
58
+ def ensure_secret_secure(secret)
59
+ if secret.blank?
60
+ raise ArgumentError, "A secret is required to generate an " +
61
+ "integrity hash for cookie session data. Use " +
62
+ "config.secret_key_base = \"some secret phrase of at " +
63
+ "least #{SECRET_MIN_LENGTH} characters\"" +
64
+ "in config/initializers/secret_token.rb"
65
+ end
66
+
67
+ if secret.length < SECRET_MIN_LENGTH
68
+ raise ArgumentError, "Secret should be something secure, " +
69
+ "like \"#{SecureRandom.hex(16)}\". The value you " +
70
+ "provided, \"#{secret}\", is shorter than the minimum length " +
71
+ "of #{SECRET_MIN_LENGTH} characters"
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,23 +1,25 @@
1
- # lazy_load_hooks allows rails to lazily load a lot of components and thus making the app boot faster. Because of
2
- # this feature now there is no need to require <tt>ActiveRecord::Base</tt> at boot time purely to apply configuration. Instead
3
- # a hook is registered that applies configuration once <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is used
4
- # as example but this feature can be applied elsewhere too.
5
- #
6
- # Here is an example where +on_load+ method is called to register a hook.
7
- #
8
- # initializer "active_record.initialize_timezone" do
9
- # ActiveSupport.on_load(:active_record) do
10
- # self.time_zone_aware_attributes = true
11
- # self.default_timezone = :utc
12
- # end
13
- # end
14
- #
15
- # When the entirety of +activerecord/lib/active_record/base.rb+ has been evaluated then +run_load_hooks+ is invoked.
16
- # The very last line of +activerecord/lib/active_record/base.rb+ is:
17
- #
18
- # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
19
- #
20
1
  module ActiveSupport
2
+ # lazy_load_hooks allows rails to lazily load a lot of components and thus
3
+ # making the app boot faster. Because of this feature now there is no need to
4
+ # require <tt>ActiveRecord::Base</tt> at boot time purely to apply
5
+ # configuration. Instead a hook is registered that applies configuration once
6
+ # <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is
7
+ # used as example but this feature can be applied elsewhere too.
8
+ #
9
+ # Here is an example where +on_load+ method is called to register a hook.
10
+ #
11
+ # initializer 'active_record.initialize_timezone' do
12
+ # ActiveSupport.on_load(:active_record) do
13
+ # self.time_zone_aware_attributes = true
14
+ # self.default_timezone = :utc
15
+ # end
16
+ # end
17
+ #
18
+ # When the entirety of +activerecord/lib/active_record/base.rb+ has been
19
+ # evaluated then +run_load_hooks+ is invoked. The very last line of
20
+ # +activerecord/lib/active_record/base.rb+ is:
21
+ #
22
+ # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
21
23
  @load_hooks = Hash.new { |h,k| h[k] = [] }
22
24
  @loaded = Hash.new { |h,k| h[k] = [] }
23
25
 
@@ -16,9 +16,9 @@ en:
16
16
  abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
17
17
  # Used in date_select and datetime_select.
18
18
  order:
19
- - :year
20
- - :month
21
- - :day
19
+ - year
20
+ - month
21
+ - day
22
22
 
23
23
  time:
24
24
  formats:
@@ -34,3 +34,100 @@ en:
34
34
  words_connector: ", "
35
35
  two_words_connector: " and "
36
36
  last_word_connector: ", and "
37
+ number:
38
+ # Used in NumberHelper.number_to_delimited()
39
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
40
+ format:
41
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
42
+ separator: "."
43
+ # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three)
44
+ delimiter: ","
45
+ # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
46
+ precision: 3
47
+ # If set to true, precision will mean the number of significant digits instead
48
+ # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
49
+ significant: false
50
+ # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2)
51
+ strip_insignificant_zeros: false
52
+
53
+ # Used in NumberHelper.number_to_currency()
54
+ currency:
55
+ format:
56
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
57
+ format: "%u%n"
58
+ unit: "$"
59
+ # These five are to override number.format and are optional
60
+ separator: "."
61
+ delimiter: ","
62
+ precision: 2
63
+ significant: false
64
+ strip_insignificant_zeros: false
65
+
66
+ # Used in NumberHelper.number_to_percentage()
67
+ percentage:
68
+ format:
69
+ # These five are to override number.format and are optional
70
+ # separator:
71
+ delimiter: ""
72
+ # precision:
73
+ # significant: false
74
+ # strip_insignificant_zeros: false
75
+ format: "%n%"
76
+
77
+ # Used in NumberHelper.number_to_rounded()
78
+ precision:
79
+ format:
80
+ # These five are to override number.format and are optional
81
+ # separator:
82
+ delimiter: ""
83
+ # precision:
84
+ # significant: false
85
+ # strip_insignificant_zeros: false
86
+
87
+ # Used in NumberHelper.number_to_human_size() and NumberHelper.number_to_human()
88
+ human:
89
+ format:
90
+ # These five are to override number.format and are optional
91
+ # separator:
92
+ delimiter: ""
93
+ precision: 3
94
+ significant: true
95
+ strip_insignificant_zeros: true
96
+ # Used in number_to_human_size()
97
+ storage_units:
98
+ # Storage units output formatting.
99
+ # %u is the storage unit, %n is the number (default: 2 MB)
100
+ format: "%n %u"
101
+ units:
102
+ byte:
103
+ one: "Byte"
104
+ other: "Bytes"
105
+ kb: "KB"
106
+ mb: "MB"
107
+ gb: "GB"
108
+ tb: "TB"
109
+ # Used in NumberHelper.number_to_human()
110
+ decimal_units:
111
+ format: "%n %u"
112
+ # Decimal units output formatting
113
+ # By default we will only quantify some of the exponents
114
+ # but the commented ones might be defined or overridden
115
+ # by the user.
116
+ units:
117
+ # femto: Quadrillionth
118
+ # pico: Trillionth
119
+ # nano: Billionth
120
+ # micro: Millionth
121
+ # mili: Thousandth
122
+ # centi: Hundredth
123
+ # deci: Tenth
124
+ unit: ""
125
+ # ten:
126
+ # one: Ten
127
+ # other: Tens
128
+ # hundred: Hundred
129
+ thousand: Thousand
130
+ million: Million
131
+ billion: Billion
132
+ trillion: Trillion
133
+ quadrillion: Quadrillion
@@ -15,7 +15,7 @@ module ActiveSupport
15
15
  # end
16
16
  #
17
17
  # def test_basic_query_logging
18
- # Developer.all
18
+ # Developer.all.to_a
19
19
  # wait
20
20
  # assert_equal 1, @logger.logged(:debug).size
21
21
  # assert_match(/Developer Load/, @logger.logged(:debug).last)
@@ -23,15 +23,15 @@ module ActiveSupport
23
23
  # end
24
24
  # end
25
25
  #
26
- # All you need to do is to ensure that your log subscriber is added to Rails::Subscriber,
27
- # as in the second line of the code above. The test helpers are responsible for setting
28
- # up the queue, subscriptions and turning colors in logs off.
29
- #
30
- # The messages are available in the @logger instance, which is a logger with limited
31
- # powers (it actually does not send anything to your output), and you can collect them
32
- # doing @logger.logged(level), where level is the level used in logging, like info,
33
- # debug, warn and so on.
26
+ # All you need to do is to ensure that your log subscriber is added to
27
+ # Rails::Subscriber, as in the second line of the code above. The test
28
+ # helpers are responsible for setting up the queue, subscriptions and
29
+ # turning colors in logs off.
34
30
  #
31
+ # The messages are available in the @logger instance, which is a logger with
32
+ # limited powers (it actually does not send anything to your output), and
33
+ # you can collect them doing @logger.logged(level), where level is the level
34
+ # used in logging, like info, debug, warn and so on.
35
35
  module TestHelper
36
36
  def setup
37
37
  @logger = MockLogger.new
@@ -50,7 +50,7 @@ module ActiveSupport
50
50
  end
51
51
 
52
52
  class MockLogger
53
- include ActiveSupport::BufferedLogger::Severity
53
+ include ActiveSupport::Logger::Severity
54
54
 
55
55
  attr_reader :flush_count
56
56
  attr_accessor :level
@@ -61,8 +61,12 @@ module ActiveSupport
61
61
  @logged = Hash.new { |h,k| h[k] = [] }
62
62
  end
63
63
 
64
- def method_missing(level, message)
65
- @logged[level] << message
64
+ def method_missing(level, message = nil)
65
+ if block_given?
66
+ @logged[level] << yield
67
+ else
68
+ @logged[level] << message
69
+ end
66
70
  end
67
71
 
68
72
  def logged(level)
@@ -73,7 +77,7 @@ module ActiveSupport
73
77
  @flush_count += 1
74
78
  end
75
79
 
76
- ActiveSupport::BufferedLogger::Severity.constants.each do |severity|
80
+ ActiveSupport::Logger::Severity.constants.each do |severity|
77
81
  class_eval <<-EOT, __FILE__, __LINE__ + 1
78
82
  def #{severity.downcase}?
79
83
  #{severity} >= @level
@@ -87,12 +91,11 @@ module ActiveSupport
87
91
  @notifier.wait
88
92
  end
89
93
 
90
- # Overwrite if you use another logger in your log subscriber:
94
+ # Overwrite if you use another logger in your log subscriber.
91
95
  #
92
96
  # def logger
93
97
  # ActiveRecord::Base.logger = @logger
94
98
  # end
95
- #
96
99
  def set_logger(logger)
97
100
  ActiveSupport::LogSubscriber.logger = logger
98
101
  end