From 36058f45040b5559fd8f6a44a17ead27a6b3d2f7 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Tue, 19 May 2009 19:51:38 -0400 Subject: Use duck typing to also allow MemCache-like object when initializing a MemCacheStore Signed-off-by: Jeremy Kemper --- activesupport/CHANGELOG | 2 +- activesupport/lib/active_support/cache/mem_cache_store.rb | 2 +- activesupport/test/caching_test.rb | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 6551be01f9..27d26b2ba5 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,6 +1,6 @@ *Edge* -* Allow MemCacheStore to be initialized with a MemCache object instead of addresses and options [Bryan Helmkamp] +* Allow MemCacheStore to be initialized with a MemCache-like object instead of addresses and options [Bryan Helmkamp] * Change spelling of Kyev timezone to Kyiv #2613 [Alexander Dymo] diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index ab8eb72096..38b3409ca6 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -39,7 +39,7 @@ module ActiveSupport # If no addresses are specified, then MemCacheStore will connect to # localhost port 11211 (the default memcached port). def initialize(*addresses) - if addresses.first.is_a?(MemCache) + if addresses.first.respond_to?(:get) @data = addresses.first else @data = self.class.build_mem_cache(*addresses) diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index ad19dcfd09..bd237a5c8e 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -27,6 +27,12 @@ class CacheStoreSettingTest < ActiveSupport::TestCase assert_kind_of(ActiveSupport::Cache::MemCacheStore, store) end + def test_mem_cache_fragment_cache_store_with_given_mem_cache_like_object + MemCache.expects(:new).never + store = ActiveSupport::Cache.lookup_store :mem_cache_store, stub("memcache", :get => true) + assert_kind_of(ActiveSupport::Cache::MemCacheStore, store) + end + def test_mem_cache_fragment_cache_store_with_multiple_servers MemCache.expects(:new).with(%w[localhost 192.168.1.1], {}) store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1' -- cgit v1.2.3 From 67247ca8ee850223193a5fe77f5460aefc0336c0 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Tue, 19 May 2009 17:41:17 -0700 Subject: Corrected new callbacks semantics with regards to using objects for around filters. --- activesupport/lib/active_support/new_callbacks.rb | 10 ++-- activesupport/test/new_callbacks_test.rb | 62 +++++++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/new_callbacks.rb b/activesupport/lib/active_support/new_callbacks.rb index 9316d6d2b6..f8108780f1 100644 --- a/activesupport/lib/active_support/new_callbacks.rb +++ b/activesupport/lib/active_support/new_callbacks.rb @@ -296,9 +296,13 @@ module ActiveSupport method_name else kind, name = @kind, @name - @klass.send(:define_method, method_name) do - filter.send("#{kind}_#{name}", self) - end + @klass.send(:define_method, "#{method_name}_object") { filter } + + @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{method_name}(&blk) + #{method_name}_object.send("#{kind}_#{name}", self, &blk) + end + RUBY_EVAL method_name end end diff --git a/activesupport/test/new_callbacks_test.rb b/activesupport/test/new_callbacks_test.rb index dec6106ac1..7bec47224d 100644 --- a/activesupport/test/new_callbacks_test.rb +++ b/activesupport/test/new_callbacks_test.rb @@ -396,6 +396,68 @@ module NewCallbacksTest end end + class CallbackObject + def before_save(caller) + caller.record << "before" + end + + def around_save(caller) + caller.record << "around before" + yield + caller.record << "around after" + end + end + + class UsingObjectBefore + include ActiveSupport::NewCallbacks + + define_callbacks :save + save_callback :before, CallbackObject.new + + attr_accessor :record + def initialize + @record = [] + end + + def save + _run_save_callbacks do + @record << "yielded" + end + end + end + + class UsingObjectAround + include ActiveSupport::NewCallbacks + + define_callbacks :save + save_callback :around, CallbackObject.new + + attr_accessor :record + def initialize + @record = [] + end + + def save + _run_save_callbacks do + @record << "yielded" + end + end + end + + class UsingObjectTest < Test::Unit::TestCase + def test_before_object + u = UsingObjectBefore.new + u.save + assert_equal ["before", "yielded"], u.record + end + + def test_around_object + u = UsingObjectAround.new + u.save + assert_equal ["around before", "yielded", "around after"], u.record + end + end + class CallbackTerminatorTest < Test::Unit::TestCase def test_termination terminator = CallbackTerminator.new -- cgit v1.2.3 From 26f2be01c2d537aac6d484c8a1ed2df92aa52f00 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Tue, 19 May 2009 18:02:03 -0700 Subject: Modify caching to use new included helper --- actionpack/lib/action_controller/caching.rb | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb index ffd8081edc..2f2eec10f6 100644 --- a/actionpack/lib/action_controller/caching.rb +++ b/actionpack/lib/action_controller/caching.rb @@ -24,31 +24,31 @@ module ActionController #:nodoc: # ActionController::Base.cache_store = :mem_cache_store, "localhost" # ActionController::Base.cache_store = MyOwnStore.new("parameter") module Caching + extend ActiveSupport::DependencyModule + autoload :Actions, 'action_controller/caching/actions' autoload :Fragments, 'action_controller/caching/fragments' autoload :Pages, 'action_controller/caching/pages' autoload :Sweeper, 'action_controller/caching/sweeping' autoload :Sweeping, 'action_controller/caching/sweeping' - def self.included(base) #:nodoc: - base.class_eval do - @@cache_store = nil - cattr_reader :cache_store + included do + @@cache_store = nil + cattr_reader :cache_store - # Defines the storage option for cached fragments - def self.cache_store=(store_option) - @@cache_store = ActiveSupport::Cache.lookup_store(store_option) - end + # Defines the storage option for cached fragments + def self.cache_store=(store_option) + @@cache_store = ActiveSupport::Cache.lookup_store(store_option) + end - include Pages, Actions, Fragments - include Sweeping if defined?(ActiveRecord) + include Pages, Actions, Fragments + include Sweeping if defined?(ActiveRecord) - @@perform_caching = true - cattr_accessor :perform_caching + @@perform_caching = true + cattr_accessor :perform_caching - def self.cache_configured? - perform_caching && cache_store - end + def self.cache_configured? + perform_caching && cache_store end end -- cgit v1.2.3 From 0e7da0e4a06f78ab39b0e90daadfc223b8f1738a Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Tue, 19 May 2009 18:04:17 -0700 Subject: Include caching module into new base --- actionpack/lib/action_controller/new_base.rb | 1 + actionpack/lib/action_controller/new_base/base.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index bc47713529..078f66ced1 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -13,6 +13,7 @@ module ActionController # Ported modules # require 'action_controller/routing' + autoload :Caching, 'action_controller/caching' autoload :Dispatcher, 'action_controller/dispatch/dispatcher' autoload :PolymorphicRoutes, 'action_controller/routing/generation/polymorphic_routes' autoload :RecordIdentifier, 'action_controller/record_identifier' diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 756a0799fe..7f830307b6 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -17,6 +17,7 @@ module ActionController # Legacy modules include SessionManagement include ActionDispatch::StatusCodes + include ActionController::Caching # Rails 2.x compatibility include ActionController::Rails2Compatibility -- cgit v1.2.3 From 67cc021d019515c94d4bcc4c3c7060c9a2594c87 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Tue, 19 May 2009 18:05:16 -0700 Subject: Modified caching implementation to work with NewBase --- .../lib/action_controller/caching/actions.rb | 22 +++++++++++++++++++--- .../lib/action_controller/new_base/renderer.rb | 5 +++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index 2b822b52c8..430db3932f 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -61,8 +61,14 @@ module ActionController #:nodoc: filter_options = { :only => actions, :if => options.delete(:if), :unless => options.delete(:unless) } cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path), :store_options => options) - around_filter(filter_options) do |controller, action| - cache_filter.filter(controller, action) + + # TODO: Remove this once new base is swapped in. + if defined?(Http) + around_filter cache_filter, filter_options + else + around_filter(filter_options) do |controller, action| + cache_filter.filter(controller, action) + end end end end @@ -85,14 +91,22 @@ module ActionController #:nodoc: @options = options end + # TODO: Remove once New Base is merged def filter(controller, action) should_continue = before(controller) action.call if should_continue after(controller) end + def around_process_action(controller) + should_continue = before(controller) + yield if should_continue + after(controller) + end + def before(controller) cache_path = ActionCachePath.new(controller, path_options_for(controller, @options.slice(:cache_path))) + if cache = controller.read_fragment(cache_path.path, @options[:store_options]) controller.rendered_action_cache = true set_content_type!(controller, cache_path.extension) @@ -129,7 +143,9 @@ module ActionController #:nodoc: end def content_for_layout(controller) - controller.template.layout && controller.template.instance_variable_get('@cached_content_for_layout') + # TODO: Remove this when new base is merged in + template = controller.respond_to?(:template) ? controller.template : controller._action_view + template.layout && template.instance_variable_get('@cached_content_for_layout') end end diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 8a9f230603..9253df53a1 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -9,6 +9,11 @@ module ActionController super end + def response_body=(body) + response.body = body if response + super + end + def render_to_body(options) _process_options(options) -- cgit v1.2.3 From 321168b17bce2e73ab7ba22309491ad5c245dcf8 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Tue, 19 May 2009 18:08:04 -0700 Subject: Make old caching tests pass on new base. --- actionpack/lib/action_controller/new_base/compatibility.rb | 4 ++++ actionpack/lib/action_controller/new_base/http.rb | 1 - actionpack/lib/action_controller/new_base/url_for.rb | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index 0a283887b6..0098c0747e 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -55,6 +55,10 @@ module ActionController self.consider_all_requests_local = true end + # For old tests + def initialize_template_class(*) end + def assign_shortcuts(*) end + module ClassMethods def protect_from_forgery() end def consider_all_requests_local() end diff --git a/actionpack/lib/action_controller/new_base/http.rb b/actionpack/lib/action_controller/new_base/http.rb index 8891a2a8c3..17466a2d52 100644 --- a/actionpack/lib/action_controller/new_base/http.rb +++ b/actionpack/lib/action_controller/new_base/http.rb @@ -60,7 +60,6 @@ module ActionController # :api: private def to_rack - @_response.body = response_body @_response.prepare! @_response.to_a end diff --git a/actionpack/lib/action_controller/new_base/url_for.rb b/actionpack/lib/action_controller/new_base/url_for.rb index af5b21012b..94de9fab50 100644 --- a/actionpack/lib/action_controller/new_base/url_for.rb +++ b/actionpack/lib/action_controller/new_base/url_for.rb @@ -1,5 +1,10 @@ module ActionController module UrlFor + def process_action(*) + initialize_current_url + super + end + def initialize_current_url @url = UrlRewriter.new(request, params.clone) end -- cgit v1.2.3 From 0029d5e5943dd20d38485ac7127cc150659da9e5 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 11 May 2009 23:04:39 -0400 Subject: Integrating Rack::MockSession (from Rack::Test) --- .../lib/action_controller/testing/integration.rb | 25 +++++++++++----------- actionpack/test/controller/integration_test.rb | 6 +++--- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/actionpack/lib/action_controller/testing/integration.rb b/actionpack/lib/action_controller/testing/integration.rb index a8e8f16d6c..31afd54258 100644 --- a/actionpack/lib/action_controller/testing/integration.rb +++ b/actionpack/lib/action_controller/testing/integration.rb @@ -1,6 +1,8 @@ require 'stringio' require 'uri' require 'active_support/test_case' +require 'rack/test' +require 'rack/mock_session' module ActionController module Integration #:nodoc: @@ -121,6 +123,8 @@ module ActionController # IntegrationTest#open_session, rather than instantiating # Integration::Session directly. class Session + DEFAULT_HOST = "www.example.com" + include Test::Unit::Assertions include ActionDispatch::Assertions include ActionController::TestProcess @@ -145,7 +149,9 @@ module ActionController # A map of the cookies returned by the last response, and which will be # sent with the next request. - attr_reader :cookies + def cookies + @mock_session.cookie_jar + end # A reference to the controller instance used by the last request. attr_reader :controller @@ -172,11 +178,11 @@ module ActionController # session.reset! def reset! @https = false - @cookies = {} + @mock_session = Rack::MockSession.new(@app, DEFAULT_HOST) @controller = @request = @response = nil @request_count = 0 - self.host = "www.example.com" + self.host = DEFAULT_HOST self.remote_addr = "127.0.0.1" self.accept = "text/xml,application/xml,application/xhtml+xml," + "text/html;q=0.9,text/plain;q=0.8,image/png," + @@ -227,6 +233,7 @@ module ActionController end private + # Performs the actual request. def process(method, path, parameters = nil, rack_environment = nil) if path =~ %r{://} @@ -258,10 +265,7 @@ module ActionController "HTTP_HOST" => host, "REMOTE_ADDR" => remote_addr, "CONTENT_TYPE" => "application/x-www-form-urlencoded", - "HTTP_ACCEPT" => accept, - "HTTP_COOKIE" => cookies.inject("") { |string, (name, value)| - string << "#{name}=#{value}; " - } + "HTTP_ACCEPT" => accept } env = Rack::MockRequest.env_for(path, opts) @@ -269,15 +273,12 @@ module ActionController env[key] = value end - app = Rack::Lint.new(@app) - status, headers, body = app.call(env) - mock_response = ::Rack::MockResponse.new(status, headers, body) + @mock_session.request(URI.parse(path), env) @request_count += 1 @request = ActionDispatch::Request.new(env) - @response = ActionDispatch::TestResponse.from_response(mock_response) + @response = ActionDispatch::TestResponse.from_response(@mock_session.last_response) - @cookies.merge!(@response.cookies) @html_document = nil if @controller = ActionController::Base.last_instantiation diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index a2b3ad2106..eae6835714 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -253,7 +253,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest assert_response 200 assert_response :success assert_response :ok - assert_equal({}, cookies) + assert_equal({}, cookies.to_hash) assert_equal "OK", body assert_equal "OK", response.body assert_kind_of HTML::Document, html_document @@ -269,7 +269,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest assert_response 201 assert_response :success assert_response :created - assert_equal({}, cookies) + assert_equal({}, cookies.to_hash) assert_equal "Created", body assert_equal "Created", response.body assert_kind_of HTML::Document, html_document @@ -287,7 +287,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest assert_response 410 assert_response :gone assert_equal "cookie_1=; path=/\ncookie_3=chocolate; path=/", headers["Set-Cookie"] - assert_equal({"cookie_1"=>nil, "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate"}, cookies) + assert_equal({"cookie_1"=>"", "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate"}, cookies.to_hash) assert_equal "Gone", response.body end end -- cgit v1.2.3 From df0faea378034b031f49995f06c8bf108a0b5530 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Tue, 12 May 2009 01:37:19 -0400 Subject: Refactor ActionController instantiation capture --- .../lib/action_controller/testing/integration.rb | 24 +++++++++------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/actionpack/lib/action_controller/testing/integration.rb b/actionpack/lib/action_controller/testing/integration.rb index 31afd54258..717b77674c 100644 --- a/actionpack/lib/action_controller/testing/integration.rb +++ b/actionpack/lib/action_controller/testing/integration.rb @@ -249,8 +249,6 @@ module ActionController end end - ActionController::Base.clear_last_instantiation! - opts = { :method => method, :params => parameters, @@ -273,18 +271,15 @@ module ActionController env[key] = value end - @mock_session.request(URI.parse(path), env) + @controller = ActionController::Base.capture_instantiation do + @mock_session.request(URI.parse(path), env) + end @request_count += 1 @request = ActionDispatch::Request.new(env) @response = ActionDispatch::TestResponse.from_response(@mock_session.last_response) - @html_document = nil - if @controller = ActionController::Base.last_instantiation - @controller.send(:set_test_assigns) - end - return response.status end @@ -305,11 +300,10 @@ module ActionController # A module used to extend ActionController::Base, so that integration tests # can capture the controller used to satisfy a request. module ControllerCapture #:nodoc: - def self.included(base) - base.extend(ClassMethods) - base.class_eval do - alias_method_chain :initialize, :capture - end + extend ActiveSupport::DependencyModule + + included do + alias_method_chain :initialize, :capture end def initialize_with_capture(*args) @@ -320,8 +314,10 @@ module ActionController module ClassMethods #:nodoc: mattr_accessor :last_instantiation - def clear_last_instantiation! + def capture_instantiation self.last_instantiation = nil + yield + return last_instantiation end end end -- cgit v1.2.3 From 6761759a90c08b9db8d5720a8ee4c4329a547caf Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 19 May 2009 22:42:59 -0500 Subject: Temporarily bundle rack-test while MockSession is baking --- .../lib/action_controller/testing/integration.rb | 3 +- actionpack/lib/action_dispatch.rb | 2 + .../vendor/rack-test/rack/mock_session.rb | 50 +++++ .../action_dispatch/vendor/rack-test/rack/test.rb | 239 +++++++++++++++++++++ .../vendor/rack-test/rack/test/cookie_jar.rb | 169 +++++++++++++++ .../vendor/rack-test/rack/test/methods.rb | 45 ++++ .../rack-test/rack/test/mock_digest_request.rb | 27 +++ .../vendor/rack-test/rack/test/uploaded_file.rb | 36 ++++ .../vendor/rack-test/rack/test/utils.rb | 75 +++++++ 9 files changed, 645 insertions(+), 1 deletion(-) create mode 100644 actionpack/lib/action_dispatch/vendor/rack-test/rack/mock_session.rb create mode 100644 actionpack/lib/action_dispatch/vendor/rack-test/rack/test.rb create mode 100644 actionpack/lib/action_dispatch/vendor/rack-test/rack/test/cookie_jar.rb create mode 100644 actionpack/lib/action_dispatch/vendor/rack-test/rack/test/methods.rb create mode 100644 actionpack/lib/action_dispatch/vendor/rack-test/rack/test/mock_digest_request.rb create mode 100644 actionpack/lib/action_dispatch/vendor/rack-test/rack/test/uploaded_file.rb create mode 100644 actionpack/lib/action_dispatch/vendor/rack-test/rack/test/utils.rb diff --git a/actionpack/lib/action_controller/testing/integration.rb b/actionpack/lib/action_controller/testing/integration.rb index 717b77674c..cc157816e2 100644 --- a/actionpack/lib/action_controller/testing/integration.rb +++ b/actionpack/lib/action_controller/testing/integration.rb @@ -1,8 +1,9 @@ require 'stringio' require 'uri' require 'active_support/test_case' -require 'rack/test' + require 'rack/mock_session' +require 'rack/test/cookie_jar' module ActionController module Integration #:nodoc: diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 6fc4ad3f21..f9003c51ea 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -33,6 +33,8 @@ end require 'rack' +$:.unshift "#{File.dirname(__FILE__)}/action_dispatch/vendor/rack-test" + module ActionDispatch autoload :Request, 'action_dispatch/http/request' autoload :Response, 'action_dispatch/http/response' diff --git a/actionpack/lib/action_dispatch/vendor/rack-test/rack/mock_session.rb b/actionpack/lib/action_dispatch/vendor/rack-test/rack/mock_session.rb new file mode 100644 index 0000000000..eba6226538 --- /dev/null +++ b/actionpack/lib/action_dispatch/vendor/rack-test/rack/mock_session.rb @@ -0,0 +1,50 @@ +module Rack + + class MockSession + attr_writer :cookie_jar + attr_reader :last_response + + def initialize(app, default_host = Rack::Test::DEFAULT_HOST) + @app = app + @default_host = default_host + end + + def clear_cookies + @cookie_jar = Rack::Test::CookieJar.new([], @default_host) + end + + def set_cookie(cookie, uri = nil) + cookie_jar.merge(cookie, uri) + end + + def request(uri, env) + env["HTTP_COOKIE"] ||= cookie_jar.for(uri) + @last_request = Rack::Request.new(env) + status, headers, body = @app.call(@last_request.env) + @last_response = MockResponse.new(status, headers, body, env["rack.errors"].flush) + cookie_jar.merge(last_response.headers["Set-Cookie"], uri) + + @last_response + end + + # Return the last request issued in the session. Raises an error if no + # requests have been sent yet. + def last_request + raise Rack::Test::Error.new("No request yet. Request a page first.") unless @last_request + @last_request + end + + # Return the last response received in the session. Raises an error if + # no requests have been sent yet. + def last_response + raise Rack::Test::Error.new("No response yet. Request a page first.") unless @last_response + @last_response + end + + def cookie_jar + @cookie_jar ||= Rack::Test::CookieJar.new([], @default_host) + end + + end + +end diff --git a/actionpack/lib/action_dispatch/vendor/rack-test/rack/test.rb b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test.rb new file mode 100644 index 0000000000..70384b1d76 --- /dev/null +++ b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test.rb @@ -0,0 +1,239 @@ +unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__) + "/..")) + $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/..")) +end + +require "uri" +require "rack" +require "rack/mock_session" +require "rack/test/cookie_jar" +require "rack/test/mock_digest_request" +require "rack/test/utils" +require "rack/test/methods" +require "rack/test/uploaded_file" + +module Rack + module Test + + VERSION = "0.3.0" + + DEFAULT_HOST = "example.org" + MULTIPART_BOUNDARY = "----------XnJLe9ZIbbGUYtzPQJ16u1" + + # The common base class for exceptions raised by Rack::Test + class Error < StandardError; end + + class Session + extend Forwardable + include Rack::Test::Utils + + def_delegators :@rack_mock_session, :clear_cookies, :set_cookie, :last_response, :last_request + + # Initialize a new session for the given Rack app + def initialize(app, default_host = DEFAULT_HOST) + @headers = {} + @default_host = default_host + @rack_mock_session = Rack::MockSession.new(app, default_host) + end + + # Issue a GET request for the given URI with the given params and Rack + # environment. Stores the issues request object in #last_request and + # the app's response in #last_response. Yield #last_response to a block + # if given. + # + # Example: + # get "/" + def get(uri, params = {}, env = {}, &block) + env = env_for(uri, env.merge(:method => "GET", :params => params)) + process_request(uri, env, &block) + end + + # Issue a POST request for the given URI. See #get + # + # Example: + # post "/signup", "name" => "Bryan" + def post(uri, params = {}, env = {}, &block) + env = env_for(uri, env.merge(:method => "POST", :params => params)) + process_request(uri, env, &block) + end + + # Issue a PUT request for the given URI. See #get + # + # Example: + # put "/" + def put(uri, params = {}, env = {}, &block) + env = env_for(uri, env.merge(:method => "PUT", :params => params)) + process_request(uri, env, &block) + end + + # Issue a DELETE request for the given URI. See #get + # + # Example: + # delete "/" + def delete(uri, params = {}, env = {}, &block) + env = env_for(uri, env.merge(:method => "DELETE", :params => params)) + process_request(uri, env, &block) + end + + # Issue a HEAD request for the given URI. See #get + # + # Example: + # head "/" + def head(uri, params = {}, env = {}, &block) + env = env_for(uri, env.merge(:method => "HEAD", :params => params)) + process_request(uri, env, &block) + end + + # Issue a request to the Rack app for the given URI and optional Rack + # environment. Stores the issues request object in #last_request and + # the app's response in #last_response. Yield #last_response to a block + # if given. + # + # Example: + # request "/" + def request(uri, env = {}, &block) + env = env_for(uri, env) + process_request(uri, env, &block) + end + + # Set a header to be included on all subsequent requests through the + # session. Use a value of nil to remove a previously configured header. + # + # Example: + # header "User-Agent", "Firefox" + def header(name, value) + if value.nil? + @headers.delete(name) + else + @headers[name] = value + end + end + + # Set the username and password for HTTP Basic authorization, to be + # included in subsequent requests in the HTTP_AUTHORIZATION header. + # + # Example: + # basic_authorize "bryan", "secret" + def basic_authorize(username, password) + encoded_login = ["#{username}:#{password}"].pack("m*") + header('HTTP_AUTHORIZATION', "Basic #{encoded_login}") + end + + alias_method :authorize, :basic_authorize + + def digest_authorize(username, password) + @digest_username = username + @digest_password = password + end + + # Rack::Test will not follow any redirects automatically. This method + # will follow the redirect returned in the last response. If the last + # response was not a redirect, an error will be raised. + def follow_redirect! + unless last_response.redirect? + raise Error.new("Last response was not a redirect. Cannot follow_redirect!") + end + + get(last_response["Location"]) + end + + private + + def env_for(path, env) + uri = URI.parse(path) + uri.host ||= @default_host + + env = default_env.merge(env) + + env.update("HTTPS" => "on") if URI::HTTPS === uri + env["X-Requested-With"] = "XMLHttpRequest" if env[:xhr] + + if (env[:method] == "POST" || env["REQUEST_METHOD"] == "POST") && !env.has_key?(:input) + env["CONTENT_TYPE"] = "application/x-www-form-urlencoded" + + multipart = (Hash === env[:params]) && + env[:params].any? { |_, v| UploadedFile === v } + + if multipart + env[:input] = multipart_body(env.delete(:params)) + env["CONTENT_LENGTH"] ||= env[:input].length.to_s + env["CONTENT_TYPE"] = "multipart/form-data; boundary=#{MULTIPART_BOUNDARY}" + else + env[:input] = params_to_string(env.delete(:params)) + end + end + + params = env[:params] || {} + params.update(parse_query(uri.query)) + + uri.query = requestify(params) + + if env.has_key?(:cookie) + set_cookie(env.delete(:cookie), uri) + end + + Rack::MockRequest.env_for(uri.to_s, env) + end + + def process_request(uri, env) + uri = URI.parse(uri) + uri.host ||= @default_host + + @rack_mock_session.request(uri, env) + + if retry_with_digest_auth?(env) + auth_env = env.merge({ + "HTTP_AUTHORIZATION" => digest_auth_header, + "rack-test.digest_auth_retry" => true + }) + auth_env.delete('rack.request') + process_request(uri.path, auth_env) + else + yield last_response if block_given? + + last_response + end + end + + def digest_auth_header + challenge = last_response["WWW-Authenticate"].split(" ", 2).last + params = Rack::Auth::Digest::Params.parse(challenge) + + params.merge!({ + "username" => @digest_username, + "nc" => "00000001", + "cnonce" => "nonsensenonce", + "uri" => last_request.path_info, + "method" => last_request.env["REQUEST_METHOD"], + }) + + params["response"] = MockDigestRequest.new(params).response(@digest_password) + + "Digest #{params}" + end + + def retry_with_digest_auth?(env) + last_response.status == 401 && + digest_auth_configured? && + !env["rack-test.digest_auth_retry"] + end + + def digest_auth_configured? + @digest_username + end + + def default_env + { "rack.test" => true, "REMOTE_ADDR" => "127.0.0.1" }.merge(@headers) + end + + def params_to_string(params) + case params + when Hash then requestify(params) + when nil then "" + else params + end + end + + end + + end +end diff --git a/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/cookie_jar.rb b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/cookie_jar.rb new file mode 100644 index 0000000000..d58c914c9b --- /dev/null +++ b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/cookie_jar.rb @@ -0,0 +1,169 @@ +require "uri" +module Rack + module Test + + class Cookie + include Rack::Utils + + # :api: private + attr_reader :name, :value + + # :api: private + def initialize(raw, uri = nil, default_host = DEFAULT_HOST) + @default_host = default_host + uri ||= default_uri + + # separate the name / value pair from the cookie options + @name_value_raw, options = raw.split(/[;,] */n, 2) + + @name, @value = parse_query(@name_value_raw, ';').to_a.first + @options = parse_query(options, ';') + + @options["domain"] ||= (uri.host || default_host) + @options["path"] ||= uri.path.sub(/\/[^\/]*\Z/, "") + end + + def replaces?(other) + [name.downcase, domain, path] == [other.name.downcase, other.domain, other.path] + end + + # :api: private + def raw + @name_value_raw + end + + # :api: private + def empty? + @value.nil? || @value.empty? + end + + # :api: private + def domain + @options["domain"] + end + + def secure? + @options.has_key?("secure") + end + + # :api: private + def path + @options["path"].strip || "/" + end + + # :api: private + def expires + Time.parse(@options["expires"]) if @options["expires"] + end + + # :api: private + def expired? + expires && expires < Time.now + end + + # :api: private + def valid?(uri) + uri ||= default_uri + + if uri.host.nil? + uri.host = @default_host + end + + (!secure? || (secure? && uri.scheme == "https")) && + uri.host =~ Regexp.new("#{Regexp.escape(domain)}$", Regexp::IGNORECASE) && + uri.path =~ Regexp.new("^#{Regexp.escape(path)}") + end + + # :api: private + def matches?(uri) + ! expired? && valid?(uri) + end + + # :api: private + def <=>(other) + # Orders the cookies from least specific to most + [name, path, domain.reverse] <=> [other.name, other.path, other.domain.reverse] + end + + protected + + def default_uri + URI.parse("//" + @default_host + "/") + end + + end + + class CookieJar + + # :api: private + def initialize(cookies = [], default_host = DEFAULT_HOST) + @default_host = default_host + @cookies = cookies + @cookies.sort! + end + + def [](name) + cookies = hash_for(nil) + # TODO: Should be case insensitive + cookies[name] && cookies[name].value + end + + def []=(name, value) + # TODO: needs proper escaping + merge("#{name}=#{value}") + end + + def merge(raw_cookies, uri = nil) + return unless raw_cookies + + raw_cookies.each_line do |raw_cookie| + cookie = Cookie.new(raw_cookie, uri, @default_host) + self << cookie if cookie.valid?(uri) + end + end + + def <<(new_cookie) + @cookies.reject! do |existing_cookie| + new_cookie.replaces?(existing_cookie) + end + + @cookies << new_cookie + @cookies.sort! + end + + # :api: private + def for(uri) + hash_for(uri).values.map { |c| c.raw }.join(';') + end + + def to_hash + cookies = {} + + hash_for(nil).each do |name, cookie| + cookies[name] = cookie.value + end + + return cookies + end + + protected + + def hash_for(uri = nil) + cookies = {} + + # The cookies are sorted by most specific first. So, we loop through + # all the cookies in order and add it to a hash by cookie name if + # the cookie can be sent to the current URI. It's added to the hash + # so that when we are done, the cookies will be unique by name and + # we'll have grabbed the most specific to the URI. + @cookies.each do |cookie| + cookies[cookie.name] = cookie if cookie.matches?(uri) + end + + return cookies + end + + end + + end +end diff --git a/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/methods.rb b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/methods.rb new file mode 100644 index 0000000000..a191fa23d8 --- /dev/null +++ b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/methods.rb @@ -0,0 +1,45 @@ +require "forwardable" + +module Rack + module Test + module Methods + extend Forwardable + + def rack_test_session + @_rack_test_session ||= Rack::Test::Session.new(app) + end + + def rack_mock_session + @_rack_mock_session ||= Rack::MockSession.new(app) + end + + METHODS = [ + :request, + + # HTTP verbs + :get, + :post, + :put, + :delete, + :head, + + # Redirects + :follow_redirect!, + + # Header-related features + :header, + :set_cookie, + :clear_cookies, + :authorize, + :basic_authorize, + :digest_authorize, + + # Expose the last request and response + :last_response, + :last_request + ] + + def_delegators :rack_test_session, *METHODS + end + end +end diff --git a/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/mock_digest_request.rb b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/mock_digest_request.rb new file mode 100644 index 0000000000..81c398ba51 --- /dev/null +++ b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/mock_digest_request.rb @@ -0,0 +1,27 @@ +module Rack + module Test + + class MockDigestRequest + def initialize(params) + @params = params + end + + def method_missing(sym) + if @params.has_key? k = sym.to_s + return @params[k] + end + + super + end + + def method + @params['method'] + end + + def response(password) + Rack::Auth::Digest::MD5.new(nil).send :digest, self, password + end + end + + end +end diff --git a/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/uploaded_file.rb b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/uploaded_file.rb new file mode 100644 index 0000000000..239302fbe4 --- /dev/null +++ b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/uploaded_file.rb @@ -0,0 +1,36 @@ +require "tempfile" + +module Rack + module Test + + class UploadedFile + # The filename, *not* including the path, of the "uploaded" file + attr_reader :original_filename + + # The content type of the "uploaded" file + attr_accessor :content_type + + def initialize(path, content_type = "text/plain", binary = false) + raise "#{path} file does not exist" unless ::File.exist?(path) + @content_type = content_type + @original_filename = ::File.basename(path) + @tempfile = Tempfile.new(@original_filename) + @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding) + @tempfile.binmode if binary + FileUtils.copy_file(path, @tempfile.path) + end + + def path + @tempfile.path + end + + alias_method :local_path, :path + + def method_missing(method_name, *args, &block) #:nodoc: + @tempfile.__send__(method_name, *args, &block) + end + + end + + end +end diff --git a/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/utils.rb b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/utils.rb new file mode 100644 index 0000000000..d25b849709 --- /dev/null +++ b/actionpack/lib/action_dispatch/vendor/rack-test/rack/test/utils.rb @@ -0,0 +1,75 @@ +module Rack + module Test + + module Utils + include Rack::Utils + + def requestify(value, prefix = nil) + case value + when Array + value.map do |v| + requestify(v, "#{prefix}[]") + end.join("&") + when Hash + value.map do |k, v| + requestify(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k)) + end.join("&") + else + "#{prefix}=#{escape(value)}" + end + end + + module_function :requestify + + def multipart_requestify(params, first=true) + p = Hash.new + + params.each do |key, value| + k = first ? key.to_s : "[#{key}]" + + if Hash === value + multipart_requestify(value, false).each do |subkey, subvalue| + p[k + subkey] = subvalue + end + else + p[k] = value + end + end + + return p + end + + module_function :multipart_requestify + + def multipart_body(params) + multipart_requestify(params).map do |key, value| + if value.respond_to?(:original_filename) + ::File.open(value.path, "rb") do |f| + f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding) + + <<-EOF +--#{MULTIPART_BOUNDARY}\r +Content-Disposition: form-data; name="#{key}"; filename="#{escape(value.original_filename)}"\r +Content-Type: #{value.content_type}\r +Content-Length: #{::File.stat(value.path).size}\r +\r +#{f.read}\r +EOF + end + else +<<-EOF +--#{MULTIPART_BOUNDARY}\r +Content-Disposition: form-data; name="#{key}"\r +\r +#{value}\r +EOF + end + end.join("")+"--#{MULTIPART_BOUNDARY}--\r" + end + + module_function :multipart_body + + end + + end +end -- cgit v1.2.3 From c03b0ca7eb7e73587005e1440bf90cd01ed10aa5 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 20 May 2009 21:15:06 +0200 Subject: Replace the class level Rack::Test DSL with the regular integration tests DSL --- actionpack/test/new_base/base_test.rb | 80 ++--- actionpack/test/new_base/content_type_test.rb | 120 +++---- actionpack/test/new_base/etag_test.rb | 23 +- actionpack/test/new_base/render_action_test.rb | 388 ++++++++++----------- .../test/new_base/render_implicit_action_test.rb | 28 +- actionpack/test/new_base/render_layout_test.rb | 64 ++-- actionpack/test/new_base/render_template_test.rb | 87 +++-- actionpack/test/new_base/render_test.rb | 45 ++- actionpack/test/new_base/render_text_test.rb | 151 ++++---- actionpack/test/new_base/test_helper.rb | 55 +-- 10 files changed, 477 insertions(+), 564 deletions(-) diff --git a/actionpack/test/new_base/base_test.rb b/actionpack/test/new_base/base_test.rb index a32653f128..d9d552f9e5 100644 --- a/actionpack/test/new_base/base_test.rb +++ b/actionpack/test/new_base/base_test.rb @@ -10,78 +10,60 @@ module Dispatching def modify_response_body self.response_body = "success" end - + def modify_response_body_twice ret = (self.response_body = "success") self.response_body = "#{ret}!" end - + def modify_response_headers - end end - - class TestSimpleDispatch < SimpleRouteCase - - get "/dispatching/simple/index" - - test "sets the body" do + + class EmptyController < ActionController::Base ; end + + module Submodule + class ContainedEmptyController < ActionController::Base ; end + end + + class BaseTest < SimpleRouteCase + # :api: plugin + test "simple dispatching" do + get "/dispatching/simple/index" + assert_body "success" - end - - test "sets the status code" do assert_status 200 - end - - test "sets the content type" do assert_content_type "text/html; charset=utf-8" - end - - test "sets the content length" do assert_header "Content-Length", "7" end - - end - - # :api: plugin - class TestDirectResponseMod < SimpleRouteCase - get "/dispatching/simple/modify_response_body" - - test "sets the body" do + + # :api: plugin + test "directly modifying response body" do + get "/dispatching/simple/modify_response_body" + assert_body "success" + assert_header "Content-Length", "7" # setting the body manually sets the content length end - - test "setting the body manually sets the content length" do - assert_header "Content-Length", "7" - end - end - - # :api: plugin - class TestDirectResponseModTwice < SimpleRouteCase - get "/dispatching/simple/modify_response_body_twice" - - test "self.response_body= returns the body being set" do + + # :api: plugin + test "directly modifying response body twice" do + get "/dispatching/simple/modify_response_body_twice" + assert_body "success!" - end - - test "updating the response body updates the content length" do assert_header "Content-Length", "8" end - end - - class EmptyController < ActionController::Base ; end - module Submodule - class ContainedEmptyController < ActionController::Base ; end - end - class ControllerClassTests < Test::Unit::TestCase - def test_controller_path + test "controller path" do assert_equal 'dispatching/empty', EmptyController.controller_path assert_equal EmptyController.controller_path, EmptyController.new.controller_path + end + + test "namespaced controller path" do assert_equal 'dispatching/submodule/contained_empty', Submodule::ContainedEmptyController.controller_path assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path end - def test_controller_name + + test "controller name" do assert_equal 'empty', EmptyController.controller_name assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name end diff --git a/actionpack/test/new_base/content_type_test.rb b/actionpack/test/new_base/content_type_test.rb index a5c04e9cb6..82b817a5a3 100644 --- a/actionpack/test/new_base/content_type_test.rb +++ b/actionpack/test/new_base/content_type_test.rb @@ -5,107 +5,107 @@ module ContentType def index render :text => "Hello world!" end - + def set_on_response_obj response.content_type = Mime::RSS render :text => "Hello world!" end - + def set_on_render render :text => "Hello world!", :content_type => Mime::RSS end end - - class TestDefault < SimpleRouteCase - describe "a default response is HTML and UTF8" - - get "/content_type/base" - assert_body "Hello world!" - assert_header "Content-Type", "text/html; charset=utf-8" - end - - class TestSetOnResponseObj < SimpleRouteCase - describe "setting the content type of the response directly on the response object" - - get "/content_type/base/set_on_response_obj" - assert_body "Hello world!" - assert_header "Content-Type", "application/rss+xml; charset=utf-8" - end - - class TestSetOnRender < SimpleRouteCase - describe "setting the content type of the response as an option to render" - - get "/content_type/base/set_on_render" - assert_body "Hello world!" - assert_header "Content-Type", "application/rss+xml; charset=utf-8" - end - + class ImpliedController < ActionController::Base + # Template's mime type is used if no content_type is specified + self.view_paths = [ActionView::Template::FixturePath.new( "content_type/implied/i_am_html_erb.html.erb" => "Hello world!", "content_type/implied/i_am_xml_erb.xml.erb" => "Hello world!", "content_type/implied/i_am_html_builder.html.builder" => "xml.p 'Hello'", "content_type/implied/i_am_xml_builder.xml.builder" => "xml.awesome 'Hello'" )] - + def i_am_html_erb() end def i_am_xml_erb() end def i_am_html_builder() end def i_am_xml_builder() end end - - class TestImpliedController < SimpleRouteCase - describe "the template's mime type is used if no content_type is specified" - + + class CharsetController < ActionController::Base + def set_on_response_obj + response.charset = "utf-16" + render :text => "Hello world!" + end + + def set_as_nil_on_response_obj + response.charset = nil + render :text => "Hello world!" + end + end + + class ExplicitContentTypeTest < SimpleRouteCase + test "default response is HTML and UTF8" do + get "/content_type/base" + + assert_body "Hello world!" + assert_header "Content-Type", "text/html; charset=utf-8" + end + + test "setting the content type of the response directly on the response object" do + get "/content_type/base/set_on_response_obj" + + assert_body "Hello world!" + assert_header "Content-Type", "application/rss+xml; charset=utf-8" + end + + test "setting the content type of the response as an option to render" do + get "/content_type/base/set_on_render" + + assert_body "Hello world!" + assert_header "Content-Type", "application/rss+xml; charset=utf-8" + end + end + + class ImpliedContentTypeTest < SimpleRouteCase test "sets Content-Type as text/html when rendering *.html.erb" do get "/content_type/implied/i_am_html_erb" + assert_header "Content-Type", "text/html; charset=utf-8" end test "sets Content-Type as application/xml when rendering *.xml.erb" do get "/content_type/implied/i_am_xml_erb" + assert_header "Content-Type", "application/xml; charset=utf-8" end test "sets Content-Type as text/html when rendering *.html.builder" do get "/content_type/implied/i_am_html_builder" + assert_header "Content-Type", "text/html; charset=utf-8" end test "sets Content-Type as application/xml when rendering *.xml.builder" do get "/content_type/implied/i_am_xml_builder" + assert_header "Content-Type", "application/xml; charset=utf-8" end - end -end -module Charset - class BaseController < ActionController::Base - def set_on_response_obj - response.charset = "utf-16" - render :text => "Hello world!" + class ExplicitCharsetTest < SimpleRouteCase + test "setting the charset of the response directly on the response object" do + get "/content_type/charset/set_on_response_obj" + + assert_body "Hello world!" + assert_header "Content-Type", "text/html; charset=utf-16" end - - def set_as_nil_on_response_obj - response.charset = nil - render :text => "Hello world!" + + test "setting the charset of the response as nil directly on the response object" do + get "/content_type/charset/set_as_nil_on_response_obj" + + assert_body "Hello world!" + assert_header "Content-Type", "text/html; charset=utf-8" end end - - class TestSetOnResponseObj < SimpleRouteCase - describe "setting the charset of the response directly on the response object" - - get "/charset/base/set_on_response_obj" - assert_body "Hello world!" - assert_header "Content-Type", "text/html; charset=utf-16" - end - - class TestSetAsNilOnResponseObj < SimpleRouteCase - describe "setting the charset of the response as nil directly on the response object" - - get "/charset/base/set_as_nil_on_response_obj" - assert_body "Hello world!" - assert_header "Content-Type", "text/html; charset=utf-8" - end -end \ No newline at end of file +end diff --git a/actionpack/test/new_base/etag_test.rb b/actionpack/test/new_base/etag_test.rb index 7af5febfb3..c77636bb64 100644 --- a/actionpack/test/new_base/etag_test.rb +++ b/actionpack/test/new_base/etag_test.rb @@ -1,47 +1,46 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module Etags - class BasicController < ActionController::Base - self.view_paths = [ActionView::Template::FixturePath.new( "etags/basic/base.html.erb" => "Hello from without_layout.html.erb", "layouts/etags.html.erb" => "teh <%= yield %> tagz" )] - + def without_layout render :action => "base" end - + def with_layout render :action => "base", :layout => "etag" end - end - - class TestBasic < SimpleRouteCase + + class EtagTest < SimpleRouteCase describe "Rendering without any special etag options returns an etag that is an MD5 hash of its text" - + test "an action without a layout" do get "/etags/basic/without_layout" + body = "Hello from without_layout.html.erb" assert_body body assert_header "Etag", etag_for(body) assert_status 200 end - + test "an action with a layout" do get "/etags/basic/with_layout" + body = "teh Hello from without_layout.html.erb tagz" assert_body body assert_header "Etag", etag_for(body) assert_status 200 end - + + private + def etag_for(text) %("#{Digest::MD5.hexdigest(text)}") end end - - end \ No newline at end of file diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/new_base/render_action_test.rb index 626c7b3540..4402eadf42 100644 --- a/actionpack/test/new_base/render_action_test.rb +++ b/actionpack/test/new_base/render_action_test.rb @@ -1,26 +1,24 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module RenderAction - # This has no layout and it works class BasicController < ActionController::Base - self.view_paths = [ActionView::Template::FixturePath.new( "render_action/basic/hello_world.html.erb" => "Hello world!" )] - + def hello_world render :action => "hello_world" end - + def hello_world_as_string render "hello_world" end - + def hello_world_as_string_with_options render "hello_world", :status => 404 end - + def hello_world_as_symbol render :hello_world end @@ -28,107 +26,95 @@ module RenderAction def hello_world_with_symbol render :action => :hello_world end - + def hello_world_with_layout render :action => "hello_world", :layout => true end - + def hello_world_with_layout_false render :action => "hello_world", :layout => false end - + def hello_world_with_layout_nil render :action => "hello_world", :layout => nil end - + def hello_world_with_custom_layout render :action => "hello_world", :layout => "greetings" end - - end - - class TestBasic < SimpleRouteCase - describe "Rendering an action using :action => " - - get "/render_action/basic/hello_world" - assert_body "Hello world!" - assert_status 200 - end - - class TestWithString < SimpleRouteCase - describe "Render an action using 'hello_world'" - - get "/render_action/basic/hello_world_as_string" - assert_body "Hello world!" - assert_status 200 - end - - class TestWithStringAndOptions < SimpleRouteCase - describe "Render an action using 'hello_world'" - - get "/render_action/basic/hello_world_as_string_with_options" - assert_body "Hello world!" - assert_status 404 - end - - class TestAsSymbol < SimpleRouteCase - describe "Render an action using :hello_world" - - get "/render_action/basic/hello_world_as_symbol" - assert_body "Hello world!" - assert_status 200 + end - - class TestWithSymbol < SimpleRouteCase - describe "Render an action using :action => :hello_world" - - get "/render_action/basic/hello_world_with_symbol" - assert_body "Hello world!" - assert_status 200 + + class RenderActionTest < SimpleRouteCase + test "rendering an action using :action => " do + get "/render_action/basic/hello_world" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering an action using ''" do + get "/render_action/basic/hello_world_as_string" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering an action using '' and options" do + get "/render_action/basic/hello_world_as_string_with_options" + + assert_body "Hello world!" + assert_status 404 + end + + test "rendering an action using :action" do + get "/render_action/basic/hello_world_as_symbol" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering an action using :action => :hello_world" do + get "/render_action/basic/hello_world_with_symbol" + + assert_body "Hello world!" + assert_status 200 + end end - - class TestLayoutTrue < SimpleRouteCase - describe "rendering a normal template with full path with layout => true" - - test "raises an exception when requesting a layout and none exist" do - assert_raise(ArgumentError, /no default layout for RenderAction::BasicController in/) do + + class RenderLayoutTest < SimpleRouteCase + describe "Both .html.erb and application.html.erb are missing" + + test "rendering with layout => true" do + assert_raise(ArgumentError, /no default layout for RenderAction::BasicController in/) do get "/render_action/basic/hello_world_with_layout", {}, "action_dispatch.show_exceptions" => false end end - end - - class TestLayoutFalse < SimpleRouteCase - describe "rendering a normal template with full path with layout => false" - - get "/render_action/basic/hello_world_with_layout_false" - assert_body "Hello world!" - assert_status 200 - end - - class TestLayoutNil < SimpleRouteCase - describe "rendering a normal template with full path with layout => :nil" - - get "/render_action/basic/hello_world_with_layout_nil" - assert_body "Hello world!" - assert_status 200 - end - - class TestCustomLayout < SimpleRouteCase - describe "rendering a normal template with full path with layout => 'greetings'" - - test "raises an exception when requesting a layout that does not exist" do + + test "rendering with layout => false" do + get "/render_action/basic/hello_world_with_layout_false" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_action/basic/hello_world_with_layout_nil" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering with layout => 'greetings'" do assert_raise(ActionView::MissingTemplate) do get "/render_action/basic/hello_world_with_custom_layout", {}, "action_dispatch.show_exceptions" => false end end end - end module RenderActionWithApplicationLayout - # # ==== Render actions with layouts ==== - class BasicController < ::ApplicationController # Set the view path to an application view structure with layouts self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new( @@ -138,205 +124,197 @@ module RenderActionWithApplicationLayout "layouts/greetings.html.erb" => "Greetings <%= yield %> Bai", "layouts/builder.html.builder" => "xml.html do\n xml << yield\nend" )] - + def hello_world render :action => "hello_world" end - + def hello_world_with_layout render :action => "hello_world", :layout => true end - + def hello_world_with_layout_false render :action => "hello_world", :layout => false end - + def hello_world_with_layout_nil render :action => "hello_world", :layout => nil end - + def hello_world_with_custom_layout render :action => "hello_world", :layout => "greetings" end - + def with_builder_and_layout render :action => "hello", :layout => "builder" end end - - class TestDefaultLayout < SimpleRouteCase - describe %( - Render hello_world and implicitly use application.html.erb as a layout if - no layout is specified and no controller layout is present - ) - - get "/render_action_with_application_layout/basic/hello_world" - assert_body "OHAI Hello World! KTHXBAI" - assert_status 200 - end - - class TestLayoutTrue < SimpleRouteCase - describe "rendering a normal template with full path with layout => true" - - get "/render_action_with_application_layout/basic/hello_world_with_layout" - assert_body "OHAI Hello World! KTHXBAI" - assert_status 200 - end - - class TestLayoutFalse < SimpleRouteCase - describe "rendering a normal template with full path with layout => false" - - get "/render_action_with_application_layout/basic/hello_world_with_layout_false" - assert_body "Hello World!" - assert_status 200 - end - - class TestLayoutNil < SimpleRouteCase - describe "rendering a normal template with full path with layout => :nil" - - get "/render_action_with_application_layout/basic/hello_world_with_layout_nil" - assert_body "Hello World!" - assert_status 200 - end - - class TestCustomLayout < SimpleRouteCase - describe "rendering a normal template with full path with layout => 'greetings'" - - get "/render_action_with_application_layout/basic/hello_world_with_custom_layout" - assert_body "Greetings Hello World! Bai" - assert_status 200 + + class LayoutTest < SimpleRouteCase + describe "Only application.html.erb is present and .html.erb is missing" + + test "rendering implicit application.html.erb as layout" do + get "/render_action_with_application_layout/basic/hello_world" + + assert_body "OHAI Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => true" do + get "/render_action_with_application_layout/basic/hello_world_with_layout" + + assert_body "OHAI Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => false" do + get "/render_action_with_application_layout/basic/hello_world_with_layout_false" + + assert_body "Hello World!" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_action_with_application_layout/basic/hello_world_with_layout_nil" + + assert_body "Hello World!" + assert_status 200 + end + + test "rendering with layout => 'greetings'" do + get "/render_action_with_application_layout/basic/hello_world_with_custom_layout" + + assert_body "Greetings Hello World! Bai" + assert_status 200 + end end - + class TestLayout < SimpleRouteCase testing BasicController - + test "builder works with layouts" do get :with_builder_and_layout assert_response "\n

Omg

\n\n" end end - + end module RenderActionWithControllerLayout - class BasicController < ActionController::Base self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new( "render_action_with_controller_layout/basic/hello_world.html.erb" => "Hello World!", "layouts/render_action_with_controller_layout/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" )] - + def hello_world render :action => "hello_world" end - + def hello_world_with_layout render :action => "hello_world", :layout => true end - + def hello_world_with_layout_false render :action => "hello_world", :layout => false end - + def hello_world_with_layout_nil render :action => "hello_world", :layout => nil end - + def hello_world_with_custom_layout render :action => "hello_world", :layout => "greetings" end end - - class TestControllerLayout < SimpleRouteCase - describe "Render hello_world and implicitly use .html.erb as a layout." - get "/render_action_with_controller_layout/basic/hello_world" - assert_body "With Controller Layout! Hello World! KTHXBAI" - assert_status 200 - end - - class TestLayoutTrue < SimpleRouteCase - describe "rendering a normal template with full path with layout => true" - - get "/render_action_with_controller_layout/basic/hello_world_with_layout" - assert_body "With Controller Layout! Hello World! KTHXBAI" - assert_status 200 - end - - class TestLayoutFalse < SimpleRouteCase - describe "rendering a normal template with full path with layout => false" - - get "/render_action_with_controller_layout/basic/hello_world_with_layout_false" - assert_body "Hello World!" - assert_status 200 - end - - class TestLayoutNil < SimpleRouteCase - describe "rendering a normal template with full path with layout => :nil" - - get "/render_action_with_controller_layout/basic/hello_world_with_layout_nil" - assert_body "Hello World!" - assert_status 200 + class ControllerLayoutTest < SimpleRouteCase + describe "Only .html.erb is present and application.html.erb is missing" + + test "render hello_world and implicitly use .html.erb as a layout." do + get "/render_action_with_controller_layout/basic/hello_world" + + assert_body "With Controller Layout! Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => true" do + get "/render_action_with_controller_layout/basic/hello_world_with_layout" + + assert_body "With Controller Layout! Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => false" do + get "/render_action_with_controller_layout/basic/hello_world_with_layout_false" + + assert_body "Hello World!" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_action_with_controller_layout/basic/hello_world_with_layout_nil" + + assert_body "Hello World!" + assert_status 200 + end end - end module RenderActionWithBothLayouts - class BasicController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new({ "render_action_with_both_layouts/basic/hello_world.html.erb" => "Hello World!", "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", "layouts/render_action_with_both_layouts/basic.html.erb" => "With Controller Layout! <%= yield %> KTHXBAI" })] - + def hello_world render :action => "hello_world" end - + def hello_world_with_layout render :action => "hello_world", :layout => true end - + def hello_world_with_layout_false render :action => "hello_world", :layout => false end - + def hello_world_with_layout_nil render :action => "hello_world", :layout => nil end end - - class TestControllerLayoutFirst < SimpleRouteCase - describe "Render hello_world and implicitly use .html.erb over application.html.erb as a layout" - get "/render_action_with_both_layouts/basic/hello_world" - assert_body "With Controller Layout! Hello World! KTHXBAI" - assert_status 200 - end - - class TestLayoutTrue < SimpleRouteCase - describe "rendering a normal template with full path with layout => true" - - get "/render_action_with_both_layouts/basic/hello_world_with_layout" - assert_body "With Controller Layout! Hello World! KTHXBAI" - assert_status 200 - end - - class TestLayoutFalse < SimpleRouteCase - describe "rendering a normal template with full path with layout => false" - - get "/render_action_with_both_layouts/basic/hello_world_with_layout_false" - assert_body "Hello World!" - assert_status 200 - end - - class TestLayoutNil < SimpleRouteCase - describe "rendering a normal template with full path with layout => :nil" - - get "/render_action_with_both_layouts/basic/hello_world_with_layout_nil" - assert_body "Hello World!" - assert_status 200 + class ControllerLayoutTest < SimpleRouteCase + describe "Both .html.erb and application.html.erb are present" + + test "rendering implicitly use .html.erb over application.html.erb as a layout" do + get "/render_action_with_both_layouts/basic/hello_world" + + assert_body "With Controller Layout! Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => true" do + get "/render_action_with_both_layouts/basic/hello_world_with_layout" + + assert_body "With Controller Layout! Hello World! KTHXBAI" + assert_status 200 + end + + test "rendering with layout => false" do + get "/render_action_with_both_layouts/basic/hello_world_with_layout_false" + + assert_body "Hello World!" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_action_with_both_layouts/basic/hello_world_with_layout_nil" + + assert_body "Hello World!" + assert_status 200 + end end - end \ No newline at end of file diff --git a/actionpack/test/new_base/render_implicit_action_test.rb b/actionpack/test/new_base/render_implicit_action_test.rb index 58f5cec181..2846df48da 100644 --- a/actionpack/test/new_base/render_implicit_action_test.rb +++ b/actionpack/test/new_base/render_implicit_action_test.rb @@ -10,19 +10,19 @@ module RenderImplicitAction def hello_world() end end - class TestImplicitRender < SimpleRouteCase - describe "render a simple action with new explicit call to render" - - get "/render_implicit_action/simple/hello_world" - assert_body "Hello world!" - assert_status 200 - end - - class TestImplicitWithSpecialCharactersRender < SimpleRouteCase - describe "render an action with a missing method and has special characters" - - get "/render_implicit_action/simple/hyphen-ated" - assert_body "Hello hyphen-ated!" - assert_status 200 + class RenderImplicitActionTest < SimpleRouteCase + test "render a simple action with new explicit call to render" do + get "/render_implicit_action/simple/hello_world" + + assert_body "Hello world!" + assert_status 200 + end + + test "render an action with a missing method and has special characters" do + get "/render_implicit_action/simple/hyphen-ated" + + assert_body "Hello hyphen-ated!" + assert_status 200 + end end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/new_base/render_layout_test.rb index dc858b4f5c..76bd5175a3 100644 --- a/actionpack/test/new_base/render_layout_test.rb +++ b/actionpack/test/new_base/render_layout_test.rb @@ -2,69 +2,65 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") module ControllerLayouts class ImplicitController < ::ApplicationController - self.view_paths = [ActionView::Template::FixturePath.new( "layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI", "layouts/override.html.erb" => "Override! <%= yield %>", "basic.html.erb" => "Hello world!", "controller_layouts/implicit/layout_false.html.erb" => "hai(layout_false.html.erb)" )] - + def index render :template => "basic" end - + def override render :template => "basic", :layout => "override" end - + def layout_false render :layout => false end - + def builder_override - end end - - class TestImplicitLayout < SimpleRouteCase - describe "rendering a normal template, but using the implicit layout" - - get "/controller_layouts/implicit/index" - assert_body "OMG Hello world! KTHXBAI" - assert_status 200 - end - + class ImplicitNameController < ::ApplicationController - self.view_paths = [ActionView::Template::FixturePath.new( "layouts/controller_layouts/implicit_name.html.erb" => "OMGIMPLICIT <%= yield %> KTHXBAI", "basic.html.erb" => "Hello world!" )] - + def index render :template => "basic" end end - - class TestImplicitNamedLayout < SimpleRouteCase - describe "rendering a normal template, but using an implicit NAMED layout" - - get "/controller_layouts/implicit_name/index" - assert_body "OMGIMPLICIT Hello world! KTHXBAI" - assert_status 200 - end - - class TestOverridingImplicitLayout < SimpleRouteCase - describe "overriding an implicit layout with render :layout option" - - get "/controller_layouts/implicit/override" - assert_body "Override! Hello world!" + + class RenderLayoutTest < SimpleRouteCase + test "rendering a normal template, but using the implicit layout" do + get "/controller_layouts/implicit/index" + + assert_body "OMG Hello world! KTHXBAI" + assert_status 200 + end + + test "rendering a normal template, but using an implicit NAMED layout" do + get "/controller_layouts/implicit_name/index" + + assert_body "OMGIMPLICIT Hello world! KTHXBAI" + assert_status 200 + end + + test "overriding an implicit layout with render :layout option" do + get "/controller_layouts/implicit/override" + assert_body "Override! Hello world!" + end + end - - class TestLayoutOptions < SimpleRouteCase + + class LayoutOptionsTest < SimpleRouteCase testing ControllerLayouts::ImplicitController - + test "rendering with :layout => false leaves out the implicit layout" do get :layout_false assert_response "hai(layout_false.html.erb)" diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/new_base/render_template_test.rb index 6c50ae4203..face5b7571 100644 --- a/actionpack/test/new_base/render_template_test.rb +++ b/actionpack/test/new_base/render_template_test.rb @@ -79,7 +79,6 @@ module RenderTemplate end class WithLayoutController < ::ApplicationController - self.view_paths = [ActionView::Template::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", "shared.html.erb" => "Elastica", @@ -108,46 +107,45 @@ module RenderTemplate end end - class TestTemplateRenderWithLayout < SimpleRouteCase - describe "rendering a normal template with full path with layout" - - get "/render_template/with_layout" - assert_body "Hello from basic.html.erb, I'm here!" - assert_status 200 - end - - class TestTemplateRenderWithLayoutTrue < SimpleRouteCase - describe "rendering a normal template with full path with layout => :true" - - get "/render_template/with_layout/with_layout" - assert_body "Hello from basic.html.erb, I'm here!" - assert_status 200 - end - - class TestTemplateRenderWithLayoutFalse < SimpleRouteCase - describe "rendering a normal template with full path with layout => :false" - - get "/render_template/with_layout/with_layout_false" - assert_body "Hello from basic.html.erb" - assert_status 200 - end - - class TestTemplateRenderWithLayoutNil < SimpleRouteCase - describe "rendering a normal template with full path with layout => :nil" - - get "/render_template/with_layout/with_layout_nil" - assert_body "Hello from basic.html.erb" - assert_status 200 - end - - class TestTemplateRenderWithCustomLayout < SimpleRouteCase - describe "rendering a normal template with full path with layout => 'greetings'" - - get "/render_template/with_layout/with_custom_layout" - assert_body "Hello from basic.html.erb, I wish thee well." - assert_status 200 + class TestWithLayout < SimpleRouteCase + describe "Rendering with :template using implicit or explicit layout" + + test "rendering with implicit layout" do + get "/render_template/with_layout" + + assert_body "Hello from basic.html.erb, I'm here!" + assert_status 200 + end + + test "rendering with layout => :true" do + get "/render_template/with_layout/with_layout" + + assert_body "Hello from basic.html.erb, I'm here!" + assert_status 200 + end + + test "rendering with layout => :false" do + get "/render_template/with_layout/with_layout_false" + + assert_body "Hello from basic.html.erb" + assert_status 200 + end + + test "rendering with layout => :nil" do + get "/render_template/with_layout/with_layout_nil" + + assert_body "Hello from basic.html.erb" + assert_status 200 + end + + test "rendering layout => 'greetings'" do + get "/render_template/with_layout/with_custom_layout" + + assert_body "Hello from basic.html.erb, I wish thee well." + assert_status 200 + end end - + module Compatibility class WithoutLayoutController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new( @@ -161,11 +159,12 @@ module RenderTemplate end class TestTemplateRenderWithForwardSlash < SimpleRouteCase - describe "rendering a normal template with full path starting with a leading slash" + test "rendering a normal template with full path starting with a leading slash" do + get "/render_template/compatibility/without_layout/with_forward_slash" - get "/render_template/compatibility/without_layout/with_forward_slash" - assert_body "Hello from basic.html.erb" - assert_status 200 + assert_body "Hello from basic.html.erb" + assert_status 200 + end end end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_test.rb b/actionpack/test/new_base/render_test.rb index ef5e7d89c5..ed3d50fa0b 100644 --- a/actionpack/test/new_base/render_test.rb +++ b/actionpack/test/new_base/render_test.rb @@ -8,60 +8,57 @@ module Render "render/blank_render/access_action_name.html.erb" => "Action Name: <%= action_name %>", "render/blank_render/access_controller_name.html.erb" => "Controller Name: <%= controller_name %>" )] - + def index render end - + def access_request render :action => "access_request" end - + def render_action_name render :action => "access_action_name" end - - private - + + private + def secretz render :text => "FAIL WHALE!" end end - - class TestBlankRender < SimpleRouteCase - describe "Render with blank" - get "/render/blank_render" - assert_body "Hello world!" - assert_status 200 - end - class DoubleRenderController < ActionController::Base def index render :text => "hello" render :text => "world" end end - - class TestBasic < SimpleRouteCase - describe "Rendering more than once" - - test "raises an exception" do + + class RenderTest < SimpleRouteCase + test "render with blank" do + get "/render/blank_render" + + assert_body "Hello world!" + assert_status 200 + end + + test "rendering more than once raises an exception" do assert_raises(AbstractController::DoubleRenderError) do get "/render/double_render", {}, "action_dispatch.show_exceptions" => false end end end - + class TestOnlyRenderPublicActions < SimpleRouteCase describe "Only public methods on actual controllers are callable actions" - + test "raises an exception when a method of Object is called" do assert_raises(AbstractController::ActionNotFound) do get "/render/blank_render/clone", {}, "action_dispatch.show_exceptions" => false end end - + test "raises an exception when a private method is called" do assert_raises(AbstractController::ActionNotFound) do get "/render/blank_render/secretz", {}, "action_dispatch.show_exceptions" => false @@ -74,12 +71,12 @@ module Render get "/render/blank_render/access_request" assert_body "The request: GET" end - + test "The action_name is accessible in the view" do get "/render/blank_render/render_action_name" assert_body "Action Name: render_action_name" end - + test "The controller_name is accessible in the view" do get "/render/blank_render/access_controller_name" assert_body "Controller Name: blank_render" diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb index 39f2f7abbf..69594e4b64 100644 --- a/actionpack/test/new_base/render_text_test.rb +++ b/actionpack/test/new_base/render_text_test.rb @@ -11,15 +11,7 @@ module RenderText render :text => "hello david" end end - - class TestSimpleTextRenderWithNoLayout < SimpleRouteCase - describe "Rendering text from a action with default options renders the text with the layout" - - get "/render_text/simple" - assert_body "hello david" - assert_status 200 - end - + class WithLayoutController < ::ApplicationController self.view_paths = [ActionView::Template::FixturePath.new( "layouts/application.html.erb" => "<%= yield %>, I'm here!", @@ -73,76 +65,77 @@ module RenderText end end - class TestSimpleTextRenderWithLayout < SimpleRouteCase - describe "Rendering text from a action with default options renders the text without the layout" - - get "/render_text/with_layout" - assert_body "hello david" - assert_status 200 - end - - class TestTextRenderWithStatus < SimpleRouteCase - describe "Rendering text, while also providing a custom status code" - - get "/render_text/with_layout/custom_code" - assert_body "hello world" - assert_status 404 - end - - class TestTextRenderWithNil < SimpleRouteCase - describe "Rendering text with nil returns a single space character" - - get "/render_text/with_layout/with_nil" - assert_body " " - assert_status 200 - end - - class TestTextRenderWithNilAndStatus < SimpleRouteCase - describe "Rendering text with nil and custom status code returns a single space character with the status" - - get "/render_text/with_layout/with_nil_and_status" - assert_body " " - assert_status 403 - end - - class TestTextRenderWithFalse < SimpleRouteCase - describe "Rendering text with false returns the string 'false'" - - get "/render_text/with_layout/with_false" - assert_body "false" - assert_status 200 - end - - class TestTextRenderWithLayoutTrue < SimpleRouteCase - describe "Rendering text with :layout => true" - - get "/render_text/with_layout/with_layout_true" - assert_body "hello world, I'm here!" - assert_status 200 - end - - class TestTextRenderWithCustomLayout < SimpleRouteCase - describe "Rendering text with :layout => 'greetings'" - - get "/render_text/with_layout/with_custom_layout" - assert_body "hello world, I wish thee well." - assert_status 200 - end - - class TestTextRenderWithLayoutFalse < SimpleRouteCase - describe "Rendering text with :layout => false" - - get "/render_text/with_layout/with_layout_false" - assert_body "hello world" - assert_status 200 - end - - class TestTextRenderWithLayoutNil < SimpleRouteCase - describe "Rendering text with :layout => nil" - - get "/render_text/with_layout/with_layout_nil" - assert_body "hello world" - assert_status 200 + class RenderTextTest < SimpleRouteCase + describe "Rendering text using render :text" + + test "rendering text from a action with default options renders the text with the layout" do + get "/render_text/simple" + assert_body "hello david" + assert_status 200 + end + + test "rendering text from a action with default options renders the text without the layout" do + get "/render_text/with_layout" + + assert_body "hello david" + assert_status 200 + end + + test "rendering text, while also providing a custom status code" do + get "/render_text/with_layout/custom_code" + + assert_body "hello world" + assert_status 404 + end + + test "rendering text with nil returns a single space character" do + get "/render_text/with_layout/with_nil" + + assert_body " " + assert_status 200 + end + + test "Rendering text with nil and custom status code returns a single space character with the status" do + get "/render_text/with_layout/with_nil_and_status" + + assert_body " " + assert_status 403 + end + + test "rendering text with false returns the string 'false'" do + get "/render_text/with_layout/with_false" + + assert_body "false" + assert_status 200 + end + + test "rendering text with :layout => true" do + get "/render_text/with_layout/with_layout_true" + + assert_body "hello world, I'm here!" + assert_status 200 + end + + test "rendering text with :layout => 'greetings'" do + get "/render_text/with_layout/with_custom_layout" + + assert_body "hello world, I wish thee well." + assert_status 200 + end + + test "rendering text with :layout => false" do + get "/render_text/with_layout/with_layout_false" + + assert_body "hello world" + assert_status 200 + end + + test "rendering text with :layout => nil" do + get "/render_text/with_layout/with_layout_nil" + + assert_body "hello world" + assert_status 200 + end end end diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index 9401e692f1..89c1290063 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -36,13 +36,13 @@ class Rack::TestCase < ActionController::IntegrationTest setup do ActionController::Base.session_options[:key] = "abc" ActionController::Base.session_options[:secret] = ("*" * 30) - + controllers = ActionController::Base.subclasses.map do |k| k.underscore.sub(/_controller$/, '') end - + ActionController::Routing.use_controllers!(controllers) - + # Move into a bootloader ActionController::Base.subclasses.each do |klass| klass = klass.constantize @@ -50,13 +50,13 @@ class Rack::TestCase < ActionController::IntegrationTest klass.class_eval do _write_layout_method end - end + end end - + def app @app ||= ActionController::Dispatcher.new end - + def self.testing(klass = nil) if klass @testing = "/#{klass.name.underscore}".sub!(/_controller$/, '') @@ -64,13 +64,7 @@ class Rack::TestCase < ActionController::IntegrationTest @testing end end - - def self.get(url) - setup do |test| - test.get url - end - end - + def get(thing, *args) if thing.is_a?(Symbol) super("#{self.class.testing}/#{thing}") @@ -78,27 +72,15 @@ class Rack::TestCase < ActionController::IntegrationTest super end end - + def assert_body(body) assert_equal body, Array.wrap(response.body).join end - - def self.assert_body(body) - test "body is set to '#{body}'" do - assert_body body - end - end - + def assert_status(code) assert_equal code, response.status end - - def self.assert_status(code) - test "status code is set to #{code}" do - assert_status code - end - end - + def assert_response(body, status = 200, headers = {}) assert_body body assert_status status @@ -106,27 +88,14 @@ class Rack::TestCase < ActionController::IntegrationTest assert_header header, value end end - + def assert_content_type(type) assert_equal type, response.headers["Content-Type"] end - - def self.assert_content_type(type) - test "content type is set to #{type}" do - assert_content_type(type) - end - end - + def assert_header(name, value) assert_equal value, response.headers[name] end - - def self.assert_header(name, value) - test "'#{name}' header is set to #{value.inspect}" do - assert_header(name, value) - end - end - end class ::ApplicationController < ActionController::Base -- cgit v1.2.3 From 01f032f256f96f65e154061b582fbb4b32e4a692 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 20 May 2009 15:33:08 -0700 Subject: Added responds_to to new base. --- .../lib/action_controller/abstract/layouts.rb | 7 +- .../lib/action_controller/base/mime_responds.rb | 215 ++++++++++----------- actionpack/lib/action_controller/new_base.rb | 1 + actionpack/lib/action_controller/new_base/base.rb | 1 + .../action_controller/new_base/compatibility.rb | 11 +- .../lib/action_controller/new_base/renderer.rb | 2 +- .../lib/action_controller/new_base/testing.rb | 2 +- .../lib/action_controller/testing/process.rb | 1 + actionpack/lib/action_view/template/text.rb | 7 +- actionpack/test/controller/caching_test.rb | 2 + actionpack/test/controller/mime_responds_test.rb | 24 ++- 11 files changed, 148 insertions(+), 125 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 35d5e85ed9..96cb05972f 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -66,7 +66,12 @@ module AbstractController raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}" end - name && view_paths.find_by_parts(name, {:formats => formats}, "layouts") + name && view_paths.find_by_parts(name, {:formats => formats}, _layout_prefix(name)) + end + + # TODO: Decide if this is the best hook point for the feature + def _layout_prefix(name) + "layouts" end def _default_layout(require_layout = false) diff --git a/actionpack/lib/action_controller/base/mime_responds.rb b/actionpack/lib/action_controller/base/mime_responds.rb index 1003e61a0b..e560376e0d 100644 --- a/actionpack/lib/action_controller/base/mime_responds.rb +++ b/actionpack/lib/action_controller/base/mime_responds.rb @@ -1,111 +1,103 @@ module ActionController #:nodoc: module MimeResponds #:nodoc: - def self.included(base) - base.module_eval do - include ActionController::MimeResponds::InstanceMethods - end - end - - module InstanceMethods - # Without web-service support, an action which collects the data for displaying a list of people - # might look something like this: - # - # def index - # @people = Person.find(:all) - # end - # - # Here's the same action, with web-service support baked in: - # - # def index - # @people = Person.find(:all) - # - # respond_to do |format| - # format.html - # format.xml { render :xml => @people.to_xml } - # end - # end - # - # What that says is, "if the client wants HTML in response to this action, just respond as we - # would have before, but if the client wants XML, return them the list of people in XML format." - # (Rails determines the desired response format from the HTTP Accept header submitted by the client.) - # - # Supposing you have an action that adds a new person, optionally creating their company - # (by name) if it does not already exist, without web-services, it might look like this: - # - # def create - # @company = Company.find_or_create_by_name(params[:company][:name]) - # @person = @company.people.create(params[:person]) - # - # redirect_to(person_list_url) - # end - # - # Here's the same action, with web-service support baked in: - # - # def create - # company = params[:person].delete(:company) - # @company = Company.find_or_create_by_name(company[:name]) - # @person = @company.people.create(params[:person]) - # - # respond_to do |format| - # format.html { redirect_to(person_list_url) } - # format.js - # format.xml { render :xml => @person.to_xml(:include => @company) } - # end - # end - # - # If the client wants HTML, we just redirect them back to the person list. If they want Javascript - # (format.js), then it is an RJS request and we render the RJS template associated with this action. - # Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also - # include the person's company in the rendered XML, so you get something like this: - # - # - # ... - # ... - # - # ... - # ... - # ... - # - # - # - # Note, however, the extra bit at the top of that action: - # - # company = params[:person].delete(:company) - # @company = Company.find_or_create_by_name(company[:name]) - # - # This is because the incoming XML document (if a web-service request is in process) can only contain a - # single root-node. So, we have to rearrange things so that the request looks like this (url-encoded): - # - # person[name]=...&person[company][name]=...&... - # - # And, like this (xml-encoded): - # - # - # ... - # - # ... - # - # - # - # In other words, we make the request so that it operates on a single entity's person. Then, in the action, - # we extract the company data from the request, find or create the company, and then create the new person - # with the remaining data. - # - # Note that you can define your own XML parameter parser which would allow you to describe multiple entities - # in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow - # and accept Rails' defaults, life will be much easier. - # - # If you need to use a MIME type which isn't supported by default, you can register your own handlers in - # environment.rb as follows. - # - # Mime::Type.register "image/jpg", :jpg - def respond_to(*types, &block) - raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block - block ||= lambda { |responder| types.each { |type| responder.send(type) } } - responder = Responder.new(self) - block.call(responder) - responder.respond - end + # Without web-service support, an action which collects the data for displaying a list of people + # might look something like this: + # + # def index + # @people = Person.find(:all) + # end + # + # Here's the same action, with web-service support baked in: + # + # def index + # @people = Person.find(:all) + # + # respond_to do |format| + # format.html + # format.xml { render :xml => @people.to_xml } + # end + # end + # + # What that says is, "if the client wants HTML in response to this action, just respond as we + # would have before, but if the client wants XML, return them the list of people in XML format." + # (Rails determines the desired response format from the HTTP Accept header submitted by the client.) + # + # Supposing you have an action that adds a new person, optionally creating their company + # (by name) if it does not already exist, without web-services, it might look like this: + # + # def create + # @company = Company.find_or_create_by_name(params[:company][:name]) + # @person = @company.people.create(params[:person]) + # + # redirect_to(person_list_url) + # end + # + # Here's the same action, with web-service support baked in: + # + # def create + # company = params[:person].delete(:company) + # @company = Company.find_or_create_by_name(company[:name]) + # @person = @company.people.create(params[:person]) + # + # respond_to do |format| + # format.html { redirect_to(person_list_url) } + # format.js + # format.xml { render :xml => @person.to_xml(:include => @company) } + # end + # end + # + # If the client wants HTML, we just redirect them back to the person list. If they want Javascript + # (format.js), then it is an RJS request and we render the RJS template associated with this action. + # Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also + # include the person's company in the rendered XML, so you get something like this: + # + # + # ... + # ... + # + # ... + # ... + # ... + # + # + # + # Note, however, the extra bit at the top of that action: + # + # company = params[:person].delete(:company) + # @company = Company.find_or_create_by_name(company[:name]) + # + # This is because the incoming XML document (if a web-service request is in process) can only contain a + # single root-node. So, we have to rearrange things so that the request looks like this (url-encoded): + # + # person[name]=...&person[company][name]=...&... + # + # And, like this (xml-encoded): + # + # + # ... + # + # ... + # + # + # + # In other words, we make the request so that it operates on a single entity's person. Then, in the action, + # we extract the company data from the request, find or create the company, and then create the new person + # with the remaining data. + # + # Note that you can define your own XML parameter parser which would allow you to describe multiple entities + # in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow + # and accept Rails' defaults, life will be much easier. + # + # If you need to use a MIME type which isn't supported by default, you can register your own handlers in + # environment.rb as follows. + # + # Mime::Type.register "image/jpg", :jpg + def respond_to(*types, &block) + raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block + block ||= lambda { |responder| types.each { |type| responder.send(type) } } + responder = Responder.new(self) + block.call(responder) + responder.respond end class Responder #:nodoc: @@ -127,8 +119,15 @@ module ActionController #:nodoc: @order << mime_type @responses[mime_type] ||= Proc.new do - @controller.template.formats = [mime_type.to_sym] - @response.content_type = mime_type.to_s + # TODO: Remove this when new base is merged in + if defined?(Http) + @controller.formats = [mime_type.to_sym] + @controller.template.formats = [mime_type.to_sym] + else + @controller.template.formats = [mime_type.to_sym] + @response.content_type = mime_type.to_s + end + block_given? ? block.call : @controller.send(:render, :action => @controller.action_name) end end diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 078f66ced1..3fc5d82d01 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -15,6 +15,7 @@ module ActionController # require 'action_controller/routing' autoload :Caching, 'action_controller/caching' autoload :Dispatcher, 'action_controller/dispatch/dispatcher' + autoload :MimeResponds, 'action_controller/base/mime_responds' autoload :PolymorphicRoutes, 'action_controller/routing/generation/polymorphic_routes' autoload :RecordIdentifier, 'action_controller/record_identifier' autoload :Resources, 'action_controller/routing/resources' diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 7f830307b6..3d8d46c9c2 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -18,6 +18,7 @@ module ActionController include SessionManagement include ActionDispatch::StatusCodes include ActionController::Caching + include ActionController::MimeResponds # Rails 2.x compatibility include ActionController::Rails2Compatibility diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index 0098c0747e..c861af2fa2 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -59,6 +59,11 @@ module ActionController def initialize_template_class(*) end def assign_shortcuts(*) end + # TODO: Remove this after we flip + def template + _action_view + end + module ClassMethods def protect_from_forgery() end def consider_all_requests_local() end @@ -95,10 +100,8 @@ module ActionController super || (respond_to?(:method_missing) && "_handle_method_missing") end - def _layout_for_name(name) - name &&= name.sub(%r{^/?layouts/}, '') - super + def _layout_prefix(name) + super unless name =~ /\blayouts/ end - end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 9253df53a1..276816a6f5 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -18,7 +18,7 @@ module ActionController _process_options(options) if options.key?(:text) - options[:_template] = ActionView::TextTemplate.new(_text(options)) + options[:_template] = ActionView::TextTemplate.new(_text(options), formats.first) template = nil elsif options.key?(:inline) handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb index b39d8d539d..0659d81710 100644 --- a/actionpack/lib/action_controller/new_base/testing.rb +++ b/actionpack/lib/action_controller/new_base/testing.rb @@ -7,7 +7,7 @@ module ActionController @_response = response @_response.request = request ret = process(request.parameters[:action]) - @_response.body = self.response_body || " " + @_response.body ||= self.response_body || " " @_response.prepare! set_test_assigns ret diff --git a/actionpack/lib/action_controller/testing/process.rb b/actionpack/lib/action_controller/testing/process.rb index 8831ff57e2..9647f8ce45 100644 --- a/actionpack/lib/action_controller/testing/process.rb +++ b/actionpack/lib/action_controller/testing/process.rb @@ -41,6 +41,7 @@ module ActionController #:nodoc: end def recycle! + @formats = nil @env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ } @env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ } @env['action_dispatch.request.query_parameters'] = {} diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index a777021a12..927a0d7a72 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -1,11 +1,16 @@ module ActionView #:nodoc: class TextTemplate < String #:nodoc: + def initialize(string, content_type = Mime[:html]) + super(string) + @content_type = Mime[content_type] + end + def identifier() self end def render(*) self end - def mime_type() Mime::HTML end + def mime_type() @content_type end def partial?() false end end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 560c09509b..c286976315 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -48,6 +48,8 @@ class PageCachingTest < ActionController::TestCase super ActionController::Base.perform_caching = true + ActionController::Routing::Routes.clear! + ActionController::Routing::Routes.draw do |map| map.main '', :controller => 'posts' map.formatted_posts 'posts.:format', :controller => 'posts' diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 7cd5145a2f..3b8babb84c 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -437,7 +437,7 @@ class MimeControllerTest < ActionController::TestCase @controller.instance_eval do def render(*args) unless args.empty? - @action = args.first[:action] + @action = args.first[:action] || action_name end response.body = "#{@action} - #{@template.formats}" end @@ -490,14 +490,15 @@ class PostController < AbstractPostController end end - protected - def with_iphone - Mime::Type.register_alias("text/html", :iphone) - request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone" - yield - ensure - Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) } - end +protected + + def with_iphone + Mime::Type.register_alias("text/html", :iphone) + request.format = "iphone" if request.env["HTTP_ACCEPT"] == "text/iphone" + yield + ensure + Mime.module_eval { remove_const :IPHONE if const_defined?(:IPHONE) } + end end class SuperPostController < PostController @@ -509,6 +510,11 @@ class SuperPostController < PostController end end +if ENV["new_base"] + PostController._write_layout_method + SuperPostController._write_layout_method +end + class MimeControllerLayoutsTest < ActionController::TestCase tests PostController -- cgit v1.2.3 From 77d955c51740216131fc0b130d5cb37fcd18d071 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 20 May 2009 15:54:29 -0700 Subject: Added passing old tests on new base to the main test runner --- actionpack/Rakefile | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 6ce8179646..f1f407c008 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -22,7 +22,7 @@ task :default => [ :test ] # Run the unit tests desc "Run all unit tests" -task :test => [:test_action_pack, :test_active_record_integration, :test_new_base] +task :test => [:test_action_pack, :test_active_record_integration, :test_new_base, :test_new_base_on_old_tests] Rake::TestTask.new(:test_action_pack) do |t| t.libs << "test" @@ -55,6 +55,17 @@ Rake::TestTask.new(:test_new_base) do |t| t.verbose = true end +desc 'Old Controller Tests on New Base' +Rake::TestTask.new(:test_new_base_on_old_tests) do |t| + ENV['new_base'] = "true" + t.libs << "test" + # content_type mime_responds layout + t.test_files = %w( + addresses_render base benchmark caching capture dispatcher record_identifier + redirect render rescue url_rewriter webservice + ).map { |name| "test/controller/#{name}_test.rb" } +end + # Genereate the RDoc documentation -- cgit v1.2.3 From b46c9071c382b48c5ff349fbe61854683663a866 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 16:00:16 -0700 Subject: Ruby 1.9 stdlib gems don't recognize .pre yet --- actionpack/lib/action_dispatch.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index f9003c51ea..ee162765cb 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -27,7 +27,7 @@ require 'active_support' begin gem 'rack', '~> 1.1.pre' -rescue Gem::LoadError +rescue Gem::LoadError, ArgumentError $:.unshift "#{File.dirname(__FILE__)}/action_dispatch/vendor/rack-1.1.pre" end -- cgit v1.2.3 From c86ec82cf63938f691c9ae4f5a4d72bea9e8a9c7 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 16:00:50 -0700 Subject: Wrap string body in an array --- actionpack/lib/action_dispatch/middleware/show_exceptions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 108355da63..4d598669c7 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -102,7 +102,7 @@ module ActionDispatch end def render(status, body) - [status, {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}, body] + [status, {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}, [body]] end def public_path -- cgit v1.2.3 From 205cfe2163d9eb6ee801a23f550e960136b5680e Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 16:23:55 -0700 Subject: Massage setup for old tests on new base --- actionpack/Rakefile | 3 +- actionpack/test/abstract_unit.rb | 4 - actionpack/test/abstract_unit2.rb | 139 ----------------------------- actionpack/test/new_base/abstract_unit.rb | 141 ++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 145 deletions(-) delete mode 100644 actionpack/test/abstract_unit2.rb create mode 100644 actionpack/test/new_base/abstract_unit.rb diff --git a/actionpack/Rakefile b/actionpack/Rakefile index f1f407c008..af14e592c0 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -57,8 +57,7 @@ end desc 'Old Controller Tests on New Base' Rake::TestTask.new(:test_new_base_on_old_tests) do |t| - ENV['new_base'] = "true" - t.libs << "test" + t.libs << "test/new_base" << "test" # content_type mime_responds layout t.test_files = %w( addresses_render base benchmark caching capture dispatcher record_identifier diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 7982f06545..f6f62bcf83 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -1,6 +1,3 @@ -if ENV["new_base"] - require "abstract_unit2" -else $:.unshift(File.dirname(__FILE__) + '/../lib') $:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib') $:.unshift(File.dirname(__FILE__) + '/fixtures/helpers') @@ -41,4 +38,3 @@ ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures') ActionController::Base.view_paths = FIXTURE_LOAD_PATH -end \ No newline at end of file diff --git a/actionpack/test/abstract_unit2.rb b/actionpack/test/abstract_unit2.rb deleted file mode 100644 index 519e6bea36..0000000000 --- a/actionpack/test/abstract_unit2.rb +++ /dev/null @@ -1,139 +0,0 @@ -$:.unshift(File.dirname(__FILE__) + '/../lib') -$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib') -$:.unshift(File.dirname(__FILE__) + '/lib') - - -require 'test/unit' -require 'active_support' -require 'active_support/test_case' -require 'action_controller/abstract' -require 'action_controller/new_base' -require 'fixture_template' -require 'action_controller/testing/process2' -require 'action_view/test_case' -require 'action_controller/testing/integration' -require 'active_support/dependencies' - -ActiveSupport::Dependencies.hook! - -FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures') - -module ActionController - Base.session = { - :key => '_testing_session', - :secret => '8273f16463985e2b3747dc25e30f2528' -} - - class ActionControllerError < StandardError #:nodoc: - end - - class SessionRestoreError < ActionControllerError #:nodoc: - end - - class RenderError < ActionControllerError #:nodoc: - end - - class RoutingError < ActionControllerError #:nodoc: - attr_reader :failures - def initialize(message, failures=[]) - super(message) - @failures = failures - end - end - - class MethodNotAllowed < ActionControllerError #:nodoc: - attr_reader :allowed_methods - - def initialize(*allowed_methods) - super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.") - @allowed_methods = allowed_methods - end - - def allowed_methods_header - allowed_methods.map { |method_symbol| method_symbol.to_s.upcase } * ', ' - end - - def handle_response!(response) - response.headers['Allow'] ||= allowed_methods_header - end - end - - class NotImplemented < MethodNotAllowed #:nodoc: - end - - class UnknownController < ActionControllerError #:nodoc: - end - - class MissingFile < ActionControllerError #:nodoc: - end - - class RenderError < ActionControllerError #:nodoc: - end - - class SessionOverflowError < ActionControllerError #:nodoc: - DEFAULT_MESSAGE = 'Your session data is larger than the data column in which it is to be stored. You must increase the size of your data column if you intend to store large data.' - - def initialize(message = nil) - super(message || DEFAULT_MESSAGE) - end - end - - class UnknownHttpMethod < ActionControllerError #:nodoc: - end - - class Base - include ActionController::Testing - end - - Base.view_paths = FIXTURE_LOAD_PATH - - class TestCase - include TestProcess - setup do - ActionController::Routing::Routes.draw do |map| - map.connect ':controller/:action/:id' - end - end - - def assert_template(options = {}, message = nil) - validate_request! - - hax = @controller._action_view.instance_variable_get(:@_rendered) - - case options - when NilClass, String - rendered = (hax[:template] || []).map { |t| t.identifier } - msg = build_message(message, - "expecting but rendering with ", - options, rendered.join(', ')) - assert_block(msg) do - if options.nil? - hax[:template].blank? - else - rendered.any? { |t| t.match(options) } - end - end - when Hash - if expected_partial = options[:partial] - partials = hax[:partials] - if expected_count = options[:count] - found = partials.detect { |p, _| p.identifier.match(expected_partial) } - actual_count = found.nil? ? 0 : found.second - msg = build_message(message, - "expecting ? to be rendered ? time(s) but rendered ? time(s)", - expected_partial, expected_count, actual_count) - assert(actual_count == expected_count.to_i, msg) - else - msg = build_message(message, - "expecting partial but action rendered ", - options[:partial], partials.keys) - assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg) - end - else - assert hax[:partials].empty?, - "Expected no partials to be rendered" - end - end - end - end -end diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb new file mode 100644 index 0000000000..e72165ee67 --- /dev/null +++ b/actionpack/test/new_base/abstract_unit.rb @@ -0,0 +1,141 @@ +$:.unshift(File.dirname(__FILE__) + '/../../lib') +$:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib') +$:.unshift(File.dirname(__FILE__) + '/../lib') + +ENV['new_base'] = "true" +$stderr.puts "Running old tests on new_base" + +require 'test/unit' +require 'active_support' +require 'active_support/test_case' +require 'action_controller/abstract' +require 'action_controller/new_base' +require 'fixture_template' +require 'action_controller/testing/process2' +require 'action_view/test_case' +require 'action_controller/testing/integration' +require 'active_support/dependencies' + +ActiveSupport::Dependencies.hook! + +FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), '../fixtures') + +module ActionController + Base.session = { + :key => '_testing_session', + :secret => '8273f16463985e2b3747dc25e30f2528' +} + + class ActionControllerError < StandardError #:nodoc: + end + + class SessionRestoreError < ActionControllerError #:nodoc: + end + + class RenderError < ActionControllerError #:nodoc: + end + + class RoutingError < ActionControllerError #:nodoc: + attr_reader :failures + def initialize(message, failures=[]) + super(message) + @failures = failures + end + end + + class MethodNotAllowed < ActionControllerError #:nodoc: + attr_reader :allowed_methods + + def initialize(*allowed_methods) + super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.") + @allowed_methods = allowed_methods + end + + def allowed_methods_header + allowed_methods.map { |method_symbol| method_symbol.to_s.upcase } * ', ' + end + + def handle_response!(response) + response.headers['Allow'] ||= allowed_methods_header + end + end + + class NotImplemented < MethodNotAllowed #:nodoc: + end + + class UnknownController < ActionControllerError #:nodoc: + end + + class MissingFile < ActionControllerError #:nodoc: + end + + class RenderError < ActionControllerError #:nodoc: + end + + class SessionOverflowError < ActionControllerError #:nodoc: + DEFAULT_MESSAGE = 'Your session data is larger than the data column in which it is to be stored. You must increase the size of your data column if you intend to store large data.' + + def initialize(message = nil) + super(message || DEFAULT_MESSAGE) + end + end + + class UnknownHttpMethod < ActionControllerError #:nodoc: + end + + class Base + include ActionController::Testing + end + + Base.view_paths = FIXTURE_LOAD_PATH + + class TestCase + include TestProcess + setup do + ActionController::Routing::Routes.draw do |map| + map.connect ':controller/:action/:id' + end + end + + def assert_template(options = {}, message = nil) + validate_request! + + hax = @controller._action_view.instance_variable_get(:@_rendered) + + case options + when NilClass, String + rendered = (hax[:template] || []).map { |t| t.identifier } + msg = build_message(message, + "expecting but rendering with ", + options, rendered.join(', ')) + assert_block(msg) do + if options.nil? + hax[:template].blank? + else + rendered.any? { |t| t.match(options) } + end + end + when Hash + if expected_partial = options[:partial] + partials = hax[:partials] + if expected_count = options[:count] + found = partials.detect { |p, _| p.identifier.match(expected_partial) } + actual_count = found.nil? ? 0 : found.second + msg = build_message(message, + "expecting ? to be rendered ? time(s) but rendered ? time(s)", + expected_partial, expected_count, actual_count) + assert(actual_count == expected_count.to_i, msg) + else + msg = build_message(message, + "expecting partial but action rendered ", + options[:partial], partials.keys) + assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg) + end + else + assert hax[:partials].empty?, + "Expected no partials to be rendered" + end + end + end + end +end -- cgit v1.2.3 From 8e7a87d299483fce6af3be89e50deae43055a96f Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 May 2009 01:38:48 +0200 Subject: Make ActionController::Flash work with new_base --- actionpack/Rakefile | 2 +- .../lib/action_controller/base/chained/flash.rb | 74 +++++++++++++++------- actionpack/lib/action_controller/new_base.rb | 5 +- actionpack/lib/action_controller/new_base/base.rb | 3 + actionpack/lib/action_controller/new_base/http.rb | 2 +- .../lib/action_controller/new_base/session.rb | 11 ++++ actionpack/test/controller/flash_test.rb | 49 +++++++------- 7 files changed, 97 insertions(+), 49 deletions(-) create mode 100644 actionpack/lib/action_controller/new_base/session.rb diff --git a/actionpack/Rakefile b/actionpack/Rakefile index af14e592c0..2a456ebb05 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -61,7 +61,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| # content_type mime_responds layout t.test_files = %w( addresses_render base benchmark caching capture dispatcher record_identifier - redirect render rescue url_rewriter webservice + redirect render rescue url_rewriter webservice flash ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/base/chained/flash.rb b/actionpack/lib/action_controller/base/chained/flash.rb index 56ee9c67e2..6bd482d85a 100644 --- a/actionpack/lib/action_controller/base/chained/flash.rb +++ b/actionpack/lib/action_controller/base/chained/flash.rb @@ -26,9 +26,18 @@ module ActionController #:nodoc: # # See docs on the FlashHash class for more details about the flash. module Flash - def self.included(base) - base.class_eval do - include InstanceMethods + extend ActiveSupport::DependencyModule + + # TODO : Remove the defined? check when new base is the main base + depends_on Session if defined?(ActionController::Http) + + included do + # TODO : Remove the defined? check when new base is the main base + if defined?(ActionController::Http) + include InstanceMethodsForNewBase + else + include InstanceMethodsForBase + alias_method_chain :perform_action, :flash alias_method_chain :reset_session, :flash end @@ -135,29 +144,50 @@ module ActionController #:nodoc: end end - module InstanceMethods #:nodoc: + module InstanceMethodsForBase #:nodoc: protected - def perform_action_with_flash - perform_action_without_flash - remove_instance_variable(:@_flash) if defined? @_flash - end - def reset_session_with_flash - reset_session_without_flash - remove_instance_variable(:@_flash) if defined? @_flash - end + def perform_action_with_flash + perform_action_without_flash + remove_instance_variable(:@_flash) if defined?(@_flash) + end - # Access the contents of the flash. Use flash["notice"] to - # read a notice you put there or flash["notice"] = "hello" - # to put a new one. - def flash #:doc: - unless defined? @_flash - @_flash = session["flash"] ||= FlashHash.new - @_flash.sweep - end + def reset_session_with_flash + reset_session_without_flash + remove_instance_variable(:@_flash) if defined?(@_flash) + end + end - @_flash - end + module InstanceMethodsForNewBase #:nodoc: + protected + + def reset_session + super + remove_flash_instance_variable + end + + def process_action(method_name) + super + remove_flash_instance_variable + end + + def remove_flash_instance_variable + remove_instance_variable(:@_flash) if defined?(@_flash) + end + end + + protected + + # Access the contents of the flash. Use flash["notice"] to + # read a notice you put there or flash["notice"] = "hello" + # to put a new one. + def flash #:doc: + unless defined?(@_flash) + @_flash = session["flash"] ||= FlashHash.new + @_flash.sweep + end + + @_flash end end end diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 3fc5d82d01..d2f6514ff9 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -10,7 +10,8 @@ module ActionController autoload :Rescue, "action_controller/new_base/rescuable" autoload :Testing, "action_controller/new_base/testing" autoload :UrlFor, "action_controller/new_base/url_for" - + autoload :Session, "action_controller/new_base/session" + # Ported modules # require 'action_controller/routing' autoload :Caching, 'action_controller/caching' @@ -23,6 +24,8 @@ module ActionController autoload :TestCase, 'action_controller/testing/test_case' autoload :UrlRewriter, 'action_controller/routing/generation/url_rewriter' autoload :UrlWriter, 'action_controller/routing/generation/url_rewriter' + + autoload :Flash, 'action_controller/base/chained/flash' require 'action_controller/routing' end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 3d8d46c9c2..eff7297973 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -14,6 +14,9 @@ module ActionController include ActionController::Layouts include ActionController::ConditionalGet + include ActionController::Session + include ActionController::Flash + # Legacy modules include SessionManagement include ActionDispatch::StatusCodes diff --git a/actionpack/lib/action_controller/new_base/http.rb b/actionpack/lib/action_controller/new_base/http.rb index 17466a2d52..2525e221a6 100644 --- a/actionpack/lib/action_controller/new_base/http.rb +++ b/actionpack/lib/action_controller/new_base/http.rb @@ -37,7 +37,7 @@ module ActionController end delegate :headers, :to => "@_response" - + def params @_params ||= @_request.parameters end diff --git a/actionpack/lib/action_controller/new_base/session.rb b/actionpack/lib/action_controller/new_base/session.rb new file mode 100644 index 0000000000..a8715555fb --- /dev/null +++ b/actionpack/lib/action_controller/new_base/session.rb @@ -0,0 +1,11 @@ +module ActionController + module Session + def session + @_request.session + end + + def reset_session + @_request.reset_session + end + end +end diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb index ef60cae0ff..84e27d7779 100644 --- a/actionpack/test/controller/flash_test.rb +++ b/actionpack/test/controller/flash_test.rb @@ -60,6 +60,7 @@ class FlashTest < ActionController::TestCase def std_action @flash_copy = {}.update(flash) + render :nothing => true end def filter_halting_action @@ -79,64 +80,64 @@ class FlashTest < ActionController::TestCase get :set_flash get :use_flash - assert_equal "hello", @controller.template.assigns["flash_copy"]["that"] - assert_equal "hello", @controller.template.assigns["flashy"] + assert_equal "hello", assigns["flash_copy"]["that"] + assert_equal "hello", assigns["flashy"] get :use_flash - assert_nil @controller.template.assigns["flash_copy"]["that"], "On second flash" + assert_nil assigns["flash_copy"]["that"], "On second flash" end def test_keep_flash get :set_flash get :use_flash_and_keep_it - assert_equal "hello", @controller.template.assigns["flash_copy"]["that"] - assert_equal "hello", @controller.template.assigns["flashy"] + assert_equal "hello", assigns["flash_copy"]["that"] + assert_equal "hello", assigns["flashy"] get :use_flash - assert_equal "hello", @controller.template.assigns["flash_copy"]["that"], "On second flash" + assert_equal "hello", assigns["flash_copy"]["that"], "On second flash" get :use_flash - assert_nil @controller.template.assigns["flash_copy"]["that"], "On third flash" + assert_nil assigns["flash_copy"]["that"], "On third flash" end def test_flash_now get :set_flash_now - assert_equal "hello", @controller.template.assigns["flash_copy"]["that"] - assert_equal "bar" , @controller.template.assigns["flash_copy"]["foo"] - assert_equal "hello", @controller.template.assigns["flashy"] + assert_equal "hello", assigns["flash_copy"]["that"] + assert_equal "bar" , assigns["flash_copy"]["foo"] + assert_equal "hello", assigns["flashy"] get :attempt_to_use_flash_now - assert_nil @controller.template.assigns["flash_copy"]["that"] - assert_nil @controller.template.assigns["flash_copy"]["foo"] - assert_nil @controller.template.assigns["flashy"] + assert_nil assigns["flash_copy"]["that"] + assert_nil assigns["flash_copy"]["foo"] + assert_nil assigns["flashy"] end def test_update_flash get :set_flash get :use_flash_and_update_it - assert_equal "hello", @controller.template.assigns["flash_copy"]["that"] - assert_equal "hello again", @controller.template.assigns["flash_copy"]["this"] + assert_equal "hello", assigns["flash_copy"]["that"] + assert_equal "hello again", assigns["flash_copy"]["this"] get :use_flash - assert_nil @controller.template.assigns["flash_copy"]["that"], "On second flash" - assert_equal "hello again", @controller.template.assigns["flash_copy"]["this"], "On second flash" + assert_nil assigns["flash_copy"]["that"], "On second flash" + assert_equal "hello again", assigns["flash_copy"]["this"], "On second flash" end def test_flash_after_reset_session get :use_flash_after_reset_session - assert_equal "hello", @controller.template.assigns["flashy_that"] - assert_equal "good-bye", @controller.template.assigns["flashy_this"] - assert_nil @controller.template.assigns["flashy_that_reset"] + assert_equal "hello", assigns["flashy_that"] + assert_equal "good-bye", assigns["flashy_this"] + assert_nil assigns["flashy_that_reset"] end def test_sweep_after_halted_filter_chain get :std_action - assert_nil @controller.template.assigns["flash_copy"]["foo"] + assert_nil assigns["flash_copy"]["foo"] get :filter_halting_action - assert_equal "bar", @controller.template.assigns["flash_copy"]["foo"] + assert_equal "bar", assigns["flash_copy"]["foo"] get :std_action # follow redirection - assert_equal "bar", @controller.template.assigns["flash_copy"]["foo"] + assert_equal "bar", assigns["flash_copy"]["foo"] get :std_action - assert_nil @controller.template.assigns["flash_copy"]["foo"] + assert_nil assigns["flash_copy"]["foo"] end end -- cgit v1.2.3 From c4a6109286909c394e8c5bfc471a1eb9de245d2b Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 20 May 2009 16:52:56 -0700 Subject: Got controller/mime_responds_test.rb running on the new base --- actionpack/Rakefile | 7 +++--- actionpack/test/abstract_unit.rb | 2 ++ actionpack/test/controller/mime_responds_test.rb | 26 +++++++++++++--------- actionpack/test/new_base/abstract_unit.rb | 3 +++ activesupport/lib/active_support/test_case.rb | 5 +++++ .../lib/active_support/testing/pending.rb | 5 +++++ 6 files changed, 34 insertions(+), 14 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 2a456ebb05..86f7adaee3 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -58,10 +58,11 @@ end desc 'Old Controller Tests on New Base' Rake::TestTask.new(:test_new_base_on_old_tests) do |t| t.libs << "test/new_base" << "test" - # content_type mime_responds layout + # content_type layout + # Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + t.test_files = %w( - addresses_render base benchmark caching capture dispatcher record_identifier - redirect render rescue url_rewriter webservice flash + addresses_render base benchmark caching capture dispatcher flash mime_responds + record_identifier redirect render rescue url_rewriter webservice ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index f6f62bcf83..5ae54d097a 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -23,6 +23,8 @@ require 'action_controller' require 'action_controller/testing/process' require 'action_view/test_case' +$tags[:old_base] = true + # Show backtraces for deprecated behavior for quicker cleanup. ActiveSupport::Deprecation.debug = true diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 3b8babb84c..56b49251c6 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -375,9 +375,11 @@ class MimeControllerTest < ActionController::TestCase end def test_rjs_type_skips_layout - @request.accept = "text/javascript" - get :all_types_with_layout - assert_equal 'RJS for all_types_with_layout', @response.body + pending(:new_base) do + @request.accept = "text/javascript" + get :all_types_with_layout + assert_equal 'RJS for all_types_with_layout', @response.body + end end def test_html_type_with_layout @@ -510,7 +512,7 @@ class SuperPostController < PostController end end -if ENV["new_base"] +if defined?(ActionController::Http) PostController._write_layout_method SuperPostController._write_layout_method end @@ -532,14 +534,16 @@ class MimeControllerLayoutsTest < ActionController::TestCase assert_equal 'Hello iPhone', @response.body end - def test_format_with_inherited_layouts - @controller = SuperPostController.new + for_tag(:old_base) do + def test_format_with_inherited_layouts + @controller = SuperPostController.new - get :index - assert_equal 'Super Firefox', @response.body + get :index + assert_equal 'Super Firefox', @response.body - @request.accept = "text/iphone" - get :index - assert_equal '
Super iPhone
', @response.body + @request.accept = "text/iphone" + get :index + assert_equal '
Super iPhone
', @response.body + end end end diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb index e72165ee67..c045247702 100644 --- a/actionpack/test/new_base/abstract_unit.rb +++ b/actionpack/test/new_base/abstract_unit.rb @@ -16,6 +16,9 @@ require 'action_view/test_case' require 'action_controller/testing/integration' require 'active_support/dependencies' +$tags[:new_base] = true + + ActiveSupport::Dependencies.hook! FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), '../fixtures') diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb index 50e25ef740..bab2a401eb 100644 --- a/activesupport/lib/active_support/test_case.rb +++ b/activesupport/lib/active_support/test_case.rb @@ -32,6 +32,11 @@ module ActiveSupport include ActiveSupport::Testing::Default end + $tags = {} + def self.for_tag(tag) + yield if $tags[tag] + end + include ActiveSupport::Testing::SetupAndTeardown include ActiveSupport::Testing::Assertions include ActiveSupport::Testing::Deprecation diff --git a/activesupport/lib/active_support/testing/pending.rb b/activesupport/lib/active_support/testing/pending.rb index d945c7e476..21134ff9e2 100644 --- a/activesupport/lib/active_support/testing/pending.rb +++ b/activesupport/lib/active_support/testing/pending.rb @@ -11,6 +11,11 @@ module ActiveSupport @@at_exit = false def pending(description = "", &block) + if description.is_a?(Symbol) + is_pending = $tags[description] + return block.call unless is_pending + end + if block_given? failed = false -- cgit v1.2.3 From c8eda9ade49700abce104de1ce7e8e1a754fc97e Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 20 May 2009 17:22:29 -0700 Subject: Fixed new_base tests on ruby 1.9 --- actionpack/lib/action_controller/new_base/renderer.rb | 4 ++-- actionpack/lib/action_dispatch/http/mime_types.rb | 2 +- actionpack/test/lib/fixture_template.rb | 2 +- actionpack/test/new_base/etag_test.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 276816a6f5..6176212970 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -4,8 +4,8 @@ module ActionController depends_on AbstractController::Renderer - def initialize(*) - self.formats = [:html] + def process_action(*) + self.formats = request.formats.map {|x| x.to_sym} super end diff --git a/actionpack/lib/action_dispatch/http/mime_types.rb b/actionpack/lib/action_dispatch/http/mime_types.rb index 2d7fba1173..7c28cac419 100644 --- a/actionpack/lib/action_dispatch/http/mime_types.rb +++ b/actionpack/lib/action_dispatch/http/mime_types.rb @@ -1,9 +1,9 @@ # Build list of Mime types for HTTP responses # http://www.iana.org/assignments/media-types/ +Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml ) Mime::Type.register "*/*", :all Mime::Type.register "text/plain", :text, [], %w(txt) -Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml ) Mime::Type.register "text/javascript", :js, %w( application/javascript application/x-javascript ) Mime::Type.register "text/css", :css Mime::Type.register "text/calendar", :ics diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb index e43e329a9e..59fb6819ed 100644 --- a/actionpack/test/lib/fixture_template.rb +++ b/actionpack/test/lib/fixture_template.rb @@ -46,7 +46,7 @@ class Template end end - %r'#{Regexp.escape(path)}#{extensions}#{handler_regexp}' + %r'^#{Regexp.escape(path)}#{extensions}#{handler_regexp}$' end # TODO: fix me diff --git a/actionpack/test/new_base/etag_test.rb b/actionpack/test/new_base/etag_test.rb index c77636bb64..a40d3c936a 100644 --- a/actionpack/test/new_base/etag_test.rb +++ b/actionpack/test/new_base/etag_test.rb @@ -12,7 +12,7 @@ module Etags end def with_layout - render :action => "base", :layout => "etag" + render :action => "base", :layout => "etags" end end -- cgit v1.2.3 From 7f7fdc407a90c9ce75ce0a77bc0f631115514d2f Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Wed, 20 May 2009 17:42:04 -0700 Subject: Make controller/content_type_test.rb pass on new base --- actionpack/Rakefile | 7 ++++--- actionpack/lib/action_controller/new_base/renderer.rb | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 86f7adaee3..684b828254 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -58,11 +58,12 @@ end desc 'Old Controller Tests on New Base' Rake::TestTask.new(:test_new_base_on_old_tests) do |t| t.libs << "test/new_base" << "test" - # content_type layout + # layout # Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + t.test_files = %w( - addresses_render base benchmark caching capture dispatcher flash mime_responds - record_identifier redirect render rescue url_rewriter webservice + addresses_render base benchmark caching capture content_type dispatcher + flash mime_responds record_identifier redirect render rescue url_rewriter + webservice ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 6176212970..81685ca9d6 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -38,7 +38,11 @@ module ActionController ret = super(options) options[:_template] ||= _action_view._partial - response.content_type ||= options[:_template].mime_type + response.content_type ||= begin + mime = options[:_template].mime_type + mime &&= mime.to_sym + formats.include?(mime) ? mime : formats.first + end ret end -- cgit v1.2.3 From e21d1614bb9006e69bf4bb2467b823aa12e64485 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 May 2009 02:55:25 +0200 Subject: Made ActionController::Verification work with new_base --- actionpack/Rakefile | 2 +- actionpack/lib/action_controller/base/verification.rb | 12 +++++++++--- actionpack/lib/action_controller/new_base.rb | 5 +++-- actionpack/lib/action_controller/new_base/base.rb | 1 + actionpack/lib/action_controller/new_base/compatibility.rb | 4 ++++ actionpack/lib/action_controller/new_base/testing.rb | 2 +- actionpack/lib/action_controller/testing/process2.rb | 2 +- actionpack/test/controller/verification_test.rb | 14 ++++++-------- 8 files changed, 26 insertions(+), 16 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 684b828254..3a6a54768e 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -63,7 +63,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| t.test_files = %w( addresses_render base benchmark caching capture content_type dispatcher flash mime_responds record_identifier redirect render rescue url_rewriter - webservice + webservice verification ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/base/verification.rb b/actionpack/lib/action_controller/base/verification.rb index c62b81b666..a513e9f40c 100644 --- a/actionpack/lib/action_controller/base/verification.rb +++ b/actionpack/lib/action_controller/base/verification.rb @@ -1,7 +1,13 @@ module ActionController #:nodoc: module Verification #:nodoc: - def self.included(base) #:nodoc: - base.extend(ClassMethods) + extend ActiveSupport::DependencyModule + + # TODO : Remove the defined? check when new base is the main base + if defined?(ActionController::Http) + depends_on AbstractController::Callbacks + depends_on Session + depends_on Flash + depends_on Renderer end # This module provides a class-level method for specifying that certain @@ -102,7 +108,7 @@ module ActionController #:nodoc: end def verify_presence_of_keys_in_hash_flash_or_params(options) # :nodoc: - [*options[:params] ].find { |v| params[v].nil? } || + [*options[:params] ].find { |v| v && params[v.to_sym].nil? } || [*options[:session]].find { |v| session[v].nil? } || [*options[:flash] ].find { |v| flash[v].nil? } end diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index d2f6514ff9..8bc15d2450 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -25,8 +25,9 @@ module ActionController autoload :UrlRewriter, 'action_controller/routing/generation/url_rewriter' autoload :UrlWriter, 'action_controller/routing/generation/url_rewriter' - autoload :Flash, 'action_controller/base/chained/flash' - + autoload :Verification, 'action_controller/base/verification' + autoload :Flash, 'action_controller/base/chained/flash' + require 'action_controller/routing' end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index eff7297973..a419a80b6a 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -16,6 +16,7 @@ module ActionController include ActionController::Session include ActionController::Flash + include ActionController::Verification # Legacy modules include SessionManagement diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index c861af2fa2..9b85b39052 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -103,5 +103,9 @@ module ActionController def _layout_prefix(name) super unless name =~ /\blayouts/ end + + def performed? + response_body + end end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb index 0659d81710..bc3bc70404 100644 --- a/actionpack/lib/action_controller/new_base/testing.rb +++ b/actionpack/lib/action_controller/new_base/testing.rb @@ -2,7 +2,7 @@ module ActionController module Testing # OMG MEGA HAX - def process_with_test(request, response) + def process_with_new_base_test(request, response) @_request = request @_response = response @_response.request = request diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb index e9a79369b9..2dafcaa5a9 100644 --- a/actionpack/lib/action_controller/testing/process2.rb +++ b/actionpack/lib/action_controller/testing/process2.rb @@ -53,7 +53,7 @@ module ActionController @controller.request = @request @controller.params.merge!(parameters) # Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest - @controller.process_with_test(@request, @response) + @controller.process_with_new_base_test(@request, @response) end def build_request_uri(action, parameters) diff --git a/actionpack/test/controller/verification_test.rb b/actionpack/test/controller/verification_test.rb index 418a81baa8..85134a8264 100644 --- a/actionpack/test/controller/verification_test.rb +++ b/actionpack/test/controller/verification_test.rb @@ -103,17 +103,15 @@ class VerificationTest < ActionController::TestCase end protected - def rescue_action(e) raise end - def unconditional_redirect - redirect_to :action => "unguarded" - end + def unconditional_redirect + redirect_to :action => "unguarded" + end end - def setup - @controller = TestController.new - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new + tests TestController + + setup do ActionController::Routing::Routes.add_named_route :foo, '/foo', :controller => 'test', :action => 'foo' end -- cgit v1.2.3 From 5a036457620b7fb22027dc4f0c399871db6ed0c3 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 May 2009 03:04:17 +0200 Subject: Allow Module#depends_on to accept multiple modules --- actionpack/lib/action_controller/base/verification.rb | 5 +---- activesupport/lib/active_support/dependency_module.rb | 10 ++++++---- activesupport/test/dependency_module_test.rb | 11 +++++++++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/actionpack/lib/action_controller/base/verification.rb b/actionpack/lib/action_controller/base/verification.rb index a513e9f40c..3fa5a105b1 100644 --- a/actionpack/lib/action_controller/base/verification.rb +++ b/actionpack/lib/action_controller/base/verification.rb @@ -4,10 +4,7 @@ module ActionController #:nodoc: # TODO : Remove the defined? check when new base is the main base if defined?(ActionController::Http) - depends_on AbstractController::Callbacks - depends_on Session - depends_on Flash - depends_on Renderer + depends_on AbstractController::Callbacks, Session, Flash, Renderer end # This module provides a class-level method for specifying that certain diff --git a/activesupport/lib/active_support/dependency_module.rb b/activesupport/lib/active_support/dependency_module.rb index 8c202acc8f..9872b9654b 100644 --- a/activesupport/lib/active_support/dependency_module.rb +++ b/activesupport/lib/active_support/dependency_module.rb @@ -16,10 +16,12 @@ module ActiveSupport end end - def depends_on(mod) - return if self < mod - @_dependencies ||= [] - @_dependencies << mod + def depends_on(*mods) + mods.each do |mod| + next if self < mod + @_dependencies ||= [] + @_dependencies << mod + end end end end diff --git a/activesupport/test/dependency_module_test.rb b/activesupport/test/dependency_module_test.rb index 07090d15a1..be7db0fa7b 100644 --- a/activesupport/test/dependency_module_test.rb +++ b/activesupport/test/dependency_module_test.rb @@ -42,6 +42,12 @@ class DependencyModuleTest < Test::Unit::TestCase end end + module Foo + extend ActiveSupport::DependencyModule + + depends_on Bar, Baz + end + def setup @klass = Class.new end @@ -74,4 +80,9 @@ class DependencyModuleTest < Test::Unit::TestCase assert_equal "baz", @klass.baz assert_equal [DependencyModuleTest::Bar, DependencyModuleTest::Baz], @klass.included_modules[0..1] end + + def test_depends_on_with_multiple_modules + @klass.send(:include, Foo) + assert_equal [DependencyModuleTest::Foo, DependencyModuleTest::Bar, DependencyModuleTest::Baz], @klass.included_modules[0..2] + end end -- cgit v1.2.3 From 429a00f225b24b938575ed40d11fa07987e12a6f Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 16:41:20 -0700 Subject: Remove bad add --- activesupport/memcached_get_multi.diff | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 activesupport/memcached_get_multi.diff diff --git a/activesupport/memcached_get_multi.diff b/activesupport/memcached_get_multi.diff deleted file mode 100644 index e69de29bb2..0000000000 -- cgit v1.2.3 From 68398838544a778244e6028f2c30deb7313ea0b2 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 16:49:21 -0700 Subject: Break up misc Object extensions --- .../lib/active_support/core_ext/object/misc.rb | 83 +--------------------- .../active_support/core_ext/object/returning.rb | 42 +++++++++++ .../lib/active_support/core_ext/object/tap.rb | 16 +++++ .../active_support/core_ext/object/with_options.rb | 24 +++++++ 4 files changed, 85 insertions(+), 80 deletions(-) create mode 100644 activesupport/lib/active_support/core_ext/object/returning.rb create mode 100644 activesupport/lib/active_support/core_ext/object/tap.rb create mode 100644 activesupport/lib/active_support/core_ext/object/with_options.rb diff --git a/activesupport/lib/active_support/core_ext/object/misc.rb b/activesupport/lib/active_support/core_ext/object/misc.rb index fb1bcdb98f..80011dfbed 100644 --- a/activesupport/lib/active_support/core_ext/object/misc.rb +++ b/activesupport/lib/active_support/core_ext/object/misc.rb @@ -1,80 +1,3 @@ -class Object - # Returns +value+ after yielding +value+ to the block. This simplifies the - # process of constructing an object, performing work on the object, and then - # returning the object from a method. It is a Ruby-ized realization of the K - # combinator, courtesy of Mikael Brockman. - # - # ==== Examples - # - # # Without returning - # def foo - # values = [] - # values << "bar" - # values << "baz" - # return values - # end - # - # foo # => ['bar', 'baz'] - # - # # returning with a local variable - # def foo - # returning values = [] do - # values << 'bar' - # values << 'baz' - # end - # end - # - # foo # => ['bar', 'baz'] - # - # # returning with a block argument - # def foo - # returning [] do |values| - # values << 'bar' - # values << 'baz' - # end - # end - # - # foo # => ['bar', 'baz'] - def returning(value) - yield(value) - value - end - - # Yields x to the block, and then returns x. - # The primary purpose of this method is to "tap into" a method chain, - # in order to perform operations on intermediate results within the chain. - # - # (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a. - # tap { |x| puts "array: #{x.inspect}" }. - # select { |x| x%2 == 0 }. - # tap { |x| puts "evens: #{x.inspect}" }. - # map { |x| x*x }. - # tap { |x| puts "squares: #{x.inspect}" } - def tap - yield self - self - end unless Object.respond_to?(:tap) - - # An elegant way to factor duplication out of options passed to a series of - # method calls. Each method called in the block, with the block variable as - # the receiver, will have its options merged with the default +options+ hash - # provided. Each method called on the block variable must take an options - # hash as its final argument. - # - # with_options :order => 'created_at', :class_name => 'Comment' do |post| - # post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all - # post.has_many :unapproved_comments, :conditions => ['approved = ?', false] - # post.has_many :all_comments - # end - # - # Can also be used with an explicit receiver: - # - # map.with_options :controller => "people" do |people| - # people.connect "/people", :action => "index" - # people.connect "/people/:id", :action => "show" - # end - # - def with_options(options) - yield ActiveSupport::OptionMerger.new(self, options) - end -end +require 'active_support/core_ext/object/returning' +require 'active_support/core_ext/object/tap' +require 'active_support/core_ext/object/with_options' diff --git a/activesupport/lib/active_support/core_ext/object/returning.rb b/activesupport/lib/active_support/core_ext/object/returning.rb new file mode 100644 index 0000000000..0dc2e1266a --- /dev/null +++ b/activesupport/lib/active_support/core_ext/object/returning.rb @@ -0,0 +1,42 @@ +class Object + # Returns +value+ after yielding +value+ to the block. This simplifies the + # process of constructing an object, performing work on the object, and then + # returning the object from a method. It is a Ruby-ized realization of the K + # combinator, courtesy of Mikael Brockman. + # + # ==== Examples + # + # # Without returning + # def foo + # values = [] + # values << "bar" + # values << "baz" + # return values + # end + # + # foo # => ['bar', 'baz'] + # + # # returning with a local variable + # def foo + # returning values = [] do + # values << 'bar' + # values << 'baz' + # end + # end + # + # foo # => ['bar', 'baz'] + # + # # returning with a block argument + # def foo + # returning [] do |values| + # values << 'bar' + # values << 'baz' + # end + # end + # + # foo # => ['bar', 'baz'] + def returning(value) + yield(value) + value + end +end diff --git a/activesupport/lib/active_support/core_ext/object/tap.rb b/activesupport/lib/active_support/core_ext/object/tap.rb new file mode 100644 index 0000000000..db7e715e2d --- /dev/null +++ b/activesupport/lib/active_support/core_ext/object/tap.rb @@ -0,0 +1,16 @@ +class Object + # Yields x to the block, and then returns x. + # The primary purpose of this method is to "tap into" a method chain, + # in order to perform operations on intermediate results within the chain. + # + # (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a. + # tap { |x| puts "array: #{x.inspect}" }. + # select { |x| x%2 == 0 }. + # tap { |x| puts "evens: #{x.inspect}" }. + # map { |x| x*x }. + # tap { |x| puts "squares: #{x.inspect}" } + def tap + yield self + self + end unless Object.respond_to?(:tap) +end diff --git a/activesupport/lib/active_support/core_ext/object/with_options.rb b/activesupport/lib/active_support/core_ext/object/with_options.rb new file mode 100644 index 0000000000..dd38b7d261 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/object/with_options.rb @@ -0,0 +1,24 @@ +class Object + # An elegant way to factor duplication out of options passed to a series of + # method calls. Each method called in the block, with the block variable as + # the receiver, will have its options merged with the default +options+ hash + # provided. Each method called on the block variable must take an options + # hash as its final argument. + # + # with_options :order => 'created_at', :class_name => 'Comment' do |post| + # post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all + # post.has_many :unapproved_comments, :conditions => ['approved = ?', false] + # post.has_many :all_comments + # end + # + # Can also be used with an explicit receiver: + # + # map.with_options :controller => "people" do |people| + # people.connect "/people", :action => "index" + # people.connect "/people/:id", :action => "show" + # end + # + def with_options(options) + yield ActiveSupport::OptionMerger.new(self, options) + end +end -- cgit v1.2.3 From 3694227f24d0f220c0ce7ef6c7f51598e2715d2d Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 17:10:10 -0700 Subject: Break out Symbol#to_proc as a future-ruby extension --- activesupport/lib/active_support/core_ext/symbol.rb | 15 +-------------- .../lib/active_support/core_ext/symbol/to_proc.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 14 deletions(-) create mode 100644 activesupport/lib/active_support/core_ext/symbol/to_proc.rb diff --git a/activesupport/lib/active_support/core_ext/symbol.rb b/activesupport/lib/active_support/core_ext/symbol.rb index 520369452b..c103cd9dcf 100644 --- a/activesupport/lib/active_support/core_ext/symbol.rb +++ b/activesupport/lib/active_support/core_ext/symbol.rb @@ -1,14 +1 @@ -class Symbol - # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples: - # - # # The same as people.collect { |p| p.name } - # people.collect(&:name) - # - # # The same as people.select { |p| p.manager? }.collect { |p| p.salary } - # people.select(&:manager?).collect(&:salary) - # - # This is a builtin method in Ruby 1.8.7 and later. - def to_proc - Proc.new { |*args| args.shift.__send__(self, *args) } - end unless :to_proc.respond_to?(:to_proc) -end +require 'active_support/core_ext/symbol/to_proc' diff --git a/activesupport/lib/active_support/core_ext/symbol/to_proc.rb b/activesupport/lib/active_support/core_ext/symbol/to_proc.rb new file mode 100644 index 0000000000..520369452b --- /dev/null +++ b/activesupport/lib/active_support/core_ext/symbol/to_proc.rb @@ -0,0 +1,14 @@ +class Symbol + # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples: + # + # # The same as people.collect { |p| p.name } + # people.collect(&:name) + # + # # The same as people.select { |p| p.manager? }.collect { |p| p.salary } + # people.select(&:manager?).collect(&:salary) + # + # This is a builtin method in Ruby 1.8.7 and later. + def to_proc + Proc.new { |*args| args.shift.__send__(self, *args) } + end unless :to_proc.respond_to?(:to_proc) +end -- cgit v1.2.3 From 5f222c524ed00b2ac805e267f70a916cf8f9bc77 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 17:11:41 -0700 Subject: Remove 'core' fluff. Hookable ActiveSupport.load_all! --- activerecord/lib/active_record/base.rb | 2 +- activesupport/lib/active_support.rb | 11 +++++++++-- activesupport/lib/active_support/all.rb | 3 +++ activesupport/lib/active_support/core.rb | 7 ------- activesupport/lib/active_support/core/all.rb | 5 ----- activesupport/lib/active_support/core/time.rb | 4 ---- activesupport/lib/active_support/core/time/autoload.rb | 5 ----- .../lib/active_support/core_ext/hash/conversions.rb | 3 +-- activesupport/lib/active_support/time.rb | 14 ++++++++++++++ activesupport/lib/active_support/time/autoload.rb | 5 +++++ activesupport/test/core_ext/duration_test.rb | 2 +- activesupport/test/core_ext/numeric_ext_test.rb | 2 +- activesupport/test/core_ext/object_and_class_ext_test.rb | 2 +- activesupport/test/core_ext/time_ext_test.rb | 2 +- activesupport/test/i18n_test.rb | 2 +- activesupport/test/time_zone_test.rb | 2 +- railties/lib/console_app.rb | 3 +-- railties/lib/initializer.rb | 3 +-- railties/lib/rails_generator.rb | 13 +++---------- railties/lib/tasks/misc.rake | 4 ++-- 20 files changed, 46 insertions(+), 48 deletions(-) create mode 100644 activesupport/lib/active_support/all.rb delete mode 100644 activesupport/lib/active_support/core.rb delete mode 100644 activesupport/lib/active_support/core/all.rb delete mode 100644 activesupport/lib/active_support/core/time.rb delete mode 100644 activesupport/lib/active_support/core/time/autoload.rb create mode 100644 activesupport/lib/active_support/time.rb create mode 100644 activesupport/lib/active_support/time/autoload.rb diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 8a65945e61..ec49d40a12 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1,6 +1,7 @@ require 'yaml' require 'set' require 'active_support/dependencies' +require 'active_support/time' require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/class/delegating_attributes' require 'active_support/core_ext/class/inheritable_attributes' @@ -10,7 +11,6 @@ require 'active_support/core_ext/hash/indifferent_access' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/string/behavior' require 'active_support/core_ext/symbol' -require 'active_support/core/time' module ActiveRecord #:nodoc: # Generic Active Record exception class. diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index dab017770d..a1a140bc33 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -22,8 +22,15 @@ #++ module ActiveSupport - def self.load_all! - [Dependencies, Deprecation, Gzip, MessageVerifier, Multibyte, SecureRandom] + Core.load_all! + class << self + attr_accessor :load_all_hooks + def on_load_all(&hook) load_all_hooks << hook end + def load_all!; load_all_hooks.each { |hook| hook.call } end + end + self.load_all_hooks = [] + + on_load_all do + [Dependencies, Deprecation, Gzip, MessageVerifier, Multibyte, SecureRandom] end autoload :BacktraceCleaner, 'active_support/backtrace_cleaner' diff --git a/activesupport/lib/active_support/all.rb b/activesupport/lib/active_support/all.rb new file mode 100644 index 0000000000..f537818300 --- /dev/null +++ b/activesupport/lib/active_support/all.rb @@ -0,0 +1,3 @@ +require 'active_support' +require 'active_support/time' +require 'active_support/core_ext' diff --git a/activesupport/lib/active_support/core.rb b/activesupport/lib/active_support/core.rb deleted file mode 100644 index ad8db94941..0000000000 --- a/activesupport/lib/active_support/core.rb +++ /dev/null @@ -1,7 +0,0 @@ -module ActiveSupport - module Core - def self.load_all! - [TimeWithZone] - end - end -end diff --git a/activesupport/lib/active_support/core/all.rb b/activesupport/lib/active_support/core/all.rb deleted file mode 100644 index 55e8b4cfac..0000000000 --- a/activesupport/lib/active_support/core/all.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'active_support/core_ext' -require 'active_support/core' -Dir["#{File.dirname(__FILE__)}/*.rb"].sort.each do |path| - require "active_support/core/#{File.basename(path, '.rb')}" -end diff --git a/activesupport/lib/active_support/core/time.rb b/activesupport/lib/active_support/core/time.rb deleted file mode 100644 index 43e13b5e58..0000000000 --- a/activesupport/lib/active_support/core/time.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'active_support/core/time/autoload' -require 'active_support/core_ext/time' -require 'active_support/core_ext/date' -require 'active_support/core_ext/date_time' diff --git a/activesupport/lib/active_support/core/time/autoload.rb b/activesupport/lib/active_support/core/time/autoload.rb deleted file mode 100644 index c9a7731b39..0000000000 --- a/activesupport/lib/active_support/core/time/autoload.rb +++ /dev/null @@ -1,5 +0,0 @@ -module ActiveSupport - autoload :Duration, 'active_support/duration' - autoload :TimeWithZone, 'active_support/time_with_zone' - autoload :TimeZone, 'active_support/values/time_zone' -end diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb index fe1f79050c..2a34874d08 100644 --- a/activesupport/lib/active_support/core_ext/hash/conversions.rb +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb @@ -1,8 +1,7 @@ -require 'date' +require 'active_support/time' require 'active_support/core_ext/object/conversions' require 'active_support/core_ext/array/conversions' require 'active_support/core_ext/hash/reverse_merge' -require 'active_support/core/time' class Hash # This module exists to decorate files deserialized using Hash.from_xml with diff --git a/activesupport/lib/active_support/time.rb b/activesupport/lib/active_support/time.rb new file mode 100644 index 0000000000..d36a683601 --- /dev/null +++ b/activesupport/lib/active_support/time.rb @@ -0,0 +1,14 @@ +require 'active_support' +require 'active_support/core_ext/time' +require 'active_support/core_ext/date' +require 'active_support/core_ext/date_time' + +module ActiveSupport + autoload :Duration, 'active_support/duration' + autoload :TimeWithZone, 'active_support/time_with_zone' + autoload :TimeZone, 'active_support/values/time_zone' + + on_load_all do + [Duration, TimeWithZone, TimeZone] + end +end diff --git a/activesupport/lib/active_support/time/autoload.rb b/activesupport/lib/active_support/time/autoload.rb new file mode 100644 index 0000000000..c9a7731b39 --- /dev/null +++ b/activesupport/lib/active_support/time/autoload.rb @@ -0,0 +1,5 @@ +module ActiveSupport + autoload :Duration, 'active_support/duration' + autoload :TimeWithZone, 'active_support/time_with_zone' + autoload :TimeZone, 'active_support/values/time_zone' +end diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb index 30d4152729..6f16621ae5 100644 --- a/activesupport/test/core_ext/duration_test.rb +++ b/activesupport/test/core_ext/duration_test.rb @@ -1,5 +1,5 @@ require 'abstract_unit' -require 'active_support/core/time' +require 'active_support/time' class DurationTest < ActiveSupport::TestCase def test_inspect diff --git a/activesupport/test/core_ext/numeric_ext_test.rb b/activesupport/test/core_ext/numeric_ext_test.rb index 74b086fa9c..992ec60302 100644 --- a/activesupport/test/core_ext/numeric_ext_test.rb +++ b/activesupport/test/core_ext/numeric_ext_test.rb @@ -1,7 +1,7 @@ require 'abstract_unit' +require 'active_support/time' require 'active_support/core_ext/numeric' require 'active_support/core_ext/integer' -require 'active_support/core/time' class NumericExtTimeAndDateTimeTest < Test::Unit::TestCase def setup diff --git a/activesupport/test/core_ext/object_and_class_ext_test.rb b/activesupport/test/core_ext/object_and_class_ext_test.rb index 8869b053e6..f0121b862d 100644 --- a/activesupport/test/core_ext/object_and_class_ext_test.rb +++ b/activesupport/test/core_ext/object_and_class_ext_test.rb @@ -1,7 +1,7 @@ require 'abstract_unit' +require 'active_support/time' require 'active_support/core_ext/object' require 'active_support/core_ext/class/removal' -require 'active_support/core/time' class ClassA; end class ClassB < ClassA; end diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index e265423f06..1c2d0fbce4 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -1,5 +1,5 @@ require 'abstract_unit' -require 'active_support/core/time' +require 'active_support/time' class TimeExtCalculationsTest < Test::Unit::TestCase def test_seconds_since_midnight diff --git a/activesupport/test/i18n_test.rb b/activesupport/test/i18n_test.rb index 2a08abfb3e..9868f1e87d 100644 --- a/activesupport/test/i18n_test.rb +++ b/activesupport/test/i18n_test.rb @@ -1,5 +1,5 @@ require 'abstract_unit' -require 'active_support/core/time' +require 'active_support/time' require 'active_support/core_ext/array/conversions' class I18nTest < Test::Unit::TestCase diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb index 87d6ccc30d..99c4310854 100644 --- a/activesupport/test/time_zone_test.rb +++ b/activesupport/test/time_zone_test.rb @@ -1,5 +1,5 @@ require 'abstract_unit' -require 'active_support/core/time' +require 'active_support/time' class TimeZoneTest < Test::Unit::TestCase def test_utc_to_local diff --git a/railties/lib/console_app.rb b/railties/lib/console_app.rb index 42bf50e01e..75e6f11ea3 100644 --- a/railties/lib/console_app.rb +++ b/railties/lib/console_app.rb @@ -1,5 +1,4 @@ -require 'active_support' -require 'active_support/core/all' +require 'active_support/all' require 'active_support/test_case' require 'action_controller' diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb index 4c6de48a65..3c0d5940ea 100644 --- a/railties/lib/initializer.rb +++ b/railties/lib/initializer.rb @@ -263,9 +263,8 @@ module Rails # list. By default, all frameworks (Active Record, Active Support, # Action Pack, Action Mailer, and Active Resource) are loaded. def require_frameworks - require 'active_support' + require 'active_support/all' configuration.frameworks.each { |framework| require(framework.to_s) } - require 'active_support/core/all' rescue LoadError => e # Re-raise as RuntimeError because Mongrel would swallow LoadError. raise e.to_s diff --git a/railties/lib/rails_generator.rb b/railties/lib/rails_generator.rb index 201a9e0f91..85400932dd 100644 --- a/railties/lib/rails_generator.rb +++ b/railties/lib/rails_generator.rb @@ -21,16 +21,9 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #++ -begin - require 'active_support' -rescue LoadError - activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib" - if File.directory?(activesupport_path) - $:.unshift activesupport_path - require 'active_support' - end -end -require 'active_support/core/all' +activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib" +$:.unshift(activesupport_path) if File.directory?(activesupport_path) +require 'active_support/all' $:.unshift(File.dirname(__FILE__)) require 'rails_generator/base' diff --git a/railties/lib/tasks/misc.rake b/railties/lib/tasks/misc.rake index a2c338aa5b..fb2fc31dc1 100644 --- a/railties/lib/tasks/misc.rake +++ b/railties/lib/tasks/misc.rake @@ -31,7 +31,7 @@ namespace :time do desc 'Displays names of time zones recognized by the Rails TimeZone class with the same offset as the system local time' task :local do require 'active_support' - require 'active_support/core/time' + require 'active_support/time' jan_offset = Time.now.beginning_of_year.utc_offset jul_offset = Time.now.beginning_of_year.change(:month => 7).utc_offset offset = jan_offset < jul_offset ? jan_offset : jul_offset @@ -41,7 +41,7 @@ namespace :time do # to find UTC -06:00 zones, OFFSET can be set to either -6, -6:00 or 21600 def build_time_zone_list(method, offset = ENV['OFFSET']) require 'active_support' - require 'active_support/core/time' + require 'active_support/time' if offset offset = if offset.to_s.match(/(\+|-)?(\d+):(\d+)/) sign = $1 == '-' ? -1 : 1 -- cgit v1.2.3 From 886aa2f0e1a1a95a5b518d918fefaa526755ad34 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 17:58:35 -0700 Subject: Extract autoloads --- activesupport/lib/active_support.rb | 25 +------------------------ activesupport/lib/active_support/autoload.rb | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 24 deletions(-) create mode 100644 activesupport/lib/active_support/autoload.rb diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index a1a140bc33..a20635ba62 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -32,32 +32,9 @@ module ActiveSupport on_load_all do [Dependencies, Deprecation, Gzip, MessageVerifier, Multibyte, SecureRandom] end - - autoload :BacktraceCleaner, 'active_support/backtrace_cleaner' - autoload :Base64, 'active_support/base64' - autoload :BasicObject, 'active_support/basic_object' - autoload :BufferedLogger, 'active_support/buffered_logger' - autoload :Cache, 'active_support/cache' - autoload :Callbacks, 'active_support/callbacks' - autoload :NewCallbacks, 'active_support/new_callbacks' - autoload :ConcurrentHash, 'active_support/concurrent_hash' - autoload :DependencyModule, 'active_support/dependency_module' - autoload :Deprecation, 'active_support/deprecation' - autoload :Gzip, 'active_support/gzip' - autoload :Inflector, 'active_support/inflector' - autoload :Memoizable, 'active_support/memoizable' - autoload :MessageEncryptor, 'active_support/message_encryptor' - autoload :MessageVerifier, 'active_support/message_verifier' - autoload :Multibyte, 'active_support/multibyte' - autoload :OptionMerger, 'active_support/option_merger' - autoload :OrderedHash, 'active_support/ordered_hash' - autoload :OrderedOptions, 'active_support/ordered_options' - autoload :Rescuable, 'active_support/rescuable' - autoload :SecureRandom, 'active_support/secure_random' - autoload :StringInquirer, 'active_support/string_inquirer' - autoload :XmlMini, 'active_support/xml_mini' end +require 'active_support/autoload' require 'active_support/vendor' I18n.load_path << "#{File.dirname(__FILE__)}/active_support/locale/en.yml" diff --git a/activesupport/lib/active_support/autoload.rb b/activesupport/lib/active_support/autoload.rb new file mode 100644 index 0000000000..ed229d1c5f --- /dev/null +++ b/activesupport/lib/active_support/autoload.rb @@ -0,0 +1,25 @@ +module ActiveSupport + autoload :BacktraceCleaner, 'active_support/backtrace_cleaner' + autoload :Base64, 'active_support/base64' + autoload :BasicObject, 'active_support/basic_object' + autoload :BufferedLogger, 'active_support/buffered_logger' + autoload :Cache, 'active_support/cache' + autoload :Callbacks, 'active_support/callbacks' + autoload :NewCallbacks, 'active_support/new_callbacks' + autoload :ConcurrentHash, 'active_support/concurrent_hash' + autoload :DependencyModule, 'active_support/dependency_module' + autoload :Deprecation, 'active_support/deprecation' + autoload :Gzip, 'active_support/gzip' + autoload :Inflector, 'active_support/inflector' + autoload :Memoizable, 'active_support/memoizable' + autoload :MessageEncryptor, 'active_support/message_encryptor' + autoload :MessageVerifier, 'active_support/message_verifier' + autoload :Multibyte, 'active_support/multibyte' + autoload :OptionMerger, 'active_support/option_merger' + autoload :OrderedHash, 'active_support/ordered_hash' + autoload :OrderedOptions, 'active_support/ordered_options' + autoload :Rescuable, 'active_support/rescuable' + autoload :SecureRandom, 'active_support/secure_random' + autoload :StringInquirer, 'active_support/string_inquirer' + autoload :XmlMini, 'active_support/xml_mini' +end -- cgit v1.2.3 From 428829fc38d06be63082e261d59f478a4b7dd354 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 17:59:34 -0700 Subject: Single-require forward compatibility with new Ruby features like Object#tap, Enumerable#group_by, and Process.daemon. Code with the latest but run anywhere. --- activesupport/lib/active_support/ruby/shim.rb | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 activesupport/lib/active_support/ruby/shim.rb diff --git a/activesupport/lib/active_support/ruby/shim.rb b/activesupport/lib/active_support/ruby/shim.rb new file mode 100644 index 0000000000..37c57c485a --- /dev/null +++ b/activesupport/lib/active_support/ruby/shim.rb @@ -0,0 +1,24 @@ +# Backported Ruby builtins so you can code with the latest & greatest +# but still run on any Ruby 1.8.x. +# +# Date next_year, next_month +# DateTime to_date, to_datetime, xmlschema +# Enumerable group_by, each_with_object, none? +# Integer even?, odd? +# Object tap +# Process Process.daemon +# REXML security fix +# String ord +# Symbol to_proc +# Time to_date, to_time, to_datetime +require 'active_support' +require 'active_support/core_ext/date/calculations' +require 'active_support/core_ext/date_time/conversions' +require 'active_support/core_ext/enumerable' +require 'active_support/core_ext/integer/even_odd' +require 'active_support/core_ext/object/tap' +require 'active_support/core_ext/process/daemon' +require 'active_support/core_ext/string/conversions' +require 'active_support/core_ext/rexml' +require 'active_support/core_ext/symbol/to_proc' +require 'active_support/core_ext/time/conversions' -- cgit v1.2.3 From e9a75451236119e1db3e5d7cc7703637d048c7f8 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 20 May 2009 18:11:06 -0700 Subject: Avoid uninitialized instance variable warning --- activesupport/lib/active_support/json.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/activesupport/lib/active_support/json.rb b/activesupport/lib/active_support/json.rb index 1e8ded12da..6d845182fb 100644 --- a/activesupport/lib/active_support/json.rb +++ b/activesupport/lib/active_support/json.rb @@ -43,10 +43,10 @@ module ActiveSupport delegate :decode, :to => :backend def backend - @backend || begin + unless defined? @backend self.backend = defined?(::JSON) ? "JSONGem" : "Yaml" - @backend end + @backend end def backend=(name) -- cgit v1.2.3 From 0f1b283e03633410729aa006f6abf070c713095d Mon Sep 17 00:00:00 2001 From: Chad Woolley Date: Thu, 21 May 2009 00:41:19 -0700 Subject: Fix eager association test related to different ordering on sqlite [#2686 state:committed] Signed-off-by: Jeremy Kemper --- activerecord/test/cases/associations/eager_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 65049c4f87..4cf49be668 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -590,7 +590,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_limited_eager_with_numeric_in_association - assert_equal people(:david, :susan), Person.find(:all, :include => [:readers, :primary_contact, :number1_fan], :conditions => "number1_fans_people.first_name like 'M%'", :order => 'readers.id', :limit => 2, :offset => 0) + assert_equal people(:david, :susan), Person.find(:all, :include => [:readers, :primary_contact, :number1_fan], :conditions => "number1_fans_people.first_name like 'M%'", :order => 'people.id', :limit => 2, :offset => 0) end def test_preload_with_interpolation -- cgit v1.2.3 From 886eeed52e17184747b43f57282d8635614f1be3 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 21 May 2009 10:03:32 -0700 Subject: Clean up tools/profile_requires a bit --- tools/profile_requires | 60 +++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/tools/profile_requires b/tools/profile_requires index 0fd11c7d41..927467bc4e 100755 --- a/tools/profile_requires +++ b/tools/profile_requires @@ -4,58 +4,52 @@ # tools/profile_requires activeresource/examples/simple.rb abort 'Use REE so you can profile memory and object allocation' unless GC.respond_to?(:enable_stats) +ENV['NO_RELOAD'] ||= '1' +ENV['RAILS_ENV'] ||= 'development' + GC.enable_stats require 'rubygems' Gem.source_index require 'benchmark' -module TrackHeapGrowth +module RequireProfiler + def require(file, *args) RequireProfiler.profile(file) { super } end + def load(file, *args) RequireProfiler.profile(file) { super } end + + @depth, @stats = 0, [] class << self - attr_accessor :indent + attr_accessor :depth attr_accessor :stats - end - self.indent = 0 - self.stats = [] - - def track_growth(file) - TrackHeapGrowth.stats << [file, TrackHeapGrowth.indent] - TrackHeapGrowth.indent += 1 - heap_before, objects_before = GC.allocated_size, ObjectSpace.allocated_objects - result = nil - elapsed = Benchmark.realtime { result = yield } - heap_after, objects_after = GC.allocated_size, ObjectSpace.allocated_objects - TrackHeapGrowth.indent -= 1 - TrackHeapGrowth.stats.pop if TrackHeapGrowth.stats.last.first == file - TrackHeapGrowth.stats << [file, TrackHeapGrowth.indent, elapsed, heap_after - heap_before, objects_after - objects_before] if result - result - end - def require(file, *args) - track_growth(file) { super } - end - - def load(file, *args) - track_growth(file) { super } + def profile(file) + stats << [file, depth] + self.depth += 1 + heap_before, objects_before = GC.allocated_size, ObjectSpace.allocated_objects + result = nil + elapsed = Benchmark.realtime { result = yield } + heap_after, objects_after = GC.allocated_size, ObjectSpace.allocated_objects + self.depth -= 1 + stats.pop if stats.last.first == file + stats << [file, depth, elapsed, heap_after - heap_before, objects_after - objects_before] if result + result + end end end -Object.instance_eval { include TrackHeapGrowth } - GC.start before = GC.allocated_size before_rss = `ps -o rss= -p #{Process.pid}`.to_i before_live_objects = ObjectSpace.live_objects path = ARGV.shift - if mode = ARGV.shift require 'ruby-prof' RubyProf.measure_mode = RubyProf.const_get(mode.upcase) RubyProf.start +else + Object.instance_eval { include RequireProfiler } end -ENV['NO_RELOAD'] ||= '1' -ENV['RAILS_ENV'] ||= 'development' elapsed = Benchmark.realtime { require path } results = RubyProf.stop if mode @@ -66,16 +60,16 @@ after = GC.allocated_size usage = (after - before) / 1024.0 if mode - File.open("profile_startup.#{mode}.tree", 'w') do |out| + File.open("#{File.basename(path, '.rb')}.#{mode}.callgrind", 'w') do |out| RubyProf::CallTreePrinter.new(results).print(out) end end -TrackHeapGrowth.stats.each do |file, indent, sec, bytes, objects| +RequireProfiler.stats.each do |file, depth, sec, bytes, objects| if sec - puts "%10.2f KB %10d obj %8.1f ms %s%s" % [bytes / 1024.0, objects, sec * 1000, ' ' * indent, file] + puts "%10.2f KB %10d obj %8.1f ms %s%s" % [bytes / 1024.0, objects, sec * 1000, ' ' * depth, file] else - puts "#{' ' * (42 + indent)}#{file}" + puts "#{' ' * (42 + depth)}#{file}" end end puts "%10.2f KB %10d obj %8.1f ms %d KB RSS" % [usage, after_live_objects - before_live_objects, elapsed * 1000, after_rss - before_rss] -- cgit v1.2.3 From 59b32f2883b58a1e7bf2c246801a605b673e3fb6 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 May 2009 11:50:34 +0200 Subject: RequestForgeryProtection now works with the new base --- actionpack/Rakefile | 2 +- .../base/request_forgery_protection.rb | 24 +++++++++++++++++----- actionpack/lib/action_controller/new_base.rb | 5 +++-- actionpack/lib/action_controller/new_base/base.rb | 9 ++++---- .../action_controller/new_base/compatibility.rb | 6 ++++-- actionpack/lib/action_dispatch.rb | 1 + 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 3a6a54768e..84b42b4eb3 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -63,7 +63,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| t.test_files = %w( addresses_render base benchmark caching capture content_type dispatcher flash mime_responds record_identifier redirect render rescue url_rewriter - webservice verification + webservice verification request_forgery_protection ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/base/request_forgery_protection.rb b/actionpack/lib/action_controller/base/request_forgery_protection.rb index 3067122ceb..0a0e20e1f1 100644 --- a/actionpack/lib/action_controller/base/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/base/request_forgery_protection.rb @@ -3,12 +3,26 @@ module ActionController #:nodoc: end module RequestForgeryProtection - def self.included(base) - base.class_eval do - helper_method :form_authenticity_token - helper_method :protect_against_forgery? + extend ActiveSupport::DependencyModule + + # TODO : Remove the defined? check when new base is the main base + if defined?(ActionController::Http) + depends_on AbstractController::Helpers, Session + end + + included do + if defined?(ActionController::Http) + # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+ + # sets it to :authenticity_token by default. + cattr_accessor :request_forgery_protection_token + + # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode. + class_inheritable_accessor :allow_forgery_protection + self.allow_forgery_protection = true end - base.extend(ClassMethods) + + helper_method :form_authenticity_token + helper_method :protect_against_forgery? end # Protecting controller actions from CSRF attacks by ensuring that all forms are coming from the current web application, not a diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 8bc15d2450..93c54174b7 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -25,8 +25,9 @@ module ActionController autoload :UrlRewriter, 'action_controller/routing/generation/url_rewriter' autoload :UrlWriter, 'action_controller/routing/generation/url_rewriter' - autoload :Verification, 'action_controller/base/verification' - autoload :Flash, 'action_controller/base/chained/flash' + autoload :Verification, 'action_controller/base/verification' + autoload :Flash, 'action_controller/base/chained/flash' + autoload :RequestForgeryProtection, 'action_controller/base/request_forgery_protection' require 'action_controller/routing' end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index a419a80b6a..3d8f785280 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -14,10 +14,6 @@ module ActionController include ActionController::Layouts include ActionController::ConditionalGet - include ActionController::Session - include ActionController::Flash - include ActionController::Verification - # Legacy modules include SessionManagement include ActionDispatch::StatusCodes @@ -27,6 +23,11 @@ module ActionController # Rails 2.x compatibility include ActionController::Rails2Compatibility + include ActionController::Session + include ActionController::Flash + include ActionController::Verification + include ActionController::RequestForgeryProtection + # TODO: Extract into its own module # This should be moved together with other normalizing behavior module ImplicitRender diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index 9b85b39052..522a9fe23b 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -1,7 +1,10 @@ module ActionController module Rails2Compatibility extend ActiveSupport::DependencyModule - + + class ::ActionController::ActionControllerError < StandardError #:nodoc: + end + # Temporary hax included do ::ActionController::UnknownAction = ::AbstractController::ActionNotFound @@ -65,7 +68,6 @@ module ActionController end module ClassMethods - def protect_from_forgery() end def consider_all_requests_local() end def rescue_action(env) raise env["action_dispatch.rescue.exception"] diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index ee162765cb..884828a01a 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -46,6 +46,7 @@ module ActionDispatch autoload :ShowExceptions, 'action_dispatch/middleware/show_exceptions' autoload :MiddlewareStack, 'action_dispatch/middleware/stack' + autoload :HTML, 'action_controller/vendor/html-scanner' autoload :Assertions, 'action_dispatch/testing/assertions' autoload :TestRequest, 'action_dispatch/testing/test_request' autoload :TestResponse, 'action_dispatch/testing/test_response' -- cgit v1.2.3 From 386ff66e5ed4fbe1e060610d4226a4eb22dca766 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 May 2009 21:48:26 +0200 Subject: Add Streaming to new base --- actionpack/Rakefile | 2 +- actionpack/lib/action_controller/base/streaming.rb | 1 + actionpack/lib/action_controller/new_base.rb | 2 +- actionpack/lib/action_controller/new_base/base.rb | 1 + .../lib/action_controller/new_base/testing.rb | 9 ++++++-- .../lib/action_controller/testing/process2.rb | 1 + actionpack/test/controller/send_file_test.rb | 24 ++++++++++++---------- 7 files changed, 25 insertions(+), 15 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 84b42b4eb3..5968317c60 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -63,7 +63,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| t.test_files = %w( addresses_render base benchmark caching capture content_type dispatcher flash mime_responds record_identifier redirect render rescue url_rewriter - webservice verification request_forgery_protection + webservice verification request_forgery_protection send_file ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/base/streaming.rb b/actionpack/lib/action_controller/base/streaming.rb index 9f80f48c3d..b69b13eea8 100644 --- a/actionpack/lib/action_controller/base/streaming.rb +++ b/actionpack/lib/action_controller/base/streaming.rb @@ -88,6 +88,7 @@ module ActionController #:nodoc: head options[:status], X_SENDFILE_HEADER => path else if options[:stream] + # TODO : Make render :text => proc {} work with the new base render :status => options[:status], :text => Proc.new { |response, output| logger.info "Streaming file #{path}" unless logger.nil? len = options[:buffer_size] || 4096 diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 93c54174b7..58c7382661 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -28,7 +28,7 @@ module ActionController autoload :Verification, 'action_controller/base/verification' autoload :Flash, 'action_controller/base/chained/flash' autoload :RequestForgeryProtection, 'action_controller/base/request_forgery_protection' - + autoload :Streaming, 'action_controller/base/streaming' require 'action_controller/routing' end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 3d8f785280..142699326e 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -27,6 +27,7 @@ module ActionController include ActionController::Flash include ActionController::Verification include ActionController::RequestForgeryProtection + include ActionController::Streaming # TODO: Extract into its own module # This should be moved together with other normalizing behavior diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb index bc3bc70404..6a92c292bd 100644 --- a/actionpack/lib/action_controller/new_base/testing.rb +++ b/actionpack/lib/action_controller/new_base/testing.rb @@ -1,6 +1,6 @@ module ActionController module Testing - + # OMG MEGA HAX def process_with_new_base_test(request, response) @_request = request @@ -20,6 +20,11 @@ module ActionController @assigns[name] = value end end - + + # TODO : Rewrite tests using controller.headers= to use Rack env + def headers=(new_headers) + @_response ||= ActionDispatch::Response.new + @_response.headers.replace(new_headers) + end end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb index 2dafcaa5a9..6a95e638cd 100644 --- a/actionpack/lib/action_controller/testing/process2.rb +++ b/actionpack/lib/action_controller/testing/process2.rb @@ -54,6 +54,7 @@ module ActionController @controller.params.merge!(parameters) # Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest @controller.process_with_new_base_test(@request, @response) + @response end def build_request_uri(action, parameters) diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index 6007ebef7a..3a99774ae0 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -40,17 +40,19 @@ class SendFileTest < ActionController::TestCase assert_equal file_data, response.body end - def test_file_stream - response = nil - assert_nothing_raised { response = process('file') } - assert_not_nil response - assert_kind_of Array, response.body_parts - - require 'stringio' - output = StringIO.new - output.binmode - assert_nothing_raised { response.body_parts.each { |part| output << part.to_s } } - assert_equal file_data, output.string + for_tag(:old_base) do + def test_file_stream + response = nil + assert_nothing_raised { response = process('file') } + assert_not_nil response + assert_kind_of Array, response.body_parts + + require 'stringio' + output = StringIO.new + output.binmode + assert_nothing_raised { response.body_parts.each { |part| output << part.to_s } } + assert_equal file_data, output.string + end end def test_file_url_based_filename -- cgit v1.2.3 From e693f45e155a81b6c337b8766870b56716a05105 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 21 May 2009 14:22:07 -0700 Subject: Remove some response content type concepts from ActionView --- .../lib/action_controller/base/mime_responds.rb | 7 +++---- actionpack/lib/action_controller/new_base/base.rb | 20 ++++++++++++++++---- .../lib/action_controller/new_base/renderer.rb | 20 +++++++++++--------- actionpack/lib/action_controller/testing/process2.rb | 1 + actionpack/lib/action_dispatch/http/mime_type.rb | 2 +- actionpack/lib/action_dispatch/http/request.rb | 2 +- actionpack/lib/action_view/base.rb | 7 +++++-- actionpack/lib/action_view/template/handler.rb | 5 +++++ .../lib/action_view/template/handlers/builder.rb | 2 ++ actionpack/lib/action_view/template/handlers/erb.rb | 2 ++ actionpack/lib/action_view/template/handlers/rjs.rb | 6 ++++++ actionpack/lib/action_view/template/template.rb | 15 ++++++++------- actionpack/test/controller/content_type_test.rb | 3 ++- 13 files changed, 63 insertions(+), 29 deletions(-) diff --git a/actionpack/lib/action_controller/base/mime_responds.rb b/actionpack/lib/action_controller/base/mime_responds.rb index e560376e0d..3c17dda1a1 100644 --- a/actionpack/lib/action_controller/base/mime_responds.rb +++ b/actionpack/lib/action_controller/base/mime_responds.rb @@ -122,12 +122,11 @@ module ActionController #:nodoc: # TODO: Remove this when new base is merged in if defined?(Http) @controller.formats = [mime_type.to_sym] - @controller.template.formats = [mime_type.to_sym] - else - @controller.template.formats = [mime_type.to_sym] - @response.content_type = mime_type.to_s end + @controller.template.formats = [mime_type.to_sym] + @response.content_type = mime_type.to_s + block_given? ? block.call : @controller.send(:render, :action => @controller.action_name) end end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 142699326e..b8674d5099 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -70,7 +70,7 @@ module ActionController end end - def render_to_body(action = nil, options = {}) + def _normalize_options(action = nil, options = {}) if action.is_a?(Hash) options, action = action, nil elsif action.is_a?(String) || action.is_a?(Symbol) @@ -87,9 +87,21 @@ module ActionController if options.key?(:action) && options[:action].to_s.index("/") options[:template] = options.delete(:action) end - - # options = {:template => options.to_s} if options.is_a?(String) || options.is_a?(Symbol) - super(options) || " " + options + end + + def render(action = nil, options = {}) + options = _normalize_options(action, options) + super(options) + end + + def render_to_string(action = nil, options = {}) + options = _normalize_options(action, options) + super(options) + end + + def render_to_body(options) + super || [" "] end # Redirects the browser to the target specified in +options+. This parameter can take one of three forms: diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 81685ca9d6..840168397d 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -14,6 +14,16 @@ module ActionController super end + def render(options) + super + options[:_template] ||= _action_view._partial + response.content_type ||= begin + mime = options[:_template].mime_type + formats.include?(mime && mime.to_sym) || formats.include?(:all) ? mime : Mime::Type.lookup_by_extension(formats.first) + end + response_body + end + def render_to_body(options) _process_options(options) @@ -35,15 +45,7 @@ module ActionController options[:_prefix] = _prefix end - ret = super(options) - - options[:_template] ||= _action_view._partial - response.content_type ||= begin - mime = options[:_template].mime_type - mime &&= mime.to_sym - formats.include?(mime) ? mime : formats.first - end - ret + super end private diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb index 6a95e638cd..bee82c280e 100644 --- a/actionpack/lib/action_controller/testing/process2.rb +++ b/actionpack/lib/action_controller/testing/process2.rb @@ -40,6 +40,7 @@ module ActionController @request.recycle! @response.recycle! @controller.response_body = nil + @controller.formats = nil @html_document = nil @request.env['REQUEST_METHOD'] = http_method diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index dfcf3a558f..25156a4c75 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -3,7 +3,7 @@ require 'active_support/core_ext/class/attribute_accessors' module Mime SET = [] - EXTENSION_LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? } + EXTENSION_LOOKUP = {} LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? } def self.[](type) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 13ff049a97..4831b89bde 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -175,7 +175,7 @@ module ActionDispatch if ActionController::Base.use_accept_header Array(Mime[parameters[:format]] || accepts) else - [format] + [format, Mime[:all]] end end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 56f0b5ef4f..6b72d406af 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -288,8 +288,11 @@ module ActionView #:nodoc: end def _set_controller_content_type(content_type) #:nodoc: - if controller.respond_to?(:response) - controller.response.content_type ||= content_type + # TODO: Remove this method when new base is switched + unless defined?(ActionController::Http) + if controller.respond_to?(:response) + controller.response.content_type ||= content_type + end end end end diff --git a/actionpack/lib/action_view/template/handler.rb b/actionpack/lib/action_view/template/handler.rb index 672da0ed2b..3481a4a4e7 100644 --- a/actionpack/lib/action_view/template/handler.rb +++ b/actionpack/lib/action_view/template/handler.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/class/inheritable_attributes" + # Legacy TemplateHandler stub module ActionView module TemplateHandlers #:nodoc: @@ -19,6 +21,9 @@ module ActionView end class TemplateHandler + extlib_inheritable_accessor :default_format + self.default_format = Mime::HTML + def self.call(template) "#{name}.new(self).render(template, local_assigns)" end diff --git a/actionpack/lib/action_view/template/handlers/builder.rb b/actionpack/lib/action_view/template/handlers/builder.rb index 788dc93326..f412228752 100644 --- a/actionpack/lib/action_view/template/handlers/builder.rb +++ b/actionpack/lib/action_view/template/handlers/builder.rb @@ -5,6 +5,8 @@ module ActionView class Builder < TemplateHandler include Compilable + self.default_format = Mime::XML + def compile(template) "_set_controller_content_type(Mime::XML);" + "xml = ::Builder::XmlMarkup.new(:indent => 2);" + diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index fdcb108ffc..95f11d6490 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -13,6 +13,8 @@ module ActionView cattr_accessor :erb_trim_mode self.erb_trim_mode = '-' + self.default_format = Mime::HTML + def compile(template) src = ::ERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src diff --git a/actionpack/lib/action_view/template/handlers/rjs.rb b/actionpack/lib/action_view/template/handlers/rjs.rb index 802a79b3fc..a36744c2b7 100644 --- a/actionpack/lib/action_view/template/handlers/rjs.rb +++ b/actionpack/lib/action_view/template/handlers/rjs.rb @@ -3,11 +3,17 @@ module ActionView class RJS < TemplateHandler include Compilable + self.default_format = Mime::JS + def compile(template) "@formats = [:html];" + "controller.response.content_type ||= Mime::JS;" + "update_page do |page|;#{template.source}\nend" end + + def default_format + Mime::JS + end end end end diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb index dcc5006103..0eedc596d2 100644 --- a/actionpack/lib/action_view/template/template.rb +++ b/actionpack/lib/action_view/template/template.rb @@ -7,13 +7,19 @@ require "action_view/template/path" module ActionView class Template extend TemplateHandlers - attr_reader :source, :identifier, :handler + attr_reader :source, :identifier, :handler, :mime_type def initialize(source, identifier, handler, details) @source = source @identifier = identifier @handler = handler @details = details + + format = details[:format] || begin + # TODO: Clean this up + handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html" + end + @mime_type = Mime::Type.lookup_by_extension(format.to_s) end def render(view, locals, &blk) @@ -35,12 +41,7 @@ module ActionView def partial? @details[:partial] end - - # TODO: Move out of Template - def mime_type - Mime::Type.lookup_by_extension(@details[:format].to_s) if @details[:format] - end - + private def compile(locals, view) diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb index 64b8b10d5b..d622ac1e85 100644 --- a/actionpack/test/controller/content_type_test.rb +++ b/actionpack/test/controller/content_type_test.rb @@ -148,12 +148,13 @@ class AcceptBasedContentTypeTest < ActionController::TestCase def setup super + @_old_accept_header = ActionController::Base.use_accept_header ActionController::Base.use_accept_header = true end def teardown super - ActionController::Base.use_accept_header = false + ActionController::Base.use_accept_header = @_old_accept_header end -- cgit v1.2.3 From 2daac47d585c5b8f37e4749d6a9a3aea4b989bd0 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 21 May 2009 14:34:42 -0700 Subject: Added the ability to register methods to handle specific render option keys and render :json --- actionpack/Rakefile | 5 +-- actionpack/lib/action_controller/new_base.rb | 2 ++ actionpack/lib/action_controller/new_base/base.rb | 2 ++ .../action_controller/new_base/render_options.rb | 39 ++++++++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 actionpack/lib/action_controller/new_base/render_options.rb diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 5968317c60..2041f5a844 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -62,8 +62,9 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| # Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + t.test_files = %w( addresses_render base benchmark caching capture content_type dispatcher - flash mime_responds record_identifier redirect render rescue url_rewriter - webservice verification request_forgery_protection send_file + flash mime_responds record_identifier redirect + render render_json + send_file request_forgery_protection rescue url_rewriter verification webservice ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 58c7382661..95808decd5 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -7,6 +7,8 @@ module ActionController autoload :Rails2Compatibility, "action_controller/new_base/compatibility" autoload :Redirector, "action_controller/new_base/redirector" autoload :Renderer, "action_controller/new_base/renderer" + autoload :RenderOptions, "action_controller/new_base/render_options" + autoload :Renderers, "action_controller/new_base/render_options" autoload :Rescue, "action_controller/new_base/rescuable" autoload :Testing, "action_controller/new_base/testing" autoload :UrlFor, "action_controller/new_base/url_for" diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index b8674d5099..6e1f92c45d 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -11,6 +11,8 @@ module ActionController include ActionController::UrlFor include ActionController::Redirector include ActionController::Renderer + include ActionController::RenderOptions + include ActionController::Renderers::Json include ActionController::Layouts include ActionController::ConditionalGet diff --git a/actionpack/lib/action_controller/new_base/render_options.rb b/actionpack/lib/action_controller/new_base/render_options.rb new file mode 100644 index 0000000000..e7ed2bd278 --- /dev/null +++ b/actionpack/lib/action_controller/new_base/render_options.rb @@ -0,0 +1,39 @@ +module ActionController + module RenderOptions + extend ActiveSupport::DependencyModule + + included do + extlib_inheritable_accessor :_renderers + self._renderers = [] + end + + def render_to_body(options) + _renderers.each do |renderer| + if options.key?(renderer) + _process_options(options) + return send("_render_#{renderer}", options[renderer], options) + end + end + super + end + end + + module Renderers + module Json + extend ActiveSupport::DependencyModule + + depends_on RenderOptions + + included do + _renderers << :json + end + + def _render_json(json, options) + json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str) + json = "#{options[:callback]}(#{json})" unless options[:callback].blank? + response.content_type ||= Mime::JSON + self.response_body = json + end + end + end +end \ No newline at end of file -- cgit v1.2.3 From ad1c90de3a766d12a0906c7cf3772f3bc0e1b445 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 21 May 2009 14:51:29 -0700 Subject: Added the :xml render option --- actionpack/Rakefile | 2 +- actionpack/lib/action_controller/new_base/base.rb | 2 +- .../action_controller/new_base/render_options.rb | 30 +++++++++++++++++----- .../lib/action_controller/new_base/renderer.rb | 3 ++- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 2041f5a844..d192a2e3bf 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -63,7 +63,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| t.test_files = %w( addresses_render base benchmark caching capture content_type dispatcher flash mime_responds record_identifier redirect - render render_json + render render_json render_xml send_file request_forgery_protection rescue url_rewriter verification webservice ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 6e1f92c45d..08ffafb27e 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -11,8 +11,8 @@ module ActionController include ActionController::UrlFor include ActionController::Redirector include ActionController::Renderer - include ActionController::RenderOptions include ActionController::Renderers::Json + include ActionController::Renderers::Xml include ActionController::Layouts include ActionController::ConditionalGet diff --git a/actionpack/lib/action_controller/new_base/render_options.rb b/actionpack/lib/action_controller/new_base/render_options.rb index e7ed2bd278..a9ac0e0a41 100644 --- a/actionpack/lib/action_controller/new_base/render_options.rb +++ b/actionpack/lib/action_controller/new_base/render_options.rb @@ -18,15 +18,23 @@ module ActionController end end - module Renderers - module Json + module RenderOption + extend ActiveSupport::DependencyModule + + included do extend ActiveSupport::DependencyModule - depends_on RenderOptions - - included do - _renderers << :json + + def self.register_renderer(name) + included { _renderers << name } end + end + end + + module Renderers + module Json + include RenderOption + register_renderer :json def _render_json(json, options) json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str) @@ -35,5 +43,15 @@ module ActionController self.response_body = json end end + + module Xml + include RenderOption + register_renderer :xml + + def _render_xml(xml, options) + response.content_type ||= Mime::XML + self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml : xml + end + end end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 840168397d..2a52eedb59 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -79,9 +79,10 @@ module ActionController end def _process_options(options) - status, content_type = options.values_at(:status, :content_type) + status, content_type, location = options.values_at(:status, :content_type, :location) response.status = status.to_i if status response.content_type = content_type if content_type + response.headers["Location"] = url_for(location) if location end end end -- cgit v1.2.3 From 9d3d7746702b65ddc09364c260ee4ace4b178281 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 21 May 2009 15:23:52 -0700 Subject: Update render options to remove performance implications of many render options types --- .../action_controller/new_base/render_options.rb | 32 +++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/render_options.rb b/actionpack/lib/action_controller/new_base/render_options.rb index a9ac0e0a41..aa6593b957 100644 --- a/actionpack/lib/action_controller/new_base/render_options.rb +++ b/actionpack/lib/action_controller/new_base/render_options.rb @@ -7,14 +7,32 @@ module ActionController self._renderers = [] end - def render_to_body(options) - _renderers.each do |renderer| - if options.key?(renderer) - _process_options(options) - return send("_render_#{renderer}", options[renderer], options) + module ClassMethods + def _write_render_options + renderers = _renderers.map do |r| + <<-RUBY_EVAL + if options.key?(:#{r}) + _process_options(options) + return _render_#{r}(options[:#{r}], options) + end + RUBY_EVAL end + + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def _handle_render_options(options) + #{renderers.join} + end + RUBY_EVAL + end + + def _add_render_option(name) + _renderers << name + _write_render_options end - super + end + + def render_to_body(options) + _handle_render_options(options) || super end end @@ -26,7 +44,7 @@ module ActionController depends_on RenderOptions def self.register_renderer(name) - included { _renderers << name } + included { _add_render_option(name) } end end end -- cgit v1.2.3 From d2cac9dd0e28b99bd45fd9eaa1d5a6b3dee8fa8f Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 21 May 2009 22:03:52 +0200 Subject: Add missing dependency in Streaming --- actionpack/lib/action_controller/base/streaming.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/actionpack/lib/action_controller/base/streaming.rb b/actionpack/lib/action_controller/base/streaming.rb index b69b13eea8..5872ba99a2 100644 --- a/actionpack/lib/action_controller/base/streaming.rb +++ b/actionpack/lib/action_controller/base/streaming.rb @@ -2,6 +2,13 @@ module ActionController #:nodoc: # Methods for sending arbitrary data and for streaming files to the browser, # instead of rendering. module Streaming + extend ActiveSupport::DependencyModule + + # TODO : Remove the defined? check when new base is the main base + if defined?(ActionController::Http) + depends_on ActionController::Renderer + end + DEFAULT_SEND_FILE_OPTIONS = { :type => 'application/octet-stream'.freeze, :disposition => 'attachment'.freeze, -- cgit v1.2.3 From 1a52b246eb245d159a1c331417a4b14923e9bc4e Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 22 May 2009 00:26:58 +0200 Subject: Add HTTP Authentication to the new base --- actionpack/Rakefile | 1 + actionpack/lib/action_controller/new_base.rb | 2 ++ actionpack/lib/action_controller/new_base/base.rb | 7 +++++++ .../lib/action_controller/new_base/conditional_get.rb | 2 +- actionpack/lib/action_controller/new_base/renderer.rb | 2 +- .../test/controller/http_digest_authentication_test.rb | 13 +++++++++---- actionpack/test/controller/send_file_test.rb | 13 +++++++++---- 7 files changed, 30 insertions(+), 10 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index d192a2e3bf..012f5384e2 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -65,6 +65,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| flash mime_responds record_identifier redirect render render_json render_xml send_file request_forgery_protection rescue url_rewriter verification webservice + http_basic_authentication http_digest_authentication ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 95808decd5..14f73e1edd 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -31,6 +31,8 @@ module ActionController autoload :Flash, 'action_controller/base/chained/flash' autoload :RequestForgeryProtection, 'action_controller/base/request_forgery_protection' autoload :Streaming, 'action_controller/base/streaming' + autoload :HttpAuthentication, 'action_controller/base/http_authentication' + require 'action_controller/routing' end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 08ffafb27e..b432060bc1 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -30,6 +30,8 @@ module ActionController include ActionController::Verification include ActionController::RequestForgeryProtection include ActionController::Streaming + include ActionController::HttpAuthentication::Basic::ControllerMethods + include ActionController::HttpAuthentication::Digest::ControllerMethods # TODO: Extract into its own module # This should be moved together with other normalizing behavior @@ -89,6 +91,11 @@ module ActionController if options.key?(:action) && options[:action].to_s.index("/") options[:template] = options.delete(:action) end + + if options[:status] + options[:status] = interpret_status(options.delete(:status)).to_i + end + options end diff --git a/actionpack/lib/action_controller/new_base/conditional_get.rb b/actionpack/lib/action_controller/new_base/conditional_get.rb index e1407e671a..116ce34494 100644 --- a/actionpack/lib/action_controller/new_base/conditional_get.rb +++ b/actionpack/lib/action_controller/new_base/conditional_get.rb @@ -57,7 +57,7 @@ module ActionController raise ArgumentError, "too few arguments to head" end options = args.extract_options! - status = interpret_status(args.shift || options.delete(:status) || :ok) + status = args.shift || options.delete(:status) || :ok options.each do |key, value| headers[key.to_s.dasherize.split(/-/).map { |v| v.capitalize }.join("-")] = value.to_s diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 2a52eedb59..878859f3e6 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -80,7 +80,7 @@ module ActionController def _process_options(options) status, content_type, location = options.values_at(:status, :content_type, :location) - response.status = status.to_i if status + response.status = status if status response.content_type = content_type if content_type response.headers["Location"] = url_for(location) if location end diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index b8a2205ce6..15a11395bb 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -38,6 +38,15 @@ class HttpDigestAuthenticationTest < ActionController::TestCase tests DummyDigestController + setup do + # Used as secret in generating nonce to prevent tampering of timestamp + @old_secret, ActionController::Base.session_options[:secret] = ActionController::Base.session_options[:secret], "session_options_secret" + end + + teardown do + ActionController::Base.session_options[:secret] = @old_secret + end + AUTH_HEADERS.each do |header| test "successful authentication with #{header.downcase}" do @request.env[header] = encode_credentials(:username => 'lifo', :password => 'world') @@ -165,10 +174,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase options.reverse_merge!(:nc => "00000001", :cnonce => "0a4f113b", :password_is_ha1 => false) password = options.delete(:password) - # Set in /initializers/session_store.rb. Used as secret in generating nonce - # to prevent tampering of timestamp - ActionController::Base.session_options[:secret] = "session_options_secret" - # Perform unauthenticated request to retrieve digest parameters to use on subsequent request method = options.delete(:method) || 'GET' diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index 3a99774ae0..0bc0eb2df6 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -11,12 +11,17 @@ class SendFileController < ActionController::Base layout "layouts/standard" # to make sure layouts don't interfere attr_writer :options - def options() @options ||= {} end + def options + @options ||= {} + end - def file() send_file(file_path, options) end - def data() send_data(file_data, options) end + def file + send_file(file_path, options) + end - def rescue_action(e) raise end + def data + send_data(file_data, options) + end end class SendFileTest < ActionController::TestCase -- cgit v1.2.3 From e773d0e68ac64bd26d86860a9a8e0048e2b6bb48 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 21 May 2009 16:31:05 -0700 Subject: Renamed #implicit_render to #default_render in new base to support the default_render API --- actionpack/lib/action_controller/new_base/base.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index b432060bc1..034e614d6e 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -38,18 +38,18 @@ module ActionController module ImplicitRender def process_action(method_name) ret = super - render if response_body.nil? + default_render if response_body.nil? ret end - def _implicit_render + def default_render render end def method_for_action(action_name) super || begin if view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path) - "_implicit_render" + "default_render" end end end -- cgit v1.2.3 From 6923b392b740f2346326634532b40cf24a0f26ef Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 21 May 2009 16:35:40 -0700 Subject: Added the :rjs render option --- actionpack/lib/action_controller/new_base/base.rb | 14 ++++++++------ .../lib/action_controller/new_base/render_options.rb | 11 +++++++++++ actionpack/lib/action_view/base.rb | 17 +++++++++-------- actionpack/lib/action_view/helpers/prototype_helper.rb | 2 ++ actionpack/lib/action_view/template/handler.rb | 1 + actionpack/test/controller/render_other_test.rb | 8 ++++++++ actionpack/test/template/javascript_helper_test.rb | 4 ++++ actionpack/test/template/prototype_helper_test.rb | 4 ++++ 8 files changed, 47 insertions(+), 14 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 034e614d6e..fae08c58b2 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -13,6 +13,7 @@ module ActionController include ActionController::Renderer include ActionController::Renderers::Json include ActionController::Renderers::Xml + include ActionController::Renderers::Rjs include ActionController::Layouts include ActionController::ConditionalGet @@ -74,7 +75,7 @@ module ActionController end end - def _normalize_options(action = nil, options = {}) + def _normalize_options(action = nil, options = {}, &blk) if action.is_a?(Hash) options, action = action, nil elsif action.is_a?(String) || action.is_a?(Symbol) @@ -93,19 +94,20 @@ module ActionController end if options[:status] - options[:status] = interpret_status(options.delete(:status)).to_i + options[:status] = interpret_status(options[:status]).to_i end + options[:update] = blk if block_given? options end - def render(action = nil, options = {}) - options = _normalize_options(action, options) + def render(action = nil, options = {}, &blk) + options = _normalize_options(action, options, &blk) super(options) end - def render_to_string(action = nil, options = {}) - options = _normalize_options(action, options) + def render_to_string(action = nil, options = {}, &blk) + options = _normalize_options(action, options, &blk) super(options) end diff --git a/actionpack/lib/action_controller/new_base/render_options.rb b/actionpack/lib/action_controller/new_base/render_options.rb index aa6593b957..1df23deee7 100644 --- a/actionpack/lib/action_controller/new_base/render_options.rb +++ b/actionpack/lib/action_controller/new_base/render_options.rb @@ -71,5 +71,16 @@ module ActionController self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml : xml end end + + module Rjs + include RenderOption + register_renderer :update + + def _render_update(proc, options) + generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(_action_view, &proc) + response.content_type = Mime::JS + self.response_body = generator.to_s + end + end end end \ No newline at end of file diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 6b72d406af..4ab568b44c 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -269,15 +269,16 @@ module ActionView #:nodoc: nil end - private - # Evaluates the local assigns and controller ivars, pushes them to the view. - def _evaluate_assigns_and_ivars #:nodoc: - unless @assigns_added - @assigns.each { |key, value| instance_variable_set("@#{key}", value) } - _copy_ivars_from_controller - @assigns_added = true - end + # Evaluates the local assigns and controller ivars, pushes them to the view. + def _evaluate_assigns_and_ivars #:nodoc: + unless @assigns_added + @assigns.each { |key, value| instance_variable_set("@#{key}", value) } + _copy_ivars_from_controller + @assigns_added = true end + end + + private def _copy_ivars_from_controller #:nodoc: if @controller diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 1fbe012a95..c0f5df3468 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -1,5 +1,6 @@ require 'set' require 'active_support/json' +require 'active_support/core_ext/object/extending' module ActionView module Helpers @@ -572,6 +573,7 @@ module ActionView # #include_helpers_from_context has nothing to overwrite. class JavaScriptGenerator #:nodoc: def initialize(context, &block) #:nodoc: + context._evaluate_assigns_and_ivars @context, @lines = context, [] include_helpers_from_context @context.with_output_buffer(@lines) do diff --git a/actionpack/lib/action_view/template/handler.rb b/actionpack/lib/action_view/template/handler.rb index 3481a4a4e7..3071c78174 100644 --- a/actionpack/lib/action_view/template/handler.rb +++ b/actionpack/lib/action_view/template/handler.rb @@ -1,4 +1,5 @@ require "active_support/core_ext/class/inheritable_attributes" +require "action_dispatch/http/mime_type" # Legacy TemplateHandler stub module ActionView diff --git a/actionpack/test/controller/render_other_test.rb b/actionpack/test/controller/render_other_test.rb index ddbdd2d213..3c52b7036d 100644 --- a/actionpack/test/controller/render_other_test.rb +++ b/actionpack/test/controller/render_other_test.rb @@ -103,6 +103,14 @@ class TestController < ActionController::Base end private + def default_render + if @alternate_default_render + @alternate_default_render.call + else + super + end + end + def determine_layout case action_name when "render_js_with_explicit_template", diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index f9bc92c7c9..8caabfc3e1 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -3,6 +3,8 @@ require 'abstract_unit' class JavaScriptHelperTest < ActionView::TestCase tests ActionView::Helpers::JavaScriptHelper + def _evaluate_assigns_and_ivars() end + attr_accessor :formats, :output_buffer def setup @@ -10,6 +12,8 @@ class JavaScriptHelperTest < ActionView::TestCase @template = self end + def _evaluate_assigns_and_ivars() end + def test_escape_javascript assert_equal '', escape_javascript(nil) assert_equal %(This \\"thing\\" is really\\n netos\\'), escape_javascript(%(This "thing" is really\n netos')) diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 28851f113f..f9f418aec9 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -61,6 +61,8 @@ class PrototypeHelperBaseTest < ActionView::TestCase end class PrototypeHelperTest < PrototypeHelperBaseTest + def _evaluate_assigns_and_ivars() end + def setup @record = @author = Author.new @article = Article.new @@ -304,6 +306,8 @@ class JavaScriptGeneratorTest < PrototypeHelperBaseTest @generator = create_generator end + def _evaluate_assigns_and_ivars() end + def test_insert_html_with_string assert_equal 'Element.insert("element", { top: "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E" });', @generator.insert_html(:top, 'element', '

This is a test

') -- cgit v1.2.3 From 68a207ccf6dffa58c9a9a3e221b99af72859ce27 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 21 May 2009 18:14:20 -0700 Subject: Implemented layout conditions in new base --- .../lib/action_controller/abstract/layouts.rb | 25 ++++++++++++++++++--- actionpack/test/controller/layout_test.rb | 26 ++++++++++++++-------- .../layouts/third_party_template_library.mab | 2 +- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 96cb05972f..557d68d866 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -4,11 +4,19 @@ module AbstractController depends_on Renderer + included do + extlib_inheritable_accessor :_layout_conditions + self._layout_conditions = {} + end + module ClassMethods - def layout(layout) + def layout(layout, conditions = {}) unless [String, Symbol, FalseClass, NilClass].include?(layout.class) raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" end + + conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} } + self._layout_conditions = conditions @_layout = layout || false # Converts nil to false _write_layout_method @@ -75,17 +83,28 @@ module AbstractController end def _default_layout(require_layout = false) - if require_layout && !_layout + if require_layout && _action_has_layout? && !_layout raise ArgumentError, "There was no default layout for #{self.class} in #{view_paths.inspect}" end begin - layout = _layout_for_name(_layout) + _layout_for_name(_layout) if _action_has_layout? rescue NameError => e raise NoMethodError, "You specified #{@_layout.inspect} as the layout, but no such method was found" end end + + def _action_has_layout? + conditions = _layout_conditions + if only = conditions[:only] + only.include?(action_name) + elsif except = conditions[:except] + !except.include?(action_name) + else + true + end + end end end \ No newline at end of file diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index 5b7d40d16d..1cd448d5e8 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -9,8 +9,11 @@ ActionView::Template::register_template_handler :mab, ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../fixtures/layout_tests/' ] +require "lib/fixture_template" + class LayoutTest < ActionController::Base def self.controller_path; 'views' end + def self._implied_layout_name; to_s.underscore.gsub(/_controller$/, '') ; end self.view_paths = ActionController::Base.view_paths.dup end @@ -35,6 +38,15 @@ end class MultipleExtensions < LayoutTest end +if defined?(ActionController::Http) + LayoutTest._write_layout_method + ProductController._write_layout_method + ItemController._write_layout_method + ThirdPartyTemplateLibraryController._write_layout_method + MultipleExtensions._write_layout_method + ControllerNameSpace::NestedController._write_layout_method +end + class LayoutAutoDiscoveryTest < ActionController::TestCase def setup super @@ -56,23 +68,19 @@ class LayoutAutoDiscoveryTest < ActionController::TestCase def test_third_party_template_library_auto_discovers_layout @controller = ThirdPartyTemplateLibraryController.new get :hello - assert @controller.active_layout(true).identifier.include?('layouts/third_party_template_library.mab') - assert @controller.template.layout.include?('layouts/third_party_template_library') assert_response :success - assert_equal 'Mab', @response.body + assert_equal 'layouts/third_party_template_library.mab', @response.body end - def test_namespaced_controllers_auto_detect_layouts + def test_namespaced_controllers_auto_detect_layouts1 @controller = ControllerNameSpace::NestedController.new get :hello - assert_equal 'layouts/controller_name_space/nested', @controller.active_layout(true).to_s assert_equal 'controller_name_space/nested.rhtml hello.rhtml', @response.body end - def test_namespaced_controllers_auto_detect_layouts + def test_namespaced_controllers_auto_detect_layouts2 @controller = MultipleExtensions.new get :hello - assert @controller.active_layout(true).identifier.include?('layouts/multiple_extensions.html.erb') assert_equal 'multiple_extensions.html.erb hello.rhtml', @response.body.strip end end @@ -139,7 +147,7 @@ class LayoutSetInResponseTest < ActionController::TestCase def test_layout_only_exception_when_excepted @controller = OnlyLayoutController.new get :goodbye - assert_equal nil, @controller.template.layout + assert !@response.body.include?("item.rhtml"), "#{@response.body.inspect} included 'item.rhtml'" end def test_layout_except_exception_when_included @@ -151,7 +159,7 @@ class LayoutSetInResponseTest < ActionController::TestCase def test_layout_except_exception_when_excepted @controller = ExceptLayoutController.new get :goodbye - assert_equal nil, @controller.template.layout + assert !@response.body.include?("item.rhtml"), "#{@response.body.inspect} included 'item.rhtml'" end def test_layout_set_when_using_render diff --git a/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab b/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab index 018abfb0ac..fcee620d82 100644 --- a/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab +++ b/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab @@ -1 +1 @@ -Mab \ No newline at end of file +layouts/third_party_template_library.mab \ No newline at end of file -- cgit v1.2.3 From e0e124757a98a22a3a1ff7cfbceb1d0e4c4c7533 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 21 May 2009 19:44:02 -0700 Subject: Fewer runs by default --- actionpack/examples/minimal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/examples/minimal.rb b/actionpack/examples/minimal.rb index 84a8499daf..76668b375d 100644 --- a/actionpack/examples/minimal.rb +++ b/actionpack/examples/minimal.rb @@ -9,7 +9,7 @@ class BaseController < ActionController::Base end end -n = (ENV['N'] || 10000).to_i +n = (ENV['N'] || 1000).to_i input = StringIO.new('') def call_index(controller, input, n) -- cgit v1.2.3 From 8f3cbb477375071cfa2ca9b3b01d8a4e3034ccf5 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 21 May 2009 19:45:15 -0700 Subject: Dead local --- actionpack/lib/action_controller/new_base/renderer.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 878859f3e6..71b79fbc42 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -29,7 +29,6 @@ module ActionController if options.key?(:text) options[:_template] = ActionView::TextTemplate.new(_text(options), formats.first) - template = nil elsif options.key?(:inline) handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {}) -- cgit v1.2.3 From 4c52ba278b8e349bc18cb89086af765d0828f0af Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 21 May 2009 20:22:18 -0700 Subject: Move Safari response-padding fix to Rails2Compatibility. Should be a Rack concern. --- actionpack/lib/action_controller/new_base/base.rb | 8 ++------ actionpack/lib/action_controller/new_base/compatibility.rb | 6 ++++-- actionpack/lib/action_controller/new_base/renderer.rb | 13 ++----------- actionpack/lib/action_controller/new_base/testing.rb | 4 ++-- actionpack/lib/action_view/template/text.rb | 2 +- actionpack/test/controller/verification_test.rb | 2 +- actionpack/test/controller/webservice_test.rb | 4 ++-- actionpack/test/new_base/render_text_test.rb | 6 +++--- 8 files changed, 17 insertions(+), 28 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index fae08c58b2..88686d29d0 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -110,11 +110,7 @@ module ActionController options = _normalize_options(action, options, &blk) super(options) end - - def render_to_body(options) - super || [" "] - end - + # Redirects the browser to the target specified in +options+. This parameter can take one of three forms: # # * Hash - The URL will be generated by calling url_for with the +options+. @@ -172,4 +168,4 @@ module ActionController super(url, status) end end -end \ No newline at end of file +end diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index 522a9fe23b..250e7f0dff 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -91,7 +91,9 @@ module ActionController options[:text] = nil if options[:nothing] == true - super + body = super + body = [' '] if body.blank? + body end def _handle_method_missing @@ -110,4 +112,4 @@ module ActionController response_body end end -end \ No newline at end of file +end diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 71b79fbc42..59df3c51da 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -28,7 +28,7 @@ module ActionController _process_options(options) if options.key?(:text) - options[:_template] = ActionView::TextTemplate.new(_text(options), formats.first) + options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first) elsif options.key?(:inline) handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {}) @@ -51,17 +51,8 @@ module ActionController def _prefix controller_path - end - - def _text(options) - text = options[:text] - - case text - when nil then " " - else text.to_s - end end - + def _render_partial(partial, options) case partial when true diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb index 6a92c292bd..d8c3421587 100644 --- a/actionpack/lib/action_controller/new_base/testing.rb +++ b/actionpack/lib/action_controller/new_base/testing.rb @@ -7,7 +7,7 @@ module ActionController @_response = response @_response.request = request ret = process(request.parameters[:action]) - @_response.body ||= self.response_body || " " + @_response.body ||= self.response_body @_response.prepare! set_test_assigns ret @@ -27,4 +27,4 @@ module ActionController @_response.headers.replace(new_headers) end end -end \ No newline at end of file +end diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index 927a0d7a72..a86c3915c2 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -2,7 +2,7 @@ module ActionView #:nodoc: class TextTemplate < String #:nodoc: def initialize(string, content_type = Mime[:html]) - super(string) + super(string.to_s) @content_type = Mime[content_type] end diff --git a/actionpack/test/controller/verification_test.rb b/actionpack/test/controller/verification_test.rb index 85134a8264..d568030e41 100644 --- a/actionpack/test/controller/verification_test.rb +++ b/actionpack/test/controller/verification_test.rb @@ -182,7 +182,7 @@ class VerificationTest < ActionController::TestCase def test_unguarded_without_params get :unguarded - assert_equal "", @response.body + assert @response.body.blank? end def test_guarded_in_session_with_prereqs diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb index e89d6bb960..9bf8da7276 100644 --- a/actionpack/test/controller/webservice_test.rb +++ b/actionpack/test/controller/webservice_test.rb @@ -34,7 +34,7 @@ class WebServiceTest < ActionController::IntegrationTest def test_check_parameters with_test_route_set do get "/" - assert_equal '', @controller.response.body + assert @controller.response.body.blank? end end @@ -163,7 +163,7 @@ class WebServiceTest < ActionController::IntegrationTest with_test_route_set do ActionController::Base.param_parsers[Mime::XML] = :xml_simple assert_nothing_raised { post "/", "", {'CONTENT_TYPE' => 'application/xml'} } - assert_equal "", @controller.response.body + assert @controller.response.body.blank? end end diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb index 69594e4b64..aed903ee8a 100644 --- a/actionpack/test/new_base/render_text_test.rb +++ b/actionpack/test/new_base/render_text_test.rb @@ -88,14 +88,14 @@ module RenderText assert_status 404 end - test "rendering text with nil returns a single space character" do + test "rendering text with nil returns an empty body padded for Safari" do get "/render_text/with_layout/with_nil" assert_body " " assert_status 200 end - test "Rendering text with nil and custom status code returns a single space character with the status" do + test "Rendering text with nil and custom status code returns an empty body padded for Safari and the status" do get "/render_text/with_layout/with_nil_and_status" assert_body " " @@ -139,4 +139,4 @@ module RenderText end end -ActionController::Base.app_loaded! \ No newline at end of file +ActionController::Base.app_loaded! -- cgit v1.2.3 From 1fa7e3322dc8ceac0da3b2b516ca338ee36c89a9 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 21 May 2009 20:54:28 -0700 Subject: Ruby 1.9 compat: don't rely on lexical scoping since the included block is called from dependency_module --- actionpack/lib/action_controller/new_base/render_options.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/render_options.rb b/actionpack/lib/action_controller/new_base/render_options.rb index 1df23deee7..2ce9d0c7ae 100644 --- a/actionpack/lib/action_controller/new_base/render_options.rb +++ b/actionpack/lib/action_controller/new_base/render_options.rb @@ -41,7 +41,7 @@ module ActionController included do extend ActiveSupport::DependencyModule - depends_on RenderOptions + depends_on ::ActionController::RenderOptions def self.register_renderer(name) included { _add_render_option(name) } @@ -83,4 +83,4 @@ module ActionController end end end -end \ No newline at end of file +end -- cgit v1.2.3 From d1d9a6c26113cf4a0decb504c46e4e7fe4351ce6 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 22 May 2009 18:15:43 +0200 Subject: Require ruby-debug from new_base/abstract_unit --- actionpack/test/new_base/abstract_unit.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb index c045247702..1d4bcbd91d 100644 --- a/actionpack/test/new_base/abstract_unit.rb +++ b/actionpack/test/new_base/abstract_unit.rb @@ -18,6 +18,13 @@ require 'active_support/dependencies' $tags[:new_base] = true +begin + require 'ruby-debug' + Debugger.settings[:autoeval] = true + Debugger.start +rescue LoadError + # Debugging disabled. `gem install ruby-debug` to enable. +end ActiveSupport::Dependencies.hook! -- cgit v1.2.3 From 9d08f86cd45ed939ecf2e24e81655371910c8045 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 22 May 2009 18:40:26 +0200 Subject: Make assertion tests pass with the new base --- actionpack/Rakefile | 1 + actionpack/lib/action_controller/testing/process2.rb | 1 + actionpack/lib/action_view/test_case.rb | 2 +- actionpack/test/controller/action_pack_assertions_test.rb | 6 +++--- actionpack/test/new_base/abstract_unit.rb | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 012f5384e2..494286fa4c 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -66,6 +66,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| render render_json render_xml send_file request_forgery_protection rescue url_rewriter verification webservice http_basic_authentication http_digest_authentication + action_pack_assertions ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb index bee82c280e..677dd41781 100644 --- a/actionpack/lib/action_controller/testing/process2.rb +++ b/actionpack/lib/action_controller/testing/process2.rb @@ -41,6 +41,7 @@ module ActionController @response.recycle! @controller.response_body = nil @controller.formats = nil + @controller.params = nil @html_document = nil @request.env['REQUEST_METHOD'] = http_method diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 22adf97304..7355af4192 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -11,7 +11,7 @@ module ActionView attr_internal :rendered alias_method :_render_template_without_template_tracking, :_render_template def _render_template(template, local_assigns = {}) - if template.respond_to?(:identifier) + if template.respond_to?(:identifier) && template.present? @_rendered[:partials][template] += 1 if template.partial? @_rendered[:template] ||= [] @_rendered[:template] << template diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index c3c769919a..24686ab4b6 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -1,4 +1,5 @@ require 'abstract_unit' +require 'action_controller/vendor/html-scanner' # a controller class to facilitate the tests class ActionPackAssertionsController < ActionController::Base @@ -295,8 +296,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase # make sure that the template objects exist def test_template_objects_alive process :assign_this - assert !@controller.template.assigns['hi'] - assert @controller.template.assigns['howdy'] + assert !@controller.template.instance_variable_get(:"@hi") + assert @controller.template.instance_variable_get(:"@howdy") end # make sure we don't have template objects when we shouldn't @@ -444,7 +445,6 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase assert_equal "Mr. David", @response.body end - def test_assert_redirection_fails_with_incorrect_controller process :redirect_to_controller assert_raise(ActiveSupport::TestCase::Assertion) do diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb index 1d4bcbd91d..5df3467ff5 100644 --- a/actionpack/test/new_base/abstract_unit.rb +++ b/actionpack/test/new_base/abstract_unit.rb @@ -113,7 +113,7 @@ module ActionController hax = @controller._action_view.instance_variable_get(:@_rendered) case options - when NilClass, String + when NilClass, String rendered = (hax[:template] || []).map { |t| t.identifier } msg = build_message(message, "expecting but rendering with ", -- cgit v1.2.3 From faaff383e6f52e1c077684bfa49619139db728fb Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 22 May 2009 19:03:27 +0200 Subject: Add assert_select tests to the new base --- actionpack/Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 494286fa4c..bc30fc7308 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -66,7 +66,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| render render_json render_xml send_file request_forgery_protection rescue url_rewriter verification webservice http_basic_authentication http_digest_authentication - action_pack_assertions + action_pack_assertions assert_select ).map { |name| "test/controller/#{name}_test.rb" } end -- cgit v1.2.3 From 1d168afcb146872cb7e49b6d513629fbb19e39b0 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Fri, 22 May 2009 19:51:11 +0200 Subject: Move FilterParameterLogging to a stand alone module and make it work on new base --- actionpack/Rakefile | 2 +- actionpack/lib/action_controller.rb | 1 + actionpack/lib/action_controller/base/base.rb | 58 +------------ .../base/filter_parameter_logging.rb | 97 ++++++++++++++++++++++ actionpack/lib/action_controller/new_base.rb | 1 + actionpack/lib/action_controller/new_base/base.rb | 1 + actionpack/test/controller/filter_params_test.rb | 45 +++++++++- 7 files changed, 144 insertions(+), 61 deletions(-) create mode 100644 actionpack/lib/action_controller/base/filter_parameter_logging.rb diff --git a/actionpack/Rakefile b/actionpack/Rakefile index bc30fc7308..c9ed9ac532 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -66,7 +66,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| render render_json render_xml send_file request_forgery_protection rescue url_rewriter verification webservice http_basic_authentication http_digest_authentication - action_pack_assertions assert_select + action_pack_assertions assert_select filter_params ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 39083a84e9..dd22bfd617 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -66,6 +66,7 @@ module ActionController autoload :UrlRewriter, 'action_controller/routing/generation/url_rewriter' autoload :UrlWriter, 'action_controller/routing/generation/url_rewriter' autoload :Verification, 'action_controller/base/verification' + autoload :FilterParameterLogging, 'action_controller/base/filter_parameter_logging' module Assertions autoload :DomAssertions, 'action_controller/testing/assertions/dom' diff --git a/actionpack/lib/action_controller/base/base.rb b/actionpack/lib/action_controller/base/base.rb index c59068c628..2586037965 100644 --- a/actionpack/lib/action_controller/base/base.rb +++ b/actionpack/lib/action_controller/base/base.rb @@ -448,55 +448,6 @@ module ActionController #:nodoc: @view_paths = superclass.view_paths.dup if @view_paths.nil? @view_paths.push(*path) end - - # Replace sensitive parameter data from the request log. - # Filters parameters that have any of the arguments as a substring. - # Looks in all subhashes of the param hash for keys to filter. - # If a block is given, each key and value of the parameter hash and all - # subhashes is passed to it, the value or key - # can be replaced using String#replace or similar method. - # - # Examples: - # filter_parameter_logging - # => Does nothing, just slows the logging process down - # - # filter_parameter_logging :password - # => replaces the value to all keys matching /password/i with "[FILTERED]" - # - # filter_parameter_logging :foo, "bar" - # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]" - # - # filter_parameter_logging { |k,v| v.reverse! if k =~ /secret/i } - # => reverses the value to all keys matching /secret/i - # - # filter_parameter_logging(:foo, "bar") { |k,v| v.reverse! if k =~ /secret/i } - # => reverses the value to all keys matching /secret/i, and - # replaces the value to all keys matching /foo|bar/i with "[FILTERED]" - def filter_parameter_logging(*filter_words, &block) - parameter_filter = Regexp.new(filter_words.collect{ |s| s.to_s }.join('|'), true) if filter_words.length > 0 - - define_method(:filter_parameters) do |unfiltered_parameters| - filtered_parameters = {} - - unfiltered_parameters.each do |key, value| - if key =~ parameter_filter - filtered_parameters[key] = '[FILTERED]' - elsif value.is_a?(Hash) - filtered_parameters[key] = filter_parameters(value) - elsif block_given? - key = key.dup - value = value.dup if value - yield key, value - filtered_parameters[key] = value - else - filtered_parameters[key] = value - end - end - - filtered_parameters - end - protected :filter_parameters - end @@exempt_from_layout = [ActionView::TemplateHandlers::RJS] @@ -853,13 +804,6 @@ module ActionController #:nodoc: logger.info(request_id) end - def log_processing_for_parameters - parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params.dup - parameters = parameters.except!(:controller, :action, :format, :_method) - - logger.info " Parameters: #{parameters.inspect}" unless parameters.empty? - end - def default_render #:nodoc: render end @@ -933,7 +877,7 @@ module ActionController #:nodoc: [ Filters, Layout, Renderer, Redirector, Responder, Benchmarking, Rescue, Flash, MimeResponds, Helpers, Cookies, Caching, Verification, Streaming, SessionManagement, HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods, RecordIdentifier, - RequestForgeryProtection, Translation + RequestForgeryProtection, Translation, FilterParameterLogging ].each do |mod| include mod end diff --git a/actionpack/lib/action_controller/base/filter_parameter_logging.rb b/actionpack/lib/action_controller/base/filter_parameter_logging.rb new file mode 100644 index 0000000000..8e012b2a25 --- /dev/null +++ b/actionpack/lib/action_controller/base/filter_parameter_logging.rb @@ -0,0 +1,97 @@ +module ActionController + module FilterParameterLogging + extend ActiveSupport::DependencyModule + + # TODO : Remove the defined? check when new base is the main base + if defined?(ActionController::Http) + depends_on AbstractController::Logger + end + + included do + if defined?(ActionController::Http) + include InstanceMethodsForNewBase + end + end + + module ClassMethods + # Replace sensitive parameter data from the request log. + # Filters parameters that have any of the arguments as a substring. + # Looks in all subhashes of the param hash for keys to filter. + # If a block is given, each key and value of the parameter hash and all + # subhashes is passed to it, the value or key + # can be replaced using String#replace or similar method. + # + # Examples: + # filter_parameter_logging + # => Does nothing, just slows the logging process down + # + # filter_parameter_logging :password + # => replaces the value to all keys matching /password/i with "[FILTERED]" + # + # filter_parameter_logging :foo, "bar" + # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]" + # + # filter_parameter_logging { |k,v| v.reverse! if k =~ /secret/i } + # => reverses the value to all keys matching /secret/i + # + # filter_parameter_logging(:foo, "bar") { |k,v| v.reverse! if k =~ /secret/i } + # => reverses the value to all keys matching /secret/i, and + # replaces the value to all keys matching /foo|bar/i with "[FILTERED]" + def filter_parameter_logging(*filter_words, &block) + parameter_filter = Regexp.new(filter_words.collect{ |s| s.to_s }.join('|'), true) if filter_words.length > 0 + + define_method(:filter_parameters) do |unfiltered_parameters| + filtered_parameters = {} + + unfiltered_parameters.each do |key, value| + if key =~ parameter_filter + filtered_parameters[key] = '[FILTERED]' + elsif value.is_a?(Hash) + filtered_parameters[key] = filter_parameters(value) + elsif block_given? + key = key.dup + value = value.dup if value + yield key, value + filtered_parameters[key] = value + else + filtered_parameters[key] = value + end + end + + filtered_parameters + end + protected :filter_parameters + end + end + + module InstanceMethodsForNewBase + # TODO : Fix the order of information inside such that it's exactly same as the old base + def process(*) + ret = super + + if logger + parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params.dup + parameters = parameters.except!(:controller, :action, :format, :_method) + + unless parameters.empty? + # TODO : Move DelayedLog to AS + log = AbstractController::Logger::DelayedLog.new { " Parameters: #{parameters.inspect}" } + logger.info(log) + end + end + + ret + end + end + + private + + # TODO : This method is not needed for the new base + def log_processing_for_parameters + parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params.dup + parameters = parameters.except!(:controller, :action, :format, :_method) + + logger.info " Parameters: #{parameters.inspect}" unless parameters.empty? + end + end +end diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 14f73e1edd..41b2a859bc 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -32,6 +32,7 @@ module ActionController autoload :RequestForgeryProtection, 'action_controller/base/request_forgery_protection' autoload :Streaming, 'action_controller/base/streaming' autoload :HttpAuthentication, 'action_controller/base/http_authentication' + autoload :FilterParameterLogging, 'action_controller/base/filter_parameter_logging' require 'action_controller/routing' end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 88686d29d0..0c85896a00 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -33,6 +33,7 @@ module ActionController include ActionController::Streaming include ActionController::HttpAuthentication::Basic::ControllerMethods include ActionController::HttpAuthentication::Digest::ControllerMethods + include ActionController::FilterParameterLogging # TODO: Extract into its own module # This should be moved together with other normalizing behavior diff --git a/actionpack/test/controller/filter_params_test.rb b/actionpack/test/controller/filter_params_test.rb index 0b259a7980..8c9e4f81de 100644 --- a/actionpack/test/controller/filter_params_test.rb +++ b/actionpack/test/controller/filter_params_test.rb @@ -1,13 +1,30 @@ require 'abstract_unit' class FilterParamController < ActionController::Base + def payment + head :ok + end end -class FilterParamTest < Test::Unit::TestCase - def setup - @controller = FilterParamController.new +class FilterParamTest < ActionController::TestCase + tests FilterParamController + + class MockLogger + attr_reader :logged + attr_accessor :level + + def initialize + @level = Logger::DEBUG + end + + def method_missing(method, *args) + @logged ||= [] + @logged << args.first + end end + setup :set_logger + def test_filter_parameters assert FilterParamController.respond_to?(:filter_parameter_logging) assert !@controller.respond_to?(:filter_parameters) @@ -46,4 +63,26 @@ class FilterParamTest < Test::Unit::TestCase assert !FilterParamController.action_methods.include?('filter_parameters') assert_raise(NoMethodError) { @controller.filter_parameters([{'password' => '[FILTERED]'}]) } end + + def test_filter_parameters_inside_logs + FilterParamController.filter_parameter_logging(:lifo, :amount) + + get :payment, :lifo => 'Pratik', :amount => '420', :step => '1' + + filtered_params_logs = logs.detect {|l| l =~ /\AParameters/ } + + assert filtered_params_logs.index('"amount"=>"[FILTERED]"') + assert filtered_params_logs.index('"lifo"=>"[FILTERED]"') + assert filtered_params_logs.index('"step"=>"1"') + end + + private + + def set_logger + @controller.logger = MockLogger.new + end + + def logs + @logs ||= @controller.logger.logged.compact.map {|l| l.to_s.strip} + end end -- cgit v1.2.3 From e976c489e6416cdc4714721df78dd43dd6d13d99 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 23 May 2009 00:17:05 +0200 Subject: Add all the existing helpers related features to the new base --- actionpack/Rakefile | 2 +- .../lib/action_controller/abstract/helpers.rb | 27 ++++- actionpack/lib/action_controller/base/helpers.rb | 22 ++-- actionpack/lib/action_controller/new_base.rb | 1 + actionpack/lib/action_controller/new_base/base.rb | 4 +- .../lib/action_controller/new_base/helpers.rb | 133 +++++++++++++++++++++ actionpack/test/controller/helper_test.rb | 6 +- actionpack/test/new_base/abstract_unit.rb | 3 + actionpack/test/new_base/render_text_test.rb | 3 - 9 files changed, 175 insertions(+), 26 deletions(-) create mode 100644 actionpack/lib/action_controller/new_base/helpers.rb diff --git a/actionpack/Rakefile b/actionpack/Rakefile index c9ed9ac532..0ce6f7823b 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -66,7 +66,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| render render_json render_xml send_file request_forgery_protection rescue url_rewriter verification webservice http_basic_authentication http_digest_authentication - action_pack_assertions assert_select filter_params + action_pack_assertions assert_select filter_params helper ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/abstract/helpers.rb b/actionpack/lib/action_controller/abstract/helpers.rb index 968d3080c1..41decfd0c7 100644 --- a/actionpack/lib/action_controller/abstract/helpers.rb +++ b/actionpack/lib/action_controller/abstract/helpers.rb @@ -24,11 +24,30 @@ module AbstractController super end - + + # Makes all the (instance) methods in the helper module available to templates rendered through this controller. + # See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules + # available to the templates. def add_template_helper(mod) master_helper_module.module_eval { include mod } end - + + # Declare a controller method as a helper. For example, the following + # makes the +current_user+ controller method available to the view: + # class ApplicationController < ActionController::Base + # helper_method :current_user, :logged_in? + # + # def current_user + # @current_user ||= User.find_by_id(session[:user]) + # end + # + # def logged_in? + # current_user != nil + # end + # end + # + # In a view: + # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%> def helper_method(*meths) meths.flatten.each do |meth| master_helper_module.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 @@ -39,14 +58,14 @@ module AbstractController end end - def helper(*args, &blk) + def helper(*args, &block) args.flatten.each do |arg| case arg when Module add_template_helper(arg) end end - master_helper_module.module_eval(&blk) if block_given? + master_helper_module.module_eval(&block) if block_given? end end diff --git a/actionpack/lib/action_controller/base/helpers.rb b/actionpack/lib/action_controller/base/helpers.rb index ba65032f6a..96fa7896a9 100644 --- a/actionpack/lib/action_controller/base/helpers.rb +++ b/actionpack/lib/action_controller/base/helpers.rb @@ -3,23 +3,19 @@ require 'active_support/dependencies' # FIXME: helper { ... } is broken on Ruby 1.9 module ActionController #:nodoc: module Helpers #:nodoc: - def self.included(base) + extend ActiveSupport::DependencyModule + + included do # Initialize the base module to aggregate its helpers. - base.class_inheritable_accessor :master_helper_module - base.master_helper_module = Module.new + class_inheritable_accessor :master_helper_module + self.master_helper_module = Module.new # Set the default directory for helpers - base.class_inheritable_accessor :helpers_dir - base.helpers_dir = (defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/app/helpers" : "app/helpers") - - # Extend base with class methods to declare helpers. - base.extend(ClassMethods) + class_inheritable_accessor :helpers_dir + self.helpers_dir = (defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/app/helpers" : "app/helpers") - base.class_eval do - # Wrap inherited to create a new master helper module for subclasses. - class << self - alias_method_chain :inherited, :helper - end + class << self + alias_method_chain :inherited, :helper end end diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 41b2a859bc..d6107d3653 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -13,6 +13,7 @@ module ActionController autoload :Testing, "action_controller/new_base/testing" autoload :UrlFor, "action_controller/new_base/url_for" autoload :Session, "action_controller/new_base/session" + autoload :Helpers, "action_controller/new_base/helpers" # Ported modules # require 'action_controller/routing' diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 0c85896a00..6340b7fde9 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -4,9 +4,9 @@ module ActionController include AbstractController::Benchmarker include AbstractController::Callbacks - include AbstractController::Helpers include AbstractController::Logger - + + include ActionController::Helpers include ActionController::HideActions include ActionController::UrlFor include ActionController::Redirector diff --git a/actionpack/lib/action_controller/new_base/helpers.rb b/actionpack/lib/action_controller/new_base/helpers.rb new file mode 100644 index 0000000000..401741c249 --- /dev/null +++ b/actionpack/lib/action_controller/new_base/helpers.rb @@ -0,0 +1,133 @@ +require 'active_support/core_ext/load_error' +require 'active_support/core_ext/name_error' +require 'active_support/dependencies' + +module ActionController + module Helpers + extend ActiveSupport::DependencyModule + + depends_on AbstractController::Helpers + + included do + # Set the default directory for helpers + class_inheritable_accessor :helpers_dir + self.helpers_dir = (defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/app/helpers" : "app/helpers") + end + + module ClassMethods + def inherited(klass) + # klass.master_helper_module = Module.new + # klass.master_helper_module.__send__ :include, master_helper_module + klass.__send__ :default_helper_module! + super + end + + # The +helper+ class method can take a series of helper module names, a block, or both. + # + # * *args: One or more modules, strings or symbols, or the special symbol :all. + # * &block: A block defining helper methods. + # + # ==== Examples + # When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file + # and include the module in the template class. The second form illustrates how to include custom helpers + # when working with namespaced controllers, or other cases where the file containing the helper definition is not + # in one of Rails' standard load paths: + # helper :foo # => requires 'foo_helper' and includes FooHelper + # helper 'resources/foo' # => requires 'resources/foo_helper' and includes Resources::FooHelper + # + # When the argument is a module it will be included directly in the template class. + # helper FooHelper # => includes FooHelper + # + # When the argument is the symbol :all, the controller will include all helpers beneath + # ActionController::Base.helpers_dir (defaults to app/helpers/**/*.rb under RAILS_ROOT). + # helper :all + # + # Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available + # to the template. + # # One line + # helper { def hello() "Hello, world!" end } + # # Multi-line + # helper do + # def foo(bar) + # "#{bar} is the very best" + # end + # end + # + # Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of + # +symbols+, +strings+, +modules+ and blocks. + # helper(:three, BlindHelper) { def mice() 'mice' end } + # + def helper(*args, &block) + args.flatten.each do |arg| + case arg + when :all + helper all_application_helpers + when String, Symbol + file_name = arg.to_s.underscore + '_helper' + class_name = file_name.camelize + + begin + require_dependency(file_name) + rescue LoadError => load_error + requiree = / -- (.*?)(\.rb)?$/.match(load_error.message).to_a[1] + if requiree == file_name + msg = "Missing helper file helpers/#{file_name}.rb" + raise LoadError.new(msg).copy_blame!(load_error) + else + raise + end + end + + add_template_helper(class_name.constantize) + else + # Explcit 'return' here so that the supplied block ( if any ) doesn't get included twice + return super + end + end + + # Evaluate block in template class if given. + master_helper_module.module_eval(&block) if block_given? + end + + # Declares helper accessors for controller attributes. For example, the + # following adds new +name+ and name= instance methods to a + # controller and makes them available to the view: + # helper_attr :name + # attr_accessor :name + def helper_attr(*attrs) + attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") } + end + + # Provides a proxy to access helpers methods from outside the view. + def helpers + unless @helper_proxy + @helper_proxy = ActionView::Base.new + @helper_proxy.extend master_helper_module + else + @helper_proxy + end + end + + private + + def default_helper_module! + unless name.blank? + module_name = name.sub(/Controller$|$/, 'Helper') + module_path = module_name.split('::').map { |m| m.underscore }.join('/') + require_dependency module_path + helper module_name.constantize + end + rescue MissingSourceFile => e + raise unless e.is_missing? module_path + rescue NameError => e + raise unless e.missing_name? module_name + end + + # Extract helper names from files in app/helpers/**/*.rb + def all_application_helpers + extract = /^#{Regexp.quote(helpers_dir)}\/?(.*)_helper.rb$/ + Dir["#{helpers_dir}/**/*_helper.rb"].map { |file| file.sub extract, '\1' } + end + end # ClassMethods + end +end diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 3bbda9eb3a..5b9feb3630 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -27,7 +27,7 @@ module Fun end end -class ApplicationController < ActionController::Base +class AllHelpersController < ActionController::Base helper :all end @@ -127,7 +127,7 @@ class HelperTest < Test::Unit::TestCase end def test_all_helpers - methods = ApplicationController.master_helper_module.instance_methods.map(&:to_s) + methods = AllHelpersController.master_helper_module.instance_methods.map(&:to_s) # abc_helper.rb assert methods.include?('bare_a') @@ -154,7 +154,7 @@ class HelperTest < Test::Unit::TestCase end def test_helper_proxy - methods = ApplicationController.helpers.methods.map(&:to_s) + methods = AllHelpersController.helpers.methods.map(&:to_s) # ActionView assert methods.include?('pluralize') diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb index 5df3467ff5..569e4e764f 100644 --- a/actionpack/test/new_base/abstract_unit.rb +++ b/actionpack/test/new_base/abstract_unit.rb @@ -2,6 +2,9 @@ $:.unshift(File.dirname(__FILE__) + '/../../lib') $:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib') $:.unshift(File.dirname(__FILE__) + '/../lib') +$:.unshift(File.dirname(__FILE__) + '/../fixtures/helpers') +$:.unshift(File.dirname(__FILE__) + '/../fixtures/alternate_helpers') + ENV['new_base'] = "true" $stderr.puts "Running old tests on new_base" diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/new_base/render_text_test.rb index aed903ee8a..ffc149283b 100644 --- a/actionpack/test/new_base/render_text_test.rb +++ b/actionpack/test/new_base/render_text_test.rb @@ -1,8 +1,5 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") -class ApplicationController < ActionController::Base -end - module RenderText class SimpleController < ActionController::Base self.view_paths = [ActionView::Template::FixturePath.new] -- cgit v1.2.3 From 01129534cde293e3561dd7cc3cb5ae9ac3de9e8c Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 22 May 2009 12:28:40 -0700 Subject: Cleaned up the #render_to_body chain by extracting determining the templates to render to a separate hook point. --- .../lib/action_controller/abstract/layouts.rb | 4 ---- .../lib/action_controller/abstract/renderer.rb | 24 ++++++++++++++-------- .../lib/action_controller/new_base/renderer.rb | 24 ++++++++++++++-------- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 557d68d866..dec394a021 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -57,10 +57,6 @@ module AbstractController end end end - - def _render_template(template, options) - _action_view._render_template_from_controller(template, options[:_layout], options, options[:_partial]) - end private diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index f2044a35ec..d7c68549e1 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -33,16 +33,12 @@ module AbstractController # # :api: plugin def render_to_body(options = {}) - name = options[:_template_name] || action_name - # TODO: Refactor so we can just use the normal template logic for this if options[:_partial_object] _action_view._render_partial_from_controller(options) - else - options[:_template] ||= view_paths.find_by_parts(name.to_s, {:formats => formats}, - options[:_prefix], options[:_partial]) - - _render_template(options[:_template], options) + else + _determine_template(options) + _render_template(options) end end @@ -56,8 +52,8 @@ module AbstractController AbstractController::Renderer.body_to_s(render_to_body(options)) end - def _render_template(template, options) - _action_view._render_template_from_controller(template, nil, options, options[:_partial]) + def _render_template(options) + _action_view._render_template_from_controller(options[:_template], options[:_layout], options, options[:_partial]) end def view_paths() _view_paths end @@ -74,6 +70,16 @@ module AbstractController end end + private + + def _determine_template(options) + name = (options[:_template_name] || action_name).to_s + + options[:_template] ||= view_paths.find_by_parts( + name, { :formats => formats }, options[:_prefix], options[:_partial] + ) + end + module ClassMethods def append_view_path(path) diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 59df3c51da..987751a601 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -27,6 +27,20 @@ module ActionController def render_to_body(options) _process_options(options) + if options.key?(:partial) + _render_partial(options[:partial], options) + end + + super + end + + private + + def _prefix + controller_path + end + + def _determine_template(options) if options.key?(:text) options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first) elsif options.key?(:inline) @@ -37,21 +51,13 @@ module ActionController options[:_template_name] = options[:template] elsif options.key?(:file) options[:_template_name] = options[:file] - elsif options.key?(:partial) - _render_partial(options[:partial], options) - else + elsif !options.key?(:partial) options[:_template_name] = (options[:action] || action_name).to_s options[:_prefix] = _prefix end super end - - private - - def _prefix - controller_path - end def _render_partial(partial, options) case partial -- cgit v1.2.3 From 72a574b5073b1debd58c954b34c54d3bdee7749f Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 22 May 2009 15:16:28 -0700 Subject: Get controller/layout_test.rb running on new base except for ActionController::Base.exempt_from_layout which is going to be deprecated. --- actionpack/Rakefile | 13 +++++++------ .../lib/action_controller/abstract/layouts.rb | 6 +++--- .../lib/action_controller/new_base/layouts.rb | 21 +++++++++------------ actionpack/lib/action_view/template/template.rb | 2 +- actionpack/lib/action_view/template/text.rb | 4 ++++ actionpack/test/controller/layout_test.rb | 17 ++++++++++------- 6 files changed, 34 insertions(+), 29 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 0ce6f7823b..6c820636d5 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -61,12 +61,13 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| # layout # Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + t.test_files = %w( - addresses_render base benchmark caching capture content_type dispatcher - flash mime_responds record_identifier redirect - render render_json render_xml - send_file request_forgery_protection rescue url_rewriter verification webservice - http_basic_authentication http_digest_authentication - action_pack_assertions assert_select filter_params helper + action_pack_assertions addresses_render assert_select + base benchmark caching capture content_type dispatcher + filter_params flash helper http_basic_authentication + http_digest_authentication layout mime_responds + record_identifier redirect render render_json render_xml + send_file request_forgery_protection rescue url_rewriter + verification webservice ).map { |name| "test/controller/#{name}_test.rb" } end diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index dec394a021..b3b743d6e8 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -65,12 +65,12 @@ module AbstractController # :api: plugin # ==== # Override this to mutate the inbound layout name - def _layout_for_name(name) + def _layout_for_name(name, details = {:formats => formats}) unless [String, FalseClass, NilClass].include?(name.class) raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}" end - name && view_paths.find_by_parts(name, {:formats => formats}, _layout_prefix(name)) + name && view_paths.find_by_parts(name, details, _layout_prefix(name)) end # TODO: Decide if this is the best hook point for the feature @@ -78,7 +78,7 @@ module AbstractController "layouts" end - def _default_layout(require_layout = false) + def _default_layout(require_layout = false, details = {:formats => formats}) if require_layout && _action_has_layout? && !_layout raise ArgumentError, "There was no default layout for #{self.class} in #{view_paths.inspect}" diff --git a/actionpack/lib/action_controller/new_base/layouts.rb b/actionpack/lib/action_controller/new_base/layouts.rb index bf5b14c4e1..35068db770 100644 --- a/actionpack/lib/action_controller/new_base/layouts.rb +++ b/actionpack/lib/action_controller/new_base/layouts.rb @@ -11,23 +11,20 @@ module ActionController end end - def render_to_body(options) - # render :text => ..., :layout => ... - # or - # render :anything_else + private + + def _determine_template(options) + super if (!options.key?(:text) && !options.key?(:inline) && !options.key?(:partial)) || options.key?(:layout) - options[:_layout] = options.key?(:layout) ? _layout_for_option(options[:layout]) : _default_layout + options[:_layout] = _layout_for_option(options.key?(:layout) ? options[:layout] : :none, options[:_template].details) end - - super end - - private - def _layout_for_option(name) + def _layout_for_option(name, details) case name - when String then _layout_for_name(name) - when true then _default_layout(true) + when String then _layout_for_name(name, details) + when true then _default_layout(true, details) + when :none then _default_layout(false, details) when false, nil then nil else raise ArgumentError, diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb index 0eedc596d2..d58f4ec19e 100644 --- a/actionpack/lib/action_view/template/template.rb +++ b/actionpack/lib/action_view/template/template.rb @@ -7,7 +7,7 @@ require "action_view/template/path" module ActionView class Template extend TemplateHandlers - attr_reader :source, :identifier, :handler, :mime_type + attr_reader :source, :identifier, :handler, :mime_type, :details def initialize(source, identifier, handler, details) @source = source diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index a86c3915c2..fd57b1677e 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -6,6 +6,10 @@ module ActionView #:nodoc: @content_type = Mime[content_type] end + def details + {:formats => [@content_type.to_sym]} + end + def identifier() self end def render(*) self end diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index 1cd448d5e8..04da0a7f86 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -174,15 +174,18 @@ class LayoutSetInResponseTest < ActionController::TestCase assert_nil @controller.template.layout end - def test_exempt_from_layout_honored_by_render_template - ActionController::Base.exempt_from_layout :erb - @controller = RenderWithTemplateOptionController.new + for_tag(:old_base) do + # exempt_from_layout is deprecated + def test_exempt_from_layout_honored_by_render_template + ActionController::Base.exempt_from_layout :erb + @controller = RenderWithTemplateOptionController.new - get :hello - assert_equal "alt/hello.rhtml", @response.body.strip + get :hello + assert_equal "alt/hello.rhtml", @response.body.strip - ensure - ActionController::Base.exempt_from_layout.delete(ERB) + ensure + ActionController::Base.exempt_from_layout.delete(ERB) + end end def test_layout_is_picked_from_the_controller_instances_view_path -- cgit v1.2.3 From 8a336d01d2c403f0a2fb818edb8db836ddc367ef Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 23 May 2009 00:30:11 +0200 Subject: Use super wherever possible in ActionController::Helpers#helper --- actionpack/lib/action_controller/new_base/helpers.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/helpers.rb b/actionpack/lib/action_controller/new_base/helpers.rb index 401741c249..e00c3c338b 100644 --- a/actionpack/lib/action_controller/new_base/helpers.rb +++ b/actionpack/lib/action_controller/new_base/helpers.rb @@ -16,8 +16,6 @@ module ActionController module ClassMethods def inherited(klass) - # klass.master_helper_module = Module.new - # klass.master_helper_module.__send__ :include, master_helper_module klass.__send__ :default_helper_module! super end @@ -78,10 +76,9 @@ module ActionController end end - add_template_helper(class_name.constantize) + super class_name.constantize else - # Explcit 'return' here so that the supplied block ( if any ) doesn't get included twice - return super + super args end end -- cgit v1.2.3 From df2d96a7f05aebca3e9d2367c2a248125b24dca6 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 11:10:41 -0700 Subject: Move misplaced test --- actionmailer/test/adv_attr_test.rb | 18 ++++++++++++++++++ actionpack/test/adv_attr_test.rb | 20 -------------------- 2 files changed, 18 insertions(+), 20 deletions(-) create mode 100644 actionmailer/test/adv_attr_test.rb delete mode 100644 actionpack/test/adv_attr_test.rb diff --git a/actionmailer/test/adv_attr_test.rb b/actionmailer/test/adv_attr_test.rb new file mode 100644 index 0000000000..fd909a5627 --- /dev/null +++ b/actionmailer/test/adv_attr_test.rb @@ -0,0 +1,18 @@ +require 'abstract_unit' +require 'action_mailer/adv_attr_accessor' + +class AdvAttrTest < Test::Unit::TestCase + class Person + include ActionMailer::AdvAttrAccessor + adv_attr_accessor :name + end + + def test_adv_attr + bob = Person.new + assert_nil bob.name + bob.name 'Bob' + assert_equal 'Bob', bob.name + + assert_raise(ArgumentError) {bob.name 'x', 'y'} + end +end diff --git a/actionpack/test/adv_attr_test.rb b/actionpack/test/adv_attr_test.rb deleted file mode 100644 index fdda4ad92d..0000000000 --- a/actionpack/test/adv_attr_test.rb +++ /dev/null @@ -1,20 +0,0 @@ -require File.dirname(__FILE__) + '/abstract_unit' -require 'action_mailer/adv_attr_accessor' - -class AdvAttrTest < Test::Unit::TestCase - class Person - include ActionMailer::AdvAttrAccessor - adv_attr_accessor :name - end - - def test_adv_attr - bob = Person.new - assert_nil bob.name - bob.name 'Bob' - assert_equal 'Bob', bob.name - - assert_raise(ArgumentError) {bob.name 'x', 'y'} - end - - -end \ No newline at end of file -- cgit v1.2.3 From 3c13551aa2c7f43f7863349ef5699d42dd255801 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 11:12:51 -0700 Subject: Complain if new_base/abstract_unit was already loaded --- actionpack/test/abstract_unit.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 5ae54d097a..c71da7fa6c 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -1,3 +1,7 @@ +if ENV['new_base'] + puts *caller + raise 'new_base/abstract_unit already loaded' +end $:.unshift(File.dirname(__FILE__) + '/../lib') $:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib') $:.unshift(File.dirname(__FILE__) + '/fixtures/helpers') -- cgit v1.2.3 From 98f856d7723bd8aa8ccc05dfb7219c897b4dcab7 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 11:13:34 -0700 Subject: Set ENV['NEW'] to run any test task with the new Base. --- actionpack/Rakefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 6c820636d5..79a582033a 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -24,8 +24,9 @@ task :default => [ :test ] desc "Run all unit tests" task :test => [:test_action_pack, :test_active_record_integration, :test_new_base, :test_new_base_on_old_tests] +test_lib_dir = ENV["NEW"] ? "test/new_base" : "test" Rake::TestTask.new(:test_action_pack) do |t| - t.libs << "test" + t.libs << test_lib_dir # make sure we include the tests in alphabetical order as on some systems # this will not happen automatically and the tests (as a whole) will error @@ -37,27 +38,27 @@ end task :isolated_test do ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME')) Dir.glob("test/{controller,dispatch,template}/**/*_test.rb").all? do |file| - system(ruby, '-Ilib:test', file) + system(ruby, "-Ilib:#{test_lib_dir}", file) end or raise "Failures" end desc 'ActiveRecord Integration Tests' Rake::TestTask.new(:test_active_record_integration) do |t| - t.libs << "test" + t.libs << test_lib_dir t.test_files = Dir.glob("test/activerecord/*_test.rb") t.verbose = true end desc 'New Controller Tests' Rake::TestTask.new(:test_new_base) do |t| - t.libs << "test" + t.libs << "test/new_base" t.test_files = Dir.glob("test/{abstract_controller,new_base}/*_test.rb") t.verbose = true end desc 'Old Controller Tests on New Base' Rake::TestTask.new(:test_new_base_on_old_tests) do |t| - t.libs << "test/new_base" << "test" + t.libs << "test/new_base" # layout # Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + t.test_files = %w( @@ -71,7 +72,6 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| ).map { |name| "test/controller/#{name}_test.rb" } end - # Genereate the RDoc documentation Rake::RDocTask.new { |rdoc| -- cgit v1.2.3 From ca7207838844f02f50afbb18beb0f535903f7929 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 16:11:54 -0700 Subject: Move fake controllers and models to a common load path --- actionpack/Rakefile | 12 ++++---- actionpack/test/controller/fake_controllers.rb | 33 ---------------------- actionpack/test/controller/fake_models.rb | 19 ------------- actionpack/test/controller/layout_test.rb | 2 +- actionpack/test/lib/controller/fake_controllers.rb | 33 ++++++++++++++++++++++ actionpack/test/lib/controller/fake_models.rb | 19 +++++++++++++ 6 files changed, 59 insertions(+), 59 deletions(-) delete mode 100644 actionpack/test/controller/fake_controllers.rb delete mode 100644 actionpack/test/controller/fake_models.rb create mode 100644 actionpack/test/lib/controller/fake_controllers.rb create mode 100644 actionpack/test/lib/controller/fake_models.rb diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 79a582033a..6ad061b0b1 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -24,9 +24,9 @@ task :default => [ :test ] desc "Run all unit tests" task :test => [:test_action_pack, :test_active_record_integration, :test_new_base, :test_new_base_on_old_tests] -test_lib_dir = ENV["NEW"] ? "test/new_base" : "test" +test_lib_dirs = [ENV["NEW"] ? "test/new_base" : "test", "test/lib"] Rake::TestTask.new(:test_action_pack) do |t| - t.libs << test_lib_dir + t.libs.concat test_lib_dirs # make sure we include the tests in alphabetical order as on some systems # this will not happen automatically and the tests (as a whole) will error @@ -38,27 +38,27 @@ end task :isolated_test do ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME')) Dir.glob("test/{controller,dispatch,template}/**/*_test.rb").all? do |file| - system(ruby, "-Ilib:#{test_lib_dir}", file) + system(ruby, "-Ilib:#{test_lib_dirs * ':'}", file) end or raise "Failures" end desc 'ActiveRecord Integration Tests' Rake::TestTask.new(:test_active_record_integration) do |t| - t.libs << test_lib_dir + t.libs.concat test_lib_dirs t.test_files = Dir.glob("test/activerecord/*_test.rb") t.verbose = true end desc 'New Controller Tests' Rake::TestTask.new(:test_new_base) do |t| - t.libs << "test/new_base" + t.libs << "test/new_base" << "test/lib" t.test_files = Dir.glob("test/{abstract_controller,new_base}/*_test.rb") t.verbose = true end desc 'Old Controller Tests on New Base' Rake::TestTask.new(:test_new_base_on_old_tests) do |t| - t.libs << "test/new_base" + t.libs << "test/new_base" << "test/lib" # layout # Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + t.test_files = %w( diff --git a/actionpack/test/controller/fake_controllers.rb b/actionpack/test/controller/fake_controllers.rb deleted file mode 100644 index 75c114c103..0000000000 --- a/actionpack/test/controller/fake_controllers.rb +++ /dev/null @@ -1,33 +0,0 @@ -class << Object; alias_method :const_available?, :const_defined?; end - -class ContentController < Class.new(ActionController::Base) -end -class NotAController -end -module Admin - class << self; alias_method :const_available?, :const_defined?; end - class UserController < Class.new(ActionController::Base); end - class NewsFeedController < Class.new(ActionController::Base); end -end - -# For speed test -class SpeedController < ActionController::Base; end -class SearchController < SpeedController; end -class VideosController < SpeedController; end -class VideoFileController < SpeedController; end -class VideoSharesController < SpeedController; end -class VideoAbusesController < SpeedController; end -class VideoUploadsController < SpeedController; end -class VideoVisitsController < SpeedController; end -class UsersController < SpeedController; end -class SettingsController < SpeedController; end -class ChannelsController < SpeedController; end -class ChannelVideosController < SpeedController; end -class SessionsController < SpeedController; end -class LostPasswordsController < SpeedController; end -class PagesController < SpeedController; end - -ActionController::Routing::Routes.draw do |map| - map.route_one 'route_one', :controller => 'elsewhere', :action => 'flash_me' - map.connect ':controller/:action/:id' -end diff --git a/actionpack/test/controller/fake_models.rb b/actionpack/test/controller/fake_models.rb deleted file mode 100644 index 0b30c79b10..0000000000 --- a/actionpack/test/controller/fake_models.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Customer < Struct.new(:name, :id) - def to_param - id.to_s - end -end - -class BadCustomer < Customer -end - -class GoodCustomer < Customer -end - -module Quiz - class Question < Struct.new(:name, :id) - def to_param - id.to_s - end - end -end diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index 04da0a7f86..cb9bdf57bb 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -9,7 +9,7 @@ ActionView::Template::register_template_handler :mab, ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../fixtures/layout_tests/' ] -require "lib/fixture_template" +require "fixture_template" class LayoutTest < ActionController::Base def self.controller_path; 'views' end diff --git a/actionpack/test/lib/controller/fake_controllers.rb b/actionpack/test/lib/controller/fake_controllers.rb new file mode 100644 index 0000000000..75c114c103 --- /dev/null +++ b/actionpack/test/lib/controller/fake_controllers.rb @@ -0,0 +1,33 @@ +class << Object; alias_method :const_available?, :const_defined?; end + +class ContentController < Class.new(ActionController::Base) +end +class NotAController +end +module Admin + class << self; alias_method :const_available?, :const_defined?; end + class UserController < Class.new(ActionController::Base); end + class NewsFeedController < Class.new(ActionController::Base); end +end + +# For speed test +class SpeedController < ActionController::Base; end +class SearchController < SpeedController; end +class VideosController < SpeedController; end +class VideoFileController < SpeedController; end +class VideoSharesController < SpeedController; end +class VideoAbusesController < SpeedController; end +class VideoUploadsController < SpeedController; end +class VideoVisitsController < SpeedController; end +class UsersController < SpeedController; end +class SettingsController < SpeedController; end +class ChannelsController < SpeedController; end +class ChannelVideosController < SpeedController; end +class SessionsController < SpeedController; end +class LostPasswordsController < SpeedController; end +class PagesController < SpeedController; end + +ActionController::Routing::Routes.draw do |map| + map.route_one 'route_one', :controller => 'elsewhere', :action => 'flash_me' + map.connect ':controller/:action/:id' +end diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb new file mode 100644 index 0000000000..0b30c79b10 --- /dev/null +++ b/actionpack/test/lib/controller/fake_models.rb @@ -0,0 +1,19 @@ +class Customer < Struct.new(:name, :id) + def to_param + id.to_s + end +end + +class BadCustomer < Customer +end + +class GoodCustomer < Customer +end + +module Quiz + class Question < Struct.new(:name, :id) + def to_param + id.to_s + end + end +end -- cgit v1.2.3 From b7c031f52ecca11558edd494d292ff6b99dd21b7 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 16:21:21 -0700 Subject: Move active_record_unit to shared load path --- actionpack/test/active_record_unit.rb | 104 ------------------------------ actionpack/test/lib/active_record_unit.rb | 104 ++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 104 deletions(-) delete mode 100644 actionpack/test/active_record_unit.rb create mode 100644 actionpack/test/lib/active_record_unit.rb diff --git a/actionpack/test/active_record_unit.rb b/actionpack/test/active_record_unit.rb deleted file mode 100644 index 9e0c66055d..0000000000 --- a/actionpack/test/active_record_unit.rb +++ /dev/null @@ -1,104 +0,0 @@ -require 'abstract_unit' - -# Define the essentials -class ActiveRecordTestConnector - cattr_accessor :able_to_connect - cattr_accessor :connected - - # Set our defaults - self.connected = false - self.able_to_connect = true -end - -# Try to grab AR -if defined?(ActiveRecord) && defined?(Fixtures) - $stderr.puts 'Active Record is already loaded, running tests' -else - $stderr.print 'Attempting to load Active Record... ' - begin - PATH_TO_AR = "#{File.dirname(__FILE__)}/../../activerecord/lib" - raise LoadError, "#{PATH_TO_AR} doesn't exist" unless File.directory?(PATH_TO_AR) - $LOAD_PATH.unshift PATH_TO_AR - require 'active_record' - require 'active_record/fixtures' - $stderr.puts 'success' - rescue LoadError => e - $stderr.print "failed. Skipping Active Record assertion tests: #{e}" - ActiveRecordTestConnector.able_to_connect = false - end -end -$stderr.flush - - -# Define the rest of the connector -class ActiveRecordTestConnector - class << self - def setup - unless self.connected || !self.able_to_connect - setup_connection - load_schema - require_fixture_models - self.connected = true - end - rescue Exception => e # errors from ActiveRecord setup - $stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}" - #$stderr.puts " #{e.backtrace.join("\n ")}\n" - self.able_to_connect = false - end - - private - def setup_connection - if Object.const_defined?(:ActiveRecord) - defaults = { :database => ':memory:' } - begin - adapter = defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3' - options = defaults.merge :adapter => adapter, :timeout => 500 - ActiveRecord::Base.establish_connection(options) - ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options } - ActiveRecord::Base.connection - rescue Exception # errors from establishing a connection - $stderr.puts 'SQLite 3 unavailable; trying SQLite 2.' - options = defaults.merge :adapter => 'sqlite' - ActiveRecord::Base.establish_connection(options) - ActiveRecord::Base.configurations = { 'sqlite2_ar_integration' => options } - ActiveRecord::Base.connection - end - - Object.send(:const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')) unless Object.const_defined?(:QUOTED_TYPE) - else - raise "Can't setup connection since ActiveRecord isn't loaded." - end - end - - # Load actionpack sqlite tables - def load_schema - File.read(File.dirname(__FILE__) + "/fixtures/db_definitions/sqlite.sql").split(';').each do |sql| - ActiveRecord::Base.connection.execute(sql) unless sql.blank? - end - end - - def require_fixture_models - Dir.glob(File.dirname(__FILE__) + "/fixtures/*.rb").each {|f| require f} - end - end -end - -class ActiveRecordTestCase < ActionController::TestCase - include ActiveRecord::TestFixtures - - # Set our fixture path - if ActiveRecordTestConnector.able_to_connect - self.fixture_path = [FIXTURE_LOAD_PATH] - self.use_transactional_fixtures = false - end - - def self.fixtures(*args) - super if ActiveRecordTestConnector.connected - end - - def run(*args) - super if ActiveRecordTestConnector.connected - end -end - -ActiveRecordTestConnector.setup diff --git a/actionpack/test/lib/active_record_unit.rb b/actionpack/test/lib/active_record_unit.rb new file mode 100644 index 0000000000..1ba308e9d7 --- /dev/null +++ b/actionpack/test/lib/active_record_unit.rb @@ -0,0 +1,104 @@ +require 'abstract_unit' + +# Define the essentials +class ActiveRecordTestConnector + cattr_accessor :able_to_connect + cattr_accessor :connected + + # Set our defaults + self.connected = false + self.able_to_connect = true +end + +# Try to grab AR +if defined?(ActiveRecord) && defined?(Fixtures) + $stderr.puts 'Active Record is already loaded, running tests' +else + $stderr.print 'Attempting to load Active Record... ' + begin + PATH_TO_AR = "#{File.dirname(__FILE__)}/../../../activerecord/lib" + raise LoadError, "#{PATH_TO_AR} doesn't exist" unless File.directory?(PATH_TO_AR) + $LOAD_PATH.unshift PATH_TO_AR + require 'active_record' + require 'active_record/fixtures' + $stderr.puts 'success' + rescue LoadError => e + $stderr.print "failed. Skipping Active Record assertion tests: #{e}" + ActiveRecordTestConnector.able_to_connect = false + end +end +$stderr.flush + + +# Define the rest of the connector +class ActiveRecordTestConnector + class << self + def setup + unless self.connected || !self.able_to_connect + setup_connection + load_schema + require_fixture_models + self.connected = true + end + rescue Exception => e # errors from ActiveRecord setup + $stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}" + #$stderr.puts " #{e.backtrace.join("\n ")}\n" + self.able_to_connect = false + end + + private + def setup_connection + if Object.const_defined?(:ActiveRecord) + defaults = { :database => ':memory:' } + begin + adapter = defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3' + options = defaults.merge :adapter => adapter, :timeout => 500 + ActiveRecord::Base.establish_connection(options) + ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options } + ActiveRecord::Base.connection + rescue Exception # errors from establishing a connection + $stderr.puts 'SQLite 3 unavailable; trying SQLite 2.' + options = defaults.merge :adapter => 'sqlite' + ActiveRecord::Base.establish_connection(options) + ActiveRecord::Base.configurations = { 'sqlite2_ar_integration' => options } + ActiveRecord::Base.connection + end + + Object.send(:const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')) unless Object.const_defined?(:QUOTED_TYPE) + else + raise "Can't setup connection since ActiveRecord isn't loaded." + end + end + + # Load actionpack sqlite tables + def load_schema + File.read(File.dirname(__FILE__) + "/../fixtures/db_definitions/sqlite.sql").split(';').each do |sql| + ActiveRecord::Base.connection.execute(sql) unless sql.blank? + end + end + + def require_fixture_models + Dir.glob(File.dirname(__FILE__) + "/../fixtures/*.rb").each {|f| require f} + end + end +end + +class ActiveRecordTestCase < ActionController::TestCase + include ActiveRecord::TestFixtures + + # Set our fixture path + if ActiveRecordTestConnector.able_to_connect + self.fixture_path = [FIXTURE_LOAD_PATH] + self.use_transactional_fixtures = false + end + + def self.fixtures(*args) + super if ActiveRecordTestConnector.connected + end + + def run(*args) + super if ActiveRecordTestConnector.connected + end +end + +ActiveRecordTestConnector.setup -- cgit v1.2.3 From 444480c9a5d9c75568a243bb73a040b3cf050814 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 16:23:48 -0700 Subject: Verbose test_new_base_on_old_tests --- actionpack/Rakefile | 1 + 1 file changed, 1 insertion(+) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 6ad061b0b1..18e5b3d96a 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -70,6 +70,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| send_file request_forgery_protection rescue url_rewriter verification webservice ).map { |name| "test/controller/#{name}_test.rb" } + t.verbose = true end # Genereate the RDoc documentation -- cgit v1.2.3 From a01d2a25867dbe5235c29557673f3a5692b82aec Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 16:25:49 -0700 Subject: Remove gratuitous filter_chain internal testing. Not part of the API and other tests are sufficient to catch regressions. --- actionpack/test/controller/filters_test.rb | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index afefc6a77e..490061ed9b 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -1,6 +1,5 @@ require 'abstract_unit' -# FIXME: crashes Ruby 1.9 class FilterTest < Test::Unit::TestCase include ActionController::TestProcess @@ -141,14 +140,6 @@ class FilterTest < Test::Unit::TestCase before_filter :clean_up_tmp, :if => Proc.new { |c| false } end - class EmptyFilterChainController < TestController - self.filter_chain.clear - def show - @action_executed = true - render :text => "yawp!" - end - end - class PrependingController < TestController prepend_before_filter :wonderful_life # skip_before_filter :fire_flash @@ -455,12 +446,6 @@ class FilterTest < Test::Unit::TestCase assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters'] end - def test_empty_filter_chain - assert_equal 0, EmptyFilterChainController.filter_chain.size - test_process(EmptyFilterChainController) - assert @controller.template.assigns['action_executed'] - end - def test_added_filter_to_inheritance_graph assert_equal [ :ensure_login ], TestController.before_filters end @@ -614,7 +599,6 @@ class FilterTest < Test::Unit::TestCase end def test_running_prepended_before_and_after_filter - assert_equal 3, PrependingBeforeAndAfterController.filter_chain.length test_process(PrependingBeforeAndAfterController) assert_equal %w( before_all between_before_all_and_after_all after_all ), @controller.template.assigns["ran_filter"] end @@ -818,15 +802,6 @@ class YieldingAroundFiltersTest < Test::Unit::TestCase include PostsController::AroundExceptions include ActionController::TestProcess - def test_filters_registering - assert_equal 1, ControllerWithFilterMethod.filter_chain.size - assert_equal 1, ControllerWithFilterClass.filter_chain.size - assert_equal 1, ControllerWithFilterInstance.filter_chain.size - assert_equal 3, ControllerWithSymbolAsFilter.filter_chain.size - assert_equal 6, ControllerWithNestedFilters.filter_chain.size - assert_equal 4, ControllerWithAllTypesOfFilters.filter_chain.size - end - def test_base controller = PostsController assert_nothing_raised { test_process(controller,'no_raise') } -- cgit v1.2.3 From f766f669464fa9900197d6b3559c2e00e53de9cd Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 23 May 2009 01:36:09 +0200 Subject: Make logging_test pass with the new base --- actionpack/Rakefile | 2 +- actionpack/lib/action_controller/base/filter_parameter_logging.rb | 2 +- actionpack/test/controller/logging_test.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 18e5b3d96a..2b48b2cad5 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -68,7 +68,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| http_digest_authentication layout mime_responds record_identifier redirect render render_json render_xml send_file request_forgery_protection rescue url_rewriter - verification webservice + verification webservice logging ).map { |name| "test/controller/#{name}_test.rb" } t.verbose = true end diff --git a/actionpack/lib/action_controller/base/filter_parameter_logging.rb b/actionpack/lib/action_controller/base/filter_parameter_logging.rb index 8e012b2a25..f5a678ca03 100644 --- a/actionpack/lib/action_controller/base/filter_parameter_logging.rb +++ b/actionpack/lib/action_controller/base/filter_parameter_logging.rb @@ -71,7 +71,7 @@ module ActionController if logger parameters = respond_to?(:filter_parameters) ? filter_parameters(params) : params.dup - parameters = parameters.except!(:controller, :action, :format, :_method) + parameters = parameters.except!(:controller, :action, :format, :_method, :only_path) unless parameters.empty? # TODO : Move DelayedLog to AS diff --git a/actionpack/test/controller/logging_test.rb b/actionpack/test/controller/logging_test.rb index 75afa2d133..a7ed1b8665 100644 --- a/actionpack/test/controller/logging_test.rb +++ b/actionpack/test/controller/logging_test.rb @@ -35,7 +35,7 @@ class LoggingTest < ActionController::TestCase end def test_logging_with_parameters - get :show, :id => 10 + get :show, :id => '10' assert_equal 3, logs.size params = logs.detect {|l| l =~ /Parameters/ } @@ -49,6 +49,6 @@ class LoggingTest < ActionController::TestCase end def logs - @logs ||= @controller.logger.logged.compact.map {|l| l.strip} + @logs ||= @controller.logger.logged.compact.map {|l| l.to_s.strip} end end -- cgit v1.2.3 From b77602824afe07dfd8fd8e48407a6086802ec7ef Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 23 May 2009 01:40:50 +0200 Subject: Add some more tests to the test_new_base_on_old_tests task --- actionpack/Rakefile | 2 +- actionpack/test/controller/routing_test.rb | 1 + actionpack/test/controller/selector_test.rb | 1 + actionpack/test/new_base/abstract_unit.rb | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 2b48b2cad5..448acf20cb 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -68,7 +68,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| http_digest_authentication layout mime_responds record_identifier redirect render render_json render_xml send_file request_forgery_protection rescue url_rewriter - verification webservice logging + verification webservice logging resources routing ).map { |name| "test/controller/#{name}_test.rb" } t.verbose = true end diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 77abb68f32..11bffdb42e 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -1,5 +1,6 @@ require 'abstract_unit' require 'controller/fake_controllers' +require 'active_support/dependencies' class MilestonesController < ActionController::Base def index() head :ok end diff --git a/actionpack/test/controller/selector_test.rb b/actionpack/test/controller/selector_test.rb index 9d0613d1e2..5a5dc840b5 100644 --- a/actionpack/test/controller/selector_test.rb +++ b/actionpack/test/controller/selector_test.rb @@ -5,6 +5,7 @@ require 'abstract_unit' require 'controller/fake_controllers' +require 'action_controller/vendor/html-scanner' class SelectorTest < Test::Unit::TestCase # diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb index 569e4e764f..0b71488bd6 100644 --- a/actionpack/test/new_base/abstract_unit.rb +++ b/actionpack/test/new_base/abstract_unit.rb @@ -10,6 +10,7 @@ $stderr.puts "Running old tests on new_base" require 'test/unit' require 'active_support' +require 'active_support/core_ext' require 'active_support/test_case' require 'action_controller/abstract' require 'action_controller/new_base' -- cgit v1.2.3 From 63ed43cb9901cc7adc352a51fa256c3ba7b6637f Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 22 May 2009 15:50:31 -0700 Subject: Added render_other_test.rb to the new base test runner --- actionpack/Rakefile | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 448acf20cb..99ef542f3e 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -61,14 +61,24 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| t.libs << "test/new_base" << "test/lib" # layout # Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + + + # ==== Not ported + # * cookie + # * filters + # * integration + # * render_js + # * selector + # * test + # * translation + # * view_paths t.test_files = %w( action_pack_assertions addresses_render assert_select base benchmark caching capture content_type dispatcher filter_params flash helper http_basic_authentication - http_digest_authentication layout mime_responds - record_identifier redirect render render_json render_xml - send_file request_forgery_protection rescue url_rewriter - verification webservice logging resources routing + http_digest_authentication layout logging mime_responds + record_identifier redirect render render_json render_other render_xml + request_forgery_protection rescue resources routing send_file + url_rewriter verification webservice ).map { |name| "test/controller/#{name}_test.rb" } t.verbose = true end -- cgit v1.2.3 From 28dbeb3a643eeb35767df55ed579f54438c3ee18 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 22 May 2009 16:50:26 -0700 Subject: Get controller/render_other_test.rb to pass on new base and fixed a bug in new base with regards to rendering layouts. --- actionpack/lib/action_controller/abstract/layouts.rb | 2 +- actionpack/lib/action_view/template/template.rb | 3 ++- actionpack/test/controller/render_other_test.rb | 14 +++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index b3b743d6e8..8721e5f4dc 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -85,7 +85,7 @@ module AbstractController end begin - _layout_for_name(_layout) if _action_has_layout? + _layout_for_name(_layout, details) if _action_has_layout? rescue NameError => e raise NoMethodError, "You specified #{@_layout.inspect} as the layout, but no such method was found" diff --git a/actionpack/lib/action_view/template/template.rb b/actionpack/lib/action_view/template/template.rb index d58f4ec19e..f61dd591a5 100644 --- a/actionpack/lib/action_view/template/template.rb +++ b/actionpack/lib/action_view/template/template.rb @@ -15,11 +15,12 @@ module ActionView @handler = handler @details = details - format = details[:format] || begin + format = details.delete(:format) || begin # TODO: Clean this up handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html" end @mime_type = Mime::Type.lookup_by_extension(format.to_s) + @details[:formats] = Array.wrap(format && format.to_sym) end def render(view, locals, &blk) diff --git a/actionpack/test/controller/render_other_test.rb b/actionpack/test/controller/render_other_test.rb index 3c52b7036d..05645e47fa 100644 --- a/actionpack/test/controller/render_other_test.rb +++ b/actionpack/test/controller/render_other_test.rb @@ -4,6 +4,7 @@ require 'pathname' class TestController < ActionController::Base protect_from_forgery + layout :determine_layout module RenderTestHelper def rjs_helper_method_from_module @@ -113,9 +114,16 @@ private def determine_layout case action_name - when "render_js_with_explicit_template", - "render_js_with_explicit_action_template", - "delete_with_js", "update_page", "update_page_with_instance_variables" + when "hello_world", "layout_test", "rendering_without_layout", + "rendering_nothing_on_layout", "render_text_hello_world", + "render_text_hello_world_with_layout", + "hello_world_with_layout_false", + "partial_only", "partial_only_with_layout", + "accessing_params_in_template", + "accessing_params_in_template_with_layout", + "render_with_explicit_template", + "render_with_explicit_string_template", + "update_page", "update_page_with_instance_variables" "layouts/standard" when "action_talk_to_layout", "layout_overriding_layout" -- cgit v1.2.3 From c90f613ad68253cb253bf47cb812f9e027c35d10 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 23 May 2009 01:59:23 +0200 Subject: Add Translation to the new base --- actionpack/lib/action_controller/new_base.rb | 1 + actionpack/lib/action_controller/new_base/base.rb | 1 + actionpack/test/new_base/abstract_unit.rb | 3 +++ 3 files changed, 5 insertions(+) diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index d6107d3653..ad0e07e261 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -34,6 +34,7 @@ module ActionController autoload :Streaming, 'action_controller/base/streaming' autoload :HttpAuthentication, 'action_controller/base/http_authentication' autoload :FilterParameterLogging, 'action_controller/base/filter_parameter_logging' + autoload :Translation, 'action_controller/translation' require 'action_controller/routing' end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 6340b7fde9..85354bfea3 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -34,6 +34,7 @@ module ActionController include ActionController::HttpAuthentication::Basic::ControllerMethods include ActionController::HttpAuthentication::Digest::ControllerMethods include ActionController::FilterParameterLogging + include ActionController::Translation # TODO: Extract into its own module # This should be moved together with other normalizing behavior diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb index 0b71488bd6..5df2576916 100644 --- a/actionpack/test/new_base/abstract_unit.rb +++ b/actionpack/test/new_base/abstract_unit.rb @@ -10,7 +10,10 @@ $stderr.puts "Running old tests on new_base" require 'test/unit' require 'active_support' + +# TODO : Revisit requiring all the core extensions here require 'active_support/core_ext' + require 'active_support/test_case' require 'action_controller/abstract' require 'action_controller/new_base' -- cgit v1.2.3 From f9dde8fe4e14e7750e9a00c666b052bb409ead05 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 16:57:45 -0700 Subject: Port cookies to new base --- actionpack/Rakefile | 3 +- actionpack/lib/action_controller/new_base.rb | 3 +- actionpack/lib/action_controller/new_base/base.rb | 1 + actionpack/test/controller/cookie_test.rb | 40 +++++++++++++++-------- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 99ef542f3e..c31d11503c 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -63,7 +63,6 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| # Dir.glob( "test/{dispatch,template}/**/*_test.rb" ).sort + # ==== Not ported - # * cookie # * filters # * integration # * render_js @@ -73,7 +72,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| # * view_paths t.test_files = %w( action_pack_assertions addresses_render assert_select - base benchmark caching capture content_type dispatcher + base benchmark caching capture content_type cookie dispatcher filter_params flash helper http_basic_authentication http_digest_authentication layout logging mime_responds record_identifier redirect render render_json render_other render_xml diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index ad0e07e261..276be50614 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -35,9 +35,10 @@ module ActionController autoload :HttpAuthentication, 'action_controller/base/http_authentication' autoload :FilterParameterLogging, 'action_controller/base/filter_parameter_logging' autoload :Translation, 'action_controller/translation' + autoload :Cookies, 'action_controller/base/cookies' require 'action_controller/routing' end require 'action_dispatch' -require 'action_view' \ No newline at end of file +require 'action_view' diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index 85354bfea3..e321d97ac1 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -26,6 +26,7 @@ module ActionController # Rails 2.x compatibility include ActionController::Rails2Compatibility + include ActionController::Cookies include ActionController::Session include ActionController::Flash include ActionController::Verification diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb index 0f22714071..39d0017dd8 100644 --- a/actionpack/test/controller/cookie_test.rb +++ b/actionpack/test/controller/cookie_test.rb @@ -4,44 +4,48 @@ class CookieTest < ActionController::TestCase class TestController < ActionController::Base def authenticate cookies["user_name"] = "david" + head :ok end def set_with_with_escapable_characters cookies["that & guy"] = "foo & bar => baz" + head :ok end def authenticate_for_fourteen_days cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) } + head :ok end def authenticate_for_fourteen_days_with_symbols cookies[:user_name] = { :value => "david", :expires => Time.utc(2005, 10, 10,5) } + head :ok end def set_multiple_cookies cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) } cookies["login"] = "XJ-122" + head :ok end def access_frozen_cookies cookies["will"] = "work" + head :ok end def logout cookies.delete("user_name") + head :ok end def delete_cookie_with_path cookies.delete("user_name", :path => '/beaten') - render :text => "hello world" + head :ok end def authenticate_with_http_only cookies["user_name"] = { :value => "david", :httponly => true } - end - - def rescue_action(e) - raise unless ActionView::MissingTemplate # No templates here, and we don't care about the output + head :ok end end @@ -54,38 +58,38 @@ class CookieTest < ActionController::TestCase def test_setting_cookie get :authenticate - assert_equal "user_name=david; path=/", @response.headers["Set-Cookie"] + assert_cookie_header "user_name=david; path=/" assert_equal({"user_name" => "david"}, @response.cookies) end def test_setting_with_escapable_characters get :set_with_with_escapable_characters - assert_equal "that+%26+guy=foo+%26+bar+%3D%3E+baz; path=/", @response.headers["Set-Cookie"] + assert_cookie_header "that+%26+guy=foo+%26+bar+%3D%3E+baz; path=/" assert_equal({"that & guy" => "foo & bar => baz"}, @response.cookies) end def test_setting_cookie_for_fourteen_days get :authenticate_for_fourteen_days - assert_equal "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT", @response.headers["Set-Cookie"] + assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT" assert_equal({"user_name" => "david"}, @response.cookies) end def test_setting_cookie_for_fourteen_days_with_symbols get :authenticate_for_fourteen_days_with_symbols - assert_equal "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT", @response.headers["Set-Cookie"] + assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT" assert_equal({"user_name" => "david"}, @response.cookies) end def test_setting_cookie_with_http_only get :authenticate_with_http_only - assert_equal "user_name=david; path=/; HttpOnly", @response.headers["Set-Cookie"] + assert_cookie_header "user_name=david; path=/; HttpOnly" assert_equal({"user_name" => "david"}, @response.cookies) end def test_multiple_cookies get :set_multiple_cookies assert_equal 2, @response.cookies.size - assert_equal "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT\nlogin=XJ-122; path=/", @response.headers["Set-Cookie"] + assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT\nlogin=XJ-122; path=/" assert_equal({"login" => "XJ-122", "user_name" => "david"}, @response.cookies) end @@ -95,7 +99,7 @@ class CookieTest < ActionController::TestCase def test_expiring_cookie get :logout - assert_equal "user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", @response.headers["Set-Cookie"] + assert_cookie_header "user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT" assert_equal({"user_name" => nil}, @response.cookies) end @@ -116,6 +120,16 @@ class CookieTest < ActionController::TestCase def test_delete_cookie_with_path get :delete_cookie_with_path - assert_equal "user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT", @response.headers["Set-Cookie"] + assert_cookie_header "user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT" end + + private + def assert_cookie_header(expected) + header = @response.headers["Set-Cookie"] + if header.respond_to?(:to_str) + assert_equal expected, header + else + assert_equal expected.split("\n"), header + end + end end -- cgit v1.2.3 From 3a72b55229f63d2cba3337c39cd118cf532ebbbc Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 23 May 2009 02:07:50 +0200 Subject: Add missing selector_test to the list --- actionpack/Rakefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index c31d11503c..ea12adb921 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -66,9 +66,7 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| # * filters # * integration # * render_js - # * selector # * test - # * translation # * view_paths t.test_files = %w( action_pack_assertions addresses_render assert_select @@ -76,8 +74,8 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| filter_params flash helper http_basic_authentication http_digest_authentication layout logging mime_responds record_identifier redirect render render_json render_other render_xml - request_forgery_protection rescue resources routing send_file - url_rewriter verification webservice + request_forgery_protection rescue resources routing selector send_file + translation url_rewriter verification webservice ).map { |name| "test/controller/#{name}_test.rb" } t.verbose = true end -- cgit v1.2.3 From 7b3fb1d43f57d6ebe3edb75434cae01e140483d0 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 22 May 2009 17:07:40 -0700 Subject: Got controller/render_js_test.rb to pass on new base --- actionpack/Rakefile | 7 +++---- actionpack/lib/action_controller/new_base/base.rb | 1 + actionpack/lib/action_controller/new_base/render_options.rb | 10 ++++++++++ actionpack/test/controller/render_js_test.rb | 2 ++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/actionpack/Rakefile b/actionpack/Rakefile index ea12adb921..b9819d4a83 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -65,7 +65,6 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| # ==== Not ported # * filters # * integration - # * render_js # * test # * view_paths t.test_files = %w( @@ -73,9 +72,9 @@ Rake::TestTask.new(:test_new_base_on_old_tests) do |t| base benchmark caching capture content_type cookie dispatcher filter_params flash helper http_basic_authentication http_digest_authentication layout logging mime_responds - record_identifier redirect render render_json render_other render_xml - request_forgery_protection rescue resources routing selector send_file - translation url_rewriter verification webservice + record_identifier redirect render render_js render_json + render_other render_xml request_forgery_protection rescue + resources routing selector send_file url_rewriter verification webservice ).map { |name| "test/controller/#{name}_test.rb" } t.verbose = true end diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index e321d97ac1..adb760ea7e 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -12,6 +12,7 @@ module ActionController include ActionController::Redirector include ActionController::Renderer include ActionController::Renderers::Json + include ActionController::Renderers::Js include ActionController::Renderers::Xml include ActionController::Renderers::Rjs include ActionController::Layouts diff --git a/actionpack/lib/action_controller/new_base/render_options.rb b/actionpack/lib/action_controller/new_base/render_options.rb index 2ce9d0c7ae..33f8957f6e 100644 --- a/actionpack/lib/action_controller/new_base/render_options.rb +++ b/actionpack/lib/action_controller/new_base/render_options.rb @@ -62,6 +62,16 @@ module ActionController end end + module Js + include RenderOption + register_renderer :js + + def _render_js(js, options) + response.content_type ||= Mime::JS + self.response_body = js + end + end + module Xml include RenderOption register_renderer :xml diff --git a/actionpack/test/controller/render_js_test.rb b/actionpack/test/controller/render_js_test.rb index 7b50242910..d02fd3fd4c 100644 --- a/actionpack/test/controller/render_js_test.rb +++ b/actionpack/test/controller/render_js_test.rb @@ -19,6 +19,8 @@ class TestController < ActionController::Base end class RenderTest < ActionController::TestCase + tests TestController + def test_render_vanilla_js get :render_vanilla_js_hello assert_equal "alert('hello')", @response.body -- cgit v1.2.3 From 8a03a999ef2ed47c7f2ead1a9dd639120c569e03 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 17:15:56 -0700 Subject: Cordon off missing filter methods --- actionpack/test/controller/filters_test.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index 490061ed9b..22aa50adb2 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -1,5 +1,13 @@ require 'abstract_unit' +class << ActionController::Base + %w(append_around_filter prepend_after_filter prepend_around_filter prepend_before_filter skip_after_filter skip_before_filter skip_filter).each do |pending| + define_method(pending) do |*args| + $stderr.puts "#{pending} unimplemented: #{args.inspect}" + end unless method_defined?(pending) + end +end + class FilterTest < Test::Unit::TestCase include ActionController::TestProcess -- cgit v1.2.3 From da9e53ec3b92fd583346896dd15c5b2533c8af6a Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 22 May 2009 17:17:14 -0700 Subject: Move testing_sandbox to test/lib --- actionpack/test/lib/testing_sandbox.rb | 15 +++++++++++++++ actionpack/test/testing_sandbox.rb | 15 --------------- 2 files changed, 15 insertions(+), 15 deletions(-) create mode 100644 actionpack/test/lib/testing_sandbox.rb delete mode 100644 actionpack/test/testing_sandbox.rb diff --git a/actionpack/test/lib/testing_sandbox.rb b/actionpack/test/lib/testing_sandbox.rb new file mode 100644 index 0000000000..c36585104f --- /dev/null +++ b/actionpack/test/lib/testing_sandbox.rb @@ -0,0 +1,15 @@ +module TestingSandbox + # Temporarily replaces KCODE for the block + def with_kcode(kcode) + if RUBY_VERSION < '1.9' + old_kcode, $KCODE = $KCODE, kcode + begin + yield + ensure + $KCODE = old_kcode + end + else + yield + end + end +end diff --git a/actionpack/test/testing_sandbox.rb b/actionpack/test/testing_sandbox.rb deleted file mode 100644 index c36585104f..0000000000 --- a/actionpack/test/testing_sandbox.rb +++ /dev/null @@ -1,15 +0,0 @@ -module TestingSandbox - # Temporarily replaces KCODE for the block - def with_kcode(kcode) - if RUBY_VERSION < '1.9' - old_kcode, $KCODE = $KCODE, kcode - begin - yield - ensure - $KCODE = old_kcode - end - else - yield - end - end -end -- cgit v1.2.3 From 69a1ea8b5d4befe93ca4d11c052e831c7bd2e2b2 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Fri, 22 May 2009 17:15:46 -0700 Subject: Created an ActionController::Renderers::All that includes all the default render options (:json, :js, :rjs, :xml) --- actionpack/lib/action_controller/new_base/base.rb | 5 +---- actionpack/lib/action_controller/new_base/render_options.rb | 11 +++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index adb760ea7e..ffe608ade4 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -11,10 +11,7 @@ module ActionController include ActionController::UrlFor include ActionController::Redirector include ActionController::Renderer - include ActionController::Renderers::Json - include ActionController::Renderers::Js - include ActionController::Renderers::Xml - include ActionController::Renderers::Rjs + include ActionController::Renderers::All include ActionController::Layouts include ActionController::ConditionalGet diff --git a/actionpack/lib/action_controller/new_base/render_options.rb b/actionpack/lib/action_controller/new_base/render_options.rb index 33f8957f6e..581a92cb7b 100644 --- a/actionpack/lib/action_controller/new_base/render_options.rb +++ b/actionpack/lib/action_controller/new_base/render_options.rb @@ -92,5 +92,16 @@ module ActionController self.response_body = generator.to_s end end + + module All + extend ActiveSupport::DependencyModule + + included do + include ::ActionController::Renderers::Json + include ::ActionController::Renderers::Js + include ::ActionController::Renderers::Xml + include ::ActionController::Renderers::Rjs + end + end end end -- cgit v1.2.3 From 595107f22e6a26e20860d0023478437a51daa5c6 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 23 May 2009 02:20:28 +0200 Subject: Move html-scanner tests one dir up --- actionpack/Rakefile | 2 +- .../controller/html-scanner/cdata_node_test.rb | 15 -- .../test/controller/html-scanner/document_test.rb | 148 ----------- .../test/controller/html-scanner/node_test.rb | 89 ------- .../test/controller/html-scanner/sanitizer_test.rb | 273 --------------------- .../test/controller/html-scanner/tag_node_test.rb | 238 ------------------ .../test/controller/html-scanner/text_node_test.rb | 50 ---- .../test/controller/html-scanner/tokenizer_test.rb | 131 ---------- actionpack/test/html-scanner/cdata_node_test.rb | 15 ++ actionpack/test/html-scanner/document_test.rb | 148 +++++++++++ actionpack/test/html-scanner/node_test.rb | 89 +++++++ actionpack/test/html-scanner/sanitizer_test.rb | 273 +++++++++++++++++++++ actionpack/test/html-scanner/tag_node_test.rb | 238 ++++++++++++++++++ actionpack/test/html-scanner/text_node_test.rb | 50 ++++ actionpack/test/html-scanner/tokenizer_test.rb | 131 ++++++++++ 15 files changed, 945 insertions(+), 945 deletions(-) delete mode 100644 actionpack/test/controller/html-scanner/cdata_node_test.rb delete mode 100644 actionpack/test/controller/html-scanner/document_test.rb delete mode 100644 actionpack/test/controller/html-scanner/node_test.rb delete mode 100644 actionpack/test/controller/html-scanner/sanitizer_test.rb delete mode 100644 actionpack/test/controller/html-scanner/tag_node_test.rb delete mode 100644 actionpack/test/controller/html-scanner/text_node_test.rb delete mode 100644 actionpack/test/controller/html-scanner/tokenizer_test.rb create mode 100644 actionpack/test/html-scanner/cdata_node_test.rb create mode 100644 actionpack/test/html-scanner/document_test.rb create mode 100644 actionpack/test/html-scanner/node_test.rb create mode 100644 actionpack/test/html-scanner/sanitizer_test.rb create mode 100644 actionpack/test/html-scanner/tag_node_test.rb create mode 100644 actionpack/test/html-scanner/text_node_test.rb create mode 100644 actionpack/test/html-scanner/tokenizer_test.rb diff --git a/actionpack/Rakefile b/actionpack/Rakefile index b9819d4a83..9ce897aae8 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -30,7 +30,7 @@ Rake::TestTask.new(:test_action_pack) do |t| # make sure we include the tests in alphabetical order as on some systems # this will not happen automatically and the tests (as a whole) will error - t.test_files = Dir.glob( "test/{controller,dispatch,template}/**/*_test.rb" ).sort + t.test_files = Dir.glob( "test/{controller,dispatch,template,html-scanner}/**/*_test.rb" ).sort t.verbose = true #t.warning = true diff --git a/actionpack/test/controller/html-scanner/cdata_node_test.rb b/actionpack/test/controller/html-scanner/cdata_node_test.rb deleted file mode 100644 index 1822cc565a..0000000000 --- a/actionpack/test/controller/html-scanner/cdata_node_test.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'abstract_unit' - -class CDATANodeTest < Test::Unit::TestCase - def setup - @node = HTML::CDATA.new(nil, 0, 0, "

howdy

") - end - - def test_to_s - assert_equal "howdy

]]>", @node.to_s - end - - def test_content - assert_equal "

howdy

", @node.content - end -end diff --git a/actionpack/test/controller/html-scanner/document_test.rb b/actionpack/test/controller/html-scanner/document_test.rb deleted file mode 100644 index c68f04fa75..0000000000 --- a/actionpack/test/controller/html-scanner/document_test.rb +++ /dev/null @@ -1,148 +0,0 @@ -require 'abstract_unit' - -class DocumentTest < Test::Unit::TestCase - def test_handle_doctype - doc = nil - assert_nothing_raised do - doc = HTML::Document.new <<-HTML.strip - - - - HTML - end - assert_equal 3, doc.root.children.length - assert_equal %{}, doc.root.children[0].content - assert_match %r{\s+}m, doc.root.children[1].content - assert_equal "html", doc.root.children[2].name - end - - def test_find_img - doc = HTML::Document.new <<-HTML.strip - - -

- - - HTML - assert doc.find(:tag=>"img", :attributes=>{"src"=>"hello.gif"}) - end - - def test_find_all - doc = HTML::Document.new <<-HTML.strip - - -

-
-

something

-

here is more

-
- - - HTML - all = doc.find_all :attributes => { :class => "test" } - assert_equal 3, all.length - assert_equal [ "p", "p", "em" ], all.map { |n| n.name } - end - - def test_find_with_text - doc = HTML::Document.new <<-HTML.strip - - -

Some text

- - - HTML - assert doc.find(:content => "Some text") - assert doc.find(:tag => "p", :child => { :content => "Some text" }) - assert doc.find(:tag => "p", :child => "Some text") - assert doc.find(:tag => "p", :content => "Some text") - end - - def test_parse_xml - assert_nothing_raised { HTML::Document.new("", true, true) } - assert_nothing_raised { HTML::Document.new("something", true, true) } - end - - def test_parse_document - doc = HTML::Document.new(<<-HTML) -
-

blah

- -
-
- HTML - assert_not_nil doc.find(:tag => "div", :children => { :count => 1, :only => { :tag => "table" } }) - end - - def test_tag_nesting_nothing_to_s - doc = HTML::Document.new("") - assert_equal "", doc.root.to_s - end - - def test_tag_nesting_space_to_s - doc = HTML::Document.new(" ") - assert_equal " ", doc.root.to_s - end - - def test_tag_nesting_text_to_s - doc = HTML::Document.new("text") - assert_equal "text", doc.root.to_s - end - - def test_tag_nesting_tag_to_s - doc = HTML::Document.new("") - assert_equal "", doc.root.to_s - end - - def test_parse_cdata - doc = HTML::Document.new(<<-HTML) - - - - <![CDATA[<br>]]> - - -

this document has <br> for a title

- - -HTML - - assert_nil doc.find(:tag => "title", :descendant => { :tag => "br" }) - assert doc.find(:tag => "title", :child => "
") - end - - def test_find_empty_tag - doc = HTML::Document.new("
") - assert_nil doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /./) - assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /\A\Z/) - assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /^$/) - assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => "") - assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => nil) - end - - def test_parse_invalid_document - assert_nothing_raised do - doc = HTML::Document.new(" - - - - -
About Us
- ") - end - end - - def test_invalid_document_raises_exception_when_strict - assert_raise RuntimeError do - doc = HTML::Document.new(" - - - - -
About Us
- ", true) - end - end - -end diff --git a/actionpack/test/controller/html-scanner/node_test.rb b/actionpack/test/controller/html-scanner/node_test.rb deleted file mode 100644 index b0df36877e..0000000000 --- a/actionpack/test/controller/html-scanner/node_test.rb +++ /dev/null @@ -1,89 +0,0 @@ -require 'abstract_unit' - -class NodeTest < Test::Unit::TestCase - - class MockNode - def initialize(matched, value) - @matched = matched - @value = value - end - - def find(conditions) - @matched && self - end - - def to_s - @value.to_s - end - end - - def setup - @node = HTML::Node.new("parent") - @node.children.concat [MockNode.new(false,1), MockNode.new(true,"two"), MockNode.new(false,:three)] - end - - def test_match - assert !@node.match("foo") - end - - def test_tag - assert !@node.tag? - end - - def test_to_s - assert_equal "1twothree", @node.to_s - end - - def test_find - assert_equal "two", @node.find('blah').to_s - end - - def test_parse_strict - s = "" - assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) } - end - - def test_parse_relaxed - s = "" - node = nil - assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) } - assert node.attributes.has_key?("foo") - assert !node.attributes.has_key?("bar") - end - - def test_to_s_with_boolean_attrs - s = "" - node = HTML::Node.parse(nil,0,0,s) - assert node.attributes.has_key?("foo") - assert node.attributes.has_key?("bar") - assert "", node.to_s - end - - def test_parse_with_unclosed_tag - s = "contents', node.content - end - - def test_parse_strict_with_unterminated_cdata_section - s = "")) - assert_equal("Dont touch me", sanitizer.sanitize("Dont touch me")) - assert_equal("This is a test.", sanitizer.sanitize("

This is a test.

")) - assert_equal("Weirdos", sanitizer.sanitize("Wei<a onclick='alert(document.cookie);'/>rdos")) - assert_equal("This is a test.", sanitizer.sanitize("This is a test.")) - assert_equal( - %{This is a test.\n\n\nIt no longer contains any HTML.\n}, sanitizer.sanitize( - %{This is <b>a <a href="" target="_blank">test</a></b>.\n\n\n\n

It no longer contains any HTML.

\n})) - assert_equal "This has a here.", sanitizer.sanitize("This has a here.") - assert_equal "This has a here.", sanitizer.sanitize("This has a ]]> here.") - assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed ]] here...") - [nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) } - end - - def test_strip_links - sanitizer = HTML::LinkSanitizer.new - assert_equal "Dont touch me", sanitizer.sanitize("Dont touch me") - assert_equal "on my mind\nall day long", sanitizer.sanitize("on my mind\nall day long") - assert_equal "0wn3d", sanitizer.sanitize("0wn3d") - assert_equal "Magic", sanitizer.sanitize("Magic") - assert_equal "FrrFox", sanitizer.sanitize("FrrFox") - assert_equal "My mind\nall day long", sanitizer.sanitize("My mind\nall day long") - assert_equal "all day long", sanitizer.sanitize("<a href='hello'>all day long</a>") - - assert_equal "", '' - end - - def test_sanitize_plaintext - raw = "<span>foo</span></plaintext>" - assert_sanitized raw, "<span>foo</span>" - end - - def test_sanitize_script - assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cd e f" - end - - # fucked - def test_sanitize_js_handlers - raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>} - assert_sanitized raw, %{onthis="do that" <a name="foo" href="#">hello</a>} - end - - def test_sanitize_javascript_href - raw = %{href="javascript:bang" <a href="javascript:bang" name="hello">foo</a>, <span href="javascript:bang">bar</span>} - assert_sanitized raw, %{href="javascript:bang" <a name="hello">foo</a>, <span>bar</span>} - end - - def test_sanitize_image_src - raw = %{src="javascript:bang" <img src="javascript:bang" width="5">foo</img>, <span src="javascript:bang">bar</span>} - assert_sanitized raw, %{src="javascript:bang" <img width="5">foo</img>, <span>bar</span>} - end - - HTML::WhiteListSanitizer.allowed_tags.each do |tag_name| - define_method "test_should_allow_#{tag_name}_tag" do - assert_sanitized "start <#{tag_name} title=\"1\" onclick=\"foo\">foo <bad>bar</bad> baz</#{tag_name}> end", %(start <#{tag_name} title="1">foo bar baz</#{tag_name}> end) - end - end - - def test_should_allow_anchors - assert_sanitized %(<a href="foo" onclick="bar"><script>baz</script></a>), %(<a href="foo"></a>) - end - - # RFC 3986, sec 4.2 - def test_allow_colons_in_path_component - assert_sanitized("<a href=\"./this:that\">foo</a>") - end - - %w(src width height alt).each do |img_attr| - define_method "test_should_allow_image_#{img_attr}_attribute" do - assert_sanitized %(<img #{img_attr}="foo" onclick="bar" />), %(<img #{img_attr}="foo" />) - end - end - - def test_should_handle_non_html - assert_sanitized 'abc' - end - - def test_should_handle_blank_text - assert_sanitized nil - assert_sanitized '' - end - - def test_should_allow_custom_tags - text = "<u>foo</u>" - sanitizer = HTML::WhiteListSanitizer.new - assert_equal(text, sanitizer.sanitize(text, :tags => %w(u))) - end - - def test_should_allow_only_custom_tags - text = "<u>foo</u> with <i>bar</i>" - sanitizer = HTML::WhiteListSanitizer.new - assert_equal("<u>foo</u> with bar", sanitizer.sanitize(text, :tags => %w(u))) - end - - def test_should_allow_custom_tags_with_attributes - text = %(<blockquote cite="http://example.com/">foo</blockquote>) - sanitizer = HTML::WhiteListSanitizer.new - assert_equal(text, sanitizer.sanitize(text)) - end - - def test_should_allow_custom_tags_with_custom_attributes - text = %(<blockquote foo="bar">Lorem ipsum</blockquote>) - sanitizer = HTML::WhiteListSanitizer.new - assert_equal(text, sanitizer.sanitize(text, :attributes => ['foo'])) - end - - [%w(img src), %w(a href)].each do |(tag, attr)| - define_method "test_should_strip_#{attr}_attribute_in_#{tag}_with_bad_protocols" do - assert_sanitized %(<#{tag} #{attr}="javascript:bang" title="1">boo</#{tag}>), %(<#{tag} title="1">boo</#{tag}>) - end - end - - def test_should_flag_bad_protocols - sanitizer = HTML::WhiteListSanitizer.new - %w(about chrome data disk hcp help javascript livescript lynxcgi lynxexec ms-help ms-its mhtml mocha opera res resource shell vbscript view-source vnd.ms.radio wysiwyg).each do |proto| - assert sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://bad") - end - end - - def test_should_accept_good_protocols - sanitizer = HTML::WhiteListSanitizer.new - HTML::WhiteListSanitizer.allowed_protocols.each do |proto| - assert !sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://good") - end - end - - def test_should_reject_hex_codes_in_protocol - assert_sanitized %(<a href="&#37;6A&#37;61&#37;76&#37;61&#37;73&#37;63&#37;72&#37;69&#37;70&#37;74&#37;3A&#37;61&#37;6C&#37;65&#37;72&#37;74&#37;28&#37;22&#37;58&#37;53&#37;53&#37;22&#37;29">1</a>), "<a>1</a>" - assert @sanitizer.send(:contains_bad_protocols?, 'src', "%6A%61%76%61%73%63%72%69%70%74%3A%61%6C%65%72%74%28%22%58%53%53%22%29") - end - - def test_should_block_script_tag - assert_sanitized %(<SCRIPT\nSRC=http://ha.ckers.org/xss.js></SCRIPT>), "" - end - - [%(<IMG SRC="javascript:alert('XSS');">), - %(<IMG SRC=javascript:alert('XSS')>), - %(<IMG SRC=JaVaScRiPt:alert('XSS')>), - %(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">), - %(<IMG SRC=javascript:alert(&quot;XSS&quot;)>), - %(<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>), - %(<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>), - %(<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>), - %(<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>), - %(<IMG SRC="jav\tascript:alert('XSS');">), - %(<IMG SRC="jav&#x09;ascript:alert('XSS');">), - %(<IMG SRC="jav&#x0A;ascript:alert('XSS');">), - %(<IMG SRC="jav&#x0D;ascript:alert('XSS');">), - %(<IMG SRC=" &#14; javascript:alert('XSS');">), - %(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each_with_index do |img_hack, i| - define_method "test_should_not_fall_for_xss_image_hack_#{i+1}" do - assert_sanitized img_hack, "<img>" - end - end - - def test_should_sanitize_tag_broken_up_by_null - assert_sanitized %(<SCR\0IPT>alert(\"XSS\")</SCR\0IPT>), "alert(\"XSS\")" - end - - def test_should_sanitize_invalid_script_tag - assert_sanitized %(<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>), "" - end - - def test_should_sanitize_script_tag_with_multiple_open_brackets - assert_sanitized %(<<SCRIPT>alert("XSS");//<</SCRIPT>), "&lt;" - assert_sanitized %(<iframe src=http://ha.ckers.org/scriptlet.html\n<a), %(&lt;a) - end - - def test_should_sanitize_unclosed_script - assert_sanitized %(<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>), "<b>" - end - - def test_should_sanitize_half_open_scripts - assert_sanitized %(<IMG SRC="javascript:alert('XSS')"), "<img>" - end - - def test_should_not_fall_for_ridiculous_hack - img_hack = %(<IMG\nSRC\n=\n"\nj\na\nv\na\ns\nc\nr\ni\np\nt\n:\na\nl\ne\nr\nt\n(\n'\nX\nS\nS\n'\n)\n"\n>) - assert_sanitized img_hack, "<img>" - end - - # fucked - def test_should_sanitize_attributes - assert_sanitized %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="'&gt;&lt;script&gt;alert()&lt;/script&gt;">blah</span>) - end - - def test_should_sanitize_illegal_style_properties - raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;) - expected = %(display: block; width: 100%; height: 100%; background-color: black; background-image: ; background-x: center; background-y: center;) - assert_equal expected, sanitize_css(raw) - end - - def test_should_sanitize_with_trailing_space - raw = "display:block; " - expected = "display: block;" - assert_equal expected, sanitize_css(raw) - end - - def test_should_sanitize_xul_style_attributes - raw = %(-moz-binding:url('http://ha.ckers.org/xssmoz.xml#xss')) - assert_equal '', sanitize_css(raw) - end - - def test_should_sanitize_invalid_tag_names - assert_sanitized(%(a b c<script/XSS src="http://ha.ckers.org/xss.js"></script>d e f), "a b cd e f") - end - - def test_should_sanitize_non_alpha_and_non_digit_characters_in_tags - assert_sanitized('<a onclick!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>foo</a>', "<a>foo</a>") - end - - def test_should_sanitize_invalid_tag_names_in_single_tags - assert_sanitized('<img/src="http://ha.ckers.org/xss.js"/>', "<img />") - end - - def test_should_sanitize_img_dynsrc_lowsrc - assert_sanitized(%(<img lowsrc="javascript:alert('XSS')" />), "<img />") - end - - def test_should_sanitize_div_background_image_unicode_encoded - raw = %(background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029) - assert_equal '', sanitize_css(raw) - end - - def test_should_sanitize_div_style_expression - raw = %(width: expression(alert('XSS'));) - assert_equal '', sanitize_css(raw) - end - - def test_should_sanitize_img_vbscript - assert_sanitized %(<img src='vbscript:msgbox("XSS")' />), '<img />' - end - - def test_should_sanitize_cdata_section - assert_sanitized "<![CDATA[<span>section</span>]]>", "&lt;![CDATA[&lt;span>section&lt;/span>]]>" - end - - def test_should_sanitize_unterminated_cdata_section - assert_sanitized "<![CDATA[<span>neverending...", "&lt;![CDATA[&lt;span>neverending...]]>" - end - - def test_should_not_mangle_urls_with_ampersand - assert_sanitized %{<a href=\"http://www.domain.com?var1=1&amp;var2=2\">my link</a>} - end - -protected - def assert_sanitized(input, expected = nil) - @sanitizer ||= HTML::WhiteListSanitizer.new - if input - assert_dom_equal expected || input, @sanitizer.sanitize(input) - else - assert_nil @sanitizer.sanitize(input) - end - end - - def sanitize_css(input) - (@sanitizer ||= HTML::WhiteListSanitizer.new).sanitize_css(input) - end -end diff --git a/actionpack/test/controller/html-scanner/tag_node_test.rb b/actionpack/test/controller/html-scanner/tag_node_test.rb deleted file mode 100644 index d1d4667378..0000000000 --- a/actionpack/test/controller/html-scanner/tag_node_test.rb +++ /dev/null @@ -1,238 +0,0 @@ -require 'abstract_unit' - -class TagNodeTest < Test::Unit::TestCase - def test_open_without_attributes - node = tag("<tag>") - assert_equal "tag", node.name - assert_equal Hash.new, node.attributes - assert_nil node.closing - end - - def test_open_with_attributes - node = tag("<TAG1 foo=hey_ho x:bar=\"blah blah\" BAZ='blah blah blah' >") - assert_equal "tag1", node.name - assert_equal "hey_ho", node["foo"] - assert_equal "blah blah", node["x:bar"] - assert_equal "blah blah blah", node["baz"] - end - - def test_self_closing_without_attributes - node = tag("<tag/>") - assert_equal "tag", node.name - assert_equal Hash.new, node.attributes - assert_equal :self, node.closing - end - - def test_self_closing_with_attributes - node = tag("<tag a=b/>") - assert_equal "tag", node.name - assert_equal( { "a" => "b" }, node.attributes ) - assert_equal :self, node.closing - end - - def test_closing_without_attributes - node = tag("</tag>") - assert_equal "tag", node.name - assert_nil node.attributes - assert_equal :close, node.closing - end - - def test_bracket_op_when_no_attributes - node = tag("</tag>") - assert_nil node["foo"] - end - - def test_bracket_op_when_attributes - node = tag("<tag a=b/>") - assert_equal "b", node["a"] - end - - def test_attributes_with_escaped_quotes - node = tag("<tag a='b\\'c' b=\"bob \\\"float\\\"\">") - assert_equal "b\\'c", node["a"] - assert_equal "bob \\\"float\\\"", node["b"] - end - - def test_to_s - node = tag("<a b=c d='f' g=\"h 'i'\" />") - assert_equal %(<a b='c' d='f' g='h \\'i\\'' />), node.to_s - end - - def test_tag - assert tag("<tag>").tag? - end - - def test_match_tag_as_string - assert tag("<tag>").match(:tag => "tag") - assert !tag("<tag>").match(:tag => "b") - end - - def test_match_tag_as_regexp - assert tag("<tag>").match(:tag => /t.g/) - assert !tag("<tag>").match(:tag => /t[bqs]g/) - end - - def test_match_attributes_as_string - t = tag("<tag a=something b=else />") - assert t.match(:attributes => {"a" => "something"}) - assert t.match(:attributes => {"b" => "else"}) - end - - def test_match_attributes_as_regexp - t = tag("<tag a=something b=else />") - assert t.match(:attributes => {"a" => /^something$/}) - assert t.match(:attributes => {"b" => /e.*e/}) - assert t.match(:attributes => {"a" => /me..i/, "b" => /.ls.$/}) - end - - def test_match_attributes_as_number - t = tag("<tag a=15 b=3.1415 />") - assert t.match(:attributes => {"a" => 15}) - assert t.match(:attributes => {"b" => 3.1415}) - assert t.match(:attributes => {"a" => 15, "b" => 3.1415}) - end - - def test_match_attributes_exist - t = tag("<tag a=15 b=3.1415 />") - assert t.match(:attributes => {"a" => true}) - assert t.match(:attributes => {"b" => true}) - assert t.match(:attributes => {"a" => true, "b" => true}) - end - - def test_match_attributes_not_exist - t = tag("<tag a=15 b=3.1415 />") - assert t.match(:attributes => {"c" => false}) - assert t.match(:attributes => {"c" => nil}) - assert t.match(:attributes => {"a" => true, "c" => false}) - end - - def test_match_parent_success - t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>")) - assert t.match(:parent => {:tag => "foo", :attributes => {"k" => /v.l/, "j" => false}}) - end - - def test_match_parent_fail - t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>")) - assert !t.match(:parent => {:tag => /kafka/}) - end - - def test_match_child_success - t = tag("<tag x:k='something'>") - tag("<child v=john a=kelly>", t) - tag("<sib m=vaughn v=james>", t) - assert t.match(:child => { :tag => "sib", :attributes => {"v" => /j/}}) - assert t.match(:child => { :attributes => {"a" => "kelly"}}) - end - - def test_match_child_fail - t = tag("<tag x:k='something'>") - tag("<child v=john a=kelly>", t) - tag("<sib m=vaughn v=james>", t) - assert !t.match(:child => { :tag => "sib", :attributes => {"v" => /r/}}) - assert !t.match(:child => { :attributes => {"v" => false}}) - end - - def test_match_ancestor_success - t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>"))) - assert t.match(:ancestor => {:tag => "parent", :attributes => {"a" => /ll/}}) - assert t.match(:ancestor => {:attributes => {"m" => "vaughn"}}) - end - - def test_match_ancestor_fail - t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>"))) - assert !t.match(:ancestor => {:tag => /^parent/, :attributes => {"v" => /m/}}) - assert !t.match(:ancestor => {:attributes => {"v" => false}}) - end - - def test_match_descendant_success - tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>"))) - assert t.match(:descendant => {:tag => "child", :attributes => {"a" => /ll/}}) - assert t.match(:descendant => {:attributes => {"m" => "vaughn"}}) - end - - def test_match_descendant_fail - tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>"))) - assert !t.match(:descendant => {:tag => /^child/, :attributes => {"v" => /m/}}) - assert !t.match(:descendant => {:attributes => {"v" => false}}) - end - - def test_match_child_count - t = tag("<tag x:k='something'>") - tag("hello", t) - tag("<child v=john a=kelly>", t) - tag("<sib m=vaughn v=james>", t) - assert t.match(:children => { :count => 2 }) - assert t.match(:children => { :count => 2..4 }) - assert t.match(:children => { :less_than => 4 }) - assert t.match(:children => { :greater_than => 1 }) - assert !t.match(:children => { :count => 3 }) - end - - def test_conditions_as_strings - t = tag("<tag x:k='something'>") - assert t.match("tag" => "tag") - assert t.match("attributes" => { "x:k" => "something" }) - assert !t.match("tag" => "gat") - assert !t.match("attributes" => { "x:j" => "something" }) - end - - def test_attributes_as_symbols - t = tag("<child v=john a=kelly>") - assert t.match(:attributes => { :v => /oh/ }) - assert t.match(:attributes => { :a => /ll/ }) - end - - def test_match_sibling - t = tag("<tag x:k='something'>") - tag("hello", t) - tag("<span a=b>", t) - tag("world", t) - m = tag("<span k=r>", t) - tag("<span m=l>", t) - - assert m.match(:sibling => {:tag => "span", :attributes => {:a => true}}) - assert m.match(:sibling => {:tag => "span", :attributes => {:m => true}}) - assert !m.match(:sibling => {:tag => "span", :attributes => {:k => true}}) - end - - def test_match_sibling_before - t = tag("<tag x:k='something'>") - tag("hello", t) - tag("<span a=b>", t) - tag("world", t) - m = tag("<span k=r>", t) - tag("<span m=l>", t) - - assert m.match(:before => {:tag => "span", :attributes => {:m => true}}) - assert !m.match(:before => {:tag => "span", :attributes => {:a => true}}) - assert !m.match(:before => {:tag => "span", :attributes => {:k => true}}) - end - - def test_match_sibling_after - t = tag("<tag x:k='something'>") - tag("hello", t) - tag("<span a=b>", t) - tag("world", t) - m = tag("<span k=r>", t) - tag("<span m=l>", t) - - assert m.match(:after => {:tag => "span", :attributes => {:a => true}}) - assert !m.match(:after => {:tag => "span", :attributes => {:m => true}}) - assert !m.match(:after => {:tag => "span", :attributes => {:k => true}}) - end - - def test_to_s - t = tag("<b x='foo'>") - tag("hello", t) - tag("<hr />", t) - assert_equal %(<b x="foo">hello<hr /></b>), t.to_s - end - - private - - def tag(content, parent=nil) - node = HTML::Node.parse(parent,0,0,content) - parent.children << node if parent - node - end -end diff --git a/actionpack/test/controller/html-scanner/text_node_test.rb b/actionpack/test/controller/html-scanner/text_node_test.rb deleted file mode 100644 index 1ab3f4454e..0000000000 --- a/actionpack/test/controller/html-scanner/text_node_test.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'abstract_unit' - -class TextNodeTest < Test::Unit::TestCase - def setup - @node = HTML::Text.new(nil, 0, 0, "hello, howdy, aloha, annyeong") - end - - def test_to_s - assert_equal "hello, howdy, aloha, annyeong", @node.to_s - end - - def test_find_string - assert_equal @node, @node.find("hello, howdy, aloha, annyeong") - assert_equal false, @node.find("bogus") - end - - def test_find_regexp - assert_equal @node, @node.find(/an+y/) - assert_nil @node.find(/b/) - end - - def test_find_hash - assert_equal @node, @node.find(:content => /howdy/) - assert_nil @node.find(:content => /^howdy$/) - assert_equal false, @node.find(:content => "howdy") - end - - def test_find_other - assert_nil @node.find(:hello) - end - - def test_match_string - assert @node.match("hello, howdy, aloha, annyeong") - assert_equal false, @node.match("bogus") - end - - def test_match_regexp - assert_not_nil @node, @node.match(/an+y/) - assert_nil @node.match(/b/) - end - - def test_match_hash - assert_not_nil @node, @node.match(:content => "howdy") - assert_nil @node.match(:content => /^howdy$/) - end - - def test_match_other - assert_nil @node.match(:hello) - end -end diff --git a/actionpack/test/controller/html-scanner/tokenizer_test.rb b/actionpack/test/controller/html-scanner/tokenizer_test.rb deleted file mode 100644 index a001bcbbad..0000000000 --- a/actionpack/test/controller/html-scanner/tokenizer_test.rb +++ /dev/null @@ -1,131 +0,0 @@ -require 'abstract_unit' - -class TokenizerTest < Test::Unit::TestCase - - def test_blank - tokenize "" - assert_end - end - - def test_space - tokenize " " - assert_next " " - assert_end - end - - def test_tag_simple_open - tokenize "<tag>" - assert_next "<tag>" - assert_end - end - - def test_tag_simple_self_closing - tokenize "<tag />" - assert_next "<tag />" - assert_end - end - - def test_tag_simple_closing - tokenize "</tag>" - assert_next "</tag>" - end - - def test_tag_with_single_quoted_attribute - tokenize %{<tag a='hello'>x} - assert_next %{<tag a='hello'>} - end - - def test_tag_with_single_quoted_attribute_with_escape - tokenize %{<tag a='hello\\''>x} - assert_next %{<tag a='hello\\''>} - end - - def test_tag_with_double_quoted_attribute - tokenize %{<tag a="hello">x} - assert_next %{<tag a="hello">} - end - - def test_tag_with_double_quoted_attribute_with_escape - tokenize %{<tag a="hello\\"">x} - assert_next %{<tag a="hello\\"">} - end - - def test_tag_with_unquoted_attribute - tokenize %{<tag a=hello>x} - assert_next %{<tag a=hello>} - end - - def test_tag_with_lt_char_in_attribute - tokenize %{<tag a="x < y">x} - assert_next %{<tag a="x < y">} - end - - def test_tag_with_gt_char_in_attribute - tokenize %{<tag a="x > y">x} - assert_next %{<tag a="x > y">} - end - - def test_doctype_tag - tokenize %{<!DOCTYPE "blah" "blah" "blah">\n <html>} - assert_next %{<!DOCTYPE "blah" "blah" "blah">} - assert_next %{\n } - assert_next %{<html>} - end - - def test_cdata_tag - tokenize %{<![CDATA[<br>]]>} - assert_next %{<![CDATA[<br>]]>} - assert_end - end - - def test_unterminated_cdata_tag - tokenize %{<content:encoded><![CDATA[ neverending...} - assert_next %{<content:encoded>} - assert_next %{<![CDATA[ neverending...} - assert_end - end - - def test_less_than_with_space - tokenize %{original < hello > world} - assert_next %{original } - assert_next %{< hello > world} - end - - def test_less_than_without_matching_greater_than - tokenize %{hello <span onmouseover="gotcha"\n<b>foo</b>\nbar</span>} - assert_next %{hello } - assert_next %{<span onmouseover="gotcha"\n} - assert_next %{<b>} - assert_next %{foo} - assert_next %{</b>} - assert_next %{\nbar} - assert_next %{</span>} - assert_end - end - - def test_unterminated_comment - tokenize %{hello <!-- neverending...} - assert_next %{hello } - assert_next %{<!-- neverending...} - assert_end - end - - private - - def tokenize(text) - @tokenizer = HTML::Tokenizer.new(text) - end - - def assert_next(expected, message=nil) - token = @tokenizer.next - assert_equal expected, token, message - end - - def assert_sequence(*expected) - assert_next expected.shift until expected.empty? - end - - def assert_end(message=nil) - assert_nil @tokenizer.next, message - end -end diff --git a/actionpack/test/html-scanner/cdata_node_test.rb b/actionpack/test/html-scanner/cdata_node_test.rb new file mode 100644 index 0000000000..1822cc565a --- /dev/null +++ b/actionpack/test/html-scanner/cdata_node_test.rb @@ -0,0 +1,15 @@ +require 'abstract_unit' + +class CDATANodeTest < Test::Unit::TestCase + def setup + @node = HTML::CDATA.new(nil, 0, 0, "<p>howdy</p>") + end + + def test_to_s + assert_equal "<![CDATA[<p>howdy</p>]]>", @node.to_s + end + + def test_content + assert_equal "<p>howdy</p>", @node.content + end +end diff --git a/actionpack/test/html-scanner/document_test.rb b/actionpack/test/html-scanner/document_test.rb new file mode 100644 index 0000000000..c68f04fa75 --- /dev/null +++ b/actionpack/test/html-scanner/document_test.rb @@ -0,0 +1,148 @@ +require 'abstract_unit' + +class DocumentTest < Test::Unit::TestCase + def test_handle_doctype + doc = nil + assert_nothing_raised do + doc = HTML::Document.new <<-HTML.strip + <!DOCTYPE "blah" "blah" "blah"> + <html> + </html> + HTML + end + assert_equal 3, doc.root.children.length + assert_equal %{<!DOCTYPE "blah" "blah" "blah">}, doc.root.children[0].content + assert_match %r{\s+}m, doc.root.children[1].content + assert_equal "html", doc.root.children[2].name + end + + def test_find_img + doc = HTML::Document.new <<-HTML.strip + <html> + <body> + <p><img src="hello.gif"></p> + </body> + </html> + HTML + assert doc.find(:tag=>"img", :attributes=>{"src"=>"hello.gif"}) + end + + def test_find_all + doc = HTML::Document.new <<-HTML.strip + <html> + <body> + <p class="test"><img src="hello.gif"></p> + <div class="foo"> + <p class="test">something</p> + <p>here is <em class="test">more</em></p> + </div> + </body> + </html> + HTML + all = doc.find_all :attributes => { :class => "test" } + assert_equal 3, all.length + assert_equal [ "p", "p", "em" ], all.map { |n| n.name } + end + + def test_find_with_text + doc = HTML::Document.new <<-HTML.strip + <html> + <body> + <p>Some text</p> + </body> + </html> + HTML + assert doc.find(:content => "Some text") + assert doc.find(:tag => "p", :child => { :content => "Some text" }) + assert doc.find(:tag => "p", :child => "Some text") + assert doc.find(:tag => "p", :content => "Some text") + end + + def test_parse_xml + assert_nothing_raised { HTML::Document.new("<tags><tag/></tags>", true, true) } + assert_nothing_raised { HTML::Document.new("<outer><link>something</link></outer>", true, true) } + end + + def test_parse_document + doc = HTML::Document.new(<<-HTML) + <div> + <h2>blah</h2> + <table> + </table> + </div> + HTML + assert_not_nil doc.find(:tag => "div", :children => { :count => 1, :only => { :tag => "table" } }) + end + + def test_tag_nesting_nothing_to_s + doc = HTML::Document.new("<tag></tag>") + assert_equal "<tag></tag>", doc.root.to_s + end + + def test_tag_nesting_space_to_s + doc = HTML::Document.new("<tag> </tag>") + assert_equal "<tag> </tag>", doc.root.to_s + end + + def test_tag_nesting_text_to_s + doc = HTML::Document.new("<tag>text</tag>") + assert_equal "<tag>text</tag>", doc.root.to_s + end + + def test_tag_nesting_tag_to_s + doc = HTML::Document.new("<tag><nested /></tag>") + assert_equal "<tag><nested /></tag>", doc.root.to_s + end + + def test_parse_cdata + doc = HTML::Document.new(<<-HTML) +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + <head> + <title><![CDATA[<br>]]></title> + </head> + <body> + <p>this document has &lt;br&gt; for a title</p> + </body> +</html> +HTML + + assert_nil doc.find(:tag => "title", :descendant => { :tag => "br" }) + assert doc.find(:tag => "title", :child => "<br>") + end + + def test_find_empty_tag + doc = HTML::Document.new("<div id='map'></div>") + assert_nil doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /./) + assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /\A\Z/) + assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /^$/) + assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => "") + assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => nil) + end + + def test_parse_invalid_document + assert_nothing_raised do + doc = HTML::Document.new("<html> + <table> + <tr> + <td style=\"color: #FFFFFF; height: 17px; onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" style=\"cursor:pointer; height: 17px;\"; nowrap onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" onmouseout=\"this.bgColor='#0066cc'; this.style.color='#FFFFFF'\" onmouseover=\"this.bgColor='#ffffff'; this.style.color='#0033cc'\">About Us</td> + </tr> + </table> + </html>") + end + end + + def test_invalid_document_raises_exception_when_strict + assert_raise RuntimeError do + doc = HTML::Document.new("<html> + <table> + <tr> + <td style=\"color: #FFFFFF; height: 17px; onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" style=\"cursor:pointer; height: 17px;\"; nowrap onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" onmouseout=\"this.bgColor='#0066cc'; this.style.color='#FFFFFF'\" onmouseover=\"this.bgColor='#ffffff'; this.style.color='#0033cc'\">About Us</td> + </tr> + </table> + </html>", true) + end + end + +end diff --git a/actionpack/test/html-scanner/node_test.rb b/actionpack/test/html-scanner/node_test.rb new file mode 100644 index 0000000000..b0df36877e --- /dev/null +++ b/actionpack/test/html-scanner/node_test.rb @@ -0,0 +1,89 @@ +require 'abstract_unit' + +class NodeTest < Test::Unit::TestCase + + class MockNode + def initialize(matched, value) + @matched = matched + @value = value + end + + def find(conditions) + @matched && self + end + + def to_s + @value.to_s + end + end + + def setup + @node = HTML::Node.new("parent") + @node.children.concat [MockNode.new(false,1), MockNode.new(true,"two"), MockNode.new(false,:three)] + end + + def test_match + assert !@node.match("foo") + end + + def test_tag + assert !@node.tag? + end + + def test_to_s + assert_equal "1twothree", @node.to_s + end + + def test_find + assert_equal "two", @node.find('blah').to_s + end + + def test_parse_strict + s = "<b foo='hello'' bar='baz'>" + assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) } + end + + def test_parse_relaxed + s = "<b foo='hello'' bar='baz'>" + node = nil + assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) } + assert node.attributes.has_key?("foo") + assert !node.attributes.has_key?("bar") + end + + def test_to_s_with_boolean_attrs + s = "<b foo bar>" + node = HTML::Node.parse(nil,0,0,s) + assert node.attributes.has_key?("foo") + assert node.attributes.has_key?("bar") + assert "<b foo bar>", node.to_s + end + + def test_parse_with_unclosed_tag + s = "<span onmouseover='bang'" + node = nil + assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) } + assert node.attributes.has_key?("onmouseover") + end + + def test_parse_with_valid_cdata_section + s = "<![CDATA[<span>contents</span>]]>" + node = nil + assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) } + assert_kind_of HTML::CDATA, node + assert_equal '<span>contents</span>', node.content + end + + def test_parse_strict_with_unterminated_cdata_section + s = "<![CDATA[neverending..." + assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) } + end + + def test_parse_relaxed_with_unterminated_cdata_section + s = "<![CDATA[neverending..." + node = nil + assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) } + assert_kind_of HTML::CDATA, node + assert_equal 'neverending...', node.content + end +end diff --git a/actionpack/test/html-scanner/sanitizer_test.rb b/actionpack/test/html-scanner/sanitizer_test.rb new file mode 100644 index 0000000000..e85a5c7abf --- /dev/null +++ b/actionpack/test/html-scanner/sanitizer_test.rb @@ -0,0 +1,273 @@ +require 'abstract_unit' + +class SanitizerTest < ActionController::TestCase + def setup + @sanitizer = nil # used by assert_sanitizer + end + + def test_strip_tags + sanitizer = HTML::FullSanitizer.new + assert_equal("<<<bad html", sanitizer.sanitize("<<<bad html")) + assert_equal("<<", sanitizer.sanitize("<<<bad html>")) + assert_equal("Dont touch me", sanitizer.sanitize("Dont touch me")) + assert_equal("This is a test.", sanitizer.sanitize("<p>This <u>is<u> a <a href='test.html'><strong>test</strong></a>.</p>")) + assert_equal("Weirdos", sanitizer.sanitize("Wei<<a>a onclick='alert(document.cookie);'</a>/>rdos")) + assert_equal("This is a test.", sanitizer.sanitize("This is a test.")) + assert_equal( + %{This is a test.\n\n\nIt no longer contains any HTML.\n}, sanitizer.sanitize( + %{<title>This is <b>a <a href="" target="_blank">test</a></b>.</title>\n\n<!-- it has a comment -->\n\n<p>It no <b>longer <strong>contains <em>any <strike>HTML</strike></em>.</strong></b></p>\n})) + assert_equal "This has a here.", sanitizer.sanitize("This has a <!-- comment --> here.") + assert_equal "This has a here.", sanitizer.sanitize("This has a <![CDATA[<section>]]> here.") + assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed <![CDATA[<section>]] here...") + [nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) } + end + + def test_strip_links + sanitizer = HTML::LinkSanitizer.new + assert_equal "Dont touch me", sanitizer.sanitize("Dont touch me") + assert_equal "on my mind\nall day long", sanitizer.sanitize("<a href='almost'>on my mind</a>\n<A href='almost'>all day long</A>") + assert_equal "0wn3d", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'><a href='http://www.rubyonrails.com/' onlclick='steal()'>0wn3d</a></a>") + assert_equal "Magic", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'>Mag<a href='http://www.ruby-lang.org/'>ic") + assert_equal "FrrFox", sanitizer.sanitize("<href onlclick='steal()'>FrrFox</a></href>") + assert_equal "My mind\nall <b>day</b> long", sanitizer.sanitize("<a href='almost'>My mind</a>\n<A href='almost'>all <b>day</b> long</A>") + assert_equal "all <b>day</b> long", sanitizer.sanitize("<<a>a href='hello'>all <b>day</b> long<</A>/a>") + + assert_equal "<a<a", sanitizer.sanitize("<a<a") + end + + def test_sanitize_form + assert_sanitized "<form action=\"/foo/bar\" method=\"post\"><input></form>", '' + end + + def test_sanitize_plaintext + raw = "<plaintext><span>foo</span></plaintext>" + assert_sanitized raw, "<span>foo</span>" + end + + def test_sanitize_script + assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cd e f" + end + + # fucked + def test_sanitize_js_handlers + raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>} + assert_sanitized raw, %{onthis="do that" <a name="foo" href="#">hello</a>} + end + + def test_sanitize_javascript_href + raw = %{href="javascript:bang" <a href="javascript:bang" name="hello">foo</a>, <span href="javascript:bang">bar</span>} + assert_sanitized raw, %{href="javascript:bang" <a name="hello">foo</a>, <span>bar</span>} + end + + def test_sanitize_image_src + raw = %{src="javascript:bang" <img src="javascript:bang" width="5">foo</img>, <span src="javascript:bang">bar</span>} + assert_sanitized raw, %{src="javascript:bang" <img width="5">foo</img>, <span>bar</span>} + end + + HTML::WhiteListSanitizer.allowed_tags.each do |tag_name| + define_method "test_should_allow_#{tag_name}_tag" do + assert_sanitized "start <#{tag_name} title=\"1\" onclick=\"foo\">foo <bad>bar</bad> baz</#{tag_name}> end", %(start <#{tag_name} title="1">foo bar baz</#{tag_name}> end) + end + end + + def test_should_allow_anchors + assert_sanitized %(<a href="foo" onclick="bar"><script>baz</script></a>), %(<a href="foo"></a>) + end + + # RFC 3986, sec 4.2 + def test_allow_colons_in_path_component + assert_sanitized("<a href=\"./this:that\">foo</a>") + end + + %w(src width height alt).each do |img_attr| + define_method "test_should_allow_image_#{img_attr}_attribute" do + assert_sanitized %(<img #{img_attr}="foo" onclick="bar" />), %(<img #{img_attr}="foo" />) + end + end + + def test_should_handle_non_html + assert_sanitized 'abc' + end + + def test_should_handle_blank_text + assert_sanitized nil + assert_sanitized '' + end + + def test_should_allow_custom_tags + text = "<u>foo</u>" + sanitizer = HTML::WhiteListSanitizer.new + assert_equal(text, sanitizer.sanitize(text, :tags => %w(u))) + end + + def test_should_allow_only_custom_tags + text = "<u>foo</u> with <i>bar</i>" + sanitizer = HTML::WhiteListSanitizer.new + assert_equal("<u>foo</u> with bar", sanitizer.sanitize(text, :tags => %w(u))) + end + + def test_should_allow_custom_tags_with_attributes + text = %(<blockquote cite="http://example.com/">foo</blockquote>) + sanitizer = HTML::WhiteListSanitizer.new + assert_equal(text, sanitizer.sanitize(text)) + end + + def test_should_allow_custom_tags_with_custom_attributes + text = %(<blockquote foo="bar">Lorem ipsum</blockquote>) + sanitizer = HTML::WhiteListSanitizer.new + assert_equal(text, sanitizer.sanitize(text, :attributes => ['foo'])) + end + + [%w(img src), %w(a href)].each do |(tag, attr)| + define_method "test_should_strip_#{attr}_attribute_in_#{tag}_with_bad_protocols" do + assert_sanitized %(<#{tag} #{attr}="javascript:bang" title="1">boo</#{tag}>), %(<#{tag} title="1">boo</#{tag}>) + end + end + + def test_should_flag_bad_protocols + sanitizer = HTML::WhiteListSanitizer.new + %w(about chrome data disk hcp help javascript livescript lynxcgi lynxexec ms-help ms-its mhtml mocha opera res resource shell vbscript view-source vnd.ms.radio wysiwyg).each do |proto| + assert sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://bad") + end + end + + def test_should_accept_good_protocols + sanitizer = HTML::WhiteListSanitizer.new + HTML::WhiteListSanitizer.allowed_protocols.each do |proto| + assert !sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://good") + end + end + + def test_should_reject_hex_codes_in_protocol + assert_sanitized %(<a href="&#37;6A&#37;61&#37;76&#37;61&#37;73&#37;63&#37;72&#37;69&#37;70&#37;74&#37;3A&#37;61&#37;6C&#37;65&#37;72&#37;74&#37;28&#37;22&#37;58&#37;53&#37;53&#37;22&#37;29">1</a>), "<a>1</a>" + assert @sanitizer.send(:contains_bad_protocols?, 'src', "%6A%61%76%61%73%63%72%69%70%74%3A%61%6C%65%72%74%28%22%58%53%53%22%29") + end + + def test_should_block_script_tag + assert_sanitized %(<SCRIPT\nSRC=http://ha.ckers.org/xss.js></SCRIPT>), "" + end + + [%(<IMG SRC="javascript:alert('XSS');">), + %(<IMG SRC=javascript:alert('XSS')>), + %(<IMG SRC=JaVaScRiPt:alert('XSS')>), + %(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">), + %(<IMG SRC=javascript:alert(&quot;XSS&quot;)>), + %(<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>), + %(<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>), + %(<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>), + %(<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>), + %(<IMG SRC="jav\tascript:alert('XSS');">), + %(<IMG SRC="jav&#x09;ascript:alert('XSS');">), + %(<IMG SRC="jav&#x0A;ascript:alert('XSS');">), + %(<IMG SRC="jav&#x0D;ascript:alert('XSS');">), + %(<IMG SRC=" &#14; javascript:alert('XSS');">), + %(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each_with_index do |img_hack, i| + define_method "test_should_not_fall_for_xss_image_hack_#{i+1}" do + assert_sanitized img_hack, "<img>" + end + end + + def test_should_sanitize_tag_broken_up_by_null + assert_sanitized %(<SCR\0IPT>alert(\"XSS\")</SCR\0IPT>), "alert(\"XSS\")" + end + + def test_should_sanitize_invalid_script_tag + assert_sanitized %(<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>), "" + end + + def test_should_sanitize_script_tag_with_multiple_open_brackets + assert_sanitized %(<<SCRIPT>alert("XSS");//<</SCRIPT>), "&lt;" + assert_sanitized %(<iframe src=http://ha.ckers.org/scriptlet.html\n<a), %(&lt;a) + end + + def test_should_sanitize_unclosed_script + assert_sanitized %(<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>), "<b>" + end + + def test_should_sanitize_half_open_scripts + assert_sanitized %(<IMG SRC="javascript:alert('XSS')"), "<img>" + end + + def test_should_not_fall_for_ridiculous_hack + img_hack = %(<IMG\nSRC\n=\n"\nj\na\nv\na\ns\nc\nr\ni\np\nt\n:\na\nl\ne\nr\nt\n(\n'\nX\nS\nS\n'\n)\n"\n>) + assert_sanitized img_hack, "<img>" + end + + # fucked + def test_should_sanitize_attributes + assert_sanitized %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="'&gt;&lt;script&gt;alert()&lt;/script&gt;">blah</span>) + end + + def test_should_sanitize_illegal_style_properties + raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;) + expected = %(display: block; width: 100%; height: 100%; background-color: black; background-image: ; background-x: center; background-y: center;) + assert_equal expected, sanitize_css(raw) + end + + def test_should_sanitize_with_trailing_space + raw = "display:block; " + expected = "display: block;" + assert_equal expected, sanitize_css(raw) + end + + def test_should_sanitize_xul_style_attributes + raw = %(-moz-binding:url('http://ha.ckers.org/xssmoz.xml#xss')) + assert_equal '', sanitize_css(raw) + end + + def test_should_sanitize_invalid_tag_names + assert_sanitized(%(a b c<script/XSS src="http://ha.ckers.org/xss.js"></script>d e f), "a b cd e f") + end + + def test_should_sanitize_non_alpha_and_non_digit_characters_in_tags + assert_sanitized('<a onclick!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>foo</a>', "<a>foo</a>") + end + + def test_should_sanitize_invalid_tag_names_in_single_tags + assert_sanitized('<img/src="http://ha.ckers.org/xss.js"/>', "<img />") + end + + def test_should_sanitize_img_dynsrc_lowsrc + assert_sanitized(%(<img lowsrc="javascript:alert('XSS')" />), "<img />") + end + + def test_should_sanitize_div_background_image_unicode_encoded + raw = %(background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029) + assert_equal '', sanitize_css(raw) + end + + def test_should_sanitize_div_style_expression + raw = %(width: expression(alert('XSS'));) + assert_equal '', sanitize_css(raw) + end + + def test_should_sanitize_img_vbscript + assert_sanitized %(<img src='vbscript:msgbox("XSS")' />), '<img />' + end + + def test_should_sanitize_cdata_section + assert_sanitized "<![CDATA[<span>section</span>]]>", "&lt;![CDATA[&lt;span>section&lt;/span>]]>" + end + + def test_should_sanitize_unterminated_cdata_section + assert_sanitized "<![CDATA[<span>neverending...", "&lt;![CDATA[&lt;span>neverending...]]>" + end + + def test_should_not_mangle_urls_with_ampersand + assert_sanitized %{<a href=\"http://www.domain.com?var1=1&amp;var2=2\">my link</a>} + end + +protected + def assert_sanitized(input, expected = nil) + @sanitizer ||= HTML::WhiteListSanitizer.new + if input + assert_dom_equal expected || input, @sanitizer.sanitize(input) + else + assert_nil @sanitizer.sanitize(input) + end + end + + def sanitize_css(input) + (@sanitizer ||= HTML::WhiteListSanitizer.new).sanitize_css(input) + end +end diff --git a/actionpack/test/html-scanner/tag_node_test.rb b/actionpack/test/html-scanner/tag_node_test.rb new file mode 100644 index 0000000000..d1d4667378 --- /dev/null +++ b/actionpack/test/html-scanner/tag_node_test.rb @@ -0,0 +1,238 @@ +require 'abstract_unit' + +class TagNodeTest < Test::Unit::TestCase + def test_open_without_attributes + node = tag("<tag>") + assert_equal "tag", node.name + assert_equal Hash.new, node.attributes + assert_nil node.closing + end + + def test_open_with_attributes + node = tag("<TAG1 foo=hey_ho x:bar=\"blah blah\" BAZ='blah blah blah' >") + assert_equal "tag1", node.name + assert_equal "hey_ho", node["foo"] + assert_equal "blah blah", node["x:bar"] + assert_equal "blah blah blah", node["baz"] + end + + def test_self_closing_without_attributes + node = tag("<tag/>") + assert_equal "tag", node.name + assert_equal Hash.new, node.attributes + assert_equal :self, node.closing + end + + def test_self_closing_with_attributes + node = tag("<tag a=b/>") + assert_equal "tag", node.name + assert_equal( { "a" => "b" }, node.attributes ) + assert_equal :self, node.closing + end + + def test_closing_without_attributes + node = tag("</tag>") + assert_equal "tag", node.name + assert_nil node.attributes + assert_equal :close, node.closing + end + + def test_bracket_op_when_no_attributes + node = tag("</tag>") + assert_nil node["foo"] + end + + def test_bracket_op_when_attributes + node = tag("<tag a=b/>") + assert_equal "b", node["a"] + end + + def test_attributes_with_escaped_quotes + node = tag("<tag a='b\\'c' b=\"bob \\\"float\\\"\">") + assert_equal "b\\'c", node["a"] + assert_equal "bob \\\"float\\\"", node["b"] + end + + def test_to_s + node = tag("<a b=c d='f' g=\"h 'i'\" />") + assert_equal %(<a b='c' d='f' g='h \\'i\\'' />), node.to_s + end + + def test_tag + assert tag("<tag>").tag? + end + + def test_match_tag_as_string + assert tag("<tag>").match(:tag => "tag") + assert !tag("<tag>").match(:tag => "b") + end + + def test_match_tag_as_regexp + assert tag("<tag>").match(:tag => /t.g/) + assert !tag("<tag>").match(:tag => /t[bqs]g/) + end + + def test_match_attributes_as_string + t = tag("<tag a=something b=else />") + assert t.match(:attributes => {"a" => "something"}) + assert t.match(:attributes => {"b" => "else"}) + end + + def test_match_attributes_as_regexp + t = tag("<tag a=something b=else />") + assert t.match(:attributes => {"a" => /^something$/}) + assert t.match(:attributes => {"b" => /e.*e/}) + assert t.match(:attributes => {"a" => /me..i/, "b" => /.ls.$/}) + end + + def test_match_attributes_as_number + t = tag("<tag a=15 b=3.1415 />") + assert t.match(:attributes => {"a" => 15}) + assert t.match(:attributes => {"b" => 3.1415}) + assert t.match(:attributes => {"a" => 15, "b" => 3.1415}) + end + + def test_match_attributes_exist + t = tag("<tag a=15 b=3.1415 />") + assert t.match(:attributes => {"a" => true}) + assert t.match(:attributes => {"b" => true}) + assert t.match(:attributes => {"a" => true, "b" => true}) + end + + def test_match_attributes_not_exist + t = tag("<tag a=15 b=3.1415 />") + assert t.match(:attributes => {"c" => false}) + assert t.match(:attributes => {"c" => nil}) + assert t.match(:attributes => {"a" => true, "c" => false}) + end + + def test_match_parent_success + t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>")) + assert t.match(:parent => {:tag => "foo", :attributes => {"k" => /v.l/, "j" => false}}) + end + + def test_match_parent_fail + t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>")) + assert !t.match(:parent => {:tag => /kafka/}) + end + + def test_match_child_success + t = tag("<tag x:k='something'>") + tag("<child v=john a=kelly>", t) + tag("<sib m=vaughn v=james>", t) + assert t.match(:child => { :tag => "sib", :attributes => {"v" => /j/}}) + assert t.match(:child => { :attributes => {"a" => "kelly"}}) + end + + def test_match_child_fail + t = tag("<tag x:k='something'>") + tag("<child v=john a=kelly>", t) + tag("<sib m=vaughn v=james>", t) + assert !t.match(:child => { :tag => "sib", :attributes => {"v" => /r/}}) + assert !t.match(:child => { :attributes => {"v" => false}}) + end + + def test_match_ancestor_success + t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>"))) + assert t.match(:ancestor => {:tag => "parent", :attributes => {"a" => /ll/}}) + assert t.match(:ancestor => {:attributes => {"m" => "vaughn"}}) + end + + def test_match_ancestor_fail + t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>"))) + assert !t.match(:ancestor => {:tag => /^parent/, :attributes => {"v" => /m/}}) + assert !t.match(:ancestor => {:attributes => {"v" => false}}) + end + + def test_match_descendant_success + tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>"))) + assert t.match(:descendant => {:tag => "child", :attributes => {"a" => /ll/}}) + assert t.match(:descendant => {:attributes => {"m" => "vaughn"}}) + end + + def test_match_descendant_fail + tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>"))) + assert !t.match(:descendant => {:tag => /^child/, :attributes => {"v" => /m/}}) + assert !t.match(:descendant => {:attributes => {"v" => false}}) + end + + def test_match_child_count + t = tag("<tag x:k='something'>") + tag("hello", t) + tag("<child v=john a=kelly>", t) + tag("<sib m=vaughn v=james>", t) + assert t.match(:children => { :count => 2 }) + assert t.match(:children => { :count => 2..4 }) + assert t.match(:children => { :less_than => 4 }) + assert t.match(:children => { :greater_than => 1 }) + assert !t.match(:children => { :count => 3 }) + end + + def test_conditions_as_strings + t = tag("<tag x:k='something'>") + assert t.match("tag" => "tag") + assert t.match("attributes" => { "x:k" => "something" }) + assert !t.match("tag" => "gat") + assert !t.match("attributes" => { "x:j" => "something" }) + end + + def test_attributes_as_symbols + t = tag("<child v=john a=kelly>") + assert t.match(:attributes => { :v => /oh/ }) + assert t.match(:attributes => { :a => /ll/ }) + end + + def test_match_sibling + t = tag("<tag x:k='something'>") + tag("hello", t) + tag("<span a=b>", t) + tag("world", t) + m = tag("<span k=r>", t) + tag("<span m=l>", t) + + assert m.match(:sibling => {:tag => "span", :attributes => {:a => true}}) + assert m.match(:sibling => {:tag => "span", :attributes => {:m => true}}) + assert !m.match(:sibling => {:tag => "span", :attributes => {:k => true}}) + end + + def test_match_sibling_before + t = tag("<tag x:k='something'>") + tag("hello", t) + tag("<span a=b>", t) + tag("world", t) + m = tag("<span k=r>", t) + tag("<span m=l>", t) + + assert m.match(:before => {:tag => "span", :attributes => {:m => true}}) + assert !m.match(:before => {:tag => "span", :attributes => {:a => true}}) + assert !m.match(:before => {:tag => "span", :attributes => {:k => true}}) + end + + def test_match_sibling_after + t = tag("<tag x:k='something'>") + tag("hello", t) + tag("<span a=b>", t) + tag("world", t) + m = tag("<span k=r>", t) + tag("<span m=l>", t) + + assert m.match(:after => {:tag => "span", :attributes => {:a => true}}) + assert !m.match(:after => {:tag => "span", :attributes => {:m => true}}) + assert !m.match(:after => {:tag => "span", :attributes => {:k => true}}) + end + + def test_to_s + t = tag("<b x='foo'>") + tag("hello", t) + tag("<hr />", t) + assert_equal %(<b x="foo">hello<hr /></b>), t.to_s + end + + private + + def tag(content, parent=nil) + node = HTML::Node.parse(parent,0,0,content) + parent.children << node if parent + node + end +end diff --git a/actionpack/test/html-scanner/text_node_test.rb b/actionpack/test/html-scanner/text_node_test.rb new file mode 100644 index 0000000000..1ab3f4454e --- /dev/null +++ b/actionpack/test/html-scanner/text_node_test.rb @@ -0,0 +1,50 @@ +require 'abstract_unit' + +class TextNodeTest < Test::Unit::TestCase + def setup + @node = HTML::Text.new(nil, 0, 0, "hello, howdy, aloha, annyeong") + end + + def test_to_s + assert_equal "hello, howdy, aloha, annyeong", @node.to_s + end + + def test_find_string + assert_equal @node, @node.find("hello, howdy, aloha, annyeong") + assert_equal false, @node.find("bogus") + end + + def test_find_regexp + assert_equal @node, @node.find(/an+y/) + assert_nil @node.find(/b/) + end + + def test_find_hash + assert_equal @node, @node.find(:content => /howdy/) + assert_nil @node.find(:content => /^howdy$/) + assert_equal false, @node.find(:content => "howdy") + end + + def test_find_other + assert_nil @node.find(:hello) + end + + def test_match_string + assert @node.match("hello, howdy, aloha, annyeong") + assert_equal false, @node.match("bogus") + end + + def test_match_regexp + assert_not_nil @node, @node.match(/an+y/) + assert_nil @node.match(/b/) + end + + def test_match_hash + assert_not_nil @node, @node.match(:content => "howdy") + assert_nil @node.match(:content => /^howdy$/) + end + + def test_match_other + assert_nil @node.match(:hello) + end +end diff --git a/actionpack/test/html-scanner/tokenizer_test.rb b/actionpack/test/html-scanner/tokenizer_test.rb new file mode 100644 index 0000000000..a001bcbbad --- /dev/null +++ b/actionpack/test/html-scanner/tokenizer_test.rb @@ -0,0 +1,131 @@ +require 'abstract_unit' + +class TokenizerTest < Test::Unit::TestCase + + def test_blank + tokenize "" + assert_end + end + + def test_space + tokenize " " + assert_next " " + assert_end + end + + def test_tag_simple_open + tokenize "<tag>" + assert_next "<tag>" + assert_end + end + + def test_tag_simple_self_closing + tokenize "<tag />" + assert_next "<tag />" + assert_end + end + + def test_tag_simple_closing + tokenize "</tag>" + assert_next "</tag>" + end + + def test_tag_with_single_quoted_attribute + tokenize %{<tag a='hello'>x} + assert_next %{<tag a='hello'>} + end + + def test_tag_with_single_quoted_attribute_with_escape + tokenize %{<tag a='hello\\''>x} + assert_next %{<tag a='hello\\''>} + end + + def test_tag_with_double_quoted_attribute + tokenize %{<tag a="hello">x} + assert_next %{<tag a="hello">} + end + + def test_tag_with_double_quoted_attribute_with_escape + tokenize %{<tag a="hello\\"">x} + assert_next %{<tag a="hello\\"">} + end + + def test_tag_with_unquoted_attribute + tokenize %{<tag a=hello>x} + assert_next %{<tag a=hello>} + end + + def test_tag_with_lt_char_in_attribute + tokenize %{<tag a="x < y">x} + assert_next %{<tag a="x < y">} + end + + def test_tag_with_gt_char_in_attribute + tokenize %{<tag a="x > y">x} + assert_next %{<tag a="x > y">} + end + + def test_doctype_tag + tokenize %{<!DOCTYPE "blah" "blah" "blah">\n <html>} + assert_next %{<!DOCTYPE "blah" "blah" "blah">} + assert_next %{\n } + assert_next %{<html>} + end + + def test_cdata_tag + tokenize %{<![CDATA[<br>]]>} + assert_next %{<![CDATA[<br>]]>} + assert_end + end + + def test_unterminated_cdata_tag + tokenize %{<content:encoded><![CDATA[ neverending...} + assert_next %{<content:encoded>} + assert_next %{<![CDATA[ neverending...} + assert_end + end + + def test_less_than_with_space + tokenize %{original < hello > world} + assert_next %{original } + assert_next %{< hello > world} + end + + def test_less_than_without_matching_greater_than + tokenize %{hello <span onmouseover="gotcha"\n<b>foo</b>\nbar</span>} + assert_next %{hello } + assert_next %{<span onmouseover="gotcha"\n} + assert_next %{<b>} + assert_next %{foo} + assert_next %{</b>} + assert_next %{\nbar} + assert_next %{</span>} + assert_end + end + + def test_unterminated_comment + tokenize %{hello <!-- neverending...} + assert_next %{hello } + assert_next %{<!-- neverending...} + assert_end + end + + private + + def tokenize(text) + @tokenizer = HTML::Tokenizer.new(text) + end + + def assert_next(expected, message=nil) + token = @tokenizer.next + assert_equal expected, token, message + end + + def assert_sequence(*expected) + assert_next expected.shift until expected.empty? + end + + def assert_end(message=nil) + assert_nil @tokenizer.next, message + end +end -- cgit v1.2.3 From fb64263c9181f247207919f1187934e29c4fe83c Mon Sep 17 00:00:00 2001 From: Jeremy Kemper <jeremy@bitsweat.net> Date: Fri, 22 May 2009 17:22:30 -0700 Subject: Restore some missing test constants --- actionpack/test/new_base/abstract_unit.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb index 5df2576916..e6690d41d9 100644 --- a/actionpack/test/new_base/abstract_unit.rb +++ b/actionpack/test/new_base/abstract_unit.rb @@ -35,6 +35,14 @@ end ActiveSupport::Dependencies.hook! +# Show backtraces for deprecated behavior for quicker cleanup. +ActiveSupport::Deprecation.debug = true + +# Register danish language for testing +I18n.backend.store_translations 'da', {} +I18n.backend.store_translations 'pt-BR', {} +ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort + FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), '../fixtures') module ActionController -- cgit v1.2.3 From 5097bd624110e190fee8033542db5d993a27696b Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche <ykatz+clerche@engineyard.com> Date: Fri, 22 May 2009 17:25:55 -0700 Subject: Modify render_test's determine_layout to match RJS --- actionpack/test/controller/render_test.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index a750f018b8..9e42d1738a 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -625,9 +625,7 @@ class TestController < ActionController::Base "accessing_params_in_template_with_layout", "render_with_explicit_template", "render_with_explicit_string_template", - "render_js_with_explicit_template", - "render_js_with_explicit_action_template", - "delete_with_js", "update_page", "update_page_with_instance_variables" + "update_page", "update_page_with_instance_variables" "layouts/standard" when "action_talk_to_layout", "layout_overriding_layout" -- cgit v1.2.3 From 9286d422f8aff0aff8529edc93966fcab987c1af Mon Sep 17 00:00:00 2001 From: Pratik Naik <pratiknaik@gmail.com> Date: Sat, 23 May 2009 02:29:44 +0200 Subject: Add asset_host to Rails2Compatibility --- actionpack/lib/action_controller/new_base/compatibility.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index 250e7f0dff..2bc76338b9 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -56,6 +56,12 @@ module ActionController cattr_accessor :consider_all_requests_local self.consider_all_requests_local = true + + # Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets, + # and images to a dedicated asset server away from the main web server. Example: + # ActionController::Base.asset_host = "http://assets.example.com" + @@asset_host = "" + cattr_accessor :asset_host end # For old tests -- cgit v1.2.3 From 3ac6d8f8b01fb04b8d6d35d75d802b41f4c256c9 Mon Sep 17 00:00:00 2001 From: Pratik Naik <pratiknaik@gmail.com> Date: Sat, 23 May 2009 02:35:34 +0200 Subject: Remove unnecessary asset_host initialization --- actionpack/lib/action_controller/base/base.rb | 1 - actionpack/lib/action_controller/new_base/compatibility.rb | 1 - 2 files changed, 2 deletions(-) diff --git a/actionpack/lib/action_controller/base/base.rb b/actionpack/lib/action_controller/base/base.rb index 2586037965..67369eb122 100644 --- a/actionpack/lib/action_controller/base/base.rb +++ b/actionpack/lib/action_controller/base/base.rb @@ -242,7 +242,6 @@ module ActionController #:nodoc: # Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets, # and images to a dedicated asset server away from the main web server. Example: # ActionController::Base.asset_host = "http://assets.example.com" - @@asset_host = "" cattr_accessor :asset_host # All requests are considered local by default, so everyone will be exposed to detailed debugging screens on errors. diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index 2bc76338b9..b3190486e8 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -60,7 +60,6 @@ module ActionController # Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets, # and images to a dedicated asset server away from the main web server. Example: # ActionController::Base.asset_host = "http://assets.example.com" - @@asset_host = "" cattr_accessor :asset_host end -- cgit v1.2.3 From e22a3d893ef8441fb52320315c5e348c6c208b69 Mon Sep 17 00:00:00 2001 From: Yehuda Katz <wycats@yehuda-katzs-macbookpro41.local> Date: Sat, 23 May 2009 00:39:32 -0700 Subject: Slightly modify things to get content type matching working without breaking other code --- actionpack/lib/action_controller/abstract/base.rb | 6 ++-- .../lib/action_controller/abstract/layouts.rb | 16 +++++------ actionpack/lib/action_dispatch/http/request.rb | 10 +++++-- actionpack/test/fixtures/test/greeting.erb | 1 - actionpack/test/fixtures/test/greeting.html.erb | 1 + actionpack/test/new_base/render_layout_test.rb | 32 ++++++++++++++++++++++ actionpack/test/new_base/test_helper.rb | 2 +- 7 files changed, 53 insertions(+), 15 deletions(-) delete mode 100644 actionpack/test/fixtures/test/greeting.erb create mode 100644 actionpack/test/fixtures/test/greeting.html.erb diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb index 1f2f096dae..0e4803388a 100644 --- a/actionpack/lib/action_controller/abstract/base.rb +++ b/actionpack/lib/action_controller/abstract/base.rb @@ -68,11 +68,11 @@ module AbstractController self.response_obj = {} end - def process(action_name) - @_action_name = action_name = action_name.to_s + def process(action) + @_action_name = action_name = action.to_s unless action_name = method_for_action(action_name) - raise ActionNotFound, "The action '#{action_name}' could not be found" + raise ActionNotFound, "The action '#{action}' could not be found" end process_action(action_name) diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 8721e5f4dc..3d6810bda9 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -39,15 +39,15 @@ module AbstractController def _write_layout_method case @_layout when String - self.class_eval %{def _layout() #{@_layout.inspect} end} + self.class_eval %{def _layout(details) #{@_layout.inspect} end} when Symbol - self.class_eval %{def _layout() #{@_layout} end} + self.class_eval %{def _layout(details) #{@_layout} end} when false - self.class_eval %{def _layout() end} + self.class_eval %{def _layout(details) end} else self.class_eval %{ - def _layout - if view_paths.find_by_parts?("#{_implied_layout_name}", {:formats => formats}, "layouts") + def _layout(details) + if view_paths.find_by_parts?("#{_implied_layout_name}", details, "layouts") "#{_implied_layout_name}" else super @@ -60,7 +60,7 @@ module AbstractController private - def _layout() end # This will be overwritten + def _layout(details) end # This will be overwritten # :api: plugin # ==== @@ -79,13 +79,13 @@ module AbstractController end def _default_layout(require_layout = false, details = {:formats => formats}) - if require_layout && _action_has_layout? && !_layout + if require_layout && _action_has_layout? && !_layout(details) raise ArgumentError, "There was no default layout for #{self.class} in #{view_paths.inspect}" end begin - _layout_for_name(_layout, details) if _action_has_layout? + _layout_for_name(_layout(details), details) if _action_has_layout? rescue NameError => e raise NoMethodError, "You specified #{@_layout.inspect} as the layout, but no such method was found" diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 4831b89bde..259164d118 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -173,9 +173,15 @@ module ActionDispatch def formats if ActionController::Base.use_accept_header - Array(Mime[parameters[:format]] || accepts) + ret = Array(Mime[parameters[:format]] || accepts) + if defined?(ActionController::Http) + if all = ret.index(Mime::ALL) + ret.delete(Mime::ALL) && ret.insert(all, *Mime::SET) + end + end + ret else - [format, Mime[:all]] + [format] + Mime::SET end end diff --git a/actionpack/test/fixtures/test/greeting.erb b/actionpack/test/fixtures/test/greeting.erb deleted file mode 100644 index 62fb0293f0..0000000000 --- a/actionpack/test/fixtures/test/greeting.erb +++ /dev/null @@ -1 +0,0 @@ -<p>This is grand!</p> diff --git a/actionpack/test/fixtures/test/greeting.html.erb b/actionpack/test/fixtures/test/greeting.html.erb new file mode 100644 index 0000000000..62fb0293f0 --- /dev/null +++ b/actionpack/test/fixtures/test/greeting.html.erb @@ -0,0 +1 @@ +<p>This is grand!</p> diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/new_base/render_layout_test.rb index 76bd5175a3..f32c60d683 100644 --- a/actionpack/test/new_base/render_layout_test.rb +++ b/actionpack/test/new_base/render_layout_test.rb @@ -66,4 +66,36 @@ module ControllerLayouts assert_response "hai(layout_false.html.erb)" end end + + class MismatchFormatController < ::ApplicationController + self.view_paths = [ActionView::Template::FixturePath.new( + "layouts/application.html.erb" => "<html><%= yield %></html>", + "controller_layouts/mismatch_format/index.js.rjs" => "page[:test].omg", + "controller_layouts/mismatch_format/implicit.rjs" => "page[:test].omg" + )] + + def explicit + render :layout => "application" + end + end + + class MismatchFormatTest < SimpleRouteCase + testing ControllerLayouts::MismatchFormatController + + test "if JS is selected, an HTML template is not also selected" do + get :index + assert_response "$(\"test\").omg();" + end + + test "if JS is implicitly selected, an HTML template is not also selected" do + get :implicit + assert_response "$(\"test\").omg();" + end + + test "if an HTML template is explicitly provides for a JS template, an error is raised" do + assert_raises ActionView::MissingTemplate do + get :explicit, {}, "action_dispatch.show_exceptions" => false + end + end + end end \ No newline at end of file diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index 89c1290063..d92029df7f 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -67,7 +67,7 @@ class Rack::TestCase < ActionController::IntegrationTest def get(thing, *args) if thing.is_a?(Symbol) - super("#{self.class.testing}/#{thing}") + super("#{self.class.testing}/#{thing}", *args) else super end -- cgit v1.2.3 From e0ed4b7aa45cacba12ad5aeba23f71305579b395 Mon Sep 17 00:00:00 2001 From: Yehuda Katz <wycats@yehuda-katzs-macbookpro41.local> Date: Sat, 23 May 2009 01:30:25 -0700 Subject: Make a couple more tests pass. A large number of the remaining failing tests have to do with the semantics of filters that are Objects. The right solution is probably to just implement the filter/before/after semantics in NewCallbacks directly (the current semantics are based on the old AS::Callbacks specs) --- actionpack/lib/action_controller/abstract/callbacks.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/actionpack/lib/action_controller/abstract/callbacks.rb b/actionpack/lib/action_controller/abstract/callbacks.rb index 51b968c694..e4f9dd3112 100644 --- a/actionpack/lib/action_controller/abstract/callbacks.rb +++ b/actionpack/lib/action_controller/abstract/callbacks.rb @@ -36,6 +36,17 @@ module AbstractController process_action_callback(:#{filter}, name, options) end end + + def skip_#{filter}_filter(*names, &blk) + options = names.last.is_a?(Hash) ? names.pop : {} + _normalize_callback_options(options) + names.push(blk) if block_given? + names.each do |name| + skip_process_action_callback(:#{filter}, name, options) + end + end + + alias_method :append_#{filter}_filter, :#{filter}_filter RUBY_EVAL end end -- cgit v1.2.3 From 4e3fd23e311cd1773e62e7971f0f47af05d5000a Mon Sep 17 00:00:00 2001 From: Jeremy Kemper <jeremy@bitsweat.net> Date: Fri, 22 May 2009 17:59:28 -0700 Subject: test depends on html-scanner --- actionpack/test/controller/integration_test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index eae6835714..197ba0c69c 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -1,4 +1,5 @@ require 'abstract_unit' +require 'action_controller/vendor/html-scanner' class SessionTest < Test::Unit::TestCase StubApp = lambda { |env| -- cgit v1.2.3 From a78b0a40c62600767d6ce75ba05bc86d401ad94c Mon Sep 17 00:00:00 2001 From: Jeremy Kemper <jeremy@bitsweat.net> Date: Sat, 23 May 2009 19:00:06 -0700 Subject: runner class --- actionpack/examples/minimal.rb | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/actionpack/examples/minimal.rb b/actionpack/examples/minimal.rb index 76668b375d..0fc527445e 100644 --- a/actionpack/examples/minimal.rb +++ b/actionpack/examples/minimal.rb @@ -1,3 +1,7 @@ +# Pass NEW=1 to run with the new Base +ENV['RAILS_ENV'] ||= 'production' +ENV['NO_RELOAD'] ||= '1' + $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" require 'action_controller' require 'action_controller/new_base' if ENV['NEW'] @@ -9,26 +13,30 @@ class BaseController < ActionController::Base end end -n = (ENV['N'] || 1000).to_i -input = StringIO.new('') - -def call_index(controller, input, n) - n.times do - controller.action(:index).call({ 'rack.input' => input }) +class Runner + def initialize(app) + @app = app end - puts controller.name - status, headers, body = controller.action(:index).call({ 'rack.input' => input }) + def call(env) + env['n'].to_i.times { @app.call(env) } + @app.call(env).tap { |response| report(env, response) } + end - puts status - puts headers.to_yaml - puts '---' - body.each do |part| - puts part + def report(env, response) + out = env['rack.errors'] + out.puts response[0], response[1].to_yaml, '---' + response[2].each { |part| out.puts part } + out.puts '---' end - puts '---' end -elapsed = Benchmark.realtime { call_index BaseController, input, n } +n = (ENV['N'] || 1000).to_i +input = StringIO.new('') -puts "%dms elapsed, %d requests/sec" % [1000 * elapsed, n / elapsed] +elapsed = Benchmark.realtime do + Runner.new(BaseController.action(:index)). + call('n' => n, 'rack.input' => input, 'rack.errors' => $stdout) +end +puts "%dms elapsed, %d req/sec, %.2f msec/req" % + [1000 * elapsed, n / elapsed, 1000 * elapsed / n] -- cgit v1.2.3 From 6e039e863a5d71f2a516be2eef2605be23281290 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper <jeremy@bitsweat.net> Date: Sat, 23 May 2009 19:11:14 -0700 Subject: Speed up Request#formats --- actionpack/lib/action_dispatch/http/request.rb | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 259164d118..140feb9a68 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -3,7 +3,9 @@ require 'stringio' require 'strscan' require 'active_support/memoizable' +require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/object/tap' module ActionDispatch class Request < Rack::Request @@ -173,15 +175,21 @@ module ActionDispatch def formats if ActionController::Base.use_accept_header - ret = Array(Mime[parameters[:format]] || accepts) - if defined?(ActionController::Http) - if all = ret.index(Mime::ALL) - ret.delete(Mime::ALL) && ret.insert(all, *Mime::SET) + if param = parameters[:format] + Array.wrap(Mime[param]) + else + accepts.dup + end.tap do |ret| + if defined?(ActionController::Http) + if ret == ONLY_ALL + ret.replace Mime::SET + elsif all = ret.index(Mime::ALL) + ret.delete_at(all) && ret.insert(all, *Mime::SET) + end end end - ret else - [format] + Mime::SET + [format] + Mime::SET end end -- cgit v1.2.3 From bdb61c1dadd64ad4e146228ac8048fd0034fa8cc Mon Sep 17 00:00:00 2001 From: Jeremy Kemper <jeremy@bitsweat.net> Date: Sun, 24 May 2009 17:34:40 -0700 Subject: Compare Base with Http --- actionpack/examples/minimal.rb | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/actionpack/examples/minimal.rb b/actionpack/examples/minimal.rb index 0fc527445e..e2d112648c 100644 --- a/actionpack/examples/minimal.rb +++ b/actionpack/examples/minimal.rb @@ -7,12 +7,6 @@ require 'action_controller' require 'action_controller/new_base' if ENV['NEW'] require 'benchmark' -class BaseController < ActionController::Base - def index - render :text => '' - end -end - class Runner def initialize(app) @app = app @@ -29,14 +23,31 @@ class Runner response[2].each { |part| out.puts part } out.puts '---' end + + def self.run(app, n) + env = { 'n' => n, 'rack.input' => StringIO.new(''), 'rack.errors' => $stdout } + t = Benchmark.realtime { new(app).call(env) } + puts "%d ms / %d req = %d usec/req" % [10**3 * t, n, 10**6 * t / n] + end +end + + +N = (ENV['N'] || 1000).to_i + +class BasePostController < ActionController::Base + def index + render :text => '' + end + + Runner.run(action(:index), N) end -n = (ENV['N'] || 1000).to_i -input = StringIO.new('') +if ActionController.const_defined?(:Http) + class HttpPostController < ActionController::Http + def index + self.response_body = '' + end -elapsed = Benchmark.realtime do - Runner.new(BaseController.action(:index)). - call('n' => n, 'rack.input' => input, 'rack.errors' => $stdout) + Runner.run(action(:index), N) + end end -puts "%dms elapsed, %d req/sec, %.2f msec/req" % - [1000 * elapsed, n / elapsed, 1000 * elapsed / n] -- cgit v1.2.3 From b1d4fb71bf890793133fab8e4226952865fd468b Mon Sep 17 00:00:00 2001 From: Jeremy Kemper <jeremy@bitsweat.net> Date: Sun, 24 May 2009 17:35:49 -0700 Subject: Construct a single HeaderHash. Speed up assign_default_content_type_and_charset --- actionpack/lib/action_dispatch/http/response.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index edb522ff49..a01114b730 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -41,8 +41,7 @@ module ActionDispatch # :nodoc: delegate :default_charset, :to => 'ActionController::Base' def initialize - super - @header = Rack::Utils::HeaderHash.new(DEFAULT_HEADERS) + super([], 200, DEFAULT_HEADERS) end # The response code of the request @@ -162,8 +161,15 @@ module ActionDispatch # :nodoc: end def assign_default_content_type_and_charset! - self.content_type ||= Mime::HTML - self.charset ||= default_charset unless sending_file? + if type = headers['Content-Type'] + unless type =~ /charset=/ || sending_file? + headers['Content-Type'] = "#{type}; charset=#{default_charset}" + end + else + type = Mime::HTML.to_s + type += "; charset=#{default_charset}" unless sending_file? + headers['Content-Type'] = type + end end def prepare! -- cgit v1.2.3 From 8097da93ccbfaec82e7785ded7b3e68c8248b32f Mon Sep 17 00:00:00 2001 From: Jeremy Kemper <jeremy@bitsweat.net> Date: Sun, 24 May 2009 19:25:53 -0700 Subject: Don't want Rack's Content-Type default header though --- actionpack/lib/action_dispatch/http/response.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index a01114b730..b9db7a4508 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -41,7 +41,8 @@ module ActionDispatch # :nodoc: delegate :default_charset, :to => 'ActionController::Base' def initialize - super([], 200, DEFAULT_HEADERS) + super + @header = Rack::Utils::HeaderHash.new(DEFAULT_HEADERS) end # The response code of the request @@ -161,7 +162,7 @@ module ActionDispatch # :nodoc: end def assign_default_content_type_and_charset! - if type = headers['Content-Type'] + if type = headers['Content-Type'] || headers['type'] unless type =~ /charset=/ || sending_file? headers['Content-Type'] = "#{type}; charset=#{default_charset}" end -- cgit v1.2.3 From 9cda410d818353a5c27cbd5df754f1d1e290927d Mon Sep 17 00:00:00 2001 From: Pratik Naik <pratiknaik@gmail.com> Date: Mon, 25 May 2009 16:52:44 +0200 Subject: Make cookie store tests pass with the new base --- actionpack/test/dispatch/session/cookie_store_test.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb index 3090a70244..2db76818ac 100644 --- a/actionpack/test/dispatch/session/cookie_store_test.rb +++ b/actionpack/test/dispatch/session/cookie_store_test.rb @@ -5,6 +5,9 @@ class CookieStoreTest < ActionController::IntegrationTest SessionKey = '_myapp_session' SessionSecret = 'b3c631c314c0bbca50c1b2843150fe33' + # Make sure Session middleware doesnt get included in the middleware stack + ActionController::Base.session_store = nil + DispatcherApp = ActionController::Dispatcher.new CookieStoreApp = ActionDispatch::Session::CookieStore.new(DispatcherApp, :key => SessionKey, :secret => SessionSecret) -- cgit v1.2.3 From 10085114ce7ec6bc967fa701c49ef218f666efb5 Mon Sep 17 00:00:00 2001 From: Pratik Naik <pratiknaik@gmail.com> Date: Mon, 25 May 2009 18:05:58 +0200 Subject: Make Filter#filter work with around filters --- .../lib/action_controller/caching/actions.rb | 24 +++-- .../action_controller/new_base/compatibility.rb | 2 +- .../lib/action_controller/new_base/testing.rb | 8 ++ actionpack/test/controller/filters_test.rb | 113 ++++++++++----------- activesupport/lib/active_support/new_callbacks.rb | 22 +++- 5 files changed, 93 insertions(+), 76 deletions(-) diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index 430db3932f..3646ff1af9 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -63,7 +63,7 @@ module ActionController #:nodoc: cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path), :store_options => options) # TODO: Remove this once new base is swapped in. - if defined?(Http) + if defined?(ActionController::Http) around_filter cache_filter, filter_options else around_filter(filter_options) do |controller, action| @@ -92,16 +92,18 @@ module ActionController #:nodoc: end # TODO: Remove once New Base is merged - def filter(controller, action) - should_continue = before(controller) - action.call if should_continue - after(controller) - end - - def around_process_action(controller) - should_continue = before(controller) - yield if should_continue - after(controller) + if defined?(ActionController::Http) + def around_process_action(controller) + should_continue = before(controller) + yield if should_continue + after(controller) + end + else + def filter(controller, action) + should_continue = before(controller) + action.call if should_continue + after(controller) + end end def before(controller) diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb index b3190486e8..4245ba982b 100644 --- a/actionpack/lib/action_controller/new_base/compatibility.rb +++ b/actionpack/lib/action_controller/new_base/compatibility.rb @@ -83,7 +83,7 @@ module ActionController @@cache_store = ActiveSupport::Cache.lookup_store(store_option) end end - + def initialize(*) super @template = _action_view diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb index d8c3421587..78051a6252 100644 --- a/actionpack/lib/action_controller/new_base/testing.rb +++ b/actionpack/lib/action_controller/new_base/testing.rb @@ -1,5 +1,6 @@ module ActionController module Testing + extend ActiveSupport::DependencyModule # OMG MEGA HAX def process_with_new_base_test(request, response) @@ -26,5 +27,12 @@ module ActionController @_response ||= ActionDispatch::Response.new @_response.headers.replace(new_headers) end + + module ClassMethods + def before_filters + _process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name} + end + end + end end diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index 22aa50adb2..bdcc24b371 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -8,8 +8,7 @@ class << ActionController::Base end end -class FilterTest < Test::Unit::TestCase - include ActionController::TestProcess +class FilterTest < ActionController::TestCase class TestController < ActionController::Base before_filter :ensure_login @@ -468,108 +467,108 @@ class FilterTest < Test::Unit::TestCase def test_running_filters test_process(PrependingController) - assert_equal %w( wonderful_life ensure_login ), @controller.template.assigns["ran_filter"] + assert_equal %w( wonderful_life ensure_login ), assigns["ran_filter"] end def test_running_filters_with_proc test_process(ProcController) - assert @controller.template.assigns["ran_proc_filter"] + assert assigns["ran_proc_filter"] end def test_running_filters_with_implicit_proc test_process(ImplicitProcController) - assert @controller.template.assigns["ran_proc_filter"] + assert assigns["ran_proc_filter"] end def test_running_filters_with_class test_process(AuditController) - assert @controller.template.assigns["was_audited"] + assert assigns["was_audited"] end def test_running_anomolous_yet_valid_condition_filters test_process(AnomolousYetValidConditionController) - assert_equal %w( ensure_login ), @controller.template.assigns["ran_filter"] - assert @controller.template.assigns["ran_class_filter"] - assert @controller.template.assigns["ran_proc_filter1"] - assert @controller.template.assigns["ran_proc_filter2"] + assert_equal %w( ensure_login ), assigns["ran_filter"] + assert assigns["ran_class_filter"] + assert assigns["ran_proc_filter1"] + assert assigns["ran_proc_filter2"] test_process(AnomolousYetValidConditionController, "show_without_filter") - assert_equal nil, @controller.template.assigns["ran_filter"] - assert !@controller.template.assigns["ran_class_filter"] - assert !@controller.template.assigns["ran_proc_filter1"] - assert !@controller.template.assigns["ran_proc_filter2"] + assert_equal nil, assigns["ran_filter"] + assert !assigns["ran_class_filter"] + assert !assigns["ran_proc_filter1"] + assert !assigns["ran_proc_filter2"] end def test_running_conditional_options test_process(ConditionalOptionsFilter) - assert_equal %w( ensure_login ), @controller.template.assigns["ran_filter"] + assert_equal %w( ensure_login ), assigns["ran_filter"] end def test_running_collection_condition_filters test_process(ConditionalCollectionFilterController) - assert_equal %w( ensure_login ), @controller.template.assigns["ran_filter"] + assert_equal %w( ensure_login ), assigns["ran_filter"] test_process(ConditionalCollectionFilterController, "show_without_filter") - assert_equal nil, @controller.template.assigns["ran_filter"] + assert_equal nil, assigns["ran_filter"] test_process(ConditionalCollectionFilterController, "another_action") - assert_equal nil, @controller.template.assigns["ran_filter"] + assert_equal nil, assigns["ran_filter"] end def test_running_only_condition_filters test_process(OnlyConditionSymController) - assert_equal %w( ensure_login ), @controller.template.assigns["ran_filter"] + assert_equal %w( ensure_login ), assigns["ran_filter"] test_process(OnlyConditionSymController, "show_without_filter") - assert_equal nil, @controller.template.assigns["ran_filter"] + assert_equal nil, assigns["ran_filter"] test_process(OnlyConditionProcController) - assert @controller.template.assigns["ran_proc_filter"] + assert assigns["ran_proc_filter"] test_process(OnlyConditionProcController, "show_without_filter") - assert !@controller.template.assigns["ran_proc_filter"] + assert !assigns["ran_proc_filter"] test_process(OnlyConditionClassController) - assert @controller.template.assigns["ran_class_filter"] + assert assigns["ran_class_filter"] test_process(OnlyConditionClassController, "show_without_filter") - assert !@controller.template.assigns["ran_class_filter"] + assert !assigns["ran_class_filter"] end def test_running_except_condition_filters test_process(ExceptConditionSymController) - assert_equal %w( ensure_login ), @controller.template.assigns["ran_filter"] + assert_equal %w( ensure_login ), assigns["ran_filter"] test_process(ExceptConditionSymController, "show_without_filter") - assert_equal nil, @controller.template.assigns["ran_filter"] + assert_equal nil, assigns["ran_filter"] test_process(ExceptConditionProcController) - assert @controller.template.assigns["ran_proc_filter"] + assert assigns["ran_proc_filter"] test_process(ExceptConditionProcController, "show_without_filter") - assert !@controller.template.assigns["ran_proc_filter"] + assert !assigns["ran_proc_filter"] test_process(ExceptConditionClassController) - assert @controller.template.assigns["ran_class_filter"] + assert assigns["ran_class_filter"] test_process(ExceptConditionClassController, "show_without_filter") - assert !@controller.template.assigns["ran_class_filter"] + assert !assigns["ran_class_filter"] end def test_running_before_and_after_condition_filters test_process(BeforeAndAfterConditionController) - assert_equal %w( ensure_login clean_up_tmp), @controller.template.assigns["ran_filter"] + assert_equal %w( ensure_login clean_up_tmp), assigns["ran_filter"] test_process(BeforeAndAfterConditionController, "show_without_filter") - assert_equal nil, @controller.template.assigns["ran_filter"] + assert_equal nil, assigns["ran_filter"] end def test_around_filter test_process(AroundFilterController) - assert @controller.template.assigns["before_ran"] - assert @controller.template.assigns["after_ran"] + assert assigns["before_ran"] + assert assigns["after_ran"] end def test_before_after_class_filter test_process(BeforeAfterClassFilterController) - assert @controller.template.assigns["before_ran"] - assert @controller.template.assigns["after_ran"] + assert assigns["before_ran"] + assert assigns["after_ran"] end def test_having_properties_in_around_filter test_process(AroundFilterController) - assert_equal "before and after", @controller.template.assigns["execution_log"] + assert_equal "before and after", assigns["execution_log"] end def test_prepending_and_appending_around_filter @@ -582,7 +581,7 @@ class FilterTest < Test::Unit::TestCase def test_rendering_breaks_filtering_chain response = test_process(RenderingController) assert_equal "something else", response.body - assert !@controller.template.assigns["ran_action"] + assert !assigns["ran_action"] end def test_filters_with_mixed_specialization_run_in_order @@ -608,26 +607,26 @@ class FilterTest < Test::Unit::TestCase def test_running_prepended_before_and_after_filter test_process(PrependingBeforeAndAfterController) - assert_equal %w( before_all between_before_all_and_after_all after_all ), @controller.template.assigns["ran_filter"] + assert_equal %w( before_all between_before_all_and_after_all after_all ), assigns["ran_filter"] end def test_skipping_and_limiting_controller test_process(SkippingAndLimitedController, "index") - assert_equal %w( ensure_login ), @controller.template.assigns["ran_filter"] + assert_equal %w( ensure_login ), assigns["ran_filter"] test_process(SkippingAndLimitedController, "public") - assert_nil @controller.template.assigns["ran_filter"] + assert_nil assigns["ran_filter"] end def test_skipping_and_reordering_controller test_process(SkippingAndReorderingController, "index") - assert_equal %w( find_record ensure_login ), @controller.template.assigns["ran_filter"] + assert_equal %w( find_record ensure_login ), assigns["ran_filter"] end def test_conditional_skipping_of_filters test_process(ConditionalSkippingController, "login") - assert_nil @controller.template.assigns["ran_filter"] + assert_nil assigns["ran_filter"] test_process(ConditionalSkippingController, "change_password") - assert_equal %w( ensure_login find_user ), @controller.template.assigns["ran_filter"] + assert_equal %w( ensure_login find_user ), assigns["ran_filter"] test_process(ConditionalSkippingController, "login") assert_nil @controller.template.controller.instance_variable_get("@ran_after_filter") @@ -637,23 +636,23 @@ class FilterTest < Test::Unit::TestCase def test_conditional_skipping_of_filters_when_parent_filter_is_also_conditional test_process(ChildOfConditionalParentController) - assert_equal %w( conditional_in_parent conditional_in_parent ), @controller.template.assigns['ran_filter'] + assert_equal %w( conditional_in_parent conditional_in_parent ), assigns['ran_filter'] test_process(ChildOfConditionalParentController, 'another_action') - assert_nil @controller.template.assigns['ran_filter'] + assert_nil assigns['ran_filter'] end def test_condition_skipping_of_filters_when_siblings_also_have_conditions test_process(ChildOfConditionalParentController) - assert_equal %w( conditional_in_parent conditional_in_parent ), @controller.template.assigns['ran_filter'], "1" + assert_equal %w( conditional_in_parent conditional_in_parent ), assigns['ran_filter'], "1" test_process(AnotherChildOfConditionalParentController) - assert_equal nil, @controller.template.assigns['ran_filter'] + assert_equal nil, assigns['ran_filter'] test_process(ChildOfConditionalParentController) - assert_equal %w( conditional_in_parent conditional_in_parent ), @controller.template.assigns['ran_filter'] + assert_equal %w( conditional_in_parent conditional_in_parent ), assigns['ran_filter'] end def test_changing_the_requirements test_process(ChangingTheRequirementsController, "go_wild") - assert_equal nil, @controller.template.assigns['ran_filter'] + assert_equal nil, assigns['ran_filter'] end def test_a_rescuing_around_filter @@ -806,9 +805,8 @@ class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters skip_filter :after end -class YieldingAroundFiltersTest < Test::Unit::TestCase +class YieldingAroundFiltersTest < ActionController::TestCase include PostsController::AroundExceptions - include ActionController::TestProcess def test_base controller = PostsController @@ -846,8 +844,8 @@ class YieldingAroundFiltersTest < Test::Unit::TestCase def test_with_proc test_process(ControllerWithProcFilter,'no_raise') - assert @controller.template.assigns['before'] - assert @controller.template.assigns['after'] + assert assigns['before'] + assert assigns['after'] end def test_nested_filters @@ -868,12 +866,12 @@ class YieldingAroundFiltersTest < Test::Unit::TestCase def test_filter_order_with_all_filter_types test_process(ControllerWithAllTypesOfFilters,'no_raise') - assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after', @controller.template.assigns['ran_filter'].join(' ') + assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after', assigns['ran_filter'].join(' ') end def test_filter_order_with_skip_filter_method test_process(ControllerWithTwoLessFilters,'no_raise') - assert_equal 'before around (before yield) around (after yield)', @controller.template.assigns['ran_filter'].join(' ') + assert_equal 'before around (before yield) around (after yield)', assigns['ran_filter'].join(' ') end def test_first_filter_in_multiple_before_filter_chain_halts @@ -903,9 +901,6 @@ class YieldingAroundFiltersTest < Test::Unit::TestCase protected def test_process(controller, action = "show") @controller = controller.is_a?(Class) ? controller.new : controller - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new - process(action) end end diff --git a/activesupport/lib/active_support/new_callbacks.rb b/activesupport/lib/active_support/new_callbacks.rb index f8108780f1..039d0fa658 100644 --- a/activesupport/lib/active_support/new_callbacks.rb +++ b/activesupport/lib/active_support/new_callbacks.rb @@ -298,11 +298,23 @@ module ActiveSupport kind, name = @kind, @name @klass.send(:define_method, "#{method_name}_object") { filter } - @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{method_name}(&blk) - #{method_name}_object.send("#{kind}_#{name}", self, &blk) - end - RUBY_EVAL + if kind == :around + @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{method_name}(&blk) + if :#{kind} == :around && #{method_name}_object.respond_to?(:filter) + #{method_name}_object.send("filter", self, &blk) + else + #{method_name}_object.send("#{kind}_#{name}", self, &blk) + end + end + RUBY_EVAL + else + @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{method_name}(&blk) + #{method_name}_object.send("#{kind}_#{name}", self, &blk) + end + RUBY_EVAL + end method_name end end -- cgit v1.2.3 From 2f59066470193c6219dfd958fc5d8096a2ddee68 Mon Sep 17 00:00:00 2001 From: Pratik Naik <pratiknaik@gmail.com> Date: Tue, 26 May 2009 13:09:33 +0200 Subject: Support Method callbacks --- activesupport/lib/active_support/new_callbacks.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/activesupport/lib/active_support/new_callbacks.rb b/activesupport/lib/active_support/new_callbacks.rb index 039d0fa658..b6cbdbb6b0 100644 --- a/activesupport/lib/active_support/new_callbacks.rb +++ b/activesupport/lib/active_support/new_callbacks.rb @@ -287,6 +287,14 @@ module ActiveSupport when Proc @klass.send(:define_method, method_name, &filter) method_name << (filter.arity == 1 ? "(self)" : "") + when Method + @klass.send(:define_method, "#{method_name}_method") { filter } + @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{method_name}(&blk) + #{method_name}_method.call(self, &blk) + end + RUBY_EVAL + method_name when String @klass.class_eval <<-RUBY_EVAL def #{method_name} -- cgit v1.2.3