aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilio Tagua <miloops@gmail.com>2009-08-27 15:56:16 -0300
committerEmilio Tagua <miloops@gmail.com>2009-08-27 15:56:16 -0300
commitd395391e1dfae4531671fbb09911e6b9418474ba (patch)
tree65d679e11c15de32c18a4303d6dcb9f88f2a0925
parent286f47f3b034db4550110b9a0f9ff48dda29e807 (diff)
parentc10396b1426fcddea35d88fe865846b8aaab5de4 (diff)
downloadrails-d395391e1dfae4531671fbb09911e6b9418474ba.tar.gz
rails-d395391e1dfae4531671fbb09911e6b9418474ba.tar.bz2
rails-d395391e1dfae4531671fbb09911e6b9418474ba.zip
Merge commit 'rails/master'
-rw-r--r--Rakefile10
-rw-r--r--actionpack/lib/abstract_controller/base.rb1
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb3
-rw-r--r--actionpack/lib/abstract_controller/logger.rb4
-rw-r--r--actionpack/lib/action_controller.rb1
-rw-r--r--actionpack/lib/action_controller/metal.rb22
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb20
-rw-r--r--actionpack/lib/action_controller/metal/redirector.rb3
-rw-r--r--actionpack/lib/action_controller/middleware.rb38
-rw-r--r--actionpack/lib/action_controller/routing/generation/url_rewriter.rb2
-rw-r--r--actionpack/lib/action_controller/testing/process.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/stack.rb6
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb3
-rw-r--r--actionpack/lib/action_view/locale/en.yml4
-rw-r--r--actionpack/lib/action_view/paths.rb3
-rw-r--r--actionpack/lib/action_view/template/resolver.rb2
-rw-r--r--actionpack/test/abstract_controller/abstract_controller_test.rb53
-rw-r--r--actionpack/test/abstract_controller/callbacks_test.rb94
-rw-r--r--actionpack/test/abstract_controller/helper_test.rb5
-rw-r--r--actionpack/test/abstract_controller/layouts_test.rb55
-rw-r--r--actionpack/test/abstract_unit.rb12
-rw-r--r--actionpack/test/activerecord/active_record_store_test.rb25
-rw-r--r--actionpack/test/controller/action_pack_assertions_test.rb8
-rw-r--r--actionpack/test/controller/routing_test.rb86
-rw-r--r--actionpack/test/controller/test_test.rb3
-rw-r--r--actionpack/test/controller/url_rewriter_test.rb26
-rw-r--r--actionpack/test/controller/webservice_test.rb1
-rw-r--r--actionpack/test/dispatch/request/json_params_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/request/multipart_params_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/request/query_string_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/request/xml_params_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/session/cookie_store_test.rb19
-rw-r--r--actionpack/test/dispatch/session/mem_cache_store_test.rb16
-rw-r--r--actionpack/test/lib/controller/fake_controllers.rb9
-rw-r--r--actionpack/test/new_base/metal_test.rb11
-rw-r--r--actionpack/test/new_base/test_helper.rb24
-rw-r--r--actionpack/test/template/form_options_helper_i18n_test.rb27
-rw-r--r--activerecord/Rakefile32
-rw-r--r--activerecord/lib/active_record/fixtures.rb16
-rw-r--r--activerecord/lib/active_record/locale/en.yml1
-rw-r--r--activerecord/lib/active_record/validations.rb3
-rw-r--r--activerecord/test/cases/validations/i18n_validation_test.rb188
-rw-r--r--activesupport/lib/active_support/core_ext/regexp.rb2
-rw-r--r--activesupport/test/core_ext/regexp_ext_test.rb18
46 files changed, 593 insertions, 274 deletions
diff --git a/Rakefile b/Rakefile
index 5dd9f40310..5f918657aa 100644
--- a/Rakefile
+++ b/Rakefile
@@ -3,7 +3,7 @@ require 'rake/rdoctask'
env = %(PKG_BUILD="#{ENV['PKG_BUILD']}") if ENV['PKG_BUILD']
-PROJECTS = %w(activesupport actionpack actionmailer activemodel activeresource activerecord railties)
+PROJECTS = %w(activesupport actionpack actionmailer activeresource activerecord railties)
Dir["#{File.dirname(__FILE__)}/*/lib/*/version.rb"].each do |version_path|
require version_path
@@ -12,7 +12,7 @@ end
desc 'Run all tests by default'
task :default => :test
-%w(test isolated_test rdoc pgem package release).each do |task_name|
+%w(test isolated_test rdoc pgem package release gem).each do |task_name|
desc "Run #{task_name} task for all projects"
task task_name do
errors = []
@@ -23,6 +23,12 @@ task :default => :test
end
end
+task :install => :gem do
+ (PROJECTS - ["railties"]).each do |project|
+ system("gem install #{project}/pkg/#{project}-#{ActionPack::VERSION::STRING}.gem --no-ri --no-rdoc")
+ end
+end
+
desc "Generate documentation for the Rails framework"
Rake::RDocTask.new do |rdoc|
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb
index b93e6ce634..f5b1c9e4d1 100644
--- a/actionpack/lib/abstract_controller/base.rb
+++ b/actionpack/lib/abstract_controller/base.rb
@@ -89,7 +89,6 @@ module AbstractController
end
process_action(action_name)
- self
end
private
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index a8bd2b80e1..ef66b24dd6 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -145,6 +145,9 @@ module AbstractController
# This is a little bit messy. We need to explicitly handle partial
# layouts here since the core lookup logic is in the view, but
# we need to determine the layout based on the controller
+ #
+ # TODO: An easier way to handle this would probably be to override
+ # render_template
if layout
layout = _layout_for_option(layout, options[:_template].details)
response = layout.render(view_context, options[:locals] || {}) { response }
diff --git a/actionpack/lib/abstract_controller/logger.rb b/actionpack/lib/abstract_controller/logger.rb
index fd33bd2ddd..1b879b963b 100644
--- a/actionpack/lib/abstract_controller/logger.rb
+++ b/actionpack/lib/abstract_controller/logger.rb
@@ -29,7 +29,7 @@ module AbstractController
# Override process_action in the AbstractController::Base
# to log details about the method.
def process_action(action)
- super
+ retval = super
if logger
log = DelayedLog.new do
@@ -40,6 +40,8 @@ module AbstractController
logger.info(log)
end
+
+ retval
end
private
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb
index 37ff618edd..d27a867efe 100644
--- a/actionpack/lib/action_controller.rb
+++ b/actionpack/lib/action_controller.rb
@@ -3,6 +3,7 @@ module ActionController
autoload :ConditionalGet, "action_controller/metal/conditional_get"
autoload :HideActions, "action_controller/metal/hide_actions"
autoload :Metal, "action_controller/metal"
+ autoload :Middleware, "action_controller/middleware"
autoload :Layouts, "action_controller/metal/layouts"
autoload :RackConvenience, "action_controller/metal/rack_convenience"
autoload :Rails2Compatibility, "action_controller/metal/compatibility"
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index aad9570237..51fbba3661 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -88,23 +88,6 @@ module ActionController
end
end
- class ActionMiddleware
- def initialize(controller, action)
- @controller, @action = controller, action
- end
-
- def call(env)
- controller = @controller.new
- controller.app = @app
- controller.call(@action, env)
- end
-
- def new(app)
- @app = app
- self
- end
- end
-
# Return a rack endpoint for the given action. Memoize the endpoint, so
# multiple calls into MyController.action will return the same object
# for the same action.
@@ -118,10 +101,5 @@ module ActionController
@actions ||= {}
@actions[name.to_s] ||= ActionEndpoint.new(self, name)
end
-
- def self.middleware(name)
- @middlewares ||= {}
- @middlewares[name.to_s] ||= ActionMiddleware.new(self, name)
- end
end
end
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 2b62a1be85..0f35a7c040 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -115,7 +115,7 @@ module ActionController
end
def authenticate_with_http_basic(&login_procedure)
- HttpAuthentication::Basic.authenticate(self, &login_procedure)
+ HttpAuthentication::Basic.authenticate(request, &login_procedure)
end
def request_http_basic_authentication(realm = "Application")
@@ -123,9 +123,9 @@ module ActionController
end
end
- def authenticate(controller, &login_procedure)
- unless authorization(controller.request).blank?
- login_procedure.call(*user_name_and_password(controller.request))
+ def authenticate(request, &login_procedure)
+ unless authorization(request).blank?
+ login_procedure.call(*user_name_and_password(request))
end
end
@@ -150,7 +150,8 @@ module ActionController
def authentication_request(controller, realm)
controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}")
- controller.__send__ :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
+ controller.response_body = "HTTP Basic: Access denied.\n"
+ controller.status = 401
end
end
@@ -164,7 +165,7 @@ module ActionController
# Authenticate with HTTP Digest, returns true or false
def authenticate_with_http_digest(realm = "Application", &password_procedure)
- HttpAuthentication::Digest.authenticate(self, realm, &password_procedure)
+ HttpAuthentication::Digest.authenticate(request, realm, &password_procedure)
end
# Render output including the HTTP Digest authentication header
@@ -174,8 +175,8 @@ module ActionController
end
# Returns false on a valid response, true otherwise
- def authenticate(controller, realm, &password_procedure)
- authorization(controller.request) && validate_digest_response(controller.request, realm, &password_procedure)
+ def authenticate(request, realm, &password_procedure)
+ authorization(request) && validate_digest_response(request, realm, &password_procedure)
end
def authorization(request)
@@ -243,7 +244,8 @@ module ActionController
def authentication_request(controller, realm, message = nil)
message ||= "HTTP Digest: Access denied.\n"
authentication_header(controller, realm)
- controller.__send__ :render, :text => message, :status => :unauthorized
+ controller.response_body = message
+ controller.status = 401
end
# Uses an MD5 digest based on time to generate a value to be used only once.
diff --git a/actionpack/lib/action_controller/metal/redirector.rb b/actionpack/lib/action_controller/metal/redirector.rb
index 20060b001f..f79fd54acd 100644
--- a/actionpack/lib/action_controller/metal/redirector.rb
+++ b/actionpack/lib/action_controller/metal/redirector.rb
@@ -8,6 +8,9 @@ module ActionController
end
module Redirector
+ extend ActiveSupport::Concern
+ include AbstractController::Logger
+
def redirect_to(url, status) #:doc:
raise AbstractController::DoubleRenderError if response_body
logger.info("Redirected to #{url}") if logger && logger.info?
diff --git a/actionpack/lib/action_controller/middleware.rb b/actionpack/lib/action_controller/middleware.rb
new file mode 100644
index 0000000000..fac0ed2645
--- /dev/null
+++ b/actionpack/lib/action_controller/middleware.rb
@@ -0,0 +1,38 @@
+module ActionController
+ class Middleware < Metal
+ class ActionMiddleware
+ def initialize(controller)
+ @controller = controller
+ end
+
+ def call(env)
+ controller = @controller.allocate
+ controller.send(:initialize)
+ controller.app = @app
+ controller._call(env)
+ end
+
+ def app=(app)
+ @app = app
+ end
+ end
+
+ def self.new(app)
+ middleware = ActionMiddleware.new(self)
+ middleware.app = app
+ middleware
+ end
+
+ def _call(env)
+ @_env = env
+ @_request = ActionDispatch::Request.new(env)
+ @_response = ActionDispatch::Response.new
+ @_response.request = @_request
+ process(:index)
+ end
+
+ def index
+ call(env)
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/routing/generation/url_rewriter.rb b/actionpack/lib/action_controller/routing/generation/url_rewriter.rb
index 9717582b5e..52b66c9303 100644
--- a/actionpack/lib/action_controller/routing/generation/url_rewriter.rb
+++ b/actionpack/lib/action_controller/routing/generation/url_rewriter.rb
@@ -172,7 +172,7 @@ module ActionController
path = rewrite_path(options)
rewritten_url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root]
rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
- rewritten_url << "##{options[:anchor]}" if options[:anchor]
+ rewritten_url << "##{CGI.escape(options[:anchor].to_param.to_s)}" if options[:anchor]
rewritten_url
end
diff --git a/actionpack/lib/action_controller/testing/process.rb b/actionpack/lib/action_controller/testing/process.rb
index 6bc7d60d76..4185b803c5 100644
--- a/actionpack/lib/action_controller/testing/process.rb
+++ b/actionpack/lib/action_controller/testing/process.rb
@@ -249,6 +249,7 @@ module ActionController #:nodoc:
temporary_routes = ActionController::Routing::RouteSet.new
ActionController::Routing.module_eval { const_set :Routes, temporary_routes }
+ ActionController::Dispatcher.router = temporary_routes
yield temporary_routes
ensure
@@ -256,6 +257,7 @@ module ActionController #:nodoc:
ActionController::Routing.module_eval { remove_const :Routes }
end
ActionController::Routing.const_set(:Routes, real_routes) if real_routes
+ ActionController::Dispatcher.router = ActionController::Routing::Routes
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index 547a2d2062..9cfd6956d0 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/hash/keys"
+
module ActionDispatch
module Session
# This cookie-based session store is the Rails default. Sessions typically
diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb
index ade2d6f05e..4f71ea6165 100644
--- a/actionpack/lib/action_dispatch/middleware/stack.rb
+++ b/actionpack/lib/action_dispatch/middleware/stack.rb
@@ -27,10 +27,10 @@ module ActionDispatch
end
def klass
- if @klass.respond_to?(:call)
- @klass.call
- elsif @klass.is_a?(Class)
+ if @klass.respond_to?(:new)
@klass
+ elsif @klass.respond_to?(:call)
+ @klass.call
else
@klass.to_s.constantize
end
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 4620a52272..3db5202e7d 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -571,7 +571,8 @@ module ActionView
option_tags = "<option value=\"\">#{options[:include_blank] if options[:include_blank].kind_of?(String)}</option>\n" + option_tags
end
if value.blank? && options[:prompt]
- ("<option value=\"\">#{options[:prompt].kind_of?(String) ? options[:prompt] : 'Please select'}</option>\n") + option_tags
+ prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('support.select.prompt', :default => 'Please select')
+ "<option value=\"\">#{prompt}</option>\n" + option_tags
else
option_tags
end
diff --git a/actionpack/lib/action_view/locale/en.yml b/actionpack/lib/action_view/locale/en.yml
index afe35691bc..c82cd07ec2 100644
--- a/actionpack/lib/action_view/locale/en.yml
+++ b/actionpack/lib/action_view/locale/en.yml
@@ -108,3 +108,7 @@
# The variable :count is also available
body: "There were problems with the following fields:"
+ support:
+ select:
+ # default value for :prompt => true in FormOptionsHelper
+ prompt: "Please select" \ No newline at end of file
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb
index 4001757a9b..5524a3219a 100644
--- a/actionpack/lib/action_view/paths.rb
+++ b/actionpack/lib/action_view/paths.rb
@@ -34,7 +34,6 @@ module ActionView #:nodoc:
end
def find(path, details = {}, prefix = nil, partial = false)
- # template_path = path.sub(/^\//, '')
template_path = path
each do |load_path|
@@ -43,8 +42,6 @@ module ActionView #:nodoc:
end
end
- # TODO: Have a fallback absolute path?
- extension = details[:formats] || []
raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path} - #{details.inspect} - partial: #{!!partial}")
end
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index fe657166d5..0b4c62d4d0 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -4,7 +4,7 @@ require "action_view/template/template"
module ActionView
# Abstract superclass
class Resolver
- def initialize(options)
+ def initialize(options = {})
@cache = options[:cache]
@cached = {}
end
diff --git a/actionpack/test/abstract_controller/abstract_controller_test.rb b/actionpack/test/abstract_controller/abstract_controller_test.rb
index 9438a4dfc9..7991436703 100644
--- a/actionpack/test/abstract_controller/abstract_controller_test.rb
+++ b/actionpack/test/abstract_controller/abstract_controller_test.rb
@@ -19,8 +19,9 @@ module AbstractController
class TestBasic < ActiveSupport::TestCase
test "dispatching works" do
- result = Me.new.process(:index)
- assert_equal "Hello world", result.response_body
+ controller = Me.new
+ controller.process(:index)
+ assert_equal "Hello world", controller.response_body
end
end
@@ -67,29 +68,33 @@ module AbstractController
end
class TestRenderingController < ActiveSupport::TestCase
+ def setup
+ @controller = Me2.new
+ end
+
test "rendering templates works" do
- result = Me2.new.process(:index)
- assert_equal "Hello from index.erb", result.response_body
+ @controller.process(:index)
+ assert_equal "Hello from index.erb", @controller.response_body
end
test "rendering passes ivars to the view" do
- result = Me2.new.process(:action_with_ivars)
- assert_equal "Hello from index_with_ivars.erb", result.response_body
+ @controller.process(:action_with_ivars)
+ assert_equal "Hello from index_with_ivars.erb", @controller.response_body
end
test "rendering with no template name" do
- result = Me2.new.process(:naked_render)
- assert_equal "Hello from naked_render.erb", result.response_body
+ @controller.process(:naked_render)
+ assert_equal "Hello from naked_render.erb", @controller.response_body
end
test "rendering to a rack body" do
- result = Me2.new.process(:rendering_to_body)
- assert_equal "Hello from naked_render.erb", result.response_body
+ @controller.process(:rendering_to_body)
+ assert_equal "Hello from naked_render.erb", @controller.response_body
end
test "rendering to a string" do
- result = Me2.new.process(:rendering_to_string)
- assert_equal "Hello from naked_render.erb", result.response_body
+ @controller.process(:rendering_to_string)
+ assert_equal "Hello from naked_render.erb", @controller.response_body
end
end
@@ -119,14 +124,18 @@ module AbstractController
end
class TestPrefixedViews < ActiveSupport::TestCase
+ def setup
+ @controller = Me3.new
+ end
+
test "templates are located inside their 'prefix' folder" do
- result = Me3.new.process(:index)
- assert_equal "Hello from me3/index.erb", result.response_body
+ @controller.process(:index)
+ assert_equal "Hello from me3/index.erb", @controller.response_body
end
test "templates included their format" do
- result = Me3.new.process(:formatted)
- assert_equal "Hello from me3/formatted.html.erb", result.response_body
+ @controller.process(:formatted)
+ assert_equal "Hello from me3/formatted.html.erb", @controller.response_body
end
end
@@ -168,8 +177,9 @@ module AbstractController
class TestLayouts < ActiveSupport::TestCase
test "layouts are included" do
- result = Me4.new.process(:index)
- assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", result.response_body
+ controller = Me4.new
+ result = controller.process(:index)
+ assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", controller.response_body
end
end
@@ -203,10 +213,11 @@ module AbstractController
end
class TestRespondToAction < ActiveSupport::TestCase
-
+
def assert_dispatch(klass, body = "success", action = :index)
- response = klass.new.process(action).response_body
- assert_equal body, response
+ controller = klass.new
+ controller.process(action)
+ assert_equal body, controller.response_body
end
test "an arbitrary method is available as an action by default" do
diff --git a/actionpack/test/abstract_controller/callbacks_test.rb b/actionpack/test/abstract_controller/callbacks_test.rb
index 817f60f7d1..8f62adce8c 100644
--- a/actionpack/test/abstract_controller/callbacks_test.rb
+++ b/actionpack/test/abstract_controller/callbacks_test.rb
@@ -19,10 +19,11 @@ module AbstractController
end
end
- class TestCallbacks < ActiveSupport::TestCase
+ class TestCallbacks1 < ActiveSupport::TestCase
test "basic callbacks work" do
- result = Callback1.new.process(:index)
- assert_equal "Hello world", result.response_body
+ controller = Callback1.new
+ result = controller.process(:index)
+ assert_equal "Hello world", controller.response_body
end
end
@@ -50,20 +51,24 @@ module AbstractController
end
end
- class TestCallbacks < ActiveSupport::TestCase
+ class TestCallbacks2 < ActiveSupport::TestCase
+ def setup
+ @controller = Callback2.new
+ end
+
test "before_filter works" do
- result = Callback2.new.process(:index)
- assert_equal "Hello world", result.response_body
+ result = @controller.process(:index)
+ assert_equal "Hello world", @controller.response_body
end
test "after_filter works" do
- result = Callback2.new.process(:index)
- assert_equal "Goodbye", result.instance_variable_get("@second")
+ @controller.process(:index)
+ assert_equal "Goodbye", @controller.instance_variable_get("@second")
end
test "around_filter works" do
- result = Callback2.new.process(:index)
- assert_equal "FIRSTSECOND", result.instance_variable_get("@aroundz")
+ @controller.process(:index)
+ assert_equal "FIRSTSECOND", @controller.instance_variable_get("@aroundz")
end
end
@@ -81,15 +86,19 @@ module AbstractController
end
end
- class TestCallbacks < ActiveSupport::TestCase
+ class TestCallbacks3 < ActiveSupport::TestCase
+ def setup
+ @controller = Callback3.new
+ end
+
test "before_filter works with procs" do
- result = Callback3.new.process(:index)
- assert_equal "Hello world", result.response_body
+ result = @controller.process(:index)
+ assert_equal "Hello world", @controller.response_body
end
test "after_filter works with procs" do
- result = Callback3.new.process(:index)
- assert_equal "Goodbye", result.instance_variable_get("@second")
+ result = @controller.process(:index)
+ assert_equal "Goodbye", @controller.instance_variable_get("@second")
end
end
@@ -116,20 +125,24 @@ module AbstractController
end
end
- class TestCallbacks < ActiveSupport::TestCase
+ class TestCallbacksWithConditions < ActiveSupport::TestCase
+ def setup
+ @controller = CallbacksWithConditions.new
+ end
+
test "when :only is specified, a before filter is triggered on that action" do
- result = CallbacksWithConditions.new.process(:index)
- assert_equal "Hello, World", result.response_body
+ @controller.process(:index)
+ assert_equal "Hello, World", @controller.response_body
end
test "when :only is specified, a before filter is not triggered on other actions" do
- result = CallbacksWithConditions.new.process(:sekrit_data)
- assert_equal "true", result.response_body
+ @controller.process(:sekrit_data)
+ assert_equal "true", @controller.response_body
end
test "when :except is specified, an after filter is not triggered on that action" do
- result = CallbacksWithConditions.new.process(:index)
- assert_nil result.instance_variable_get("@authenticated")
+ result = @controller.process(:index)
+ assert_nil @controller.instance_variable_get("@authenticated")
end
end
@@ -156,20 +169,24 @@ module AbstractController
end
end
- class TestCallbacks < ActiveSupport::TestCase
+ class TestCallbacksWithArrayConditions < ActiveSupport::TestCase
+ def setup
+ @controller = CallbacksWithArrayConditions.new
+ end
+
test "when :only is specified with an array, a before filter is triggered on that action" do
- result = CallbacksWithArrayConditions.new.process(:index)
- assert_equal "Hello, World", result.response_body
+ result = @controller.process(:index)
+ assert_equal "Hello, World", @controller.response_body
end
test "when :only is specified with an array, a before filter is not triggered on other actions" do
- result = CallbacksWithArrayConditions.new.process(:sekrit_data)
- assert_equal "true", result.response_body
+ result = @controller.process(:sekrit_data)
+ assert_equal "true", @controller.response_body
end
test "when :except is specified with an array, an after filter is not triggered on that action" do
- result = CallbacksWithArrayConditions.new.process(:index)
- assert_nil result.instance_variable_get("@authenticated")
+ result = @controller.process(:index)
+ assert_nil @controller.instance_variable_get("@authenticated")
end
end
@@ -181,15 +198,19 @@ module AbstractController
end
end
- class TestCallbacks < ActiveSupport::TestCase
+ class TestCallbacksWithChangedConditions < ActiveSupport::TestCase
+ def setup
+ @controller = ChangedConditions.new
+ end
+
test "when a callback is modified in a child with :only, it works for the :only action" do
- result = ChangedConditions.new.process(:index)
- assert_equal "Hello world", result.response_body
+ result = @controller.process(:index)
+ assert_equal "Hello world", @controller.response_body
end
test "when a callback is modified in a child with :only, it does not work for other actions" do
- result = ChangedConditions.new.process(:not_index)
- assert_equal "", result.response_body
+ result = @controller.process(:not_index)
+ assert_equal "", @controller.response_body
end
end
@@ -207,8 +228,9 @@ module AbstractController
class TestHalting < ActiveSupport::TestCase
test "when a callback sets the response body, the action should not be invoked" do
- result = SetsResponseBody.new.process(:index)
- assert_equal "Success", result.response_body
+ controller = SetsResponseBody.new
+ controller.process(:index)
+ assert_equal "Success", controller.response_body
end
end
diff --git a/actionpack/test/abstract_controller/helper_test.rb b/actionpack/test/abstract_controller/helper_test.rb
index e9a60c0307..34a10cecc9 100644
--- a/actionpack/test/abstract_controller/helper_test.rb
+++ b/actionpack/test/abstract_controller/helper_test.rb
@@ -34,8 +34,9 @@ module AbstractController
class TestHelpers < ActiveSupport::TestCase
def test_helpers
- result = MyHelpers1.new.process(:index)
- assert_equal "Hello World : Included", result.response_body
+ controller = MyHelpers1.new
+ controller.process(:index)
+ assert_equal "Hello World : Included", controller.response_body
end
end
diff --git a/actionpack/test/abstract_controller/layouts_test.rb b/actionpack/test/abstract_controller/layouts_test.rb
index 42f73faa61..995aac7fad 100644
--- a/actionpack/test/abstract_controller/layouts_test.rb
+++ b/actionpack/test/abstract_controller/layouts_test.rb
@@ -143,13 +143,15 @@ module AbstractControllerTests
class TestBase < ActiveSupport::TestCase
test "when no layout is specified, and no default is available, render without a layout" do
- result = Blank.new.process(:index)
- assert_equal "Hello blank!", result.response_body
+ controller = Blank.new
+ controller.process(:index)
+ assert_equal "Hello blank!", controller.response_body
end
test "when layout is specified as a string, render with that layout" do
- result = WithString.new.process(:index)
- assert_equal "With String Hello string!", result.response_body
+ controller = WithString.new
+ controller.process(:index)
+ assert_equal "With String Hello string!", controller.response_body
end
test "when layout is specified as a string, but the layout is missing, raise an exception" do
@@ -157,23 +159,27 @@ module AbstractControllerTests
end
test "when layout is specified as false, do not use a layout" do
- result = WithFalseLayout.new.process(:index)
- assert_equal "Hello false!", result.response_body
+ controller = WithFalseLayout.new
+ controller.process(:index)
+ assert_equal "Hello false!", controller.response_body
end
test "when layout is specified as nil, do not use a layout" do
- result = WithNilLayout.new.process(:index)
- assert_equal "Hello nil!", result.response_body
+ controller = WithNilLayout.new
+ controller.process(:index)
+ assert_equal "Hello nil!", controller.response_body
end
test "when layout is specified as a symbol, call the requested method and use the layout returned" do
- result = WithSymbol.new.process(:index)
- assert_equal "OMGHI2U Hello symbol!", result.response_body
+ controller = WithSymbol.new
+ controller.process(:index)
+ assert_equal "OMGHI2U Hello symbol!", controller.response_body
end
test "when layout is specified as a symbol and the method returns nil, don't use a layout" do
- result = WithSymbolReturningNil.new.process(:index)
- assert_equal "Hello nilz!", result.response_body
+ controller = WithSymbolReturningNil.new
+ controller.process(:index)
+ assert_equal "Hello nilz!", controller.response_body
end
test "when the layout is specified as a symbol and the method doesn't exist, raise an exception" do
@@ -185,29 +191,34 @@ module AbstractControllerTests
end
test "when a child controller does not have a layout, use the parent controller layout" do
- result = WithStringChild.new.process(:index)
- assert_equal "With String Hello string!", result.response_body
+ controller = WithStringChild.new
+ controller.process(:index)
+ assert_equal "With String Hello string!", controller.response_body
end
test "when a child controller has specified a layout, use that layout and not the parent controller layout" do
- result = WithStringOverriddenChild.new.process(:index)
- assert_equal "With Override Hello string!", result.response_body
+ controller = WithStringOverriddenChild.new
+ controller.process(:index)
+ assert_equal "With Override Hello string!", controller.response_body
end
test "when a child controller has an implied layout, use that layout and not the parent controller layout" do
- result = WithStringImpliedChild.new.process(:index)
- assert_equal "With Implied Hello string!", result.response_body
+ controller = WithStringImpliedChild.new
+ controller.process(:index)
+ assert_equal "With Implied Hello string!", controller.response_body
end
test "when a child controller specifies layout nil, do not use the parent layout" do
- result = WithNilChild.new.process(:index)
- assert_equal "Hello string!", result.response_body
+ controller = WithNilChild.new
+ controller.process(:index)
+ assert_equal "Hello string!", controller.response_body
end
test "when a grandchild has no layout specified, the child has an implied layout, and the " \
"parent has specified a layout, use the child controller layout" do
- result = WithChildOfImplied.new.process(:index)
- assert_equal "With Implied Hello string!", result.response_body
+ controller = WithChildOfImplied.new
+ controller.process(:index)
+ assert_equal "With Implied Hello string!", controller.response_body
end
test "raises an exception when specifying layout true" do
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index a21b00915e..07ba37c51c 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -62,8 +62,20 @@ module ActionController
}
Base.session_store = nil
+ class << Routing
+ def possible_controllers
+ @@possible_controllers ||= []
+ end
+ end
+
class Base
include ActionController::Testing
+
+ def self.inherited(klass)
+ name = klass.name.underscore.sub(/_controller$/, '')
+ ActionController::Routing.possible_controllers << name unless name.blank?
+ super
+ end
end
Base.view_paths = FIXTURE_LOAD_PATH
diff --git a/actionpack/test/activerecord/active_record_store_test.rb b/actionpack/test/activerecord/active_record_store_test.rb
index 47f8496181..a46ce7a0aa 100644
--- a/actionpack/test/activerecord/active_record_store_test.rb
+++ b/actionpack/test/activerecord/active_record_store_test.rb
@@ -1,12 +1,6 @@
require 'active_record_unit'
class ActiveRecordStoreTest < ActionController::IntegrationTest
- DispatcherApp = ActionController::Dispatcher.new
- SessionApp = ActiveRecord::SessionStore.new(DispatcherApp,
- :key => '_session_id')
- SessionAppWithFixation = ActiveRecord::SessionStore.new(DispatcherApp,
- :key => '_session_id', :cookie_only => false)
-
class TestController < ActionController::Base
def no_session_access
head :ok
@@ -39,7 +33,7 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
def setup
ActiveRecord::SessionStore.session_class.create_table!
- @integration_session = open_session(SessionApp)
+ reset_app!
end
def teardown
@@ -138,9 +132,9 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
end
def test_allows_session_fixation
- @integration_session = open_session(SessionAppWithFixation)
-
with_test_route_set do
+ reset_with_fixation!
+
get '/set_session_value'
assert_response :success
assert cookies['_session_id']
@@ -151,8 +145,7 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
session_id = cookies['_session_id']
assert session_id
- reset!
- @integration_session = open_session(SessionAppWithFixation)
+ reset_with_fixation!
get '/set_session_value', :_session_id => session_id, :foo => "baz"
assert_response :success
@@ -166,6 +159,16 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
end
private
+ def reset_app!
+ app = ActiveRecord::SessionStore.new(ActionController::Dispatcher.new, :key => '_session_id')
+ @integration_session = open_session(app)
+ end
+
+ def reset_with_fixation!
+ app = ActiveRecord::SessionStore.new(ActionController::Dispatcher.new, :key => '_session_id', :cookie_only => false)
+ @integration_session = open_session(app)
+ end
+
def with_test_route_set
with_routing do |set|
set.draw do |map|
diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb
index 06827e5fbc..453812c128 100644
--- a/actionpack/test/controller/action_pack_assertions_test.rb
+++ b/actionpack/test/controller/action_pack_assertions_test.rb
@@ -182,14 +182,6 @@ end
# a test case to exercise the new capabilities TestRequest & TestResponse
class ActionPackAssertionsControllerTest < ActionController::TestCase
- # let's get this party started
- def setup
- super
-
- ActionController::Routing.use_controllers!(%w(action_pack_assertions admin/inner_module user content admin/user))
- ActionController::Routing::Routes.load_routes!
- end
-
# -- assertion-based testing ------------------------------------------------
def test_assert_tag_and_url_for
diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb
index 5be780dd42..d20684296f 100644
--- a/actionpack/test/controller/routing_test.rb
+++ b/actionpack/test/controller/routing_test.rb
@@ -44,11 +44,11 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase
end
def test_route_recognition_unescapes_path_components
- options = { :controller => "controller",
+ options = { :controller => "content",
:action => "act#{@segment}ion",
:variable => "var#{@segment}iable",
:additional => ["add#{@segment}itional-1", "add#{@segment}itional-2"] }
- assert_equal options, @set.recognize_path("/controller/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2")
+ assert_equal options, @set.recognize_path("/content/act#{@escaped}ion/var#{@escaped}iable/add#{@escaped}itional-1/add#{@escaped}itional-2")
end
def test_route_generation_allows_passing_non_string_values_to_generated_helper
@@ -60,58 +60,6 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase
end
class RoutingTest < Test::Unit::TestCase
- def test_possible_controllers
- true_controller_paths = ActionController::Routing.controller_paths
-
- ActionController::Routing.use_controllers! nil
-
- Object.send(:remove_const, :RAILS_ROOT) if defined?(::RAILS_ROOT)
- Object.const_set(:RAILS_ROOT, File.dirname(__FILE__) + '/controller_fixtures')
-
- ActionController::Routing.controller_paths = [
- RAILS_ROOT, RAILS_ROOT + '/app/controllers', RAILS_ROOT + '/vendor/plugins/bad_plugin/lib'
- ]
-
- assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
- ensure
- if true_controller_paths
- ActionController::Routing.controller_paths = true_controller_paths
- end
- ActionController::Routing.use_controllers! nil
- Object.send(:remove_const, :RAILS_ROOT) rescue nil
- end
-
- def test_possible_controllers_are_reset_on_each_load
- true_possible_controllers = ActionController::Routing.possible_controllers
- true_controller_paths = ActionController::Routing.controller_paths
-
- ActionController::Routing.use_controllers! nil
- root = File.dirname(__FILE__) + '/controller_fixtures'
-
- ActionController::Routing.controller_paths = []
- assert_equal [], ActionController::Routing.possible_controllers
-
- ActionController::Routing.controller_paths = [
- root, root + '/app/controllers', root + '/vendor/plugins/bad_plugin/lib'
- ]
- ActionController::Routing::Routes.load!
-
- assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
- ensure
- ActionController::Routing.controller_paths = true_controller_paths
- ActionController::Routing.use_controllers! true_possible_controllers
- Object.send(:remove_const, :RAILS_ROOT) rescue nil
-
- ActionController::Routing::Routes.reload!
- end
-
- def test_with_controllers
- c = %w(admin/accounts admin/users account pages)
- ActionController::Routing.with_controllers c do
- assert_equal c, ActionController::Routing.possible_controllers
- end
- end
-
def test_normalize_unix_paths
load_paths = %w(. config/../app/controllers config/../app//helpers script/../config/../vendor/rails/actionpack/lib vendor/rails/railties/builtin/rails_info app/models lib script/../config/../foo/bar/../../app/models .foo/../.bar foo.bar/../config)
paths = ActionController::Routing.normalize_paths(load_paths)
@@ -1815,22 +1763,20 @@ class RouteSetTest < ActiveSupport::TestCase
end
def test_slashes_are_implied
- ActionController::Routing.with_controllers(['foo']) do
- ['/:controller/:action/:id/', '/:controller/:action/:id',
- ':controller/:action/:id', '/:controller/:action/:id/'
- ].each do |path|
- @set = nil
- set.draw { |map| map.connect(path) }
-
- assert_equal '/foo', set.generate(:controller => 'foo', :action => 'index')
- assert_equal '/foo/list', set.generate(:controller => 'foo', :action => 'list')
- assert_equal '/foo/show/1', set.generate(:controller => 'foo', :action => 'show', :id => '1')
-
- assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/foo'))
- assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/foo/index'))
- assert_equal({:controller => "foo", :action => "list"}, set.recognize_path('/foo/list'))
- assert_equal({:controller => "foo", :action => "show", :id => "1"}, set.recognize_path('/foo/show/1'))
- end
+ ['/:controller/:action/:id/', '/:controller/:action/:id',
+ ':controller/:action/:id', '/:controller/:action/:id/'
+ ].each do |path|
+ @set = nil
+ set.draw { |map| map.connect(path) }
+
+ assert_equal '/content', set.generate(:controller => 'content', :action => 'index')
+ assert_equal '/content/list', set.generate(:controller => 'content', :action => 'list')
+ assert_equal '/content/show/1', set.generate(:controller => 'content', :action => 'show', :id => '1')
+
+ assert_equal({:controller => "content", :action => "index"}, set.recognize_path('/content'))
+ assert_equal({:controller => "content", :action => "index"}, set.recognize_path('/content/index'))
+ assert_equal({:controller => "content", :action => "list"}, set.recognize_path('/content/list'))
+ assert_equal({:controller => "content", :action => "show", :id => "1"}, set.recognize_path('/content/show/1'))
end
end
diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb
index 84c97851ee..73870a56bb 100644
--- a/actionpack/test/controller/test_test.rb
+++ b/actionpack/test/controller/test_test.rb
@@ -123,9 +123,6 @@ XML
@controller = TestController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
-
- ActionController::Routing.use_controllers! %w(content admin/user test_test/test)
- ActionController::Routing::Routes.load_routes!
end
def test_raw_post_handling
diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb
index ad915e7a57..9b8d07222b 100644
--- a/actionpack/test/controller/url_rewriter_test.rb
+++ b/actionpack/test/controller/url_rewriter_test.rb
@@ -46,6 +46,20 @@ class UrlRewriterTests < ActionController::TestCase
)
end
+ def test_anchor_should_call_to_param
+ assert_equal(
+ 'http://test.host/c/a/i#anchor',
+ @rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anchor'))
+ )
+ end
+
+ def test_anchor_should_be_cgi_escaped
+ assert_equal(
+ 'http://test.host/c/a/i#anc%2Fhor',
+ @rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anc/hor'))
+ )
+ end
+
def test_overwrite_params
@params[:controller] = 'hi'
@params[:action] = 'bye'
@@ -110,6 +124,18 @@ class UrlWriterTests < ActionController::TestCase
)
end
+ def test_anchor_should_call_to_param
+ assert_equal('/c/a#anchor',
+ W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anchor'))
+ )
+ end
+
+ def test_anchor_should_be_cgi_escaped
+ assert_equal('/c/a#anc%2Fhor',
+ W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :anchor => Struct.new(:to_param).new('anc/hor'))
+ )
+ end
+
def test_default_host
add_host!
assert_equal('http://www.basecamphq.com/c/a/i',
diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb
index 3fded34d78..916124e221 100644
--- a/actionpack/test/controller/webservice_test.rb
+++ b/actionpack/test/controller/webservice_test.rb
@@ -259,6 +259,7 @@ class WebServiceTest < ActionController::IntegrationTest
c.connect "/", :action => "assign_parameters"
end
end
+ reset!
yield
end
end
diff --git a/actionpack/test/dispatch/request/json_params_parsing_test.rb b/actionpack/test/dispatch/request/json_params_parsing_test.rb
index db6cf7b330..995f36bb29 100644
--- a/actionpack/test/dispatch/request/json_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/json_params_parsing_test.rb
@@ -59,6 +59,7 @@ class JsonParamsParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "json_params_parsing_test/test"
end
+ reset!
yield
end
end
diff --git a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
index 301080842e..d4ee4362eb 100644
--- a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
@@ -153,6 +153,7 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "multipart_params_parsing_test/test"
end
+ reset!
yield
end
end
diff --git a/actionpack/test/dispatch/request/query_string_parsing_test.rb b/actionpack/test/dispatch/request/query_string_parsing_test.rb
index a31e326ddf..2261934e45 100644
--- a/actionpack/test/dispatch/request/query_string_parsing_test.rb
+++ b/actionpack/test/dispatch/request/query_string_parsing_test.rb
@@ -111,6 +111,7 @@ class QueryStringParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "query_string_parsing_test/test"
end
+ reset!
get "/parse", actual
assert_response :ok
diff --git a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb
index 7167cdafac..6c9967d26e 100644
--- a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb
@@ -132,6 +132,7 @@ class UrlEncodedParamsParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "url_encoded_params_parsing_test/test"
end
+ reset!
yield
end
end
diff --git a/actionpack/test/dispatch/request/xml_params_parsing_test.rb b/actionpack/test/dispatch/request/xml_params_parsing_test.rb
index 521002b519..2f2dd695c4 100644
--- a/actionpack/test/dispatch/request/xml_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/xml_params_parsing_test.rb
@@ -86,6 +86,7 @@ class XmlParamsParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "xml_params_parsing_test/test"
end
+ reset!
yield
end
end
diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb
index 2db76818ac..0723a76d2b 100644
--- a/actionpack/test/dispatch/session/cookie_store_test.rb
+++ b/actionpack/test/dispatch/session/cookie_store_test.rb
@@ -8,10 +8,6 @@ class CookieStoreTest < ActionController::IntegrationTest
# 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)
-
Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1')
SignedBar = Verifier.generate(:foo => "bar", :session_id => ActiveSupport::SecureRandom.hex(16))
@@ -51,7 +47,7 @@ class CookieStoreTest < ActionController::IntegrationTest
end
def setup
- @integration_session = open_session(CookieStoreApp)
+ reset_app!
end
def test_raises_argument_error_if_missing_session_key
@@ -197,10 +193,10 @@ class CookieStoreTest < ActionController::IntegrationTest
end
def test_session_store_with_expire_after
- app = ActionDispatch::Session::CookieStore.new(DispatcherApp, :key => SessionKey, :secret => SessionSecret, :expire_after => 5.hours)
- @integration_session = open_session(app)
-
with_test_route_set do
+ app = ActionDispatch::Session::CookieStore.new(ActionController::Dispatcher.new, :key => SessionKey, :secret => SessionSecret, :expire_after => 5.hours)
+ @integration_session = open_session(app)
+
# First request accesses the session
time = Time.local(2008, 4, 24)
Time.stubs(:now).returns(time)
@@ -230,6 +226,12 @@ class CookieStoreTest < ActionController::IntegrationTest
end
private
+ def reset_app!
+ app = ActionDispatch::Session::CookieStore.new(ActionController::Dispatcher.new,
+ :key => SessionKey, :secret => SessionSecret)
+ @integration_session = open_session(app)
+ end
+
def with_test_route_set
with_routing do |set|
set.draw do |map|
@@ -237,6 +239,7 @@ class CookieStoreTest < ActionController::IntegrationTest
c.connect "/:action"
end
end
+ reset_app!
yield
end
end
diff --git a/actionpack/test/dispatch/session/mem_cache_store_test.rb b/actionpack/test/dispatch/session/mem_cache_store_test.rb
index 7561c93e4a..1588918be7 100644
--- a/actionpack/test/dispatch/session/mem_cache_store_test.rb
+++ b/actionpack/test/dispatch/session/mem_cache_store_test.rb
@@ -32,14 +32,7 @@ class MemCacheStoreTest < ActionController::IntegrationTest
end
begin
- DispatcherApp = ActionController::Dispatcher.new
- MemCacheStoreApp = ActionDispatch::Session::MemCacheStore.new(
- DispatcherApp, :key => '_session_id')
-
-
- def setup
- @integration_session = open_session(MemCacheStoreApp)
- end
+ App = ActionDispatch::Session::MemCacheStore.new(ActionController::Dispatcher.new, :key => '_session_id')
def test_setting_and_getting_session_value
with_test_route_set do
@@ -114,6 +107,12 @@ class MemCacheStoreTest < ActionController::IntegrationTest
end
private
+ def reset_app!
+ app = ActionDispatch::Session::MemCacheStore.new(
+ ActionController::Dispatcher.new, :key => '_session_id')
+ @integration_session = open_session(app)
+ end
+
def with_test_route_set
with_routing do |set|
set.draw do |map|
@@ -121,6 +120,7 @@ class MemCacheStoreTest < ActionController::IntegrationTest
c.connect "/:action"
end
end
+ reset_app!
yield
end
end
diff --git a/actionpack/test/lib/controller/fake_controllers.rb b/actionpack/test/lib/controller/fake_controllers.rb
index 75c114c103..6e02e2d21b 100644
--- a/actionpack/test/lib/controller/fake_controllers.rb
+++ b/actionpack/test/lib/controller/fake_controllers.rb
@@ -1,15 +1,16 @@
class << Object; alias_method :const_available?, :const_defined?; end
-
-class ContentController < Class.new(ActionController::Base)
+
+class ContentController < 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
+ class UserController < ActionController::Base; end
+ class NewsFeedController < ActionController::Base; end
end
+
# For speed test
class SpeedController < ActionController::Base; end
class SearchController < SpeedController; end
diff --git a/actionpack/test/new_base/metal_test.rb b/actionpack/test/new_base/metal_test.rb
index c7c45b5cc9..2b7720863a 100644
--- a/actionpack/test/new_base/metal_test.rb
+++ b/actionpack/test/new_base/metal_test.rb
@@ -1,13 +1,12 @@
require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
module MetalTest
- class MetalMiddleware < ActionController::Metal
- def index
+ class MetalMiddleware < ActionController::Middleware
+ def call(env)
if env["PATH_INFO"] =~ /authed/
- self.response = app.call(env)
+ app.call(env)
else
- self.response_body = "Not authed!"
- self.status = 401
+ [401, headers, "Not authed!"]
end
end
end
@@ -21,7 +20,7 @@ module MetalTest
class TestMiddleware < ActiveSupport::TestCase
def setup
@app = Rack::Builder.new do
- use MetalMiddleware.middleware(:index)
+ use MetalMiddleware
run Endpoint.new
end.to_app
end
diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb
index 9271b2dd59..b7ccd3db8d 100644
--- a/actionpack/test/new_base/test_helper.rb
+++ b/actionpack/test/new_base/test_helper.rb
@@ -35,12 +35,6 @@ 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)
end
def app
@@ -91,10 +85,26 @@ end
class ::ApplicationController < ActionController::Base
end
+module ActionController
+ class << Routing
+ def possible_controllers
+ @@possible_controllers ||= []
+ end
+ end
+
+ class Base
+ def self.inherited(klass)
+ name = klass.name.underscore.sub(/_controller$/, '')
+ ActionController::Routing.possible_controllers << name unless name.blank?
+ super
+ end
+ end
+end
+
class SimpleRouteCase < Rack::TestCase
setup do
ActionController::Routing::Routes.draw do |map|
map.connect ':controller/:action/:id'
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/template/form_options_helper_i18n_test.rb b/actionpack/test/template/form_options_helper_i18n_test.rb
new file mode 100644
index 0000000000..91e370efa7
--- /dev/null
+++ b/actionpack/test/template/form_options_helper_i18n_test.rb
@@ -0,0 +1,27 @@
+require 'abstract_unit'
+
+class FormOptionsHelperI18nTests < ActionView::TestCase
+ tests ActionView::Helpers::FormOptionsHelper
+
+ def setup
+ @prompt_message = 'Select!'
+ I18n.backend.send(:init_translations)
+ I18n.backend.store_translations :en, :support => { :select => { :prompt => @prompt_message } }
+ end
+
+ def teardown
+ I18n.backend = I18n::Backend::Simple.new
+ end
+
+ def test_select_with_prompt_true_translates_prompt_message
+ I18n.expects(:translate).with('support.select.prompt', { :default => 'Please select' })
+ select('post', 'category', [], :prompt => true)
+ end
+
+ def test_select_with_translated_prompt
+ assert_dom_equal(
+ %Q(<select id="post_category" name="post[category]"><option value="">#{@prompt_message}</option>\n</select>),
+ select('post', 'category', [], :prompt => true)
+ )
+ end
+end \ No newline at end of file
diff --git a/activerecord/Rakefile b/activerecord/Rakefile
index c4971e88b0..a9e4a92e37 100644
--- a/activerecord/Rakefile
+++ b/activerecord/Rakefile
@@ -24,17 +24,37 @@ PKG_FILES = FileList[
"lib/**/*", "test/**/*", "examples/**/*", "doc/**/*", "[A-Z]*", "install.rb", "Rakefile"
].exclude(/\bCVS\b|~$/)
+def run_without_aborting(*tasks)
+ errors = []
+
+ tasks.each do |task|
+ begin
+ Rake::Task[task].invoke
+ rescue Exception
+ errors << task
+ end
+ end
+
+ abort "Errors running #{errors.join(', ')}" if errors.any?
+end
desc 'Run mysql, sqlite, and postgresql tests by default'
task :default => :test
desc 'Run mysql, sqlite, and postgresql tests'
-task :test => defined?(JRUBY_VERSION) ?
- %w(test_jdbcmysql test_jdbcsqlite3 test_jdbcpostgresql) :
- %w(test_mysql test_sqlite3 test_postgresql)
-task :isolated_test => defined?(JRUBY_VERSION) ?
- %w(isolated_test_jdbcmysql isolated_test_jdbcsqlite3 isolated_test_jdbcpostgresql) :
- %w(isolated_test_mysql isolated_test_sqlite3 isolated_test_postgresql)
+task :test do
+ tasks = defined?(JRUBY_VERSION) ?
+ %w(test_jdbcmysql test_jdbcsqlite3 test_jdbcpostgresql) :
+ %w(test_mysql test_sqlite3 test_postgresql)
+ run_without_aborting(*tasks)
+end
+
+task :isolated_test do
+ tasks = defined?(JRUBY_VERSION) ?
+ %w(isolated_test_jdbcmysql isolated_test_jdbcsqlite3 isolated_test_jdbcpostgresql) :
+ %w(isolated_test_mysql isolated_test_sqlite3 isolated_test_postgresql)
+ run_without_aborting(*tasks)
+end
%w( mysql postgresql sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
Rake::TestTask.new("test_#{adapter}") { |t|
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 6eeeddc9e1..99b812b5fc 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -622,7 +622,8 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
targets.each do |target|
join_fixtures["#{label}_#{target}"] = Fixture.new(
{ association.primary_key_name => row[primary_key_name],
- association.association_foreign_key => Fixtures.identify(target) }, nil)
+ association.association_foreign_key => Fixtures.identify(target) },
+ nil, @connection)
end
end
end
@@ -706,12 +707,12 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
yaml_value.each do |fixture|
raise Fixture::FormatError, "Bad data for #{@class_name} fixture named #{fixture}" unless fixture.respond_to?(:each)
- fixture.each do |name, data|
+ fixture.each do |name, data|
unless data
raise Fixture::FormatError, "Bad data for #{@class_name} fixture named #{name} (nil)"
end
- self[name] = Fixture.new(data, model_class)
+ self[name] = Fixture.new(data, model_class, @connection)
end
end
end
@@ -724,7 +725,7 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
reader.each do |row|
data = {}
row.each_with_index { |cell, j| data[header[j].to_s.strip] = cell.to_s.strip }
- self["#{@class_name.to_s.underscore}_#{i+=1}"] = Fixture.new(data, model_class)
+ self["#{@class_name.to_s.underscore}_#{i+=1}"] = Fixture.new(data, model_class, @connection)
end
end
@@ -762,7 +763,8 @@ class Fixture #:nodoc:
attr_reader :model_class
- def initialize(fixture, model_class)
+ def initialize(fixture, model_class, connection = ActiveRecord::Base.connection)
+ @connection = connection
@fixture = fixture
@model_class = model_class.is_a?(Class) ? model_class : model_class.constantize rescue nil
end
@@ -784,14 +786,14 @@ class Fixture #:nodoc:
end
def key_list
- columns = @fixture.keys.collect{ |column_name| ActiveRecord::Base.connection.quote_column_name(column_name) }
+ columns = @fixture.keys.collect{ |column_name| @connection.quote_column_name(column_name) }
columns.join(", ")
end
def value_list
list = @fixture.inject([]) do |fixtures, (key, value)|
col = model_class.columns_hash[key] if model_class.respond_to?(:ancestors) && model_class.ancestors.include?(ActiveRecord::Base)
- fixtures << ActiveRecord::Base.connection.quote(value, col).gsub('[^\]\\n', "\n").gsub('[^\]\\r', "\r")
+ fixtures << @connection.quote(value, col).gsub('[^\]\\n', "\n").gsub('[^\]\\r', "\r")
end
list * ', '
end
diff --git a/activerecord/lib/active_record/locale/en.yml b/activerecord/lib/active_record/locale/en.yml
index bf8a71d236..092f5f0023 100644
--- a/activerecord/lib/active_record/locale/en.yml
+++ b/activerecord/lib/active_record/locale/en.yml
@@ -23,6 +23,7 @@ en:
less_than_or_equal_to: "must be less than or equal to {{count}}"
odd: "must be odd"
even: "must be even"
+ record_invalid: "Validation failed: {{errors}}"
# Append your own errors here or at the model/attributes scope.
# You can define own errors for models or model attributes.
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index a7fa98756e..5fc41cf054 100644
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -12,7 +12,8 @@ module ActiveRecord
attr_reader :record
def initialize(record)
@record = record
- super("Validation failed: #{@record.errors.full_messages.join(", ")}")
+ errors = @record.errors.full_messages.join(I18n.t('support.array.words_connector', :default => ', '))
+ super(I18n.t('activerecord.errors.messages.record_invalid', :errors => errors))
end
end
diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb
index 0303147e50..73d9c7249c 100644
--- a/activerecord/test/cases/validations/i18n_validation_test.rb
+++ b/activerecord/test/cases/validations/i18n_validation_test.rb
@@ -709,3 +709,191 @@ class I18nValidationTest < ActiveRecord::TestCase
assert_equal ["I am a custom error"], @topic.errors[:title]
end
end
+
+class ActiveRecordValidationsGenerateMessageI18nTests < ActiveSupport::TestCase
+ def setup
+ reset_callbacks Topic
+ @topic = Topic.new
+ I18n.backend.store_translations :'en', {
+ :activerecord => {
+ :errors => {
+ :messages => {
+ :inclusion => "is not included in the list",
+ :exclusion => "is reserved",
+ :invalid => "is invalid",
+ :confirmation => "doesn't match confirmation",
+ :accepted => "must be accepted",
+ :empty => "can't be empty",
+ :blank => "can't be blank",
+ :too_long => "is too long (maximum is {{count}} characters)",
+ :too_short => "is too short (minimum is {{count}} characters)",
+ :wrong_length => "is the wrong length (should be {{count}} characters)",
+ :taken => "has already been taken",
+ :not_a_number => "is not a number",
+ :greater_than => "must be greater than {{count}}",
+ :greater_than_or_equal_to => "must be greater than or equal to {{count}}",
+ :equal_to => "must be equal to {{count}}",
+ :less_than => "must be less than {{count}}",
+ :less_than_or_equal_to => "must be less than or equal to {{count}}",
+ :odd => "must be odd",
+ :even => "must be even"
+ }
+ }
+ }
+ }
+ end
+
+ def reset_callbacks(*models)
+ models.each do |model|
+ model.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ model.instance_variable_set("@validate_on_create_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ model.instance_variable_set("@validate_on_update_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ end
+ end
+
+ # validates_inclusion_of: generate_message(attr_name, :inclusion, :default => configuration[:message], :value => value)
+ def test_generate_message_inclusion_with_default_message
+ assert_equal 'is not included in the list', @topic.errors.generate_message(:title, :inclusion, :default => nil, :value => 'title')
+ end
+
+ def test_generate_message_inclusion_with_custom_message
+ assert_equal 'custom message title', @topic.errors.generate_message(:title, :inclusion, :default => 'custom message {{value}}', :value => 'title')
+ end
+
+ # validates_exclusion_of: generate_message(attr_name, :exclusion, :default => configuration[:message], :value => value)
+ def test_generate_message_exclusion_with_default_message
+ assert_equal 'is reserved', @topic.errors.generate_message(:title, :exclusion, :default => nil, :value => 'title')
+ end
+
+ def test_generate_message_exclusion_with_custom_message
+ assert_equal 'custom message title', @topic.errors.generate_message(:title, :exclusion, :default => 'custom message {{value}}', :value => 'title')
+ end
+
+ # validates_associated: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value)
+ # validates_format_of: generate_message(attr_name, :invalid, :default => configuration[:message], :value => value)
+ def test_generate_message_invalid_with_default_message
+ assert_equal 'is invalid', @topic.errors.generate_message(:title, :invalid, :default => nil, :value => 'title')
+ end
+
+ def test_generate_message_invalid_with_custom_message
+ assert_equal 'custom message title', @topic.errors.generate_message(:title, :invalid, :default => 'custom message {{value}}', :value => 'title')
+ end
+
+ # validates_confirmation_of: generate_message(attr_name, :confirmation, :default => configuration[:message])
+ def test_generate_message_confirmation_with_default_message
+ assert_equal "doesn't match confirmation", @topic.errors.generate_message(:title, :confirmation, :default => nil)
+ end
+
+ def test_generate_message_confirmation_with_custom_message
+ assert_equal 'custom message', @topic.errors.generate_message(:title, :confirmation, :default => 'custom message')
+ end
+
+ # validates_acceptance_of: generate_message(attr_name, :accepted, :default => configuration[:message])
+ def test_generate_message_accepted_with_default_message
+ assert_equal "must be accepted", @topic.errors.generate_message(:title, :accepted, :default => nil)
+ end
+
+ def test_generate_message_accepted_with_custom_message
+ assert_equal 'custom message', @topic.errors.generate_message(:title, :accepted, :default => 'custom message')
+ end
+
+ # add_on_empty: generate_message(attr, :empty, :default => custom_message)
+ def test_generate_message_empty_with_default_message
+ assert_equal "can't be empty", @topic.errors.generate_message(:title, :empty, :default => nil)
+ end
+
+ def test_generate_message_empty_with_custom_message
+ assert_equal 'custom message', @topic.errors.generate_message(:title, :empty, :default => 'custom message')
+ end
+
+ # add_on_blank: generate_message(attr, :blank, :default => custom_message)
+ def test_generate_message_blank_with_default_message
+ assert_equal "can't be blank", @topic.errors.generate_message(:title, :blank, :default => nil)
+ end
+
+ def test_generate_message_blank_with_custom_message
+ assert_equal 'custom message', @topic.errors.generate_message(:title, :blank, :default => 'custom message')
+ end
+
+ # validates_length_of: generate_message(attr, :too_long, :default => options[:too_long], :count => option_value.end)
+ def test_generate_message_too_long_with_default_message
+ assert_equal "is too long (maximum is 10 characters)", @topic.errors.generate_message(:title, :too_long, :default => nil, :count => 10)
+ end
+
+ def test_generate_message_too_long_with_custom_message
+ assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_long, :default => 'custom message {{count}}', :count => 10)
+ end
+
+ # validates_length_of: generate_message(attr, :too_short, :default => options[:too_short], :count => option_value.begin)
+ def test_generate_message_too_short_with_default_message
+ assert_equal "is too short (minimum is 10 characters)", @topic.errors.generate_message(:title, :too_short, :default => nil, :count => 10)
+ end
+
+ def test_generate_message_too_short_with_custom_message
+ assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_short, :default => 'custom message {{count}}', :count => 10)
+ end
+
+ # validates_length_of: generate_message(attr, key, :default => custom_message, :count => option_value)
+ def test_generate_message_wrong_length_with_default_message
+ assert_equal "is the wrong length (should be 10 characters)", @topic.errors.generate_message(:title, :wrong_length, :default => nil, :count => 10)
+ end
+
+ def test_generate_message_wrong_length_with_custom_message
+ assert_equal 'custom message 10', @topic.errors.generate_message(:title, :wrong_length, :default => 'custom message {{count}}', :count => 10)
+ end
+
+ # validates_uniqueness_of: generate_message(attr_name, :taken, :default => configuration[:message])
+ def test_generate_message_taken_with_default_message
+ assert_equal "has already been taken", @topic.errors.generate_message(:title, :taken, :default => nil, :value => 'title')
+ end
+
+ def test_generate_message_taken_with_custom_message
+ assert_equal 'custom message title', @topic.errors.generate_message(:title, :taken, :default => 'custom message {{value}}', :value => 'title')
+ end
+
+ # validates_numericality_of: generate_message(attr_name, :not_a_number, :value => raw_value, :default => configuration[:message])
+ def test_generate_message_not_a_number_with_default_message
+ assert_equal "is not a number", @topic.errors.generate_message(:title, :not_a_number, :default => nil, :value => 'title')
+ end
+
+ def test_generate_message_not_a_number_with_custom_message
+ assert_equal 'custom message title', @topic.errors.generate_message(:title, :not_a_number, :default => 'custom message {{value}}', :value => 'title')
+ end
+
+ # validates_numericality_of: generate_message(attr_name, option, :value => raw_value, :default => configuration[:message])
+ def test_generate_message_greater_than_with_default_message
+ assert_equal "must be greater than 10", @topic.errors.generate_message(:title, :greater_than, :default => nil, :value => 'title', :count => 10)
+ end
+
+ def test_generate_message_greater_than_or_equal_to_with_default_message
+ assert_equal "must be greater than or equal to 10", @topic.errors.generate_message(:title, :greater_than_or_equal_to, :default => nil, :value => 'title', :count => 10)
+ end
+
+ def test_generate_message_equal_to_with_default_message
+ assert_equal "must be equal to 10", @topic.errors.generate_message(:title, :equal_to, :default => nil, :value => 'title', :count => 10)
+ end
+
+ def test_generate_message_less_than_with_default_message
+ assert_equal "must be less than 10", @topic.errors.generate_message(:title, :less_than, :default => nil, :value => 'title', :count => 10)
+ end
+
+ def test_generate_message_less_than_or_equal_to_with_default_message
+ assert_equal "must be less than or equal to 10", @topic.errors.generate_message(:title, :less_than_or_equal_to, :default => nil, :value => 'title', :count => 10)
+ end
+
+ def test_generate_message_odd_with_default_message
+ assert_equal "must be odd", @topic.errors.generate_message(:title, :odd, :default => nil, :value => 'title', :count => 10)
+ end
+
+ def test_generate_message_even_with_default_message
+ assert_equal "must be even", @topic.errors.generate_message(:title, :even, :default => nil, :value => 'title', :count => 10)
+ end
+ # ActiveRecord#RecordInvalid exception
+
+ test "RecordInvalid exception can be localized" do
+ topic = Topic.new
+ topic.errors.add(:title, :invalid)
+ topic.errors.add(:title, :blank)
+ assert_equal "Validation failed: Title is invalid, Title can't be blank", ActiveRecord::RecordInvalid.new(topic).message
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/regexp.rb b/activesupport/lib/active_support/core_ext/regexp.rb
index 1a04c70d87..95d06ee6ee 100644
--- a/activesupport/lib/active_support/core_ext/regexp.rb
+++ b/activesupport/lib/active_support/core_ext/regexp.rb
@@ -9,6 +9,8 @@ class Regexp #:nodoc:
class << self
def optionalize(pattern)
+ return pattern if pattern == ""
+
case unoptionalize(pattern)
when /\A(.|\(.*\))\Z/ then "#{pattern}?"
else "(?:#{pattern})?"
diff --git a/activesupport/test/core_ext/regexp_ext_test.rb b/activesupport/test/core_ext/regexp_ext_test.rb
index f71099856d..e2d9140bca 100644
--- a/activesupport/test/core_ext/regexp_ext_test.rb
+++ b/activesupport/test/core_ext/regexp_ext_test.rb
@@ -7,20 +7,20 @@ class RegexpExtAccessTests < Test::Unit::TestCase
end
def test_multiline
- assert //m.multiline?
- assert ! //.multiline?
- assert ! /(?m:)/.multiline?
+ assert_equal true, //m.multiline?
+ assert_equal false, //.multiline?
+ assert_equal false, /(?m:)/.multiline?
end
def test_optionalize
- assert "a?", Regexp.optionalize("a")
- assert "(?:foo)?", Regexp.optionalize("foo")
- assert "", Regexp.optionalize("")
+ assert_equal "a?", Regexp.optionalize("a")
+ assert_equal "(?:foo)?", Regexp.optionalize("foo")
+ assert_equal "", Regexp.optionalize("")
end
def test_unoptionalize
- assert "a", Regexp.unoptionalize("a?")
- assert "foo", Regexp.unoptionalize("(?:foo)")
- assert "", Regexp.unoptionalize("")
+ assert_equal "a", Regexp.unoptionalize("a?")
+ assert_equal "foo", Regexp.unoptionalize("(?:foo)?")
+ assert_equal "", Regexp.unoptionalize("")
end
end \ No newline at end of file