From ecc054352512cac8c0895c78c5f3d043046dcfec Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 15 Jul 2008 18:42:22 -0700 Subject: JavaScriptGenerator should only sets output_buffer for the duration of the update block --- actionpack/lib/action_view/helpers/capture_helper.rb | 17 +++++++++-------- actionpack/lib/action_view/helpers/prototype_helper.rb | 5 +++-- actionpack/test/template/javascript_helper_test.rb | 6 +++++- actionpack/test/template/prototype_helper_test.rb | 6 +++++- 4 files changed, 22 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 720e2da8cc..e86ca27f31 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -122,14 +122,15 @@ module ActionView nil end - private - def with_output_buffer(buf = '') - self.output_buffer, old_buffer = buf, output_buffer - yield - output_buffer - ensure - self.output_buffer = old_buffer - end + # Use an alternate output buffer for the duration of the block. + # Defaults to a new empty string. + def with_output_buffer(buf = '') #:nodoc: + self.output_buffer, old_buffer = buf, output_buffer + yield + output_buffer + ensure + self.output_buffer = old_buffer + end end end end diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index edb43844a4..8c8c22dd4a 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -580,9 +580,10 @@ module ActionView class JavaScriptGenerator #:nodoc: def initialize(context, &block) #:nodoc: @context, @lines = context, [] - @context.output_buffer = @lines if @context include_helpers_from_context - @context.instance_exec(self, &block) + @context.with_output_buffer(@lines) do + @context.instance_exec(self, &block) + end end private diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 36dfeba5ed..d41111127b 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -3,7 +3,11 @@ require 'abstract_unit' class JavaScriptHelperTest < ActionView::TestCase tests ActionView::Helpers::JavaScriptHelper - attr_accessor :output_buffer + attr_accessor :template_format, :output_buffer + + def setup + @template = self + end def test_escape_javascript assert_equal '', escape_javascript(nil) diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 5528430d80..92cc85703b 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -28,7 +28,7 @@ class PrototypeHelperBaseTest < ActionView::TestCase attr_accessor :template_format, :output_buffer def setup - @template = nil + @template = self @controller = Class.new do def url_for(options) if options.is_a?(String) @@ -243,8 +243,12 @@ class PrototypeHelperTest < PrototypeHelperBaseTest end def test_update_page + old_output_buffer = output_buffer + block = Proc.new { |page| page.replace_html('foo', 'bar') } assert_equal create_generator(&block).to_s, update_page(&block) + + assert_equal old_output_buffer, output_buffer end def test_update_page_tag -- cgit v1.2.3 From 8b306bf24c53f698cd83f7d616f2478a6efa5797 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 15 Jul 2008 20:52:29 -0500 Subject: Improved test coverage for fragment cache helper --- actionpack/test/controller/caching_test.rb | 62 +++++++++++++++++----- .../formatted_fragment_cached.html.erb | 3 ++ .../formatted_fragment_cached.js.rjs | 6 +++ .../formatted_fragment_cached.xml.builder | 5 ++ 4 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb create mode 100644 actionpack/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs create mode 100644 actionpack/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder (limited to 'actionpack') diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 8f53ecd178..47a0fcf99d 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -148,7 +148,6 @@ class PageCachingTest < Test::Unit::TestCase end end - class ActionCachingTestController < ActionController::Base caches_action :index, :redirected, :forbidden, :if => Proc.new { |c| !c.request.format.json? }, :expires_in => 1.hour caches_action :show, :cache_path => 'http://test.host/custom/show' @@ -489,54 +488,54 @@ class FragmentCachingTest < Test::Unit::TestCase def test_fragment_cache_key assert_equal 'views/what a key', @controller.fragment_cache_key('what a key') - assert_equal( "views/test.host/fragment_caching_test/some_action", - @controller.fragment_cache_key(:controller => 'fragment_caching_test',:action => 'some_action')) + assert_equal "views/test.host/fragment_caching_test/some_action", + @controller.fragment_cache_key(:controller => 'fragment_caching_test',:action => 'some_action') end - def test_read_fragment__with_caching_enabled + def test_read_fragment_with_caching_enabled @store.write('views/name', 'value') assert_equal 'value', @controller.read_fragment('name') end - def test_read_fragment__with_caching_disabled + def test_read_fragment_with_caching_disabled ActionController::Base.perform_caching = false @store.write('views/name', 'value') assert_nil @controller.read_fragment('name') end - def test_fragment_exist__with_caching_enabled + def test_fragment_exist_with_caching_enabled @store.write('views/name', 'value') assert @controller.fragment_exist?('name') assert !@controller.fragment_exist?('other_name') end - def test_fragment_exist__with_caching_disabled + def test_fragment_exist_with_caching_disabled ActionController::Base.perform_caching = false @store.write('views/name', 'value') assert !@controller.fragment_exist?('name') assert !@controller.fragment_exist?('other_name') end - def test_write_fragment__with_caching_enabled + def test_write_fragment_with_caching_enabled assert_nil @store.read('views/name') assert_equal 'value', @controller.write_fragment('name', 'value') assert_equal 'value', @store.read('views/name') end - def test_write_fragment__with_caching_disabled + def test_write_fragment_with_caching_disabled assert_nil @store.read('views/name') ActionController::Base.perform_caching = false assert_equal nil, @controller.write_fragment('name', 'value') assert_nil @store.read('views/name') end - def test_expire_fragment__with_simple_key + def test_expire_fragment_with_simple_key @store.write('views/name', 'value') @controller.expire_fragment 'name' assert_nil @store.read('views/name') end - def test_expire_fragment__with__regexp + def test_expire_fragment_with_regexp @store.write('views/name', 'value') @store.write('views/another_name', 'another_value') @store.write('views/primalgrasp', 'will not expire ;-)') @@ -548,7 +547,7 @@ class FragmentCachingTest < Test::Unit::TestCase assert_equal 'will not expire ;-)', @store.read('views/primalgrasp') end - def test_fragment_for__with_disabled_caching + def test_fragment_for_with_disabled_caching ActionController::Base.perform_caching = false @store.write('views/expensive', 'fragment content') @@ -573,7 +572,6 @@ class FragmentCachingTest < Test::Unit::TestCase end end - class FunctionalCachingController < ActionController::Base def fragment_cached end @@ -590,6 +588,13 @@ class FunctionalCachingController < ActionController::Base end end + def formatted_fragment_cached + respond_to do |format| + format.html + format.xml + format.js + end + end def rescue_action(e) raise e @@ -639,4 +644,35 @@ CACHED assert_match /Fragment caching in a partial/, @response.body assert_match "Fragment caching in a partial", @store.read('views/test.host/functional_caching/js_fragment_cached_with_partial') end + + def test_html_formatted_fragment_caching + get :formatted_fragment_cached, :format => "html" + assert_response :success + expected_body = "\n

ERB

\n" + + assert_equal expected_body, @response.body + + assert_equal "

ERB

", @store.read('views/test.host/functional_caching/formatted_fragment_cached') + end + + def test_xml_formatted_fragment_caching + get :formatted_fragment_cached, :format => "xml" + assert_response :success + expected_body = "\n

Builder

\n\n" + + assert_equal expected_body, @response.body + + assert_equal "

Builder

