activesupport 3.1.0 → 5.0.0

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 (276) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +798 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +13 -7
  5. data/lib/active_support/array_inquirer.rb +44 -0
  6. data/lib/active_support/backtrace_cleaner.rb +38 -34
  7. data/lib/active_support/benchmarkable.rb +17 -28
  8. data/lib/active_support/cache/file_store.rb +85 -70
  9. data/lib/active_support/cache/mem_cache_store.rb +75 -66
  10. data/lib/active_support/cache/memory_store.rb +31 -23
  11. data/lib/active_support/cache/null_store.rb +41 -0
  12. data/lib/active_support/cache/strategy/local_cache.rb +73 -70
  13. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  14. data/lib/active_support/cache.rb +360 -294
  15. data/lib/active_support/callbacks.rb +563 -393
  16. data/lib/active_support/concern.rb +42 -34
  17. data/lib/active_support/concurrency/latch.rb +19 -0
  18. data/lib/active_support/concurrency/share_lock.rb +186 -0
  19. data/lib/active_support/configurable.rb +70 -12
  20. data/lib/active_support/core_ext/array/access.rb +53 -9
  21. data/lib/active_support/core_ext/array/conversions.rb +109 -62
  22. data/lib/active_support/core_ext/array/extract_options.rb +2 -2
  23. data/lib/active_support/core_ext/array/grouping.rb +39 -32
  24. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  25. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
  26. data/lib/active_support/core_ext/array/wrap.rb +16 -18
  27. data/lib/active_support/core_ext/array.rb +2 -2
  28. data/lib/active_support/core_ext/benchmark.rb +7 -0
  29. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -36
  30. data/lib/active_support/core_ext/class/attribute.rb +47 -34
  31. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -79
  32. data/lib/active_support/core_ext/class/subclasses.rb +12 -7
  33. data/lib/active_support/core_ext/class.rb +0 -3
  34. data/lib/active_support/core_ext/date/blank.rb +12 -0
  35. data/lib/active_support/core_ext/date/calculations.rb +57 -167
  36. data/lib/active_support/core_ext/date/conversions.rb +31 -42
  37. data/lib/active_support/core_ext/date/zones.rb +2 -10
  38. data/lib/active_support/core_ext/date.rb +5 -0
  39. data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
  40. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
  41. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  42. data/lib/active_support/core_ext/date_time/acts_like.rb +1 -0
  43. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  44. data/lib/active_support/core_ext/date_time/calculations.rb +132 -65
  45. data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
  46. data/lib/active_support/core_ext/date_time/conversions.rb +36 -34
  47. data/lib/active_support/core_ext/date_time.rb +5 -0
  48. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  49. data/lib/active_support/core_ext/enumerable.rb +81 -74
  50. data/lib/active_support/core_ext/file/atomic.rb +53 -26
  51. data/lib/active_support/core_ext/file.rb +0 -1
  52. data/lib/active_support/core_ext/hash/compact.rb +20 -0
  53. data/lib/active_support/core_ext/hash/conversions.rb +175 -70
  54. data/lib/active_support/core_ext/hash/deep_merge.rb +30 -8
  55. data/lib/active_support/core_ext/hash/except.rb +11 -12
  56. data/lib/active_support/core_ext/hash/indifferent_access.rb +7 -8
  57. data/lib/active_support/core_ext/hash/keys.rb +147 -24
  58. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
  59. data/lib/active_support/core_ext/hash/slice.rb +22 -14
  60. data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
  61. data/lib/active_support/core_ext/hash.rb +2 -2
  62. data/lib/active_support/core_ext/integer/inflections.rb +13 -1
  63. data/lib/active_support/core_ext/integer/multiple.rb +4 -0
  64. data/lib/active_support/core_ext/integer/time.rb +12 -22
  65. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
  66. data/lib/active_support/core_ext/kernel/concern.rb +12 -0
  67. data/lib/active_support/core_ext/kernel/debugger.rb +2 -15
  68. data/lib/active_support/core_ext/kernel/reporting.rb +12 -62
  69. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
  70. data/lib/active_support/core_ext/kernel.rb +2 -3
  71. data/lib/active_support/core_ext/load_error.rb +14 -7
  72. data/lib/active_support/core_ext/marshal.rb +22 -0
  73. data/lib/active_support/core_ext/module/aliasing.rb +16 -12
  74. data/lib/active_support/core_ext/module/anonymous.rb +12 -8
  75. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  76. data/lib/active_support/core_ext/module/attribute_accessors.rb +165 -13
  77. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  78. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  79. data/lib/active_support/core_ext/module/delegation.rb +141 -68
  80. data/lib/active_support/core_ext/module/deprecation.rb +17 -3
  81. data/lib/active_support/core_ext/module/introspection.rb +9 -31
  82. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
  83. data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
  84. data/lib/active_support/core_ext/module/reachable.rb +1 -3
  85. data/lib/active_support/core_ext/module/remove_method.rb +24 -5
  86. data/lib/active_support/core_ext/module.rb +3 -3
  87. data/lib/active_support/core_ext/name_error.rb +15 -2
  88. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  89. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  90. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  91. data/lib/active_support/core_ext/numeric/time.rb +31 -36
  92. data/lib/active_support/core_ext/numeric.rb +2 -0
  93. data/lib/active_support/core_ext/object/acts_like.rb +4 -4
  94. data/lib/active_support/core_ext/object/blank.rb +52 -18
  95. data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
  96. data/lib/active_support/core_ext/object/duplicable.rb +12 -20
  97. data/lib/active_support/core_ext/object/inclusion.rb +13 -1
  98. data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
  99. data/lib/active_support/core_ext/object/json.rb +205 -0
  100. data/lib/active_support/core_ext/object/to_param.rb +1 -55
  101. data/lib/active_support/core_ext/object/to_query.rb +66 -9
  102. data/lib/active_support/core_ext/object/try.rb +124 -33
  103. data/lib/active_support/core_ext/object/with_options.rb +37 -11
  104. data/lib/active_support/core_ext/object.rb +2 -1
  105. data/lib/active_support/core_ext/range/conversions.rb +17 -7
  106. data/lib/active_support/core_ext/range/each.rb +21 -0
  107. data/lib/active_support/core_ext/range/include_range.rb +20 -18
  108. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  109. data/lib/active_support/core_ext/range.rb +1 -2
  110. data/lib/active_support/core_ext/securerandom.rb +23 -0
  111. data/lib/active_support/core_ext/string/access.rb +95 -90
  112. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  113. data/lib/active_support/core_ext/string/conversions.rb +41 -38
  114. data/lib/active_support/core_ext/string/exclude.rb +6 -1
  115. data/lib/active_support/core_ext/string/filters.rb +70 -17
  116. data/lib/active_support/core_ext/string/indent.rb +43 -0
  117. data/lib/active_support/core_ext/string/inflections.rb +139 -59
  118. data/lib/active_support/core_ext/string/inquiry.rb +2 -2
  119. data/lib/active_support/core_ext/string/multibyte.rb +46 -65
  120. data/lib/active_support/core_ext/string/output_safety.rb +153 -56
  121. data/lib/active_support/core_ext/string/strip.rb +3 -6
  122. data/lib/active_support/core_ext/string/zones.rb +14 -0
  123. data/lib/active_support/core_ext/string.rb +2 -3
  124. data/lib/active_support/core_ext/struct.rb +3 -0
  125. data/lib/active_support/core_ext/time/calculations.rb +173 -173
  126. data/lib/active_support/core_ext/time/compatibility.rb +5 -0
  127. data/lib/active_support/core_ext/time/conversions.rb +33 -29
  128. data/lib/active_support/core_ext/time/marshal.rb +2 -56
  129. data/lib/active_support/core_ext/time/zones.rb +57 -32
  130. data/lib/active_support/core_ext/time.rb +5 -0
  131. data/lib/active_support/core_ext/uri.rb +13 -19
  132. data/lib/active_support/core_ext.rb +3 -2
  133. data/lib/active_support/dependencies/autoload.rb +47 -20
  134. data/lib/active_support/dependencies/interlock.rb +51 -0
  135. data/lib/active_support/dependencies.rb +315 -265
  136. data/lib/active_support/deprecation/behaviors.rb +71 -30
  137. data/lib/active_support/deprecation/instance_delegator.rb +24 -0
  138. data/lib/active_support/deprecation/method_wrappers.rb +59 -18
  139. data/lib/active_support/deprecation/proxy_wrappers.rb +82 -14
  140. data/lib/active_support/deprecation/reporting.rb +61 -14
  141. data/lib/active_support/deprecation.rb +38 -13
  142. data/lib/active_support/descendants_tracker.rb +34 -19
  143. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  144. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  145. data/lib/active_support/duration.rb +85 -14
  146. data/lib/active_support/evented_file_update_checker.rb +194 -0
  147. data/lib/active_support/execution_wrapper.rb +117 -0
  148. data/lib/active_support/executor.rb +6 -0
  149. data/lib/active_support/file_update_checker.rb +138 -17
  150. data/lib/active_support/gem_version.rb +15 -0
  151. data/lib/active_support/gzip.rb +11 -5
  152. data/lib/active_support/hash_with_indifferent_access.rb +199 -49
  153. data/lib/active_support/i18n.rb +6 -2
  154. data/lib/active_support/i18n_railtie.rb +40 -21
  155. data/lib/active_support/inflections.rb +22 -13
  156. data/lib/active_support/inflector/inflections.rb +175 -144
  157. data/lib/active_support/inflector/methods.rb +328 -91
  158. data/lib/active_support/inflector/transliterate.rb +51 -37
  159. data/lib/active_support/json/decoding.rb +31 -22
  160. data/lib/active_support/json/encoding.rb +88 -248
  161. data/lib/active_support/key_generator.rb +71 -0
  162. data/lib/active_support/lazy_load_hooks.rb +27 -25
  163. data/lib/active_support/locale/en.yml +102 -3
  164. data/lib/active_support/log_subscriber/test_helper.rb +24 -21
  165. data/lib/active_support/log_subscriber.rb +36 -49
  166. data/lib/active_support/logger.rb +106 -0
  167. data/lib/active_support/logger_silence.rb +28 -0
  168. data/lib/active_support/logger_thread_safe_level.rb +31 -0
  169. data/lib/active_support/message_encryptor.rb +72 -36
  170. data/lib/active_support/message_verifier.rb +96 -24
  171. data/lib/active_support/multibyte/chars.rb +88 -333
  172. data/lib/active_support/multibyte/unicode.rb +156 -136
  173. data/lib/active_support/multibyte.rb +5 -28
  174. data/lib/active_support/notifications/fanout.rb +115 -19
  175. data/lib/active_support/notifications/instrumenter.rb +52 -15
  176. data/lib/active_support/notifications.rb +168 -33
  177. data/lib/active_support/number_helper/number_converter.rb +182 -0
  178. data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
  179. data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
  180. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  181. data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
  182. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  183. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  184. data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
  185. data/lib/active_support/number_helper.rb +368 -0
  186. data/lib/active_support/option_merger.rb +1 -1
  187. data/lib/active_support/ordered_hash.rb +18 -183
  188. data/lib/active_support/ordered_options.rb +44 -24
  189. data/lib/active_support/per_thread_registry.rb +58 -0
  190. data/lib/active_support/proxy_object.rb +13 -0
  191. data/lib/active_support/rails.rb +27 -0
  192. data/lib/active_support/railtie.rb +25 -34
  193. data/lib/active_support/reloader.rb +129 -0
  194. data/lib/active_support/rescuable.rb +98 -48
  195. data/lib/active_support/security_utils.rb +27 -0
  196. data/lib/active_support/string_inquirer.rb +14 -9
  197. data/lib/active_support/subscriber.rb +120 -0
  198. data/lib/active_support/tagged_logging.rb +78 -0
  199. data/lib/active_support/test_case.rb +69 -17
  200. data/lib/active_support/testing/assertions.rb +43 -41
  201. data/lib/active_support/testing/autorun.rb +12 -0
  202. data/lib/active_support/testing/constant_lookup.rb +50 -0
  203. data/lib/active_support/testing/declarative.rb +7 -21
  204. data/lib/active_support/testing/deprecation.rb +14 -33
  205. data/lib/active_support/testing/file_fixtures.rb +34 -0
  206. data/lib/active_support/testing/isolation.rb +53 -95
  207. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  208. data/lib/active_support/testing/setup_and_teardown.rb +21 -82
  209. data/lib/active_support/testing/stream.rb +42 -0
  210. data/lib/active_support/testing/tagged_logging.rb +25 -0
  211. data/lib/active_support/testing/time_helpers.rb +134 -0
  212. data/lib/active_support/time.rb +6 -23
  213. data/lib/active_support/time_with_zone.rb +239 -92
  214. data/lib/active_support/values/time_zone.rb +236 -160
  215. data/lib/active_support/values/unicode_tables.dat +0 -0
  216. data/lib/active_support/version.rb +5 -7
  217. data/lib/active_support/xml_mini/jdom.rb +19 -13
  218. data/lib/active_support/xml_mini/libxml.rb +3 -4
  219. data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
  220. data/lib/active_support/xml_mini/nokogiri.rb +3 -4
  221. data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
  222. data/lib/active_support/xml_mini/rexml.rb +8 -10
  223. data/lib/active_support/xml_mini.rb +66 -34
  224. data/lib/active_support.rb +40 -23
  225. metadata +185 -134
  226. data/CHANGELOG +0 -1534
  227. data/lib/active_support/base64.rb +0 -42
  228. data/lib/active_support/basic_object.rb +0 -21
  229. data/lib/active_support/buffered_logger.rb +0 -137
  230. data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
  231. data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
  232. data/lib/active_support/core_ext/array/random_access.rb +0 -30
  233. data/lib/active_support/core_ext/array/uniq_by.rb +0 -16
  234. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
  235. data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
  236. data/lib/active_support/core_ext/date/freeze.rb +0 -31
  237. data/lib/active_support/core_ext/date_time/zones.rb +0 -21
  238. data/lib/active_support/core_ext/exception.rb +0 -3
  239. data/lib/active_support/core_ext/file/path.rb +0 -5
  240. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  241. data/lib/active_support/core_ext/float.rb +0 -1
  242. data/lib/active_support/core_ext/hash/deep_dup.rb +0 -11
  243. data/lib/active_support/core_ext/hash/diff.rb +0 -13
  244. data/lib/active_support/core_ext/kernel/requires.rb +0 -28
  245. data/lib/active_support/core_ext/logger.rb +0 -81
  246. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
  247. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  248. data/lib/active_support/core_ext/module/synchronization.rb +0 -43
  249. data/lib/active_support/core_ext/object/to_json.rb +0 -19
  250. data/lib/active_support/core_ext/proc.rb +0 -14
  251. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  252. data/lib/active_support/core_ext/process.rb +0 -1
  253. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  254. data/lib/active_support/core_ext/range/cover.rb +0 -3
  255. data/lib/active_support/core_ext/rexml.rb +0 -46
  256. data/lib/active_support/core_ext/string/encoding.rb +0 -11
  257. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  258. data/lib/active_support/core_ext/string/xchar.rb +0 -18
  259. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
  260. data/lib/active_support/file_watcher.rb +0 -36
  261. data/lib/active_support/json/variable.rb +0 -9
  262. data/lib/active_support/memoizable.rb +0 -105
  263. data/lib/active_support/multibyte/exceptions.rb +0 -8
  264. data/lib/active_support/multibyte/utils.rb +0 -60
  265. data/lib/active_support/ruby/shim.rb +0 -22
  266. data/lib/active_support/secure_random.rb +0 -6
  267. data/lib/active_support/testing/mochaing.rb +0 -7
  268. data/lib/active_support/testing/pending.rb +0 -52
  269. data/lib/active_support/testing/performance/jruby.rb +0 -115
  270. data/lib/active_support/testing/performance/rubinius.rb +0 -113
  271. data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
  272. data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
  273. data/lib/active_support/testing/performance/ruby.rb +0 -152
  274. data/lib/active_support/testing/performance.rb +0 -317
  275. data/lib/active_support/time/autoload.rb +0 -5
  276. data/lib/active_support/whiny_nil.rb +0 -60
