From c8c2b3820e662a2f9dfbfdae7211625adfabf15f Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 12 Mar 2009 12:22:52 -0700 Subject: Eliminate internal render stack since we only need its head and tail --- actionpack/lib/action_view/base.rb | 18 ++++++++++++++++-- actionpack/lib/action_view/renderable.rb | 26 +++++++++++--------------- 2 files changed, 27 insertions(+), 17 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index fe6053e574..0f396817a5 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -221,10 +221,12 @@ module ActionView #:nodoc: def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc: @assigns = assigns_for_first_render @assigns_added = nil - @_render_stack = [] @controller = controller @helpers = ProxyModule.new(self) self.view_paths = view_paths + + @_first_template = nil + @_current_template = nil end attr_reader :view_paths @@ -286,7 +288,19 @@ module ActionView #:nodoc: # Access the current template being rendered. # Returns a ActionView::Template object. def template - @_render_stack.last + @_current_template + end + + def template=(template) #:nodoc: + @_first_template ||= template + @_current_template = template + end + + def with_template(current_template) + last_template, self.template = template, current_template + yield + ensure + self.template = last_template end private diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 41080ed629..ff7bc7d9de 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -27,23 +27,19 @@ module ActionView def render(view, local_assigns = {}) compile(local_assigns) - stack = view.instance_variable_get(:@_render_stack) - stack.push(self) - - view.send(:_evaluate_assigns_and_ivars) - view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type) - - result = view.send(method_name(local_assigns), local_assigns) do |*names| - ivar = :@_proc_for_layout - if !view.instance_variable_defined?(:"@content_for_#{names.first}") && view.instance_variable_defined?(ivar) && (proc = view.instance_variable_get(ivar)) - view.capture(*names, &proc) - elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}") - view.instance_variable_get(ivar) + view.with_template self do + view.send(:_evaluate_assigns_and_ivars) + view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type) + + view.send(method_name(local_assigns), local_assigns) do |*names| + ivar = :@_proc_for_layout + if !view.instance_variable_defined?(:"@content_for_#{names.first}") && view.instance_variable_defined?(ivar) && (proc = view.instance_variable_get(ivar)) + view.capture(*names, &proc) + elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}") + view.instance_variable_get(ivar) + end end end - - stack.pop - result end def method_name(local_assigns) -- cgit v1.2.3 From 91d274059536f09dffd87141e570c3eab9ebd9b4 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 12 Mar 2009 21:47:34 -0700 Subject: Return body parts directly to Rack rather than building a response string ourselves. Allows Rack middleware to orchestrate response building. --- actionpack/lib/action_controller/base.rb | 12 ++++---- actionpack/lib/action_controller/integration.rb | 10 ++++--- actionpack/lib/action_controller/response.rb | 37 +++++++++++++++++------- actionpack/lib/action_controller/test_process.rb | 4 +-- actionpack/test/controller/rack_test.rb | 2 +- actionpack/test/controller/send_file_test.rb | 4 +-- 6 files changed, 43 insertions(+), 26 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 0facf7066d..c6dd99e959 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -984,6 +984,7 @@ module ActionController #:nodoc: # of sending it as the response body to the browser. def render_to_string(options = nil, &block) #:doc: render(options, &block) + response.body ensure response.content_type = nil erase_render_results @@ -1020,7 +1021,7 @@ module ActionController #:nodoc: # Clears the rendered results, allowing for another render to be performed. def erase_render_results #:nodoc: - response.body = nil + response.body = [] @performed_render = false end @@ -1247,13 +1248,12 @@ module ActionController #:nodoc: response.status = interpret_status(status || DEFAULT_RENDER_STATUS_CODE) if append_response - response.body ||= '' - response.body << text.to_s + response.body_parts << text.to_s else response.body = case text - when Proc then text - when nil then " " # Safari doesn't pass the headers of the return if the response is zero length - else text.to_s + when Proc then text + when nil then [" "] # Safari doesn't pass the headers of the return if the response is zero length + else [text.to_s] end end end diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb index 1c05ab0bf6..4faa263e2d 100644 --- a/actionpack/lib/action_controller/integration.rb +++ b/actionpack/lib/action_controller/integration.rb @@ -332,11 +332,13 @@ module ActionController @cookies[name] = value end - @body = "" if body.is_a?(String) - @body << body + @body_parts = [body] + @body = body else - body.each { |part| @body << part } + @body_parts = [] + body.each { |part| @body_parts << part.to_s } + @body = @body_parts.join end if @controller = ActionController::Base.last_instantiation @@ -349,7 +351,7 @@ module ActionController @response = Response.new @response.status = status.to_s @response.headers.replace(@headers) - @response.body = @body + @response.body = @body_parts end # Decorate the response with the standard behavior of the diff --git a/actionpack/lib/action_controller/response.rb b/actionpack/lib/action_controller/response.rb index ccff473df0..c69223dd69 100644 --- a/actionpack/lib/action_controller/response.rb +++ b/actionpack/lib/action_controller/response.rb @@ -40,14 +40,28 @@ module ActionController # :nodoc: delegate :default_charset, :to => 'ActionController::Base' def initialize - @status = 200 + super @header = Rack::Utils::HeaderHash.new(DEFAULT_HEADERS) + @session, @assigns = [], [] + end - @writer = lambda { |x| @body << x } - @block = nil + def body + str = '' + each { |part| str << part.to_s } + str + end - @body = "", - @session, @assigns = [], [] + def body=(body) + @body = + if body.is_a?(String) + [body] + else + body + end + end + + def body_parts + @body end def location; headers['Location'] end @@ -152,7 +166,7 @@ module ActionController # :nodoc: @writer = lambda { |x| callback.call(x) } @body.call(self, self) elsif @body.is_a?(String) - @body.each_line(&callback) + callback.call(@body) else @body.each(&callback) end @@ -162,7 +176,8 @@ module ActionController # :nodoc: end def write(str) - @writer.call str.to_s + str = str.to_s + @writer.call str str end @@ -186,7 +201,7 @@ module ActionController # :nodoc: if request && request.etag_matches?(etag) self.status = '304 Not Modified' - self.body = '' + self.body = [] end set_conditional_cache_control! @@ -195,7 +210,7 @@ module ActionController # :nodoc: def nonempty_ok_response? ok = !status || status.to_s[0..2] == '200' - ok && body.is_a?(String) && !body.empty? + ok && !body_parts.respond_to?(:call) && body_parts.any? end def set_conditional_cache_control! @@ -216,8 +231,8 @@ module ActionController # :nodoc: headers.delete('Content-Length') elsif length = headers['Content-Length'] headers['Content-Length'] = length.to_s - elsif !body.respond_to?(:call) && (!status || status.to_s[0..2] != '304') - headers["Content-Length"] = (body.respond_to?(:bytesize) ? body.bytesize : body.size).to_s + elsif !body_parts.respond_to?(:call) && (!status || status.to_s[0..2] != '304') + headers["Content-Length"] = Rack::Utils.bytesize(body).to_s end end diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index dbaec00bee..9dd09c30b4 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -258,11 +258,11 @@ module ActionController #:nodoc: # Returns binary content (downloadable file), converted to a String def binary_content - raise "Response body is not a Proc: #{body.inspect}" unless body.kind_of?(Proc) + raise "Response body is not a Proc: #{body_parts.inspect}" unless body_parts.kind_of?(Proc) require 'stringio' sio = StringIO.new - body.call(self, sio) + body_parts.call(self, sio) sio.rewind sio.read diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index b550d3db78..89bf4fdacc 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -258,7 +258,7 @@ class RackResponseTest < BaseRackTest }, headers) parts = [] - body.each { |part| parts << part } + body.each { |part| parts << part.to_s } assert_equal ["0", "1", "2", "3", "4"], parts end end diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index a27e951929..3d1904fee9 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -44,12 +44,12 @@ class SendFileTest < ActionController::TestCase response = nil assert_nothing_raised { response = process('file') } assert_not_nil response - assert_kind_of Proc, response.body + assert_kind_of Proc, response.body_parts require 'stringio' output = StringIO.new output.binmode - assert_nothing_raised { response.body.call(response, output) } + assert_nothing_raised { response.body_parts.call(response, output) } assert_equal file_data, output.string end -- cgit v1.2.3 From 3d260760f035c5aab11ab218881ed36e3046157b Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 13 Mar 2009 00:25:05 -0700 Subject: Introduce flush_output_buffer to append the buffer to the response body then start a new buffer. Useful for pushing custom parts to the response body without disrupting template rendering. --- .../lib/action_view/helpers/capture_helper.rb | 8 +++++ actionpack/test/template/output_buffer_test.rb | 35 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 actionpack/test/template/output_buffer_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index e86ca27f31..9e39536653 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -131,6 +131,14 @@ module ActionView ensure self.output_buffer = old_buffer end + + # Add the output buffer to the response body and start a new one. + def flush_output_buffer #:nodoc: + if output_buffer && output_buffer != '' + response.body_parts << output_buffer + self.output_buffer = '' + end + end end end end diff --git a/actionpack/test/template/output_buffer_test.rb b/actionpack/test/template/output_buffer_test.rb new file mode 100644 index 0000000000..6d8eab63dc --- /dev/null +++ b/actionpack/test/template/output_buffer_test.rb @@ -0,0 +1,35 @@ +require 'abstract_unit' + +class OutputBufferTest < ActionController::TestCase + class TestController < ActionController::Base + def index + render :text => 'foo' + end + end + + tests TestController + + def test_flush_output_buffer + # Start with the default body parts + get :index + assert_equal ['foo'], @response.body_parts + assert_nil @response.template.output_buffer + + # Nil output buffer is skipped + @response.template.flush_output_buffer + assert_nil @response.template.output_buffer + assert_equal ['foo'], @response.body_parts + + # Empty output buffer is skipped + @response.template.output_buffer = '' + @response.template.flush_output_buffer + assert_equal '', @response.template.output_buffer + assert_equal ['foo'], @response.body_parts + + # Flushing appends the output buffer to the body parts + @response.template.output_buffer = 'bar' + @response.template.flush_output_buffer + assert_equal '', @response.template.output_buffer + assert_equal ['foo', 'bar'], @response.body_parts + end +end -- cgit v1.2.3 From 79b0b1a0ef926e91388e24bc77d3831f6d50b13d Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 13 Mar 2009 02:15:51 -0700 Subject: Extract Response#string_body? --- actionpack/lib/action_controller/response.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/response.rb b/actionpack/lib/action_controller/response.rb index c69223dd69..febe4ccf29 100644 --- a/actionpack/lib/action_controller/response.rb +++ b/actionpack/lib/action_controller/response.rb @@ -210,7 +210,11 @@ module ActionController # :nodoc: def nonempty_ok_response? ok = !status || status.to_s[0..2] == '200' - ok && !body_parts.respond_to?(:call) && body_parts.any? + ok && string_body? + end + + def string_body? + !body_parts.respond_to?(:call) && body_parts.any? && body_parts.all? { |part| part.is_a?(String) } end def set_conditional_cache_control! @@ -231,7 +235,7 @@ module ActionController # :nodoc: headers.delete('Content-Length') elsif length = headers['Content-Length'] headers['Content-Length'] = length.to_s - elsif !body_parts.respond_to?(:call) && (!status || status.to_s[0..2] != '304') + elsif string_body? && (!status || status.to_s[0..2] != '304') headers["Content-Length"] = Rack::Utils.bytesize(body).to_s end end -- cgit v1.2.3 From 7c1714cbd0b37d1fc5ca2ac3e08980943454d516 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 13 Mar 2009 02:36:00 -0700 Subject: Body parts: future rendering, threaded future, queued future, open-uri example --- actionpack/lib/action_view/base.rb | 10 +- actionpack/lib/action_view/body_parts/future.rb | 26 ++++ actionpack/lib/action_view/body_parts/open_uri.rb | 13 ++ actionpack/lib/action_view/body_parts/queued.rb | 21 ++++ actionpack/lib/action_view/body_parts/threaded.rb | 21 ++++ actionpack/test/template/body_parts_test.rb | 142 ++++++++++++++++++++++ actionpack/test/template/output_buffer_test.rb | 35 ------ 7 files changed, 231 insertions(+), 37 deletions(-) create mode 100644 actionpack/lib/action_view/body_parts/future.rb create mode 100644 actionpack/lib/action_view/body_parts/open_uri.rb create mode 100644 actionpack/lib/action_view/body_parts/queued.rb create mode 100644 actionpack/lib/action_view/body_parts/threaded.rb create mode 100644 actionpack/test/template/body_parts_test.rb delete mode 100644 actionpack/test/template/output_buffer_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index e19acc5c29..3bbd2ca530 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -288,12 +288,12 @@ module ActionView #:nodoc: # Access the current template being rendered. # Returns a ActionView::Template object. def template - @_current_render + Thread.current[:_current_render] end def template=(template) #:nodoc: @_first_render ||= template - @_current_render = template + Thread.current[:_current_render] = template end def with_template(current_template) @@ -303,6 +303,12 @@ module ActionView #:nodoc: self.template = last_template end + def punctuate_body!(part) + flush_output_buffer + response.body_parts << part + nil + end + private # Evaluates the local assigns and controller ivars, pushes them to the view. def _evaluate_assigns_and_ivars #:nodoc: diff --git a/actionpack/lib/action_view/body_parts/future.rb b/actionpack/lib/action_view/body_parts/future.rb new file mode 100644 index 0000000000..a5291c6e8c --- /dev/null +++ b/actionpack/lib/action_view/body_parts/future.rb @@ -0,0 +1,26 @@ +module ActionView + module BodyParts + class Future + def initialize(&block) + @block = block + @parts = [] + end + + def to_s + finish + body + end + + protected + def work + @block.call(@parts) + end + + def body + str = '' + @parts.each { |part| str << part.to_s } + str + end + end + end +end diff --git a/actionpack/lib/action_view/body_parts/open_uri.rb b/actionpack/lib/action_view/body_parts/open_uri.rb new file mode 100644 index 0000000000..8ebd17b4a1 --- /dev/null +++ b/actionpack/lib/action_view/body_parts/open_uri.rb @@ -0,0 +1,13 @@ +require 'action_view/body_parts/threaded' +require 'open-uri' + +module ActionView + module BodyParts + class OpenUri < Threaded + def initialize(url) + url = URI::Generic === url ? url : URI.parse(url) + super(true) { |parts| parts << url.read } + end + end + end +end diff --git a/actionpack/lib/action_view/body_parts/queued.rb b/actionpack/lib/action_view/body_parts/queued.rb new file mode 100644 index 0000000000..f8501f6a85 --- /dev/null +++ b/actionpack/lib/action_view/body_parts/queued.rb @@ -0,0 +1,21 @@ +require 'action_view/body_parts/future' + +module ActionView + module BodyParts + class Queued < Future + def initialize(job, &block) + super(&block) + enqueue(job) + end + + protected + def enqueue(job) + @receipt = submit(job) + end + + def finish + @parts << redeem(@receipt) + end + end + end +end diff --git a/actionpack/lib/action_view/body_parts/threaded.rb b/actionpack/lib/action_view/body_parts/threaded.rb new file mode 100644 index 0000000000..34800bf9c7 --- /dev/null +++ b/actionpack/lib/action_view/body_parts/threaded.rb @@ -0,0 +1,21 @@ +require 'action_view/body_parts/future' + +module ActionView + module BodyParts + class Threaded < Future + def initialize(concurrent = false, &block) + super(&block) + concurrent ? start : work + end + + protected + def start + @worker = Thread.new { work } + end + + def finish + @worker.join if @worker && @worker.alive? + end + end + end +end diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb new file mode 100644 index 0000000000..d15c8808d9 --- /dev/null +++ b/actionpack/test/template/body_parts_test.rb @@ -0,0 +1,142 @@ +require 'abstract_unit' +require 'action_view/body_parts/queued' +require 'action_view/body_parts/open_uri' + +class OutputBufferTest < ActionController::TestCase + class TestController < ActionController::Base + def index + render :text => 'foo' + end + end + + tests TestController + + def test_flush_output_buffer + # Start with the default body parts + get :index + assert_equal ['foo'], @response.body_parts + assert_nil @response.template.output_buffer + + # Nil output buffer is skipped + @response.template.flush_output_buffer + assert_nil @response.template.output_buffer + assert_equal ['foo'], @response.body_parts + + # Empty output buffer is skipped + @response.template.output_buffer = '' + @response.template.flush_output_buffer + assert_equal '', @response.template.output_buffer + assert_equal ['foo'], @response.body_parts + + # Flushing appends the output buffer to the body parts + @response.template.output_buffer = 'bar' + @response.template.flush_output_buffer + assert_equal '', @response.template.output_buffer + assert_equal ['foo', 'bar'], @response.body_parts + end +end + +class QueuedPartTest < ActionController::TestCase + class SimpleQueued < ActionView::BodyParts::Queued + protected + def submit(job) + job + end + + def redeem(receipt) + receipt.to_s.reverse + end + end + + class TestController < ActionController::Base + def index + queued_render 'foo' + queued_render 'bar' + queued_render 'baz' + @performed_render = true + end + + def queued_render(job) + response.template.punctuate_body! SimpleQueued.new(job) + end + end + + tests TestController + + def test_queued_parts + get :index + assert_equal 'oofrabzab', @response.body + end +end + +class ThreadedPartTest < ActionController::TestCase + class TestController < ActionController::Base + def index + append_thread_id = lambda do |parts| + parts << Thread.current.object_id + parts << '::' + parts << Time.now.to_i + sleep 1 + end + + future_render &append_thread_id + response.body_parts << '-' + + future_render &append_thread_id + response.body_parts << '-' + + future_render do |parts| + parts << ActionView::BodyParts::Threaded.new(true, &append_thread_id) + parts << '-' + parts << ActionView::BodyParts::Threaded.new(true, &append_thread_id) + end + + @performed_render = true + end + + def future_render(&block) + response.template.punctuate_body! ActionView::BodyParts::Threaded.new(true, &block) + end + end + + tests TestController + + def test_concurrent_threaded_parts + get :index + + before = Time.now.to_i + thread_ids = @response.body.split('-').map { |part| part.split('::').first.to_i } + elapsed = Time.now.to_i - before + + assert_equal thread_ids.size, thread_ids.uniq.size + assert elapsed < 1.1 + end +end + +class OpenUriPartTest < ActionController::TestCase + class TestController < ActionController::Base + def index + render_url 'http://localhost/foo' + render_url 'http://localhost/bar' + render_url 'http://localhost/baz' + @performed_render = true + end + + def render_url(url) + url = URI.parse(url) + def url.read; path end + response.template.punctuate_body! ActionView::BodyParts::OpenUri.new(url) + end + end + + tests TestController + + def test_concurrent_open_uri_parts + get :index + + elapsed = Benchmark.ms do + assert_equal '/foo/bar/baz', @response.body + end + assert elapsed < 1.1 + end +end diff --git a/actionpack/test/template/output_buffer_test.rb b/actionpack/test/template/output_buffer_test.rb deleted file mode 100644 index 6d8eab63dc..0000000000 --- a/actionpack/test/template/output_buffer_test.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'abstract_unit' - -class OutputBufferTest < ActionController::TestCase - class TestController < ActionController::Base - def index - render :text => 'foo' - end - end - - tests TestController - - def test_flush_output_buffer - # Start with the default body parts - get :index - assert_equal ['foo'], @response.body_parts - assert_nil @response.template.output_buffer - - # Nil output buffer is skipped - @response.template.flush_output_buffer - assert_nil @response.template.output_buffer - assert_equal ['foo'], @response.body_parts - - # Empty output buffer is skipped - @response.template.output_buffer = '' - @response.template.flush_output_buffer - assert_equal '', @response.template.output_buffer - assert_equal ['foo'], @response.body_parts - - # Flushing appends the output buffer to the body parts - @response.template.output_buffer = 'bar' - @response.template.flush_output_buffer - assert_equal '', @response.template.output_buffer - assert_equal ['foo', 'bar'], @response.body_parts - end -end -- cgit v1.2.3 From 5d76dee329282acc918de50fecde869f1431e2f1 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 13 Mar 2009 02:55:24 -0700 Subject: Example using an edge side include body part to fetch queued rendering results --- actionpack/lib/action_view/body_parts/open_uri.rb | 13 -------- actionpack/test/template/body_parts_test.rb | 36 +++++++++++++++++------ 2 files changed, 27 insertions(+), 22 deletions(-) delete mode 100644 actionpack/lib/action_view/body_parts/open_uri.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/body_parts/open_uri.rb b/actionpack/lib/action_view/body_parts/open_uri.rb deleted file mode 100644 index 8ebd17b4a1..0000000000 --- a/actionpack/lib/action_view/body_parts/open_uri.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'action_view/body_parts/threaded' -require 'open-uri' - -module ActionView - module BodyParts - class OpenUri < Threaded - def initialize(url) - url = URI::Generic === url ? url : URI.parse(url) - super(true) { |parts| parts << url.read } - end - end - end -end diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb index d15c8808d9..88f09af94f 100644 --- a/actionpack/test/template/body_parts_test.rb +++ b/actionpack/test/template/body_parts_test.rb @@ -36,28 +36,36 @@ class OutputBufferTest < ActionController::TestCase end end + class QueuedPartTest < ActionController::TestCase - class SimpleQueued < ActionView::BodyParts::Queued + class EdgeSideInclude < ActionView::BodyParts::Queued + QUEUE_REDEMPTION_URL = 'http://queue/jobs/%s' + ESI_INCLUDE_TAG = '' + + def self.redemption_tag(receipt) + ESI_INCLUDE_TAG % QUEUE_REDEMPTION_URL % receipt + end + protected def submit(job) - job + job.reverse end def redeem(receipt) - receipt.to_s.reverse + self.class.redemption_tag(receipt) end end class TestController < ActionController::Base def index - queued_render 'foo' - queued_render 'bar' - queued_render 'baz' + edge_side_include 'foo' + edge_side_include 'bar' + edge_side_include 'baz' @performed_render = true end - def queued_render(job) - response.template.punctuate_body! SimpleQueued.new(job) + def edge_side_include(job) + response.template.punctuate_body! EdgeSideInclude.new(job) end end @@ -65,10 +73,12 @@ class QueuedPartTest < ActionController::TestCase def test_queued_parts get :index - assert_equal 'oofrabzab', @response.body + expected = %(oof rab zab).map { |receipt| EdgeSideInclude.redemption_tag(receipt) } + assert_equal expected, @response.body end end + class ThreadedPartTest < ActionController::TestCase class TestController < ActionController::Base def index @@ -113,7 +123,15 @@ class ThreadedPartTest < ActionController::TestCase end end + class OpenUriPartTest < ActionController::TestCase + class OpenUri < ActionView::BodyParts::Threaded + def initialize(url) + url = URI::Generic === url ? url : URI.parse(url) + super(true) { |parts| parts << url.read } + end + end + class TestController < ActionController::Base def index render_url 'http://localhost/foo' -- cgit v1.2.3 From d54d97b07c1b258f42210b1a3fc2e8c56e434ee9 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 13 Mar 2009 03:01:47 -0700 Subject: Fix tests --- actionpack/test/template/body_parts_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb index 88f09af94f..7418f4a716 100644 --- a/actionpack/test/template/body_parts_test.rb +++ b/actionpack/test/template/body_parts_test.rb @@ -1,6 +1,6 @@ require 'abstract_unit' require 'action_view/body_parts/queued' -require 'action_view/body_parts/open_uri' +require 'action_view/body_parts/threaded' class OutputBufferTest < ActionController::TestCase class TestController < ActionController::Base @@ -73,7 +73,7 @@ class QueuedPartTest < ActionController::TestCase def test_queued_parts get :index - expected = %(oof rab zab).map { |receipt| EdgeSideInclude.redemption_tag(receipt) } + expected = %w(oof rab zab).map { |receipt| EdgeSideInclude.redemption_tag(receipt) }.join assert_equal expected, @response.body end end @@ -125,7 +125,7 @@ end class OpenUriPartTest < ActionController::TestCase - class OpenUri < ActionView::BodyParts::Threaded + class OpenUriPart < ActionView::BodyParts::Threaded def initialize(url) url = URI::Generic === url ? url : URI.parse(url) super(true) { |parts| parts << url.read } @@ -143,7 +143,7 @@ class OpenUriPartTest < ActionController::TestCase def render_url(url) url = URI.parse(url) def url.read; path end - response.template.punctuate_body! ActionView::BodyParts::OpenUri.new(url) + response.template.punctuate_body! OpenUriPart.new(url) end end -- cgit v1.2.3 From b2f98c13a3308e6db618d6f3f9f706cbc19f13fd Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 13 Mar 2009 03:16:14 -0700 Subject: Simplify parts and tests --- actionpack/lib/action_view/body_parts/future.rb | 16 ---------------- actionpack/lib/action_view/body_parts/queued.rb | 13 +++++-------- actionpack/lib/action_view/body_parts/threaded.rb | 13 ++++++++++++- actionpack/test/template/body_parts_test.rb | 17 ++++++++--------- 4 files changed, 25 insertions(+), 34 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/body_parts/future.rb b/actionpack/lib/action_view/body_parts/future.rb index a5291c6e8c..f03c2b395b 100644 --- a/actionpack/lib/action_view/body_parts/future.rb +++ b/actionpack/lib/action_view/body_parts/future.rb @@ -1,26 +1,10 @@ module ActionView module BodyParts class Future - def initialize(&block) - @block = block - @parts = [] - end - def to_s finish body end - - protected - def work - @block.call(@parts) - end - - def body - str = '' - @parts.each { |part| str << part.to_s } - str - end end end end diff --git a/actionpack/lib/action_view/body_parts/queued.rb b/actionpack/lib/action_view/body_parts/queued.rb index f8501f6a85..618999742b 100644 --- a/actionpack/lib/action_view/body_parts/queued.rb +++ b/actionpack/lib/action_view/body_parts/queued.rb @@ -3,18 +3,15 @@ require 'action_view/body_parts/future' module ActionView module BodyParts class Queued < Future - def initialize(job, &block) - super(&block) - enqueue(job) + attr_reader :body + + def initialize(job) + @receipt = enqueue(job) end protected - def enqueue(job) - @receipt = submit(job) - end - def finish - @parts << redeem(@receipt) + @body = redeem(@receipt) end end end diff --git a/actionpack/lib/action_view/body_parts/threaded.rb b/actionpack/lib/action_view/body_parts/threaded.rb index 34800bf9c7..a2347a2f0e 100644 --- a/actionpack/lib/action_view/body_parts/threaded.rb +++ b/actionpack/lib/action_view/body_parts/threaded.rb @@ -4,11 +4,22 @@ module ActionView module BodyParts class Threaded < Future def initialize(concurrent = false, &block) - super(&block) + @block = block + @parts = [] concurrent ? start : work end protected + def work + @block.call(@parts) + end + + def body + str = '' + @parts.each { |part| str << part.to_s } + str + end + def start @worker = Thread.new { work } end diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb index 7418f4a716..4555a6b015 100644 --- a/actionpack/test/template/body_parts_test.rb +++ b/actionpack/test/template/body_parts_test.rb @@ -47,7 +47,7 @@ class QueuedPartTest < ActionController::TestCase end protected - def submit(job) + def enqueue(job) job.reverse end @@ -114,12 +114,11 @@ class ThreadedPartTest < ActionController::TestCase def test_concurrent_threaded_parts get :index - before = Time.now.to_i - thread_ids = @response.body.split('-').map { |part| part.split('::').first.to_i } - elapsed = Time.now.to_i - before - - assert_equal thread_ids.size, thread_ids.uniq.size - assert elapsed < 1.1 + elapsed = Benchmark.ms do + thread_ids = @response.body.split('-').map { |part| part.split('::').first.to_i } + assert_equal thread_ids.size, thread_ids.uniq.size + end + assert (elapsed - 1000).abs < 100, elapsed end end @@ -142,7 +141,7 @@ class OpenUriPartTest < ActionController::TestCase def render_url(url) url = URI.parse(url) - def url.read; path end + def url.read; sleep 1; path end response.template.punctuate_body! OpenUriPart.new(url) end end @@ -155,6 +154,6 @@ class OpenUriPartTest < ActionController::TestCase elapsed = Benchmark.ms do assert_equal '/foo/bar/baz', @response.body end - assert elapsed < 1.1 + assert (elapsed - 1000).abs < 100, elapsed end end -- cgit v1.2.3 From 2f998fc81fd3525e4f19ba55937ee423c4b71856 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 13 Mar 2009 03:23:13 -0700 Subject: Extract output buffer test --- actionpack/test/template/body_parts_test.rb | 34 ------------------------- actionpack/test/template/output_buffer_test.rb | 35 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 34 deletions(-) create mode 100644 actionpack/test/template/output_buffer_test.rb (limited to 'actionpack') diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb index 4555a6b015..aece24635c 100644 --- a/actionpack/test/template/body_parts_test.rb +++ b/actionpack/test/template/body_parts_test.rb @@ -2,40 +2,6 @@ require 'abstract_unit' require 'action_view/body_parts/queued' require 'action_view/body_parts/threaded' -class OutputBufferTest < ActionController::TestCase - class TestController < ActionController::Base - def index - render :text => 'foo' - end - end - - tests TestController - - def test_flush_output_buffer - # Start with the default body parts - get :index - assert_equal ['foo'], @response.body_parts - assert_nil @response.template.output_buffer - - # Nil output buffer is skipped - @response.template.flush_output_buffer - assert_nil @response.template.output_buffer - assert_equal ['foo'], @response.body_parts - - # Empty output buffer is skipped - @response.template.output_buffer = '' - @response.template.flush_output_buffer - assert_equal '', @response.template.output_buffer - assert_equal ['foo'], @response.body_parts - - # Flushing appends the output buffer to the body parts - @response.template.output_buffer = 'bar' - @response.template.flush_output_buffer - assert_equal '', @response.template.output_buffer - assert_equal ['foo', 'bar'], @response.body_parts - end -end - class QueuedPartTest < ActionController::TestCase class EdgeSideInclude < ActionView::BodyParts::Queued diff --git a/actionpack/test/template/output_buffer_test.rb b/actionpack/test/template/output_buffer_test.rb new file mode 100644 index 0000000000..6d8eab63dc --- /dev/null +++ b/actionpack/test/template/output_buffer_test.rb @@ -0,0 +1,35 @@ +require 'abstract_unit' + +class OutputBufferTest < ActionController::TestCase + class TestController < ActionController::Base + def index + render :text => 'foo' + end + end + + tests TestController + + def test_flush_output_buffer + # Start with the default body parts + get :index + assert_equal ['foo'], @response.body_parts + assert_nil @response.template.output_buffer + + # Nil output buffer is skipped + @response.template.flush_output_buffer + assert_nil @response.template.output_buffer + assert_equal ['foo'], @response.body_parts + + # Empty output buffer is skipped + @response.template.output_buffer = '' + @response.template.flush_output_buffer + assert_equal '', @response.template.output_buffer + assert_equal ['foo'], @response.body_parts + + # Flushing appends the output buffer to the body parts + @response.template.output_buffer = 'bar' + @response.template.flush_output_buffer + assert_equal '', @response.template.output_buffer + assert_equal ['foo', 'bar'], @response.body_parts + end +end -- cgit v1.2.3 From 4a7b11d5d857a0f5ce6eb8af7a6dfcb94f31fcfa Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 13 Mar 2009 18:49:53 -0700 Subject: Less ceremony --- .../lib/action_view/body_parts/concurrent_block.rb | 25 +++++++++ actionpack/lib/action_view/body_parts/future.rb | 10 ---- actionpack/lib/action_view/body_parts/queued.rb | 18 ------- actionpack/lib/action_view/body_parts/threaded.rb | 32 ------------ actionpack/test/template/body_parts_test.rb | 61 ++++++++++++---------- 5 files changed, 59 insertions(+), 87 deletions(-) create mode 100644 actionpack/lib/action_view/body_parts/concurrent_block.rb delete mode 100644 actionpack/lib/action_view/body_parts/future.rb delete mode 100644 actionpack/lib/action_view/body_parts/queued.rb delete mode 100644 actionpack/lib/action_view/body_parts/threaded.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/body_parts/concurrent_block.rb b/actionpack/lib/action_view/body_parts/concurrent_block.rb new file mode 100644 index 0000000000..28a3a3bf4d --- /dev/null +++ b/actionpack/lib/action_view/body_parts/concurrent_block.rb @@ -0,0 +1,25 @@ +module ActionView + module BodyParts + class ConcurrentBlock + def initialize(&block) + @block = block + @body = [] + start + end + + def to_s + finish + @body.join + end + + protected + def start + @worker = Thread.new { @block.call(@body) } + end + + def finish + @worker.join if @worker && @worker.alive? + end + end + end +end diff --git a/actionpack/lib/action_view/body_parts/future.rb b/actionpack/lib/action_view/body_parts/future.rb deleted file mode 100644 index f03c2b395b..0000000000 --- a/actionpack/lib/action_view/body_parts/future.rb +++ /dev/null @@ -1,10 +0,0 @@ -module ActionView - module BodyParts - class Future - def to_s - finish - body - end - end - end -end diff --git a/actionpack/lib/action_view/body_parts/queued.rb b/actionpack/lib/action_view/body_parts/queued.rb deleted file mode 100644 index 618999742b..0000000000 --- a/actionpack/lib/action_view/body_parts/queued.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'action_view/body_parts/future' - -module ActionView - module BodyParts - class Queued < Future - attr_reader :body - - def initialize(job) - @receipt = enqueue(job) - end - - protected - def finish - @body = redeem(@receipt) - end - end - end -end diff --git a/actionpack/lib/action_view/body_parts/threaded.rb b/actionpack/lib/action_view/body_parts/threaded.rb deleted file mode 100644 index a2347a2f0e..0000000000 --- a/actionpack/lib/action_view/body_parts/threaded.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'action_view/body_parts/future' - -module ActionView - module BodyParts - class Threaded < Future - def initialize(concurrent = false, &block) - @block = block - @parts = [] - concurrent ? start : work - end - - protected - def work - @block.call(@parts) - end - - def body - str = '' - @parts.each { |part| str << part.to_s } - str - end - - def start - @worker = Thread.new { work } - end - - def finish - @worker.join if @worker && @worker.alive? - end - end - end -end diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb index aece24635c..369756cbf5 100644 --- a/actionpack/test/template/body_parts_test.rb +++ b/actionpack/test/template/body_parts_test.rb @@ -1,37 +1,44 @@ require 'abstract_unit' -require 'action_view/body_parts/queued' -require 'action_view/body_parts/threaded' +require 'action_view/body_parts/concurrent_block' - -class QueuedPartTest < ActionController::TestCase - class EdgeSideInclude < ActionView::BodyParts::Queued - QUEUE_REDEMPTION_URL = 'http://queue/jobs/%s' +class BodyPartTest < ActionController::TestCase + module EdgeSideInclude + QUEUE_REDEMPTION_URL = 'http://render.farm/renderings/%s' ESI_INCLUDE_TAG = '' def self.redemption_tag(receipt) ESI_INCLUDE_TAG % QUEUE_REDEMPTION_URL % receipt end - protected - def enqueue(job) - job.reverse + class BodyPart + def initialize(rendering) + @receipt = enqueue(rendering) end - def redeem(receipt) - self.class.redemption_tag(receipt) + def to_s + EdgeSideInclude.redemption_tag(@receipt) end + + protected + # Pretend we sent this rendering off for processing. + def enqueue(rendering) + rendering.object_id.to_s + end + end end class TestController < ActionController::Base + RENDERINGS = [Object.new, Object.new, Object.new] + def index - edge_side_include 'foo' - edge_side_include 'bar' - edge_side_include 'baz' + RENDERINGS.each do |rendering| + edge_side_include rendering + end @performed_render = true end - def edge_side_include(job) - response.template.punctuate_body! EdgeSideInclude.new(job) + def edge_side_include(rendering) + response.template.punctuate_body! EdgeSideInclude::BodyPart.new(rendering) end end @@ -39,20 +46,20 @@ class QueuedPartTest < ActionController::TestCase def test_queued_parts get :index - expected = %w(oof rab zab).map { |receipt| EdgeSideInclude.redemption_tag(receipt) }.join + expected = TestController::RENDERINGS.map { |rendering| EdgeSideInclude.redemption_tag(rendering.object_id) }.join assert_equal expected, @response.body end end -class ThreadedPartTest < ActionController::TestCase +class ConcurrentBlockPartTest < ActionController::TestCase class TestController < ActionController::Base def index append_thread_id = lambda do |parts| parts << Thread.current.object_id parts << '::' parts << Time.now.to_i - sleep 1 + sleep 0.1 end future_render &append_thread_id @@ -62,16 +69,16 @@ class ThreadedPartTest < ActionController::TestCase response.body_parts << '-' future_render do |parts| - parts << ActionView::BodyParts::Threaded.new(true, &append_thread_id) + parts << ActionView::BodyParts::ConcurrentBlock.new(&append_thread_id) parts << '-' - parts << ActionView::BodyParts::Threaded.new(true, &append_thread_id) + parts << ActionView::BodyParts::ConcurrentBlock.new(&append_thread_id) end @performed_render = true end def future_render(&block) - response.template.punctuate_body! ActionView::BodyParts::Threaded.new(true, &block) + response.template.punctuate_body! ActionView::BodyParts::ConcurrentBlock.new(&block) end end @@ -84,16 +91,16 @@ class ThreadedPartTest < ActionController::TestCase thread_ids = @response.body.split('-').map { |part| part.split('::').first.to_i } assert_equal thread_ids.size, thread_ids.uniq.size end - assert (elapsed - 1000).abs < 100, elapsed + assert (elapsed - 100).abs < 10, elapsed end end class OpenUriPartTest < ActionController::TestCase - class OpenUriPart < ActionView::BodyParts::Threaded + class OpenUriPart < ActionView::BodyParts::ConcurrentBlock def initialize(url) url = URI::Generic === url ? url : URI.parse(url) - super(true) { |parts| parts << url.read } + super() { |body| body << url.read } end end @@ -107,7 +114,7 @@ class OpenUriPartTest < ActionController::TestCase def render_url(url) url = URI.parse(url) - def url.read; sleep 1; path end + def url.read; sleep 0.1; path end response.template.punctuate_body! OpenUriPart.new(url) end end @@ -120,6 +127,6 @@ class OpenUriPartTest < ActionController::TestCase elapsed = Benchmark.ms do assert_equal '/foo/bar/baz', @response.body end - assert (elapsed - 1000).abs < 100, elapsed + assert (elapsed - 100).abs < 10, elapsed end end -- cgit v1.2.3 From 07710fd3e0c5c84521b7929738ba33cea99bc108 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Sat, 14 Mar 2009 10:06:00 -0500 Subject: Fix requirements for additional member/collection routes [#2054 state:resolved] Signed-off-by: Joshua Peek --- actionpack/lib/action_controller/resources.rb | 11 ++++++----- actionpack/test/controller/resources_test.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb index 5f71a105c8..86abb7b2f4 100644 --- a/actionpack/lib/action_controller/resources.rb +++ b/actionpack/lib/action_controller/resources.rb @@ -630,7 +630,7 @@ module ActionController action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash) action_path ||= Base.resources_path_names[action] || action - map_resource_routes(map, resource, action, "#{resource.member_path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", m) + map_resource_routes(map, resource, action, "#{resource.member_path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", m, { :force_id => true }) end end end @@ -641,9 +641,9 @@ module ActionController map_resource_routes(map, resource, :destroy, resource.member_path, route_path) end - def map_resource_routes(map, resource, action, route_path, route_name = nil, method = nil) + def map_resource_routes(map, resource, action, route_path, route_name = nil, method = nil, resource_options = {} ) if resource.has_action?(action) - action_options = action_options_for(action, resource, method) + action_options = action_options_for(action, resource, method, resource_options) formatted_route_path = "#{route_path}.:format" if route_name && @set.named_routes[route_name.to_sym].nil? @@ -660,9 +660,10 @@ module ActionController end end - def action_options_for(action, resource, method = nil) + def action_options_for(action, resource, method = nil, resource_options = {}) default_options = { :action => action.to_s } require_id = !resource.kind_of?(SingletonResource) + force_id = resource_options[:force_id] && !resource.kind_of?(SingletonResource) case default_options[:action] when "index", "new"; default_options.merge(add_conditions_for(resource.conditions, method || :get)).merge(resource.requirements) @@ -670,7 +671,7 @@ module ActionController when "show", "edit"; default_options.merge(add_conditions_for(resource.conditions, method || :get)).merge(resource.requirements(require_id)) when "update"; default_options.merge(add_conditions_for(resource.conditions, method || :put)).merge(resource.requirements(require_id)) when "destroy"; default_options.merge(add_conditions_for(resource.conditions, method || :delete)).merge(resource.requirements(require_id)) - else default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements) + else default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements(force_id)) end end end diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index 91066ea893..c807e71cd7 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -175,6 +175,24 @@ class ResourcesTest < ActionController::TestCase end end + def test_with_collection_actions_and_name_prefix_and_member_action_with_same_name + actions = { 'a' => :get } + + with_restful_routing :messages, :path_prefix => '/threads/:thread_id', :name_prefix => "thread_", :collection => actions, :member => actions do + assert_restful_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options| + actions.each do |action, method| + assert_recognizes(options.merge(:action => action), :path => "/threads/1/messages/#{action}", :method => method) + end + end + + assert_restful_named_routes_for :messages, :path_prefix => 'threads/1/', :name_prefix => 'thread_', :options => { :thread_id => '1' } do |options| + actions.keys.each do |action| + assert_named_route "/threads/1/messages/#{action}", "#{action}_thread_messages_path", :action => action + end + end + end + end + def test_with_collection_action_and_name_prefix_and_formatted actions = { 'a' => :get, 'b' => :put, 'c' => :post, 'd' => :delete } @@ -209,6 +227,14 @@ class ResourcesTest < ActionController::TestCase end end + def test_with_member_action_and_requirement + expected_options = {:controller => 'messages', :action => 'mark', :id => '1.1.1'} + + with_restful_routing(:messages, :requirements => {:id => /[0-9]\.[0-9]\.[0-9]/}, :member => { :mark => :get }) do + assert_recognizes(expected_options, :path => 'messages/1.1.1/mark', :method => :get) + end + end + def test_member_when_override_paths_for_default_restful_actions_with [:put, :post].each do |method| with_restful_routing :messages, :member => { :mark => method }, :path_names => {:new => 'nuevo'} do -- cgit v1.2.3 From 112056333f6ad2492a37b7eb9d647ecd23980592 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sat, 14 Mar 2009 10:37:20 -0500 Subject: Add Rack version to Rails info --- actionpack/lib/action_controller/vendor/rack-1.0/rack.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb index 7fab1a7931..6c73d64612 100644 --- a/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb +++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb @@ -3,7 +3,7 @@ # Rack is freely distributable under the terms of an MIT-style license. # See COPYING or http://www.opensource.org/licenses/mit-license.php. -$:.unshift(File.expand_path(File.dirname(__FILE__))) +$: << File.expand_path(File.dirname(__FILE__)) # The Rack main module, serving as a namespace for all core Rack @@ -23,7 +23,7 @@ module Rack # Return the Rack release as a dotted string. def self.release - "0.4" + "1.0 bundled" end autoload :Builder, "rack/builder" -- cgit v1.2.3 From 7706b57034e91820cf83445aede57c54ab66ac2d Mon Sep 17 00:00:00 2001 From: misfo Date: Sat, 14 Mar 2009 10:42:02 -0500 Subject: allowed render :file to take Pathnames [#2220 state:resolved] Signed-off-by: Joshua Peek --- actionpack/lib/action_view/template.rb | 2 +- actionpack/test/controller/render_test.rb | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 0dd3a7e619..c339c8a554 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -218,7 +218,7 @@ module ActionView #:nodoc: # Returns file split into an array # [base_path, name, locale, format, extension] def split(file) - if m = file.match(/^(.*\/)?([^\.]+)\.(.*)$/) + if m = file.to_s.match(/^(.*\/)?([^\.]+)\.(.*)$/) base_path = m[1] name = m[2] extensions = m[3] diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index af623395f0..a52931565d 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -157,6 +157,11 @@ class TestController < ActionController::Base render :file => 'test/dot.directory/render_file_with_ivar' end + def render_file_using_pathname + @secret = 'in the sauce' + render :file => Pathname.new(File.dirname(__FILE__)).join('..', 'fixtures', 'test', 'dot.directory', 'render_file_with_ivar.erb') + end + def render_file_from_template @secret = 'in the sauce' @path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')) @@ -861,6 +866,11 @@ class RenderTest < ActionController::TestCase assert_equal "The secret is in the sauce\n", @response.body end + def test_render_file_using_pathname + get :render_file_using_pathname + assert_equal "The secret is in the sauce\n", @response.body + end + def test_render_file_with_locals get :render_file_with_locals assert_equal "The secret is in the sauce\n", @response.body -- cgit v1.2.3 From 73fc42cc0b5e94541480032c2941a50edd4080c2 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 15 Mar 2009 22:06:50 -0500 Subject: Prepare for final 2.3 release --- actionpack/CHANGELOG | 5 +---- actionpack/Rakefile | 2 +- actionpack/lib/action_pack/version.rb | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 90232d8c2d..8c9486cc63 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,4 +1,4 @@ -*2.3.1 [RC2] (March 5, 2009)* +*2.3.2 [Final] (March 15, 2009)* * Fixed that redirection would just log the options, not the final url (which lead to "Redirected to #") [DHH] @@ -14,9 +14,6 @@ * Added localized rescue template when I18n.locale is set (ex: public/404.da.html) #1835 [José Valim] - -*2.3.0 [RC1] (February 1st, 2009)* - * Make the form_for and fields_for helpers support the new Active Record nested update options. #1202 [Eloy Duran] <% form_for @person do |person_form| %> diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 2c0c28b755..6cacdf3c6e 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -80,7 +80,7 @@ spec = Gem::Specification.new do |s| s.has_rdoc = true s.requirements << 'none' - s.add_dependency('activesupport', '= 2.3.1' + PKG_BUILD) + s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD) s.require_path = 'lib' s.autorequire = 'action_controller' diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb index f03a2a7605..e0aa2a5f2f 100644 --- a/actionpack/lib/action_pack/version.rb +++ b/actionpack/lib/action_pack/version.rb @@ -2,7 +2,7 @@ module ActionPack #:nodoc: module VERSION #:nodoc: MAJOR = 2 MINOR = 3 - TINY = 1 + TINY = 2 STRING = [MAJOR, MINOR, TINY].join('.') end -- cgit v1.2.3 From 39ff550fa88da9a22d8c21ca872f5e4d0d83f8d4 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 15 Mar 2009 22:54:26 -0500 Subject: Ensure our bundled version of rack is at the front of the load path --- actionpack/lib/action_controller/vendor/rack-1.0/rack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb index 6c73d64612..6349b95094 100644 --- a/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb +++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb @@ -3,7 +3,7 @@ # Rack is freely distributable under the terms of an MIT-style license. # See COPYING or http://www.opensource.org/licenses/mit-license.php. -$: << File.expand_path(File.dirname(__FILE__)) +$:.unshift(File.expand_path(File.dirname(__FILE__))) # The Rack main module, serving as a namespace for all core Rack -- cgit v1.2.3 From 367049cae69ec535e7105b35f4877167adca1188 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 15 Mar 2009 23:17:31 -0500 Subject: Fix brittle Time.now mock --- .../test/controller/session/cookie_store_test.rb | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/session/cookie_store_test.rb b/actionpack/test/controller/session/cookie_store_test.rb index 9c93ca6539..c406188972 100644 --- a/actionpack/test/controller/session/cookie_store_test.rb +++ b/actionpack/test/controller/session/cookie_store_test.rb @@ -199,29 +199,17 @@ class CookieStoreTest < ActionController::IntegrationTest with_test_route_set do # First request accesses the session - time = Time.local(2008, 4, 24) - Time.stubs(:now).returns(time) - expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d-%b-%Y %H:%M:%S GMT") - cookies[SessionKey] = SignedBar get '/set_session_value' assert_response :success + cookie = headers['Set-Cookie'] - cookie_body = response.body - assert_equal "_myapp_session=#{cookie_body}; path=/; expires=#{expected_expiry}; HttpOnly", - headers['Set-Cookie'] - - # Second request does not access the session - time = Time.local(2008, 4, 25) - Time.stubs(:now).returns(time) - expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d-%b-%Y %H:%M:%S GMT") - + # Second request does not access the session so the + # expires header should not be changed get '/no_session_access' assert_response :success - - assert_equal "_myapp_session=#{cookie_body}; path=/; expires=#{expected_expiry}; HttpOnly", - headers['Set-Cookie'] + assert_equal cookie, headers['Set-Cookie'] end end -- cgit v1.2.3 From d0e5417861fad15e9e493a1843f8b54fb7a993ec Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 15 Mar 2009 23:25:12 -0500 Subject: update rack fixture to be ruby 1.9 compat --- actionpack/test/controller/integration_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index b3f40fbe95..43d2307d34 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -2,7 +2,7 @@ require 'abstract_unit' class SessionTest < Test::Unit::TestCase StubApp = lambda { |env| - [200, {"Content-Type" => "text/html", "Content-Length" => "13"}, "Hello, World!"] + [200, {"Content-Type" => "text/html", "Content-Length" => "13"}, ["Hello, World!"]] } def setup -- cgit v1.2.3 From 46c12fdcb6fb11ae62786eeafd0d1784343b3daa Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 15 Mar 2009 23:29:00 -0500 Subject: ruby 1.9 compat: Pathname doesn't support =~ --- actionpack/lib/action_view/paths.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 37d96b2f82..8cc3fe291c 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -61,7 +61,7 @@ module ActionView #:nodoc: end end - return Template.new(original_template_path, original_template_path =~ /\A\// ? "" : ".") if File.file?(original_template_path) + return Template.new(original_template_path, original_template_path.to_s =~ /\A\// ? "" : ".") if File.file?(original_template_path) raise MissingTemplate.new(self, original_template_path, format) end -- cgit v1.2.3 From 0706de4301bbf12a4c369bd4776ad58affee9ad4 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 15 Mar 2009 23:41:47 -0500 Subject: Better error message to try to figure out why the CI build is failing --- actionpack/test/controller/session/cookie_store_test.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/session/cookie_store_test.rb b/actionpack/test/controller/session/cookie_store_test.rb index c406188972..48a961ca34 100644 --- a/actionpack/test/controller/session/cookie_store_test.rb +++ b/actionpack/test/controller/session/cookie_store_test.rb @@ -209,7 +209,8 @@ class CookieStoreTest < ActionController::IntegrationTest # expires header should not be changed get '/no_session_access' assert_response :success - assert_equal cookie, headers['Set-Cookie'] + assert_equal cookie, headers['Set-Cookie'], + "#{unmarshal_session(cookie).inspect} expected but was #{unmarshal_session(headers['Set-Cookie']).inspect}" end end @@ -224,4 +225,13 @@ class CookieStoreTest < ActionController::IntegrationTest yield end end + + def unmarshal_session(cookie_string) + session = Rack::Utils.parse_query(cookie_string, ';,').inject({}) {|h,(k,v)| + h[k] = Array === v ? v.first : v + h + }[SessionKey] + verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1') + verifier.verify(session) + end end -- cgit v1.2.3 From 4185a4a5f5e53b55c9ba3757a837d33fb91f4091 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 15 Mar 2009 23:48:07 -0500 Subject: update rack fixture to be ruby 1.9 compat --- actionpack/test/controller/integration_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 43d2307d34..e39a934c24 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -389,9 +389,9 @@ class MetalTest < ActionController::IntegrationTest class Poller def self.call(env) if env["PATH_INFO"] =~ /^\/success/ - [200, {"Content-Type" => "text/plain", "Content-Length" => "12"}, "Hello World!"] + [200, {"Content-Type" => "text/plain", "Content-Length" => "12"}, ["Hello World!"]] else - [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, ''] + [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []] end end end -- cgit v1.2.3 From 18eb80ccc7e932f9a6c00462ceaeea648631b120 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Mon, 16 Mar 2009 11:28:36 +0000 Subject: Merge docrails --- actionpack/lib/action_controller/integration.rb | 2 +- actionpack/lib/action_view/helpers/date_helper.rb | 4 ++-- actionpack/lib/action_view/helpers/number_helper.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb index 1c05ab0bf6..26b695570b 100644 --- a/actionpack/lib/action_controller/integration.rb +++ b/actionpack/lib/action_controller/integration.rb @@ -5,7 +5,7 @@ require 'active_support/test_case' module ActionController module Integration #:nodoc: # An integration Session instance represents a set of requests and responses - # performed sequentially by some virtual user. Becase you can instantiate + # performed sequentially by some virtual user. Because you can instantiate # multiple sessions and run them side-by-side, you can also mimic (to some # limited extent) multiple simultaneous users interacting with your system. # diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index b7ef1fb90d..c74909a360 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -876,8 +876,8 @@ module ActionView input_name_from_type(type).gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '') end - # Given an ordering of datetime components, create the selection html - # and join them with their appropriate seperators + # Given an ordering of datetime components, create the selection HTML + # and join them with their appropriate separators. def build_selects_from_types(order) select = '' order.reverse.each do |type| diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index 539f43c6e3..dea958deaf 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -140,7 +140,7 @@ module ActionView # number_with_delimiter(12345678) # => 12,345,678 # number_with_delimiter(12345678.05) # => 12,345,678.05 # number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678 - # number_with_delimiter(12345678, :seperator => ",") # => 12,345,678 + # number_with_delimiter(12345678, :separator => ",") # => 12,345,678 # number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",") # # => 98 765 432,98 # -- cgit v1.2.3 From 70e3dfb2e9f94396eb6525d13f9adccd3e845c3d Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 16 Mar 2009 12:09:34 -0700 Subject: Pare down unit test --- actionpack/test/template/body_parts_test.rb | 42 +++++------------------------ 1 file changed, 6 insertions(+), 36 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb index 369756cbf5..209f6ec1ff 100644 --- a/actionpack/test/template/body_parts_test.rb +++ b/actionpack/test/template/body_parts_test.rb @@ -1,57 +1,27 @@ require 'abstract_unit' require 'action_view/body_parts/concurrent_block' -class BodyPartTest < ActionController::TestCase - module EdgeSideInclude - QUEUE_REDEMPTION_URL = 'http://render.farm/renderings/%s' - ESI_INCLUDE_TAG = '' - - def self.redemption_tag(receipt) - ESI_INCLUDE_TAG % QUEUE_REDEMPTION_URL % receipt - end - - class BodyPart - def initialize(rendering) - @receipt = enqueue(rendering) - end - - def to_s - EdgeSideInclude.redemption_tag(@receipt) - end - - protected - # Pretend we sent this rendering off for processing. - def enqueue(rendering) - rendering.object_id.to_s - end - end - end +class BodyPartsTest < ActionController::TestCase + RENDERINGS = [Object.new, Object.new, Object.new] class TestController < ActionController::Base - RENDERINGS = [Object.new, Object.new, Object.new] - def index RENDERINGS.each do |rendering| - edge_side_include rendering + response.template.punctuate_body! rendering end @performed_render = true end - - def edge_side_include(rendering) - response.template.punctuate_body! EdgeSideInclude::BodyPart.new(rendering) - end end tests TestController - def test_queued_parts + def test_body_parts get :index - expected = TestController::RENDERINGS.map { |rendering| EdgeSideInclude.redemption_tag(rendering.object_id) }.join - assert_equal expected, @response.body + assert_equal RENDERINGS, @response.body_parts + assert_equal RENDERINGS.join, @response.body end end - class ConcurrentBlockPartTest < ActionController::TestCase class TestController < ActionController::Base def index -- cgit v1.2.3 From d36df5e7a8a2791bb890afa0c11b8f3985293c21 Mon Sep 17 00:00:00 2001 From: Clemens Kofler Date: Tue, 17 Mar 2009 14:46:19 +0100 Subject: Hidden field with check box goes first. --- actionpack/lib/action_view/helpers/form_helper.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index a589bcba2a..93b8ae687f 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -657,17 +657,17 @@ module ActionView # ==== Examples # # Let's say that @post.validated? is 1: # check_box("post", "validated") - # # => - # # + # # => + # # # # # Let's say that @puppy.gooddog is "no": # check_box("puppy", "gooddog", {}, "yes", "no") - # # => - # # + # # => + # # # # check_box("eula", "accepted", { :class => 'eula_check' }, "yes", "no") - # # => - # # + # # => + # # # def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") InstanceTag.new(object_name, method, self, options.delete(:object)).to_check_box_tag(options, checked_value, unchecked_value) -- cgit v1.2.3 From a8bf6fa30882cdbb2c84b1840f3bd3f10894af3d Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 17 Mar 2009 18:50:50 +0100 Subject: update explanation of check box generation according to f400209 --- actionpack/lib/action_view/helpers/form_helper.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 93b8ae687f..4e1927a897 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -628,7 +628,7 @@ module ActionView # # The HTML specification says unchecked check boxes are not successful, and # thus web browsers do not send them. Unfortunately this introduces a gotcha: - # if an Invoice model has a +paid+ flag, and in the form that edits a paid + # if an +Invoice+ model has a +paid+ flag, and in the form that edits a paid # invoice the user unchecks its check box, no +paid+ parameter is sent. So, # any mass-assignment idiom like # @@ -636,12 +636,15 @@ module ActionView # # wouldn't update the flag. # - # To prevent this the helper generates a hidden field with the same name as - # the checkbox after the very check box. So, the client either sends only the - # hidden field (representing the check box is unchecked), or both fields. - # Since the HTML specification says key/value pairs have to be sent in the - # same order they appear in the form and Rails parameters extraction always - # gets the first occurrence of any given key, that works in ordinary forms. + # To prevent this the helper generates an auxiliary hidden field before + # the very check box. The hidden field has the same name and its + # attributes mimick an unchecked check box. + # + # This way, the client either sends only the hidden field (representing + # the check box is unchecked), or both fields. Since the HTML specification + # says key/value pairs have to be sent in the same order they appear in the + # form, and parameters extraction gets the last occurrence of any repeated + # key in the query string, that works for ordinary forms. # # Unfortunately that workaround does not work when the check box goes # within an array-like parameter, as in -- cgit v1.2.3 From 168e3958df38b7f6738d60f2510a2e6d1ebcc9fb Mon Sep 17 00:00:00 2001 From: Giles Bowkett Date: Tue, 17 Mar 2009 12:41:15 -0700 Subject: this page referred to an :href_options keyword hash, in fact the correct keyword (the one the code responds to) is :html --- actionpack/lib/action_view/helpers/text_helper.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 48bf4717ad..573b99b96e 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -324,7 +324,7 @@ module ActionView # Turns all URLs and e-mail addresses into clickable links. The :link option # will limit what should be linked. You can add HTML attributes to the links using - # :href_options. Possible values for :link are :all (default), + # :html. Possible values for :link are :all (default), # :email_addresses, and :urls. If a block is given, each URL and # e-mail address is yielded and the result is used as the link text. # @@ -341,7 +341,7 @@ module ActionView # # => "Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com" # # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com." - # auto_link(post_body, :href_options => { :target => '_blank' }) do |text| + # auto_link(post_body, :html => { :target => '_blank' }) do |text| # truncate(text, 15) # end # # => "Welcome to my new blog at http://www.m.... @@ -359,7 +359,7 @@ module ActionView # auto_link(post_body, :all, :target => "_blank") # => Once upon\na time # # => "Welcome to my new blog at http://www.myblog.com. # Please e-mail me at me@email.com." - def auto_link(text, *args, &block)#link = :all, href_options = {}, &block) + def auto_link(text, *args, &block)#link = :all, html = {}, &block) return '' if text.blank? options = args.size == 2 ? {} : args.extract_options! # this is necessary because the old auto_link API has a Hash as its last parameter -- cgit v1.2.3 From e8501a15a84f4c0d894273b0decedf64cce66c76 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 17 Mar 2009 21:01:50 +0100 Subject: clarifies a bit more what's the issue with check boxes and arrays of parameters --- actionpack/lib/action_view/helpers/form_helper.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 4e1927a897..a59829b23f 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -655,7 +655,11 @@ module ActionView # <% end %> # # because parameter name repetition is precisely what Rails seeks to distinguish - # the elements of the array. + # the elements of the array. For each item with a checked check box you + # get an extra ghost item with only that attribute, assigned to "0". + # + # In that case it is preferable to either use +check_box_tag+ or to use + # hashes instead of arrays. # # ==== Examples # # Let's say that @post.validated? is 1: -- cgit v1.2.3 From 0d5b50ee3a6d65471f311980b9b6e49fe4b4a021 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 19 Mar 2009 03:30:01 -0700 Subject: pluginize concurrent block body part --- actionpack/lib/action_view/base.rb | 4 +- .../lib/action_view/body_parts/concurrent_block.rb | 25 ------- actionpack/test/template/body_parts_test.rb | 80 ---------------------- 3 files changed, 2 insertions(+), 107 deletions(-) delete mode 100644 actionpack/lib/action_view/body_parts/concurrent_block.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 3bbd2ca530..9c0134e7f7 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -288,12 +288,12 @@ module ActionView #:nodoc: # Access the current template being rendered. # Returns a ActionView::Template object. def template - Thread.current[:_current_render] + @_current_render end def template=(template) #:nodoc: @_first_render ||= template - Thread.current[:_current_render] = template + @_current_render = template end def with_template(current_template) diff --git a/actionpack/lib/action_view/body_parts/concurrent_block.rb b/actionpack/lib/action_view/body_parts/concurrent_block.rb deleted file mode 100644 index 28a3a3bf4d..0000000000 --- a/actionpack/lib/action_view/body_parts/concurrent_block.rb +++ /dev/null @@ -1,25 +0,0 @@ -module ActionView - module BodyParts - class ConcurrentBlock - def initialize(&block) - @block = block - @body = [] - start - end - - def to_s - finish - @body.join - end - - protected - def start - @worker = Thread.new { @block.call(@body) } - end - - def finish - @worker.join if @worker && @worker.alive? - end - end - end -end diff --git a/actionpack/test/template/body_parts_test.rb b/actionpack/test/template/body_parts_test.rb index 209f6ec1ff..4c82b75cdc 100644 --- a/actionpack/test/template/body_parts_test.rb +++ b/actionpack/test/template/body_parts_test.rb @@ -1,5 +1,4 @@ require 'abstract_unit' -require 'action_view/body_parts/concurrent_block' class BodyPartsTest < ActionController::TestCase RENDERINGS = [Object.new, Object.new, Object.new] @@ -21,82 +20,3 @@ class BodyPartsTest < ActionController::TestCase assert_equal RENDERINGS.join, @response.body end end - -class ConcurrentBlockPartTest < ActionController::TestCase - class TestController < ActionController::Base - def index - append_thread_id = lambda do |parts| - parts << Thread.current.object_id - parts << '::' - parts << Time.now.to_i - sleep 0.1 - end - - future_render &append_thread_id - response.body_parts << '-' - - future_render &append_thread_id - response.body_parts << '-' - - future_render do |parts| - parts << ActionView::BodyParts::ConcurrentBlock.new(&append_thread_id) - parts << '-' - parts << ActionView::BodyParts::ConcurrentBlock.new(&append_thread_id) - end - - @performed_render = true - end - - def future_render(&block) - response.template.punctuate_body! ActionView::BodyParts::ConcurrentBlock.new(&block) - end - end - - tests TestController - - def test_concurrent_threaded_parts - get :index - - elapsed = Benchmark.ms do - thread_ids = @response.body.split('-').map { |part| part.split('::').first.to_i } - assert_equal thread_ids.size, thread_ids.uniq.size - end - assert (elapsed - 100).abs < 10, elapsed - end -end - - -class OpenUriPartTest < ActionController::TestCase - class OpenUriPart < ActionView::BodyParts::ConcurrentBlock - def initialize(url) - url = URI::Generic === url ? url : URI.parse(url) - super() { |body| body << url.read } - end - end - - class TestController < ActionController::Base - def index - render_url 'http://localhost/foo' - render_url 'http://localhost/bar' - render_url 'http://localhost/baz' - @performed_render = true - end - - def render_url(url) - url = URI.parse(url) - def url.read; sleep 0.1; path end - response.template.punctuate_body! OpenUriPart.new(url) - end - end - - tests TestController - - def test_concurrent_open_uri_parts - get :index - - elapsed = Benchmark.ms do - assert_equal '/foo/bar/baz', @response.body - end - assert (elapsed - 100).abs < 10, elapsed - end -end -- cgit v1.2.3