aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2017-05-26 20:00:27 +0200
committerGitHub <noreply@github.com>2017-05-26 20:00:27 +0200
commit24a864437e845febe91e3646ca008e8dc7f76b56 (patch)
tree0bc2430abcaa4834c351cdb8be7b2a9a9b920e16 /railties
parentb404764e15586902597d66aca31c157185b4b3a1 (diff)
downloadrails-24a864437e845febe91e3646ca008e8dc7f76b56.tar.gz
rails-24a864437e845febe91e3646ca008e8dc7f76b56.tar.bz2
rails-24a864437e845febe91e3646ca008e8dc7f76b56.zip
ActiveSupport::CurrentAttributes provides a thread-isolated attributes singleton (#29180)
* Add ActiveSupport::CurrentAttributes to provide a thread-isolated attributes singleton * Need to require first * Move stubs into test namespace. Thus they won't conflict with other Current and Person stubs. * End of the line for you, whitespace! * Support super in attribute methods. Define instance level accessors in an included module such that `super` in an overriden accessor works, akin to Active Model. * Spare users the manual require. Follow the example of concerns, autoload in the top level Active Support file. * Add bidelegation support * Rename #expose to #set. Simpler, clearer * Automatically reset every instance. Skips the need for users to actively embed something that resets their CurrentAttributes instances. * Fix test name; add tangible name value when blank. * Try to ensure we run after a request as well. * Delegate all missing methods to the instance This allows regular `delegate` to serve, so we don't need bidelegate. * Properly test resetting after execution cycle. Also remove the stale puts debugging. * Update documentation to match new autoreset
Diffstat (limited to 'railties')
-rw-r--r--railties/test/application/current_attributes_integration_test.rb88
1 files changed, 88 insertions, 0 deletions
diff --git a/railties/test/application/current_attributes_integration_test.rb b/railties/test/application/current_attributes_integration_test.rb
new file mode 100644
index 0000000000..eea2a791a2
--- /dev/null
+++ b/railties/test/application/current_attributes_integration_test.rb
@@ -0,0 +1,88 @@
+require "isolation/abstract_unit"
+require "rack/test"
+
+class CurrentAttributesIntegrationTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+ include Rack::Test::Methods
+
+ setup do
+ build_app
+
+ app_file "app/services/current.rb", <<-RUBY
+ class Current < ActiveSupport::CurrentAttributes
+ attribute :customer
+
+ resets { Time.zone = "UTC" }
+
+ def customer=(customer)
+ super
+ Time.zone = customer.try(:time_zone)
+ end
+ end
+ RUBY
+
+ app_file "app/models/customer.rb", <<-RUBY
+ class Customer < Struct.new(:name)
+ def time_zone
+ "Copenhagen"
+ end
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get "/customers/:action", controller: :customers
+ end
+ RUBY
+
+ app_file "app/controllers/customers_controller.rb", <<-RUBY
+ class CustomersController < ApplicationController
+ def set_current_customer
+ Current.customer = Customer.new("david")
+ render :index
+ end
+
+ def set_no_customer
+ render :index
+ end
+ end
+ RUBY
+
+ app_file "app/views/customers/index.html.erb", <<-RUBY
+ <%= Current.customer.try(:name) || 'noone' %>,<%= Time.zone.name %>
+ RUBY
+
+ app_file "app/executor_intercept.rb", <<-RUBY
+ check_state = -> { puts [ Current.customer.try(:name) || "noone", Time.zone.name ].join(",") }
+
+ check_state.call
+
+ Rails.application.executor.wrap do
+ Current.customer = Customer.new("david")
+ check_state.call
+ end
+
+ check_state.call
+ RUBY
+
+ require "#{app_path}/config/environment"
+ end
+
+ teardown :teardown_app
+
+ test "current customer is assigned and cleared" do
+ get "/customers/set_current_customer"
+ assert_equal 200, last_response.status
+ assert_match(/david,Copenhagen/, last_response.body)
+
+ get "/customers/set_no_customer"
+ assert_equal 200, last_response.status
+ assert_match(/noone,UTC/, last_response.body)
+ end
+
+ test "resets after execution" do
+ Dir.chdir(app_path) do
+ assert_equal "noone,UTC\ndavid,Copenhagen\nnoone,UTC\n", `bin/rails runner app/executor_intercept.rb`
+ end
+ end
+end