@@ -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,102 @@ 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
+ pb: "PB"
110
+ eb: "EB"
111
+ # Used in NumberHelper.number_to_human()
112
+ decimal_units:
113
+ format: "%n %u"
114
+ # Decimal units output formatting
115
+ # By default we will only quantify some of the exponents
116
+ # but the commented ones might be defined or overridden
117
+ # by the user.
118
+ units:
119
+ # femto: Quadrillionth
120
+ # pico: Trillionth
121
+ # nano: Billionth
122
+ # micro: Millionth
123
+ # mili: Thousandth
124
+ # centi: Hundredth
125
+ # deci: Tenth
126
+ unit: ""
127
+ # ten:
128
+ # one: Ten
129
+ # other: Tens
130
+ # hundred: Hundred
131
+ thousand: Thousand
132
+ million: Million
133
+ billion: Billion
134
+ trillion: Trillion
135
+ quadrillion: Quadrillion
@@ -1,5 +1,5 @@
1
1
  require 'active_support/log_subscriber'
2
- require 'active_support/buffered_logger'
2
+ require 'active_support/logger'
3
3
  require 'active_support/notifications'
4
4
 
5
5
  module ActiveSupport
@@ -10,30 +10,30 @@ module ActiveSupport
10
10
  # class SyncLogSubscriberTest < ActiveSupport::TestCase
