diff options
33 files changed, 193 insertions, 63 deletions
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index c95b9a4097..96d701dba5 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -88,7 +88,7 @@ module AbstractController # Returns the full controller name, underscored, without the ending Controller. # # class MyApp::MyPostsController < AbstractController::Base - # end + # # end # # MyApp::MyPostsController.controller_path # => "my_app/my_posts" diff --git a/actionpack/lib/action_dispatch/journey/router.rb b/actionpack/lib/action_dispatch/journey/router.rb index cc4bd6105d..b84aad8eb6 100644 --- a/actionpack/lib/action_dispatch/journey/router.rb +++ b/actionpack/lib/action_dispatch/journey/router.rb @@ -121,7 +121,8 @@ module ActionDispatch end def match_head_routes(routes, req) - head_routes = match_routes(routes, req) + verb_specific_routes = routes.reject { |route| route.verb == // } + head_routes = match_routes(verb_specific_routes, req) if head_routes.empty? begin diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 77f86b7a62..26b8636c2f 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -3567,12 +3567,11 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest mount lambda { |env| [200, {}, [env['REQUEST_METHOD']]] }, at: '/' end - # TODO: HEAD request should match `get /home` rather than the + # HEAD request should match `get /home` rather than the # lower-precedence Rack app mounted at `/`. head '/home' assert_response :ok - #assert_equal 'test#index', @response.body - assert_equal 'HEAD', @response.body + assert_equal 'test#index', @response.body # But the Rack app can still respond to its own HEAD requests. head '/foobar' diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb index 0633213d5e..9c8edc69a9 100644 --- a/actionview/lib/action_view/helpers/date_helper.rb +++ b/actionview/lib/action_view/helpers/date_helper.rb @@ -69,8 +69,8 @@ module ActionView # distance_of_time_in_words(to_time, from_time, include_seconds: true) # => about 6 years # distance_of_time_in_words(Time.now, Time.now) # => less than a minute # - # With the <tt>scope</tt> you can define a custom scope for Rails lookup - # the translation. + # With the <tt>scope</tt> option, you can define a custom scope for Rails + # to lookup the translation. # # For example you can define the following in your locale (e.g. en.yml). # @@ -78,8 +78,8 @@ module ActionView # distance_in_words: # short: # about_x_hours: - # one: 1 hr - # other: '%{count} hr' + # one: 'an hour' + # other: '%{count} hours' # # See https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en.yml # for more examples. @@ -87,8 +87,8 @@ module ActionView # Which will then result in the following: # # from_time = Time.now - # distance_of_time_in_words(from_time, from_time + 50.minutes, scope: 'datetime.distance_in_words.short') # => 1 hr - # distance_of_time_in_words(from_time, from_time + 3.hours, scope: 'datetime.distance_in_words.short') # => 3 hr + # distance_of_time_in_words(from_time, from_time + 50.minutes, scope: 'datetime.distance_in_words.short') # => "an hour" + # distance_of_time_in_words(from_time, from_time + 3.hours, scope: 'datetime.distance_in_words.short') # => "3 hours" def distance_of_time_in_words(from_time, to_time = 0, options = {}) options = { scope: :'datetime.distance_in_words' diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb index 2ea740b56b..fb33342d30 100644 --- a/activemodel/lib/active_model/validations/length.rb +++ b/activemodel/lib/active_model/validations/length.rb @@ -98,7 +98,7 @@ module ActiveModel module HelperMethods - # Validates that the specified attribute matches the length restrictions + # Validates that the specified attributes match the length restrictions # supplied. Only one option can be used at a time: # # class Person < ActiveRecord::Base diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 3351013b16..d87e609956 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,17 @@ +* Prevent error when using `force_reload: true` on an unassigned polymorphic + belongs_to association. + + Fixes #20426. + + *James Dabbs* + +* Correctly raise `ActiveRecord::AssociationTypeMismatch` when assigning + a wrong type to a namespaced association. + + Fixes #20545. + + *Diego Carrion* + * `validates_absence_of` respects `marked_for_destruction?`. Fixes #20449. diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb index 930f678ae8..7c729676a7 100644 --- a/activerecord/lib/active_record/associations/association.rb +++ b/activerecord/lib/active_record/associations/association.rb @@ -211,9 +211,12 @@ module ActiveRecord # the kind of the class of the associated objects. Meant to be used as # a sanity check when you are about to assign an associated record. def raise_on_type_mismatch!(record) - unless record.is_a?(reflection.klass) || record.is_a?(reflection.class_name.constantize) - message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})" - raise ActiveRecord::AssociationTypeMismatch, message + unless record.is_a?(reflection.klass) + fresh_class = reflection.class_name.safe_constantize + unless fresh_class && record.is_a?(fresh_class) + message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})" + raise ActiveRecord::AssociationTypeMismatch, message + end end end diff --git a/activerecord/lib/active_record/associations/preloader.rb b/activerecord/lib/active_record/associations/preloader.rb index 97f4bd3811..d60dd911e1 100644 --- a/activerecord/lib/active_record/associations/preloader.rb +++ b/activerecord/lib/active_record/associations/preloader.rb @@ -10,13 +10,13 @@ module ActiveRecord # end # # class Book < ActiveRecord::Base - # # columns: title, sales + # # columns: title, sales, author_id # end # # When you load an author with all associated books Active Record will make # multiple queries like this: # - # Author.includes(:books).where(:name => ['bell hooks', 'Homer').to_a + # Author.includes(:books).where(name: ['bell hooks', 'Homer']).to_a # # => SELECT `authors`.* FROM `authors` WHERE `name` IN ('bell hooks', 'Homer') # => SELECT `books`.* FROM `books` WHERE `author_id` IN (2, 5) diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb index 58d0f7d65d..bec9505bd2 100644 --- a/activerecord/lib/active_record/associations/singular_association.rb +++ b/activerecord/lib/active_record/associations/singular_association.rb @@ -3,7 +3,7 @@ module ActiveRecord class SingularAssociation < Association #:nodoc: # Implements the reader method, e.g. foo.bar for Foo.has_one :bar def reader(force_reload = false) - if force_reload + if force_reload && klass klass.uncached { reload } elsif !loaded? || stale_target? reload diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index 7108b087f1..df72ba7e9c 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -139,7 +139,7 @@ module ActiveRecord # # SELECT people.id, people.name FROM people # # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']] # - # Person.pluck('DISTINCT role') + # Person.uniq.pluck(:role) # # SELECT DISTINCT role FROM people # # => ['admin', 'member', 'guest'] # diff --git a/activerecord/lib/active_record/type/decimal.rb b/activerecord/lib/active_record/type/decimal.rb index 867b5f75c7..f200a92d10 100644 --- a/activerecord/lib/active_record/type/decimal.rb +++ b/activerecord/lib/active_record/type/decimal.rb @@ -8,7 +8,7 @@ module ActiveRecord end def type_cast_for_schema(value) - value.to_s + value.to_s.inspect end private diff --git a/activerecord/lib/active_record/validations/length.rb b/activerecord/lib/active_record/validations/length.rb index ebb1034da7..69e048eef1 100644 --- a/activerecord/lib/active_record/validations/length.rb +++ b/activerecord/lib/active_record/validations/length.rb @@ -22,7 +22,7 @@ module ActiveRecord end module ClassMethods - # Validates that the specified attributes matches the length restrictions supplied. + # Validates that the specified attributes match the length restrictions supplied. # If the attribute is an association, records that are marked for destruction are not counted. # # See ActiveModel::Validations::HelperMethods.validates_length_of for more information. diff --git a/activerecord/test/cases/adapters/postgresql/money_test.rb b/activerecord/test/cases/adapters/postgresql/money_test.rb index e3670c203d..c031178479 100644 --- a/activerecord/test/cases/adapters/postgresql/money_test.rb +++ b/activerecord/test/cases/adapters/postgresql/money_test.rb @@ -56,7 +56,7 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase def test_schema_dumping output = dump_table_schema("postgresql_moneys") assert_match %r{t\.money\s+"wealth",\s+scale: 2$}, output - assert_match %r{t\.money\s+"depth",\s+scale: 2,\s+default: 150\.55$}, output + assert_match %r{t\.money\s+"depth",\s+scale: 2,\s+default: "150\.55"$}, output end def test_create_and_update_money diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index 9aba2b5976..35d5581aa7 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -480,6 +480,7 @@ class DefaultsUsingMultipleSchemasAndDomainTest < ActiveRecord::PostgreSQLTestCa @connection.create_table "defaults" do |t| t.text "text_col", default: "some value" t.string "string_col", default: "some value" + t.decimal "decimal_col", default: "3.14159265358979323846" end Default.reset_column_information end @@ -498,6 +499,10 @@ class DefaultsUsingMultipleSchemasAndDomainTest < ActiveRecord::PostgreSQLTestCa assert_equal "some value", Default.new.string_col, "Default of string column was not correctly parsed" end + def test_decimal_defaults_in_new_schema_when_overriding_domain + assert_equal BigDecimal.new("3.14159265358979323846"), Default.new.decimal_col, "Default of decimal column was not correctly parsed" + end + def test_bpchar_defaults_in_new_schema_when_overriding_domain @connection.execute "ALTER TABLE defaults ADD bpchar_col bpchar DEFAULT 'some value'" Default.reset_column_information diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 039cc46b0b..ebe08c618f 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -19,6 +19,8 @@ require 'models/invoice' require 'models/line_item' require 'models/column' require 'models/record' +require 'models/admin' +require 'models/admin/user' class BelongsToAssociationsTest < ActiveRecord::TestCase fixtures :accounts, :companies, :developers, :projects, :topics, @@ -151,6 +153,30 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) } end + def test_raises_type_mismatch_with_namespaced_class + assert_nil defined?(Region), "This test requires that there is no top-level Region class" + + ActiveRecord::Base.connection.instance_eval do + create_table(:admin_regions) { |t| t.string :name } + add_column :admin_users, :region_id, :integer + end + Admin.const_set "RegionalUser", Class.new(Admin::User) { belongs_to(:region) } + Admin.const_set "Region", Class.new(ActiveRecord::Base) + + e = assert_raise(ActiveRecord::AssociationTypeMismatch) { + Admin::RegionalUser.new(region: 'wrong value') + } + assert_match(/^Region\([^)]+\) expected, got String\([^)]+\)$/, e.message) + ensure + Admin.send :remove_const, "Region" if Admin.const_defined?("Region") + Admin.send :remove_const, "RegionalUser" if Admin.const_defined?("RegionalUser") + + ActiveRecord::Base.connection.instance_eval do + remove_column :admin_users, :region_id if column_exists?(:admin_users, :region_id) + drop_table :admin_regions, if_exists: true + end + end + def test_natural_assignment apple = Firm.create("name" => "Apple") citibank = Account.create("credit_limit" => 10) @@ -292,9 +318,11 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_polymorphic_association_class sponsor = Sponsor.new assert_nil sponsor.association(:sponsorable).send(:klass) + assert_nil sponsor.sponsorable(force_reload: true) sponsor.sponsorable_type = '' # the column doesn't have to be declared NOT NULL assert_nil sponsor.association(:sponsorable).send(:klass) + assert_nil sponsor.sponsorable(force_reload: true) sponsor.sponsorable = Member.new :name => "Bert" assert_equal Member, sponsor.association(:sponsorable).send(:klass) diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 51170c533b..feb1c29656 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -239,7 +239,7 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_schema_dump_includes_decimal_options output = dump_all_table_schema([/^[^n]/]) - assert_match %r{precision: 3,[[:space:]]+scale: 2,[[:space:]]+default: 2\.78}, output + assert_match %r{precision: 3,[[:space:]]+scale: 2,[[:space:]]+default: "2\.78"}, output end if current_adapter?(:PostgreSQLAdapter) @@ -255,7 +255,7 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_schema_dump_allows_array_of_decimal_defaults output = standard_dump - assert_match %r{t\.decimal\s+"decimal_array_default",\s+default: \[1.23, 3.45\],\s+array: true}, output + assert_match %r{t\.decimal\s+"decimal_array_default",\s+default: \["1.23", "3.45"\],\s+array: true}, output end if ActiveRecord::Base.connection.supports_extensions? diff --git a/activerecord/test/cases/touch_later_test.rb b/activerecord/test/cases/touch_later_test.rb index 11804ff90b..49ada22529 100644 --- a/activerecord/test/cases/touch_later_test.rb +++ b/activerecord/test/cases/touch_later_test.rb @@ -2,8 +2,11 @@ require 'cases/helper' require 'models/invoice' require 'models/line_item' require 'models/topic' +require 'models/node' +require 'models/tree' class TouchLaterTest < ActiveRecord::TestCase + fixtures :nodes, :trees def test_touch_laster_raise_if_non_persisted invoice = Invoice.new @@ -90,4 +93,22 @@ class TouchLaterTest < ActiveRecord::TestCase invoice.touch_later end end + + def test_touching_three_deep + skip "Pending from #19324" + + previous_tree_updated_at = trees(:root).updated_at + previous_grandparent_updated_at = nodes(:grandparent).updated_at + previous_parent_updated_at = nodes(:parent_a).updated_at + previous_child_updated_at = nodes(:child_one_of_a).updated_at + + travel 5.seconds + + Node.create! parent: nodes(:child_one_of_a), tree: trees(:root) + + assert_not_equal nodes(:child_one_of_a).reload.updated_at, previous_child_updated_at + assert_not_equal nodes(:parent_a).reload.updated_at, previous_parent_updated_at + assert_not_equal nodes(:grandparent).reload.updated_at, previous_grandparent_updated_at + assert_not_equal trees(:root).reload.updated_at, previous_tree_updated_at + end end diff --git a/activerecord/test/fixtures/nodes.yml b/activerecord/test/fixtures/nodes.yml new file mode 100644 index 0000000000..b8bb8216ee --- /dev/null +++ b/activerecord/test/fixtures/nodes.yml @@ -0,0 +1,29 @@ +grandparent: + id: 1 + tree_id: 1 + name: Grand Parent + +parent_a: + id: 2 + tree_id: 1 + parent_id: 1 + name: Parent A + +parent_b: + id: 3 + tree_id: 1 + parent_id: 1 + name: Parent B + +child_one_of_a: + id: 4 + tree_id: 1 + parent_id: 2 + name: Child one + +child_two_of_b: + id: 5 + tree_id: 1 + parent_id: 2 + name: Child two + diff --git a/activerecord/test/fixtures/trees.yml b/activerecord/test/fixtures/trees.yml new file mode 100644 index 0000000000..9e030b7632 --- /dev/null +++ b/activerecord/test/fixtures/trees.yml @@ -0,0 +1,3 @@ +root: + id: 1 + name: The Root diff --git a/activerecord/test/models/node.rb b/activerecord/test/models/node.rb new file mode 100644 index 0000000000..07dd2dbccb --- /dev/null +++ b/activerecord/test/models/node.rb @@ -0,0 +1,5 @@ +class Node < ActiveRecord::Base + belongs_to :tree, touch: true + belongs_to :parent, class_name: 'Node', touch: true, optional: true + has_many :children, class_name: 'Node', foreign_key: :parent_id, dependent: :destroy +end diff --git a/activerecord/test/models/tree.rb b/activerecord/test/models/tree.rb new file mode 100644 index 0000000000..dc29cccc9c --- /dev/null +++ b/activerecord/test/models/tree.rb @@ -0,0 +1,3 @@ +class Tree < ActiveRecord::Base + has_many :nodes, dependent: :destroy +end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index dffccc9326..6872b49ad9 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -867,6 +867,17 @@ ActiveRecord::Schema.define do t.string 'from' end + create_table :nodes, force: true do |t| + t.integer :tree_id + t.integer :parent_id + t.string :name + t.datetime :updated_at + end + create_table :trees, force: true do |t| + t.string :name + t.datetime :updated_at + end + create_table :hotels, force: true do |t| end create_table :departments, force: true do |t| diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 8e22d4ed2f..69aea6213f 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -1026,10 +1026,6 @@ class NullStoreTest < ActiveSupport::TestCase end assert_nil @cache.read("name") end - - def test_setting_nil_cache_store - assert ActiveSupport::Cache.lookup_store.class.name, ActiveSupport::Cache::NullStore.name - end end class CacheStoreLoggerTest < ActiveSupport::TestCase diff --git a/guides/assets/images/getting_started/rails_welcome.png b/guides/assets/images/getting_started/rails_welcome.png Binary files differindex 3e07c948a0..4d0cb417b7 100644 --- a/guides/assets/images/getting_started/rails_welcome.png +++ b/guides/assets/images/getting_started/rails_welcome.png diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md index 373dbbb9aa..e49abc41f4 100644 --- a/guides/source/active_support_instrumentation.md +++ b/guides/source/active_support_instrumentation.md @@ -321,17 +321,6 @@ Action Mailer } ``` -Active Resource --------------- - -### request.active_resource - -| Key | Value | -| -------------- | -------------------- | -| `:method` | HTTP method | -| `:request_uri` | Complete URI | -| `:result` | HTTP response object | - Active Support -------------- diff --git a/guides/source/generators.md b/guides/source/generators.md index 14f451cbc9..32bbdc554a 100644 --- a/guides/source/generators.md +++ b/guides/source/generators.md @@ -503,6 +503,14 @@ Adds a specified source to `Gemfile`: add_source "http://gems.github.com" ``` +This method also takes a block: + +```ruby +add_source "http://gems.github.com" do + gem "rspec-rails" +end +``` + ### `inject_into_file` Injects a block of code into a defined position in your file. diff --git a/guides/source/i18n.md b/guides/source/i18n.md index 31682464ee..272a0e3623 100644 --- a/guides/source/i18n.md +++ b/guides/source/i18n.md @@ -210,7 +210,7 @@ This approach has almost the same set of advantages as setting the locale from t Getting the locale from `params` and setting it accordingly is not hard; including it in every URL and thus **passing it through the requests** is. To include an explicit option in every URL, e.g. `link_to(books_url(locale: I18n.locale))`, would be tedious and probably impossible, of course. -Rails contains infrastructure for "centralizing dynamic decisions about the URLs" in its [`ApplicationController#default_url_options`](http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Base.html#method-i-default_url_options), which is useful precisely in this scenario: it enables us to set "defaults" for [`url_for`](http://api.rubyonrails.org/classes/ActionDispatch/Routing/UrlFor.html#method-i-url_for) and helper methods dependent on it (by implementing/overriding this method). +Rails contains infrastructure for "centralizing dynamic decisions about the URLs" in its [`ApplicationController#default_url_options`](http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Base.html#method-i-default_url_options), which is useful precisely in this scenario: it enables us to set "defaults" for [`url_for`](http://api.rubyonrails.org/classes/ActionDispatch/Routing/UrlFor.html#method-i-url_for) and helper methods dependent on it (by implementing/overriding `default_url_options`). We can include something like this in our `ApplicationController` then: diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md index 99ab47d1db..1e2fe94010 100644 --- a/guides/source/rails_on_rack.md +++ b/guides/source/rails_on_rack.md @@ -58,22 +58,6 @@ class Server < ::Rack::Server end ``` -Here's how it loads the middlewares: - -```ruby -def middleware - middlewares = [] - middlewares << [::Rack::ContentLength] - Hash.new(middlewares) -end -``` - -The following table explains the usage of the loaded middlewares: - -| Middleware | Purpose | -| ----------------------- | --------------------------------------------------------------------------------- | -| `Rack::ContentLength` | Counts the number of bytes in the response and set the HTTP Content-Length header | - ### `rackup` To use `rackup` instead of Rails' `rails server`, you can put the following inside `config.ru` of your Rails application's root directory: @@ -81,8 +65,6 @@ To use `rackup` instead of Rails' `rails server`, you can put the following insi ```ruby # Rails.root/config.ru require ::File.expand_path('../config/environment', __FILE__) - -use Rack::ContentLength run Rails.application ``` diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 7367f0a813..7c0d4e3b31 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,7 @@ +* Adding support for passing a block to the `add_source` action of a custom generator + + *Mike Dalton*, *Hirofumi Wakasugi* + * `assert_file` understands paths with special characters (eg. `v0.1.4~alpha+nightly`). diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 70a20801a0..560a553789 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -63,12 +63,26 @@ module Rails # Add the given source to +Gemfile+ # + # If block is given, gem entries in block are wrapped into the source group. + # # add_source "http://gems.github.com/" - def add_source(source, options={}) + # + # add_source "http://gems.github.com/" do + # gem "rspec-rails" + # end + def add_source(source, options={}, &block) log :source, source in_root do - prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false + if block + append_file "Gemfile", "source #{quote(source)} do", force: true + @in_group = true + instance_eval(&block) + @in_group = false + append_file "Gemfile", "\nend\n", force: true + else + prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false + end end end diff --git a/railties/lib/rails/test_unit/reporter.rb b/railties/lib/rails/test_unit/reporter.rb index faf551f381..09b8675cf8 100644 --- a/railties/lib/rails/test_unit/reporter.rb +++ b/railties/lib/rails/test_unit/reporter.rb @@ -7,7 +7,7 @@ module Rails self.executable = "bin/rails test" def report - return if results.empty? + return if filtered_results.empty? io.puts io.puts "Failed tests:" io.puts @@ -15,14 +15,20 @@ module Rails end def aggregated_results # :nodoc: - filtered_results = results.dup - filtered_results.reject!(&:skipped?) unless options[:verbose] filtered_results.map do |result| location, line = result.method(result.name).source_location "#{self.executable} #{relative_path_for(location)}:#{line}" end.join "\n" end + def filtered_results + if options[:verbose] + results + else + results.reject(&:skipped?) + end + end + def relative_path_for(file) file.sub(/^#{Rails.root}\/?/, '') end diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 4a4317c4f4..2857dae07e 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -47,6 +47,14 @@ class ActionsTest < Rails::Generators::TestCase assert_file 'Gemfile', /source 'http:\/\/gems\.github\.com'/ end + def test_add_source_with_block_adds_source_to_gemfile_with_gem + run_generator + action :add_source, 'http://gems.github.com' do + gem 'rspec-rails' + end + assert_file 'Gemfile', /source 'http:\/\/gems\.github\.com' do\n gem 'rspec-rails'\nend/ + end + def test_gem_should_put_gem_dependency_in_gemfile run_generator action :gem, 'will-paginate' diff --git a/railties/test/test_unit/reporter_test.rb b/railties/test/test_unit/reporter_test.rb index f9c7888bc6..3066ba82d6 100644 --- a/railties/test/test_unit/reporter_test.rb +++ b/railties/test/test_unit/reporter_test.rb @@ -32,6 +32,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase @reporter.record(passing_test) @reporter.record(skipped_test) @reporter.report + assert_no_match 'Failed tests:', @output.string assert_rerun_snippet_count 0 end |