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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +364 -135
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -4
- data/lib/active_support/backtrace_cleaner.rb +33 -25
- data/lib/active_support/basic_object.rb +7 -17
- data/lib/active_support/benchmarkable.rb +19 -15
- data/lib/active_support/buffered_logger.rb +9 -113
- data/lib/active_support/cache/file_store.rb +14 -14
- data/lib/active_support/cache/mem_cache_store.rb +24 -30
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/strategy/local_cache.rb +48 -37
- data/lib/active_support/cache.rb +228 -183
- data/lib/active_support/callbacks.rb +201 -253
- data/lib/active_support/concern.rb +16 -23
- data/lib/active_support/concurrency/latch.rb +27 -0
- data/lib/active_support/configurable.rb +69 -12
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +115 -55
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +21 -22
- data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
- data/lib/active_support/core_ext/array/wrap.rb +13 -16
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -24
- data/lib/active_support/core_ext/class/attribute.rb +40 -32
- data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
- data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
- data/lib/active_support/core_ext/class/subclasses.rb +11 -5
- data/lib/active_support/core_ext/date/calculations.rb +44 -187
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +77 -62
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/date_time.rb +4 -0
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/conversions.rb +145 -79
- data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
- data/lib/active_support/core_ext/hash/diff.rb +5 -4
- data/lib/active_support/core_ext/hash/except.rb +1 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
- data/lib/active_support/core_ext/hash/keys.rb +108 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +12 -12
- data/lib/active_support/core_ext/hash.rb +0 -1
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/time.rb +17 -12
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/load_error.rb +7 -5
- data/lib/active_support/core_ext/logger.rb +7 -23
- data/lib/active_support/core_ext/marshal.rb +21 -0
- data/lib/active_support/core_ext/module/aliasing.rb +8 -9
- data/lib/active_support/core_ext/module/anonymous.rb +2 -7
- data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
- data/lib/active_support/core_ext/module/delegation.rb +92 -49
- data/lib/active_support/core_ext/module/deprecation.rb +19 -3
- data/lib/active_support/core_ext/module/introspection.rb +17 -27
- data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
- data/lib/active_support/core_ext/module/remove_method.rb +1 -5
- data/lib/active_support/core_ext/module.rb +1 -3
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +7 -23
- data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
- data/lib/active_support/core_ext/object/duplicable.rb +1 -30
- data/lib/active_support/core_ext/object/inclusion.rb +8 -7
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/to_json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +5 -2
- data/lib/active_support/core_ext/object/try.rb +46 -25
- data/lib/active_support/core_ext/object/with_options.rb +7 -8
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/proc.rb +3 -0
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +3 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +27 -38
- data/lib/active_support/core_ext/string/encoding.rb +6 -9
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +70 -60
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +41 -64
- data/lib/active_support/core_ext/string/output_safety.rb +59 -51
- data/lib/active_support/core_ext/string/zones.rb +13 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time/calculations.rb +108 -184
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/marshal.rb +0 -27
- data/lib/active_support/core_ext/time/zones.rb +27 -17
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -17
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/deprecation/behaviors.rb +44 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +33 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
- data/lib/active_support/deprecation/reporting.rb +40 -11
- data/lib/active_support/deprecation.rb +39 -14
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration.rb +6 -8
- data/lib/active_support/file_update_checker.rb +63 -47
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +127 -42
- data/lib/active_support/i18n.rb +4 -0
- data/lib/active_support/i18n_railtie.rb +5 -22
- data/lib/active_support/inflections.rb +14 -12
- data/lib/active_support/inflector/inflections.rb +108 -71
- data/lib/active_support/inflector/methods.rb +181 -160
- data/lib/active_support/inflector/transliterate.rb +16 -17
- data/lib/active_support/json/decoding.rb +18 -17
- data/lib/active_support/json/encoding.rb +93 -39
- data/lib/active_support/json/variable.rb +10 -1
- data/lib/active_support/key_generator.rb +75 -0
- data/lib/active_support/lazy_load_hooks.rb +21 -19
- data/lib/active_support/locale/en.yml +100 -3
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/log_subscriber.rb +35 -52
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +38 -35
- data/lib/active_support/message_verifier.rb +9 -15
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +112 -18
- data/lib/active_support/notifications/instrumenter.rb +33 -14
- data/lib/active_support/notifications.rb +79 -26
- data/lib/active_support/number_helper.rb +637 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- data/lib/active_support/per_thread_registry.rb +52 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +12 -32
- data/lib/active_support/rescuable.rb +9 -4
- data/lib/active_support/string_inquirer.rb +13 -8
- data/lib/active_support/subscriber.rb +93 -0
- data/lib/active_support/tagged_logging.rb +51 -73
- data/lib/active_support/test_case.rb +46 -17
- data/lib/active_support/testing/assertions.rb +56 -26
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/constant_lookup.rb +54 -0
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +0 -19
- data/lib/active_support/testing/isolation.rb +29 -58
- data/lib/active_support/testing/pending.rb +5 -43
- data/lib/active_support/testing/setup_and_teardown.rb +6 -92
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/time.rb +6 -21
- data/lib/active_support/time_with_zone.rb +80 -43
- data/lib/active_support/values/time_zone.rb +81 -60
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +9 -11
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support.rb +8 -21
- metadata +104 -72
- data/lib/active_support/base64.rb +0 -54
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/date/freeze.rb +0 -33
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
- data/lib/active_support/core_ext/io.rb +0 -15
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -45
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/string/xchar.rb +0 -18
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/memoizable.rb +0 -116
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/security_utils.rb +0 -27
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/time/autoload.rb +0 -5
- 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
|
|
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
|
|
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
|
|
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
|
-
|
|
123
|
-
|
|
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)
|
|
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 =
|
|
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)
|
|
162
|
-
|
|
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)
|
|
167
|
-
|
|
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)
|
|
172
|
-
|
|
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)
|
|
177
|
-
|
|
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)
|
|
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)
|
|
186
|
-
|
|
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
|
|
196
|
-
# the other end knows by contract that the data is supposed to be a
|
|
197
|
-
# it still has the chance to post-process the string and get the
|
|
198
|
-
|
|
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)
|
|
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
|
|
284
|
+
slice(*Array(attrs))
|
|
230
285
|
elsif attrs = options[:except]
|
|
231
|
-
except(*Array
|
|
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
|
-
|
|
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
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
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
|
|
27
|
-
# as in the second line of the code above. The test
|
|
28
|
-
# up the queue, subscriptions and
|
|
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::
|
|
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
|
-
|
|
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::
|
|
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
|