11
11
  # include ActiveSupport::LogSubscriber::TestHelper
12
12
  #
13
- # def setup
13
+ # setup do
14
14
  # ActiveRecord::LogSubscriber.attach_to(:active_record)
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
- # assert_match /Developer Load/, @logger.logged(:debug).last
22
- # assert_match /SELECT \* FROM "developers"/, @logger.logged(:debug).last
21
+ # assert_match(/Developer Load/, @logger.logged(:debug).last)
22
+ # assert_match(/SELECT \* FROM "developers"/, @logger.logged(:debug).last)
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
- def setup
36
+ def setup # :nodoc:
37
37
  @logger = MockLogger.new
38
38
  @notifier = ActiveSupport::Notifications::Fanout.new
39
39
 
@@ -44,13 +44,13 @@ module ActiveSupport
44
44
  ActiveSupport::Notifications.notifier = @notifier
45
45
  end
46
46
 
47
- def teardown
47
+ def teardown # :nodoc:
48
48
  set_logger(nil)
49
49
  ActiveSupport::Notifications.notifier = @old_notifier
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
@@ -1,12 +1,15 @@
1
1
  require 'active_support/core_ext/module/attribute_accessors'
2
2
  require 'active_support/core_ext/class/attribute'
3
+ require 'active_support/subscriber'
3
4
 