\n", @store.read('views/test.host/functional_caching/formatted_fragment_cached') + end + + def test_js_formatted_fragment_caching + get :formatted_fragment_cached, :format => "js" + assert_response :success + expected_body = %(title = "Hey";\n$("element_1").visualEffect("highlight");\n) + + %($("element_2").visualEffect("highlight");\nfooter = "Bye";) + assert_equal expected_body, @response.body + + assert_equal ['$("element_1").visualEffect("highlight");', '$("element_2").visualEffect("highlight");'], + @store.read('views/test.host/functional_caching/formatted_fragment_cached') + end end diff --git a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb new file mode 100644 index 0000000000..d7f43ad95e --- /dev/null +++ b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.html.erb @@ -0,0 +1,3 @@ + +<% cache do %>

ERB

<% end %> + \ No newline at end of file diff --git a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs new file mode 100644 index 0000000000..057f15e62f --- /dev/null +++ b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs @@ -0,0 +1,6 @@ +page.assign 'title', 'Hey' +cache do + page['element_1'].visual_effect :highlight + page['element_2'].visual_effect :highlight +end +page.assign 'footer', 'Bye' diff --git a/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder new file mode 100644 index 0000000000..efdcc28e0f --- /dev/null +++ b/actionpack/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder @@ -0,0 +1,5 @@ +xml.body do + cache do + xml.p "Builder" + end +end -- cgit v1.2.3 From 0f8206104e5dfca1024d1f6bc12a8783c00527e2 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 16 Jul 2008 03:18:09 +0100 Subject: RackRequest#content_type should return Mime::Type --- actionpack/lib/action_controller/rack_process.rb | 2 +- actionpack/test/controller/rack_test.rb | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index 01bc1ebb26..dfa2b8d0bd 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -24,7 +24,7 @@ module ActionController #:nodoc: super() end - %w[ AUTH_TYPE CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO + %w[ AUTH_TYPE GATEWAY_INTERFACE PATH_INFO PATH_TRANSLATED QUERY_STRING REMOTE_HOST REMOTE_IDENT REMOTE_USER SCRIPT_NAME SERVER_NAME SERVER_PROTOCOL diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 486fe49737..67ccf1b127 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -166,6 +166,18 @@ class RackRequestParamsParsingTest < BaseRackTest end end +class RackRequestContentTypeTest < BaseRackTest + def test_html_content_type_verification + @request.env['CONTENT_TYPE'] = Mime::HTML.to_s + assert @request.content_type.verify_request? + end + + def test_xml_content_type_verification + @request.env['CONTENT_TYPE'] = Mime::XML.to_s + assert !@request.content_type.verify_request? + end +end + class RackRequestNeedsRewoundTest < BaseRackTest def test_body_should_be_rewound data = 'foo' -- cgit v1.2.3 From 89eec91e670ae267cd88b2b3555bfefe527f0eaa Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 16 Jul 2008 03:31:45 +0100 Subject: Add tests for CgiRequest#content_type --- actionpack/test/controller/cgi_test.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'actionpack') diff --git a/actionpack/test/controller/cgi_test.rb b/actionpack/test/controller/cgi_test.rb index bf3b8b788e..7367036dec 100755 --- a/actionpack/test/controller/cgi_test.rb +++ b/actionpack/test/controller/cgi_test.rb @@ -168,6 +168,18 @@ class CgiRequestParamsParsingTest < BaseCgiTest end end +class CgiRequestContentTypeTest < BaseCgiTest + def test_html_content_type_verification + @request.env['CONTENT_TYPE'] = Mime::HTML.to_s + assert @request.content_type.verify_request? + end + + def test_xml_content_type_verification + @request.env['CONTENT_TYPE'] = Mime::XML.to_s + assert !@request.content_type.verify_request? + end +end + class CgiRequestNeedsRewoundTest < BaseCgiTest def test_body_should_be_rewound data = 'foo' -- cgit v1.2.3 From 3343eb428c502006c40368231a154d8f82be97eb Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 16 Jul 2008 04:09:01 +0100 Subject: Tests for rack response content type --- actionpack/test/controller/rack_test.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'actionpack') diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 67ccf1b127..0636a85013 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -246,3 +246,24 @@ class RackResponseTest < BaseRackTest assert_equal ["Hello, World!"], parts end end + +class RackResponseHeadersTest < BaseRackTest + def setup + super + @response = ActionController::RackResponse.new(@request) + @output = StringIO.new('') + @headers = proc { @response.out(@output)[1] } + end + + def test_content_type + [204, 304].each do |c| + @response.headers['Status'] = c + assert !@headers.call.has_key?("Content-Type") + end + + [200, 302, 404, 500].each do |c| + @response.headers['Status'] = c + assert @headers.call.has_key?("Content-Type") + end + end +end -- cgit v1.2.3 From 5cc3ea6969f047a782fa8ac44530baeef597edb3 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 16 Jul 2008 04:17:28 +0100 Subject: RackResponse should not contain Status header --- actionpack/lib/action_controller/rack_process.rb | 2 +- actionpack/test/controller/rack_test.rb | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index dfa2b8d0bd..614913fcd9 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -250,7 +250,7 @@ end_msg headers['Content-Language'] = options.delete('language') if options['language'] headers['Expires'] = options.delete('expires') if options['expires'] - @status = options['Status'] || "200 OK" + @status = options.delete('Status') || "200 OK" # Convert 'cookie' header to 'Set-Cookie' headers. # Because Set-Cookie header can appear more the once in the response body, diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 0636a85013..1cef1e0f58 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -252,18 +252,28 @@ class RackResponseHeadersTest < BaseRackTest super @response = ActionController::RackResponse.new(@request) @output = StringIO.new('') - @headers = proc { @response.out(@output)[1] } + @response.headers['Status'] = 200 end def test_content_type [204, 304].each do |c| @response.headers['Status'] = c - assert !@headers.call.has_key?("Content-Type") + assert !response_headers.has_key?("Content-Type") end [200, 302, 404, 500].each do |c| @response.headers['Status'] = c - assert @headers.call.has_key?("Content-Type") + assert response_headers.has_key?("Content-Type") end end + + def test_status + assert !response_headers.has_key?('Status') + end + + private + + def response_headers + @response.out(@output)[1] + end end -- cgit v1.2.3 From 83e29b9773ac113ceacb1e36c2f333d692de2573 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 15 Jul 2008 22:51:16 -0500 Subject: Removed config.action_view.cache_template_loading, use config.cache_classes instead --- actionpack/CHANGELOG | 2 ++ actionpack/lib/action_view/base.rb | 7 ++++--- actionpack/lib/action_view/paths.rb | 16 ++++++++++++---- actionpack/lib/action_view/renderable.rb | 2 +- actionpack/test/abstract_unit.rb | 1 - 5 files changed, 19 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 52d00a417c..cec593a6a0 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Removed config.action_view.cache_template_loading, use config.cache_classes instead [Josh Peek] + * Get buffer for fragment cache from template's @output_buffer [Josh Peek] * Set config.action_view.warn_cache_misses = true to receive a warning if you perform an action that results in an expensive disk operation that could be cached [Josh Peek] diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 04e8d3a358..0ea96f045e 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -171,9 +171,10 @@ module ActionView #:nodoc: delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB' end - # Specify whether templates should be cached. Otherwise the file we be read everytime it is accessed. - @@cache_template_loading = false - cattr_accessor :cache_template_loading + def self.cache_template_loading=(*args) + ActiveSupport::Deprecation.warn("config.action_view.cache_template_loading option has been deprecated and has no affect. " << + "Please remove it from your config files.", caller) + end def self.cache_template_extensions=(*args) ActiveSupport::Deprecation.warn("config.action_view.cache_template_extensions option has been deprecated and has no affect. " << diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index b0ab7d0c67..c7a5df762f 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -16,6 +16,14 @@ module ActionView #:nodoc: end class Path #:nodoc: + def self.eager_load_templates! + @eager_load_templates = true + end + + def self.eager_load_templates? + @eager_load_templates || false + end + attr_reader :path, :paths delegate :to_s, :to_str, :inspect, :to => :path @@ -37,6 +45,9 @@ module ActionView #:nodoc: @paths = {} templates_in_path do |template| + # Eager load memoized methods and freeze cached template + template.freeze if self.class.eager_load_templates? + @paths[template.path] = template @paths[template.path_without_extension] ||= template end @@ -48,10 +59,7 @@ module ActionView #:nodoc: def templates_in_path (Dir.glob("#{@path}/**/*/**") | Dir.glob("#{@path}/**")).each do |file| unless File.directory?(file) - template = Template.new(file.split("#{self}/").last, self) - # Eager load memoized methods and freeze cached template - template.freeze if Base.cache_template_loading - yield template + yield Template.new(file.split("#{self}/").last, self) end end end diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index f66356c939..badb2b171c 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -72,7 +72,7 @@ module ActionView # if local_assigns has a new key, which isn't supported by the compiled code yet. def recompile?(symbol) meth = Base::CompiledTemplates.instance_method(template.method) rescue nil - !(meth && Base.cache_template_loading) + !(meth && frozen?) end end end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 0d2e0f273a..520379fe82 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -22,7 +22,6 @@ ActiveSupport::Deprecation.debug = true ActionController::Base.logger = nil ActionController::Routing::Routes.reload rescue nil -ActionView::Base.cache_template_loading = true FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures') ActionController::Base.view_paths = FIXTURE_LOAD_PATH -- cgit v1.2.3 From 1d002f6bcbd4e4f5cc421ee4da5be18839ccc4cb Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 16 Jul 2008 05:01:29 +0100 Subject: Make RackRequest#request_method respect _method --- actionpack/lib/action_controller/rack_process.rb | 4 --- actionpack/test/controller/cgi_test.rb | 33 ++++++++++++++++++++++++ actionpack/test/controller/rack_test.rb | 33 ++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index 614913fcd9..ef329b759a 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -98,10 +98,6 @@ module ActionController #:nodoc: @env['REMOTE_ADDR'] end - def request_method - @env['REQUEST_METHOD'].downcase.to_sym - end - def server_port @env['SERVER_PORT'].to_i end diff --git a/actionpack/test/controller/cgi_test.rb b/actionpack/test/controller/cgi_test.rb index 7367036dec..9120458d24 100755 --- a/actionpack/test/controller/cgi_test.rb +++ b/actionpack/test/controller/cgi_test.rb @@ -53,6 +53,14 @@ class BaseCgiTest < Test::Unit::TestCase end def default_test; end + + private + + def set_content_data(data) + @request.env['CONTENT_LENGTH'] = data.length + @request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8' + @request.env['RAW_POST_DATA'] = data + end end class CgiRequestTest < BaseCgiTest @@ -180,6 +188,31 @@ class CgiRequestContentTypeTest < BaseCgiTest end end +class CgiRequestMethodTest < BaseCgiTest + def test_get + assert_equal :get, @request.request_method + end + + def test_post + @request.env['REQUEST_METHOD'] = 'POST' + assert_equal :post, @request.request_method + end + + def test_put + @request.env['REQUEST_METHOD'] = 'POST' + set_content_data '_method=put' + + assert_equal :put, @request.request_method + end + + def test_delete + @request.env['REQUEST_METHOD'] = 'POST' + set_content_data '_method=delete' + + assert_equal :delete, @request.request_method + end +end + class CgiRequestNeedsRewoundTest < BaseCgiTest def test_body_should_be_rewound data = 'foo' diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 1cef1e0f58..99edb2c901 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -51,6 +51,14 @@ class BaseRackTest < Test::Unit::TestCase end def default_test; end + + private + + def set_content_data(data) + @request.env['CONTENT_LENGTH'] = data.length + @request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8' + @request.env['RAW_POST_DATA'] = data + end end class RackRequestTest < BaseRackTest @@ -178,6 +186,31 @@ class RackRequestContentTypeTest < BaseRackTest end end +class RackRequestMethodTest < BaseRackTest + def test_get + assert_equal :get, @request.request_method + end + + def test_post + @request.env['REQUEST_METHOD'] = 'POST' + assert_equal :post, @request.request_method + end + + def test_put + @request.env['REQUEST_METHOD'] = 'POST' + set_content_data '_method=put' + + assert_equal :put, @request.request_method + end + + def test_delete + @request.env['REQUEST_METHOD'] = 'POST' + set_content_data '_method=delete' + + assert_equal :delete, @request.request_method + end +end + class RackRequestNeedsRewoundTest < BaseRackTest def test_body_should_be_rewound data = 'foo' -- cgit v1.2.3 From 2a7aca8ec34ebfe0e30dd5e8696918b083ef56f5 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 16 Jul 2008 05:07:34 +0100 Subject: Improve rack/cgi tests --- actionpack/test/controller/cgi_test.rb | 9 +++------ actionpack/test/controller/rack_test.rb | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/cgi_test.rb b/actionpack/test/controller/cgi_test.rb index 9120458d24..8ca70f8595 100755 --- a/actionpack/test/controller/cgi_test.rb +++ b/actionpack/test/controller/cgi_test.rb @@ -57,6 +57,7 @@ class BaseCgiTest < Test::Unit::TestCase private def set_content_data(data) + @request.env['REQUEST_METHOD'] = 'POST' @request.env['CONTENT_LENGTH'] = data.length @request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8' @request.env['RAW_POST_DATA'] = data @@ -163,10 +164,8 @@ end class CgiRequestParamsParsingTest < BaseCgiTest def test_doesnt_break_when_content_type_has_charset - data = 'flamenco=love' - @request.env['CONTENT_LENGTH'] = data.length - @request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8' - @request.env['RAW_POST_DATA'] = data + set_content_data 'flamenco=love' + assert_equal({"flamenco"=> "love"}, @request.request_parameters) end @@ -199,14 +198,12 @@ class CgiRequestMethodTest < BaseCgiTest end def test_put - @request.env['REQUEST_METHOD'] = 'POST' set_content_data '_method=put' assert_equal :put, @request.request_method end def test_delete - @request.env['REQUEST_METHOD'] = 'POST' set_content_data '_method=delete' assert_equal :delete, @request.request_method diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 99edb2c901..ab8bbc3bf9 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -55,6 +55,7 @@ class BaseRackTest < Test::Unit::TestCase private def set_content_data(data) + @request.env['REQUEST_METHOD'] = 'POST' @request.env['CONTENT_LENGTH'] = data.length @request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8' @request.env['RAW_POST_DATA'] = data @@ -161,10 +162,8 @@ end class RackRequestParamsParsingTest < BaseRackTest def test_doesnt_break_when_content_type_has_charset - data = 'flamenco=love' - @request.env['CONTENT_LENGTH'] = data.length - @request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8' - @request.env['RAW_POST_DATA'] = data + set_content_data 'flamenco=love' + assert_equal({"flamenco"=> "love"}, @request.request_parameters) end @@ -197,14 +196,12 @@ class RackRequestMethodTest < BaseRackTest end def test_put - @request.env['REQUEST_METHOD'] = 'POST' set_content_data '_method=put' assert_equal :put, @request.request_method end def test_delete - @request.env['REQUEST_METHOD'] = 'POST' set_content_data '_method=delete' assert_equal :delete, @request.request_method -- cgit v1.2.3 From 0432d151647f2178ddee79979827d552447c251f Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 16 Jul 2008 13:00:36 +0100 Subject: Merge with docrails. --- actionpack/README | 18 ++++------- .../assertions/selector_assertions.rb | 6 ++-- .../lib/action_controller/caching/fragments.rb | 2 +- actionpack/lib/action_controller/cookies.rb | 10 +++++++ actionpack/lib/action_controller/integration.rb | 2 +- actionpack/lib/action_controller/rack_process.rb | 2 +- actionpack/lib/action_controller/request.rb | 6 ++-- .../request_forgery_protection.rb | 2 +- actionpack/lib/action_controller/resources.rb | 4 +++ actionpack/lib/action_controller/streaming.rb | 23 +++++++++----- actionpack/lib/action_controller/test_case.rb | 23 ++++++++++++++ actionpack/lib/action_controller/test_process.rb | 2 +- .../vendor/html-scanner/html/selector.rb | 4 +-- actionpack/lib/action_view/base.rb | 2 +- .../action_view/helpers/active_record_helper.rb | 2 +- actionpack/lib/action_view/helpers/date_helper.rb | 4 +-- actionpack/lib/action_view/helpers/debug_helper.rb | 33 ++++++++++++-------- actionpack/lib/action_view/helpers/form_helper.rb | 35 ++++++++++++++++++++-- .../lib/action_view/helpers/form_options_helper.rb | 8 +++-- .../lib/action_view/helpers/javascript_helper.rb | 21 +++++++++++-- .../lib/action_view/helpers/prototype_helper.rb | 2 +- .../lib/action_view/helpers/sanitize_helper.rb | 2 +- .../action_view/helpers/scriptaculous_helper.rb | 2 +- actionpack/lib/action_view/helpers/tag_helper.rb | 2 +- actionpack/lib/action_view/helpers/url_helper.rb | 2 +- 25 files changed, 155 insertions(+), 64 deletions(-) (limited to 'actionpack') diff --git a/actionpack/README b/actionpack/README index 2746c3cc43..6090089bb9 100644 --- a/actionpack/README +++ b/actionpack/README @@ -31,7 +31,7 @@ http://www.rubyonrails.org. A short rundown of the major features: * Actions grouped in controller as methods instead of separate command objects - and can therefore share helper methods. + and can therefore share helper methods BlogController < ActionController::Base def show @@ -168,7 +168,7 @@ A short rundown of the major features: {Learn more}[link:classes/ActionController/Base.html] -* Javascript and Ajax integration. +* Javascript and Ajax integration link_to_function "Greeting", "alert('Hello world!')" link_to_remote "Delete this post", :update => "posts", @@ -177,7 +177,7 @@ A short rundown of the major features: {Learn more}[link:classes/ActionView/Helpers/JavaScriptHelper.html] -* Pagination for navigating lists of results. +* Pagination for navigating lists of results # controller def list @@ -192,15 +192,9 @@ A short rundown of the major features: {Learn more}[link:classes/ActionController/Pagination.html] -* Easy testing of both controller and template result through TestRequest/Response - - class LoginControllerTest < Test::Unit::TestCase - def setup - @controller = LoginController.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - end +* Easy testing of both controller and rendered template through ActionController::TestCase + class LoginControllerTest < ActionController::TestCase def test_failing_authenticate process :authenticate, :user_name => "nop", :password => "" assert flash.has_key?(:alert) @@ -208,7 +202,7 @@ A short rundown of the major features: end end - {Learn more}[link:classes/ActionController/TestRequest.html] + {Learn more}[link:classes/ActionController/TestCase.html] * Automated benchmarking and integrated logging diff --git a/actionpack/lib/action_controller/assertions/selector_assertions.rb b/actionpack/lib/action_controller/assertions/selector_assertions.rb index d3594e711c..70b0ed53e7 100644 --- a/actionpack/lib/action_controller/assertions/selector_assertions.rb +++ b/actionpack/lib/action_controller/assertions/selector_assertions.rb @@ -21,10 +21,8 @@ module ActionController # from the response HTML or elements selected by the enclosing assertion. # # In addition to HTML responses, you can make the following assertions: - # * +assert_select_rjs+ - Assertions on HTML content of RJS update and - # insertion operations. - # * +assert_select_encoded+ - Assertions on HTML encoded inside XML, - # for example for dealing with feed item descriptions. + # * +assert_select_rjs+ - Assertions on HTML content of RJS update and insertion operations. + # * +assert_select_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions. # * +assert_select_email+ - Assertions on the HTML body of an e-mail. # # Also see HTML::Selector to learn how to use selectors. diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb index b1f25fdf5c..e9b434dd25 100644 --- a/actionpack/lib/action_controller/caching/fragments.rb +++ b/actionpack/lib/action_controller/caching/fragments.rb @@ -2,7 +2,7 @@ module ActionController #:nodoc: module Caching # Fragment caching is used for caching various blocks within templates without caching the entire action as a whole. This is useful when # certain elements of an action change frequently or depend on complicated state while other parts rarely change or can be shared amongst multiple - # parties. The caching is doing using the cache helper available in the Action View. A template with caching might look something like: + # parties. The caching is done using the cache helper available in the Action View. A template with caching might look something like: # # Hello <%= @name %> # <% cache do %> diff --git a/actionpack/lib/action_controller/cookies.rb b/actionpack/lib/action_controller/cookies.rb index a4cddbcea2..0428f2a23d 100644 --- a/actionpack/lib/action_controller/cookies.rb +++ b/actionpack/lib/action_controller/cookies.rb @@ -22,6 +22,16 @@ module ActionController #:nodoc: # # 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: # # * :value - The cookie's value or list of values (as an array). diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb index 18c2df8b37..2a732448f2 100644 --- a/actionpack/lib/action_controller/integration.rb +++ b/actionpack/lib/action_controller/integration.rb @@ -101,7 +101,7 @@ module ActionController @https = flag end - # Return +true+ if the session is mimicing a secure HTTPS request. + # Return +true+ if the session is mimicking a secure HTTPS request. # # if session.https? # ... diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index ef329b759a..7e0a6b091e 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -250,7 +250,7 @@ end_msg # Convert 'cookie' header to 'Set-Cookie' headers. # Because Set-Cookie header can appear more the once in the response body, - # we store it in a line break seperated string that will be translated to + # we store it in a line break separated string that will be translated to # multiple Set-Cookie header by the handler. if cookie = options.delete('cookie') cookies = [] diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 2d9f6c3e6f..c42f113d2c 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -61,7 +61,7 @@ module ActionController request_method == :head end - # Provides acccess to the request's HTTP headers, for example: + # Provides access to the request's HTTP headers, for example: # request.headers["Content-Type"] # => "text/plain" def headers @headers ||= ActionController::Http::Headers.new(@env) @@ -265,7 +265,7 @@ EOM parts[0..-(tld_length+2)] end - # Return the query string, accounting for server idiosyncracies. + # Return the query string, accounting for server idiosyncrasies. def query_string if uri = @env['REQUEST_URI'] uri.split('?', 2)[1] || '' @@ -274,7 +274,7 @@ EOM end end - # Return the request URI, accounting for server idiosyncracies. + # Return the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri if uri = @env['REQUEST_URI'] diff --git a/actionpack/lib/action_controller/request_forgery_protection.rb b/actionpack/lib/action_controller/request_forgery_protection.rb index 02c9d59d07..05a6d8bb79 100644 --- a/actionpack/lib/action_controller/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/request_forgery_protection.rb @@ -17,7 +17,7 @@ module ActionController #:nodoc: # forged link from another site, is done by embedding a token based on the session (which an attacker wouldn't know) in all # forms and Ajax requests generated by Rails and then verifying the authenticity of that token in the controller. Only # HTML/JavaScript requests are checked, so this will not protect your XML API (presumably you'll have a different authentication - # scheme there anyway). Also, GET requests are not protected as these should be indempotent anyway. + # scheme there anyway). Also, GET requests are not protected as these should be idempotent anyway. # # This is turned on with the protect_from_forgery method, which will check the token and raise an # ActionController::InvalidAuthenticityToken if it doesn't match what was expected. You can customize the error message in diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb index af2fcaf3ad..b11aa5625b 100644 --- a/actionpack/lib/action_controller/resources.rb +++ b/actionpack/lib/action_controller/resources.rb @@ -296,6 +296,10 @@ module ActionController # article_comments_url(:article_id => @article) # article_comment_url(:article_id => @article, :id => @comment) # + # If you don't want to load all objects from the database you might want to use the article_id directly: + # + # articles_comments_url(@comment.article_id, @comment) + # # * :name_prefix - Define a prefix for all generated routes, usually ending in an underscore. # Use this if you have named routes that may clash. # diff --git a/actionpack/lib/action_controller/streaming.rb b/actionpack/lib/action_controller/streaming.rb index 186e0e5531..333fb61b45 100644 --- a/actionpack/lib/action_controller/streaming.rb +++ b/actionpack/lib/action_controller/streaming.rb @@ -12,19 +12,21 @@ module ActionController #:nodoc: X_SENDFILE_HEADER = 'X-Sendfile'.freeze protected - # Sends the file by streaming it 4096 bytes at a time. This way the - # whole file doesn't need to be read into memory at once. This makes - # it feasible to send even large files. + # Sends the file, by default streaming it 4096 bytes at a time. This way the + # whole file doesn't need to be read into memory at once. This makes it + # feasible to send even large files. You can optionally turn off streaming + # and send the whole file at once. # - # Be careful to sanitize the path parameter if it coming from a web + # Be careful to sanitize the path parameter if it is coming from a web # page. send_file(params[:path]) allows a malicious user to # download any file on your server. # # Options: # * :filename - suggests a filename for the browser to use. # Defaults to File.basename(path). - # * :type - specifies an HTTP content type. - # Defaults to 'application/octet-stream'. + # * :type - specifies an HTTP content type. Defaults to 'application/octet-stream'. + # * :length - used to manually override the length (in bytes) of the content that + # is going to be sent to the client. Defaults to File.size(path). # * :disposition - specifies whether the file will be shown inline or downloaded. # Valid values are 'inline' and 'attachment' (default). # * :stream - whether to send the file to the user agent as it is read (+true+) @@ -35,6 +37,12 @@ module ActionController #:nodoc: # * :url_based_filename - set to +true+ if you want the browser guess the filename from # the URL, which is necessary for i18n filenames on certain browsers # (setting :filename overrides this option). + # * :x_sendfile - uses X-Sendfile to send the file when set to +true+. This is currently + # only available with Lighttpd/Apache2 and specific modules installed and activated. Since this + # uses the web server to send the file, this may lower memory consumption on your server and + # it will not block your application for further requests. + # See http://blog.lighttpd.net/articles/2006/07/02/x-sendfile and + # http://tn123.ath.cx/mod_xsendfile/ for details. Defaults to +false+. # # The default Content-Type and Content-Disposition headers are # set to download arbitrary binary files in as many browsers as @@ -99,8 +107,7 @@ module ActionController #:nodoc: # # Options: # * :filename - suggests a filename for the browser to use. - # * :type - specifies an HTTP content type. - # Defaults to 'application/octet-stream'. + # * :type - specifies an HTTP content type. Defaults to 'application/octet-stream'. # * :disposition - specifies whether the file will be shown inline or downloaded. # Valid values are 'inline' and 'attachment' (default). # * :status - specifies the status code to send with the response. Defaults to '200 OK'. diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 77c6f26eac..c09050c390 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -15,6 +15,27 @@ module ActionController end end + # Superclass for Action Controller functional tests. Infers the controller under test from the test class name, + # and creates @controller, @request, @response instance variables. + # + # class WidgetsControllerTest < ActionController::TestCase + # def test_index + # get :index + # end + # end + # + # * @controller - WidgetController.new + # * @request - ActionController::TestRequest.new + # * @response - ActionController::TestResponse.new + # + # (Earlier versions of Rails required each functional test to subclass Test::Unit::TestCase and define + # @controller, @request, @response in +setup+.) + # + # If the controller cannot be inferred from the test class name, you can explicity set it with +tests+. + # + # class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase + # tests WidgetController + # end class TestCase < ActiveSupport::TestCase # When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline # (bystepping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular @@ -41,6 +62,8 @@ module ActionController @@controller_class = nil class << self + # Sets the controller class name. Useful if the name can't be inferred from test class. + # Expects +controller_class+ as a constant. Example: tests WidgetController. def tests(controller_class) self.controller_class = controller_class end diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index a6e0c98936..0b160ff41d 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -211,7 +211,7 @@ module ActionController #:nodoc: template._first_render end - # A shortcut to the flash. Returns an empyt hash if no session flash exists. + # A shortcut to the flash. Returns an empty hash if no session flash exists. def flash session['flash'] || {} end diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb index 1a3c770254..376bb87409 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb @@ -64,7 +64,7 @@ module HTML # # When using a combination of the above, the element name comes first # followed by identifier, class names, attributes, pseudo classes and - # negation in any order. Do not seprate these parts with spaces! + # negation in any order. Do not separate these parts with spaces! # Space separation is used for descendant selectors. # # For example: @@ -158,7 +158,7 @@ module HTML # * :not(selector) -- Match the element only if the element does not # match the simple selector. # - # As you can see, :nth-child pseudo class and its varient can get quite + # As you can see, :nth-child pseudo class and its variant can get quite # tricky and the CSS specification doesn't do a much better job explaining it. # But after reading the examples and trying a few combinations, it's easy to # figure out. diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 0ea96f045e..85af73390d 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -177,7 +177,7 @@ module ActionView #:nodoc: end def self.cache_template_extensions=(*args) - ActiveSupport::Deprecation.warn("config.action_view.cache_template_extensions option has been deprecated and has no affect. " << + ActiveSupport::Deprecation.warn("config.action_view.cache_template_extensions option has been deprecated and has no effect. " << "Please remove it from your config files.", caller) end diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb index f3f204cc97..e788ebf359 100644 --- a/actionpack/lib/action_view/helpers/active_record_helper.rb +++ b/actionpack/lib/action_view/helpers/active_record_helper.rb @@ -141,7 +141,7 @@ module ActionView # # error_messages_for 'user_common', 'user', :object_name => 'user' # - # If the objects cannot be located as instance variables, you can add an extra :object paremeter which gives the actual + # If the objects cannot be located as instance variables, you can add an extra :object parameter which gives the actual # object (or array of objects to use): # # error_messages_for 'user', :object => @question.user diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index d018034ebe..0735ed07ee 100755 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -280,11 +280,11 @@ module ActionView # # # Generates a date select that discards the type of the field and defaults to the date in # # my_date (six days after today) - # select_datetime(my_date_time, :discard_type => true) + # select_date(my_date, :discard_type => true) # # # Generates a date select that defaults to the datetime in my_date (six days after today) # # prefixed with 'payday' rather than 'date' - # select_datetime(my_date_time, :prefix => 'payday') + # select_date(my_date, :prefix => 'payday') # def select_date(date = Date.current, options = {}, html_options = {}) options[:order] ||= [] diff --git a/actionpack/lib/action_view/helpers/debug_helper.rb b/actionpack/lib/action_view/helpers/debug_helper.rb index 20de7e465f..90863fca08 100644 --- a/actionpack/lib/action_view/helpers/debug_helper.rb +++ b/actionpack/lib/action_view/helpers/debug_helper.rb @@ -2,21 +2,28 @@ module ActionView module Helpers # Provides a set of methods for making it easier to debug Rails objects. module DebugHelper - # Returns a
-tag that has +object+ dumped by YAML. This creates a very
-      # readable way to inspect an object.
+      # Returns a YAML representation of +object+ wrapped with 
 and 
