diff options
103 files changed, 566 insertions, 1544 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index e29890f2d8..68b34805ff 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -27,4 +27,8 @@ * Asynchronously send messages via the Rails Queue *Brian Cardarella* +* Allow callbacks to be defined in mailers similar to `ActionController::Base`. You can configure default + settings, headers, attachments, delivery settings or change delivery using + `before_filter`, `after_filter` etc. *Justin S. Leitgeb* + Please check [3-2-stable](https://github.com/rails/rails/blob/3-2-stable/actionmailer/CHANGELOG.md) for previous changes. diff --git a/actionmailer/README.rdoc b/actionmailer/README.rdoc index cf10bfffdb..59c33b7940 100644 --- a/actionmailer/README.rdoc +++ b/actionmailer/README.rdoc @@ -83,7 +83,7 @@ Note that every value you set with this method will get over written if you use Example: class AuthenticationMailer < ActionMailer::Base - default :from => "awesome@application.com", :subject => Proc.new { "E-mail was generated at #{Time.now}" } + default from: "awesome@application.com", subject: Proc.new { "E-mail was generated at #{Time.now}" } ..... end @@ -100,13 +100,13 @@ Example: def receive(email) page = Page.find_by_address(email.to.first) page.emails.create( - :subject => email.subject, :body => email.body + subject: email.subject, body: email.body ) if email.has_attachments? email.attachments.each do |attachment| page.attachments.create({ - :file => attachment, :description => email.subject + file: attachment, description: email.subject }) end end @@ -127,11 +127,11 @@ a limited number of email. The Base class has the full list of configuration options. Here's an example: ActionMailer::Base.smtp_settings = { - :address => 'smtp.yourserver.com', # default: localhost - :port => '25', # default: 25 - :user_name => 'user', - :password => 'pass', - :authentication => :plain # :plain, :login or :cram_md5 + address: 'smtp.yourserver.com', # default: localhost + port: '25', # default: 25 + user_name: 'user', + password: 'pass', + authentication: :plain # :plain, :login or :cram_md5 } diff --git a/actionmailer/lib/rails/generators/mailer/USAGE b/actionmailer/lib/rails/generators/mailer/USAGE index 9f1d6b182e..7470289fd3 100644 --- a/actionmailer/lib/rails/generators/mailer/USAGE +++ b/actionmailer/lib/rails/generators/mailer/USAGE @@ -13,6 +13,6 @@ Example: creates a Notifications mailer class, views, test, and fixtures: Mailer: app/mailers/notifications.rb Views: app/views/notifications/signup.erb [...] - Test: test/functional/notifications_test.rb + Test: test/mailers/notifications_test.rb Fixtures: test/fixtures/notifications/signup [...] diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 77010ecc70..fd02492834 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,7 @@ ## Rails 4.0.0 (unreleased) ## +* Remove old asset tag concatenation (no longer needed now that we have the asset pipeline). *Josh Peek* + * Accept :remote as symbolic option for `link_to` helper. *Riley Lynch* * Warn when the `:locals` option is passed to `assert_template` outside of a view test case diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 402f29cd76..0de10695e0 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -6,7 +6,7 @@ module ActionDispatch # and calls an exceptions app that will wrap it in a format for the end user. # # The exceptions app should be passed as parameter on initialization - # of ShowExceptions. Everytime there is an exception, ShowExceptions will + # of ShowExceptions. Every time there is an exception, ShowExceptions will # store the exception in env["action_dispatch.exception"], rewrite the # PATH_INFO to the exception status code and call the rack app. # diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb deleted file mode 100644 index e42e49fb04..0000000000 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +++ /dev/null @@ -1,145 +0,0 @@ -require 'active_support/core_ext/string/inflections' -require 'active_support/core_ext/file' -require 'action_view/helpers/tag_helper' - -module ActionView - module Helpers - module AssetTagHelper - - class AssetIncludeTag #:nodoc: - include TagHelper - - attr_reader :config, :asset_paths - class_attribute :expansions - - def self.inherited(base) - base.expansions = { } - end - - def initialize(config, asset_paths) - @config = config - @asset_paths = asset_paths - end - - def asset_name - raise NotImplementedError - end - - def extension - raise NotImplementedError - end - - def custom_dir - raise NotImplementedError - end - - def asset_tag(source, options) - raise NotImplementedError - end - - def include_tag(*sources) - options = sources.extract_options!.stringify_keys - concat = options.delete("concat") - cache = concat || options.delete("cache") - recursive = options.delete("recursive") - - if concat || (config.perform_caching && cache) - joined_name = (cache == true ? "all" : cache) + ".#{extension}" - joined_path = File.join((joined_name[/^#{File::SEPARATOR}/] ? config.assets_dir : custom_dir), joined_name) - unless config.perform_caching && File.exists?(joined_path) - write_asset_file_contents(joined_path, compute_paths(sources, recursive)) - end - asset_tag(joined_name, options) - else - sources = expand_sources(sources, recursive) - ensure_sources!(sources) if cache - sources.collect { |source| asset_tag(source, options) }.join("\n").html_safe - end - end - - private - - def path_to_asset(source, options = {}) - asset_paths.compute_public_path(source, asset_name.to_s.pluralize, options.merge(:ext => extension)) - end - - def path_to_asset_source(source) - asset_paths.compute_source_path(source, asset_name.to_s.pluralize, extension) - end - - def compute_paths(*args) - expand_sources(*args).collect { |source| path_to_asset_source(source) } - end - - def expand_sources(sources, recursive) - if sources.first == :all - collect_asset_files(custom_dir, ('**' if recursive), "*.#{extension}") - else - sources.inject([]) do |list, source| - determined_source = determine_source(source, expansions) - update_source_list(list, determined_source) - end - end - end - - def update_source_list(list, source) - case source - when String - list.delete(source) - list << source - when Array - updated_sources = source - list - list.concat(updated_sources) - end - end - - def ensure_sources!(sources) - sources.each do |source| - asset_file_path!(path_to_asset_source(source)) - end - end - - def collect_asset_files(*path) - dir = path.first - - Dir[File.join(*path.compact)].collect do |file| - file[-(file.size - dir.size - 1)..-1].sub(/\.\w+$/, '') - end.sort - end - - def determine_source(source, collection) - case source - when Symbol - collection[source] || raise(ArgumentError, "No expansion found for #{source.inspect}") - else - source - end - end - - def join_asset_file_contents(paths) - paths.collect { |path| File.read(asset_file_path!(path, true)) }.join("\n\n") - end - - def write_asset_file_contents(joined_asset_path, asset_paths) - FileUtils.mkdir_p(File.dirname(joined_asset_path)) - File.atomic_write(joined_asset_path) { |cache| cache.write(join_asset_file_contents(asset_paths)) } - - # Set mtime to the latest of the combined files to allow for - # consistent ETag without a shared filesystem. - mt = asset_paths.map { |p| File.mtime(asset_file_path!(p)) }.max - File.utime(mt, mt, joined_asset_path) - end - - def asset_file_path!(absolute_path, error_if_file_is_uri = false) - if asset_paths.is_uri?(absolute_path) - raise(Errno::ENOENT, "Asset file #{path} is uri and cannot be merged into single file") if error_if_file_is_uri - else - raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path) - return absolute_path - end - end - end - - end - end -end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb index 139f4d19ab..b6b9eadc88 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb @@ -1,76 +1,11 @@ require 'active_support/core_ext/file' -require 'action_view/helpers/asset_tag_helpers/asset_include_tag' module ActionView module Helpers module AssetTagHelper - - class JavascriptIncludeTag < AssetIncludeTag #:nodoc: - def asset_name - 'javascript' - end - - def extension - 'js' - end - - def asset_tag(source, options) - content_tag("script", "", { "src" => path_to_asset(source) }.merge(options)) - end - - def custom_dir - config.javascripts_dir - end - - private - - def expand_sources(sources, recursive = false) - if sources.include?(:all) - all_asset_files = (collect_asset_files(custom_dir, ('**' if recursive), "*.#{extension}") - ['application']) - add_application_js(all_asset_files, sources) - ((determine_source(:defaults, expansions).dup & all_asset_files) + all_asset_files).uniq - else - expanded_sources = sources.inject([]) do |list, source| - determined_source = determine_source(source, expansions) - update_source_list(list, determined_source) - end - add_application_js(expanded_sources, sources) - expanded_sources - end - end - - def add_application_js(expanded_sources, sources) - if (sources.include?(:defaults) || sources.include?(:all)) && File.exist?(File.join(custom_dir, "application.#{extension}")) - expanded_sources.delete('application') - expanded_sources << "application" - end - end - end - - module JavascriptTagHelpers extend ActiveSupport::Concern - module ClassMethods - # Register one or more javascript files to be included when <tt>symbol</tt> - # is passed to <tt>javascript_include_tag</tt>. This method is typically intended - # to be called from plugin initialization to register javascript files - # that the plugin installed in <tt>public/javascripts</tt>. - # - # ActionView::Helpers::AssetTagHelper.register_javascript_expansion :monkey => ["head", "body", "tail"] - # - # javascript_include_tag :monkey # => - # <script src="/javascripts/head.js"></script> - # <script src="/javascripts/body.js"></script> - # <script src="/javascripts/tail.js"></script> - def register_javascript_expansion(expansions) - js_expansions = JavascriptIncludeTag.expansions - expansions.each do |key, values| - js_expansions[key] = (js_expansions[key] || []) | Array(values) - end - end - end - # Computes the path to a javascript asset in the public javascripts directory. # If the +source+ filename has no extension, .js will be appended (except for explicit URIs) # Full paths from the document root will be passed through. @@ -101,15 +36,6 @@ module ActionView # # When passing paths, the ".js" extension is optional. # - # If the application is not using the asset pipeline, to include the default JavaScript - # expansion pass <tt>:defaults</tt> as source. By default, <tt>:defaults</tt> loads jQuery, - # and that can be overridden in <tt>config/application.rb</tt>: - # - # config.action_view.javascript_expansions[:defaults] = %w(foo.js bar.js) - # - # When using <tt>:defaults</tt> or <tt>:all</tt>, if an <tt>application.js</tt> file exists - # in <tt>public/javascripts</tt> it will be included as well at the end. - # # You can modify the HTML attributes of the script tag by passing a hash as the # last argument. # @@ -129,65 +55,14 @@ module ActionView # javascript_include_tag "http://www.example.com/xmlhr.js" # # => <script src="http://www.example.com/xmlhr.js"></script> # - # javascript_include_tag :defaults - # # => <script src="/javascripts/jquery.js?1284139606"></script> - # # <script src="/javascripts/rails.js?1284139606"></script> - # # <script src="/javascripts/application.js?1284139606"></script> - # - # Note: The application.js file is only referenced if it exists - # - # You can also include all JavaScripts in the +javascripts+ directory using <tt>:all</tt> as the source: - # - # javascript_include_tag :all - # # => <script src="/javascripts/jquery.js?1284139606"></script> - # # <script src="/javascripts/rails.js?1284139606"></script> - # # <script src="/javascripts/shop.js?1284139606"></script> - # # <script src="/javascripts/checkout.js?1284139606"></script> - # # <script src="/javascripts/application.js?1284139606"></script> - # - # Note that your defaults of choice will be included first, so they will be available to all subsequently - # included files. - # - # If you want Rails to search in all the subdirectories under <tt>public/javascripts</tt>, you should - # explicitly set <tt>:recursive</tt>: - # - # javascript_include_tag :all, :recursive => true - # - # == Caching multiple JavaScripts into one - # - # You can also cache multiple JavaScripts into one file, which requires less HTTP connections to download - # and can better be compressed by gzip (leading to faster transfers). Caching will only happen if - # <tt>config.perform_caching</tt> is set to true (which is the case by default for the Rails - # production environment, but not for the development environment). - # - # # assuming config.perform_caching is false - # javascript_include_tag :all, :cache => true - # # => <script src="/javascripts/jquery.js?1284139606"></script> - # # <script src="/javascripts/rails.js?1284139606"></script> - # # <script src="/javascripts/shop.js?1284139606"></script> - # # <script src="/javascripts/checkout.js?1284139606"></script> - # # <script src="/javascripts/application.js?1284139606"></script> - # - # # assuming config.perform_caching is true - # javascript_include_tag :all, :cache => true - # # => <script src="/javascripts/all.js?1344139789"></script> - # - # # assuming config.perform_caching is false - # javascript_include_tag "jquery", "cart", "checkout", :cache => "shop" - # # => <script src="/javascripts/jquery.js?1284139606"></script> - # # <script src="/javascripts/cart.js?1289139157"></script> - # # <script src="/javascripts/checkout.js?1299139816"></script> - # - # # assuming config.perform_caching is true - # javascript_include_tag "jquery", "cart", "checkout", :cache => "shop" - # # => <script src="/javascripts/shop.js?1299139816"></script> - # - # The <tt>:recursive</tt> option is also available for caching: - # - # javascript_include_tag :all, :cache => true, :recursive => true def javascript_include_tag(*sources) - @javascript_include ||= JavascriptIncludeTag.new(config, asset_paths) - @javascript_include.include_tag(*sources) + options = sources.extract_options!.stringify_keys + sources.dup.map { |source| + tag_options = { + "src" => path_to_javascript(source) + }.merge(options) + content_tag(:script, "", tag_options) + }.join("\n").html_safe end end end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb index e3a86a8889..bf59f8e81a 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb @@ -1,53 +1,11 @@ require 'active_support/core_ext/file' -require 'action_view/helpers/asset_tag_helpers/asset_include_tag' module ActionView module Helpers module AssetTagHelper - - class StylesheetIncludeTag < AssetIncludeTag #:nodoc: - def asset_name - 'stylesheet' - end - - def extension - 'css' - end - - def asset_tag(source, options) - # We force the :request protocol here to avoid a double-download bug in IE7 and IE8 - tag("link", { "rel" => "stylesheet", "media" => "screen", "href" => path_to_asset(source, :protocol => :request) }.merge(options)) - end - - def custom_dir - config.stylesheets_dir - end - end - - module StylesheetTagHelpers extend ActiveSupport::Concern - module ClassMethods - # Register one or more stylesheet files to be included when <tt>symbol</tt> - # is passed to <tt>stylesheet_link_tag</tt>. This method is typically intended - # to be called from plugin initialization to register stylesheet files - # that the plugin installed in <tt>public/stylesheets</tt>. - # - # ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :monkey => ["head", "body", "tail"] - # - # stylesheet_link_tag :monkey # => - # <link href="/stylesheets/head.css" media="screen" rel="stylesheet" /> - # <link href="/stylesheets/body.css" media="screen" rel="stylesheet" /> - # <link href="/stylesheets/tail.css" media="screen" rel="stylesheet" /> - def register_stylesheet_expansion(expansions) - style_expansions = StylesheetIncludeTag.expansions - expansions.each do |key, values| - style_expansions[key] = (style_expansions[key] || []) | Array(values) - end - end - end - # Computes the path to a stylesheet asset in the public stylesheets directory. # If the +source+ filename has no extension, <tt>.css</tt> will be appended (except for explicit URIs). # Full paths from the document root will be passed through. @@ -96,56 +54,18 @@ module ActionView # <link href="/stylesheets/random.styles" media="screen" rel="stylesheet" /> # <link href="/css/stylish.css" media="screen" rel="stylesheet" /> # - # You can also include all styles in the stylesheets directory using <tt>:all</tt> as the source: - # - # stylesheet_link_tag :all # => - # <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" /> - # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" /> - # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" /> - # - # If you want Rails to search in all the subdirectories under stylesheets, you should explicitly set <tt>:recursive</tt>: - # - # stylesheet_link_tag :all, :recursive => true - # - # == Caching multiple stylesheets into one - # - # You can also cache multiple stylesheets into one file, which requires less HTTP connections and can better be - # compressed by gzip (leading to faster transfers). Caching will only happen if +config.perform_caching+ - # is set to true (which is the case by default for the Rails production environment, but not for the development - # environment). Examples: - # - # stylesheet_link_tag :all, :cache => true # when config.perform_caching is false => - # <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" /> - # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" /> - # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" /> - # - # stylesheet_link_tag :all, :cache => true # when config.perform_caching is true => - # <link href="/stylesheets/all.css" media="screen" rel="stylesheet" /> - # - # stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is false => - # <link href="/stylesheets/shop.css" media="screen" rel="stylesheet" /> - # <link href="/stylesheets/cart.css" media="screen" rel="stylesheet" /> - # <link href="/stylesheets/checkout.css" media="screen" rel="stylesheet" /> - # - # stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is true => - # <link href="/stylesheets/payment.css" media="screen" rel="stylesheet" /> - # - # The <tt>:recursive</tt> option is also available for caching: - # - # stylesheet_link_tag :all, :cache => true, :recursive => true - # - # To force concatenation (even in development mode) set <tt>:concat</tt> to true. This is useful if - # you have too many stylesheets for IE to load. - # - # stylesheet_link_tag :all, :concat => true - # def stylesheet_link_tag(*sources) - @stylesheet_include ||= StylesheetIncludeTag.new(config, asset_paths) - @stylesheet_include.include_tag(*sources) + options = sources.extract_options!.stringify_keys + sources.uniq.map { |source| + tag_options = { + "rel" => "stylesheet", + "media" => "screen", + "href" => path_to_stylesheet(source) + }.merge(options) + tag(:link, tag_options) + }.join("\n").html_safe end - end - end end end diff --git a/actionpack/lib/action_view/railtie.rb b/actionpack/lib/action_view/railtie.rb index 2d36deaa78..55f6ea5522 100644 --- a/actionpack/lib/action_view/railtie.rb +++ b/actionpack/lib/action_view/railtie.rb @@ -5,8 +5,6 @@ module ActionView # = Action View Railtie class Railtie < Rails::Railtie config.action_view = ActiveSupport::OrderedOptions.new - config.action_view.stylesheet_expansions = {} - config.action_view.javascript_expansions = { :defaults => %w(jquery jquery_ujs) } config.action_view.embed_authenticity_token_in_remote_forms = false config.eager_load_namespaces << ActionView @@ -30,18 +28,6 @@ module ActionView end end - initializer "action_view.javascript_expansions" do |app| - ActiveSupport.on_load(:action_view) do - ActionView::Helpers::AssetTagHelper.register_javascript_expansion( - app.config.action_view.delete(:javascript_expansions) - ) - - ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion( - app.config.action_view.delete(:stylesheet_expansions) - ) - end - end - initializer "action_view.set_configs" do |app| ActiveSupport.on_load(:action_view) do app.config.action_view.each do |k,v| diff --git a/actionpack/lib/action_view/vendor/html-scanner/html/selector.rb b/actionpack/lib/action_view/vendor/html-scanner/html/selector.rb index 1eadfc0390..60b6783b19 100644 --- a/actionpack/lib/action_view/vendor/html-scanner/html/selector.rb +++ b/actionpack/lib/action_view/vendor/html-scanner/html/selector.rb @@ -160,7 +160,7 @@ module HTML # * <tt>:not(selector)</tt> -- Match the element only if the element does not # match the simple selector. # - # As you can see, <tt>:nth-child<tt> pseudo class and its variant can get quite + # As you can see, <tt>:nth-child</tt> pseudo class and its variant can get quite # tricky and the CSS specification doesn't do a much better job explaining it. # But after reading the examples and trying a few combinations, it's easy to # figure out. diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index a04694714d..754622c883 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -45,8 +45,6 @@ class AssetTagHelperTest < ActionView::TestCase end.new @controller.request = @request - - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :defaults => ['prototype', 'effects', 'dragdrop', 'controls', 'rails'] end def url_for(*args) @@ -54,11 +52,7 @@ class AssetTagHelperTest < ActionView::TestCase end def teardown - config.perform_caching = false ENV.delete('RAILS_ASSET_ID') - - JavascriptIncludeTag.expansions.clear - StylesheetIncludeTag.expansions.clear end AutoDiscoveryToTag = { @@ -105,12 +99,6 @@ class AssetTagHelperTest < ActionView::TestCase %(javascript_include_tag("bank.js")) => %(<script src="/javascripts/bank.js" ></script>), %(javascript_include_tag("bank", :lang => "vbscript")) => %(<script lang="vbscript" src="/javascripts/bank.js" ></script>), %(javascript_include_tag("common.javascript", "/elsewhere/cools")) => %(<script src="/javascripts/common.javascript" ></script>\n<script src="/elsewhere/cools.js" ></script>), - %(javascript_include_tag(:defaults)) => %(<script src="/javascripts/prototype.js" ></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/application.js"></script>), - %(javascript_include_tag(:all)) => %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>\n<script src="/javascripts/version.1.0.js"></script>\n<script src="/javascripts/application.js"></script>), - %(javascript_include_tag(:all, :recursive => true)) => %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>\n<script src="/javascripts/subdir/subdir.js"></script>\n<script src="/javascripts/version.1.0.js"></script>\n<script src="/javascripts/application.js"></script>), - %(javascript_include_tag(:defaults, "bank")) => %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/application.js"></script>), - %(javascript_include_tag(:defaults, "application")) => %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/application.js"></script>), - %(javascript_include_tag("bank", :defaults)) => %(<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/application.js"></script>), %(javascript_include_tag("http://example.com/all")) => %(<script src="http://example.com/all"></script>), %(javascript_include_tag("http://example.com/all.js")) => %(<script src="http://example.com/all.js"></script>), @@ -151,9 +139,6 @@ class AssetTagHelperTest < ActionView::TestCase %(stylesheet_link_tag("/elsewhere/file")) => %(<link href="/elsewhere/file.css" media="screen" rel="stylesheet" />), %(stylesheet_link_tag("subdir/subdir")) => %(<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" />), %(stylesheet_link_tag("bank", :media => "all")) => %(<link href="/stylesheets/bank.css" media="all" rel="stylesheet" />), - %(stylesheet_link_tag(:all)) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" />), - %(stylesheet_link_tag(:all, :recursive => true)) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" />), - %(stylesheet_link_tag(:all, :media => "all")) => %(<link href="/stylesheets/bank.css" media="all" rel="stylesheet" />\n<link href="/stylesheets/robber.css" media="all" rel="stylesheet" />\n<link href="/stylesheets/version.1.0.css" media="all" rel="stylesheet" />), %(stylesheet_link_tag("random.styles", "/elsewhere/file")) => %(<link href="/stylesheets/random.styles" media="screen" rel="stylesheet" />\n<link href="/elsewhere/file.css" media="screen" rel="stylesheet" />), %(stylesheet_link_tag("http://www.example.com/styles/style")) => %(<link href="http://www.example.com/styles/style" media="screen" rel="stylesheet" />), @@ -339,93 +324,14 @@ class AssetTagHelperTest < ActionView::TestCase } assert_nothing_raised { - javascript_include_tag(:defaults, 'missing_security_guard') - } - - assert_nothing_raised { javascript_include_tag('http://example.com/css/missing_security_guard') } end - def test_javascript_include_tag_with_given_asset_id - ENV["RAILS_ASSET_ID"] = "1" - assert_dom_equal(%(<script src="/javascripts/prototype.js?1"></script>\n<script src="/javascripts/effects.js?1"></script>\n<script src="/javascripts/dragdrop.js?1"></script>\n<script src="/javascripts/controls.js?1"></script>\n<script src="/javascripts/rails.js?1"></script>\n<script src="/javascripts/application.js?1"></script>), javascript_include_tag(:defaults)) - end - def test_javascript_include_tag_is_html_safe - assert javascript_include_tag(:defaults).html_safe? assert javascript_include_tag("prototype").html_safe? end - def test_custom_javascript_expansions - ENV["RAILS_ASSET_ID"] = "" - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :robbery => ["bank", "robber"] - assert_dom_equal %(<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>\n<script src="/javascripts/effects.js"></script>), javascript_include_tag('controls', :robbery, 'effects') - end - - def test_custom_javascript_expansions_return_unique_set - ENV["RAILS_ASSET_ID"] = "" - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :defaults => %w(prototype effects dragdrop controls rails application) - assert_dom_equal %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/application.js"></script>), javascript_include_tag(:defaults) - end - - def test_custom_javascript_expansions_and_defaults_puts_application_js_at_the_end - ENV["RAILS_ASSET_ID"] = "" - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :robbery => ["bank", "robber"] - assert_dom_equal %(<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/application.js"></script>), javascript_include_tag('controls',:defaults, :robbery, 'effects') - end - - def test_javascript_include_tag_should_not_output_the_same_asset_twice - ENV["RAILS_ASSET_ID"] = "" - assert_dom_equal %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/application.js"></script>), javascript_include_tag('prototype', 'effects', :defaults) - end - - def test_javascript_include_tag_should_not_output_the_same_expansion_twice - ENV["RAILS_ASSET_ID"] = "" - assert_dom_equal %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/application.js"></script>), javascript_include_tag(:defaults, :defaults) - end - - def test_single_javascript_asset_keys_should_take_precedence_over_expansions - ENV["RAILS_ASSET_ID"] = "" - assert_dom_equal %(<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/application.js"></script>), javascript_include_tag('controls', :defaults, 'effects') - assert_dom_equal %(<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/rails.js"></script>\n<script src="/javascripts/application.js"></script>), javascript_include_tag('controls', 'effects', :defaults) - end - - def test_registering_javascript_expansions_merges_with_existing_expansions - ENV["RAILS_ASSET_ID"] = "" - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :can_merge => ['bank'] - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :can_merge => ['robber'] - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :can_merge => ['bank'] - assert_dom_equal %(<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>), javascript_include_tag(:can_merge) - end - - def test_custom_javascript_expansions_with_undefined_symbol - assert_raise(ArgumentError) { javascript_include_tag('first', :unknown, 'last') } - end - - def test_custom_javascript_expansions_with_nil_value - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :monkey => nil - assert_dom_equal %(<script src="/javascripts/first.js"></script>\n<script src="/javascripts/last.js"></script>), javascript_include_tag('first', :monkey, 'last') - end - - def test_custom_javascript_expansions_with_empty_array_value - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :monkey => [] - assert_dom_equal %(<script src="/javascripts/first.js"></script>\n<script src="/javascripts/last.js"></script>), javascript_include_tag('first', :monkey, 'last') - end - - def test_custom_javascript_and_stylesheet_expansion_with_same_name - ENV["RAILS_ASSET_ID"] = "" - ActionView::Helpers::AssetTagHelper::register_javascript_expansion :robbery => ["bank", "robber"] - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :robbery => ["money", "security"] - assert_dom_equal %(<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>\n<script src="/javascripts/effects.js"></script>), javascript_include_tag('controls', :robbery, 'effects') - assert_dom_equal %(<link href="/stylesheets/style.css" rel="stylesheet" media="screen" />\n<link href="/stylesheets/money.css" rel="stylesheet" media="screen" />\n<link href="/stylesheets/security.css" rel="stylesheet" media="screen" />\n<link href="/stylesheets/print.css" rel="stylesheet" media="screen" />), stylesheet_link_tag('style', :robbery, 'print') - end - - def test_reset_javascript_expansions - JavascriptIncludeTag.expansions.clear - assert_raise(ArgumentError) { javascript_include_tag(:defaults) } - end - def test_all_javascript_expansion_not_include_application_js_if_not_exists FileUtils.mv(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'application.js'), File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'application.bak')) @@ -478,57 +384,11 @@ class AssetTagHelperTest < ActionView::TestCase assert_dom_equal %(<link href="/file.css" media="<script>" rel="stylesheet" />), stylesheet_link_tag('/file', :media => '<script>') end - def test_custom_stylesheet_expansions - ENV["RAILS_ASSET_ID"] = '' - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :robbery => ["bank", "robber"] - assert_dom_equal %(<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" />), stylesheet_link_tag('version.1.0', :robbery, 'subdir/subdir') - end - - def test_custom_stylesheet_expansions_return_unique_set - ENV["RAILS_ASSET_ID"] = "" - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :cities => %w(wellington amsterdam london) - assert_dom_equal %(<link href="/stylesheets/wellington.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/amsterdam.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/london.css" media="screen" rel="stylesheet" />), stylesheet_link_tag(:cities) - end - def test_stylesheet_link_tag_should_not_output_the_same_asset_twice ENV["RAILS_ASSET_ID"] = "" assert_dom_equal %(<link href="/stylesheets/wellington.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/amsterdam.css" media="screen" rel="stylesheet" />), stylesheet_link_tag('wellington', 'wellington', 'amsterdam') end - def test_stylesheet_link_tag_should_not_output_the_same_expansion_twice - ENV["RAILS_ASSET_ID"] = "" - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :cities => %w(wellington amsterdam london) - assert_dom_equal %(<link href="/stylesheets/wellington.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/amsterdam.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/london.css" media="screen" rel="stylesheet" />), stylesheet_link_tag(:cities, :cities) - end - - def test_single_stylesheet_asset_keys_should_take_precedence_over_expansions - ENV["RAILS_ASSET_ID"] = "" - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :cities => %w(wellington amsterdam london) - assert_dom_equal %(<link href="/stylesheets/london.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/wellington.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/amsterdam.css" media="screen" rel="stylesheet" />), stylesheet_link_tag('london', :cities) - end - - def test_custom_stylesheet_expansions_with_unknown_symbol - assert_raise(ArgumentError) { stylesheet_link_tag('first', :unknown, 'last') } - end - - def test_custom_stylesheet_expansions_with_nil_value - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :monkey => nil - assert_dom_equal %(<link href="/stylesheets/first.css" rel="stylesheet" media="screen" />\n<link href="/stylesheets/last.css" rel="stylesheet" media="screen" />), stylesheet_link_tag('first', :monkey, 'last') - end - - def test_custom_stylesheet_expansions_with_empty_array_value - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :monkey => [] - assert_dom_equal %(<link href="/stylesheets/first.css" rel="stylesheet" media="screen" />\n<link href="/stylesheets/last.css" rel="stylesheet" media="screen" />), stylesheet_link_tag('first', :monkey, 'last') - end - - def test_registering_stylesheet_expansions_merges_with_existing_expansions - ENV["RAILS_ASSET_ID"] = "" - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :can_merge => ['bank'] - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :can_merge => ['robber'] - ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :can_merge => ['bank'] - assert_dom_equal %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" />), stylesheet_link_tag(:can_merge) - end - def test_image_path ImagePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -714,616 +574,6 @@ class AssetTagHelperTest < ActionView::TestCase @controller.request.stubs(:ssl?).returns(true) assert_equal "http://localhost/images/xml.png", image_path("xml.png") end - - def test_caching_javascript_include_tag_when_caching_on - ENV["RAILS_ASSET_ID"] = "" - @controller.config.asset_host = 'http://a0.example.com' - config.perform_caching = true - - assert_dom_equal( - %(<script src="http://a0.example.com/javascripts/all.js"></script>), - javascript_include_tag(:all, :cache => true) - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - - assert_dom_equal( - %(<script src="http://a0.example.com/javascripts/money.js"></script>), - javascript_include_tag(:all, :cache => "money") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - - assert_dom_equal( - %(<script src="http://a0.example.com/absolute/test.js"></script>), - javascript_include_tag(:all, :cache => "/absolute/test") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute', 'test.js')) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute')) - end - - def test_caching_javascript_include_tag_when_caching_on_with_proc_asset_host - ENV['RAILS_ASSET_ID'] = '' - @controller.config.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" } - config.perform_caching = true - - assert_equal '/javascripts/scripts.js'.length, 23 - assert_dom_equal( - %(<script src="http://a23.example.com/javascripts/scripts.js"></script>), - javascript_include_tag(:all, :cache => 'scripts') - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'scripts.js')) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'scripts.js')) - end - - def test_caching_javascript_include_tag_when_caching_on_with_2_argument_proc_asset_host - ENV['RAILS_ASSET_ID'] = '' - @controller.config.asset_host = Proc.new { |source, request| - if request.ssl? - "#{request.protocol}#{request.host_with_port}" - else - "#{request.protocol}assets#{source.length}.example.com" - end - } - config.perform_caching = true - - assert_equal '/javascripts/vanilla.js'.length, 23 - assert_dom_equal( - %(<script src="http://assets23.example.com/javascripts/vanilla.js"></script>), - javascript_include_tag(:all, :cache => 'vanilla') - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'vanilla.js')) - - class << @controller.request - def protocol() 'https://' end - def ssl?() true end - end - - assert_equal '/javascripts/secure.js'.length, 22 - assert_dom_equal( - %(<script src="https://localhost/javascripts/secure.js"></script>), - javascript_include_tag(:all, :cache => 'secure') - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'secure.js')) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'vanilla.js')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'secure.js')) - end - - def test_caching_javascript_include_tag_when_caching_on_with_2_argument_object_asset_host - ENV['RAILS_ASSET_ID'] = '' - @controller.config.asset_host = Class.new do - def call(source, request) - if request.ssl? - "#{request.protocol}#{request.host_with_port}" - else - "#{request.protocol}assets#{source.length}.example.com" - end - end - end.new - - config.perform_caching = true - - assert_equal '/javascripts/vanilla.js'.length, 23 - assert_dom_equal( - %(<script src="http://assets23.example.com/javascripts/vanilla.js"></script>), - javascript_include_tag(:all, :cache => 'vanilla') - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'vanilla.js')) - - class << @controller.request - def protocol() 'https://' end - def ssl?() true end - end - - assert_equal '/javascripts/secure.js'.length, 22 - assert_dom_equal( - %(<script src="https://localhost/javascripts/secure.js"></script>), - javascript_include_tag(:all, :cache => 'secure') - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'secure.js')) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'vanilla.js')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'secure.js')) - end - - def test_caching_javascript_include_tag_when_caching_on_and_using_subdirectory - ENV["RAILS_ASSET_ID"] = "" - @controller.config.asset_host = 'http://a%d.example.com' - config.perform_caching = true - - number = Zlib.crc32('/javascripts/cache/money.js') % 4 - assert_dom_equal( - %(<script src="http://a#{number}.example.com/javascripts/cache/money.js"></script>), - javascript_include_tag(:all, :cache => "cache/money") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'cache', 'money.js')) - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'cache', 'money.js')) - end - - def test_caching_javascript_include_tag_with_all_and_recursive_puts_defaults_at_the_start_of_the_file - ENV["RAILS_ASSET_ID"] = "" - @controller.config.asset_host = 'http://a0.example.com' - config.perform_caching = true - - assert_dom_equal( - %(<script src="http://a0.example.com/javascripts/combined.js"></script>), - javascript_include_tag(:all, :cache => "combined", :recursive => true) - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) - - assert_equal( - %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// bank js\n\n// robber js\n\n// subdir js\n\n\n// version.1.0 js\n\n// application js), - IO.read(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) - ) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) - end - - def test_caching_javascript_include_tag_with_all_puts_defaults_at_the_start_of_the_file - ENV["RAILS_ASSET_ID"] = "" - @controller.config.asset_host = 'http://a0.example.com' - config.perform_caching = true - - assert_dom_equal( - %(<script src="http://a0.example.com/javascripts/combined.js"></script>), - javascript_include_tag(:all, :cache => "combined") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) - - assert_equal( - %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// bank js\n\n// robber js\n\n// version.1.0 js\n\n// application js), - IO.read(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) - ) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) - end - - def test_caching_javascript_include_tag_with_relative_url_root - ENV["RAILS_ASSET_ID"] = "" - @controller.config.relative_url_root = "/collaboration/hieraki" - config.perform_caching = true - - assert_dom_equal( - %(<script src="/collaboration/hieraki/javascripts/all.js"></script>), - javascript_include_tag(:all, :cache => true) - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - - assert_dom_equal( - %(<script src="/collaboration/hieraki/javascripts/money.js"></script>), - javascript_include_tag(:all, :cache => "money") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - end - - # Same as above, but with script_name - def test_caching_javascript_include_tag_with_script_name - ENV["RAILS_ASSET_ID"] = "" - @request.script_name = "/collaboration/hieraki" - config.perform_caching = true - - assert_dom_equal( - %(<script src="/collaboration/hieraki/javascripts/all.js"></script>), - javascript_include_tag(:all, :cache => true) - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - - assert_dom_equal( - %(<script src="/collaboration/hieraki/javascripts/money.js"></script>), - javascript_include_tag(:all, :cache => "money") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - end - - def test_caching_javascript_include_tag_with_named_paths_and_relative_url_root_when_caching_off - ENV["RAILS_ASSET_ID"] = "" - @controller.config.relative_url_root = "/collaboration/hieraki" - config.perform_caching = false - - assert_dom_equal( - %(<script src="/collaboration/hieraki/javascripts/robber.js"></script>), - javascript_include_tag('robber', :cache => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - - assert_dom_equal( - %(<script src="/collaboration/hieraki/javascripts/robber.js"></script>), - javascript_include_tag('robber', :cache => "money", :recursive => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - end - - # Same as above, but with script_name - def test_caching_javascript_include_tag_with_named_paths_and_script_name_when_caching_off - ENV["RAILS_ASSET_ID"] = "" - @request.script_name = "/collaboration/hieraki" - config.perform_caching = false - - assert_dom_equal( - %(<script src="/collaboration/hieraki/javascripts/robber.js"></script>), - javascript_include_tag('robber', :cache => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - - assert_dom_equal( - %(<script src="/collaboration/hieraki/javascripts/robber.js"></script>), - javascript_include_tag('robber', :cache => "money", :recursive => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - end - - def test_caching_javascript_include_tag_when_caching_off - ENV["RAILS_ASSET_ID"] = "" - config.perform_caching = false - - assert_dom_equal( - %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>\n<script src="/javascripts/version.1.0.js"></script>\n<script src="/javascripts/application.js"></script>), - javascript_include_tag(:all, :cache => true) - ) - - assert_dom_equal( - %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>\n<script src="/javascripts/subdir/subdir.js"></script>\n<script src="/javascripts/version.1.0.js"></script>\n<script src="/javascripts/application.js"></script>), - javascript_include_tag(:all, :cache => true, :recursive => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - - assert_dom_equal( - %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>\n<script src="/javascripts/version.1.0.js"></script>\n<script src="/javascripts/application.js"></script>), - javascript_include_tag(:all, :cache => "money") - ) - - assert_dom_equal( - %(<script src="/javascripts/prototype.js"></script>\n<script src="/javascripts/effects.js"></script>\n<script src="/javascripts/dragdrop.js"></script>\n<script src="/javascripts/controls.js"></script>\n<script src="/javascripts/bank.js"></script>\n<script src="/javascripts/robber.js"></script>\n<script src="/javascripts/subdir/subdir.js"></script>\n<script src="/javascripts/version.1.0.js"></script>\n<script src="/javascripts/application.js"></script>), - javascript_include_tag(:all, :cache => "money", :recursive => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - end - - def test_caching_javascript_include_tag_when_caching_on_and_missing_javascript_file - ENV["RAILS_ASSET_ID"] = "" - config.perform_caching = true - - assert_raise(Errno::ENOENT) { - javascript_include_tag('bank', 'robber', 'missing_security_guard', :cache => true) - } - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - - assert_raise(Errno::ENOENT) { - javascript_include_tag('bank', 'robber', 'missing_security_guard', :cache => "money") - } - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - end - - def test_caching_javascript_include_tag_when_caching_on_and_javascript_file_is_uri - ENV["RAILS_ASSET_ID"] = "" - config.perform_caching = true - - assert_raise(Errno::ENOENT) { - javascript_include_tag('bank', 'robber', 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.js', :cache => true) - } - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - end - - def test_caching_javascript_include_tag_when_caching_off_and_missing_javascript_file - ENV["RAILS_ASSET_ID"] = "" - config.perform_caching = false - - assert_raise(Errno::ENOENT) { - javascript_include_tag('bank', 'robber', 'missing_security_guard', :cache => true) - } - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) - - assert_raise(Errno::ENOENT) { - javascript_include_tag('bank', 'robber', 'missing_security_guard', :cache => "money") - } - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) - end - - def test_caching_stylesheet_link_tag_when_caching_on - ENV["RAILS_ASSET_ID"] = "" - @controller.config.asset_host = 'a0.example.com' - config.perform_caching = true - - assert_dom_equal( - %(<link href="http://a0.example.com/stylesheets/all.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => true) - ) - - files_to_be_joined = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/[^all]*.css"] - - expected_mtime = files_to_be_joined.map { |p| File.mtime(p) }.max - assert_equal expected_mtime, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - bytes_added_by_join = "\n\n".size * files_to_be_joined.size - "\n\n".size - expected_size = files_to_be_joined.sum { |p| File.size(p) } + bytes_added_by_join - assert_equal expected_size, File.size(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - assert_dom_equal( - %(<link href="http://a0.example.com/stylesheets/money.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => "money") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - - assert_dom_equal( - %(<link href="http://a0.example.com/absolute/test.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => "/absolute/test") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute', 'test.css')) - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute')) - end - - def test_concat_stylesheet_link_tag_when_caching_off - ENV["RAILS_ASSET_ID"] = "" - - assert_dom_equal( - %(<link href="/stylesheets/all.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :concat => true) - ) - - expected = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/*.css"].map { |p| File.mtime(p) }.max - assert_equal expected, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - assert_dom_equal( - %(<link href="/stylesheets/money.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :concat => "money") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - - assert_dom_equal( - %(<link href="/absolute/test.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :concat => "/absolute/test") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute', 'test.css')) - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute')) - end - - def test_caching_stylesheet_link_tag_when_caching_on_and_missing_css_file - ENV["RAILS_ASSET_ID"] = "" - config.perform_caching = true - - assert_raise(Errno::ENOENT) { - stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => true) - } - - assert ! File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - assert_raise(Errno::ENOENT) { - stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => "money") - } - - assert ! File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - end - - def test_caching_stylesheet_link_tag_when_caching_off_and_missing_css_file - ENV["RAILS_ASSET_ID"] = "" - config.perform_caching = false - - assert_raise(Errno::ENOENT) { - stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => true) - } - - assert ! File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - assert_raise(Errno::ENOENT) { - stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => "money") - } - - assert ! File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - end - - def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host - ENV["RAILS_ASSET_ID"] = "" - @controller.config.asset_host = Proc.new { |source| "a#{source.length}.example.com" } - config.perform_caching = true - - assert_equal '/stylesheets/styles.css'.length, 23 - assert_dom_equal( - %(<link href="http://a23.example.com/stylesheets/styles.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => 'styles') - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'styles.css')) - - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'styles.css')) - end - - def test_caching_stylesheet_link_tag_with_relative_url_root - ENV["RAILS_ASSET_ID"] = "" - @controller.config.relative_url_root = "/collaboration/hieraki" - config.perform_caching = true - - assert_dom_equal( - %(<link href="/collaboration/hieraki/stylesheets/all.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => true) - ) - - files_to_be_joined = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/[^all]*.css"] - - expected_mtime = files_to_be_joined.map { |p| File.mtime(p) }.max - assert_equal expected_mtime, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - assert_dom_equal( - %(<link href="/collaboration/hieraki/stylesheets/money.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => "money") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - end - - # Same as above, but with script_name - def test_caching_stylesheet_link_tag_with_script_name - ENV["RAILS_ASSET_ID"] = "" - @request.script_name = "/collaboration/hieraki" - config.perform_caching = true - - assert_dom_equal( - %(<link href="/collaboration/hieraki/stylesheets/all.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => true) - ) - - files_to_be_joined = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/[^all]*.css"] - - expected_mtime = files_to_be_joined.map { |p| File.mtime(p) }.max - assert_equal expected_mtime, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - assert_dom_equal( - %(<link href="/collaboration/hieraki/stylesheets/money.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => "money") - ) - - assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - ensure - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - end - - - def test_caching_stylesheet_link_tag_with_named_paths_and_relative_url_root_when_caching_off - ENV["RAILS_ASSET_ID"] = "" - @controller.config.relative_url_root = "/collaboration/hieraki" - config.perform_caching = false - - assert_dom_equal( - %(<link href="/collaboration/hieraki/stylesheets/robber.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag('robber', :cache => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - assert_dom_equal( - %(<link href="/collaboration/hieraki/stylesheets/robber.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag('robber', :cache => "money") - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - end - - # Same as above, but with script_name - def test_caching_stylesheet_link_tag_with_named_paths_and_script_name_when_caching_off - ENV["RAILS_ASSET_ID"] = "" - @request.script_name = "/collaboration/hieraki" - config.perform_caching = false - - assert_dom_equal( - %(<link href="/collaboration/hieraki/stylesheets/robber.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag('robber', :cache => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - assert_dom_equal( - %(<link href="/collaboration/hieraki/stylesheets/robber.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag('robber', :cache => "money") - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - end - - def test_caching_stylesheet_include_tag_when_caching_off - ENV["RAILS_ASSET_ID"] = "" - config.perform_caching = false - - assert_dom_equal( - %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => true) - ) - - assert_dom_equal( - %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => true, :recursive => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - - assert_dom_equal( - %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => "money") - ) - - assert_dom_equal( - %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag(:all, :cache => "money", :recursive => true) - ) - - assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) - end - - def test_caching_stylesheet_include_tag_with_absolute_uri - ENV["RAILS_ASSET_ID"] = "" - - assert_dom_equal( - %(<link href="/stylesheets/all.css" media="screen" rel="stylesheet" />), - stylesheet_link_tag("/foo/baz", :cache => true) - ) - - FileUtils.rm(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) - end end class AssetTagHelperNonVhostTest < ActionView::TestCase @@ -1336,8 +586,6 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase @request = Struct.new(:protocol).new("gopher://") @controller.request = @request - - JavascriptIncludeTag.expansions.clear end def url_for(options) diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index b4565b5881..fc34d69ff6 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -23,7 +23,7 @@ to integrate with Action Pack out of the box: <tt>ActiveModel::Model</tt>. validates_presence_of :name end - person = Person.new(:name => 'bob', :age => '18') + person = Person.new(name: 'bob', age: '18') person.name # => 'bob' person.age # => '18' person.valid? # => true diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 258d602afa..69b95f814c 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -190,10 +190,10 @@ module ActiveRecord # * <tt>Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?</tt> # * <tt>Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,</tt> # * <tt>Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),</tt> - # <tt>Project#milestones.delete(milestone), Project#milestones.find(milestone_id), Project#milestones.all(options),</tt> - # <tt>Project#milestones.build, Project#milestones.create</tt> + # <tt>Project#milestones.delete(milestone), Project#milestones.destroy(mileston), Project#milestones.find(milestone_id),</tt> + # <tt>Project#milestones.all(options), Project#milestones.build, Project#milestones.create</tt> # * <tt>Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1),</tt> - # <tt>Project#categories.delete(category1)</tt> + # <tt>Project#categories.delete(category1), Project#categories.destroy(category1)</tt> # # === A word of warning # @@ -236,6 +236,7 @@ module ActiveRecord # others.clear | X | X | X # others.delete(other,other,...) | X | X | X # others.delete_all | X | X | X + # others.destroy(other,other,...) | X | X | X # others.destroy_all | X | X | X # others.find(*args) | X | X | X # others.exists? | X | X | X @@ -1031,6 +1032,12 @@ module ActiveRecord # If the <tt>:through</tt> option is used, then the join records are deleted (rather than # nullified) by default, but you can specify <tt>:dependent => :destroy</tt> or # <tt>:dependent => :nullify</tt> to override this. + # [collection.destroy(object, ...)] + # Removes one or more objects from the collection by running <tt>destroy</tt> on + # each record, regardless of any dependent option, ensuring callbacks are run. + # + # If the <tt>:through</tt> option is used, then the join records are destroyed + # instead, not the objects themselves. # [collection=objects] # Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt> # option is true callbacks in the join models are triggered except destroy callbacks, since deletion is @@ -1074,6 +1081,7 @@ module ActiveRecord # * <tt>Firm#clients</tt> (similar to <tt>Clients.all :conditions => ["firm_id = ?", id]</tt>) # * <tt>Firm#clients<<</tt> # * <tt>Firm#clients.delete</tt> + # * <tt>Firm#clients.destroy</tt> # * <tt>Firm#clients=</tt> # * <tt>Firm#client_ids</tt> # * <tt>Firm#client_ids=</tt> @@ -1425,6 +1433,9 @@ module ActiveRecord # [collection.delete(object, ...)] # Removes one or more objects from the collection by removing their associations from the join table. # This does not destroy the objects. + # [collection.destroy(object, ...)] + # Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option. + # This does not destroy the objects. # [collection=objects] # Replaces the collection's content by deleting and adding objects as appropriate. # [collection_singular_ids] @@ -1461,6 +1472,7 @@ module ActiveRecord # * <tt>Developer#projects</tt> # * <tt>Developer#projects<<</tt> # * <tt>Developer#projects.delete</tt> + # * <tt>Developer#projects.destroy</tt> # * <tt>Developer#projects=</tt> # * <tt>Developer#project_ids</tt> # * <tt>Developer#project_ids=</tt> diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index 96270ec0e9..7f39d3083e 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -414,7 +414,7 @@ module ActiveRecord persisted.map! do |record| if mem_record = memory.delete(record) - (record.attribute_names - mem_record.changes.keys).each do |name| + ((record.attribute_names & mem_record.attribute_names) - mem_record.changes.keys).each do |name| mem_record[name] = record[name] end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 5e35f472c7..bd375ad15a 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -241,7 +241,7 @@ module ActiveRecord # <encoding></tt> call on the connection. # * <tt>:min_messages</tt> - An optional client min messages that is used in a # <tt>SET client_min_messages TO <min_messages></tt> call on the connection. - # * <tt>:insert_returning</tt> - An optional boolean to control the use or <tt>RETURNING</tt> for <tt>INSERT<tt> statements + # * <tt>:insert_returning</tt> - An optional boolean to control the use or <tt>RETURNING</tt> for <tt>INSERT</tt> statements # defaults to true. # # Any further options are used as connection parameters to libpq. See diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index c1d57855a9..d5ee98382d 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -50,7 +50,7 @@ module ActiveRecord # # class AddSsl < ActiveRecord::Migration # def up - # add_column :accounts, :ssl_enabled, :boolean, :default => true + # add_column :accounts, :ssl_enabled, :boolean, default: true # end # # def down @@ -62,7 +62,7 @@ module ActiveRecord # if you're backing out of the migration. It shows how all migrations have # two methods +up+ and +down+ that describes the transformations # required to implement or remove the migration. These methods can consist - # of both the migration specific methods like add_column and remove_column, + # of both the migration specific methods like +add_column+ and +remove_column+, # but may also contain regular Ruby code for generating data needed for the # transformations. # @@ -78,9 +78,9 @@ module ActiveRecord # t.integer :position # end # - # SystemSetting.create :name => "notice", - # :label => "Use notice?", - # :value => 1 + # SystemSetting.create name: 'notice', + # label: 'Use notice?', + # value: 1 # end # # def down @@ -88,19 +88,22 @@ module ActiveRecord # end # end # - # This migration first adds the system_settings table, then creates the very + # This migration first adds the +system_settings+ table, then creates the very # first row in it using the Active Record model that relies on the table. It - # also uses the more advanced create_table syntax where you can specify a + # also uses the more advanced +create_table+ syntax where you can specify a # complete table schema in one block call. # # == Available transformations # - # * <tt>create_table(name, options)</tt> Creates a table called +name+ and + # * <tt>create_table(name, options)</tt>: Creates a table called +name+ and # makes the table object available to a block that can then add columns to it, - # following the same format as add_column. See example above. The options hash + # following the same format as +add_column+. See example above. The options hash # is for fragments like "DEFAULT CHARSET=UTF-8" that are appended to the create # table definition. # * <tt>drop_table(name)</tt>: Drops the table called +name+. + # * <tt>change_table(name, options)</tt>: Allows to make column alterations to + # the table called +name+. It makes the table object availabe to a block that + # can then add/remove columns, indexes or foreign keys to it. # * <tt>rename_table(old_name, new_name)</tt>: Renames the table called +old_name+ # to +new_name+. # * <tt>add_column(table_name, column_name, type, options)</tt>: Adds a new column @@ -109,9 +112,9 @@ module ActiveRecord # <tt>:string</tt>, <tt>:text</tt>, <tt>:integer</tt>, <tt>:float</tt>, # <tt>:decimal</tt>, <tt>:datetime</tt>, <tt>:timestamp</tt>, <tt>:time</tt>, # <tt>:date</tt>, <tt>:binary</tt>, <tt>:boolean</tt>. A default value can be - # specified by passing an +options+ hash like <tt>{ :default => 11 }</tt>. + # specified by passing an +options+ hash like <tt>{ default: 11 }</tt>. # Other options include <tt>:limit</tt> and <tt>:null</tt> (e.g. - # <tt>{ :limit => 50, :null => false }</tt>) -- see + # <tt>{ limit: 50, null: false }</tt>) -- see # ActiveRecord::ConnectionAdapters::TableDefinition#column for details. # * <tt>rename_column(table_name, column_name, new_column_name)</tt>: Renames # a column but keeps the type and content. @@ -122,11 +125,11 @@ module ActiveRecord # * <tt>add_index(table_name, column_names, options)</tt>: Adds a new index # with the name of the column. Other options include # <tt>:name</tt>, <tt>:unique</tt> (e.g. - # <tt>{ :name => "users_name_index", :unique => true }</tt>) and <tt>:order</tt> - # (e.g. { :order => {:name => :desc} }</tt>). - # * <tt>remove_index(table_name, :column => column_name)</tt>: Removes the index + # <tt>{ name: 'users_name_index', unique: true }</tt>) and <tt>:order</tt> + # (e.g. <tt>{ order: { name: :desc } }</tt>). + # * <tt>remove_index(table_name, column: column_name)</tt>: Removes the index # specified by +column_name+. - # * <tt>remove_index(table_name, :name => index_name)</tt>: Removes the index + # * <tt>remove_index(table_name, name: index_name)</tt>: Removes the index # specified by +index_name+. # # == Irreversible transformations diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 0107667fbe..611d3d97c3 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -197,7 +197,7 @@ module ActiveRecord end end - # Updates a single attribute of an object, without having to call save on that object. + # Updates a single attribute of an object, without having to explicitly call save on that object. # # * Validation is skipped. # * Callbacks are skipped. @@ -209,7 +209,7 @@ module ActiveRecord update_columns(name => value) end - # Updates the attributes from the passed-in hash, without having to call save on that object. + # Updates the attributes from the passed-in hash, without having to explicitly call save on that object. # # * Validation is skipped. # * Callbacks are skipped. diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index 28aab6d92b..8af0c6a8ef 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -40,7 +40,7 @@ module ActiveRecord # # It's not possible to set the order. That is automatically set to # ascending on the primary key ("id ASC") to make the batch ordering - # work. This also mean that this method only works with integer-based + # work. This also means that this method only works with integer-based # primary keys. You can't set the limit either, that's used to control # the batch sizes. # diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb index 86893ec4b3..9b00c21b52 100644 --- a/activerecord/test/cases/associations/join_model_test.rb +++ b/activerecord/test/cases/associations/join_model_test.rb @@ -231,6 +231,14 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase assert_equal "2", categories(:sti_test).authors_with_select.first.post_id.to_s end + def test_create_through_has_many_with_piggyback + category = categories(:sti_test) + ernie = category.authors_with_select.create(:name => 'Ernie') + assert_nothing_raised do + assert_equal ernie, category.authors_with_select.detect {|a| a.name == 'Ernie'} + end + end + def test_include_has_many_through posts = Post.all.merge!(:order => 'posts.id').to_a posts_with_authors = Post.all.merge!(:includes => :authors, :order => 'posts.id').to_a diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 9120083eca..fe9eddbdec 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -156,7 +156,7 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase end def test_reject_if_with_blank_nested_attributes_id - # When using a select list to choose an existing 'ship' id, with :include_blank => true + # When using a select list to choose an existing 'ship' id, with include_blank: true Pirate.accepts_nested_attributes_for :ship, :reject_if => proc {|attributes| attributes[:id].blank? } pirate = Pirate.new(:catchphrase => "Stop wastin' me time") diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb index 15b97c02c8..efa0c9b934 100644 --- a/activerecord/test/cases/validations/i18n_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_validation_test.rb @@ -43,7 +43,7 @@ class I18nValidationTest < ActiveRecord::TestCase [ "given option that is not reserved", {:format => "jpg"}, {:format => "jpg" }] # TODO Add :on case, but below doesn't work, because then the validation isn't run for some reason # even when using .save instead .valid? - # [ "given on condition", {:on => :save}, {}] + # [ "given on condition", {on: :save}, {}] ] # validates_uniqueness_of w/ mocha diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 690e5ce194..732ab4b7df 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -644,7 +644,7 @@ module ActiveSupport @c = @compressed remove_instance_variable(:@compressed) end - if defined?(@expires_in) && defined?(@created_at) + if defined?(@expires_in) && defined?(@created_at) && @expires_in && @created_at @x = (@created_at + @expires_in).to_i remove_instance_variable(:@created_at) remove_instance_variable(:@expires_in) diff --git a/guides/CHANGELOG.md b/guides/CHANGELOG.md index d65e507a74..a1a480e911 100644 --- a/guides/CHANGELOG.md +++ b/guides/CHANGELOG.md @@ -1,3 +1,5 @@ ## Rails 4.0.0 (unreleased) ## +* Guides updated to reflect new test locations. *Mike Moore* + * Guides have a responsive design. *Joe Fiorini* diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md index cce5bc5331..54fe49252f 100644 --- a/guides/source/4_0_release_notes.md +++ b/guides/source/4_0_release_notes.md @@ -141,6 +141,8 @@ Action Mailer end ``` +* Allow for callbacks in mailers similar to ActionController::Base. You can now set up headers/attachments using `before_filter` or `after_filter`. You could also change delivery settings or prevent delivery in an after filter based on instance variables set in your mailer action. You have access to `ActionMailer::Base` instance methods like `message`, `attachments`, `headers`. + Action Pack ----------- diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md index 5e731d0a18..a938db6265 100644 --- a/guides/source/action_mailer_basics.md +++ b/guides/source/action_mailer_basics.md @@ -27,7 +27,7 @@ create app/mailers/user_mailer.rb invoke erb create app/views/user_mailer invoke test_unit -create test/functional/user_mailer_test.rb +create test/mailers/user_mailer_test.rb ``` So we got the mailer, the views, and the tests. @@ -476,7 +476,7 @@ The following configuration options are best made in one of the environment file |`logger`|Generates information on the mailing run if available. Can be set to `nil` for no logging. Compatible with both Ruby's own `Logger` and `Log4r` loggers.| |`smtp_settings`|Allows detailed configuration for `:smtp` delivery method:<ul><li>`:address` - Allows you to use a remote mail server. Just change it from its default "localhost" setting.</li><li>`:port` - On the off chance that your mail server doesn't run on port 25, you can change it.</li><li>`:domain` - If you need to specify a HELO domain, you can do it here.</li><li>`:user_name` - If your mail server requires authentication, set the username in this setting.</li><li>`:password` - If your mail server requires authentication, set the password in this setting.</li><li>`:authentication` - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of `:plain`, `:login`, `:cram_md5`.</li><li>`:enable_starttls_auto` - Set this to `false` if there is a problem with your server certificate that you cannot resolve.</li></ul>| |`sendmail_settings`|Allows you to override options for the `:sendmail` delivery method.<ul><li>`:location` - The location of the sendmail executable. Defaults to `/usr/sbin/sendmail`.</li><li>`:arguments` - The command line arguments to be passed to sendmail. Defaults to `-i -t`.</li></ul>| -|`raise_delivery_errors`|Whether or not errors should be raised if the email fails to be delivered.| +|`raise_delivery_errors`|Whether or not errors should be raised if the email fails to be delivered. This only works if the external email server is configured for immediate delivery.| |`delivery_method`|Defines a delivery method. Possible values are `:smtp` (default), `:sendmail`, `:file` and `:test`.| |`perform_deliveries`|Determines whether deliveries are actually carried out when the `deliver` method is invoked on the Mail message. By default they are, but this can be turned off to help functional testing.| |`deliveries`|Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.| diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index 1ae6a1f204..66e6390f67 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -375,8 +375,6 @@ end Another example would be if you wanted multiple workers handling the same processing queue. You could have each worker handle 10000 records by setting the appropriate `:start` option on each worker. -NOTE: The `:include` option allows you to name associations that should be loaded alongside with the models. - #### `find_in_batches` The `find_in_batches` method is similar to `find_each`, since both retrieve batches of records. The difference is that `find_in_batches` yields _batches_ to the block as an array of models, instead of individually. The following example will yield to the supplied block an array of up to 1000 invoices at a time, with the final block containing any remaining invoices: diff --git a/guides/source/active_record_validations_callbacks.md b/guides/source/active_record_validations_callbacks.md index f32c1050ce..333cbdd90b 100644 --- a/guides/source/active_record_validations_callbacks.md +++ b/guides/source/active_record_validations_callbacks.md @@ -50,6 +50,7 @@ end We can see how it works by looking at some `rails console` output: ```ruby +$ rails console >> p = Person.new(:name => "John Doe") => #<Person id: nil, name: "John Doe", created_at: nil, updated_at: nil> >> p.new_record? @@ -60,6 +61,8 @@ We can see how it works by looking at some `rails console` output: => false ``` +TIP: All lines starting with a dollar sign `$` are intended to be run on the command line. + Creating and saving a new record will send an SQL `INSERT` operation to the database. Updating an existing record will send an SQL `UPDATE` operation instead. Validations are typically run before these commands are sent to the database. If any validations fail, the object will be marked as invalid and Active Record will not perform the `INSERT` or `UPDATE` operation. This helps to avoid storing an invalid object in the database. You can choose to have specific validations run when an object is created, saved, or updated. CAUTION: There are many ways to change the state of an object in the database. Some methods will trigger validations, but some will not. This means that it's possible to save an object in the database in an invalid state if you aren't careful. diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md index dbf18b511c..42c7c07745 100644 --- a/guides/source/association_basics.md +++ b/guides/source/association_basics.md @@ -1130,6 +1130,7 @@ When you declare a `has_many` association, the declaring class automatically gai * `collection(force_reload = false)` * `collection<<(object, ...)` * `collection.delete(object, ...)` +* `collection.destroy(object, ...)` * `collection=objects` * `collection_singular_ids` * `collection_singular_ids=ids` @@ -1156,6 +1157,7 @@ Each instance of the customer model will have these methods: orders(force_reload = false) orders<<(object, ...) orders.delete(object, ...) +orders.destroy(object, ...) orders=objects order_ids order_ids=ids @@ -1195,6 +1197,15 @@ The `collection.delete` method removes one or more objects from the collection b WARNING: Additionally, objects will be destroyed if they're associated with `:dependent => :destroy`, and deleted if they're associated with `:dependent => :delete_all`. +##### `collection.destroy(object, ...)` + +The `collection.destroy` method removes one or more objects from the collection by running `destroy` on each object. + +```ruby +@customer.orders.destroy(@order1) +``` + +WARNING: Objects will _always_ be removed from the database, ignoring the `:dependent` option. ##### `collection=objects` @@ -1564,6 +1575,7 @@ When you declare a `has_and_belongs_to_many` association, the declaring class au * `collection(force_reload = false)` * `collection<<(object, ...)` * `collection.delete(object, ...)` +* `collection.destroy(object, ...)` * `collection=objects` * `collection_singular_ids` * `collection_singular_ids=ids` @@ -1590,6 +1602,7 @@ Each instance of the part model will have these methods: assemblies(force_reload = false) assemblies<<(object, ...) assemblies.delete(object, ...) +assemblies.destroy(object, ...) assemblies=objects assembly_ids assembly_ids=ids @@ -1636,6 +1649,16 @@ The `collection.delete` method removes one or more objects from the collection b @part.assemblies.delete(@assembly1) ``` +WARNING: This does not trigger callbacks on the join records. + +##### `collection.destroy(object, ...)` + +The `collection.destroy` method removes one or more objects from the collection by running `destroy` on each record in the join table, including running callbacks. This does not destroy the objects. + +```ruby +@part.assemblies.destroy(@assembly1) +``` + ##### `collection=objects` The `collection=` method makes the collection contain only the supplied objects, by adding and deleting as appropriate. diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md index ce1a01d313..e4d2ecaba1 100644 --- a/guides/source/caching_with_rails.md +++ b/guides/source/caching_with_rails.md @@ -5,17 +5,20 @@ This guide will teach you what you need to know about avoiding that expensive ro After reading this guide, you should be able to use and configure: -* Page, action, and fragment caching -* Sweepers -* Alternative cache stores -* Conditional GET support +* Page, action, and fragment caching. +* Sweepers. +* Alternative cache stores. +* Conditional GET support. -------------------------------------------------------------------------------- Basic Caching ------------- -This is an introduction to the three types of caching techniques that Rails provides by default without the use of any third party plugins. +This is an introduction to three types of caching techniques: page, action and +fragment caching. Rails provides by default fragment caching. In order to use +page and action caching, you will need to add `actionpack-page_caching` and +`actionpack-action_caching` to your Gemfile. To start playing with caching you'll want to ensure that `config.action_controller.perform_caching` is set to `true`, if you're running in development mode. This flag is normally set in the corresponding `config/environments/*.rb` and caching is disabled by default for development and test, and enabled for production. @@ -44,7 +47,7 @@ Let's say you have a controller called `ProductsController` and an `index` actio By default, the page cache directory is set to `Rails.public_path` (which is usually set to the `public` folder) and this can be configured by changing the configuration setting `config.action_controller.page_cache_directory`. Changing the default from `public` helps avoid naming conflicts, since you may want to put other static html in `public`, but changing this will require web server reconfiguration to let the web server know where to serve the cached files from. -The Page Caching mechanism will automatically add a `.html` extension to requests for pages that do not have an extension to make it easy for the webserver to find those pages and this can be configured by changing the configuration setting `config.action_controller.page_cache_extension`. +The Page Caching mechanism will automatically add a `.html` extension to requests for pages that do not have an extension to make it easy for the webserver to find those pages and this can be configured by changing the configuration setting `config.action_controller.default_static_extension`. In order to expire this page when a new product is added we could extend our example controller like this: diff --git a/guides/source/command_line.md b/guides/source/command_line.md index 22645babfe..0338ef5ad0 100644 --- a/guides/source/command_line.md +++ b/guides/source/command_line.md @@ -134,10 +134,10 @@ Example: `rails generate controller CreditCard open debit credit close` Credit card controller with URLs like /credit_card/debit. - Controller: app/controllers/credit_card_controller.rb - Functional Test: test/functional/credit_card_controller_test.rb - Views: app/views/credit_card/debit.html.erb [...] - Helper: app/helpers/credit_card_helper.rb + Controller: app/controllers/credit_card_controller.rb + Test: test/controllers/credit_card_controller_test.rb + Views: app/views/credit_card/debit.html.erb [...] + Helper: app/helpers/credit_card_helper.rb ``` The controller generator is expecting parameters in the form of `generate controller ControllerName action1 action2`. Let's make a `Greetings` controller with an action of **hello**, which will say something nice to us. @@ -150,11 +150,11 @@ $ rails generate controller Greetings hello create app/views/greetings create app/views/greetings/hello.html.erb invoke test_unit - create test/functional/greetings_controller_test.rb + create test/controllers/greetings_controller_test.rb invoke helper create app/helpers/greetings_helper.rb invoke test_unit - create test/unit/helpers/greetings_helper_test.rb + create test/helpers/greetings_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/greetings.js.coffee @@ -223,7 +223,7 @@ $ rails generate scaffold HighScore game:string score:integer create db/migrate/20120528060026_create_high_scores.rb create app/models/high_score.rb invoke test_unit - create test/unit/high_score_test.rb + create test/models/high_score_test.rb create test/fixtures/high_scores.yml route resources :high_scores invoke scaffold_controller @@ -236,11 +236,11 @@ $ rails generate scaffold HighScore game:string score:integer create app/views/high_scores/new.html.erb create app/views/high_scores/_form.html.erb invoke test_unit - create test/functional/high_scores_controller_test.rb + create test/controllers/high_scores_controller_test.rb invoke helper create app/helpers/high_scores_helper.rb invoke test_unit - create test/unit/helpers/high_scores_helper_test.rb + create test/helpers/high_scores_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/high_scores.js.coffee @@ -327,7 +327,7 @@ $ rails generate model Oops create db/migrate/20120528062523_create_oops.rb create app/models/oops.rb invoke test_unit - create test/unit/oops_test.rb + create test/models/oops_test.rb create test/fixtures/oops.yml ``` ```bash @@ -336,7 +336,7 @@ $ rails destroy model Oops remove db/migrate/20120528062523_create_oops.rb remove app/models/oops.rb invoke test_unit - remove test/unit/oops_test.rb + remove test/models/oops_test.rb remove test/fixtures/oops.yml ``` diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 8efc1f655f..2131a6c6a8 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -282,12 +282,8 @@ config.middleware.delete ActionDispatch::BestStandardsSupport * `config.active_record.lock_optimistically` controls whether Active Record will use optimistic locking and is true by default. -* `config.active_record.whitelist_attributes` will create an empty whitelist of attributes available for mass-assignment security for all models in your app. - * `config.active_record.auto_explain_threshold_in_seconds` configures the threshold for automatic EXPLAINs (`nil` disables this feature). Queries exceeding the threshold get their query plan logged. Default is 0.5 in development mode. -* `config.active_record.mass_assignment_sanitizer` will determine the strictness of the mass assignment sanitization within Rails. Defaults to `:strict`. In this mode, mass assigning any non-`attr_accessible` attribute in a `create` or `update_attributes` call will raise an exception. Setting this option to `:logger` will only print to the log file when an attribute is being assigned and will not raise an exception. - The MySQL adapter adds one additional configuration option: * `ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans` controls whether Active Record will consider all `tinyint(1)` columns in a MySQL database to be booleans and is true by default. @@ -304,27 +300,21 @@ The schema dumper adds one additional configuration option: * `config.action_controller.asset_path` takes a block which configures where assets can be found. Shorter version of `config.action_controller.asset_path`. -* `config.action_controller.page_cache_directory` should be the document root for the web server and is set using `Base.page_cache_directory = "/document/root"`. For Rails, this directory has already been set to `Rails.public_path` (which is usually set to `Rails.root ` "/public"`). Changing this setting can be useful to avoid naming conflicts with files in `public/`, but doing so will likely require configuring your web server to look in the new location for cached files. - -* `config.action_controller.page_cache_extension` configures the extension used for cached pages saved to `page_cache_directory`. Defaults to `.html`. - * `config.action_controller.perform_caching` configures whether the application should perform caching or not. Set to false in development mode, true in production. +* `config.action_controller.default_static_extension` configures the extension used for cached pages. Defaults to `.html`. + * `config.action_controller.default_charset` specifies the default character set for all renders. The default is "utf-8". * `config.action_controller.logger` accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action Controller. Set to `nil` to disable logging. * `config.action_controller.request_forgery_protection_token` sets the token parameter name for RequestForgery. Calling `protect_from_forgery` sets it to `:authenticity_token` by default. -* `config.action_controller.allow_forgery_protection` enables or disables CSRF protection. By default this is false in test mode and true in all other modes. +* `config.action_controller.allow_forgery_protection` enables or disables CSRF protection. By default this is `false` in test mode and `true` in all other modes. * `config.action_controller.relative_url_root` can be used to tell Rails that you are deploying to a subdirectory. The default is `ENV['RAILS_RELATIVE_URL_ROOT']`. -The caching code adds two additional settings: - -* `ActionController::Base.page_cache_directory` sets the directory where Rails will create cached pages for your web server. The default is `Rails.public_path` (which is usually set to `Rails.root + "/public"`). - -* `ActionController::Base.page_cache_extension` sets the extension to be used when generating pages for the cache (this is ignored if the incoming request already has an extension). The default is `.html`. +* `config.action_controller.permit_all_parameters` sets all the parameters for mass assignment to be permitted by default. The default value is `false`. ### Configuring Action Dispatch diff --git a/guides/source/engines.md b/guides/source/engines.md index 6d2d8ca409..97af423f3e 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -33,10 +33,10 @@ Finally, engines would not have been possible without the work of James Adam, Pi Generating an engine -------------------- -To generate an engine with Rails 3.1, you will need to run the plugin generator and pass it the `--full` and `--mountable` options. To generate the beginnings of the "blorgh" engine you will need to run this command in a terminal: +To generate an engine with Rails 3.2, you will need to run the plugin generator and pass it options as appropriate to the need. For the "blorgh" example, you will need to create a "mountable" engine, running this command in a terminal: ```bash -$ rails plugin new blorgh --full --mountable +$ rails plugin new blorgh --mountable ``` The full list of options for the plugin generator may be seen by typing: @@ -45,9 +45,48 @@ The full list of options for the plugin generator may be seen by typing: $ rails plugin --help ``` -The `--full` option tells the plugin generator that you want to create an engine, creating the basic directory structure of an engine by providing things such as an `app` directory and a `config/routes.rb` file. This generator also provides a file at `lib/blorgh/engine.rb` which is identical in function to a standard Rails application's `config/application.rb` file. +The `--full` option tells the generator that you want to create an engine, including a skeleton structure by providing the following: -The `--mountable` option tells the generator to mount the engine inside the dummy testing application located at `test/dummy`. It does this by placing this line into the dummy application's routes file at `test/dummy/config/routes.rb`: + * An `app` directory tree + * A `config/routes.rb` file: + + ```ruby + Rails.application.routes.draw do + end + ``` + * A file at `lib/blorgh/engine.rb` which is identical in function to a standard Rails application's `config/application.rb` file: + + ```ruby + module Blorgh + class Engine < ::Rails::Engine + end + end + ``` + +The `--mountable` option tells the generator that you want to create a "mountable" and namespace-isolated engine. This generator will provide the same skeleton structure as would the `--full` option, and will add: + + * Asset manifest files (`application.js` and `application.css`) + * A namespaced `ApplicationController` stub + * A namespaced `ApplicationHelper` stub + * A layout view template for the engine + * Namespace isolation to `config/routes.rb`: + + ```ruby + Blorgh::Engine.routes.draw do + end + ``` + + * Namespace isolation to `lib/blorgh/engine.rb`: + + ```ruby + module Blorgh + class Engine < ::Rails::Engine + isolate_namespace Blorgh + end + end + ``` + +Additionally, the `--mountable` option tells the generator to mount the engine inside the dummy testing application located at `test/dummy` by adding the following to the dummy application's routes file at `test/dummy/config/routes.rb`: ```ruby mount Blorgh::Engine, :at => "blorgh" @@ -130,7 +169,7 @@ end This line mounts the engine at the path `/blorgh`, which will make it accessible through the application only at that path. -Also in the test directory is the `test/integration` directory, where integration tests for the engine should be placed. Other directories can be created in the `test` directory also. For example, you may wish to create a `test/unit` directory for your unit tests. +Also in the test directory is the `test/integration` directory, where integration tests for the engine should be placed. Other directories can be created in the `test` directory also. For example, you may wish to create a `test/models` directory for your models tests. Providing engine functionality ------------------------------ @@ -152,7 +191,7 @@ invoke active_record create db/migrate/[timestamp]_create_blorgh_posts.rb create app/models/blorgh/post.rb invoke test_unit -create test/unit/blorgh/post_test.rb +create test/models/blorgh/post_test.rb create test/fixtures/blorgh/posts.yml route resources :posts invoke scaffold_controller @@ -165,11 +204,11 @@ create app/views/blorgh/posts/show.html.erb create app/views/blorgh/posts/new.html.erb create app/views/blorgh/posts/_form.html.erb invoke test_unit -create test/functional/blorgh/posts_controller_test.rb +create test/controllers/blorgh/posts_controller_test.rb invoke helper create app/helpers/blorgh/posts_helper.rb invoke test_unit -create test/unit/helpers/blorgh/posts_helper_test.rb +create test/helpers/blorgh/posts_helper_test.rb invoke assets invoke js create app/assets/javascripts/blorgh/posts.js @@ -181,7 +220,7 @@ create app/assets/stylesheets/scaffold.css The first thing that the scaffold generator does is invoke the `active_record` generator, which generates a migration and a model for the resource. Note here, however, that the migration is called `create_blorgh_posts` rather than the usual `create_posts`. This is due to the `isolate_namespace` method called in the `Blorgh::Engine` class's definition. The model here is also namespaced, being placed at `app/models/blorgh/post.rb` rather than `app/models/post.rb` due to the `isolate_namespace` call within the `Engine` class. -Next, the `test_unit` generator is invoked for this model, generating a unit test at `test/unit/blorgh/post_test.rb` (rather than `test/unit/post_test.rb`) and a fixture at `test/fixtures/blorgh/posts.yml` (rather than `test/fixtures/posts.yml`). +Next, the `test_unit` generator is invoked for this model, generating a model test at `test/models/blorgh/post_test.rb` (rather than `test/models/post_test.rb`) and a fixture at `test/fixtures/blorgh/posts.yml` (rather than `test/fixtures/posts.yml`). After that, a line for the resource is inserted into the `config/routes.rb` file for the engine. This line is simply `resources :posts`, turning the `config/routes.rb` file for the engine into this: @@ -193,7 +232,7 @@ end Note here that the routes are drawn upon the `Blorgh::Engine` object rather than the `YourApp::Application` class. This is so that the engine routes are confined to the engine itself and can be mounted at a specific point as shown in the [test directory](#test-directory) section. This is also what causes the engine's routes to be isolated from those routes that are within the application. This is discussed further in the [Routes](#routes) section of this guide. -Next, the `scaffold_controller` generator is invoked, generating a controller called `Blorgh::PostsController` (at `app/controllers/blorgh/posts_controller.rb`) and its related views at `app/views/blorgh/posts`. This generator also generates a functional test for the controller (`test/functional/blorgh/posts_controller_test.rb`) and a helper (`app/helpers/blorgh/posts_controller.rb`). +Next, the `scaffold_controller` generator is invoked, generating a controller called `Blorgh::PostsController` (at `app/controllers/blorgh/posts_controller.rb`) and its related views at `app/views/blorgh/posts`. This generator also generates a test for the controller (`test/controllers/blorgh/posts_controller_test.rb`) and a helper (`app/helpers/blorgh/posts_controller.rb`). Everything this generator has created is neatly namespaced. The controller's class is defined within the `Blorgh` module: @@ -261,7 +300,7 @@ invoke active_record create db/migrate/[timestamp]_create_blorgh_comments.rb create app/models/blorgh/comment.rb invoke test_unit -create test/unit/blorgh/comment_test.rb +create test/models/blorgh/comment_test.rb create test/fixtures/blorgh/comments.yml ``` @@ -334,11 +373,11 @@ create app/controllers/blorgh/comments_controller.rb invoke erb exist app/views/blorgh/comments invoke test_unit -create test/functional/blorgh/comments_controller_test.rb +create test/controllers/blorgh/comments_controller_test.rb invoke helper create app/helpers/blorgh/comments_helper.rb invoke test_unit -create test/unit/helpers/blorgh/comments_helper_test.rb +create test/helpers/blorgh/comments_helper_test.rb invoke assets invoke js create app/assets/javascripts/blorgh/comments.js diff --git a/guides/source/generators.md b/guides/source/generators.md index 0bcfa1dc68..d56bbe853c 100644 --- a/guides/source/generators.md +++ b/guides/source/generators.md @@ -176,7 +176,7 @@ $ rails generate scaffold User name:string create db/migrate/20091120125558_create_users.rb create app/models/user.rb invoke test_unit - create test/unit/user_test.rb + create test/models/user_test.rb create test/fixtures/users.yml route resources :users invoke scaffold_controller @@ -189,11 +189,11 @@ $ rails generate scaffold User name:string create app/views/users/new.html.erb create app/views/users/_form.html.erb invoke test_unit - create test/functional/users_controller_test.rb + create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb invoke test_unit - create test/unit/helpers/users_helper_test.rb + create test/helpers/users_helper_test.rb invoke stylesheets create app/assets/stylesheets/scaffold.css ``` @@ -350,7 +350,7 @@ $ rails generate scaffold Comment body:text create db/migrate/20091120151323_create_comments.rb create app/models/comment.rb invoke shoulda - create test/unit/comment_test.rb + create test/models/comment_test.rb create test/fixtures/comments.yml route resources :comments invoke scaffold_controller @@ -364,11 +364,11 @@ $ rails generate scaffold Comment body:text create app/views/comments/_form.html.erb create app/views/layouts/comments.html.erb invoke shoulda - create test/functional/comments_controller_test.rb + create test/controllers/comments_controller_test.rb invoke my_helper create app/helpers/comments_helper.rb invoke shoulda - create test/unit/helpers/comments_helper_test.rb + create test/helpers/comments_helper_test.rb ``` Fallbacks allow your generators to have a single responsibility, increasing code reuse and reducing the amount of duplication. diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 28adad3855..9f23f9fc42 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -77,10 +77,17 @@ TIP: The examples below use # and $ to denote superuser and regular user termina ### Installing Rails +Open up a command line prompt. On a mac this is called terminal, on windows it is called command prompt. Any commands prefaced with a dollar sign `$` should be run in the command line. Verify sure you have a current version of Ruby installed: + +```bash +$ ruby -v +ruby 1.9.3p194 +``` + To install Rails, use the `gem install` command provided by RubyGems: ```bash -# gem install rails +$ gem install rails ``` TIP. A number of tools exist to help you quickly install Ruby and Ruby @@ -154,11 +161,11 @@ $ rails server TIP: Compiling CoffeeScript to JavaScript requires a JavaScript runtime and the absence of a runtime will give you an `execjs` error. Usually Mac OS X and Windows come with a JavaScript runtime installed. Rails adds the `therubyracer` gem to Gemfile in a commented line for new apps and you can uncomment if you need it. `therubyrhino` is the recommended runtime for JRuby users and is added by default to Gemfile in apps generated under JRuby. You can investigate about all the supported runtimes at [ExecJS](https://github.com/sstephenson/execjs#readme). -This will fire up WEBrick, a webserver built into Ruby by default. To see your application in action, open a browser window and navigate to [http://localhost:3000](http://localhost:3000). You should see the Rails default information page: +This will fire up WEBrick, a webserver built into Ruby by default. To see your application in action, open a browser window and navigate to <http://localhost:3000>. You should see the Rails default information page:  -TIP: To stop the web server, hit Ctrl+C in the terminal window where it's running. In development mode, Rails does not generally require you to restart the server; changes you make in files will be automatically picked up by the server. +TIP: To stop the web server, hit Ctrl+C in the terminal window where it's running. To verify the server has stopped you should see your command prompt cursor again. For most unix like systems including mac this will be a dollar sign `$`. In development mode, Rails does not generally require you to restart the server; changes you make in files will be automatically picked up by the server. The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. You can also click on the _About your application’s environment_ link to see a summary of your application's environment. @@ -185,11 +192,11 @@ invoke erb create app/views/welcome create app/views/welcome/index.html.erb invoke test_unit -create test/functional/welcome_controller_test.rb +create test/controllers/welcome_controller_test.rb invoke helper create app/helpers/welcome_helper.rb invoke test_unit -create test/unit/helpers/welcome_helper_test.rb +create test/helpers/welcome_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/welcome.js.coffee @@ -207,11 +214,11 @@ Open the `app/views/welcome/index.html.erb` file in your text editor and edit it ### Setting the Application Home Page -Now that we have made the controller and view, we need to tell Rails when we want Hello Rails! to show up. In our case, we want it to show up when we navigate to the root URL of our site, [http://localhost:3000](http://localhost:3000). At the moment, however, the "Welcome Aboard" smoke test is occupying that spot. +Now that we have made the controller and view, we need to tell Rails when we want Hello Rails! to show up. In our case, we want it to show up when we navigate to the root URL of our site, <http://localhost:3000>. At the moment, however, the "Welcome Aboard" smoke test is occupying that spot. To fix this, delete the `index.html` file located inside the `public` directory of the application. -You need to do this because Rails will serve any static file in the `public` directory that matches a route in preference to any dynamic content you generate from the controllers. The `index.html` file is special: it will be served if a request comes in at the root route, e.g. [http://localhost:3000](http://localhost:3000). If another request such as [http://localhost:3000/welcome](http://localhost:3000/welcome) happened, a static file at `public/welcome.html` would be served first, but only if it existed. +You need to do this because Rails will serve any static file in the `public` directory that matches a route in preference to any dynamic content you generate from the controllers. The `index.html` file is special: it will be served if a request comes in at the root route, e.g. <http://localhost:3000>. If another request such as <http://localhost:3000/welcome> happened, a static file at `public/welcome.html` would be served first, but only if it existed. Next, you have to tell Rails where your actual home page is located. @@ -235,9 +242,9 @@ This is your application's _routing file_ which holds entries in a special DSL ( root :to => "welcome#index" ``` -The `root :to => "welcome#index"` tells Rails to map requests to the root of the application to the welcome controller's index action and `get "welcome/index"` tells Rails to map requests to [http://localhost:3000/welcome/index](http://localhost:3000/welcome/index) to the welcome controller's index action. This was created earlier when you ran the controller generator (`rails generate controller welcome index`). +The `root :to => "welcome#index"` tells Rails to map requests to the root of the application to the welcome controller's index action and `get "welcome/index"` tells Rails to map requests to <http://localhost:3000/welcome/index> to the welcome controller's index action. This was created earlier when you ran the controller generator (`rails generate controller welcome index`). -If you navigate to [http://localhost:3000](http://localhost:3000) in your browser, you'll see the `Hello, Rails!` message you put into `app/views/welcome/index.html.erb`, indicating that this new route is indeed going to `WelcomeController`'s `index` action and is rendering the view correctly. +If you navigate to <http://localhost:3000> in your browser, you'll see the `Hello, Rails!` message you put into `app/views/welcome/index.html.erb`, indicating that this new route is indeed going to `WelcomeController`'s `index` action and is rendering the view correctly. NOTE. For more information about routing, refer to [Rails Routing from the Outside In](routing.html). @@ -256,7 +263,7 @@ It will look a little basic for now, but that's ok. We'll look at improving the ### Laying down the ground work -The first thing that you are going to need to create a new post within the application is a place to do that. A great place for that would be at `/posts/new`. If you attempt to navigate to that now -- by visiting [http://localhost:3000/posts/new](http://localhost:3000/posts/new) -- Rails will give you a routing error: +The first thing that you are going to need to create a new post within the application is a place to do that. A great place for that would be at `/posts/new`. If you attempt to navigate to that now -- by visiting <http://localhost:3000/posts/new> -- Rails will give you a routing error:  @@ -270,7 +277,7 @@ get "posts/new" This route is a super-simple route: it defines a new route that only responds to `GET` requests, and that the route is at `posts/new`. But how does it know where to go without the use of the `:to` option? Well, Rails uses a sensible default here: Rails will assume that you want this route to go to the new action inside the posts controller. -With the route defined, requests can now be made to `/posts/new` in the application. Navigate to [http://localhost:3000/posts/new](http://localhost:3000/posts/new) and you'll see another routing error: +With the route defined, requests can now be made to `/posts/new` in the application. Navigate to <http://localhost:3000/posts/new> and you'll see another routing error:  @@ -289,7 +296,7 @@ end A controller is simply a class that is defined to inherit from `ApplicationController`. It's inside this class that you'll define methods that will become the actions for this controller. These actions will perform CRUD operations on the posts within our system. -If you refresh [http://localhost:3000/posts/new](http://localhost:3000/posts/new) now, you'll get a new error: +If you refresh <http://localhost:3000/posts/new> now, you'll get a new error:  @@ -302,7 +309,7 @@ def new end ``` -With the `new` method defined in `PostsController`, if you refresh [http://localhost:3000/posts/new](http://localhost:3000/posts/new) you'll see another error: +With the `new` method defined in `PostsController`, if you refresh <http://localhost:3000/posts/new> you'll see another error:  @@ -330,7 +337,7 @@ Go ahead now and create a new file at `app/views/posts/new.html.erb` and write t <h1>New Post</h1> ``` -When you refresh [http://localhost:3000/posts/new](http://localhost:3000/posts/new) you'll now see that the page has a title. The route, controller, action and view are now working harmoniously! It's time to create the form for a new post. +When you refresh <http://localhost:3000/posts/new> you'll now see that the page has a title. The route, controller, action and view are now working harmoniously! It's time to create the form for a new post. ### The first form @@ -579,7 +586,7 @@ content: ``` Finally, if you now go to -[http://localhost:3000/posts/new](http://localhost:3000/posts/new) you'll +<http://localhost:3000/posts/new> you'll be able to create a post. Try it!  @@ -756,7 +763,7 @@ Notice that inside the `create` action we use `render` instead of `redirect_to` returns `false`. The `render` method is used so that the `@post` object is passed back to the `new` template when it is rendered. This rendering is done within the same request as the form submission, whereas the `redirect_to` will tell the browser to issue another request. If you reload -[http://localhost:3000/posts/new](http://localhost:3000/posts/new) and +<http://localhost:3000/posts/new> and try to save a post without a title, Rails will send you back to the form, but that's not very useful. You need to tell the user that something went wrong. To do that, you'll modify @@ -1037,7 +1044,7 @@ Then do the same for the `app/views/posts/edit.html.erb` view: <%= link_to 'Back', :action => :index %> ``` -Point your browser to [http://localhost:3000/posts/new](http://localhost:3000/posts/new) and +Point your browser to <http://localhost:3000/posts/new> and try creating a new post. Everything still works. Now try editing the post and you'll receive the following error: @@ -1057,10 +1064,10 @@ If you run `rake routes` from the console you'll see that we already have a `posts_path` route, which was created automatically by Rails when we defined the route for the index action. However, we don't have a `post_path` yet, which is the reason why we -received an error before. +received an error before. With your server running you can view your routes by visiting [localhost:3000/rails/info/routes](http://localhost:3000/rails/info/routes), or you can generate them from the command line by running `rake routes`: ```bash -# rake routes +$ rake routes posts GET /posts(.:format) posts#index posts_new GET /posts/new(.:format) posts#new @@ -1198,7 +1205,7 @@ If you run `rake routes`, you'll see that all the routes that we declared before are still available: ```bash -# rake routes +$ rake routes posts GET /posts(.:format) posts#index POST /posts(.:format) posts#create new_post GET /posts/new(.:format) posts#new @@ -1239,7 +1246,7 @@ This command will generate four files: | -------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | db/migrate/20100207235629_create_comments.rb | Migration to create the comments table in your database (your name will include a different timestamp) | | app/models/comment.rb | The Comment model | -| test/unit/comment_test.rb | Unit testing harness for the comments model | +| test/models/comment_test.rb | Testing harness for the comments model | | test/fixtures/comments.yml | Sample comments for use in testing | First, take a look at `comment.rb`: @@ -1360,15 +1367,15 @@ $ rails generate controller Comments This creates six files and one empty directory: -| File/Directory | Purpose | -| ------------------------------------------- | ---------------------------------------- | -| app/controllers/comments_controller.rb | The Comments controller | -| app/views/comments/ | Views of the controller are stored here | -| test/functional/comments_controller_test.rb | The functional tests for the controller | -| app/helpers/comments_helper.rb | A view helper file | -| test/unit/helpers/comments_helper_test.rb | The unit tests for the helper | -| app/assets/javascripts/comment.js.coffee | CoffeeScript for the controller | -| app/assets/stylesheets/comment.css.scss | Cascading style sheet for the controller | +| File/Directory | Purpose | +| -------------------------------------------- | ---------------------------------------- | +| app/controllers/comments_controller.rb | The Comments controller | +| app/views/comments/ | Views of the controller are stored here | +| test/controllers/comments_controller_test.rb | The test for the controller | +| app/helpers/comments_helper.rb | A view helper file | +| test/helpers/comments_helper_test.rb | The test for the helper | +| app/assets/javascripts/comment.js.coffee | CoffeeScript for the controller | +| app/assets/stylesheets/comment.css.scss | Cascading style sheet for the controller | Like with any blog, our readers will create their comments directly after reading the post, and once they have added their comment, will be sent back to diff --git a/guides/source/i18n.md b/guides/source/i18n.md index a3c6b514a4..eda1881e73 100644 --- a/guides/source/i18n.md +++ b/guides/source/i18n.md @@ -94,13 +94,13 @@ This means, that in the `:en` locale, the key _hello_ will map to the _Hello wor The I18n library will use **English** as a **default locale**, i.e. if you don't set a different locale, `:en` will be used for looking up translations. -NOTE: The i18n library takes a **pragmatic approach** to locale keys (after [some discussion](http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like `:en`, `:pl`, not the _region_ part, like `:en-US` or `:en-GB`, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as `:cs`, `:th` or `:es` (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the `:en-US` locale you would have $ as a currency symbol, while in `:en-GB`, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a `:en-GB` dictionary. Various [Rails I18n plugins](http://rails-i18n.org/wiki) such as [Globalize2](ht) +NOTE: The i18n library takes a **pragmatic approach** to locale keys (after [some discussion](http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like `:en`, `:pl`, not the _region_ part, like `:en-US` or `:en-GB`, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as `:cs`, `:th` or `:es` (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the `:en-US` locale you would have $ as a currency symbol, while in `:en-GB`, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a `:en-GB` dictionary. Various [Rails I18n plugins](http://rails-i18n.org/wiki) such as [Globalize2](https://github.com/joshmh/globalize2/tree/master) may help you implement it. The **translations load path** (`I18n.load_path`) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you. NOTE: The backend will lazy-load these translations when a translation is looked up for the first time. This makes it possible to just swap the backend with something else even after translations have already been announced. -The default `application.rb` files has instructions on how to add locales from another directory and how to set a different default locale. Just uncomment and edit the specific lines. +The default initializer `locale.rb` file has instructions on how to add locales from another directory and how to set a different default locale. Just uncomment and edit the specific lines. ```ruby # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. diff --git a/guides/source/initialization.md b/guides/source/initialization.md index c760a18dda..c582acd3a3 100644 --- a/guides/source/initialization.md +++ b/guides/source/initialization.md @@ -367,7 +367,7 @@ on your needs. ### `Rails::Server#start` -After `congif/application` is loaded, `server.start` is called. This method is defined like this: +After `config/application` is loaded, `server.start` is called. This method is defined like this: ```ruby def start diff --git a/guides/source/migrations.md b/guides/source/migrations.md index 705b65ee8b..67538b85e8 100644 --- a/guides/source/migrations.md +++ b/guides/source/migrations.md @@ -85,7 +85,7 @@ existing users. ### Using the change method -Rails 3.1 makes migrations smarter by providing a new `change` method. +Rails 3.1 and up makes migrations smarter by providing a `change` method. This method is preferred for writing constructive migrations (adding columns or tables). The migration knows how to migrate your database and reverse it when the migration is rolled back without the need to write a separate `down` method. @@ -235,6 +235,8 @@ adding these columns will also be created. For example, running $ rails generate model Product name:string description:text ``` +TIP: All lines starting with a dollar sign `$` are intended to be run on the command line. + will create a migration that looks like this ```ruby @@ -544,7 +546,7 @@ support](#active-record-and-referential-integrity). If the helpers provided by Active Record aren't enough you can use the `execute` method to execute arbitrary SQL. -For more details and examples of individual methods, check the API documentation. +For more details and examples of individual methods, check the API documentation. In particular the documentation for [`ActiveRecord::ConnectionAdapters::SchemaStatements`](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html) (which provides the methods available in the `up` and `down` methods), @@ -700,6 +702,14 @@ will run the `up` method from the 20080906120000 migration. This task will first check whether the migration is already performed and will do nothing if Active Record believes that it has already been run. +### Running Migrations in Different Environments + +By default running `rake db:migrate` will run in the `development` environment. To run migrations against another environment you can specify it using the `RAILS_ENV` environment variable while running the command. For example to run migrations against the `test` environment you could run: + +```bash +$ rake db:migrate RAILS_ENV=test +``` + ### Changing the Output of Running Migrations By default migrations tell you exactly what they're doing and how long it took. diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md index 0e59395c8a..ba96c0c0a9 100644 --- a/guides/source/rails_on_rack.md +++ b/guides/source/rails_on_rack.md @@ -162,8 +162,8 @@ You can add a new middleware to the middleware stack using any of the following config.middleware.use Rack::BounceFavicon # Add Lifo::Cache after ActiveRecord::QueryCache. -# Pass { :page_cache => false } argument to Lifo::Cache. -config.middleware.insert_after ActiveRecord::QueryCache, Lifo::Cache, :page_cache => false +# Pass { page_cache: false } argument to Lifo::Cache. +config.middleware.insert_after ActiveRecord::QueryCache, Lifo::Cache, page_cache: false ``` #### Swapping a Middleware diff --git a/guides/source/routing.md b/guides/source/routing.md index 3acb7fa0e5..469fcf49fb 100644 --- a/guides/source/routing.md +++ b/guides/source/routing.md @@ -30,14 +30,14 @@ it asks the router to match it to a controller action. If the first matching rou get "/patients/:id" => "patients#show" ``` -the request is dispatched to the `patients` controller's `show` action with `{ :id => "17" }` in `params`. +the request is dispatched to the `patients` controller's `show` action with `{ id: "17" }` in `params`. ### Generating Paths and URLs from Code You can also generate paths and URLs. If the route above is modified to be ```ruby -get "/patients/:id" => "patients#show", :as => "patient" +get "/patients/:id" => "patients#show", as: "patient" ``` If your application contains this code: @@ -73,7 +73,7 @@ it asks the router to map it to a controller action. If the first matching route resources :photos ``` -Rails would dispatch that request to the `destroy` method on the `photos` controller with `{ :id => "17" }` in `params`. +Rails would dispatch that request to the `destroy` method on the `photos` controller with `{ id: "17" }` in `params`. ### CRUD, Verbs, and Actions @@ -186,7 +186,7 @@ This will create a number of routes for each of the `posts` and `comments` contr If you want to route `/posts` (without the prefix `/admin`) to `Admin::PostsController`, you could use ```ruby -scope :module => "admin" do +scope module: "admin" do resources :posts, :comments end ``` @@ -194,7 +194,7 @@ end or, for a single case ```ruby -resources :posts, :module => "admin" +resources :posts, module: "admin" ``` If you want to route `/admin/posts` to `PostsController` (without the `Admin::` module prefix), you could use @@ -208,7 +208,7 @@ end or, for a single case ```ruby -resources :posts, :path => "/admin/posts" +resources :posts, path: "/admin/posts" ``` In each of these cases, the named routes remain the same as if you did not use `scope`. In the last case, the following paths map to `PostsController`: @@ -375,7 +375,7 @@ Within the block of member routes, each route name specifies the HTTP verb that ```ruby resources :photos do - get 'preview', :on => :member + get 'preview', on: :member end ``` @@ -397,7 +397,7 @@ Just as with member routes, you can pass `:on` to a route: ```ruby resources :photos do - get 'search', :on => :collection + get 'search', on: :collection end ``` @@ -407,7 +407,7 @@ To add an alternate new action using the `:on` shortcut: ```ruby resources :comments do - get 'preview', :on => :new + get 'preview', on: :new end ``` @@ -449,10 +449,10 @@ An incoming path of `/photos/show/1/2` will be dispatched to the `show` action o NOTE: You can't use `:namespace` or `:module` with a `:controller` path segment. If you need to do this then use a constraint on :controller that matches the namespace you require. e.g: ```ruby -get ':controller(/:action(/:id))', :controller => /admin\/[^\/]+/ +get ':controller(/:action(/:id))', controller: /admin\/[^\/]+/ ``` -TIP: By default dynamic segments don't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment, add a constraint that overrides this – for example, `:id => /[^\/]+/` allows anything except a slash. +TIP: By default dynamic segments don't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment, add a constraint that overrides this – for example, `id: /[^\/]+/` allows anything except a slash. ### Static Segments @@ -462,7 +462,7 @@ You can specify static segments when creating a route: get ':controller/:action/:id/with_user/:user_id' ``` -This route would respond to paths such as `/photos/show/1/with_user/2`. In this case, `params` would be `{ :controller => "photos", :action => "show", :id => "1", :user_id => "2" }`. +This route would respond to paths such as `/photos/show/1/with_user/2`. In this case, `params` would be `{ controller: "photos", action: "show", id: "1", user_id: "2" }`. ### The Query String @@ -472,7 +472,7 @@ The `params` will also include any parameters from the query string. For example get ':controller/:action/:id' ``` -An incoming path of `/photos/show/1?user_id=2` will be dispatched to the `show` action of the `Photos` controller. `params` will be `{ :controller => "photos", :action => "show", :id => "1", :user_id => "2" }`. +An incoming path of `/photos/show/1?user_id=2` will be dispatched to the `show` action of the `Photos` controller. `params` will be `{ controller: "photos", action: "show", id: "1", user_id: "2" }`. ### Defining Defaults @@ -487,7 +487,7 @@ With this route, Rails will match an incoming path of `/photos/12` to the `show` You can also define other defaults in a route by supplying a hash for the `:defaults` option. This even applies to parameters that you do not specify as dynamic segments. For example: ```ruby -get 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' } +get 'photos/:id' => 'photos#show', defaults: { format: 'jpg' } ``` Rails would match `photos/12` to the `show` action of `PhotosController`, and set `params[:format]` to `"jpg"`. @@ -497,7 +497,7 @@ Rails would match `photos/12` to the `show` action of `PhotosController`, and se You can specify a name for any route using the `:as` option. ```ruby -get 'exit' => 'sessions#destroy', :as => :logout +get 'exit' => 'sessions#destroy', as: :logout ``` This will create `logout_path` and `logout_url` as named helpers in your application. Calling `logout_path` will return `/exit` @@ -505,7 +505,7 @@ This will create `logout_path` and `logout_url` as named helpers in your applica You can also use this to override routing methods defined by resources, like this: ```ruby -get ':username', :to => "users#show", :as => :user +get ':username', to: "users#show", as: :user ``` This will define a `user_path` method that will be available in controllers, helpers and views that will go to a route such as `/bob`. Inside the `show` action of `UsersController`, `params[:username]` will contain the username for the user. Change `:username` in the route definition if you do not want your parameter name to be `:username`. @@ -515,13 +515,13 @@ This will define a `user_path` method that will be available in controllers, hel In general, you should use the `get`, `post`, `put` and `delete` methods to constrain a route to a particular verb. You can use the `match` method with the `:via` option to match multiple verbs at once: ```ruby -match 'photos' => 'photos#show', :via => [:get, :post] +match 'photos' => 'photos#show', via: [:get, :post] ``` -You can match all verbs to a particular route using `:via => :all`: +You can match all verbs to a particular route using `via: :all`: ```ruby -match 'photos' => 'photos#show', :via => :all +match 'photos' => 'photos#show', via: :all ``` You should avoid routing all verbs to an action unless you have a good reason to, as routing both `GET` requests and `POST` requests to a single action has security implications. @@ -531,19 +531,19 @@ You should avoid routing all verbs to an action unless you have a good reason to You can use the `:constraints` option to enforce a format for a dynamic segment: ```ruby -get 'photos/:id' => 'photos#show', :constraints => { :id => /[A-Z]\d{5}/ } +get 'photos/:id' => 'photos#show', constraints: { id: /[A-Z]\d{5}/ } ``` This route would match paths such as `/photos/A12345`. You can more succinctly express the same route this way: ```ruby -get 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/ +get 'photos/:id' => 'photos#show', id: /[A-Z]\d{5}/ ``` `:constraints` takes regular expressions with the restriction that regexp anchors can't be used. For example, the following route will not work: ```ruby -get '/:id' => 'posts#show', :constraints => {:id => /^\d/} +get '/:id' => 'posts#show', constraints: {id: /^\d/} ``` However, note that you don't need to use anchors because all routes are anchored at the start. @@ -551,7 +551,7 @@ However, note that you don't need to use anchors because all routes are anchored For example, the following routes would allow for `posts` with `to_param` values like `1-hello-world` that always begin with a number and `users` with `to_param` values like `david` that never begin with a number to share the root namespace: ```ruby -get '/:id' => 'posts#show', :constraints => { :id => /\d.+/ } +get '/:id' => 'posts#show', constraints: { id: /\d.+/ } get '/:username' => 'users#show' ``` @@ -562,14 +562,14 @@ You can also constrain a route based on any method on the <a href="action_contro You specify a request-based constraint the same way that you specify a segment constraint: ```ruby -get "photos", :constraints => {:subdomain => "admin"} +get "photos", constraints: {subdomain: "admin"} ``` You can also specify constraints in a block form: ```ruby namespace :admin do - constraints :subdomain => "admin" do + constraints subdomain: "admin" do resources :photos end end @@ -592,7 +592,7 @@ end TwitterClone::Application.routes.draw do get "*path" => "blacklist#index", - :constraints => BlacklistConstraint.new + constraints: BlacklistConstraint.new end ``` @@ -601,7 +601,7 @@ You can also specify constraints as a lambda: ```ruby TwitterClone::Application.routes.draw do get "*path" => "blacklist#index", - :constraints => lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) } + constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) } end ``` @@ -639,16 +639,16 @@ NOTE: Starting from Rails 3.1, wildcard routes will always match the optional fo get '*pages' => 'pages#show' ``` -NOTE: By requesting `"/foo/bar.json"`, your `params[:pages]` will be equals to `"foo/bar"` with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `:format => false` like this: +NOTE: By requesting `"/foo/bar.json"`, your `params[:pages]` will be equals to `"foo/bar"` with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `format: false` like this: ```ruby -get '*pages' => 'pages#show', :format => false +get '*pages' => 'pages#show', format: false ``` -NOTE: If you want to make the format segment mandatory, so it cannot be omitted, you can supply `:format => true` like this: +NOTE: If you want to make the format segment mandatory, so it cannot be omitted, you can supply `format: true` like this: ```ruby -get '*pages' => 'pages#show', :format => true +get '*pages' => 'pages#show', format: true ``` ### Redirection @@ -681,10 +681,10 @@ In all of these cases, if you don't provide the leading host (`http://www.exampl Instead of a String, like `"posts#index"`, which corresponds to the `index` action in the `PostsController`, you can specify any <a href="rails_on_rack.html">Rack application</a> as the endpoint for a matcher. ```ruby -match "/application.js" => Sprockets, :via => :all +match "/application.js" => Sprockets, via: :all ``` -As long as `Sprockets` responds to `call` and returns a `[status, headers, body]`, the router won't know the difference between the Rack application and an action. This is an appropriate use of `:via => :all`, as you will want to allow your Rack application to handle all verbs as it considers appropriate. +As long as `Sprockets` responds to `call` and returns a `[status, headers, body]`, the router won't know the difference between the Rack application and an action. This is an appropriate use of `via: :all`, as you will want to allow your Rack application to handle all verbs as it considers appropriate. NOTE: For the curious, `"posts#index"` actually expands out to `PostsController.action(:index)`, which returns a valid Rack application. @@ -693,7 +693,7 @@ NOTE: For the curious, `"posts#index"` actually expands out to `PostsController. You can specify what Rails should route `"/"` to with the `root` method: ```ruby -root :to => 'pages#main' +root to: 'pages#main' root 'pages#main' # shortcut for the above ``` @@ -719,7 +719,7 @@ While the default routes and helpers generated by `resources :posts` will usuall The `:controller` option lets you explicitly specify a controller to use for the resource. For example: ```ruby -resources :photos, :controller => "images" +resources :photos, controller: "images" ``` will recognize incoming paths beginning with `/photos` but route to the `Images` controller: @@ -741,7 +741,7 @@ NOTE: Use `photos_path`, `new_photo_path`, etc. to generate paths for this resou You can use the `:constraints` option to specify a required format on the implicit `id`. For example: ```ruby -resources :photos, :constraints => {:id => /[A-Z][A-Z][0-9]+/} +resources :photos, constraints: {id: /[A-Z][A-Z][0-9]+/} ``` This declaration constrains the `:id` parameter to match the supplied regular expression. So, in this case, the router would no longer match `/photos/1` to this route. Instead, `/photos/RR27` would match. @@ -749,7 +749,7 @@ This declaration constrains the `:id` parameter to match the supplied regular ex You can specify a single constraint to apply to a number of routes by using the block form: ```ruby -constraints(:id => /[A-Z][A-Z][0-9]+/) do +constraints(id: /[A-Z][A-Z][0-9]+/) do resources :photos resources :accounts end @@ -757,14 +757,14 @@ end NOTE: Of course, you can use the more advanced constraints available in non-resourceful routes in this context. -TIP: By default the `:id` parameter doesn't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within an `:id` add a constraint which overrides this - for example `:id => /[^\/]+/` allows anything except a slash. +TIP: By default the `:id` parameter doesn't accept dots - this is because the dot is used as a separator for formatted routes. If you need to use a dot within an `:id` add a constraint which overrides this - for example `id: /[^\/]+/` allows anything except a slash. ### Overriding the Named Helpers The `:as` option lets you override the normal naming for the named route helpers. For example: ```ruby -resources :photos, :as => "images" +resources :photos, as: "images" ``` will recognize incoming paths beginning with `/photos` and route the requests to `PhotosController`, but use the value of the :as option to name the helpers. @@ -784,7 +784,7 @@ will recognize incoming paths beginning with `/photos` and route the requests to The `:path_names` option lets you override the automatically-generated "new" and "edit" segments in paths: ```ruby -resources :photos, :path_names => { :new => 'make', :edit => 'change' } +resources :photos, path_names: { new: 'make', edit: 'change' } ``` This would cause the routing to recognize paths such as @@ -799,7 +799,7 @@ NOTE: The actual action names aren't changed by this option. The two paths shown TIP: If you find yourself wanting to change this option uniformly for all of your routes, you can use a scope. ```ruby -scope :path_names => { :new => "make" } do +scope path_names: { new: "make" } do # rest of your routes end ``` @@ -810,7 +810,7 @@ You can use the `:as` option to prefix the named route helpers that Rails genera ```ruby scope "admin" do - resources :photos, :as => "admin_photos" + resources :photos, as: "admin_photos" end resources :photos @@ -821,7 +821,7 @@ This will provide route helpers such as `admin_photos_path`, `new_admin_photo_pa To prefix a group of route helpers, use `:as` with `scope`: ```ruby -scope "admin", :as => "admin" do +scope "admin", as: "admin" do resources :photos, :accounts end @@ -847,7 +847,7 @@ This will provide you with URLs such as `/bob/posts/1` and will allow you to ref By default, Rails creates routes for the seven default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application. You can use the `:only` and `:except` options to fine-tune this behavior. The `:only` option tells Rails to create only the specified routes: ```ruby -resources :photos, :only => [:index, :show] +resources :photos, only: [:index, :show] ``` Now, a `GET` request to `/photos` would succeed, but a `POST` request to `/photos` (which would ordinarily be routed to the `create` action) will fail. @@ -855,7 +855,7 @@ Now, a `GET` request to `/photos` would succeed, but a `POST` request to `/photo The `:except` option specifies a route or list of routes that Rails should _not_ create: ```ruby -resources :photos, :except => :destroy +resources :photos, except: :destroy ``` In this case, Rails will create all of the normal routes except the route for `destroy` (a `DELETE` request to `/photos/:id`). @@ -867,8 +867,8 @@ TIP: If your application has many RESTful routes, using `:only` and `:except` to Using `scope`, we can alter path names generated by resources: ```ruby -scope(:path_names => { :new => "neu", :edit => "bearbeiten" }) do - resources :categories, :path => "kategorien" +scope(path_names: { new: "neu", edit: "bearbeiten" }) do + resources :categories, path: "kategorien" end ``` @@ -900,7 +900,7 @@ The `:as` option overrides the automatically-generated name for the resource in ```ruby resources :magazines do - resources :ads, :as => 'periodical_ads' + resources :ads, as: 'periodical_ads' end ``` @@ -952,8 +952,8 @@ Routes should be included in your testing strategy (just like the rest of your a `assert_generates` asserts that a particular set of options generate a particular path and can be used with default routes or custom routes. ```ruby -assert_generates "/photos/1", { :controller => "photos", :action => "show", :id => "1" } -assert_generates "/about", :controller => "pages", :action => "about" +assert_generates "/photos/1", { controller: "photos", action: "show", id: "1" } +assert_generates "/about", controller: "pages", action: "about" ``` #### The `assert_recognizes` Assertion @@ -961,13 +961,13 @@ assert_generates "/about", :controller => "pages", :action => "about" `assert_recognizes` is the inverse of `assert_generates`. It asserts that a given path is recognized and routes it to a particular spot in your application. ```ruby -assert_recognizes({ :controller => "photos", :action => "show", :id => "1" }, "/photos/1") +assert_recognizes({ controller: "photos", action: "show", id: "1" }, "/photos/1") ``` You can supply a `:method` argument to specify the HTTP verb: ```ruby -assert_recognizes({ :controller => "photos", :action => "create" }, { :path => "photos", :method => :post }) +assert_recognizes({ controller: "photos", action: "create" }, { path: "photos", method: :post }) ``` #### The `assert_routing` Assertion @@ -975,5 +975,5 @@ assert_recognizes({ :controller => "photos", :action => "create" }, { :path => " The `assert_routing` assertion checks the route both ways: it tests that the path generates the options, and that the options generate the path. Thus, it combines the functions of `assert_generates` and `assert_recognizes`. ```ruby -assert_routing({ :path => "photos", :method => :post }, { :controller => "photos", :action => "create" }) +assert_routing({ path: "photos", method: :post }, { controller: "photos", action: "create" }) ``` diff --git a/guides/source/security.md b/guides/source/security.md index 0186386059..5ef68d2272 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -96,8 +96,8 @@ That means the security of this storage depends on this secret (and on the diges ```ruby config.action_dispatch.session = { - :key => '_app_session', - :secret => '0x0dkfj3927dkc7djdh36rkckdfzsg...' + key: '_app_session', + secret: '0x0dkfj3927dkc7djdh36rkckdfzsg...' } ``` @@ -233,7 +233,7 @@ Or the attacker places the code into the onmouseover event handler of an image: There are many other possibilities, including Ajax to attack the victim in the background.
The _solution to this is including a security token in non-GET requests_ which check on the server-side. In Rails 2 or higher, this is a one-liner in the application controller: ```ruby -protect_from_forgery :secret => "123456789012345678901234567890..." +protect_from_forgery secret: "123456789012345678901234567890..." ``` This will automatically include a security token, calculated from the current session and the server-side secret, in all forms and Ajax requests generated by Rails. You won't need the secret, if you use CookieStorage as session storage. If the security token doesn't match what was expected, the session will be reset. **Note:** In Rails versions prior to 3.0.4, this raised an `ActionController::InvalidAuthenticityToken` error. @@ -264,7 +264,7 @@ Whenever the user is allowed to pass (parts of) the URL for redirection, it is p ```ruby def legacy - redirect_to(params.update(:action=>'main')) + redirect_to(params.update(action:'main')) end ``` @@ -334,7 +334,7 @@ basename = File.expand_path(File.join(File.dirname(__FILE__), '../../files')) filename = File.expand_path(File.join(basename, @file.public_filename)) raise if basename != File.expand_path(File.join(File.dirname(filename), '../../../')) -send_file filename, :disposition => 'inline' +send_file filename, disposition: 'inline' ``` Another (additional) approach is to store the file names in the database and name the files on the disk after the ids in the database. This is also a good approach to avoid possible code in an uploaded file to be executed. The attachment_fu plugin does this in a similar way. @@ -383,7 +383,7 @@ any model's attributes by manipulating the hash passed to a model's `new()` meth ```ruby def signup - params[:user] # => {:name=>"ow3ned", :admin=>true} + params[:user] # => {name:"ow3ned", admin:true} @user = User.new(params[:user]) end ``` @@ -402,7 +402,7 @@ http://www.example.com/user/signup?user[name]=ow3ned&user[admin]=1 This will set the following parameters in the controller: ```ruby -params[:user] # => {:name=>"ow3ned", :admin=>true} +params[:user] # => {name:"ow3ned", admin:true} ``` So if you create a new user using mass-assignment, it may be too easy to become @@ -459,9 +459,9 @@ should be allowed for mass updating using the slice pattern. For example: ```ruby def signup params[:user] - # => {:name=>"ow3ned", :admin=>true} + # => {name:"ow3ned", admin:true} permitted_params = params.require(:user).permit(:name) - # => {:name=>"ow3ned"} + # => {name:"ow3ned"} @user = User.new(permitted_params) end @@ -499,10 +499,11 @@ attributes. ```ruby def user_params - filters = [:name] - filters << :admin if current_user.try(:admin?) - - params.require(:user).permit(*filters) + if current_user.admin? + params.require(:user).permit(:name, :admin) + else + params.require(:user).permit(:name) + end end ``` @@ -647,7 +648,7 @@ Since this is a frequent mistake, the format validator (validates_format_of) now ```ruby # content should include a line "Meanwhile" anywhere in the string - validates :content, :format => { :with => /^Meanwhile$/, :multiline => true } + validates :content, format: { with: /^Meanwhile$/, multiline: true } ``` Note that this only protects you against the most common mistake when using the format validator - you always need to keep in mind that ^ and $ match the **line** beginning and line end in Ruby, and not the beginning and end of a string. @@ -685,7 +686,7 @@ NOTE: _When sanitizing, protecting or verifying something, whitelists over black A blacklist can be a list of bad e-mail addresses, non-public actions or bad HTML tags. This is opposed to a whitelist which lists the good e-mail addresses, public actions, good HTML tags and so on. Although sometimes it is not possible to create a whitelist (in a SPAM filter, for example), _prefer to use whitelist approaches_: -* Use before_filter :only => [...] instead of :except => [...]. This way you don't forget to turn it off for newly added actions. +* Use before_filter only: [...] instead of except: [...]. This way you don't forget to turn it off for newly added actions. * Use attr_accessible instead of attr_protected. See the mass-assignment section for details * Allow <strong> instead of removing <script> against Cross-Site Scripting (XSS). See below for details. * Don't try to correct user input by blacklists: @@ -768,7 +769,7 @@ Model.where("login = ? AND password = ?", entered_user_name, entered_password).f As you can see, the first part of the array is an SQL fragment with question marks. The sanitized versions of the variables in the second part of the array replace the question marks. Or you can pass a hash for the same result: ```ruby -Model.where(:login => entered_user_name, :password => entered_password).first +Model.where(login: entered_user_name, password: entered_password).first ``` The array or hash form is only available in model instances. You can try `sanitize_sql()` elsewhere. _Make it a habit to think about the security consequences when using an external string in SQL_. @@ -863,7 +864,7 @@ This returned "some<script>alert('hello')</script>", which makes an ```ruby tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) -s = sanitize(user_input, :tags => tags, :attributes => %w(href title)) +s = sanitize(user_input, tags: tags, attributes: %w(href title)) ``` This allows only the given tags and does a good job, even against all kinds of tricks and malformed tags. diff --git a/guides/source/testing.md b/guides/source/testing.md index 2680525928..b45aba8d55 100644 --- a/guides/source/testing.md +++ b/guides/source/testing.md @@ -121,18 +121,18 @@ For this guide we will be using Rails _scaffolding_. It will create the model, a NOTE: For more information on Rails <i>scaffolding</i>, refer to [Getting Started with Rails](getting_started.html) -When you use `rails generate scaffold`, for a resource among other things it creates a test stub in the `test/unit` folder: +When you use `rails generate scaffold`, for a resource among other things it creates a test stub in the `test/models` folder: ```bash $ rails generate scaffold post title:string body:text ... create app/models/post.rb -create test/unit/post_test.rb +create test/models/post_test.rb create test/fixtures/posts.yml ... ``` -The default test stub in `test/unit/post_test.rb` looks like this: +The default test stub in `test/models/post_test.rb` looks like this: ```ruby require 'test_helper' @@ -225,9 +225,9 @@ TIP: You can see all these rake tasks and their descriptions by running `rake -- Running a test is as simple as invoking the file containing the test cases through Ruby: ```bash -$ ruby -Itest test/unit/post_test.rb +$ ruby -Itest test/models/post_test.rb -Loaded suite unit/post_test +Loaded suite models/post_test Started . Finished in 0.023513 seconds. @@ -240,9 +240,9 @@ This will run all the test methods from the test case. Note that `test_helper.rb You can also run a particular test method from the test case by using the `-n` switch with the `test method name`. ```bash -$ ruby -Itest test/unit/post_test.rb -n test_the_truth +$ ruby -Itest test/models/post_test.rb -n test_the_truth -Loaded suite unit/post_test +Loaded suite models/post_test Started . Finished in 0.023513 seconds. @@ -271,7 +271,7 @@ F Finished in 0.102072 seconds. 1) Failure: -test_should_not_save_post_without_title(PostTest) [/test/unit/post_test.rb:6]: +test_should_not_save_post_without_title(PostTest) [/test/models/post_test.rb:6]: <false> is not true. 1 tests, 1 assertions, 1 failures, 0 errors @@ -290,7 +290,7 @@ Running this test shows the friendlier assertion message: ```bash 1) Failure: -test_should_not_save_post_without_title(PostTest) [/test/unit/post_test.rb:6]: +test_should_not_save_post_without_title(PostTest) [/test/models/post_test.rb:6]: Saved the post without a title. <false> is not true. ``` @@ -341,7 +341,7 @@ Finished in 0.082603 seconds. 1) Error: test_should_report_error(PostTest): NameError: undefined local variable or method `some_undefined_variable' for #<PostTest:0x249d354> - /test/unit/post_test.rb:6:in `test_should_report_error' + /test/models/post_test.rb:6:in `test_should_report_error' 1 tests, 0 assertions, 0 failures, 1 errors ``` @@ -420,7 +420,7 @@ You should test for things such as: * was the correct object stored in the response template? * was the appropriate message displayed to the user in the view? -Now that we have used Rails scaffold generator for our `Post` resource, it has already created the controller code and functional tests. You can take look at the file `posts_controller_test.rb` in the `test/functional` directory. +Now that we have used Rails scaffold generator for our `Post` resource, it has already created the controller code and tests. You can take look at the file `posts_controller_test.rb` in the `test/controllers` directory. Let me take you through one such test, `test_should_get_index` from the file `posts_controller_test.rb`. @@ -762,12 +762,16 @@ You don't need to set up and run your tests by hand on a test-by-test basis. Rai | ------------------------------- | ----------- | | `rake test` | Runs all unit, functional and integration tests. You can also simply run `rake` as the _test_ target is the default.| | `rake test:benchmark` | Benchmark the performance tests| -| `rake test:functionals` | Runs all the functional tests from `test/functional`| +| `rake test:controllers` | Runs all the controller tests from `test/controllers`| +| `rake test:functionals` | Runs all the functional tests from `test/controllers`, `test/mailers`, and `test/functional`| +| `rake test:helpers` | Runs all the helper tests from `test/helpers`| | `rake test:integration` | Runs all the integration tests from `test/integration`| +| `rake test:mailers` | Runs all the mailer tests from `test/mailers`| +| `rake test:models` | Runs all the model tests from `test/models`| | `rake test:profile` | Profile the performance tests| | `rake test:recent` | Tests recent changes| | `rake test:uncommitted` | Runs all the tests which are uncommitted. Supports Subversion and Git| -| `rake test:units` | Runs all the unit tests from `test/unit`| +| `rake test:units` | Runs all the unit tests from `test/models`, `test/helpers`, and `test/unit`| Brief Note About `Test::Unit` diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 0ae0e30ab7..148316d170 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -255,7 +255,7 @@ ActiveSupport.on_load(:active_record) do end ``` -h4(#config_session3_1). config/initializers/session_store.rb +### config/initializers/session_store.rb You need to change your session key to something new, or remove all sessions: @@ -266,4 +266,6 @@ AppName::Application.config.session_store :cookie_store, :key => 'SOMETHINGNEW' or -<tt>$ rake db:sessions:clear</tt> +```bash +$ rake db:sessions:clear +``` diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 1e6aa1afd4..c9fa541db8 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,5 +1,8 @@ ## Rails 4.0.0 (unreleased) ## +* New test locations `test/models`, `test/helpers`, `test/controllers`, and + `test/mailers`. Corresponding rake tasks added as well. *Mike Moore* + * Set a different cache per environment for assets pipeline through `config.assets.cache`. diff --git a/railties/lib/rails/commands/application.rb b/railties/lib/rails/commands/application.rb index 2cb6d5ca2e..ff0eda3413 100644 --- a/railties/lib/rails/commands/application.rb +++ b/railties/lib/rails/commands/application.rb @@ -24,7 +24,7 @@ require 'rails/generators/rails/app/app_generator' module Rails module Generators - class AppGenerator + class AppGenerator # :nodoc: # We want to exit on failure to be kind to other libraries # This is only when accessing via CLI def self.exit_on_failure? diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 44c6507b08..e761e26b04 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -8,7 +8,7 @@ require 'uri' module Rails module Generators - class AppBase < Base + class AppBase < Base # :nodoc: DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db sqlserver ) JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc ) DATABASES.concat(JDBC_DATABASES) diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb index c2accf0387..5ca1bfc20f 100644 --- a/railties/lib/rails/generators/base.rb +++ b/railties/lib/rails/generators/base.rb @@ -11,7 +11,7 @@ require 'rails/generators/actions' module Rails module Generators - class Error < Thor::Error + class Error < Thor::Error # :nodoc: end class Base < Thor::Group diff --git a/railties/lib/rails/generators/css/assets/assets_generator.rb b/railties/lib/rails/generators/css/assets/assets_generator.rb index 492177ca2e..e4a305f4b3 100644 --- a/railties/lib/rails/generators/css/assets/assets_generator.rb +++ b/railties/lib/rails/generators/css/assets/assets_generator.rb @@ -1,8 +1,8 @@ require "rails/generators/named_base" -module Css - module Generators - class AssetsGenerator < Rails::Generators::NamedBase +module Css # :nodoc: + module Generators # :nodoc: + class AssetsGenerator < Rails::Generators::NamedBase # :nodoc: source_root File.expand_path("../templates", __FILE__) def copy_stylesheet diff --git a/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb index 1d7fe9fac0..cf534030f9 100644 --- a/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb @@ -1,8 +1,8 @@ require "rails/generators/named_base" -module Css - module Generators - class ScaffoldGenerator < Rails::Generators::NamedBase +module Css # :nodoc: + module Generators # :nodoc: + class ScaffoldGenerator < Rails::Generators::NamedBase # :nodoc: # In order to allow the Sass generators to pick up the default Rails CSS and # transform it, we leave it in a standard location for the CSS stylesheet # generators to handle. For the simple, default case, just copy it over. diff --git a/railties/lib/rails/generators/erb.rb b/railties/lib/rails/generators/erb.rb index 3e6371268f..aa824499ac 100644 --- a/railties/lib/rails/generators/erb.rb +++ b/railties/lib/rails/generators/erb.rb @@ -1,7 +1,7 @@ require 'rails/generators/named_base' -module Erb - module Generators +module Erb # :nodoc: + module Generators # :nodoc: class Base < Rails::Generators::NamedBase #:nodoc: protected diff --git a/railties/lib/rails/generators/erb/controller/controller_generator.rb b/railties/lib/rails/generators/erb/controller/controller_generator.rb index ac57140c23..e14cb09ff7 100644 --- a/railties/lib/rails/generators/erb/controller/controller_generator.rb +++ b/railties/lib/rails/generators/erb/controller/controller_generator.rb @@ -1,8 +1,8 @@ require 'rails/generators/erb' -module Erb - module Generators - class ControllerGenerator < Base +module Erb # :nodoc: + module Generators # :nodoc: + class ControllerGenerator < Base # :nodoc: argument :actions, :type => :array, :default => [], :banner => "action action" def copy_view_files diff --git a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb index 943d0c9f8d..89de2a4be5 100644 --- a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb +++ b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb @@ -1,8 +1,8 @@ require 'rails/generators/erb/controller/controller_generator' -module Erb - module Generators - class MailerGenerator < ControllerGenerator +module Erb # :nodoc: + module Generators # :nodoc: + class MailerGenerator < ControllerGenerator # :nodoc: protected def format diff --git a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb index b2c8d7051b..19fc53aeee 100644 --- a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb @@ -1,9 +1,9 @@ require 'rails/generators/erb' require 'rails/generators/resource_helpers' -module Erb - module Generators - class ScaffoldGenerator < Base +module Erb # :nodoc: + module Generators # :nodoc: + class ScaffoldGenerator < Base # :nodoc: include Rails::Generators::ResourceHelpers argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb index d2c2abf40c..231813f774 100644 --- a/railties/lib/rails/generators/generated_attribute.rb +++ b/railties/lib/rails/generators/generated_attribute.rb @@ -2,7 +2,7 @@ require 'active_support/time' module Rails module Generators - class GeneratedAttribute + class GeneratedAttribute # :nodoc: INDEX_OPTIONS = %w(index uniq) UNIQ_INDEX_OPTIONS = %w(uniq) diff --git a/railties/lib/rails/generators/js/assets/assets_generator.rb b/railties/lib/rails/generators/js/assets/assets_generator.rb index d134a9e392..82f40de009 100644 --- a/railties/lib/rails/generators/js/assets/assets_generator.rb +++ b/railties/lib/rails/generators/js/assets/assets_generator.rb @@ -1,8 +1,8 @@ require "rails/generators/named_base" -module Js - module Generators - class AssetsGenerator < Rails::Generators::NamedBase +module Js # :nodoc: + module Generators # :nodoc: + class AssetsGenerator < Rails::Generators::NamedBase # :nodoc: source_root File.expand_path("../templates", __FILE__) def copy_javascript diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index b71b16b043..67e7c4d54f 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -1,7 +1,7 @@ require 'rails/generators/app_base' module Rails - module ActionMethods + module ActionMethods # :nodoc: attr_reader :options def initialize(generator) @@ -113,9 +113,11 @@ module Rails def test empty_directory_with_keep_file 'test/fixtures' - empty_directory_with_keep_file 'test/functional' + empty_directory_with_keep_file 'test/controllers' + empty_directory_with_keep_file 'test/mailers' + empty_directory_with_keep_file 'test/models' + empty_directory_with_keep_file 'test/helpers' empty_directory_with_keep_file 'test/integration' - empty_directory_with_keep_file 'test/unit' template 'test/performance/browsing_test.rb' template 'test/test_helper.rb' @@ -146,7 +148,7 @@ module Rails RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__)) RESERVED_NAMES = %w[application destroy benchmarker profiler plugin runner test] - class AppGenerator < AppBase + class AppGenerator < AppBase # :nodoc: add_shared_options_for "application" # Add bin/rails options diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index e5aa153e29..30f8a5f75e 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -9,13 +9,10 @@ source 'https://rubygems.org' <%= assets_gemfile_entry %> <%= javascript_gemfile_entry %> -# Puts a simple HTTP cache in front of your app (and gets you ready for later upgrading to nginx/varnish/squid) -# gem 'rack-cache', '~> 1.2' - # To use ActiveModel has_secure_password # gem 'bcrypt-ruby', '~> 3.0.0' -# Build JSON APIs with ease. Read more: http://github.com/rails/jbuilder +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder # gem 'jbuilder' # Use unicorn as the app server 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 3629920c30..74457b0efd 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 @@ -60,7 +60,8 @@ # config.assets.precompile += %w( search.js ) <%- end -%> - # Disable delivery errors, bad email addresses will be ignored. + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false # Enable threaded mode. diff --git a/railties/lib/rails/generators/rails/assets/assets_generator.rb b/railties/lib/rails/generators/rails/assets/assets_generator.rb index 2e7f25a0b7..e4f07bba2e 100644 --- a/railties/lib/rails/generators/rails/assets/assets_generator.rb +++ b/railties/lib/rails/generators/rails/assets/assets_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class AssetsGenerator < NamedBase + class AssetsGenerator < NamedBase # :nodoc: class_option :javascripts, :type => :boolean, :desc => "Generate JavaScripts" class_option :stylesheets, :type => :boolean, :desc => "Generate Stylesheets" diff --git a/railties/lib/rails/generators/rails/controller/USAGE b/railties/lib/rails/generators/rails/controller/USAGE index b658777b12..9def4af65c 100644 --- a/railties/lib/rails/generators/rails/controller/USAGE +++ b/railties/lib/rails/generators/rails/controller/USAGE @@ -12,7 +12,7 @@ Example: `rails generate controller CreditCards open debit credit close` CreditCards controller with URLs like /credit_cards/debit. - Controller: app/controllers/credit_cards_controller.rb - Functional Test: test/functional/credit_cards_controller_test.rb - Views: app/views/credit_cards/debit.html.erb [...] - Helper: app/helpers/credit_cards_helper.rb + Controller: app/controllers/credit_cards_controller.rb + Test: test/controllers/credit_cards_controller_test.rb + Views: app/views/credit_cards/debit.html.erb [...] + Helper: app/helpers/credit_cards_helper.rb diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb index 74aa0432a8..1482fc28d4 100644 --- a/railties/lib/rails/generators/rails/controller/controller_generator.rb +++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class ControllerGenerator < NamedBase + class ControllerGenerator < NamedBase # :nodoc: argument :actions, :type => :array, :default => [], :banner => "action action" check_class_collision :suffix => "Controller" diff --git a/railties/lib/rails/generators/rails/generator/generator_generator.rb b/railties/lib/rails/generators/rails/generator/generator_generator.rb index 3e0a442bda..8a0fdbf2fb 100644 --- a/railties/lib/rails/generators/rails/generator/generator_generator.rb +++ b/railties/lib/rails/generators/rails/generator/generator_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class GeneratorGenerator < NamedBase + class GeneratorGenerator < NamedBase # :nodoc: check_class_collision :suffix => "Generator" class_option :namespace, :type => :boolean, :default => true, diff --git a/railties/lib/rails/generators/rails/helper/USAGE b/railties/lib/rails/generators/rails/helper/USAGE index c0ddb0f606..30e323a858 100644 --- a/railties/lib/rails/generators/rails/helper/USAGE +++ b/railties/lib/rails/generators/rails/helper/USAGE @@ -13,5 +13,5 @@ Example: Credit card helper. Helper: app/helpers/credit_card_helper.rb - Test: test/unit/helpers/credit_card_helper_test.rb + Test: test/helpers/credit_card_helper_test.rb diff --git a/railties/lib/rails/generators/rails/helper/helper_generator.rb b/railties/lib/rails/generators/rails/helper/helper_generator.rb index ad66388591..0975ab3903 100644 --- a/railties/lib/rails/generators/rails/helper/helper_generator.rb +++ b/railties/lib/rails/generators/rails/helper/helper_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class HelperGenerator < NamedBase + class HelperGenerator < NamedBase # :nodoc: check_class_collision :suffix => "Helper" def create_helper_files diff --git a/railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb b/railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb index 363a327fcb..9258ae1ee8 100644 --- a/railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb +++ b/railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class IntegrationTestGenerator < NamedBase + class IntegrationTestGenerator < NamedBase # :nodoc: hook_for :integration_tool, :as => :integration end end diff --git a/railties/lib/rails/generators/rails/migration/migration_generator.rb b/railties/lib/rails/generators/rails/migration/migration_generator.rb index f87dce1502..2e1b6a27d8 100644 --- a/railties/lib/rails/generators/rails/migration/migration_generator.rb +++ b/railties/lib/rails/generators/rails/migration/migration_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class MigrationGenerator < NamedBase #metagenerator + class MigrationGenerator < NamedBase # :nodoc: argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]" hook_for :orm, :required => true end diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE index c46c86076e..e29e19490e 100644 --- a/railties/lib/rails/generators/rails/model/USAGE +++ b/railties/lib/rails/generators/rails/model/USAGE @@ -74,7 +74,7 @@ Examples: For ActiveRecord and TestUnit it creates: Model: app/models/account.rb - Test: test/unit/account_test.rb + Test: test/models/account_test.rb Fixtures: test/fixtures/accounts.yml Migration: db/migrate/XXX_add_accounts.rb @@ -88,7 +88,7 @@ Examples: Module: app/models/admin.rb Model: app/models/admin/account.rb - Test: test/unit/admin/account_test.rb + Test: test/models/admin/account_test.rb Fixtures: test/fixtures/admin/accounts.yml Migration: db/migrate/XXX_add_admin_accounts.rb diff --git a/railties/lib/rails/generators/rails/model/model_generator.rb b/railties/lib/rails/generators/rails/model/model_generator.rb index 9bb29b784e..af1617fadf 100644 --- a/railties/lib/rails/generators/rails/model/model_generator.rb +++ b/railties/lib/rails/generators/rails/model/model_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class ModelGenerator < NamedBase #metagenerator + class ModelGenerator < NamedBase # :nodoc: argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]" hook_for :orm, :required => true end diff --git a/railties/lib/rails/generators/rails/observer/USAGE b/railties/lib/rails/generators/rails/observer/USAGE index d8f32a6a48..177ff49e4a 100644 --- a/railties/lib/rails/generators/rails/observer/USAGE +++ b/railties/lib/rails/generators/rails/observer/USAGE @@ -9,4 +9,4 @@ Example: For ActiveRecord and TestUnit it creates: Observer: app/models/account_observer.rb - TestUnit: test/unit/account_observer_test.rb + TestUnit: test/models/account_observer_test.rb diff --git a/railties/lib/rails/generators/rails/observer/observer_generator.rb b/railties/lib/rails/generators/rails/observer/observer_generator.rb index f5cedee91f..a11085eb0f 100644 --- a/railties/lib/rails/generators/rails/observer/observer_generator.rb +++ b/railties/lib/rails/generators/rails/observer/observer_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class ObserverGenerator < NamedBase #metagenerator + class ObserverGenerator < NamedBase # :nodoc: hook_for :orm, :required => true end end diff --git a/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb b/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb index d1c71ab8ed..83771c3dd7 100644 --- a/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb +++ b/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class PerformanceTestGenerator < NamedBase + class PerformanceTestGenerator < NamedBase # :nodoc: hook_for :performance_tool, :as => :performance end end diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb index c77b3450a3..42e0246f76 100644 --- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb @@ -3,6 +3,13 @@ require "rails/generators/rails/app/app_generator" require 'date' module Rails + # The plugin builder allows you to override elements of the plugin + # generator without being forced to reverse the operations of the default + # generator. + # + # This allows you to override entire operations, like the creation of the + # Gemfile, README, or JavaScript files, without needing to know exactly + # what those operations do so you can create another template action. class PluginBuilder def rakefile template "Rakefile" @@ -146,7 +153,7 @@ task :default => :test end module Generators - class PluginNewGenerator < AppBase + class PluginNewGenerator < AppBase # :nodoc: add_shared_options_for "plugin" alias_method :plugin_path, :app_path diff --git a/railties/lib/rails/generators/rails/resource/resource_generator.rb b/railties/lib/rails/generators/rails/resource/resource_generator.rb index 3a0586ee43..d3ba597dbd 100644 --- a/railties/lib/rails/generators/rails/resource/resource_generator.rb +++ b/railties/lib/rails/generators/rails/resource/resource_generator.rb @@ -4,7 +4,7 @@ require 'active_support/core_ext/object/blank' module Rails module Generators - class ResourceGenerator < ModelGenerator #metagenerator + class ResourceGenerator < ModelGenerator # :nodoc: include ResourceHelpers hook_for :resource_controller, :required => true do |controller| diff --git a/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb index f33d56b564..121205b254 100644 --- a/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb +++ b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class ResourceRouteGenerator < NamedBase + class ResourceRouteGenerator < NamedBase # :nodoc: # Properly nests namespaces passed into a generator # diff --git a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb index 03a61a035e..c33c99e989 100644 --- a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb @@ -2,7 +2,7 @@ require 'rails/generators/rails/resource/resource_generator' module Rails module Generators - class ScaffoldGenerator < ResourceGenerator #metagenerator + class ScaffoldGenerator < ResourceGenerator # :nodoc: remove_hook_for :resource_controller remove_class_option :actions diff --git a/railties/lib/rails/generators/rails/scaffold_controller/USAGE b/railties/lib/rails/generators/rails/scaffold_controller/USAGE index 5cd51b62d4..8ba4c5ccbc 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/USAGE +++ b/railties/lib/rails/generators/rails/scaffold_controller/USAGE @@ -13,7 +13,7 @@ Example: `rails generate scaffold_controller CreditCard` Credit card controller with URLs like /credit_card/debit. - Controller: app/controllers/credit_cards_controller.rb - Functional Test: test/functional/credit_cards_controller_test.rb - Views: app/views/credit_cards/index.html.erb [...] - Helper: app/helpers/credit_cards_helper.rb + Controller: app/controllers/credit_cards_controller.rb + Test: test/controllers/credit_cards_controller_test.rb + Views: app/views/credit_cards/index.html.erb [...] + Helper: app/helpers/credit_cards_helper.rb diff --git a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb index f30ad6e20d..df069ca937 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +++ b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb @@ -2,7 +2,7 @@ require 'rails/generators/resource_helpers' module Rails module Generators - class ScaffoldControllerGenerator < NamedBase + class ScaffoldControllerGenerator < NamedBase # :nodoc: include ResourceHelpers check_class_collision :suffix => "Controller" diff --git a/railties/lib/rails/generators/rails/task/task_generator.rb b/railties/lib/rails/generators/rails/task/task_generator.rb index 8a62d9e8eb..cf3d1182ea 100644 --- a/railties/lib/rails/generators/rails/task/task_generator.rb +++ b/railties/lib/rails/generators/rails/task/task_generator.rb @@ -1,6 +1,6 @@ module Rails module Generators - class TaskGenerator < NamedBase + class TaskGenerator < NamedBase # :nodoc: argument :actions, :type => :array, :default => [], :banner => "action action" def create_task_files diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb index 48833869e5..3df25219ab 100644 --- a/railties/lib/rails/generators/resource_helpers.rb +++ b/railties/lib/rails/generators/resource_helpers.rb @@ -4,8 +4,7 @@ module Rails module Generators # Deal with controller names on scaffold and add some helpers to deal with # ActiveModel. - # - module ResourceHelpers + module ResourceHelpers # :nodoc: mattr_accessor :skip_warn def self.included(base) #:nodoc: @@ -13,7 +12,6 @@ module Rails end # Set controller variables on initialization. - # def initialize(*args) #:nodoc: super diff --git a/railties/lib/rails/generators/test_case.rb b/railties/lib/rails/generators/test_case.rb index 2ff340755a..30ae805348 100644 --- a/railties/lib/rails/generators/test_case.rb +++ b/railties/lib/rails/generators/test_case.rb @@ -26,7 +26,6 @@ module Rails # destination File.expand_path("../tmp", File.dirname(__FILE__)) # setup :prepare_destination # end - # class TestCase < ActiveSupport::TestCase include FileUtils @@ -37,13 +36,13 @@ module Rails self.current_path = File.expand_path(Dir.pwd) self.default_arguments = [] - def setup + def setup # :nodoc: destination_root_is_set? ensure_current_path super end - def teardown + def teardown # :nodoc: ensure_current_path super end @@ -51,7 +50,6 @@ module Rails # Sets which generator should be tested: # # tests AppGenerator - # def self.tests(klass) self.generator_class = klass end @@ -60,7 +58,6 @@ module Rails # invoking it. # # arguments %w(app_name --skip-active-record) - # def self.arguments(array) self.default_arguments = array end @@ -68,7 +65,6 @@ module Rails # Sets the destination of generator files: # # destination File.expand_path("../tmp", File.dirname(__FILE__)) - # def self.destination(path) self.destination_root = path end @@ -91,7 +87,6 @@ module Rails # assert_match(/Product\.all/, index) # end # end - # def assert_file(relative, *contents) absolute = File.expand_path(relative, destination_root) assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not" @@ -114,7 +109,6 @@ module Rails # path relative to the configured destination: # # assert_no_file "config/random.rb" - # def assert_no_file(relative) absolute = File.expand_path(relative, destination_root) assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does" @@ -132,7 +126,6 @@ module Rails # assert_file "db/migrate/003_create_products.rb" # # Consequently, assert_migration accepts the same arguments has assert_file. - # def assert_migration(relative, *contents, &block) file_name = migration_file_name(relative) assert file_name, "Expected migration #{relative} to exist, but was not found" @@ -143,7 +136,6 @@ module Rails # path relative to the configured destination: # # assert_no_migration "db/migrate/create_products.rb" - # def assert_no_migration(relative) file_name = migration_file_name(relative) assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}" @@ -158,7 +150,6 @@ module Rails # assert_match(/create_table/, up) # end # end - # def assert_class_method(method, content, &block) assert_instance_method "self.#{method}", content, &block end @@ -171,7 +162,6 @@ module Rails # assert_match(/Product\.all/, index) # end # end - # def assert_instance_method(method, content) assert content =~ /def #{method}(\(.+\))?(.*?)\n end/m, "Expected to have method #{method}" yield $2.strip if block_given? @@ -182,7 +172,6 @@ module Rails # properly: # # assert_field_type :date, :date_select - # def assert_field_type(attribute_type, field_type) assert_equal(field_type, create_generated_attribute(attribute_type).field_type) end @@ -190,7 +179,6 @@ module Rails # Asserts the given attribute type gets a proper default value: # # assert_field_default_value :string, "MyString" - # def assert_field_default_value(attribute_type, value) assert_equal(value, create_generated_attribute(attribute_type).default) end @@ -224,27 +212,26 @@ module Rails # attribute type and, optionally, the attribute name: # # create_generated_attribute(:string, 'name') - # def create_generated_attribute(attribute_type, name = 'test', index = nil) Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(':')) end protected - def destination_root_is_set? #:nodoc: + def destination_root_is_set? # :nodoc: raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root end - def ensure_current_path #:nodoc: + def ensure_current_path # :nodoc: cd current_path end - def prepare_destination + def prepare_destination # :nodoc: rm_rf(destination_root) mkdir_p(destination_root) end - def migration_file_name(relative) #:nodoc: + def migration_file_name(relative) # :nodoc: absolute = File.expand_path(relative, destination_root) dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first diff --git a/railties/lib/rails/generators/test_unit.rb b/railties/lib/rails/generators/test_unit.rb index 62b9afaa2c..fe45c9e15d 100644 --- a/railties/lib/rails/generators/test_unit.rb +++ b/railties/lib/rails/generators/test_unit.rb @@ -1,8 +1,8 @@ require 'rails/generators/named_base' -module TestUnit - module Generators - class Base < Rails::Generators::NamedBase #:nodoc: +module TestUnit # :nodoc: + module Generators # :nodoc: + class Base < Rails::Generators::NamedBase # :nodoc: end end end diff --git a/railties/lib/rails/generators/test_unit/controller/controller_generator.rb b/railties/lib/rails/generators/test_unit/controller/controller_generator.rb index 20f3bd8965..c53930f994 100644 --- a/railties/lib/rails/generators/test_unit/controller/controller_generator.rb +++ b/railties/lib/rails/generators/test_unit/controller/controller_generator.rb @@ -1,14 +1,14 @@ require 'rails/generators/test_unit' -module TestUnit - module Generators - class ControllerGenerator < Base +module TestUnit # :nodoc: + module Generators # :nodoc: + class ControllerGenerator < Base # :nodoc: argument :actions, :type => :array, :default => [], :banner => "action action" check_class_collision :suffix => "ControllerTest" def create_test_files template 'functional_test.rb', - File.join('test/functional', class_path, "#{file_name}_controller_test.rb") + File.join('test/controllers', class_path, "#{file_name}_controller_test.rb") end end end diff --git a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb b/railties/lib/rails/generators/test_unit/helper/helper_generator.rb index 4ea80bf7be..bcd370098e 100644 --- a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb +++ b/railties/lib/rails/generators/test_unit/helper/helper_generator.rb @@ -1,12 +1,12 @@ require 'rails/generators/test_unit' -module TestUnit - module Generators - class HelperGenerator < Base +module TestUnit # :nodoc: + module Generators # :nodoc: + class HelperGenerator < Base # :nodoc: check_class_collision :suffix => "HelperTest" def create_helper_files - template 'helper_test.rb', File.join('test/unit/helpers', class_path, "#{file_name}_helper_test.rb") + template 'helper_test.rb', File.join('test/helpers', class_path, "#{file_name}_helper_test.rb") end end end diff --git a/railties/lib/rails/generators/test_unit/integration/integration_generator.rb b/railties/lib/rails/generators/test_unit/integration/integration_generator.rb index 32d0fac029..427d128275 100644 --- a/railties/lib/rails/generators/test_unit/integration/integration_generator.rb +++ b/railties/lib/rails/generators/test_unit/integration/integration_generator.rb @@ -1,8 +1,8 @@ require 'rails/generators/test_unit' -module TestUnit - module Generators - class IntegrationGenerator < Base +module TestUnit # :nodoc: + module Generators # :nodoc: + class IntegrationGenerator < Base # :nodoc: check_class_collision :suffix => "Test" def create_test_files diff --git a/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb b/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb index 1a49286d41..570a733227 100644 --- a/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb +++ b/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb @@ -1,13 +1,13 @@ require 'rails/generators/test_unit' -module TestUnit - module Generators - class MailerGenerator < Base +module TestUnit # :nodoc: + module Generators # :nodoc: + class MailerGenerator < Base # :nodoc: argument :actions, :type => :array, :default => [], :banner => "method method" check_class_collision :suffix => "Test" def create_test_files - template "functional_test.rb", File.join('test/functional', class_path, "#{file_name}_test.rb") + template "functional_test.rb", File.join('test/mailers', class_path, "#{file_name}_test.rb") end end end diff --git a/railties/lib/rails/generators/test_unit/model/model_generator.rb b/railties/lib/rails/generators/test_unit/model/model_generator.rb index c1dd535dd3..9b73f3561f 100644 --- a/railties/lib/rails/generators/test_unit/model/model_generator.rb +++ b/railties/lib/rails/generators/test_unit/model/model_generator.rb @@ -1,15 +1,15 @@ require 'rails/generators/test_unit' -module TestUnit - module Generators - class ModelGenerator < Base +module TestUnit # :nodoc: + module Generators # :nodoc: + class ModelGenerator < Base # :nodoc: argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" class_option :fixture, :type => :boolean check_class_collision :suffix => "Test" def create_test_file - template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb") + template 'unit_test.rb', File.join('test/models', class_path, "#{file_name}_test.rb") end hook_for :fixture_replacement diff --git a/railties/lib/rails/generators/test_unit/observer/observer_generator.rb b/railties/lib/rails/generators/test_unit/observer/observer_generator.rb index 6cc1158c21..8bfb749743 100644 --- a/railties/lib/rails/generators/test_unit/observer/observer_generator.rb +++ b/railties/lib/rails/generators/test_unit/observer/observer_generator.rb @@ -1,12 +1,12 @@ require 'rails/generators/test_unit' -module TestUnit - module Generators - class ObserverGenerator < Base +module TestUnit # :nodoc: + module Generators # :nodoc: + class ObserverGenerator < Base # :nodoc: check_class_collision :suffix => "ObserverTest" def create_test_files - template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_observer_test.rb") + template 'unit_test.rb', File.join('test/models', class_path, "#{file_name}_observer_test.rb") end end end diff --git a/railties/lib/rails/generators/test_unit/performance/performance_generator.rb b/railties/lib/rails/generators/test_unit/performance/performance_generator.rb index 99edda5461..9a80d1ea54 100644 --- a/railties/lib/rails/generators/test_unit/performance/performance_generator.rb +++ b/railties/lib/rails/generators/test_unit/performance/performance_generator.rb @@ -1,8 +1,8 @@ require 'rails/generators/test_unit' -module TestUnit - module Generators - class PerformanceGenerator < Base +module TestUnit # :nodoc: + module Generators # :nodoc: + class PerformanceGenerator < Base # :nodoc: check_class_collision :suffix => "Test" def create_test_files diff --git a/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb b/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb index 4d65cd7d89..41e8873783 100644 --- a/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb +++ b/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb @@ -1,8 +1,8 @@ require 'rails/generators/test_unit' -module TestUnit - module Generators - class PluginGenerator < Base +module TestUnit # :nodoc: + module Generators # :nodoc: + class PluginGenerator < Base # :nodoc: check_class_collision :suffix => "Test" def create_test_files 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 ca7fee3b6e..0462c15224 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb @@ -1,9 +1,9 @@ require 'rails/generators/test_unit' require 'rails/generators/resource_helpers' -module TestUnit - module Generators - class ScaffoldGenerator < Base +module TestUnit # :nodoc: + module Generators # :nodoc: + class ScaffoldGenerator < Base # :nodoc: include Rails::Generators::ResourceHelpers check_class_collision :suffix => "ControllerTest" @@ -12,7 +12,7 @@ module TestUnit def create_test_files template "functional_test.rb", - File.join("test/functional", controller_class_path, "#{controller_file_name}_controller_test.rb") + File.join("test/controllers", controller_class_path, "#{controller_file_name}_controller_test.rb") end private diff --git a/railties/lib/rails/tasks/statistics.rake b/railties/lib/rails/tasks/statistics.rake index 67a6d2d2ac..c1674c72ad 100644 --- a/railties/lib/rails/tasks/statistics.rake +++ b/railties/lib/rails/tasks/statistics.rake @@ -6,9 +6,13 @@ STATS_DIRECTORIES = [ %w(Javascripts app/assets/javascripts), %w(Libraries lib/), %w(APIs app/apis), + %w(Controller\ tests test/controllers), + %w(Helper\ tests test/helpers), + %w(Model\ tests test/models), + %w(Mailer\ tests test/mailers), %w(Integration\ tests test/integration), - %w(Functional\ tests test/functional), - %w(Unit\ tests test/unit) + %w(Functional\ tests\ (old) test/functional), + %w(Unit\ tests \ (old) test/unit) ].collect { |name, dir| [ name, "#{Rails.root}/#{dir}" ] }.select { |name, dir| File.directory?(dir) } desc "Report code statistics (KLOCs, etc) from the application" diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake index 0de4afe905..63cb955d44 100644 --- a/railties/lib/rails/test_unit/testing.rake +++ b/railties/lib/rails/test_unit/testing.rake @@ -15,11 +15,11 @@ def recent_tests(source_pattern, test_path, touched_since = 10.minutes.ago) # Support subdirs in app/models and app/controllers modified_test_path = source_dir.length > 2 ? "#{test_path}/" << source_dir[1..source_dir.length].join('/') : test_path - # For modified files in app/ run the tests for it. ex. /test/functional/account_controller.rb + # For modified files in app/ run the tests for it. ex. /test/controllers/account_controller.rb test = "#{modified_test_path}/#{source_file}_test.rb" tests.push test if File.exist?(test) - # For modified files in app, run tests in subdirs too. ex. /test/functional/account/*_test.rb + # For modified files in app, run tests in subdirs too. ex. /test/controllers/account/*_test.rb test = "#{modified_test_path}/#{File.basename(path, '.rb').sub("_controller","")}" FileList["#{test}/*_test.rb"].each { |f| tests.push f } if File.exist?(test) @@ -74,7 +74,9 @@ namespace :test do Rake::TestTask.new(:recent => "test:prepare") do |t| since = TEST_CHANGES_SINCE touched = FileList['test/**/*_test.rb'].select { |path| File.mtime(path) > since } + + recent_tests('app/models/**/*.rb', 'test/models', since) + recent_tests('app/models/**/*.rb', 'test/unit', since) + + recent_tests('app/controllers/**/*.rb', 'test/controllers', since) + recent_tests('app/controllers/**/*.rb', 'test/functional', since) t.libs << 'test' @@ -95,8 +97,10 @@ namespace :test do models = changed_since_checkin.select { |path| path =~ /app[\\\/]models[\\\/].*\.rb$/ } controllers = changed_since_checkin.select { |path| path =~ /app[\\\/]controllers[\\\/].*\.rb$/ } - unit_tests = models.map { |model| "test/unit/#{File.basename(model, '.rb')}_test.rb" } - functional_tests = controllers.map { |controller| "test/functional/#{File.basename(controller, '.rb')}_test.rb" } + unit_tests = models.map { |model| "test/models/#{File.basename(model, '.rb')}_test.rb" } + + models.map { |model| "test/unit/#{File.basename(model, '.rb')}_test.rb" } + + functional_tests = controllers.map { |controller| "test/controllers/#{File.basename(controller, '.rb')}_test.rb" } + + controllers.map { |controller| "test/functional/#{File.basename(controller, '.rb')}_test.rb" } (unit_tests + functional_tests).uniq.select { |file| File.exist?(file) } end @@ -108,14 +112,34 @@ namespace :test do t.libs << "test" end + Rails::SubTestTask.new(:models => "test:prepare") do |t| + t.libs << "test" + t.pattern = 'test/models/**/*_test.rb' + end + + Rails::SubTestTask.new(:helpers => "test:prepare") do |t| + t.libs << "test" + t.pattern = 'test/helpers/**/*_test.rb' + end + Rails::SubTestTask.new(:units => "test:prepare") do |t| t.libs << "test" - t.pattern = 'test/unit/**/*_test.rb' + t.pattern = 'test/{models,helpers,unit}/**/*_test.rb' + end + + Rails::SubTestTask.new(:controllers => "test:prepare") do |t| + t.libs << "test" + t.pattern = 'test/controllers/**/*_test.rb' + end + + Rails::SubTestTask.new(:mailers => "test:prepare") do |t| + t.libs << "test" + t.pattern = 'test/mailers/**/*_test.rb' end Rails::SubTestTask.new(:functionals => "test:prepare") do |t| t.libs << "test" - t.pattern = 'test/functional/**/*_test.rb' + t.pattern = 'test/{controllers,mailers,functional}/**/*_test.rb' end Rails::SubTestTask.new(:integration => "test:prepare") do |t| diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index b05fe3aed5..2e7426150c 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -86,12 +86,12 @@ module ApplicationTests def test_rake_test_error_output Dir.chdir(app_path){ `rake db:migrate` } - app_file "test/unit/one_unit_test.rb", <<-RUBY - raise 'unit' + app_file "test/models/one_model_test.rb", <<-RUBY + raise 'models' RUBY - app_file "test/functional/one_functional_test.rb", <<-RUBY - raise 'functional' + app_file "test/controllers/one_controller_test.rb", <<-RUBY + raise 'controllers' RUBY app_file "test/integration/one_integration_test.rb", <<-RUBY @@ -100,8 +100,8 @@ module ApplicationTests silence_stderr do output = Dir.chdir(app_path) { `rake test 2>&1` } - assert_match 'unit', output - assert_match 'functional', output + assert_match 'models', output + assert_match 'controllers', output assert_match 'integration', output end end diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb index 91ede1cb68..69e89d87ae 100644 --- a/railties/test/commands/console_test.rb +++ b/railties/test/commands/console_test.rb @@ -68,40 +68,40 @@ class Rails::ConsoleTest < ActiveSupport::TestCase def test_default_environment_with_no_rails_env with_rails_env nil do start - assert_match /\sdevelopment\s/, output + assert_match(/\sdevelopment\s/, output) end end def test_default_environment_with_rails_env with_rails_env 'special-production' do start - assert_match /\sspecial-production\s/, output + assert_match(/\sspecial-production\s/, output) end end def test_e_option start ['-e', 'special-production'] - assert_match /\sspecial-production\s/, output + assert_match(/\sspecial-production\s/, output) end def test_environment_option start ['--environment=special-production'] - assert_match /\sspecial-production\s/, output + assert_match(/\sspecial-production\s/, output) end def test_rails_env_is_production_when_first_argument_is_p start ['p'] - assert_match /\sproduction\s/, output + assert_match(/\sproduction\s/, output) end def test_rails_env_is_test_when_first_argument_is_t start ['t'] - assert_match /\stest\s/, output + assert_match(/\stest\s/, output) end def test_rails_env_is_development_when_argument_is_d start ['d'] - assert_match /\sdevelopment\s/, output + assert_match(/\sdevelopment\s/, output) end private diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 7a646626c6..91575a38b6 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -26,10 +26,12 @@ DEFAULT_APP_FILES = %w( log script/rails test/fixtures - test/functional + test/controllers + test/models + test/helpers + test/mailers test/integration test/performance - test/unit vendor vendor/assets tmp/cache diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb index c3fa9ebb03..5205deafd9 100644 --- a/railties/test/generators/controller_generator_test.rb +++ b/railties/test/generators/controller_generator_test.rb @@ -28,13 +28,13 @@ class ControllerGeneratorTest < Rails::Generators::TestCase def test_invokes_helper run_generator assert_file "app/helpers/account_helper.rb" - assert_file "test/unit/helpers/account_helper_test.rb" + assert_file "test/helpers/account_helper_test.rb" end def test_does_not_invoke_helper_if_required run_generator ["account", "--skip-helper"] assert_no_file "app/helpers/account_helper.rb" - assert_no_file "test/unit/helpers/account_helper_test.rb" + assert_no_file "test/helpers/account_helper_test.rb" end def test_invokes_assets @@ -45,12 +45,12 @@ class ControllerGeneratorTest < Rails::Generators::TestCase def test_invokes_default_test_framework run_generator - assert_file "test/functional/account_controller_test.rb" + assert_file "test/controllers/account_controller_test.rb" end def test_does_not_invoke_test_framework_if_required run_generator ["account", "--no-test-framework"] - assert_no_file "test/functional/account_controller_test.rb" + assert_no_file "test/controllers/account_controller_test.rb" end def test_invokes_default_template_engine diff --git a/railties/test/generators/helper_generator_test.rb b/railties/test/generators/helper_generator_test.rb index 8da3aa61a4..81d4fcb129 100644 --- a/railties/test/generators/helper_generator_test.rb +++ b/railties/test/generators/helper_generator_test.rb @@ -15,7 +15,7 @@ class HelperGeneratorTest < Rails::Generators::TestCase def test_invokes_default_test_framework run_generator - assert_file "test/unit/helpers/admin_helper_test.rb", /class AdminHelperTest < ActionView::TestCase/ + assert_file "test/helpers/admin_helper_test.rb", /class AdminHelperTest < ActionView::TestCase/ end def test_logs_if_the_test_framework_cannot_be_found diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb index c501780e7f..6b2351fc1a 100644 --- a/railties/test/generators/mailer_generator_test.rb +++ b/railties/test/generators/mailer_generator_test.rb @@ -29,7 +29,7 @@ class MailerGeneratorTest < Rails::Generators::TestCase def test_invokes_default_test_framework run_generator - assert_file "test/functional/notifier_test.rb" do |test| + assert_file "test/mailers/notifier_test.rb" do |test| assert_match(/class NotifierTest < ActionMailer::TestCase/, test) assert_match(/test "foo"/, test) assert_match(/test "bar"/, test) diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index 436de26826..a90ad5cde0 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -157,7 +157,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_match(/create_table :products/, up) assert_match(/t\.string :name/, up) assert_match(/t\.integer :supplier_id/, up) - + assert_match(/add_index :products, :name/, up) assert_match(/add_index :products, :supplier_id/, up) assert_no_match(/add_index :products, :year/, up) @@ -181,7 +181,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase assert_match(/add_index :products, :discount, unique: true/, content) end end - + def test_migration_without_timestamps ActiveRecord::Base.timestamped_migrations = false run_generator ["account"] @@ -269,7 +269,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase def test_invokes_default_test_framework run_generator - assert_file "test/unit/account_test.rb", /class AccountTest < ActiveSupport::TestCase/ + assert_file "test/models/account_test.rb", /class AccountTest < ActiveSupport::TestCase/ assert_file "test/fixtures/accounts.yml", /name: MyString/, /age: 1/ end diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb index ede779ea59..d48712e51f 100644 --- a/railties/test/generators/namespaced_generators_test.rb +++ b/railties/test/generators/namespaced_generators_test.rb @@ -25,7 +25,7 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase /module TestApp/, / class AccountController < ApplicationController/ - assert_file "test/functional/test_app/account_controller_test.rb", + assert_file "test/controllers/test_app/account_controller_test.rb", /module TestApp/, / class AccountControllerTest/ end @@ -46,12 +46,12 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase def test_helpr_is_also_namespaced run_generator assert_file "app/helpers/test_app/account_helper.rb", /module TestApp/, / module AccountHelper/ - assert_file "test/unit/helpers/test_app/account_helper_test.rb", /module TestApp/, / class AccountHelperTest/ + assert_file "test/helpers/test_app/account_helper_test.rb", /module TestApp/, / class AccountHelperTest/ end def test_invokes_default_test_framework run_generator - assert_file "test/functional/test_app/account_controller_test.rb" + assert_file "test/controllers/test_app/account_controller_test.rb" end def test_invokes_default_template_engine @@ -136,7 +136,7 @@ class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase def test_invokes_default_test_framework run_generator - assert_file "test/unit/test_app/account_test.rb", /module TestApp/, /class AccountTest < ActiveSupport::TestCase/ + assert_file "test/models/test_app/account_test.rb", /module TestApp/, /class AccountTest < ActiveSupport::TestCase/ assert_file "test/fixtures/test_app/accounts.yml", /name: MyString/, /age: 1/ end end @@ -158,7 +158,7 @@ class NamespacedObserverGeneratorTest < NamespacedGeneratorTestCase def test_invokes_default_test_framework run_generator - assert_file "test/unit/test_app/account_observer_test.rb", /module TestApp/, / class AccountObserverTest < ActiveSupport::TestCase/ + assert_file "test/models/test_app/account_observer_test.rb", /module TestApp/, / class AccountObserverTest < ActiveSupport::TestCase/ end end @@ -186,7 +186,7 @@ class NamespacedMailerGeneratorTest < NamespacedGeneratorTestCase def test_invokes_default_test_framework run_generator - assert_file "test/functional/test_app/notifier_test.rb" do |test| + assert_file "test/mailers/test_app/notifier_test.rb" do |test| assert_match(/module TestApp/, test) assert_match(/class NotifierTest < ActionMailer::TestCase/, test) assert_match(/test "foo"/, test) @@ -225,7 +225,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Model assert_file "app/models/test_app/product_line.rb", /module TestApp\n class ProductLine < ActiveRecord::Base/ - assert_file "test/unit/test_app/product_line_test.rb", /module TestApp\n class ProductLineTest < ActiveSupport::TestCase/ + assert_file "test/models/test_app/product_line_test.rb", /module TestApp\n class ProductLineTest < ActiveSupport::TestCase/ assert_file "test/fixtures/test_app/product_lines.yml" assert_migration "db/migrate/create_test_app_product_lines.rb" @@ -240,7 +240,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase /module TestApp/, /class ProductLinesController < ApplicationController/ - assert_file "test/functional/test_app/product_lines_controller_test.rb", + assert_file "test/controllers/test_app/product_lines_controller_test.rb", /module TestApp\n class ProductLinesControllerTest < ActionController::TestCase/ # Views @@ -255,7 +255,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/product_lines_helper.rb" - assert_file "test/unit/helpers/test_app/product_lines_helper_test.rb" + assert_file "test/helpers/test_app/product_lines_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -267,7 +267,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Model assert_no_file "app/models/test_app/product_line.rb" - assert_no_file "test/unit/test_app/product_line_test.rb" + assert_no_file "test/models/test_app/product_line_test.rb" assert_no_file "test/fixtures/test_app/product_lines.yml" assert_no_migration "db/migrate/create_test_app_product_lines.rb" @@ -278,7 +278,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Controller assert_no_file "app/controllers/test_app/product_lines_controller.rb" - assert_no_file "test/functional/test_app/product_lines_controller_test.rb" + assert_no_file "test/controllers/test_app/product_lines_controller_test.rb" # Views assert_no_file "app/views/test_app/product_lines" @@ -286,7 +286,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/product_lines_helper.rb" - assert_no_file "test/unit/helpers/test_app/product_lines_helper_test.rb" + assert_no_file "test/helpers/test_app/product_lines_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" @@ -298,7 +298,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Model assert_file "app/models/test_app/admin.rb", /module TestApp\n module Admin/ assert_file "app/models/test_app/admin/role.rb", /module TestApp\n class Admin::Role < ActiveRecord::Base/ - assert_file "test/unit/test_app/admin/role_test.rb", /module TestApp\n class Admin::RoleTest < ActiveSupport::TestCase/ + assert_file "test/models/test_app/admin/role_test.rb", /module TestApp\n class Admin::RoleTest < ActiveSupport::TestCase/ assert_file "test/fixtures/test_app/admin/roles.yml" assert_migration "db/migrate/create_test_app_admin_roles.rb" @@ -312,7 +312,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase assert_match(/module TestApp\n class Admin::RolesController < ApplicationController/, content) end - assert_file "test/functional/test_app/admin/roles_controller_test.rb", + assert_file "test/controllers/test_app/admin/roles_controller_test.rb", /module TestApp\n class Admin::RolesControllerTest < ActionController::TestCase/ # Views @@ -327,7 +327,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/admin/roles_helper.rb" - assert_file "test/unit/helpers/test_app/admin/roles_helper_test.rb" + assert_file "test/helpers/test_app/admin/roles_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -340,7 +340,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Model assert_file "app/models/test_app/admin.rb" # ( should not be remove ) assert_no_file "app/models/test_app/admin/role.rb" - assert_no_file "test/unit/test_app/admin/role_test.rb" + assert_no_file "test/models/test_app/admin/role_test.rb" assert_no_file "test/fixtures/test_app/admin/roles.yml" assert_no_migration "db/migrate/create_test_app_admin_roles.rb" @@ -351,7 +351,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Controller assert_no_file "app/controllers/test_app/admin/roles_controller.rb" - assert_no_file "test/functional/test_app/admin/roles_controller_test.rb" + assert_no_file "test/controllers/test_app/admin/roles_controller_test.rb" # Views assert_no_file "app/views/test_app/admin/roles" @@ -359,19 +359,19 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/admin/roles_helper.rb" - assert_no_file "test/unit/helpers/test_app/admin/roles_helper_test.rb" + assert_no_file "test/helpers/test_app/admin/roles_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" end - + def test_scaffold_with_nested_namespace_on_invoke run_generator [ "admin/user/special/role", "name:string", "description:string" ] # Model assert_file "app/models/test_app/admin/user/special.rb", /module TestApp\n module Admin/ assert_file "app/models/test_app/admin/user/special/role.rb", /module TestApp\n class Admin::User::Special::Role < ActiveRecord::Base/ - assert_file "test/unit/test_app/admin/user/special/role_test.rb", /module TestApp\n class Admin::User::Special::RoleTest < ActiveSupport::TestCase/ + assert_file "test/models/test_app/admin/user/special/role_test.rb", /module TestApp\n class Admin::User::Special::RoleTest < ActiveSupport::TestCase/ assert_file "test/fixtures/test_app/admin/user/special/roles.yml" assert_migration "db/migrate/create_test_app_admin_user_special_roles.rb" @@ -385,7 +385,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase assert_match(/module TestApp\n class Admin::User::Special::RolesController < ApplicationController/, content) end - assert_file "test/functional/test_app/admin/user/special/roles_controller_test.rb", + assert_file "test/controllers/test_app/admin/user/special/roles_controller_test.rb", /module TestApp\n class Admin::User::Special::RolesControllerTest < ActionController::TestCase/ # Views @@ -400,7 +400,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/admin/user/special/roles_helper.rb" - assert_file "test/unit/helpers/test_app/admin/user/special/roles_helper_test.rb" + assert_file "test/helpers/test_app/admin/user/special/roles_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -413,7 +413,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Model assert_file "app/models/test_app/admin/user/special.rb" # ( should not be remove ) assert_no_file "app/models/test_app/admin/user/special/role.rb" - assert_no_file "test/unit/test_app/admin/user/special/role_test.rb" + assert_no_file "test/models/test_app/admin/user/special/role_test.rb" assert_no_file "test/fixtures/test_app/admin/user/special/roles.yml" assert_no_migration "db/migrate/create_test_app_admin_user_special_roles.rb" @@ -424,14 +424,14 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Controller assert_no_file "app/controllers/test_app/admin/user/special/roles_controller.rb" - assert_no_file "test/functional/test_app/admin/user/special/roles_controller_test.rb" + assert_no_file "test/controllers/test_app/admin/user/special/roles_controller_test.rb" # Views assert_no_file "app/views/test_app/admin/user/special/roles" # Helpers assert_no_file "app/helpers/test_app/admin/user/special/roles_helper.rb" - assert_no_file "test/unit/helpers/test_app/admin/user/special/roles_helper_test.rb" + assert_no_file "test/helpers/test_app/admin/user/special/roles_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" diff --git a/railties/test/generators/observer_generator_test.rb b/railties/test/generators/observer_generator_test.rb index afcee0a2dc..1231827466 100644 --- a/railties/test/generators/observer_generator_test.rb +++ b/railties/test/generators/observer_generator_test.rb @@ -17,7 +17,7 @@ class ObserverGeneratorTest < Rails::Generators::TestCase def test_invokes_default_test_framework run_generator - assert_file "test/unit/account_observer_test.rb", /class AccountObserverTest < ActiveSupport::TestCase/ + assert_file "test/models/account_observer_test.rb", /class AccountObserverTest < ActiveSupport::TestCase/ end def test_logs_if_the_test_framework_cannot_be_found diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb index 73804dae45..0ae0841442 100644 --- a/railties/test/generators/resource_generator_test.rb +++ b/railties/test/generators/resource_generator_test.rb @@ -18,7 +18,7 @@ class ResourceGeneratorTest < Rails::Generators::TestCase %w( app/models/account.rb - test/unit/account_test.rb + test/models/account_test.rb test/fixtures/accounts.yml ).each { |path| assert_file path } @@ -33,10 +33,10 @@ class ResourceGeneratorTest < Rails::Generators::TestCase def test_resource_controller_with_pluralized_class_name run_generator assert_file "app/controllers/accounts_controller.rb", /class AccountsController < ApplicationController/ - assert_file "test/functional/accounts_controller_test.rb", /class AccountsControllerTest < ActionController::TestCase/ + assert_file "test/controllers/accounts_controller_test.rb", /class AccountsControllerTest < ActionController::TestCase/ assert_file "app/helpers/accounts_helper.rb", /module AccountsHelper/ - assert_file "test/unit/helpers/accounts_helper_test.rb", /class AccountsHelperTest < ActionView::TestCase/ + assert_file "test/helpers/accounts_helper_test.rb", /class AccountsHelperTest < ActionView::TestCase/ end def test_resource_controller_with_actions @@ -62,14 +62,14 @@ class ResourceGeneratorTest < Rails::Generators::TestCase def test_plural_names_are_singularized content = run_generator ["accounts".freeze] assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/ - assert_file "test/unit/account_test.rb", /class AccountTest/ + assert_file "test/models/account_test.rb", /class AccountTest/ assert_match(/Plural version of the model detected, using singularized version. Override with --force-plural./, content) end def test_plural_names_can_be_forced content = run_generator ["accounts", "--force-plural"] assert_file "app/models/accounts.rb", /class Accounts < ActiveRecord::Base/ - assert_file "test/unit/accounts_test.rb", /class AccountsTest/ + assert_file "test/models/accounts_test.rb", /class AccountsTest/ assert_no_match(/Plural version of the model detected/, content) end diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index aa09343346..38454dfb8b 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -57,7 +57,7 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_helper_are_invoked_with_a_pluralized_name run_generator assert_file "app/helpers/users_helper.rb", /module UsersHelper/ - assert_file "test/unit/helpers/users_helper_test.rb", /class UsersHelperTest < ActionView::TestCase/ + assert_file "test/helpers/users_helper_test.rb", /class UsersHelperTest < ActionView::TestCase/ end def test_views_are_generated @@ -75,7 +75,7 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_functional_tests run_generator - assert_file "test/functional/users_controller_test.rb" do |content| + assert_file "test/controllers/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) @@ -86,7 +86,7 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_functional_tests_without_attributes run_generator ["User"] - assert_file "test/functional/users_controller_test.rb" do |content| + assert_file "test/controllers/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) @@ -97,7 +97,7 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_skip_helper_if_required run_generator ["User", "name:string", "age:integer", "--no-helper"] assert_no_file "app/helpers/users_helper.rb" - assert_no_file "test/unit/helpers/users_helper_test.rb" + assert_no_file "test/helpers/users_helper_test.rb" end def test_skip_layout_if_required diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index f802f3c4ad..dc825c7c99 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -12,7 +12,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Model assert_file "app/models/product_line.rb", /class ProductLine < ActiveRecord::Base/ - assert_file "test/unit/product_line_test.rb", /class ProductLineTest < ActiveSupport::TestCase/ + assert_file "test/models/product_line_test.rb", /class ProductLineTest < ActiveSupport::TestCase/ assert_file "test/fixtures/product_lines.yml" assert_migration "db/migrate/create_product_lines.rb", /belongs_to :product, index: true/ assert_migration "db/migrate/create_product_lines.rb", /references :user, index: true/ @@ -60,7 +60,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase end end - assert_file "test/functional/product_lines_controller_test.rb" do |test| + assert_file "test/controllers/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) @@ -78,7 +78,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_file "app/helpers/product_lines_helper.rb" - assert_file "test/unit/helpers/product_lines_helper_test.rb" + assert_file "test/helpers/product_lines_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css" @@ -89,7 +89,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase def test_functional_tests_without_attributes run_generator ["product_line"] - assert_file "test/functional/product_lines_controller_test.rb" do |content| + assert_file "test/controllers/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) @@ -103,7 +103,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Model assert_no_file "app/models/product_line.rb" - assert_no_file "test/unit/product_line_test.rb" + assert_no_file "test/models/product_line_test.rb" assert_no_file "test/fixtures/product_lines.yml" assert_no_migration "db/migrate/create_product_lines.rb" @@ -114,7 +114,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Controller assert_no_file "app/controllers/product_lines_controller.rb" - assert_no_file "test/functional/product_lines_controller_test.rb" + assert_no_file "test/controllers/product_lines_controller_test.rb" # Views assert_no_file "app/views/product_lines" @@ -122,7 +122,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_no_file "app/helpers/product_lines_helper.rb" - assert_no_file "test/unit/helpers/product_lines_helper_test.rb" + assert_no_file "test/helpers/product_lines_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ @@ -136,7 +136,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Model assert_file "app/models/admin.rb", /module Admin/ assert_file "app/models/admin/role.rb", /class Admin::Role < ActiveRecord::Base/ - assert_file "test/unit/admin/role_test.rb", /class Admin::RoleTest < ActiveSupport::TestCase/ + assert_file "test/models/admin/role_test.rb", /class Admin::RoleTest < ActiveSupport::TestCase/ assert_file "test/fixtures/admin/roles.yml" assert_migration "db/migrate/create_admin_roles.rb" @@ -183,7 +183,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase end end - assert_file "test/functional/admin/roles_controller_test.rb", + assert_file "test/controllers/admin/roles_controller_test.rb", /class Admin::RolesControllerTest < ActionController::TestCase/ # Views @@ -198,7 +198,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_file "app/helpers/admin/roles_helper.rb" - assert_file "test/unit/helpers/admin/roles_helper_test.rb" + assert_file "test/helpers/admin/roles_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ @@ -213,7 +213,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Model assert_file "app/models/admin.rb" # ( should not be remove ) assert_no_file "app/models/admin/role.rb" - assert_no_file "test/unit/admin/role_test.rb" + assert_no_file "test/models/admin/role_test.rb" assert_no_file "test/fixtures/admin/roles.yml" assert_no_migration "db/migrate/create_admin_roles.rb" @@ -224,7 +224,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Controller assert_no_file "app/controllers/admin/roles_controller.rb" - assert_no_file "test/functional/admin/roles_controller_test.rb" + assert_no_file "test/controllers/admin/roles_controller_test.rb" # Views assert_no_file "app/views/admin/roles" @@ -232,7 +232,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_no_file "app/helpers/admin/roles_helper.rb" - assert_no_file "test/unit/helpers/admin/roles_helper_test.rb" + assert_no_file "test/helpers/admin/roles_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css" |