4
5
  module ActiveSupport
5
- # ActiveSupport::LogSubscriber is an object set to consume ActiveSupport::Notifications
6
- # with the sole purpose of logging them. The log subscriber dispatches notifications to
7
- # a registered object based on its given namespace.
6
+ # ActiveSupport::LogSubscriber is an object set to consume
7
+ # ActiveSupport::Notifications with the sole purpose of logging them.
8
+ # The log subscriber dispatches notifications to a registered object based
9
+ # on its given namespace.
8
10
  #
9
- # An example would be Active Record log subscriber responsible for logging queries:
11
+ # An example would be Active Record log subscriber responsible for logging
12
+ # queries:
10
13
  #
11
14
  # module ActiveRecord
12
15
  # class LogSubscriber < ActiveSupport::LogSubscriber
@@ -20,17 +23,18 @@ module ActiveSupport
20
23
  #
21
24
  # ActiveRecord::LogSubscriber.attach_to :active_record
22
25
  #
23
- # Since we need to know all instance methods before attaching the log subscriber,
24
- # the line above should be called after your <tt>ActiveRecord::LogSubscriber</tt> definition.
26
+ # Since we need to know all instance methods before attaching the log
27
+ # subscriber, the line above should be called after your
28
+ # <tt>ActiveRecord::LogSubscriber</tt> definition.
25
29
  #
