Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of github.com:lifo/docrails

  • Loading branch information...
commit eaae58ce0c79aa5b4d6de16e2e67034b7fd971bb 2 parents c5acbcb + c71120e
@mikel mikel authored
Showing with 1,497 additions and 1,308 deletions.
  1. +37 −4 actionmailer/lib/action_mailer/base.rb
  2. +16 −22 actionmailer/lib/action_mailer/deprecated_body.rb
  3. +4 −6 actionmailer/test/mail_service_test.rb
  4. +74 −66 actionpack/lib/abstract_controller/base.rb
  5. +1 −4 actionpack/lib/action_controller/deprecated/dispatcher.rb
  6. +3 −183 actionpack/lib/action_controller/metal/cookies.rb
  7. +0 −4 actionpack/lib/action_controller/metal/instrumentation.rb
  8. +3 −0  actionpack/lib/action_controller/metal/testing.rb
  9. +0 −50 actionpack/lib/action_controller/railtie.rb
  10. +1 −6 actionpack/lib/action_controller/railties/subscriber.rb
  11. +2 −0  actionpack/lib/action_dispatch.rb
  12. +1 −1  actionpack/lib/action_dispatch/http/response.rb
  13. +0 −2  actionpack/lib/action_dispatch/middleware/callbacks.rb
  14. +216 −0 actionpack/lib/action_dispatch/middleware/cookies.rb
  15. +24 −0 actionpack/lib/action_dispatch/middleware/notifications.rb
  16. +22 −10 actionpack/lib/action_dispatch/middleware/show_exceptions.rb
  17. +8 −1 actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
  18. +3 −3 actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb
  19. +1 −1  actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
  20. +29 −0 actionpack/lib/action_dispatch/railtie.rb
  21. +17 −0 actionpack/lib/action_dispatch/railties/subscriber.rb
  22. +25 −34 actionpack/lib/action_dispatch/routing/mapper.rb
  23. +2 −2 actionpack/lib/action_view/helpers/debug_helper.rb
  24. +1 −0  actionpack/test/abstract_unit.rb
  25. +2 −2 actionpack/test/activerecord/controller_runtime_test.rb
  26. +10 −27 actionpack/test/controller/cookie_test.rb
  27. +0 −27 actionpack/test/controller/filter_params_test.rb
  28. +1 −1  actionpack/test/controller/flash_test.rb
  29. +27 −1 actionpack/test/controller/new_base/base_test.rb
  30. +14 −28 actionpack/test/controller/subscriber_test.rb
  31. +0 −12 actionpack/test/dispatch/callbacks_test.rb
  32. +3 −6 actionpack/test/dispatch/response_test.rb
  33. +2 −2 actionpack/test/dispatch/session/cookie_store_test.rb
  34. +12 −33 actionpack/test/dispatch/show_exceptions_test.rb
  35. +112 −0 actionpack/test/dispatch/subscriber_test.rb
  36. +1 −1  actionpack/test/fixtures/reply.rb
  37. +2 −0  activemodel/lib/active_model/errors.rb
  38. +2 −0  activemodel/lib/active_model/validations/validates.rb
  39. +8 −0 activemodel/test/cases/validations_test.rb
  40. +10 −0 activerecord/CHANGELOG
  41. +7 −27 activerecord/lib/active_record/associations.rb
  42. +0 −2  activerecord/lib/active_record/associations/association_collection.rb
  43. +1 −1  activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
  44. +1 −1  activerecord/lib/active_record/associations/has_many_association.rb
  45. +1 −1  activerecord/lib/active_record/associations/has_many_through_association.rb
  46. +5 −5 activerecord/lib/active_record/autosave_association.rb
  47. +5 −5 activerecord/lib/active_record/base.rb
  48. +10 −49 activerecord/lib/active_record/calculations.rb
  49. +1 −1  activerecord/lib/active_record/callbacks.rb
  50. +69 −84 activerecord/lib/active_record/named_scope.rb
  51. +1 −1  activerecord/lib/active_record/railties/databases.rake
  52. +1 −1  activerecord/lib/active_record/railties/subscriber.rb
  53. +12 −32 activerecord/lib/active_record/relation.rb
  54. +36 −0 activerecord/lib/active_record/relation/finder_methods.rb
  55. +2 −1  activerecord/lib/active_record/relation/predicate_builder.rb
  56. +10 −10 activerecord/lib/active_record/relation/spawn_methods.rb
  57. +2 −2 activerecord/lib/active_record/transactions.rb
  58. +11 −1 activerecord/lib/active_record/validations.rb
  59. +8 −0 {railties/lib/rails → activerecord/lib}/generators/active_record.rb
  60. +1 −1  {railties/lib/rails → activerecord/lib}/generators/active_record/migration/migration_generator.rb
  61. 0  {railties/lib/rails → activerecord/lib}/generators/active_record/migration/templates/migration.rb
  62. +1 −1  {railties/lib/rails → activerecord/lib}/generators/active_record/model/model_generator.rb
  63. 0  {railties/lib/rails → activerecord/lib}/generators/active_record/model/templates/migration.rb
  64. 0  {railties/lib/rails → activerecord/lib}/generators/active_record/model/templates/model.rb
  65. +1 −1  {railties/lib/rails → activerecord/lib}/generators/active_record/observer/observer_generator.rb
  66. 0  {railties/lib/rails → activerecord/lib}/generators/active_record/observer/templates/observer.rb
  67. +1 −1  ...ib/rails → activerecord/lib}/generators/active_record/session_migration/session_migration_generator.rb
  68. 0  {railties/lib/rails → activerecord/lib}/generators/active_record/session_migration/templates/migration.rb
  69. +6 −6 activerecord/test/cases/autosave_association_test.rb
  70. +3 −1 activerecord/test/cases/base_test.rb
  71. +7 −7 activerecord/test/cases/method_scoping_test.rb
  72. +24 −19 activerecord/test/cases/named_scope_test.rb
  73. +10 −7 activerecord/test/cases/relations_test.rb
  74. +27 −2 activerecord/test/cases/validations_test.rb
  75. +3 −3 activerecord/test/models/comment.rb
  76. +3 −5 activerecord/test/models/company.rb
  77. +2 −2 activerecord/test/models/developer.rb
  78. +1 −1  activerecord/test/models/organization.rb
  79. +2 −2 activerecord/test/models/person.rb
  80. +9 −9 activerecord/test/models/post.rb
  81. +1 −1  activerecord/test/models/reply.rb
  82. +11 −11 activerecord/test/models/topic.rb
  83. +12 −3 activeresource/lib/active_resource/validations.rb
  84. +13 −0 activeresource/test/cases/validations_test.rb
  85. +24 −8 activesupport/lib/active_support/backtrace_cleaner.rb
  86. +4 −4 activesupport/lib/active_support/cache.rb
  87. +0 −47 activesupport/lib/active_support/core_ext/exception.rb
  88. +1 −1  activesupport/lib/active_support/notifications.rb
  89. +9 −0 activesupport/lib/active_support/notifications/instrumenter.rb
  90. +0 −69 activesupport/test/core_ext/exception_test.rb
  91. +16 −0 activesupport/test/notifications_test.rb
  92. +1 −1  railties/bin/rails
  93. 0  railties/lib/{rails → }/generators/erb.rb
  94. +1 −1  railties/lib/{rails → }/generators/erb/controller/controller_generator.rb
  95. 0  railties/lib/{rails → }/generators/erb/controller/templates/view.html.erb
  96. +1 −1  railties/lib/{rails → }/generators/erb/mailer/mailer_generator.rb
  97. 0  railties/lib/{rails → }/generators/erb/mailer/templates/view.erb
  98. +1 −1  railties/lib/{rails → }/generators/erb/scaffold/scaffold_generator.rb
  99. 0  railties/lib/{rails → }/generators/erb/scaffold/templates/_form.html.erb
  100. 0  railties/lib/{rails → }/generators/erb/scaffold/templates/edit.html.erb
  101. 0  railties/lib/{rails → }/generators/erb/scaffold/templates/index.html.erb
  102. 0  railties/lib/{rails → }/generators/erb/scaffold/templates/layout.html.erb
  103. 0  railties/lib/{rails → }/generators/erb/scaffold/templates/new.html.erb
  104. 0  railties/lib/{rails → }/generators/erb/scaffold/templates/show.html.erb
  105. 0  railties/lib/{rails → }/generators/rails/app/USAGE
  106. +3 −3 railties/lib/{rails → }/generators/rails/app/app_generator.rb
  107. 0  railties/lib/{rails → }/generators/rails/app/templates/Gemfile
  108. 0  railties/lib/{rails → }/generators/rails/app/templates/README
  109. 0  railties/lib/{rails → }/generators/rails/app/templates/Rakefile
  110. 0  railties/lib/{rails → }/generators/rails/app/templates/app/controllers/application_controller.rb
  111. 0  railties/lib/{rails → }/generators/rails/app/templates/app/helpers/application_helper.rb
  112. 0  ...tors/rails/generator/templates/templates → generators/rails/app/templates/app/models}/.empty_directory
  113. 0  ...ors/rails/app/templates/test/unit → generators/rails/app/templates/app/views/layouts}/.empty_directory
  114. 0  railties/lib/{rails → }/generators/rails/app/templates/config.ru
  115. 0  railties/lib/{rails → }/generators/rails/app/templates/config/application.rb
  116. +12 −1 railties/lib/{rails → }/generators/rails/app/templates/config/boot.rb
  117. 0  railties/lib/{rails → }/generators/rails/app/templates/config/databases/frontbase.yml
  118. 0  railties/lib/{rails → }/generators/rails/app/templates/config/databases/ibm_db.yml
  119. 0  railties/lib/{rails → }/generators/rails/app/templates/config/databases/mysql.yml
  120. 0  railties/lib/{rails → }/generators/rails/app/templates/config/databases/oracle.yml
  121. 0  railties/lib/{rails → }/generators/rails/app/templates/config/databases/postgresql.yml
  122. 0  railties/lib/{rails → }/generators/rails/app/templates/config/databases/sqlite3.yml
  123. 0  railties/lib/{rails → }/generators/rails/app/templates/config/environment.rb
  124. 0  railties/lib/{rails → }/generators/rails/app/templates/config/environments/development.rb.tt
  125. 0  railties/lib/{rails → }/generators/rails/app/templates/config/environments/production.rb.tt
  126. 0  railties/lib/{rails → }/generators/rails/app/templates/config/environments/test.rb.tt
  127. 0  railties/lib/{rails → }/generators/rails/app/templates/config/initializers/backtrace_silencers.rb
  128. 0  ...ies/lib/{rails → }/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt
  129. 0  railties/lib/{rails → }/generators/rails/app/templates/config/initializers/inflections.rb
  130. 0  railties/lib/{rails → }/generators/rails/app/templates/config/initializers/mime_types.rb
  131. 0  railties/lib/{rails → }/generators/rails/app/templates/config/initializers/session_store.rb.tt
  132. 0  railties/lib/{rails → }/generators/rails/app/templates/config/locales/en.yml
  133. 0  railties/lib/{rails → }/generators/rails/app/templates/config/routes.rb
  134. 0  railties/lib/{rails → }/generators/rails/app/templates/db/seeds.rb
  135. 0  railties/lib/{rails → }/generators/rails/app/templates/doc/README_FOR_APP
  136. 0  railties/lib/{rails → }/generators/rails/app/templates/gitignore
  137. 0  railties/lib/{rails → }/generators/rails/app/templates/public/404.html
  138. 0  railties/lib/{rails → }/generators/rails/app/templates/public/422.html
  139. 0  railties/lib/{rails → }/generators/rails/app/templates/public/500.html
  140. 0  railties/lib/{rails → }/generators/rails/app/templates/public/favicon.ico
  141. 0  railties/lib/{rails → }/generators/rails/app/templates/public/images/rails.png
  142. 0  railties/lib/{rails → }/generators/rails/app/templates/public/index.html
  143. 0  railties/lib/{rails → }/generators/rails/app/templates/public/javascripts/application.js
  144. 0  railties/lib/{rails → }/generators/rails/app/templates/public/javascripts/controls.js
  145. 0  railties/lib/{rails → }/generators/rails/app/templates/public/javascripts/dragdrop.js
  146. 0  railties/lib/{rails → }/generators/rails/app/templates/public/javascripts/effects.js
  147. 0  railties/lib/{rails → }/generators/rails/app/templates/public/javascripts/prototype.js
  148. 0  railties/lib/{rails → }/generators/rails/app/templates/public/robots.txt
  149. 0  ...s/app/templates/test/integration → generators/rails/app/templates/public/stylesheets}/.empty_directory
  150. 0  railties/lib/{rails → }/generators/rails/app/templates/script/about
  151. 0  railties/lib/{rails → }/generators/rails/app/templates/script/console.tt
  152. 0  railties/lib/{rails → }/generators/rails/app/templates/script/dbconsole.tt
  153. 0  railties/lib/{rails → }/generators/rails/app/templates/script/destroy
  154. 0  railties/lib/{rails → }/generators/rails/app/templates/script/generate
  155. 0  railties/lib/{rails → }/generators/rails/app/templates/script/performance/benchmarker
  156. 0  railties/lib/{rails → }/generators/rails/app/templates/script/performance/profiler
  157. 0  railties/lib/{rails → }/generators/rails/app/templates/script/plugin
  158. 0  railties/lib/{rails → }/generators/rails/app/templates/script/runner
  159. 0  railties/lib/{rails → }/generators/rails/app/templates/script/server.tt
  160. 0  ...s/rails/app/templates/test/functional → generators/rails/app/templates/test/fixtures}/.empty_directory
  161. 0  ...s/rails/app/templates/test/fixtures → generators/rails/app/templates/test/functional}/.empty_directory
  162. 0  ...s/app/templates/public/stylesheets → generators/rails/app/templates/test/integration}/.empty_directory
  163. 0  railties/lib/{rails → }/generators/rails/app/templates/test/performance/browsing_test.rb
  164. 0  railties/lib/{rails → }/generators/rails/app/templates/test/test_helper.rb
  165. 0  ...ors/rails/app/templates/app/views/layouts → generators/rails/app/templates/test/unit}/.empty_directory
  166. 0  railties/lib/{rails → }/generators/rails/controller/USAGE
  167. 0  railties/lib/{rails → }/generators/rails/controller/controller_generator.rb
  168. 0  railties/lib/{rails → }/generators/rails/controller/templates/controller.rb
  169. 0  railties/lib/{rails → }/generators/rails/generator/USAGE
  170. 0  railties/lib/{rails → }/generators/rails/generator/generator_generator.rb
  171. 0  railties/lib/{rails → }/generators/rails/generator/templates/%file_name%_generator.rb.tt
  172. 0  railties/lib/{rails → }/generators/rails/generator/templates/USAGE.tt
  173. 0  ...tors/rails/app/templates/app/models → generators/rails/generator/templates/templates}/.empty_directory
  174. 0  railties/lib/{rails → }/generators/rails/helper/USAGE
  175. 0  railties/lib/{rails → }/generators/rails/helper/helper_generator.rb
  176. 0  railties/lib/{rails → }/generators/rails/helper/templates/helper.rb
  177. 0  railties/lib/{rails → }/generators/rails/integration_test/USAGE
  178. 0  railties/lib/{rails → }/generators/rails/integration_test/integration_test_generator.rb
  179. +2 −2 railties/lib/{rails → }/generators/rails/mailer/USAGE
  180. +1 −1  railties/lib/{rails → }/generators/rails/mailer/mailer_generator.rb
  181. 0  railties/lib/{rails → }/generators/rails/mailer/templates/mailer.rb
  182. 0  railties/lib/{rails → }/generators/rails/metal/USAGE
  183. 0  railties/lib/{rails → }/generators/rails/metal/metal_generator.rb
  184. 0  railties/lib/{rails → }/generators/rails/metal/templates/metal.rb
  185. 0  railties/lib/{rails → }/generators/rails/migration/USAGE
  186. 0  railties/lib/{rails → }/generators/rails/migration/migration_generator.rb
  187. 0  railties/lib/{rails → }/generators/rails/model/USAGE
  188. 0  railties/lib/{rails → }/generators/rails/model/model_generator.rb
  189. +1 −0  railties/lib/{rails → }/generators/rails/model_subclass/model_subclass_generator.rb
  190. 0  railties/lib/{rails → }/generators/rails/observer/USAGE
  191. 0  railties/lib/{rails → }/generators/rails/observer/observer_generator.rb
  192. 0  railties/lib/{rails → }/generators/rails/performance_test/USAGE
  193. 0  railties/lib/{rails → }/generators/rails/performance_test/performance_test_generator.rb
  194. 0  railties/lib/{rails → }/generators/rails/plugin/USAGE
  195. +7 −7 railties/lib/{rails → }/generators/rails/plugin/plugin_generator.rb
  196. 0  ...ails/generators/rails/plugin/templates/MIT-LICENSE → generators/rails/plugin/templates/MIT-LICENSE.tt}
  197. 0  ...ies/lib/{rails/generators/rails/plugin/templates/README → generators/rails/plugin/templates/README.tt}
  198. 0  ...lib/{rails/generators/rails/plugin/templates/Rakefile → generators/rails/plugin/templates/Rakefile.tt}
  199. 0  railties/lib/{rails → }/generators/rails/plugin/templates/init.rb
  200. 0  railties/lib/{rails → }/generators/rails/plugin/templates/install.rb
  201. 0  railties/lib/{rails → }/generators/rails/plugin/templates/lib/%file_name%.rb.tt
  202. 0  railties/lib/{rails → }/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt
  203. 0  railties/lib/{rails → }/generators/rails/plugin/templates/uninstall.rb
  204. 0  railties/lib/{rails → }/generators/rails/resource/USAGE
  205. +1 −1  railties/lib/{rails → }/generators/rails/resource/resource_generator.rb
  206. 0  railties/lib/{rails → }/generators/rails/scaffold/USAGE
  207. +1 −1  railties/lib/{rails → }/generators/rails/scaffold/scaffold_generator.rb
  208. 0  railties/lib/{rails → }/generators/rails/scaffold_controller/USAGE
  209. 0  railties/lib/{rails → }/generators/rails/scaffold_controller/scaffold_controller_generator.rb
  210. 0  railties/lib/{rails → }/generators/rails/scaffold_controller/templates/controller.rb
  211. 0  railties/lib/{rails → }/generators/rails/session_migration/USAGE
  212. 0  railties/lib/{rails → }/generators/rails/session_migration/session_migration_generator.rb
  213. 0  railties/lib/{rails → }/generators/rails/stylesheets/USAGE
  214. 0  railties/lib/{rails → }/generators/rails/stylesheets/stylesheets_generator.rb
  215. 0  railties/lib/{rails → }/generators/rails/stylesheets/templates/scaffold.css
  216. 0  railties/lib/{rails → }/generators/test_unit.rb
  217. +1 −1  railties/lib/{rails → }/generators/test_unit/controller/controller_generator.rb
  218. 0  railties/lib/{rails → }/generators/test_unit/controller/templates/functional_test.rb
  219. +1 −1  railties/lib/{rails → }/generators/test_unit/helper/helper_generator.rb
  220. 0  railties/lib/{rails → }/generators/test_unit/helper/templates/helper_test.rb
  221. +1 −1  railties/lib/{rails → }/generators/test_unit/integration/integration_generator.rb
  222. 0  railties/lib/{rails → }/generators/test_unit/integration/templates/integration_test.rb
  223. +2 −2 railties/lib/{rails → }/generators/test_unit/mailer/mailer_generator.rb
  224. 0  railties/lib/{rails → }/generators/test_unit/mailer/templates/fixture
  225. 0  ...rs/test_unit/mailer/templates/unit_test.rb → generators/test_unit/mailer/templates/functional_test.rb}
  226. +1 −1  railties/lib/{rails → }/generators/test_unit/model/model_generator.rb
  227. 0  railties/lib/{rails → }/generators/test_unit/model/templates/fixtures.yml
  228. 0  railties/lib/{rails → }/generators/test_unit/model/templates/unit_test.rb
  229. +1 −1  railties/lib/{rails → }/generators/test_unit/observer/observer_generator.rb
  230. 0  railties/lib/{rails → }/generators/test_unit/observer/templates/unit_test.rb
  231. +1 −1  railties/lib/{rails → }/generators/test_unit/performance/performance_generator.rb
  232. 0  railties/lib/{rails → }/generators/test_unit/performance/templates/performance_test.rb
  233. +1 −1  railties/lib/{rails → }/generators/test_unit/plugin/plugin_generator.rb
  234. 0  railties/lib/{rails → }/generators/test_unit/plugin/templates/%file_name%_test.rb.tt
  235. 0  railties/lib/{rails → }/generators/test_unit/plugin/templates/test_helper.rb
  236. +1 −1  railties/lib/{rails → }/generators/test_unit/scaffold/scaffold_generator.rb
  237. 0  railties/lib/{rails → }/generators/test_unit/scaffold/templates/functional_test.rb
  238. +3 −2 railties/lib/rails.rb
  239. +12 −2 railties/lib/rails/application.rb
  240. +16 −15 railties/lib/rails/backtrace_cleaner.rb
  241. +8 −3 railties/lib/rails/bootstrap.rb
  242. +7 −16 railties/lib/rails/configuration.rb
  243. +3 −3 railties/lib/rails/deprecation.rb
  244. +93 −91 railties/lib/rails/generators.rb
  245. +6 −2 railties/lib/rails/generators/base.rb
  246. +5 −3 railties/lib/rails/generators/named_base.rb
  247. +7 −3 railties/lib/rails/generators/resource_helpers.rb
  248. +6 −2 railties/lib/rails/plugin.rb
  249. +3 −2 railties/lib/rails/rack.rb
  250. +26 −0 railties/lib/rails/rack/metal.rb
  251. +1 −1  railties/lib/rails/subscriber.rb
  252. +1 −1  railties/lib/rails/tasks/documentation.rake
  253. +4 −3 railties/lib/rails/tasks/framework.rake
  254. +6 −3 railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb
  255. +2 −0  railties/test/application/middleware_test.rb
  256. +1 −1  railties/test/application/notifications_test.rb
  257. +2 −2 railties/test/backtrace_cleaner_test.rb
  258. +1 −1  railties/test/fixtures/lib/generators/active_record/{fixjour → }/fixjour_generator.rb
  259. +0 −4 railties/test/fixtures/lib/generators/rails/javascripts_generator.rb
  260. 0  railties/test/fixtures/{vendor/gems/gems/wrong → }/lib/generators/wrong_generator.rb
  261. +0 −2  railties/test/fixtures/vendor/another_gem_path/xspec/lib/generators/xspec_generator.rb
  262. +0 −2  railties/test/fixtures/vendor/plugins/mspec/lib/rails_generators/mspec_generator.rb
  263. +16 −2 railties/test/generators/actions_test.rb
  264. +8 −8 railties/test/generators/app_generator_test.rb
  265. +3 −2 railties/test/generators/controller_generator_test.rb
  266. +3 −2 railties/test/generators/generator_generator_test.rb
  267. +10 −12 railties/test/generators/generators_test_helper.rb
  268. +3 −2 railties/test/generators/helper_generator_test.rb
  269. +3 −2 railties/test/generators/integration_test_generator_test.rb
  270. +7 −6 railties/test/generators/mailer_generator_test.rb
  271. +3 −2 railties/test/generators/metal_generator_test.rb
  272. +4 −2 railties/test/generators/migration_generator_test.rb
  273. +3 −2 railties/test/generators/model_generator_test.rb
  274. +3 −2 railties/test/generators/named_base_test.rb
  275. +3 −2 railties/test/generators/observer_generator_test.rb
  276. +3 −2 railties/test/generators/performance_test_generator_test.rb
  277. +18 −2 railties/test/generators/plugin_generator_test.rb
  278. +3 −2 railties/test/generators/resource_generator_test.rb
  279. +3 −2 railties/test/generators/scaffold_controller_generator_test.rb
  280. +3 −2 railties/test/generators/scaffold_generator_test.rb
  281. +4 −2 railties/test/generators/session_migration_generator_test.rb
  282. +4 −2 railties/test/generators/stylesheets_generator_test.rb
  283. +61 −76 railties/test/generators_test.rb
  284. +3 −3 railties/test/subscriber_test.rb
