diff options
Diffstat (limited to 'railties')
26 files changed, 281 insertions, 167 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 960b1ed8ca..e7994e45c6 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -20,6 +20,11 @@ * Rails::Plugin has gone. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies. *Santiago Pastorino* +## Rails 3.2.2 (March 1, 2012) ## + +* No changes. + + ## Rails 3.2.1 (January 26, 2012) ## * Documentation fixes. diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile index f007629207..42120e9bad 100644 --- a/railties/guides/source/action_view_overview.textile +++ b/railties/guides/source/action_view_overview.textile @@ -431,11 +431,11 @@ form("post") <form action='/posts/create' method='post'> <p> <label for="post_title">Title</label><br /> - <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> + <input id="post_title" name="post[title]" type="text" value="Hello World" /> </p> <p> <label for="post_body">Body</label><br /> - <textarea cols="40" id="post_body" name="post[body]" rows="20"></textarea> + <textarea id="post_body" name="post[body]"></textarea> </p> <input name="commit" type="submit" value="Create" /> </form> @@ -451,7 +451,7 @@ For example, if +@post+ has an attribute +title+ mapped to a +String+ column tha <ruby> input("post", "title") # => - <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> + <input id="post_title" name="post[title]" type="text" value="Hello World" /> </ruby> h4. RecordTagHelper @@ -987,8 +987,8 @@ The HTML generated for this would be: <html> <form action="/persons/create" method="post"> - <input id="person_first_name" name="person[first_name]" size="30" type="text" /> - <input id="person_last_name" name="person[last_name]" size="30" type="text" /> + <input id="person_first_name" name="person[first_name]" type="text" /> + <input id="person_last_name" name="person[last_name]" type="text" /> <input name="commit" type="submit" value="Create" /> </form> </html> diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile index d9a62f7574..8e23a577e2 100644 --- a/railties/guides/source/active_record_querying.textile +++ b/railties/guides/source/active_record_querying.textile @@ -1133,6 +1133,8 @@ Client.where(:first_name => 'Andy').first_or_create!(:locked => false) # => ActiveRecord::RecordInvalid: Validation failed: Orders count can't be blank </ruby> +As with +first_or_create+ there is a +find_or_create_by!+ method but the +first_or_create!+ method is preferred for clarity. + h4. +first_or_initialize+ The +first_or_initialize+ method will work just like +first_or_create+ but it will not call +create+ but +new+. This means that a new model instance will be created in memory but won't be saved to the database. Continuing with the +first_or_create+ example, we now want the client named 'Nick': diff --git a/railties/guides/source/api_app.textile b/railties/guides/source/api_app.textile index f2d00c5768..9bbf7b36b1 100644 --- a/railties/guides/source/api_app.textile +++ b/railties/guides/source/api_app.textile @@ -13,15 +13,14 @@ endprologue. h3. What is an API app? -Traditionally, when people said that they used Rails as an "API", they meant -providing a programmatically accessible API alongside their web application. +Traditionally, when people said that they used Rails as an "API", they meant providing a programmatically accessible API alongside their web application. For example, GitHub provides "an API":http://developer.github.com that you can use from your own custom clients. With the advent of client-side frameworks, more developers are using Rails to build a backend that is shared between their web application and other native applications. For example, Twitter uses its "public API":https://dev.twitter.com in its web application, which is built as a static site that consumes JSON resources. -Instead of using Rails to generate dynamic HTML that will communicate with the server through forms and links, many developers are treating their web application as just another client, delivered as static HTML, CSS and JavaScript, and consuming a simple JSON API +Instead of using Rails to generate dynamic HTML that will communicate with the server through forms and links, many developers are treating their web application as just another client, delivered as static HTML, CSS and JavaScript, and consuming a simple JSON API This guide covers building a Rails application that serves JSON resources to an API client *or* client-side framework. @@ -72,13 +71,13 @@ If you're building a Rails application that will be an API server first and fore You can generate a new bare Rails app: <shell> -$ rails new my_api --api +$ rails new my_api --http </shell> This will do three main things for you: * Configure your application to start with a more limited set of middleware than normal. Specifically, it will not include any middleware primarily useful for browser applications (like cookie support) by default. -* Make +ApplicationController+ inherit from +ActionController::API+ instead of +ActionController::Base+. As with middleware, this will leave out any +ActionController+ modules that provide functionality primarily used by browser applications. +* Make +ApplicationController+ inherit from +ActionController::HTTP+ instead of +ActionController::Base+. As with middleware, this will leave out any +ActionController+ modules that provide functionality primarily used by browser applications. * Configure the generators to skip generating views, helpers and assets when you generate a new resource. If you want to take an existing app and make it an API app, follow the following steps. @@ -86,8 +85,8 @@ If you want to take an existing app and make it an API app, follow the following In +config/application.rb+ add the following lines at the top of the +Application+ class: <ruby> -config.middleware.api_only! -config.generators.api_only! +config.middleware.http_only! +config.generators.http_only! </ruby> Change +app/controllers/application_controller.rb+: @@ -98,7 +97,7 @@ class ApplicationController < ActionController::Base end # do -class ApplicationController < ActionController::API +class ApplicationController < ActionController::HTTP end </ruby> @@ -240,7 +239,7 @@ Keep in mind that removing these features may remove support for certain feature h3. Choosing Controller Modules -An API application (using +ActionController::API+) comes with the following controller modules by default: +An API application (using +ActionController::HTTP+) comes with the following controller modules by default: * +AbstractController::Translation+: Support for the +l+ and +t+ localization and translation methods. These delegate to +I18n.translate+ and +I18n.localize+. * +ActionController::UrlFor+: Makes +url_for+ and friends available. @@ -253,11 +252,11 @@ An API application (using +ActionController::API+) comes with the following cont * +AbstractController::Callbacks+: Support for +before_filter+ and friends * +ActionController::Instrumentation+: Support for the instrumentation hooks defined by +ActionController+ (see "the source":https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/instrumentation.rb for more). -Other plugins may add additional modules. You can get a list of all modules included into +ActionController::API+ in the rails console: +Other plugins may add additional modules. You can get a list of all modules included into +ActionController::HTTP+ in the rails console: <shell> $ irb ->> ActionController::API.ancestors - ActionController::Metal.ancestors +>> ActionController::HTTP.ancestors - ActionController::Metal.ancestors </shell> h4. Adding Other Modules diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile index 7a93a30702..d6e500fc4b 100644 --- a/railties/guides/source/configuring.textile +++ b/railties/guides/source/configuring.textile @@ -248,6 +248,14 @@ They can also be removed from the stack completely: config.middleware.delete ActionDispatch::BestStandardsSupport </ruby> +In addition to these methods to handle the stack, if your application is going to be used as an API endpoint only, the middleware stack can be configured like this: + +<ruby> +config.middleware.http_only! +</ruby> + +By doing this, Rails will create a smaller middleware stack, by not adding some middlewares that are usually useful for browser access only, such as Cookies, Session and Flash, BestStandardsSupport, and MethodOverride. You can always add any of them later manually if you want. Refer to the "API App docs":api_app.html for more info on how to setup your application for API only apps. + h4. Configuring i18n * +config.i18n.default_locale+ sets the default locale of an application used for i18n. Defaults to +:en+. diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile index dd993cc3b9..df8b16eb9e 100644 --- a/railties/guides/source/contributing_to_ruby_on_rails.textile +++ b/railties/guides/source/contributing_to_ruby_on_rails.textile @@ -309,7 +309,7 @@ Rails follows a simple set of coding style conventions. * Two spaces, no tabs. * No trailing whitespace. Blank lines should not have any space. -* Outdent private/protected from method definitions. Same indentation as the class/module. +* Indent after private/protected. * Prefer +&&+/+||+ over +and+/+or+. * Prefer class << self block over self.method for class methods. * +MyClass.my_method(my_arg)+ not +my_method( my_arg )+ or +my_method my_arg+. diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile index 9f91d12a54..8934667c5e 100644 --- a/railties/guides/source/form_helpers.textile +++ b/railties/guides/source/form_helpers.textile @@ -169,11 +169,11 @@ Output: <textarea id="message" name="message" cols="24" rows="6">Hi, nice site</textarea> <input id="password" name="password" type="password" /> <input id="parent_id" name="parent_id" type="hidden" value="5" /> -<input id="user_name" name="user[name]" size="30" type="search" /> -<input id="user_phone" name="user[phone]" size="30" type="tel" /> +<input id="user_name" name="user[name]" type="search" /> +<input id="user_phone" name="user[phone]" type="tel" /> <input id="user_born_on" name="user[born_on]" type="date" /> -<input id="user_homepage" size="30" name="user[homepage]" type="url" /> -<input id="user_address" size="30" name="user[address]" type="email" /> +<input id="user_homepage" name="user[homepage]" type="url" /> +<input id="user_address" name="user[address]" type="email" /> </html> Hidden inputs are not shown to the user but instead hold data like any textual input. Values inside them can be changed with JavaScript. @@ -239,7 +239,7 @@ The resulting HTML is: <html> <form accept-charset="UTF-8" action="/articles/create" method="post" class="nifty_form"> - <input id="article_title" name="article[title]" size="30" type="text" /> + <input id="article_title" name="article[title]" type="text" /> <textarea id="article_body" name="article[body]" cols="60" rows="12"></textarea> <input name="commit" type="submit" value="Create" /> </form> @@ -264,8 +264,8 @@ which produces the following output: <html> <form accept-charset="UTF-8" action="/people/create" class="new_person" id="new_person" method="post"> - <input id="person_name" name="person[name]" size="30" type="text" /> - <input id="contact_detail_phone_number" name="contact_detail[phone_number]" size="30" type="text" /> + <input id="person_name" name="person[name]" type="text" /> + <input id="contact_detail_phone_number" name="contact_detail[phone_number]" type="text" /> </form> </html> @@ -714,9 +714,9 @@ Assuming the person had two addresses, with ids 23 and 45 this would create outp <html> <form accept-charset="UTF-8" action="/people/1" class="edit_person" id="edit_person_1" method="post"> - <input id="person_name" name="person[name]" size="30" type="text" /> - <input id="person_address_23_city" name="person[address][23][city]" size="30" type="text" /> - <input id="person_address_45_city" name="person[address][45][city]" size="30" type="text" /> + <input id="person_name" name="person[name]" type="text" /> + <input id="person_address_23_city" name="person[address][23][city]" type="text" /> + <input id="person_address_45_city" name="person[address][45][city]" type="text" /> </form> </html> @@ -739,7 +739,7 @@ To create more intricate nestings, you can specify the first part of the input n will create inputs like <html> -<input id="person_address_primary_1_city" name="person[address][primary][1][city]" size="30" type="text" value="bologna" /> +<input id="person_address_primary_1_city" name="person[address][primary][1][city]" type="text" value="bologna" /> </html> As a general rule the final input name is the concatenation of the name given to +fields_for+/+form_for+, the index value and the name of the attribute. You can also pass an +:index+ option directly to helpers such as +text_field+, but it is usually less repetitive to specify this at the form builder level rather than on individual input controls. diff --git a/railties/guides/source/nested_model_forms.textile b/railties/guides/source/nested_model_forms.textile index 4b1fd2e0ac..82c9ab9d36 100644 --- a/railties/guides/source/nested_model_forms.textile +++ b/railties/guides/source/nested_model_forms.textile @@ -131,7 +131,7 @@ This will generate the following html: <html> <form action="/people" class="new_person" id="new_person" method="post"> - <input id="person_name" name="person[name]" size="30" type="text" /> + <input id="person_name" name="person[name]" type="text" /> </form> </html> @@ -153,9 +153,9 @@ This generates: <html> <form action="/people" class="new_person" id="new_person" method="post"> - <input id="person_name" name="person[name]" size="30" type="text" /> + <input id="person_name" name="person[name]" type="text" /> - <input id="person_address_attributes_street" name="person[address_attributes][street]" size="30" type="text" /> + <input id="person_address_attributes_street" name="person[address_attributes][street]" type="text" /> </form> </html> @@ -194,10 +194,10 @@ Which generates: <html> <form action="/people" class="new_person" id="new_person" method="post"> - <input id="person_name" name="person[name]" size="30" type="text" /> + <input id="person_name" name="person[name]" type="text" /> - <input id="person_projects_attributes_0_name" name="person[projects_attributes][0][name]" size="30" type="text" /> - <input id="person_projects_attributes_1_name" name="person[projects_attributes][1][name]" size="30" type="text" /> + <input id="person_projects_attributes_0_name" name="person[projects_attributes][0][name]" type="text" /> + <input id="person_projects_attributes_1_name" name="person[projects_attributes][1][name]" type="text" /> </form> </html> diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 10fa63c303..3191fe68a7 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -239,7 +239,7 @@ module Rails middleware.use ::Rack::Lock unless config.allow_concurrency middleware.use ::Rack::Runtime - middleware.use ::Rack::MethodOverride unless config.middleware.api_only? + middleware.use ::Rack::MethodOverride unless config.middleware.http_only? middleware.use ::ActionDispatch::RequestId middleware.use ::Rails::Rack::Logger, config.log_tags # must come after Rack::MethodOverride to properly log overridden methods middleware.use ::ActionDispatch::ShowExceptions, config.exceptions_app || ActionDispatch::PublicExceptions.new(Rails.public_path) @@ -252,9 +252,9 @@ module Rails end middleware.use ::ActionDispatch::Callbacks - middleware.use ::ActionDispatch::Cookies unless config.middleware.api_only? + middleware.use ::ActionDispatch::Cookies unless config.middleware.http_only? - if !config.middleware.api_only? && config.session_store + if !config.middleware.http_only? && config.session_store if config.force_ssl && !config.session_options.key?(:secure) config.session_options[:secure] = true end @@ -267,7 +267,7 @@ module Rails middleware.use ::Rack::ConditionalGet middleware.use ::Rack::ETag, "no-cache" - if !config.middleware.api_only? && config.action_dispatch.best_standards_support + if !config.middleware.http_only? && config.action_dispatch.best_standards_support middleware.use ::ActionDispatch::BestStandardsSupport, config.action_dispatch.best_standards_support end end diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb index 93a0fba10b..e567df7162 100644 --- a/railties/lib/rails/application/bootstrap.rb +++ b/railties/lib/rails/application/bootstrap.rb @@ -32,9 +32,9 @@ module Rails f.binmode f.sync = config.autoflush_log # if true make sure every write flushes - logger = ActiveSupport::TaggedLogging.new( - ActiveSupport::Logger.new(f) - ) + logger = ActiveSupport::Logger.new f + logger.formatter = config.log_formatter + logger = ActiveSupport::TaggedLogging.new(logger) logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase) logger rescue StandardError diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 0f5fc2b7bc..1cfcd30c5b 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -8,7 +8,7 @@ module Rails attr_accessor :allow_concurrency, :asset_host, :asset_path, :assets, :autoflush_log, :cache_classes, :cache_store, :consider_all_requests_local, :console, :dependency_loading, :exceptions_app, :file_watcher, :filter_parameters, - :force_ssl, :helpers_paths, :logger, :log_tags, :preload_frameworks, + :force_ssl, :helpers_paths, :logger, :log_formatter, :log_tags, :preload_frameworks, :railties_order, :relative_url_root, :secret_token, :serve_static_assets, :ssl_options, :static_cache_control, :session_options, :time_zone, :reload_classes_only_on_change, :use_schema_cache_dump @@ -41,6 +41,7 @@ module Rails @file_watcher = ActiveSupport::FileUpdateChecker @exceptions_app = nil @autoflush_log = true + @log_formatter = ActiveSupport::Logger::SimpleFormatter.new @use_schema_cache_dump = true @assets = ActiveSupport::OrderedOptions.new diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index 0b757cbe28..a608693ca4 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -71,6 +71,8 @@ module Rails wrapped_app # touch the app so the logger is set up console = ActiveSupport::Logger.new($stdout) + console.formatter = Rails.logger.formatter + Rails.logger.extend(ActiveSupport::Logger.broadcast(console)) end diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb index 0efa21d82c..d8185bcb34 100644 --- a/railties/lib/rails/configuration.rb +++ b/railties/lib/rails/configuration.rb @@ -6,17 +6,54 @@ require 'rails/rack' module Rails module Configuration - class MiddlewareStackProxy #:nodoc: + # MiddlewareStackProxy is a proxy for the Rails middleware stack that allows + # you to configure middlewares in your application. It works basically as a + # command recorder, saving each command to be applied after initialization + # over the default middleware stack, so you can add, swap, or remove any + # middleware in Rails. + # + # You can add your own middlewares by using the +config.middleware.use+ method: + # + # config.middleware.use Magical::Unicorns + # + # This will put the +Magical::Unicorns+ middleware on the end of the stack. + # You can use +insert_before+ if you wish to add a middleware before another: + # + # config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns + # + # There's also +insert_after+ which will insert a middleware after another: + # + # config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns + # + # Middlewares can also be completely swapped out and replaced with others: + # + # config.middleware.swap ActionDispatch::BestStandardsSupport, Magical::Unicorns + # + # And finally they can also be removed from the stack completely: + # + # config.middleware.delete ActionDispatch::BestStandardsSupport + # + # In addition to these methods to handle the stack, if your application is + # going to be used as an API endpoint only, the middleware stack can be + # configured like this: + # + # config.middleware.http_only! + # + # By doing this, Rails will create a smaller middleware stack, by not adding + # some middlewares that are usually useful for browser access only, such as + # Cookies, Session and Flash, BestStandardsSupport, and MethodOverride. You + # can always add any of them later manually if you want. + class MiddlewareStackProxy def initialize @operations = [] - @api_only = false + @http_only = false end - attr_reader :api_only - alias :api_only? :api_only + attr_reader :http_only + alias :http_only? :http_only - def api_only! - @api_only = true + def http_only! + @http_only = true end def insert_before(*args, &block) @@ -41,7 +78,7 @@ module Rails @operations << [:delete, args, block] end - def merge_into(other) + def merge_into(other) #:nodoc: @operations.each do |operation, args, block| other.send(operation, *args, &block) end diff --git a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb index e8065d9505..b3d6adad2a 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb +++ b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb @@ -1,3 +1,5 @@ class ApplicationController < ActionController::Base - protect_from_forgery + # prevent CSRF attacks by raising an exception, + # if your application has an API, you'll probably need to use :reset_session + protect_from_forgery :with => :exception end diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt index 7041550fd0..d0d9083c37 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt @@ -73,4 +73,7 @@ # Disable automatic flushing of the log to improve performance. # config.autoflush_log = false + + # Use default logging formatter so that PID and timestamp are not suppressed + config.log_formatter = ::Logger::Formatter.new end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb index dcd3b276e3..8d45b2bbd9 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb +++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb @@ -8,3 +8,8 @@ Rails.backtrace_cleaner.remove_silencers! # Load support files Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } + +# Load fixtures from the engine +if ActiveSupport::TestCase.method_defined?(:fixture_path) + ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__) +end
\ No newline at end of file diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb index f7e907a017..4c07baae36 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb @@ -8,10 +8,31 @@ module TestUnit check_class_collision :suffix => "ControllerTest" + argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" + def create_test_files template 'functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb") end + + private + + def resource_attributes + key_value singular_table_name, "{ #{attributes_hash} }" + end + + def attributes_hash + return if accessible_attributes.empty? + + accessible_attributes.map do |a| + name = a.name + "#{name}: @#{singular_table_name}.#{name}" + end.sort.join(', ') + end + + def accessible_attributes + attributes.reject(&:reference?) + end end end end diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb index 9ec2e34545..19894443d5 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb @@ -19,7 +19,7 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase test "should create <%= singular_table_name %>" do assert_difference('<%= class_name %>.count') do - post :create, <%= key_value singular_table_name, "@#{singular_table_name}.attributes" %> + post :create, <%= resource_attributes %> end assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>)) @@ -36,7 +36,7 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase end test "should update <%= singular_table_name %>" do - put :update, <%= key_value :id, "@#{singular_table_name}" %>, <%= key_value singular_table_name, "@#{singular_table_name}.attributes" %> + put :update, <%= key_value :id, "@#{singular_table_name}" %>, <%= resource_attributes %> assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>)) end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index c9310aff87..ac5ac2b93e 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -275,19 +275,23 @@ module ApplicationTests require "#{app_path}/config/environment" + token = "cf50faa3fe97702ca1ae" + PostsController.any_instance.stubs(:form_authenticity_token).returns(token) + params = {:authenticity_token => token} + get "/posts/1" assert_match /patch/, last_response.body - patch "/posts/1" + patch "/posts/1", params assert_match /update/, last_response.body - patch "/posts/1" + patch "/posts/1", params assert_equal 200, last_response.status - put "/posts/1" + put "/posts/1", params assert_match /update/, last_response.body - put "/posts/1" + put "/posts/1", params assert_equal 200, last_response.status end @@ -528,6 +532,12 @@ module ApplicationTests end RUBY + app_file 'app/controllers/application_controller.rb', <<-RUBY + class ApplicationController < ActionController::Base + protect_from_forgery :with => :reset_session # as we are testing API here + end + RUBY + app_file 'app/controllers/posts_controller.rb', <<-RUBY class PostsController < ApplicationController def create diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb index a0e88cd0f0..a08e5b2374 100644 --- a/railties/test/application/initializers/frameworks_test.rb +++ b/railties/test/application/initializers/frameworks_test.rb @@ -1,4 +1,5 @@ require "isolation/abstract_unit" +require 'set' module ApplicationTests class FrameworksTest < ActiveSupport::TestCase @@ -66,7 +67,7 @@ module ApplicationTests require "#{app_path}/config/environment" assert Foo.method_defined?(:foo_path) assert Foo.method_defined?(:main_app) - assert_equal ["notify"], Foo.action_methods + assert_equal Set.new(["notify"]), Foo.action_methods end test "allows to not load all helpers for controllers" do @@ -196,9 +197,8 @@ module ApplicationTests test "use schema cache dump" do Dir.chdir(app_path) do - `rails generate model post title:string` - `bundle exec rake db:migrate` - `bundle exec rake db:schema:cache:dump` + `rails generate model post title:string; + bundle exec rake db:migrate db:schema:cache:dump` end require "#{app_path}/config/environment" ActiveRecord::Base.connection.drop_table("posts") # force drop posts table for test. @@ -207,17 +207,13 @@ module ApplicationTests test "expire schema cache dump" do Dir.chdir(app_path) do - `rails generate model post title:string` - `bundle exec rake db:migrate` - `bundle exec rake db:schema:cache:dump` - - `bundle exec rake db:rollback` + `rails generate model post title:string; + bundle exec rake db:migrate db:schema:cache:dump db:rollback` end silence_warnings { require "#{app_path}/config/environment" assert !ActiveRecord::Base.connection.schema_cache.tables["posts"] } end - end end diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index a190a31fc7..712a555c4a 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -53,7 +53,7 @@ module ApplicationTests end test "api middleware stack" do - add_to_config "config.middleware.api_only!" + add_to_config "config.middleware.http_only!" add_to_config "config.force_ssl = true" add_to_config "config.action_dispatch.x_sendfile_header = 'X-Sendfile'" @@ -216,7 +216,6 @@ module ApplicationTests assert_equal etag, last_response.headers["Etag"] get "/?nothing=true" - puts last_response.body assert_equal 200, last_response.status assert_equal "", last_response.body assert_equal "text/html; charset=utf-8", last_response.headers["Content-Type"] diff --git a/railties/test/application/rake/migrations_test.rb b/railties/test/application/rake/migrations_test.rb index c94334f189..0a47fd014c 100644 --- a/railties/test/application/rake/migrations_test.rb +++ b/railties/test/application/rake/migrations_test.rb @@ -16,44 +16,45 @@ module ApplicationTests test 'running migrations with given scope' do Dir.chdir(app_path) do `rails generate model user username:string password:string` - end - app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION - class AMigration < ActiveRecord::Migration - end - MIGRATION - output = Dir.chdir(app_path) { `rake db:migrate SCOPE=bukkits` } - assert_no_match(/create_table\(:users\)/, output) - assert_no_match(/CreateUsers/, output) - assert_no_match(/add_column\(:users, :email, :string\)/, output) + app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION + class AMigration < ActiveRecord::Migration + end + MIGRATION + + output = `rake db:migrate SCOPE=bukkits` + assert_no_match(/create_table\(:users\)/, output) + assert_no_match(/CreateUsers/, output) + assert_no_match(/add_column\(:users, :email, :string\)/, output) - assert_match(/AMigration: migrated/, output) + assert_match(/AMigration: migrated/, output) - output = Dir.chdir(app_path) { `rake db:migrate SCOPE=bukkits VERSION=0` } - assert_no_match(/drop_table\(:users\)/, output) - assert_no_match(/CreateUsers/, output) - assert_no_match(/remove_column\(:users, :email\)/, output) + output = `rake db:migrate SCOPE=bukkits VERSION=0` + assert_no_match(/drop_table\(:users\)/, output) + assert_no_match(/CreateUsers/, output) + assert_no_match(/remove_column\(:users, :email\)/, output) - assert_match(/AMigration: reverted/, output) + assert_match(/AMigration: reverted/, output) + end end test 'model and migration generator with change syntax' do Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate migration add_email_to_users email:string` + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string` + + output = `rake db:migrate` + assert_match(/create_table\(:users\)/, output) + assert_match(/CreateUsers: migrated/, output) + assert_match(/add_column\(:users, :email, :string\)/, output) + assert_match(/AddEmailToUsers: migrated/, output) + + output = `rake db:rollback STEP=2` + assert_match(/drop_table\("users"\)/, output) + assert_match(/CreateUsers: reverted/, output) + assert_match(/remove_column\("users", :email\)/, output) + assert_match(/AddEmailToUsers: reverted/, output) end - - output = Dir.chdir(app_path){ `rake db:migrate` } - assert_match(/create_table\(:users\)/, output) - assert_match(/CreateUsers: migrated/, output) - assert_match(/add_column\(:users, :email, :string\)/, output) - assert_match(/AddEmailToUsers: migrated/, output) - - output = Dir.chdir(app_path){ `rake db:rollback STEP=2` } - assert_match(/drop_table\("users"\)/, output) - assert_match(/CreateUsers: reverted/, output) - assert_match(/remove_column\("users", :email\)/, output) - assert_match(/AddEmailToUsers: reverted/, output) end test 'migration status when schema migrations table is not present' do @@ -63,94 +64,94 @@ module ApplicationTests test 'test migration status' do Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate migration add_email_to_users email:string` - end + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string; + rake db:migrate` - Dir.chdir(app_path) { `rake db:migrate` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + output = `rake db:migrate:status` - assert_match(/up\s+\d{14}\s+Create users/, output) - assert_match(/up\s+\d{14}\s+Add email to users/, output) + assert_match(/up\s+\d{14}\s+Create users/, output) + assert_match(/up\s+\d{14}\s+Add email to users/, output) - Dir.chdir(app_path) { `rake db:rollback STEP=1` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + `rake db:rollback STEP=1` + output = `rake db:migrate:status` - assert_match(/up\s+\d{14}\s+Create users/, output) - assert_match(/down\s+\d{14}\s+Add email to users/, output) + assert_match(/up\s+\d{14}\s+Create users/, output) + assert_match(/down\s+\d{14}\s+Add email to users/, output) + end end test 'migration status without timestamps' do add_to_config('config.active_record.timestamped_migrations = false') Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate migration add_email_to_users email:string` - end + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string; + rake db:migrate` - Dir.chdir(app_path) { `rake db:migrate` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + output = `rake db:migrate:status` - assert_match(/up\s+\d{3,}\s+Create users/, output) - assert_match(/up\s+\d{3,}\s+Add email to users/, output) + assert_match(/up\s+\d{3,}\s+Create users/, output) + assert_match(/up\s+\d{3,}\s+Add email to users/, output) - Dir.chdir(app_path) { `rake db:rollback STEP=1` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + `rake db:rollback STEP=1` + output = `rake db:migrate:status` - assert_match(/up\s+\d{3,}\s+Create users/, output) - assert_match(/down\s+\d{3,}\s+Add email to users/, output) + assert_match(/up\s+\d{3,}\s+Create users/, output) + assert_match(/down\s+\d{3,}\s+Add email to users/, output) + end end test 'test migration status after rollback and redo' do Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate migration add_email_to_users email:string` - end + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string; + rake db:migrate` - Dir.chdir(app_path) { `rake db:migrate` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + output = `rake db:migrate:status` - assert_match(/up\s+\d{14}\s+Create users/, output) - assert_match(/up\s+\d{14}\s+Add email to users/, output) + assert_match(/up\s+\d{14}\s+Create users/, output) + assert_match(/up\s+\d{14}\s+Add email to users/, output) - Dir.chdir(app_path) { `rake db:rollback STEP=2` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + `rake db:rollback STEP=2` + output = `rake db:migrate:status` - assert_match(/down\s+\d{14}\s+Create users/, output) - assert_match(/down\s+\d{14}\s+Add email to users/, output) + assert_match(/down\s+\d{14}\s+Create users/, output) + assert_match(/down\s+\d{14}\s+Add email to users/, output) - Dir.chdir(app_path) { `rake db:migrate:redo` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + `rake db:migrate:redo` + output = `rake db:migrate:status` - assert_match(/up\s+\d{14}\s+Create users/, output) - assert_match(/up\s+\d{14}\s+Add email to users/, output) + assert_match(/up\s+\d{14}\s+Create users/, output) + assert_match(/up\s+\d{14}\s+Add email to users/, output) + end end test 'migration status after rollback and redo without timestamps' do add_to_config('config.active_record.timestamped_migrations = false') Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate migration add_email_to_users email:string` - end + `rails generate model user username:string password:string; + rails generate migration add_email_to_users email:string; + rake db:migrate` - Dir.chdir(app_path) { `rake db:migrate` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + output = `rake db:migrate:status` - assert_match(/up\s+\d{3,}\s+Create users/, output) - assert_match(/up\s+\d{3,}\s+Add email to users/, output) + assert_match(/up\s+\d{3,}\s+Create users/, output) + assert_match(/up\s+\d{3,}\s+Add email to users/, output) - Dir.chdir(app_path) { `rake db:rollback STEP=2` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + `rake db:rollback STEP=2` + output = `rake db:migrate:status` - assert_match(/down\s+\d{3,}\s+Create users/, output) - assert_match(/down\s+\d{3,}\s+Add email to users/, output) + assert_match(/down\s+\d{3,}\s+Create users/, output) + assert_match(/down\s+\d{3,}\s+Add email to users/, output) - Dir.chdir(app_path) { `rake db:migrate:redo` } - output = Dir.chdir(app_path) { `rake db:migrate:status` } + `rake db:migrate:redo` + output = `rake db:migrate:status` - assert_match(/up\s+\d{3,}\s+Create users/, output) - assert_match(/up\s+\d{3,}\s+Add email to users/, output) + assert_match(/up\s+\d{3,}\s+Create users/, output) + assert_match(/up\s+\d{3,}\s+Add email to users/, output) + end end end end diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 4ab20afc47..b66433f64d 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -3,7 +3,7 @@ require "isolation/abstract_unit" module ApplicationTests module RakeTests class RakeNotesTest < ActiveSupport::TestCase - def setup + def setup build_app require "rails/all" end @@ -13,7 +13,6 @@ module ApplicationTests end test 'notes' do - app_file "app/views/home/index.html.erb", "<% # TODO: note in erb %>" app_file "app/views/home/index.html.haml", "-# TODO: note in haml" app_file "app/views/home/index.html.slim", "/ TODO: note in slim" diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index 9515e40b6e..fed9dce8e1 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -107,9 +107,9 @@ module ApplicationTests def test_loading_specific_fixtures Dir.chdir(app_path) do - `rails generate model user username:string password:string` - `rails generate model product name:string` - `rake db:migrate` + `rails generate model user username:string password:string; + rails generate model product name:string; + rake db:migrate` end require "#{rails_root}/config/environment" @@ -124,8 +124,8 @@ module ApplicationTests def test_scaffold_tests_pass_by_default content = Dir.chdir(app_path) do - `rails generate scaffold user username:string password:string` - `bundle exec rake db:migrate db:test:clone test` + `rails generate scaffold user username:string password:string; + bundle exec rake db:migrate db:test:clone test` end assert_match(/\d+ tests, \d+ assertions, 0 failures, 0 errors/, content) @@ -133,29 +133,26 @@ module ApplicationTests def test_rake_dump_structure_should_respect_db_structure_env_variable Dir.chdir(app_path) do - `bundle exec rake db:migrate` # ensure we have a schema_migrations table to dump - `bundle exec rake db:structure:dump DB_STRUCTURE=db/my_structure.sql` + # ensure we have a schema_migrations table to dump + `bundle exec rake db:migrate db:structure:dump DB_STRUCTURE=db/my_structure.sql` end assert File.exists?(File.join(app_path, 'db', 'my_structure.sql')) end def test_rake_dump_schema_cache Dir.chdir(app_path) do - `rails generate model post title:string` - `rails generate model product name:string` - `bundle exec rake db:migrate` - `bundle exec rake db:schema:cache:dump` + `rails generate model post title:string; + rails generate model product name:string; + bundle exec rake db:migrate db:schema:cache:dump` end assert File.exists?(File.join(app_path, 'db', 'schema_cache.dump')) end def test_rake_clear_schema_cache Dir.chdir(app_path) do - `bundle exec rake db:schema:cache:dump` - `bundle exec rake db:schema:cache:clear` + `bundle exec rake db:schema:cache:dump db:schema:cache:clear` end assert !File.exists?(File.join(app_path, 'db', 'schema_cache.dump')) end - end end diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 1382133d7b..03a753151d 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -75,6 +75,19 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase assert_file "test/functional/users_controller_test.rb" do |content| assert_match(/class UsersControllerTest < ActionController::TestCase/, content) assert_match(/test "should get index"/, content) + assert_match(/post :create, user: { age: @user.age, name: @user.name }/, content) + assert_match(/put :update, id: @user, user: { age: @user.age, name: @user.name }/, content) + end + end + + def test_functional_tests_without_attributes + run_generator ["User"] + + assert_file "test/functional/users_controller_test.rb" do |content| + assert_match(/class UsersControllerTest < ActionController::TestCase/, content) + assert_match(/test "should get index"/, content) + assert_match(/post :create, user: { }/, content) + assert_match(/put :update, id: @user, user: { }/, content) end end diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 2db8090621..f4f0147156 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -62,8 +62,11 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase end end - assert_file "test/functional/product_lines_controller_test.rb", - /class ProductLinesControllerTest < ActionController::TestCase/ + assert_file "test/functional/product_lines_controller_test.rb" do |test| + assert_match(/class ProductLinesControllerTest < ActionController::TestCase/, test) + assert_match(/post :create, product_line: { title: @product_line.title }/, test) + assert_match(/put :update, id: @product_line, product_line: { title: @product_line.title }/, test) + end # Views %w( @@ -85,6 +88,17 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_file "app/assets/stylesheets/product_lines.css" end + def test_functional_tests_without_attributes + run_generator ["product_line"] + + assert_file "test/functional/product_lines_controller_test.rb" do |content| + assert_match(/class ProductLinesControllerTest < ActionController::TestCase/, content) + assert_match(/test "should get index"/, content) + assert_match(/post :create, product_line: { }/, content) + assert_match(/put :update, id: @product_line, product_line: { }/, content) + end + end + def test_scaffold_on_revoke run_generator run_generator ["product_line"], :behavior => :revoke |