26
30
  # After configured, whenever a "sql.active_record" notification is published,
27
31
  # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
28
32
  # the sql method.
29
33
  #
30
- # Log subscriber also has some helpers to deal with logging and automatically flushes
31
- # all logs when the request finishes (via action_dispatch.callback notification) in
32
- # a Rails environment.
33
- class LogSubscriber
34
+ # Log subscriber also has some helpers to deal with logging and automatically
35
+ # flushes all logs when the request finishes (via action_dispatch.callback
36
+ # notification) in a Rails environment.
37
+ class LogSubscriber < Subscriber
34
38
  # Embed in a String to clear all previous ANSI sequences.
35
39
  CLEAR = "\e[0m"
36
40
  BOLD = "\e[1m"
@@ -48,73 +52,56 @@ module ActiveSupport
48
52
  mattr_accessor :colorize_logging
49
53
  self.colorize_logging = true
50
54
 
51
- class_attribute :logger
52
-
53
55
  class << self
54
- remove_method :logger
55
56
  def logger
56
- @logger ||= Rails.logger if defined?(Rails)
57
- end
58
-
59
- def attach_to(namespace, log_subscriber=new, notifier=ActiveSupport::Notifications)
60
- log_subscribers << log_subscriber
61
- @@flushable_loggers = nil
62
-
63
- log_subscriber.public_methods(false).each do |event|
64
- next if 'call' == event.to_s
65
-
66
- notifier.subscribe("#{event}.#{namespace}", log_subscriber)
57
+ @logger ||= if defined?(Rails) && Rails.respond_to?(:logger)
58
+ Rails.logger
67
59
  end