View
41 actionmailer/lib/action_mailer/base.rb
@@ -23,8 +23,7 @@ module ActionMailer #:nodoc:
# bcc ["bcc@example.com", "Order Watcher <watcher@example.com>"]
# from "system@example.com"
# subject "New account information"
- #
- # @account = recipient
+ # body :account => recipient
# end
# end
#
@@ -144,12 +143,13 @@ module ActionMailer #:nodoc:
# subject "New account information"
# from "system@example.com"
# content_type "multipart/alternative"
+ # body :account => recipient
#
# part :content_type => "text/html",
- # :body => render_message("signup-as-html", :account => recipient)
+ # :data => render_message("signup-as-html")
#
# part "text/plain" do |p|
- # p.body = render_message("signup-as-plain", :account => recipient)
+ # p.body = render_message("signup-as-plain")
# p.content_transfer_encoding = "base64"
# end
# end
@@ -454,11 +454,13 @@ def matches_dynamic_method?(method_name) #:nodoc:
# body, headers, etc.) can be set on it.
def part(params)
params = {:content_type => params} if String === params
+
if custom_headers = params.delete(:headers)
ActiveSupport::Deprecation.warn('Passing custom headers with :headers => {} is deprecated. ' <<
'Please just pass in custom headers directly.', caller[0,10])
params.merge!(custom_headers)
end
+
part = Mail::Part.new(params)
yield part if block_given?
@parts << part
@@ -476,6 +478,20 @@ def attachment(params, &block)
part(params, &block)
end
+ # Allow you to set assigns for your template:
+ #
+ # body :greetings => "Hi"
+ #
+ # Will make @greetings available in the template to be rendered.
+ def body(object=nil)
+ returning(super) do # Run deprecation hooks
+ if object.is_a?(Hash)
+ @assigns_set = true
+ object.each { |k, v| instance_variable_set(:"@#{k}", v) }
+ end
+ end
+ end
+
# Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
# will be initialized according to the named method. If not, the mailer will
# remain uninitialized (useful when you only need to invoke the "receive"
@@ -523,6 +539,23 @@ def deliver!(mail = @mail)
private
+ # Render a message but does not set it as mail body. Useful for rendering
+ # data for part and attachments.
+ #
+ # Examples:
+ #
+ # render_message "special_message"
+ # render_message :template => "special_message"
+ # render_message :inline => "<%= 'Hi!' %>"
+ def render_message(object)
+ case object
+ when String
+ render_to_body(:template => object)
+ else
+ render_to_body(object)
+ end
+ end
+
# Set up the default values for the various instance variables of this
# mailer. Subclasses may override this method to provide different
# defaults.
View
38 actionmailer/lib/action_mailer/deprecated_body.rb
@@ -1,15 +1,13 @@
module ActionMailer
# TODO Remove this module all together in a next release. Ensure that super
- # hooks in ActionMailer::Base are removed as well.
+ # hooks and @assigns_set in ActionMailer::Base are removed as well.
module DeprecatedBody
- def self.included(base)
- base.class_eval do
- # Define the body of the message. This is either a Hash (in which case it
- # specifies the variables to pass to the template when it is rendered),
- # or a string, in which case it specifies the actual text of the message.
- adv_attr_accessor :body
- end
- end
+ extend ActionMailer::AdvAttrAccessor
+
+ # Define the body of the message. This is either a Hash (in which case it
+ # specifies the variables to pass to the template when it is rendered),
+ # or a string, in which case it specifies the actual text of the message.
+ adv_attr_accessor :body
def initialize_defaults(method_name)
@body ||= {}
@@ -18,32 +16,28 @@ def initialize_defaults(method_name)
def attachment(params, &block)
if params[:body]
ActiveSupport::Deprecation.warn('attachment :body => "string" is deprecated. To set the body of an attachment ' <<
- 'please use :data instead, like attachment :data => "string".', caller[0,10])
+ 'please use :data instead, like attachment :data => "string"', caller[0,10])
params[:data] = params.delete(:body)
end
end
def create_parts
- if String === @body
- ActiveSupport::Deprecation.warn('body is deprecated. To set the body with a text ' <<
- 'call render(:text => "body").', caller[0,10])
+ if String === @body && !defined?(@assigns_set)
+ ActiveSupport::Deprecation.warn('body(String) is deprecated. To set the body with a text ' <<
+ 'call render(:text => "body")', caller[0,10])
self.response_body = @body
- elsif @body.is_a?(Hash) && !@body.empty?
- ActiveSupport::Deprecation.warn('body is deprecated. To set assigns simply ' <<
- 'use instance variables', caller[0,10])
- @body.each { |k, v| instance_variable_set(:"@#{k}", v) }
+ elsif self.response_body
+ @body = self.response_body
end
end
def render(*args)
options = args.last.is_a?(Hash) ? args.last : {}
if options[:body]
- ActiveSupport::Deprecation.warn(':body is deprecated. To set assigns simply ' <<
- 'use instance variables', caller[0,1])
+ ActiveSupport::Deprecation.warn(':body in render deprecated. Please call body ' <<
+ 'with a hash instead', caller[0,1])
- options.delete(:body).each do |k, v|
- instance_variable_set(:"@#{k}", v)
- end
+ body options.delete(:body)
end
super
View
10 actionmailer/test/mail_service_test.rb
@@ -120,11 +120,11 @@ def multipart_with_mime_version(recipient)
content_type "multipart/alternative"
part "text/plain" do |p|
- p.body = "blah"
+ p.body = render_message(:text => "blah")
end
part "text/html" do |p|
- p.body = "<b>blah</b>"
+ p.body = render_message(:inline => "<%= content_tag(:b, 'blah') %>")
end
end
@@ -301,7 +301,6 @@ def return_path
render :text => "testing"
end
- # This tests body calls accepeting a hash, which is deprecated.
def body_ivar(recipient)
recipients recipient
subject "Body as a local variable"
@@ -1078,7 +1077,7 @@ def test_return_path_with_create
def test_return_path_with_create
mail = TestMailer.create_return_path
- assert_equal "another@somewhere.test", mail.return_path
+ assert_equal ["another@somewhere.test"], mail.return_path
end
def test_return_path_with_deliver
@@ -1089,8 +1088,7 @@ def test_return_path_with_deliver
end
def test_body_is_stored_as_an_ivar
- mail = nil
- ActiveSupport::Deprecation.silence { mail = TestMailer.create_body_ivar(@recipient) }
+ mail = TestMailer.create_body_ivar(@recipient)
assert_equal "body: foo\nbar: baz", mail.body.to_s
end
View
140 actionpack/lib/abstract_controller/base.rb
@@ -62,15 +62,19 @@ def hidden_actions
# Array[String]:: A list of all methods that should be considered
# actions.
def action_methods
- @action_methods ||=
+ @action_methods ||= begin
# All public instance methods of this class, including ancestors
- public_instance_methods(true).map { |m| m.to_s }.to_set -
- # Except for public instance methods of Base and its ancestors
- internal_methods.map { |m| m.to_s } +
- # Be sure to include shadowed public instance methods of this class
- public_instance_methods(false).map { |m| m.to_s } -
- # And always exclude explicitly hidden actions
- hidden_actions
+ methods = public_instance_methods(true).map { |m| m.to_s }.to_set -
+ # Except for public instance methods of Base and its ancestors
+ internal_methods.map { |m| m.to_s } +
+ # Be sure to include shadowed public instance methods of this class
+ public_instance_methods(false).map { |m| m.to_s } -
+ # And always exclude explicitly hidden actions
+ hidden_actions
+
+ # Clear out AS callback method pollution
+ methods.reject { |method| method =~ /_one_time_conditions/ }
+ end
end
# Returns the full controller name, underscored, without the ending Controller.
@@ -116,68 +120,72 @@ def controller_path
self.class.controller_path
end
- private
- # Returns true if the name can be considered an action. This can
- # be overridden in subclasses to modify the semantics of what
- # can be considered an action.
- #
- # ==== Parameters
- # name<String>:: The name of an action to be tested
- #
- # ==== Returns
- # TrueClass, FalseClass
- def action_method?(name)
- self.class.action_methods.include?(name)
+ def action_methods
+ self.class.action_methods
end
- # Call the action. Override this in a subclass to modify the
- # behavior around processing an action. This, and not #process,
- # is the intended way to override action dispatching.
- def process_action(method_name, *args)
- send_action(method_name, *args)
- end
+ private
+ # Returns true if the name can be considered an action. This can
+ # be overridden in subclasses to modify the semantics of what
+ # can be considered an action.
+ #
+ # ==== Parameters
+ # name<String>:: The name of an action to be tested
+ #
+ # ==== Returns
+ # TrueClass, FalseClass
+ def action_method?(name)
+ self.class.action_methods.include?(name)
+ end
- # Actually call the method associated with the action. Override
- # this method if you wish to change how action methods are called,
- # not to add additional behavior around it. For example, you would
- # override #send_action if you want to inject arguments into the
- # method.
- alias send_action send
-
- # If the action name was not found, but a method called "action_missing"
- # was found, #method_for_action will return "_handle_action_missing".
- # This method calls #action_missing with the current action name.
- def _handle_action_missing
- action_missing(@_action_name)
- end
+ # Call the action. Override this in a subclass to modify the
+ # behavior around processing an action. This, and not #process,
+ # is the intended way to override action dispatching.
+ def process_action(method_name, *args)
+ send_action(method_name, *args)
+ end
- # Takes an action name and returns the name of the method that will
- # handle the action. In normal cases, this method returns the same
- # name as it receives. By default, if #method_for_action receives
- # a name that is not an action, it will look for an #action_missing
- # method and return "_handle_action_missing" if one is found.
- #
- # Subclasses may override this method to add additional conditions
- # that should be considered an action. For instance, an HTTP controller
- # with a template matching the action name is considered to exist.
- #
- # If you override this method to handle additional cases, you may
- # also provide a method (like _handle_method_missing) to handle
- # the case.
- #
- # If none of these conditions are true, and method_for_action
- # returns nil, an ActionNotFound exception will be raised.
- #
- # ==== Parameters
- # action_name<String>:: An action name to find a method name for
- #
- # ==== Returns
- # String:: The name of the method that handles the action
- # nil:: No method name could be found. Raise ActionNotFound.
- def method_for_action(action_name)
- if action_method?(action_name) then action_name
- elsif respond_to?(:action_missing, true) then "_handle_action_missing"
+ # Actually call the method associated with the action. Override
+ # this method if you wish to change how action methods are called,
+ # not to add additional behavior around it. For example, you would
+ # override #send_action if you want to inject arguments into the
+ # method.
+ alias send_action send
+
+ # If the action name was not found, but a method called "action_missing"
+ # was found, #method_for_action will return "_handle_action_missing".
+ # This method calls #action_missing with the current action name.
+ def _handle_action_missing
+ action_missing(@_action_name)
+ end
+
+ # Takes an action name and returns the name of the method that will
+ # handle the action. In normal cases, this method returns the same
+ # name as it receives. By default, if #method_for_action receives
+ # a name that is not an action, it will look for an #action_missing
+ # method and return "_handle_action_missing" if one is found.
+ #
+ # Subclasses may override this method to add additional conditions
+ # that should be considered an action. For instance, an HTTP controller
+ # with a template matching the action name is considered to exist.
+ #
+ # If you override this method to handle additional cases, you may
+ # also provide a method (like _handle_method_missing) to handle
+ # the case.
+ #
+ # If none of these conditions are true, and method_for_action
+ # returns nil, an ActionNotFound exception will be raised.
+ #
+ # ==== Parameters
+ # action_name<String>:: An action name to find a method name for
+ #
+ # ==== Returns
+ # String:: The name of the method that handles the action
+ # nil:: No method name could be found. Raise ActionNotFound.
+ def method_for_action(action_name)
+ if action_method?(action_name) then action_name
+ elsif respond_to?(:action_missing, true) then "_handle_action_missing"
+ end
end
- end
end
end
View
5 actionpack/lib/action_controller/deprecated/dispatcher.rb
@@ -1,8 +1,5 @@
module ActionController
class Dispatcher
- cattr_accessor :prepare_each_request
- self.prepare_each_request = false
-
class << self
def before_dispatch(*args, &block)
ActiveSupport::Deprecation.warn "ActionController::Dispatcher.before_dispatch is deprecated. " <<
@@ -18,7 +15,7 @@ def after_dispatch(*args, &block)
def to_prepare(*args, &block)
ActiveSupport::Deprecation.warn "ActionController::Dispatcher.to_prepare is deprecated. " <<
- "Please use ActionDispatch::Callbacks.to_prepare instead.", caller
+ "Please use config.to_prepare instead", caller
ActionDispatch::Callbacks.after(*args, &block)
end
View
186 actionpack/lib/action_controller/metal/cookies.rb
@@ -1,48 +1,4 @@
module ActionController #:nodoc:
- # Cookies are read and written through ActionController#cookies.
- #
- # The cookies being read are the ones received along with the request, the cookies
- # being written will be sent out with the response. Reading a cookie does not get
- # the cookie object itself back, just the value it holds.
- #
- # Examples for writing:
- #
- # # Sets a simple session cookie.
- # cookies[:user_name] = "david"
- #
- # # Sets a cookie that expires in 1 hour.
- # cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now }
- #
- # Examples for reading:
- #
- # cookies[:user_name] # => "david"
- # cookies.size # => 2
- #
- # Example for deleting:
- #
- # cookies.delete :user_name
- #
- # Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:
- #
- # cookies[:key] = {
- # :value => 'a yummy cookie',
- # :expires => 1.year.from_now,
- # :domain => 'domain.com'
- # }
- #
- # cookies.delete(:key, :domain => 'domain.com')
- #
- # The option symbols for setting cookies are:
- #
- # * <tt>:value</tt> - The cookie's value or list of values (as an array).
- # * <tt>:path</tt> - The path for which this cookie applies. Defaults to the root
- # of the application.
- # * <tt>:domain</tt> - The domain for which this cookie applies.
- # * <tt>:expires</tt> - The time at which this cookie expires, as a Time object.
- # * <tt>:secure</tt> - Whether this cookie is a only transmitted to HTTPS servers.
- # Default is +false+.
- # * <tt>:httponly</tt> - Whether this cookie is accessible via scripting or
- # only HTTP. Defaults to +false+.
module Cookies
extend ActiveSupport::Concern
@@ -52,146 +8,10 @@ module Cookies
helper_method :cookies
cattr_accessor :cookie_verifier_secret
end
-
- protected
- # Returns the cookie container, which operates as described above.
+
+ private
def cookies
- @cookies ||= CookieJar.build(request, response)
- end
- end
-
- class CookieJar < Hash #:nodoc:
- def self.build(request, response)
- new.tap do |hash|
- hash.update(request.cookies)
- hash.response = response
- end
- end
-
- attr_accessor :response
-
- # Returns the value of the cookie by +name+, or +nil+ if no such cookie exists.
- def [](name)
- super(name.to_s)
- end
-
- # Sets the cookie named +name+. The second argument may be the very cookie
- # value, or a hash of options as documented above.
- def []=(key, options)
- if options.is_a?(Hash)
- options.symbolize_keys!
- value = options[:value]
- else
- value = options
- options = { :value => value }
+ request.cookie_jar
end
-
- super(key.to_s, value)
-
- options[:path] ||= "/"
- response.set_cookie(key, options)
- end
-
- # Removes the cookie on the client machine by setting the value to an empty string
- # and setting its expiration date into the past. Like <tt>[]=</tt>, you can pass in
- # an options hash to delete cookies with extra data such as a <tt>:path</tt>.
- def delete(key, options = {})
- options.symbolize_keys!
- options[:path] ||= "/"
- value = super(key.to_s)
- response.delete_cookie(key, options)
- value
- end
-
- # Returns a jar that'll automatically set the assigned cookies to have an expiration date 20 years from now. Example:
- #
- # cookies.permanent[:prefers_open_id] = true
- # # => Set-Cookie: prefers_open_id=true; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
- #
- # This jar is only meant for writing. You'll read permanent cookies through the regular accessor.
- #
- # This jar allows chaining with the signed jar as well, so you can set permanent, signed cookies. Examples:
- #
- # cookies.permanent.signed[:remember_me] = current_user.id
- # # => Set-Cookie: discount=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
- def permanent
- @permanent ||= PermanentCookieJar.new(self)
- end
-
- # Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from
- # the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed
- # cookie was tampered with by the user (or a 3rd party), an ActiveSupport::MessageVerifier::InvalidSignature exception will
- # be raised.
- #
- # This jar requires that you set a suitable secret for the verification on ActionController::Base.cookie_verifier_secret.
- #
- # Example:
- #
- # cookies.signed[:discount] = 45
- # # => Set-Cookie: discount=BAhpMg==--2c1c6906c90a3bc4fd54a51ffb41dffa4bf6b5f7; path=/
- #
- # cookies.signed[:discount] # => 45
- def signed
- @signed ||= SignedCookieJar.new(self)
- end
- end
-
- class PermanentCookieJar < CookieJar #:nodoc:
- def initialize(parent_jar)
- @parent_jar = parent_jar
- end
-
- def []=(key, options)
- if options.is_a?(Hash)
- options.symbolize_keys!
- else
- options = { :value => options }
- end
-
- options[:expires] = 20.years.from_now
- @parent_jar[key] = options
- end
-
- def signed
- @signed ||= SignedCookieJar.new(self)
- end
-
- def controller
- @parent_jar.controller
- end
-
- def method_missing(method, *arguments, &block)
- @parent_jar.send(method, *arguments, &block)
- end
- end
-
- class SignedCookieJar < CookieJar #:nodoc:
- def initialize(parent_jar)
- unless ActionController::Base.cookie_verifier_secret
- raise "You must set ActionController::Base.cookie_verifier_secret to use signed cookies"
- end
-
- @parent_jar = parent_jar
- @verifier = ActiveSupport::MessageVerifier.new(ActionController::Base.cookie_verifier_secret)
- end
-
- def [](name)
- @verifier.verify(@parent_jar[name])
- end
-
- def []=(key, options)
- if options.is_a?(Hash)
- options.symbolize_keys!
- options[:value] = @verifier.generate(options[:value])
- else
- options = { :value => @verifier.generate(options) }
- end
-
- @parent_jar[key] = options
- end
-
- def method_missing(method, *arguments, &block)
- @parent_jar.send(method, *arguments, &block)
- end
end
end
View
4 actionpack/lib/action_controller/metal/instrumentation.rb
@@ -20,11 +20,7 @@ def process_action(action, *args)
result = super
payload[:controller] = self.class.name
payload[:action] = self.action_name
- payload[:formats] = request.formats.map(&:to_s)
- payload[:remote_ip] = request.remote_ip
- payload[:method] = request.method
payload[:status] = response.status
- payload[:request_uri] = request.request_uri rescue "unknown"
append_info_to_payload(payload)
result
end
View
3  actionpack/lib/action_controller/metal/testing.rb
@@ -10,6 +10,9 @@ def process_with_new_base_test(request, response)
@_response = response
@_response.request = request
ret = process(request.parameters[:action])
+ if cookies = @_request.env['action_dispatch.cookies']
+ cookies.write(@_response)
+ end
@_response.body ||= self.response_body
@_response.prepare!
set_test_assigns
View
50 actionpack/lib/action_controller/railtie.rb
@@ -23,7 +23,6 @@ class Railtie < Rails::Railtie
initializer "action_controller.initialize_routing" do |app|
app.route_configuration_files << app.config.routes_configuration_file
app.route_configuration_files << app.config.builtin_routes_configuration_file
- app.reload_routes!
end
initializer "action_controller.initialize_framework_caches" do
@@ -40,54 +39,5 @@ class Railtie < Rails::Railtie
ActionController::Base.view_paths = view_path if ActionController::Base.view_paths.blank?
end
- class MetalMiddlewareBuilder
- def initialize(metals)
- @metals = metals
- end
-
- def new(app)
- ActionDispatch::Cascade.new(@metals, app)
- end
-
- def name
- ActionDispatch::Cascade.name
- end
- alias_method :to_s, :name
- end
-
- initializer "action_controller.initialize_metal" do |app|
- metal_root = "#{Rails.root}/app/metal"
- load_list = app.config.metals || Dir["#{metal_root}/**/*.rb"]
-
- metals = load_list.map { |metal|
- metal = File.basename(metal.gsub("#{metal_root}/", ''), '.rb')
- require_dependency metal
- metal.camelize.constantize
- }.compact
-
- middleware = MetalMiddlewareBuilder.new(metals)
- app.config.middleware.insert_before(:"ActionDispatch::ParamsParser", middleware)
- end
-
- # Prepare dispatcher callbacks and run 'prepare' callbacks
- initializer "action_controller.prepare_dispatcher" do |app|
- # TODO: This used to say unless defined?(Dispatcher). Find out why and fix.
- # Notice that at this point, ActionDispatch::Callbacks were already loaded.
- require 'rails/dispatcher'
- ActionController::Dispatcher.prepare_each_request = true unless app.config.cache_classes
-
- unless app.config.cache_classes
- # Setup dev mode route reloading
- routes_last_modified = app.routes_changed_at
- reload_routes = lambda do
- unless app.routes_changed_at == routes_last_modified
- routes_last_modified = app.routes_changed_at
- app.reload_routes!
- end
- end
- ActionDispatch::Callbacks.before { |callbacks| reload_routes.call }
- end
- end
-
end
end
View
7 actionpack/lib/action_controller/railties/subscriber.rb
@@ -3,18 +3,13 @@ module Railties
class Subscriber < Rails::Subscriber
def process_action(event)
payload = event.payload
-
- info "\nProcessed #{payload[:controller]}##{payload[:action]} " \
- "to #{payload[:formats].join(', ')} (for #{payload[:remote_ip]} at #{event.time.to_s(:db)}) " \
- "[#{payload[:method].to_s.upcase}]"
-
info " Parameters: #{payload[:params].inspect}" unless payload[:params].blank?
additions = ActionController::Base.log_process_action(payload)
message = "Completed in %.0fms" % event.duration
message << " (#{additions.join(" | ")})" unless additions.blank?
- message << " | #{payload[:status]} [#{payload[:request_uri]}]\n\n"
+ message << " by #{payload[:controller]}##{payload[:action]} [#{payload[:status]}]"
info(message)
end
View
2  actionpack/lib/action_dispatch.rb
@@ -43,8 +43,10 @@ module ActionDispatch
autoload_under 'middleware' do
autoload :Callbacks
autoload :Cascade
+ autoload :Cookies
autoload :Flash
autoload :Head
+ autoload :Notifications
autoload :ParamsParser
autoload :Rescue
autoload :ShowExceptions
View
2  actionpack/lib/action_dispatch/http/response.rb
@@ -119,7 +119,7 @@ def location=(url)
def to_a
assign_default_content_type_and_charset!
handle_conditional_get!
- self["Set-Cookie"] = @cookie.join("\n")
+ self["Set-Cookie"] = @cookie.join("\n") unless @cookie.blank?
self["ETag"] = @etag if @etag
super
end
View
2  actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -45,8 +45,6 @@ def call(env)
run_callbacks(:prepare) if @prepare_each_request
@app.call(env)
end
- ensure
- ActiveSupport::Notifications.instrument "action_dispatch.callback"
end
end
end
View
216 actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -0,0 +1,216 @@
+module ActionDispatch
+ class Request
+ def cookie_jar
+ env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self)
+ end
+ end
+
+ # Cookies are read and written through ActionController#cookies.
+ #
+ # The cookies being read are the ones received along with the request, the cookies
+ # being written will be sent out with the response. Reading a cookie does not get
+ # the cookie object itself back, just the value it holds.
+ #
+ # Examples for writing:
+ #
+ # # Sets a simple session cookie.
+ # cookies[:user_name] = "david"
+ #
+ # # Sets a cookie that expires in 1 hour.
+ # cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now }
+ #
+ # Examples for reading:
+ #
+ # cookies[:user_name] # => "david"
+ # cookies.size # => 2
+ #
+ # Example for deleting:
+ #
+ # cookies.delete :user_name
+ #
+ # Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:
+ #
+ # cookies[:key] = {
+ # :value => 'a yummy cookie',
+ # :expires => 1.year.from_now,
+ # :domain => 'domain.com'
+ # }
+ #
+ # cookies.delete(:key, :domain => 'domain.com')
+ #
+ # The option symbols for setting cookies are:
+ #
+ # * <tt>:value</tt> - The cookie's value or list of values (as an array).
+ # * <tt>:path</tt> - The path for which this cookie applies. Defaults to the root
+ # of the application.
+ # * <tt>:domain</tt> - The domain for which this cookie applies.
+ # * <tt>:expires</tt> - The time at which this cookie expires, as a Time object.
+ # * <tt>:secure</tt> - Whether this cookie is a only transmitted to HTTPS servers.
+ # Default is +false+.
+ # * <tt>:httponly</tt> - Whether this cookie is accessible via scripting or
+ # only HTTP. Defaults to +false+.
+ class Cookies
+ class CookieJar < Hash #:nodoc:
+ def self.build(request)
+ new.tap do |hash|
+ hash.update(request.cookies)
+ end
+ end
+
+ def initialize
+ @set_cookies = {}
+ @delete_cookies = {}
+
+ super
+ end
+
+ # Returns the value of the cookie by +name+, or +nil+ if no such cookie exists.
+ def [](name)
+ super(name.to_s)
+ end
+
+ # Sets the cookie named +name+. The second argument may be the very cookie
+ # value, or a hash of options as documented above.
+ def []=(key, options)
+ if options.is_a?(Hash)
+ options.symbolize_keys!
+ value = options[:value]
+ else
+ value = options
+ options = { :value => value }
+ end
+
+ value = super(key.to_s, value)
+
+ options[:path] ||= "/"
+ @set_cookies[key] = options
+ value
+ end
+
+ # Removes the cookie on the client machine by setting the value to an empty string
+ # and setting its expiration date into the past. Like <tt>[]=</tt>, you can pass in
+ # an options hash to delete cookies with extra data such as a <tt>:path</tt>.
+ def delete(key, options = {})
+ options.symbolize_keys!
+ options[:path] ||= "/"
+ value = super(key.to_s)
+ @delete_cookies[key] = options
+ value
+ end
+
+ # Returns a jar that'll automatically set the assigned cookies to have an expiration date 20 years from now. Example:
+ #
+ # cookies.permanent[:prefers_open_id] = true
+ # # => Set-Cookie: prefers_open_id=true; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
+ #
+ # This jar is only meant for writing. You'll read permanent cookies through the regular accessor.
+ #
+ # This jar allows chaining with the signed jar as well, so you can set permanent, signed cookies. Examples:
+ #
+ # cookies.permanent.signed[:remember_me] = current_user.id
+ # # => Set-Cookie: discount=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
+ def permanent
+ @permanent ||= PermanentCookieJar.new(self)
+ end
+
+ # Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from
+ # the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed
+ # cookie was tampered with by the user (or a 3rd party), an ActiveSupport::MessageVerifier::InvalidSignature exception will
+ # be raised.
+ #
+ # This jar requires that you set a suitable secret for the verification on ActionController::Base.cookie_verifier_secret.
+ #
+ # Example:
+ #
+ # cookies.signed[:discount] = 45
+ # # => Set-Cookie: discount=BAhpMg==--2c1c6906c90a3bc4fd54a51ffb41dffa4bf6b5f7; path=/
+ #
+ # cookies.signed[:discount] # => 45
+ def signed
+ @signed ||= SignedCookieJar.new(self)
+ end
+
+ def write(response)
+ @set_cookies.each { |k, v| response.set_cookie(k, v) }
+ @delete_cookies.each { |k, v| response.delete_cookie(k, v) }
+ end
+ end
+
+ class PermanentCookieJar < CookieJar #:nodoc:
+ def initialize(parent_jar)
+ @parent_jar = parent_jar
+ end
+
+ def []=(key, options)
+ if options.is_a?(Hash)
+ options.symbolize_keys!
+ else
+ options = { :value => options }
+ end
+
+ options[:expires] = 20.years.from_now
+ @parent_jar[key] = options
+ end
+
+ def signed
+ @signed ||= SignedCookieJar.new(self)
+ end
+
+ def controller
+ @parent_jar.controller
+ end
+
+ def method_missing(method, *arguments, &block)
+ @parent_jar.send(method, *arguments, &block)
+ end
+ end
+
+ class SignedCookieJar < CookieJar #:nodoc:
+ def initialize(parent_jar)
+ unless ActionController::Base.cookie_verifier_secret
+ raise "You must set ActionController::Base.cookie_verifier_secret to use signed cookies"
+ end
+
+ @parent_jar = parent_jar
+ @verifier = ActiveSupport::MessageVerifier.new(ActionController::Base.cookie_verifier_secret)
+ end
+
+ def [](name)
+ if value = @parent_jar[name]
+ @verifier.verify(value)
+ end
+ end
+
+ def []=(key, options)
+ if options.is_a?(Hash)
+ options.symbolize_keys!
+ options[:value] = @verifier.generate(options[:value])
+ else
+ options = { :value => @verifier.generate(options) }
+ end
+
+ @parent_jar[key] = options
+ end
+
+ def method_missing(method, *arguments, &block)
+ @parent_jar.send(method, *arguments, &block)
+ end
+ end
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ status, headers, body = @app.call(env)
+
+ if cookie_jar = env['action_dispatch.cookies']
+ response = Rack::Response.new(body, status, headers)
+ cookie_jar.write(response)
+ response.to_a
+ else
+ [status, headers, body]
+ end
+ end
+ end
+end
View
24 actionpack/lib/action_dispatch/middleware/notifications.rb
@@ -0,0 +1,24 @@
+module ActionDispatch
+ # Provide notifications in the middleware stack. Notice that for the before_dispatch
+ # and after_dispatch notifications, we just send the original env, so we don't pile
+ # up large env hashes in the queue. However, in exception cases, the whole env hash
+ # is actually useful, so we send it all.
+ class Notifications
+ def initialize(app)
+ @app = app
+ end
+
+ def call(stack_env)
+ env = stack_env.dup
+ ActiveSupport::Notifications.instrument("action_dispatch.before_dispatch", :env => env)
+
+ ActiveSupport::Notifications.instrument!("action_dispatch.after_dispatch", :env => env) do
+ @app.call(stack_env)
+ end
+ rescue Exception => exception
+ ActiveSupport::Notifications.instrument('action_dispatch.exception',
+ :env => stack_env, :exception => exception)
+ raise exception
+ end
+ end
+end
View
32 actionpack/lib/action_dispatch/middleware/show_exceptions.rb
@@ -20,7 +20,7 @@ module ActionDispatch
# * :exception - The exception raised;
#
class ShowExceptions
- LOCALHOST = '127.0.0.1'.freeze
+ LOCALHOST = ['127.0.0.1', '::1'].freeze
RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates')
@@ -61,11 +61,8 @@ def initialize(app, consider_all_requests_local = false)
def call(env)
@app.call(env)
rescue Exception => exception
- ActiveSupport::Notifications.instrument 'action_dispatch.show_exception',
- :env => env, :exception => exception do
- raise exception if env['action_dispatch.show_exceptions'] == false
- render_exception(env, exception)
- end
+ raise exception if env['action_dispatch.show_exceptions'] == false
+ render_exception(env, exception)
end
private
@@ -88,7 +85,10 @@ def render_exception(env, exception)
def rescue_action_locally(request, exception)
template = ActionView::Base.new([RESCUES_TEMPLATE_PATH],
:request => request,
- :exception => exception
+ :exception => exception,
+ :application_trace => application_trace(exception),
+ :framework_trace => framework_trace(exception),
+ :full_trace => full_trace(exception)
)
file = "rescues/#{@@rescue_templates[exception.class.name]}.erb"
body = template.render(:file => file, :layout => 'rescues/layout.erb')
@@ -118,7 +118,7 @@ def rescue_action_in_public(exception)
# True if the request came from localhost, 127.0.0.1.
def local_request?(request)
- request.remote_addr == LOCALHOST && request.remote_ip == LOCALHOST
+ LOCALHOST.any?{ |local_ip| request.remote_addr == local_ip && request.remote_ip == local_ip }
end
def status_code(exception)
@@ -148,9 +148,21 @@ def log_error(exception)
end
end
- def clean_backtrace(exception)
+ def application_trace(exception)
+ clean_backtrace(exception, :silent)
+ end
+
+ def framework_trace(exception)
+ clean_backtrace(exception, :noise)
+ end
+
+ def full_trace(exception)
+ clean_backtrace(exception, :all)
+ end
+
+ def clean_backtrace(exception, *args)
defined?(Rails) && Rails.respond_to?(:backtrace_cleaner) ?
- Rails.backtrace_cleaner.clean(exception.backtrace) :
+ Rails.backtrace_cleaner.clean(exception.backtrace, *args) :
exception.backtrace
end
View
9 actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
@@ -11,13 +11,20 @@
clean_params.delete("controller")
request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n")
+
+ def debug_hash(hash)
+ hash.sort_by { |k, v| k.to_s }.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
+ end
%>
<h2 style="margin-top: 30px">Request</h2>
<p><b>Parameters</b>: <pre><%=h request_dump %></pre></p>
<p><a href="#" onclick="document.getElementById('session_dump').style.display='block'; return false;">Show session dump</a></p>
-<div id="session_dump" style="display:none"><%= debug(@request.session.instance_variable_get("@data")) %></div>
+<div id="session_dump" style="display:none"><pre><%= debug_hash @request.session %></pre></div>
+
+<p><a href="#" onclick="document.getElementById('env_dump').style.display='block'; return false;">Show env dump</a></p>
+<div id="env_dump" style="display:none"><pre><%= debug_hash @request.env %></pre></div>
<h2 style="margin-top: 30px">Response</h2>
View
6 actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb
@@ -1,8 +1,8 @@
<%
traces = [
- ["Application Trace", @exception.application_backtrace],
- ["Framework Trace", @exception.framework_backtrace],
- ["Full Trace", @exception.clean_backtrace]
+ ["Application Trace", @application_trace],
+ ["Framework Trace", @framework_trace],
+ ["Full Trace", @full_trace]
]
names = traces.collect {|name, trace| name}
%>
View
2  actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
@@ -4,7 +4,7 @@
in <%=h @request.parameters['controller'].humanize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %>
<% end %>
</h1>
-<pre><%=h @exception.clean_message %></pre>
+<pre><%=h @exception.message %></pre>
<%= render :file => "rescues/_trace.erb" %>
<%= render :file => "rescues/_request_and_response.erb" %>
View
29 actionpack/lib/action_dispatch/railtie.rb
@@ -0,0 +1,29 @@
+require "action_dispatch"
+require "rails"
+
+module ActionDispatch
+ class Railtie < Rails::Railtie
+ plugin_name :action_dispatch
+
+ require "action_dispatch/railties/subscriber"
+ subscriber ActionDispatch::Railties::Subscriber.new
+
+ # Prepare dispatcher callbacks and run 'prepare' callbacks
+ initializer "action_dispatch.prepare_dispatcher" do |app|
+ # TODO: This used to say unless defined?(Dispatcher). Find out why and fix.
+ require 'rails/dispatcher'
+
+ unless app.config.cache_classes
+ # Setup dev mode route reloading
+ routes_last_modified = app.routes_changed_at
+ reload_routes = lambda do
+ unless app.routes_changed_at == routes_last_modified
+ routes_last_modified = app.routes_changed_at
+ app.reload_routes!
+ end
+ end
+ ActionDispatch::Callbacks.before { |callbacks| reload_routes.call }
+ end
+ end
+ end
+end
View
17 actionpack/lib/action_dispatch/railties/subscriber.rb
@@ -0,0 +1,17 @@
+module ActionDispatch
+ module Railties
+ class Subscriber < Rails::Subscriber
+ def before_dispatch(event)
+ request = Request.new(event.payload[:env])
+ path = request.request_uri.inspect rescue "unknown"
+
+ info "\n\nProcessing #{path} to #{request.formats.join(', ')} " <<
+ "(for #{request.remote_ip} at #{event.time.to_s(:db)}) [#{request.method.to_s.upcase}]"
+ end
+
+ def logger
+ ActionController::Base.logger
+ end
+ end
+ end
+end
View
59 actionpack/lib/action_dispatch/routing/mapper.rb
@@ -418,28 +418,12 @@ def initialize(*args)
def resource(*resources, &block)
options = resources.extract_options!
- if resources.length > 1
- raise ArgumentError if block_given?
- resources.each { |r| resource(r, options) }
- return self
- end
-
- if path_names = options.delete(:path_names)
- scope(:resources_path_names => path_names) do
- resource(resources, options)
- end
+ if verify_common_behavior_for(:resource, resources, options, &block)
return self
end
resource = SingletonResource.new(resources.pop, options)
- if @scope[:scope_level] == :resources
- nested do
- resource(resource.name, options, &block)
- end
- return self
- end
-
scope(:path => resource.name.to_s, :controller => resource.controller) do
with_scope_level(:resource, resource) do
yield if block_given?
@@ -459,28 +443,12 @@ def resource(*resources, &block)
def resources(*resources, &block)
options = resources.extract_options!
- if resources.length > 1
- raise ArgumentError if block_given?
- resources.each { |r| resources(r, options) }
- return self
- end
-
- if path_names = options.delete(:path_names)
- scope(:resources_path_names => path_names) do
- resources(resources, options)
- end
+ if verify_common_behavior_for(:resources, resources, options, &block)
return self
end
resource = Resource.new(resources.pop, options)
- if @scope[:scope_level] == :resources
- nested do
- resources(resource.name, options, &block)
- end
- return self
- end
-
scope(:path => resource.name.to_s, :controller => resource.controller) do
with_scope_level(:resources, resource) do
yield if block_given?
@@ -595,6 +563,29 @@ def action_path(name, path_names = nil)
path_names[name.to_sym] || name.to_s
end
+ def verify_common_behavior_for(method, resources, options, &block)
+ if resources.length > 1
+ resources.each { |r| send(method, r, options, &block) }
+ return true
+ end
+
+ if path_names = options.delete(:path_names)
+ scope(:resources_path_names => path_names) do
+ send(method, resources.pop, options, &block)
+ end
+ return true
+ end
+
+ if @scope[:scope_level] == :resources
+ nested do
+ send(method, resources.pop, options, &block)
+ end
+ return true
+ end
+
+ false
+ end
+
def with_exclusive_name_prefix(prefix)
begin
old_name_prefix = @scope[:name_prefix]
View
4 actionpack/lib/action_view/helpers/debug_helper.rb
@@ -27,10 +27,10 @@ module DebugHelper
def debug(object)
begin
Marshal::dump(object)
- "<pre class='debug_dump'>#{h(object.to_yaml).gsub(" ", "&nbsp; ")}</pre>"
+ "<pre class='debug_dump'>#{h(object.to_yaml).gsub(" ", "&nbsp; ")}</pre>".html_safe!
rescue Exception => e # errors from Marshal or YAML
# Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback
- "<code class='debug_dump'>#{h(object.inspect)}</code>"
+ "<code class='debug_dump'>#{h(object.inspect)}</code>".html_safe!
end
end
end
View
1  actionpack/test/abstract_unit.rb
@@ -92,6 +92,7 @@ def self.build_app(routes = nil)
middleware.use "ActionDispatch::ShowExceptions"
middleware.use "ActionDispatch::Callbacks"
middleware.use "ActionDispatch::ParamsParser"
+ middleware.use "ActionDispatch::Cookies"
middleware.use "ActionDispatch::Flash"
middleware.use "ActionDispatch::Head"
}.build(routes || ActionController::Routing::Routes)
View
4 actionpack/test/activerecord/controller_runtime_test.rb
@@ -37,8 +37,8 @@ def test_log_with_active_record
get :show
wait
- assert_equal 2, @logger.logged(:info).size
- assert_match /\(Views: [\d\.]+ms | ActiveRecord: [\d\.]+ms\)/, @logger.logged(:info)[1]
+ assert_equal 1, @logger.logged(:info).size
+ assert_match /\(Views: [\d\.]+ms | ActiveRecord: [\d\.]+ms\)/, @logger.logged(:info)[0]
end
class SyncSubscriberTest < ActionController::TestCase
View
37 actionpack/test/controller/cookie_test.rb
@@ -54,12 +54,12 @@ def set_permanent_cookie
cookies.permanent[:user_name] = "Jamie"
head :ok
end
-
+
def set_signed_cookie
cookies.signed[:user_id] = 45
head :ok
end
-
+
def set_permanent_signed_cookie
cookies.permanent.signed[:remember_me] = 100
head :ok
@@ -120,28 +120,6 @@ def test_expiring_cookie
assert_equal({"user_name" => nil}, @response.cookies)
end
- def test_cookiejar_accessor
- @request.cookies["user_name"] = "david"
- @controller.request = @request
- jar = ActionController::CookieJar.build(@controller.request, @controller.response)
- assert_equal "david", jar["user_name"]
- assert_equal nil, jar["something_else"]
- end
-
- def test_cookiejar_accessor_with_array_value
- @request.cookies["pages"] = %w{1 2 3}
- @controller.request = @request
- jar = ActionController::CookieJar.build(@controller.request, @controller.response)
- assert_equal %w{1 2 3}, jar["pages"]
- end
-
- def test_cookiejar_delete_removes_item_and_returns_its_value
- @request.cookies["user_name"] = "david"
- @controller.response = @response
- jar = ActionController::CookieJar.build(@controller.request, @controller.response)
- assert_equal "david", jar.delete("user_name")
- end
-
def test_delete_cookie_with_path
get :delete_cookie_with_path
assert_cookie_header "user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT"
@@ -157,19 +135,24 @@ def test_permanent_cookie
assert_match /Jamie/, @response.headers["Set-Cookie"]
assert_match %r(#{20.years.from_now.utc.year}), @response.headers["Set-Cookie"]
end
-
+
def test_signed_cookie
get :set_signed_cookie
assert_equal 45, @controller.send(:cookies).signed[:user_id]
end
-
+
+ def test_accessing_nonexistant_signed_cookie_should_not_raise_an_invalid_signature
+ get :set_signed_cookie
+ assert_nil @controller.send(:cookies).signed[:non_existant_attribute]
+ end
+
def test_permanent_signed_cookie
get :set_permanent_signed_cookie
assert_match %r(#{20.years.from_now.utc.year}), @response.headers["Set-Cookie"]
assert_equal 100, @controller.send(:cookies).signed[:remember_me]
end
-
+
private
def assert_cookie_header(expected)
header = @response.headers["Set-Cookie"]
View
27 actionpack/test/controller/filter_params_test.rb
@@ -9,23 +9,6 @@ def payment
class FilterParamTest < ActionController::TestCase
tests FilterParamController
- class MockLogger
- attr_reader :logged
- attr_accessor :level
-
- def initialize
- @level = Logger::DEBUG
- end
-
- def method_missing(method, *args)
- @logged ||= []
- @logged << args.first unless block_given?
- @logged << yield if block_given?
- end
- end
-
- setup :set_logger
-
def test_filter_parameters_must_have_one_word
assert_raises RuntimeError do
FilterParamController.filter_parameter_logging
@@ -65,14 +48,4 @@ def test_filter_parameters_is_protected
assert !FilterParamController.action_methods.include?('filter_parameters')
assert_raise(NoMethodError) { @controller.filter_parameters([{'password' => '[FILTERED]'}]) }
end
-
- private
-
- def set_logger
- @controller.logger = MockLogger.new
- end
-
- def logs
- @logs ||= @controller.logger.logged.compact.map {|l| l.to_s.strip}
- end
end
View
2  actionpack/test/controller/flash_test.rb
@@ -220,7 +220,7 @@ def test_flash
def with_test_route_set
with_routing do |set|
set.draw do |map|
- match ':action', :to => ActionDispatch::Session::CookieStore.new(TestController, :key => SessionKey, :secret => SessionSecret)
+ match ':action', :to => ActionDispatch::Session::CookieStore.new(FlashIntegrationTest::TestController, :key => FlashIntegrationTest::SessionKey, :secret => FlashIntegrationTest::SessionSecret)
end
yield
end
View
28 actionpack/test/controller/new_base/base_test.rb
@@ -3,6 +3,8 @@
# Tests the controller dispatching happy path
module Dispatching
class SimpleController < ActionController::Base
+ before_filter :authenticate
+
def index
render :text => "success"
end
@@ -12,12 +14,20 @@ def modify_response_body
end
def modify_response_body_twice
- ret = (self.response_body = "success")
+ ret = (self.response_body = "success")
self.response_body = "#{ret}!"
end
def modify_response_headers
end
+
+ def show_actions
+ render :text => "actions: #{action_methods.to_a.join(', ')}"
+ end
+
+ protected
+ def authenticate
+ end
end
class EmptyController < ActionController::Base ; end
@@ -64,5 +74,21 @@ class BaseTest < Rack::TestCase
assert_equal 'empty', EmptyController.controller_name
assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name
end
+
+ test "action methods" do
+ assert_equal Set.new(%w(
+ modify_response_headers
+ modify_response_body_twice
+ index
+ modify_response_body
+ show_actions
+ )), SimpleController.action_methods
+
+ assert_equal Set.new, EmptyController.action_methods
+ assert_equal Set.new, Submodule::ContainedEmptyController.action_methods
+
+ get "/dispatching/simple/show_actions"
+ assert_body "actions: modify_response_headers, modify_response_body_twice, index, modify_response_body, show_actions"
+ end
end
end
View
42 actionpack/test/controller/subscriber_test.rb
@@ -66,15 +66,10 @@ def set_logger(logger)
def test_process_action
get :show
wait
- assert_equal 2, logs.size
- assert_match /Processed\sAnother::SubscribersController#show/, logs[0]
- end
-
- def test_process_action_formats
- get :show
- wait
- assert_equal 2, logs.size
- assert_match /text\/html/, logs[0]
+ assert_equal 1, logs.size
+ assert_match /Completed/, logs.first
+ assert_match /\[200\]/, logs.first
+ assert_match /Another::SubscribersController#show/, logs.first
end
def test_process_action_without_parameters
@@ -87,23 +82,14 @@ def test_process_action_with_parameters
get :show, :id => '10'
wait
- assert_equal 3, logs.size
- assert_equal 'Parameters: {"id"=>"10"}', logs[1]
+ assert_equal 2, logs.size
+ assert_equal 'Parameters: {"id"=>"10"}', logs[0]
end
def test_process_action_with_view_runtime
get :show
wait
- assert_match /\(Views: [\d\.]+ms\)/, logs[1]
- end
-
- def test_process_action_with_status_and_request_uri
- get :show
- wait
- last = logs.last
- assert_match /Completed/, last
- assert_match /200/, last
- assert_match /another\/subscribers\/show/, last
+ assert_match /\(Views: [\d\.]+ms\)/, logs[0]
end
def test_process_action_with_filter_parameters
@@ -112,7 +98,7 @@ def test_process_action_with_filter_parameters
get :show, :lifo => 'Pratik', :amount => '420', :step => '1'
wait
- params = logs[1]
+ params = logs[0]
assert_match /"amount"=>"\[FILTERED\]"/, params
assert_match /"lifo"=>"\[FILTERED\]"/, params
assert_match /"step"=>"1"/, params
@@ -122,7 +108,7 @@ def test_redirect_to
get :redirector
wait
- assert_equal 3, logs.size
+ assert_equal 2, logs.size
assert_equal "Redirected to http://foo.bar/", logs[0]
end
@@ -130,7 +116,7 @@ def test_send_data
get :data_sender
wait
- assert_equal 3, logs.size
+ assert_equal 2, logs.size
assert_match /Sent data omg\.txt/, logs[0]
end
@@ -138,7 +124,7 @@ def test_send_file
get :file_sender
wait
- assert_equal 3, logs.size
+ assert_equal 2, logs.size
assert_match /Sent file/, logs[0]
assert_match /test\/fixtures\/company\.rb/, logs[0]
end
@@ -147,7 +133,7 @@ def test_send_xfile
get :xfile_sender
wait
- assert_equal 3, logs.size
+ assert_equal 2, logs.size
assert_match /Sent X\-Sendfile header/, logs[0]
assert_match /test\/fixtures\/company\.rb/, logs[0]
end
@@ -157,7 +143,7 @@ def test_with_fragment_cache
get :with_fragment_cache
wait
- assert_equal 4, logs.size
+ assert_equal 3, logs.size
assert_match /Exist fragment\? views\/foo/, logs[0]
assert_match /Write fragment views\/foo/, logs[1]
ensure
@@ -169,7 +155,7 @@ def test_with_page_cache
get :with_page_cache
wait
- assert_equal 3, logs.size
+ assert_equal 2, logs.size
assert_match /Write page/, logs[0]
assert_match /\/index\.html/, logs[0]
ensure
View
12 actionpack/test/dispatch/callbacks_test.rb
@@ -85,18 +85,6 @@ def test_before_and_after_callbacks
assert_equal 4, Foo.b
end
- def test_should_send_an_instrumentation_callback_for_async_processing
- ActiveSupport::Notifications.expects(:instrument).with("action_dispatch.callback")
- dispatch
- end
-
- def test_should_send_an_instrumentation_callback_for_async_processing_even_on_failure
- ActiveSupport::Notifications.notifier.expects(:publish)
- assert_raise RuntimeError do
- dispatch { |env| raise "OMG" }
- end
- end
-
private
def dispatch(cache_classes = true, &block)
View
9 actionpack/test/dispatch/response_test.rb
@@ -13,8 +13,7 @@ def setup
assert_equal({
"Content-Type" => "text/html; charset=utf-8",
"Cache-Control" => "max-age=0, private, must-revalidate",
- "ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"',
- "Set-Cookie" => ""
+ "ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"'
}, headers)
parts = []
@@ -30,8 +29,7 @@ def setup
assert_equal({
"Content-Type" => "text/html; charset=utf-8",
"Cache-Control" => "max-age=0, private, must-revalidate",
- "ETag" => '"ebb5e89e8a94e9dd22abf5d915d112b2"',
- "Set-Cookie" => ""
+ "ETag" => '"ebb5e89e8a94e9dd22abf5d915d112b2"'
}, headers)
end
@@ -44,8 +42,7 @@ def setup
assert_equal 200, status
assert_equal({
"Content-Type" => "text/html; charset=utf-8",
- "Cache-Control" => "no-cache",
- "Set-Cookie" => ""
+ "Cache-Control" => "no-cache"
}, headers)
parts = []
View
4 actionpack/test/dispatch/session/cookie_store_test.rb
@@ -137,7 +137,7 @@ def test_doesnt_write_session_cookie_if_session_is_not_accessed
with_test_route_set do
get '/no_session_access'
assert_response :success
- assert_equal "", headers['Set-Cookie']
+ assert_equal nil, headers['Set-Cookie']
end
end
@@ -147,7 +147,7 @@ def test_doesnt_write_session_cookie_if_session_is_unchanged
"fef868465920f415f2c0652d6910d3af288a0367"
get '/no_session_access'
assert_response :success
- assert_equal "", headers['Set-Cookie']
+ assert_equal nil, headers['Set-Cookie']
end
end
View
45 actionpack/test/dispatch/show_exceptions_test.rb
@@ -53,19 +53,21 @@ class ShowExceptionsTest < ActionController::IntegrationTest
test "rescue locally from a local request" do
@app = ProductionApp
- self.remote_addr = '127.0.0.1'
+ ['127.0.0.1', '::1'].each do |ip_address|
+ self.remote_addr = ip_address
- get "/"
- assert_response 500
- assert_match /puke/, body
+ get "/"
+ assert_response 500
+ assert_match /puke/, body
- get "/not_found"
- assert_response 404
- assert_match /#{ActionController::UnknownAction.name}/, body
+ get "/not_found"
+ assert_response 404
+ assert_match /#{ActionController::UnknownAction.name}/, body
- get "/method_not_allowed"
- assert_response 405
- assert_match /ActionController::MethodNotAllowed/, body
+ get "/method_not_allowed"
+ assert_response 405
+ assert_match /ActionController::MethodNotAllowed/, body
+ end
end
test "localize public rescue message" do
@@ -104,27 +106,4 @@ class ShowExceptionsTest < ActionController::IntegrationTest
assert_response 405
assert_match /ActionController::MethodNotAllowed/, body
end
-
- test "publishes notifications" do
- # Wait pending notifications to be published
- ActiveSupport::Notifications.notifier.wait
-
- @app, event = ProductionApp, nil
- self.remote_addr = '127.0.0.1'
-
- ActiveSupport::Notifications.subscribe('action_dispatch.show_exception') do |*args|
- event = args
- end
-
- get "/"
- assert_response 500
- assert_match /puke/, body
-
- ActiveSupport::Notifications.notifier.wait
-
- assert_equal 'action_dispatch.show_exception', event.first
- assert_kind_of Hash, event.last[:env]
- assert_equal 'GET', event.last[:env]["REQUEST_METHOD"]
- assert_kind_of RuntimeError, event.last[:exception]
- end
end
View
112 actionpack/test/dispatch/subscriber_test.rb
@@ -0,0 +1,112 @@
+require "abstract_unit"
+require "rails/subscriber/test_helper"
+require "action_dispatch/railties/subscriber"
+
+module DispatcherSubscriberTest
+ Boomer = lambda do |env|
+ req = ActionDispatch::Request.new(env)
+ case req.path
+ when "/"
+ [200, {}, []]
+ else
+ raise "puke!"
+ end
+ end
+
+ App = ActionDispatch::Notifications.new(Boomer)
+
+ def setup
+ Rails::Subscriber.add(:action_dispatch, ActionDispatch::Railties::Subscriber.new)
+ @app = App
+ super
+
+ @events = []