. + # If the object cannot be converted to YAML using +to_yaml+, +inspect+ will be called instead. + # Useful for inspecting an object at the time of rendering. # # ==== Example - # my_hash = {'first' => 1, 'second' => 'two', 'third' => [1,2,3]} - # debug(my_hash) # - # =>
--- 
-      #  first: 1
-      #  second: two
-      #  third: 
-      #  - 1
-      #  - 2
-      #  - 3
-      #  
+ # @user = User.new({ :username => 'testing', :password => 'xyz', :age => 42}) %> + # debug(@user) + # # => + #
--- !ruby/object:User
+      #   attributes:
+      #     updated_at:
+      #     username: testing
+      #
+      #     age: 42
+      #     password: xyz
+      #     created_at:
+      #   attributes_cache: {}
+      #
+      #   new_record: true
+      #   
+ def debug(object) begin Marshal::dump(object) @@ -28,4 +35,4 @@ module ActionView end end end -end \ No newline at end of file +end diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index bafc635ad2..fa26aa4640 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -76,7 +76,7 @@ module ActionView # Creates a form and a scope around a specific model object that is used as # a base for questioning about values for the fields. # - # Rails provides succint resource-oriented form generation with +form_for+ + # Rails provides succinct resource-oriented form generation with +form_for+ # like this: # # <% form_for @offer do |f| %> @@ -449,8 +449,37 @@ module ActionView # assigned to the template (identified by +object+). It's intended that +method+ returns an integer and if that # integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a # hash with +options+. The +checked_value+ defaults to 1 while the default +unchecked_value+ - # is set to 0 which is convenient for boolean values. Since HTTP standards say that unchecked checkboxes don't post anything, - # we add a hidden value with the same name as the checkbox as a work around. + # is set to 0 which is convenient for boolean values. + # + # ==== Gotcha + # + # 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 + # invoice the user unchecks its check box, no +paid+ parameter is sent. So, + # any mass-assignment idiom like + # + # @invoice.update_attributes(params[:invoice]) + # + # 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. + # + # Unfortunately that workaround does not work when the check box goes + # within an array-like parameter, as in + # + # <% fields_for "project[invoice_attributes][]", invoice, :index => nil do |form| %> + # <%= form.check_box :paid %> + # ... + # <% end %> + # + # because parameter name repetition is precisely what Rails seeks to distinguish + # the elements of the array. # # ==== Examples # # Let's say that @post.validated? is 1: diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 87d49397c6..cc609f5d67 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -274,9 +274,11 @@ module ActionView end end - # Returns a string of option tags for pretty much any country in the world. Supply a country name as +selected+ to - # have it marked as the selected option tag. You can also supply an array of countries as +priority_countries+, so - # that they will be listed above the rest of the (long) list. + # Returns a string of option tags for most countries in the + # world (as defined in COUNTRIES). Supply a country name as + # +selected+ to have it marked as the selected option tag. You + # can also supply an array of countries as +priority_countries+, + # so that they will be listed above the rest of the (long) list. # # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag. def country_options_for_select(selected = nil, priority_countries = nil) diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 22bd5cb440..32089442b7 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -44,13 +44,22 @@ module ActionView include PrototypeHelper - # Returns a link that will trigger a JavaScript +function+ using the + # Returns a link of the given +name+ that will trigger a JavaScript +function+ using the # onclick handler and return false after the fact. # + # The first argument +name+ is used as the link text. + # + # The next arguments are optional and may include the javascript function definition and a hash of html_options. + # # The +function+ argument can be omitted in favor of an +update_page+ # block, which evaluates to a string when the template is rendered # (instead of making an Ajax request first). # + # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button" + # + # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil + # + # # Examples: # link_to_function "Greeting", "alert('Hello world!')" # Produces: @@ -89,13 +98,21 @@ module ActionView content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) end - # Returns a button that'll trigger a JavaScript +function+ using the + # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the # onclick handler. # + # The first argument +name+ is used as the button's value or display text. + # + # The next arguments are optional and may include the javascript function definition and a hash of html_options. + # # The +function+ argument can be omitted in favor of an +update_page+ # block, which evaluates to a string when the template is rendered # (instead of making an Ajax request first). # + # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button" + # + # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil + # # Examples: # button_to_function "Greeting", "alert('Hello world!')" # button_to_function "Delete", "if (confirm('Really?')) do_delete()" diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 8c8c22dd4a..cb4b53a9f7 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -61,7 +61,7 @@ module ActionView # # == Designing your Rails actions for Ajax # When building your action handlers (that is, the Rails actions that receive your background requests), it's - # important to remember a few things. First, whatever your action would normall return to the browser, it will + # important to remember a few things. First, whatever your action would normally return to the browser, it will # return to the Ajax call. As such, you typically don't want to render with a layout. This call will cause # the layout to be transmitted back to your page, and, if you have a full HTML/CSS, will likely mess a lot of things up. # You can turn the layout off on particular actions by doing the following: diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index b0dacfe964..c3c03394ee 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -184,7 +184,7 @@ module ActionView HTML::WhiteListSanitizer.allowed_attributes.merge(attributes) end - # Adds to the Set of allowed CSS properties for the #sanitize and +sanitize_css+ heleprs. + # Adds to the Set of allowed CSS properties for the #sanitize and +sanitize_css+ helpers. # # Rails::Initializer.run do |config| # config.action_view.sanitized_allowed_css_properties = 'expression' diff --git a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb index c9b2761cb8..b938c1a801 100644 --- a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb +++ b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb @@ -193,7 +193,7 @@ module ActionView # # * :onDrop - Called when a +draggable_element+ is dropped onto # this element. Override this callback with a JavaScript expression to - # change the default drop behavour. Example: + # change the default drop behaviour. Example: # # :onDrop => "function(draggable_element, droppable_element, event) { alert('I like bananas') }" # diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 5a296da247..de08672d2d 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -64,7 +64,7 @@ module ActionView # <% content_tag :div, :class => "strong" do -%> # Hello world! # <% end -%> - # # =>