68
60
  end
69
61
 
70
- def log_subscribers
71
- @@log_subscribers ||= []
72
- end
62
+ attr_writer :logger
73
63
 
74
- def flushable_loggers
75
- @@flushable_loggers ||= begin
76
- loggers = log_subscribers.map(&:logger)
77
- loggers.uniq!
78
- loggers.select { |l| l.respond_to?(:flush) }
79
- end
64
+ def log_subscribers
65
+ subscribers
80
66
  end
81
67
 
82
68
  # Flush all log_subscribers' logger.
83
69
  def flush_all!
84
- flushable_loggers.each { |log| log.flush }
70
+ logger.flush if logger.respond_to?(:flush)
85
71
  end
86
72
  end
87
73
 
88
- def call(message, *args)
89
- return unless logger
74
+ def logger
75
+ LogSubscriber.logger
76
+ end
77
+
78
+ def start(name, id, payload)
79
+ super if logger
80
+ end
90
81
 
91
- method = message.split('.').first
92
- begin
93
- send(method, ActiveSupport::Notifications::Event.new(message, *args))
94
- rescue Exception => e
95
- logger.error "Could not log #{message.inspect} event. #{e.class}: #{e.message}"
96
- end
82
+ def finish(name, id, payload)
83
+ super if logger
84
+ rescue Exception => e
85
+ logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
97
86
  end
98
87
 
99
88
  protected
100
89
 
101
90
  %w(info debug warn error fatal unknown).each do |level|
102
91
  class_eval <<-METHOD, __FILE__, __LINE__ + 1
103
- def #{level}(*args, &block)
104
- return unless logger
105
- logger.#{level}(*args, &block)
92
+ def #{level}(progname = nil, &block)
93
+ logger.#{level}(progname, &block) if logger
106
94
  end
107
95
  METHOD
108
96
  end
109
97
 
110
- # Set color by using a string or one of the defined constants. If a third
111
- # option is set to true, it also adds bold to the string. This is based
98
+ # Set color by using a symbol or one of the defined constants. If a third
99
+ # option is set to +true+, it also adds bold to the string. This is based
112
100
  # on the Highline implementation and will automatically append CLEAR to the
113
101
  # end of the returned String.
114
- #
115
102
  def color(text, color, bold=false)
116
103
  return text unless colorize_logging
117
- color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
104
+ color = self.class.const_get(color.upcase) if color.is_a?(Symbol)
118
105
  bold = bold ? BOLD : ""
119
106
  "#{bold}#{color}#{text}#{CLEAR}"
120
107
  end
@@ -0,0 +1,106 @@
1
+ require 'active_support/logger_silence'
2
+ require 'active_support/logger_thread_safe_level'
3
+ require 'logger'
4
+
5
+ module ActiveSupport
6
+ class Logger < ::Logger
7
+ include ActiveSupport::LoggerThreadSafeLevel
8
+ include LoggerSilence
9
+
10
+ # Returns true if the logger destination matches one of the sources
11
+ #
12
+ # logger = Logger.new(STDOUT)
13
+ # ActiveSupport::Logger.logger_outputs_to?(logger, STDOUT)
14
+ # # => true
15
+ def self.logger_outputs_to?(logger, *sources)
16
+ logdev = logger.instance_variable_get("@logdev")
17
+ logger_source = logdev.dev if logdev.respond_to?(:dev)
18
+ sources.any? { |source| source == logger_source }
19
+ end
20
+
21
+ # Broadcasts logs to multiple loggers.
22
+ def self.broadcast(logger) # :nodoc:
23
+ Module.new do
24
+ define_method(:add) do |*args, &block|
25
+ logger.add(*args, &block)
26
+ super(*args, &block)
27
+ end
28
+
29
+ define_method(:<<) do |x|
30
+ logger << x
31
+ super(x)
32
+ end
33
+
34
+ define_method(:close) do
35
+ logger.close
36
+ super()
37
+ end
38
+
39
+ define_method(:progname=) do |name|
40
+ logger.progname = name
41
+ super(name)
42
+ end
43
+
44
+ define_method(:formatter=) do |formatter|
45
+ logger.formatter = formatter
46
+ super(formatter)
47
+ end
48
+
49
+ define_method(:level=) do |level|
50
+ logger.level = level
51
+ super(level)
52
+ end
53
+
54
+ define_method(:local_level=) do |level|
55
+ logger.local_level = level if logger.respond_to?(:local_level=)
56
+ super(level) if respond_to?(:local_level=)
57
+ end
58
+
59
+ define_method(:silence) do |level = Logger::ERROR, &block|
60
+ if logger.respond_to?(:silence)
61
+ logger.silence(level) do
62
+ if respond_to?(:silence)
63
+ super(level, &block)
64
+ else
65
+ block.call(self)
66
+ end
67
+ end
68
+ else
69
+ if respond_to?(:silence)
70
+ super(level, &block)
71
+ else
72
+ block.call(self)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ def initialize(*args)
80
+ super
81
+ @formatter = SimpleFormatter.new
82
+ after_initialize if respond_to? :after_initialize
83
+ end
84
+
85
+ def add(severity, message = nil, progname = nil, &block)
86
+ return true if @logdev.nil? || (severity || UNKNOWN) < level
87
+ super
88
+ end
89
+
90
+ Logger::Severity.constants.each do |severity|
91
+ class_eval(<<-EOT, __FILE__, __LINE__ + 1)
92
+ def #{severity.downcase}? # def debug?
93
+ Logger::#{severity} >= level # DEBUG >= level
94
+ end # end
95
+ EOT
96
+ end
97
+
98
+ # Simple formatter which only displays the message.
99
+ class SimpleFormatter < ::Logger::Formatter
100
+ # This method is invoked when a log event occurs
101
+ def call(severity, timestamp, progname, msg)
102
+ "#{String === msg ? msg : msg.inspect}\n"
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,28 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/module/attribute_accessors'
3
+ require 'concurrent'
4
+
5
+ module LoggerSilence
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ cattr_accessor :silencer
10
+ self.silencer = true
11
+ end
12
+
13
+ # Silences the logger for the duration of the block.
14
+ def silence(temporary_level = Logger::ERROR)
15
+ if silencer
16
+ begin
17
+ old_local_level = local_level
18
+ self.local_level = temporary_level
19
+
20
+ yield self
21
+ ensure
22
+ self.local_level = old_local_level
23
+ end
24
+ else
25
+ yield self
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ require 'active_support/concern'
2
+
3
+ module ActiveSupport
4
+ module LoggerThreadSafeLevel # :nodoc:
5
+ extend ActiveSupport::Concern
6
+
7
+ def after_initialize
8
+ @local_levels = Concurrent::Map.new(initial_capacity: 2)
9
+ end
10
+
11
+ def local_log_id
12
+ Thread.current.__id__
13
+ end
14
+
15
+ def local_level
16
+ @local_levels[local_log_id]
17
+ end
18
+
19
+ def local_level=(level)
20
+ if level
21
+ @local_levels[local_log_id] = level
22
+ else
23
+ @local_levels.delete(local_log_id)
24
+ end
25
+ end
26
+
27
+ def level
28
+ local_level || super
29
+ end
30
+ end
31
+ end
@@ -1,41 +1,88 @@
1
1
  require 'openssl'
2
- require 'active_support/base64'
2
+ require 'base64'
3
+ require 'active_support/core_ext/array/extract_options'
3
4
 
4
5
  module ActiveSupport
5
- # MessageEncryptor is a simple way to encrypt values which get stored somewhere
6
- # you don't trust.
6
+ # MessageEncryptor is a simple way to encrypt values which get stored
7
+ # somewhere you don't trust.
7
8
  #
8
- # The cipher text and initialization vector are base64 encoded and returned to you.
9
+ # The cipher text and initialization vector are base64 encoded and returned
10
+ # to you.
9
11
  #
10
- # This can be used in situations similar to the <tt>MessageVerifier</tt>, but where you don't
11
- # want users to be able to determine the value of the payload.
12
+ # This can be used in situations similar to the <tt>MessageVerifier</tt>, but
13
+ # where you don't want users to be able to determine the value of the payload.
14
+ #
15
+ # salt = SecureRandom.random_bytes(64)
16
+ # key = ActiveSupport::KeyGenerator.new('password').generate_key(salt) # => "\x89\xE0\x156\xAC..."
17
+ # crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>
18
+ # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
19
+ # crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
12
20
  class MessageEncryptor