Hello world!

+ # # =>
Hello world!
def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) if block_given? options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index e5178938fd..94e1f1d33a 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -185,7 +185,7 @@ module ActionView # link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux") # # => Nonsense search # - # The three options specfic to +link_to+ (:confirm, :popup, and :method) are used as follows: + # The three options specific to +link_to+ (:confirm, :popup, and :method) are used as follows: # # link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?" # # => Visit Other Site -- cgit v1.2.3 From c64d749abdf31a2be322b1787165024067abbda7 Mon Sep 17 00:00:00 2001 From: Stefan Kaes Date: Wed, 16 Jul 2008 08:26:23 -0500 Subject: Fixed template recompile logic [#630 state:resolved] Signed-off-by: Joshua Peek --- actionpack/lib/action_view/renderable.rb | 53 +++++++++++++--------- actionpack/test/abstract_unit.rb | 1 + .../test/template/compiled_templates_test.rb | 41 +++++++++++++++++ 3 files changed, 73 insertions(+), 22 deletions(-) create mode 100644 actionpack/test/template/compiled_templates_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index badb2b171c..46193670f3 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -9,6 +9,10 @@ module ActionView include ActiveSupport::Memoizable + def filename + 'compiled-template' + end + def handler Template.handler_class_for_extension(extension) end @@ -35,35 +39,41 @@ module ActionView end private - # Compile and evaluate the template's code + # Compile and evaluate the template's code (if necessary) def compile(local_assigns) render_symbol = method(local_assigns) @@mutex.synchronize do - return false unless recompile?(render_symbol) + if recompile?(render_symbol) + compile!(render_symbol, local_assigns) + end + end + end - locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join + def compile!(render_symbol, local_assigns) + locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join - source = <<-end_src - def #{render_symbol}(local_assigns) - old_output_buffer = output_buffer;#{locals_code};#{compiled_source} - ensure - self.output_buffer = old_output_buffer - end - end_src + source = <<-end_src + def #{render_symbol}(local_assigns) + old_output_buffer = output_buffer;#{locals_code};#{compiled_source} + ensure + self.output_buffer = old_output_buffer + end + end_src - begin - file_name = respond_to?(:filename) ? filename : 'compiled-template' - ActionView::Base::CompiledTemplates.module_eval(source, file_name, 0) - rescue Exception => e # errors from template code - if logger = ActionController::Base.logger - logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}" - logger.debug "Function body: #{source}" - logger.debug "Backtrace: #{e.backtrace.join("\n")}" - end + begin + logger = ActionController::Base.logger + logger.debug "Compiling template #{render_symbol}" if logger - raise ActionView::TemplateError.new(self, {}, e) + ActionView::Base::CompiledTemplates.module_eval(source, filename, 0) + rescue Exception => e # errors from template code + if logger + logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}" + logger.debug "Function body: #{source}" + logger.debug "Backtrace: #{e.backtrace.join("\n")}" end + + raise ActionView::TemplateError.new(self, {}, e) end end @@ -71,8 +81,7 @@ module ActionView # The template will be compiled if the file has not been compiled yet, or # if local_assigns has a new key, which isn't supported by the compiled code yet. def recompile?(symbol) - meth = Base::CompiledTemplates.instance_method(template.method) rescue nil - !(meth && frozen?) + !(frozen? && Base::CompiledTemplates.method_defined?(symbol)) end end end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 520379fe82..9db4cddd6a 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -23,6 +23,7 @@ ActionController::Base.logger = nil ActionController::Routing::Routes.reload rescue nil FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures') +ActionView::PathSet::Path.eager_load_templates! ActionController::Base.view_paths = FIXTURE_LOAD_PATH # Wrap tests that use Mocha and skip if unavailable. diff --git a/actionpack/test/template/compiled_templates_test.rb b/actionpack/test/template/compiled_templates_test.rb new file mode 100644 index 0000000000..4b34827f91 --- /dev/null +++ b/actionpack/test/template/compiled_templates_test.rb @@ -0,0 +1,41 @@ +require 'abstract_unit' +require 'controller/fake_models' + +uses_mocha 'TestTemplateRecompilation' do + class CompiledTemplatesTest < Test::Unit::TestCase + def setup + @view = ActionView::Base.new(ActionController::Base.view_paths, {}) + @compiled_templates = ActionView::Base::CompiledTemplates + @compiled_templates.instance_methods.each do |m| + @compiled_templates.send(:remove_method, m) if m =~ /^_run_/ + end + end + + def test_template_gets_compiled + assert_equal 0, @compiled_templates.instance_methods.size + assert_equal "Hello world!", @view.render("test/hello_world.erb") + assert_equal 1, @compiled_templates.instance_methods.size + end + + def test_template_gets_recompiled_when_using_different_keys_in_local_assigns + assert_equal 0, @compiled_templates.instance_methods.size + assert_equal "Hello world!", @view.render("test/hello_world.erb") + assert_equal "Hello world!", @view.render("test/hello_world.erb", {:foo => "bar"}) + assert_equal 2, @compiled_templates.instance_methods.size + end + + def test_compiled_template_will_not_be_recompiled_when_rendered_with_identical_local_assigns + assert_equal 0, @compiled_templates.instance_methods.size + assert_equal "Hello world!", @view.render("test/hello_world.erb") + ActionView::Template.any_instance.expects(:compile!).never + assert_equal "Hello world!", @view.render("test/hello_world.erb") + end + + def test_compiled_template_will_always_be_recompiled_when_rendered_if_template_is_outside_cache + assert_equal 0, @compiled_templates.instance_methods.size + assert_equal "Hello world!", @view.render("#{FIXTURE_LOAD_PATH}/test/hello_world.erb") + ActionView::Template.any_instance.expects(:compile!).times(3) + 3.times { assert_equal "Hello world!", @view.render("#{FIXTURE_LOAD_PATH}/test/hello_world.erb") } + end + end +end -- cgit v1.2.3 From 90c930f45c5c6766306929241462ffff8f67b86e Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 16 Jul 2008 18:51:40 +0100 Subject: Allow Dispatcher exceptions to be handled in application.rb using rescue_from --- actionpack/lib/action_controller/rescue.rb | 28 ++++++++++++++++------------ actionpack/test/controller/rescue_test.rb | 9 +++++++++ 2 files changed, 25 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb index 163ed87fbb..482ac7d7a4 100644 --- a/actionpack/lib/action_controller/rescue.rb +++ b/actionpack/lib/action_controller/rescue.rb @@ -112,19 +112,23 @@ module ActionController #:nodoc: protected # Exception handler called when the performance of an action raises an exception. def rescue_action(exception) - log_error(exception) if logger - erase_results if performed? + if handler_for_rescue(exception) + rescue_action_with_handler(exception) + else + log_error(exception) if logger + erase_results if performed? - # Let the exception alter the response if it wants. - # For example, MethodNotAllowed sets the Allow header. - if exception.respond_to?(:handle_response!) - exception.handle_response!(response) - end + # Let the exception alter the response if it wants. + # For example, MethodNotAllowed sets the Allow header. + if exception.respond_to?(:handle_response!) + exception.handle_response!(response) + end - if consider_all_requests_local || local_request? - rescue_action_locally(exception) - else - rescue_action_in_public(exception) + if consider_all_requests_local || local_request? + rescue_action_locally(exception) + else + rescue_action_in_public(exception) + end end end @@ -200,7 +204,7 @@ module ActionController #:nodoc: def perform_action_with_rescue #:nodoc: perform_action_without_rescue rescue Exception => exception - rescue_action_with_handler(exception) || rescue_action(exception) + rescue_action(exception) end def rescues_path(template_name) diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb index 27fcc5e04c..da076d2090 100644 --- a/actionpack/test/controller/rescue_test.rb +++ b/actionpack/test/controller/rescue_test.rb @@ -62,6 +62,11 @@ class RescueController < ActionController::Base render :text => exception.message end + # This is a Dispatcher exception and should be in ApplicationController. + rescue_from ActionController::RoutingError do + render :text => 'no way' + end + def raises render :text => 'already rendered' raise "don't panic!" @@ -378,6 +383,10 @@ class RescueTest < Test::Unit::TestCase assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body end + def test_rescue_dispatcher_exceptions + RescueController.process_with_exception(@request, @response, ActionController::RoutingError.new("Route not found")) + assert_equal "no way", @response.body + end protected def with_all_requests_local(local = true) -- cgit v1.2.3 From 8fe01de2e8753d045408ecde3178ab4e9192bf9a Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 16 Jul 2008 17:39:14 -0500 Subject: Fixed that AssetTagHelper#compute_public_path shouldn't cache the asset_host along with the source or per-request proc's won't run [DHH] --- actionpack/CHANGELOG | 2 ++ .../lib/action_view/helpers/asset_tag_helper.rb | 25 ++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 5a5895d9b4..e8d518baf3 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Fixed that AssetTagHelper#compute_public_path shouldn't cache the asset_host along with the source or per-request proc's won't run [DHH] + * Add :as option to render a collection of partials with a custom local variable name. #509 [Simon Jefford, Pratik Naik] render :partial => 'other_people', :collection => @people, :as => :person diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index e5a95a961c..b86e1b7da4 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -485,21 +485,24 @@ module ActionView source = "#{@controller.request.relative_url_root}#{source}" end end - source = rewrite_asset_path(source) - if include_host - host = compute_asset_host(source) + rewrite_asset_path(source) + end + end - if has_request && !host.blank? && host !~ %r{^[-a-z]+://} - host = "#{@controller.request.protocol}#{host}" - end + source = ActionView::Base.computed_public_paths[cache_key] - "#{host}#{source}" - else - source - end - end + if include_host && source !~ %r{^[-a-z]+://} + host = compute_asset_host(source) + + if has_request && !host.blank? && host !~ %r{^[-a-z]+://} + host = "#{@controller.request.protocol}#{host}" end + + "#{host}#{source}" + else + source + end end # Pick an asset host for this source. Returns +nil+ if no host is set, -- cgit v1.2.3 From f7fdbae770275ccbc277c42287b9783cb00fa9fa Mon Sep 17 00:00:00 2001 From: Ripta Pasay Date: Sat, 12 Jul 2008 18:54:24 -0400 Subject: Use fully-qualified controller name when logging. [#600 state:resolved] Signed-off-by: Pratik Naik --- actionpack/lib/action_controller/base.rb | 2 +- actionpack/test/controller/base_test.rb | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index df94f78f18..c56812c2d9 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -1155,7 +1155,7 @@ module ActionController #:nodoc: def log_processing if logger && logger.info? - logger.info "\n\nProcessing #{controller_class_name}\##{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]" + logger.info "\n\nProcessing #{self.class.name}\##{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]" logger.info " Session ID: #{@_session.session_id}" if @_session and @_session.respond_to?(:session_id) logger.info " Parameters: #{respond_to?(:filter_parameters) ? filter_parameters(params).inspect : params.inspect}" end diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 34c0200fe8..d49cc2a9aa 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -7,6 +7,7 @@ module Submodule end class ContainedNonEmptyController < ActionController::Base def public_action + render :nothing => true end hide_action :hidden_action @@ -105,6 +106,18 @@ end class PerformActionTest < Test::Unit::TestCase + class MockLogger + attr_reader :logged + + def initialize + @logged = [] + end + + def method_missing(method, *args) + @logged << args.first + end + end + def use_controller(controller_class) @controller = controller_class.new @@ -142,6 +155,13 @@ class PerformActionTest < Test::Unit::TestCase get :another_hidden_action assert_response 404 end + + def test_namespaced_action_should_log_module_name + use_controller Submodule::ContainedNonEmptyController + @controller.logger = MockLogger.new + get :public_action + assert_match /Processing\sSubmodule::ContainedNonEmptyController#public_action/, @controller.logger.logged[1] + end end class DefaultUrlOptionsTest < Test::Unit::TestCase -- cgit v1.2.3 From cd6301557005617583e3f9ca5fb56297adcce7cc Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 16 Jul 2008 19:49:46 -0500 Subject: All 2xx requests are considered successful [#217 state:resolved] --- actionpack/CHANGELOG | 2 ++ actionpack/lib/action_controller/test_process.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 21cc7a9c64..da9fdbfd9d 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* All 2xx requests are considered successful [Josh Peek] + * Fixed that AssetTagHelper#compute_public_path shouldn't cache the asset_host along with the source or per-request proc's won't run [DHH] * Removed config.action_view.cache_template_loading, use config.cache_classes instead [Josh Peek] diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index 0b160ff41d..721592b81f 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -171,7 +171,7 @@ module ActionController #:nodoc: # Was the response successful? def success? - response_code == 200 + (200..299).include?(response_code) end # Was the URL not found? -- cgit v1.2.3 From 99930d499e424f4560b371412e05d10476216ece Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 17 Jul 2008 18:19:09 +0100 Subject: Fix symbol cookie test --- actionpack/test/controller/cookie_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb index b45fbb17d3..5a6fb49861 100644 --- a/actionpack/test/controller/cookie_test.rb +++ b/actionpack/test/controller/cookie_test.rb @@ -60,7 +60,7 @@ class CookieTest < Test::Unit::TestCase end def test_setting_cookie_for_fourteen_days_with_symbols - get :authenticate_for_fourteen_days + get :authenticate_for_fourteen_days_with_symbols assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david", "expires" => Time.local(2005, 10, 10)) ], @response.headers["cookie"] end -- cgit v1.2.3