13
- class InvalidMessage < StandardError; end
14
- OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError
21
+ module NullSerializer #:nodoc:
22
+ def self.load(value)
23
+ value
24
+ end
25
+
26
+ def self.dump(value)
27
+ value
28
+ end
29
+ end
15
30
 
16
- def initialize(secret, cipher = 'aes-256-cbc')
31
+ class InvalidMessage < StandardError; end
32
+ OpenSSLCipherError = OpenSSL::Cipher::CipherError
33
+
34
+ # Initialize a new MessageEncryptor. +secret+ must be at least as long as
35
+ # the cipher key size. For the default 'aes-256-cbc' cipher, this is 256
36
+ # bits. If you are using a user-entered secret, you can generate a suitable
37
+ # key by using <tt>ActiveSupport::KeyGenerator</tt> or a similar key
38
+ # derivation function.
39
+ #
40
+ # Options:
41
+ # * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by
42
+ # <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'.
43
+ # * <tt>:digest</tt> - String of digest to use for signing. Default is +SHA1+.
44
+ # * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
45
+ def initialize(secret, *signature_key_or_options)
46
+ options = signature_key_or_options.extract_options!
47
+ sign_secret = signature_key_or_options.first
17
48
  @secret = secret
18
- @cipher = cipher
49
+ @sign_secret = sign_secret
50
+ @cipher = options[:cipher] || 'aes-256-cbc'
51
+ @verifier = MessageVerifier.new(@sign_secret || @secret, digest: options[:digest] || 'SHA1', serializer: NullSerializer)
52
+ @serializer = options[:serializer] || Marshal
19
53
  end
20
54
 
21
- def encrypt(value)
22
- cipher = new_cipher
23
- # Rely on OpenSSL for the initialization vector
24
- iv = cipher.random_iv
55
+ # Encrypt and sign a message. We need to sign the message in order to avoid
56
+ # padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks.
57
+ def encrypt_and_sign(value)
58
+ verifier.generate(_encrypt(value))
59
+ end
25
60
 
61
+ # Decrypt and verify a message. We need to verify the message in order to
62
+ # avoid padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks.
63
+ def decrypt_and_verify(value)
64
+ _decrypt(verifier.verify(value))
65
+ end
66
+
67
+ private
68
+
69
+ def _encrypt(value)
70
+ cipher = new_cipher
26
71
  cipher.encrypt
27
72
  cipher.key = @secret
28
- cipher.iv = iv
29
73
 
30
- encrypted_data = cipher.update(Marshal.dump(value))
74
+ # Rely on OpenSSL for the initialization vector
75
+ iv = cipher.random_iv
76
+
77
+ encrypted_data = cipher.update(@serializer.dump(value))
31
78
  encrypted_data << cipher.final
32
79
 
33
- [encrypted_data, iv].map {|v| ActiveSupport::Base64.encode64s(v)}.join("--")
80
+ "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}"
34
81
  end
35
82
 
36
- def decrypt(encrypted_message)
83
+ def _decrypt(encrypted_message)
37
84
  cipher = new_cipher
38
- encrypted_data, iv = encrypted_message.split("--").map {|v| ActiveSupport::Base64.decode64(v)}
85
+ encrypted_data, iv = encrypted_message.split("--".freeze).map {|v| ::Base64.strict_decode64(v)}
39
86
 
40
87
  cipher.decrypt
41
88
  cipher.key = @secret
@@ -44,28 +91,17 @@ module ActiveSupport
44
91
  decrypted_data = cipher.update(encrypted_data)
45
92
  decrypted_data << cipher.final
46
93
 
47
- Marshal.load(decrypted_data)
48
- rescue OpenSSLCipherError, TypeError
94
+ @serializer.load(decrypted_data)
95
+ rescue OpenSSLCipherError, TypeError, ArgumentError
49
96
  raise InvalidMessage
50
97
  end
51
98
 
52
- def encrypt_and_sign(value)
53
- verifier.generate(encrypt(value))
99
+ def new_cipher
100
+ OpenSSL::Cipher.new(@cipher)
54
101
  end
55
102
 
56
- def decrypt_and_verify(value)
57
- decrypt(verifier.verify(value))
103
+ def verifier
104
+ @verifier
58
105
  end
59
-
60
-
61
-
62
- private
63
- def new_cipher
64
- OpenSSL::Cipher::Cipher.new(@cipher)
65
- end
66
-
67
- def verifier
68
- MessageVerifier.new(@secret)
69
- end
70
106
  end
71
107
  end