diff options
35 files changed, 271 insertions, 196 deletions
@@ -4,7 +4,7 @@ gemspec gem 'arel', github: 'rails/arel', branch: 'master' -gem 'mocha', '>= 0.11.2', require: false +gem 'mocha', github: 'freerange/mocha', require: false gem 'rack-test', github: 'brynary/rack-test' gem 'rack-cache', '~> 1.2' gem 'bcrypt-ruby', '~> 3.0.0' diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 72121668ac..e04eac739d 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,21 @@ ## Rails 4.0.0 (unreleased) ## +* Fix input name when `:multiple => true` and `:index` are set. + + Before: + + check_box("post", "comment_ids", { :multiple => true, :index => "foo" }, 1) + #=> <input name=\"post[foo][comment_ids]\" type=\"hidden\" value=\"0\" /><input id=\"post_foo_comment_ids_1\" name=\"post[foo][comment_ids]\" type=\"checkbox\" value=\"1\" /> + + After: + + check_box("post", "comment_ids", { :multiple => true, :index => "foo" }, 1) + #=> <input name=\"post[foo][comment_ids][]\" type=\"hidden\" value=\"0\" /><input id=\"post_foo_comment_ids_1\" name=\"post[foo][comment_ids][]\" type=\"checkbox\" value=\"1\" /> + + Fix #8108 + + *Daniel Fox, Grant Hutchins & Trace Wax* + * Clear url helpers when reloading routes. *Santiago Pastorino* diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index bd0bcd23ff..da640502a2 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -259,7 +259,9 @@ module ActionController # params.slice(:a, :b) # => {"a"=>1, "b"=>2} # params.slice(:d) # => {} def slice(*keys) - self.class.new(super) + self.class.new(super).tap do |new_instance| + new_instance.instance_variable_set :@permitted, @permitted + end end # Returns an exact copy of the <tt>ActionController::Parameters</tt> diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 0de10695e0..2b37a8d026 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -28,7 +28,7 @@ module ActionDispatch def call(env) begin - response = @app.call(env) + response = @app.call(env) rescue Exception => exception raise exception if env['action_dispatch.show_exceptions'] == false end diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index fc63470174..7cc71fe6dc 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -20,26 +20,51 @@ class ParametersPermitTest < ActiveSupport::TestCase assert_equal "monkey", @params.fetch(:foo) { "monkey" } end - test "permitted is sticky on accessors" do + test "not permitted is sticky on accessors" do assert !@params.slice(:person).permitted? assert !@params[:person][:name].permitted? + assert !@params[:person].except(:name).permitted? - @params.each { |key, value| assert(value.permitted?) if key == :person } + @params.each { |key, value| assert(!value.permitted?) if key == "person" } assert !@params.fetch(:person).permitted? assert !@params.values_at(:person).first.permitted? end + test "permitted is sticky on accessors" do + @params.permit! + assert @params.slice(:person).permitted? + assert @params[:person][:name].permitted? + assert @params[:person].except(:name).permitted? + + @params.each { |key, value| assert(value.permitted?) if key == "person" } + + assert @params.fetch(:person).permitted? + + assert @params.values_at(:person).first.permitted? + end + + test "not permitted is sticky on mutators" do + assert !@params.delete_if { |k| k == "person" }.permitted? + assert !@params.keep_if { |k,v| k == "person" }.permitted? + end + test "permitted is sticky on mutators" do - assert !@params.delete_if { |k| k == :person }.permitted? - assert !@params.keep_if { |k,v| k == :person }.permitted? + @params.permit! + assert @params.delete_if { |k| k == "person" }.permitted? + assert @params.keep_if { |k,v| k == "person" }.permitted? end - test "permitted is sticky beyond merges" do + test "not permitted is sticky beyond merges" do assert !@params.merge(a: "b").permitted? end + test "permitted is sticky beyond merges" do + @params.permit! + assert @params.merge(a: "b").permitted? + end + test "modifying the parameters" do @params[:person][:hometown] = "Chicago" @params[:person][:family] = { brother: "Jonas" } @@ -77,7 +102,7 @@ class ParametersPermitTest < ActiveSupport::TestCase ActionController::Parameters.permit_all_parameters = false end end - + test "permitting parameters as an array" do assert_equal "32", @params[:person].permit([ :age ])[:age] end diff --git a/actionpack/test/controller/show_exceptions_test.rb b/actionpack/test/controller/show_exceptions_test.rb index ab1bd0e3b6..718d06ef38 100644 --- a/actionpack/test/controller/show_exceptions_test.rb +++ b/actionpack/test/controller/show_exceptions_test.rb @@ -104,7 +104,7 @@ module ShowExceptions get '/', {}, 'HTTP_ACCEPT' => 'text/json' assert_response :internal_server_error assert_equal 'text/plain', response.content_type.to_s - + ensure @app.instance_variable_set(:@exceptions_app, @exceptions_app) $stderr = STDERR end diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 6882b59e26..c82d4f012c 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -308,7 +308,7 @@ module ActiveModel # person.errors.messages # # => {:name=>["can't be empty"]} def add_on_empty(attributes, options = {}) - [attributes].flatten.each do |attribute| + Array(attributes).each do |attribute| value = @base.send(:read_attribute_for_validation, attribute) is_empty = value.respond_to?(:empty?) ? value.empty? : false add(attribute, :empty, options) if value.nil? || is_empty @@ -322,7 +322,7 @@ module ActiveModel # person.errors.messages # # => {:name=>["can't be blank"]} def add_on_blank(attributes, options = {}) - [attributes].flatten.each do |attribute| + Array(attributes).each do |attribute| value = @base.send(:read_attribute_for_validation, attribute) add(attribute, :blank, options) if value.blank? end diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index 3bc0d58351..293ce07f4e 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -7,7 +7,7 @@ class ErrorsTest < ActiveModel::TestCase @errors = ActiveModel::Errors.new(self) end - attr_accessor :name + attr_accessor :name, :age attr_reader :errors def validate! @@ -201,5 +201,43 @@ class ErrorsTest < ActiveModel::TestCase person.errors.generate_message(:name, :blank) } end + + test "add_on_empty generates message" do + person = Person.new + person.errors.expects(:generate_message).with(:name, :empty, {}) + person.errors.add_on_empty :name + end + + test "add_on_empty generates message for multiple attributes" do + person = Person.new + person.errors.expects(:generate_message).with(:name, :empty, {}) + person.errors.expects(:generate_message).with(:age, :empty, {}) + person.errors.add_on_empty [:name, :age] + end + + test "add_on_empty generates message with custom default message" do + person = Person.new + person.errors.expects(:generate_message).with(:name, :empty, {:message => 'custom'}) + person.errors.add_on_empty :name, :message => 'custom' + end + + test "add_on_blank generates message" do + person = Person.new + person.errors.expects(:generate_message).with(:name, :blank, {}) + person.errors.add_on_blank :name + end + + test "add_on_blank generates message for multiple attributes" do + person = Person.new + person.errors.expects(:generate_message).with(:name, :blank, {}) + person.errors.expects(:generate_message).with(:age, :blank, {}) + person.errors.add_on_blank [:name, :age] + end + + test "add_on_blank generates message with custom default message" do + person = Person.new + person.errors.expects(:generate_message).with(:name, :blank, {:message => 'custom'}) + person.errors.add_on_blank :name, :message => 'custom' + end end diff --git a/activemodel/test/cases/validations/i18n_validation_test.rb b/activemodel/test/cases/validations/i18n_validation_test.rb index 4f8b7327c0..4c01b47608 100644 --- a/activemodel/test/cases/validations/i18n_validation_test.rb +++ b/activemodel/test/cases/validations/i18n_validation_test.rb @@ -21,26 +21,6 @@ class I18nValidationTest < ActiveModel::TestCase I18n.backend = @old_backend end - def test_errors_add_on_empty_generates_message - @person.errors.expects(:generate_message).with(:title, :empty, {}) - @person.errors.add_on_empty :title - end - - def test_errors_add_on_empty_generates_message_with_custom_default_message - @person.errors.expects(:generate_message).with(:title, :empty, {:message => 'custom'}) - @person.errors.add_on_empty :title, :message => 'custom' - end - - def test_errors_add_on_blank_generates_message - @person.errors.expects(:generate_message).with(:title, :blank, {}) - @person.errors.add_on_blank :title - end - - def test_errors_add_on_blank_generates_message_with_custom_default_message - @person.errors.expects(:generate_message).with(:title, :blank, {:message => 'custom'}) - @person.errors.add_on_blank :title, :message => 'custom' - end - def test_full_message_encoding I18n.backend.store_translations('en', :errors => { :messages => { :too_short => '猫舌' }}) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 69b95f814c..a86e43664e 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1,6 +1,9 @@ require 'active_support/core_ext/enumerable' require 'active_support/core_ext/string/conversions' require 'active_support/core_ext/module/remove_method' +require 'active_support/dependencies/autoload' +require 'active_support/concern' +require 'active_record/errors' module ActiveRecord class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc: diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index 1b382f7285..fcdfc1e150 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -1,5 +1,8 @@ +require 'active_record/associations' + module ActiveRecord::Associations::Builder class CollectionAssociation < Association #:nodoc: + CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove] def valid_options diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index eabbd80f66..a694a292fe 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -8,7 +8,6 @@ require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/class/delegating_attributes' require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/hash/deep_merge' -require 'active_support/core_ext/hash/indifferent_access' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/string/behavior' require 'active_support/core_ext/kernel/singleton_class' diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index c3b9a0f9b7..22347fcaef 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -642,7 +642,11 @@ module ActiveRecord def proper_table_name(name) # Use the Active Record objects own table_name, or pre/suffix from ActiveRecord::Base if name is a symbol/string - name.table_name rescue "#{ActiveRecord::Base.table_name_prefix}#{name}#{ActiveRecord::Base.table_name_suffix}" + if name.respond_to? :table_name + name.table_name + else + "#{ActiveRecord::Base.table_name_prefix}#{name}#{ActiveRecord::Base.table_name_suffix}" + end end def migrations_paths diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 99c2f45bc8..af67b2ba6c 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -1,5 +1,3 @@ -require 'active_support/core_ext/hash/indifferent_access' - module ActiveRecord module FinderMethods # Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]). @@ -225,7 +223,7 @@ module ActiveRecord def construct_limited_ids_condition(relation) orders = relation.order_values.map { |val| val.presence }.compact - values = @klass.connection.distinct("#{@klass.connection.quote_table_name table_name}.#{primary_key}", orders) + values = @klass.connection.distinct("#{quoted_table_name}.#{primary_key}", orders) relation = relation.dup @@ -234,8 +232,6 @@ module ActiveRecord end def find_with_ids(*ids) - return to_a.find { |*block_args| yield(*block_args) } if block_given? - expects_array = ids.first.kind_of?(Array) return ids.first if expects_array && ids.first.empty? diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 4fdc296c7e..0817bb6d81 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -218,7 +218,6 @@ module ActiveRecord # Like #order, but modifies relation in place. def order!(*args) args.flatten! - validate_order_args args references = args.reject { |arg| Arel::Node === arg } @@ -245,7 +244,6 @@ module ActiveRecord # Like #reorder, but modifies relation in place. def reorder!(*args) args.flatten! - validate_order_args args self.reordering_value = true @@ -796,7 +794,7 @@ module ActiveRecord def reverse_sql_order(order_query) order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty? - order_query.map do |o| + order_query.flat_map do |o| case o when Arel::Nodes::Ordering o.reverse @@ -814,7 +812,7 @@ module ActiveRecord else o end - end.flatten + end end def array_of_strings?(o) @@ -825,7 +823,7 @@ module ActiveRecord orders = order_values orders = reverse_sql_order(orders) if reverse_order_value - orders = orders.uniq.reject(&:blank?).map do |order| + orders = orders.uniq.reject(&:blank?).flat_map do |order| case order when Symbol table[order].asc @@ -834,7 +832,7 @@ module ActiveRecord else order end - end.flatten + end arel.order(*orders) unless orders.empty? end diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 9674f2ce94..3f08f9ea4d 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -185,6 +185,17 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase assert_equal "James", mean_pirate.parrot.name assert_equal "blue", mean_pirate.parrot.color end + + def test_accepts_nested_attributes_for_can_be_overridden_in_subclasses + Pirate.accepts_nested_attributes_for(:parrot) + + mean_pirate_class = Class.new(Pirate) do + accepts_nested_attributes_for :parrot + end + mean_pirate = mean_pirate_class.new + mean_pirate.parrot_attributes = { :name => "James" } + assert_equal "James", mean_pirate.parrot.name + end end class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 02ae57b4a6..439d380af7 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -8,6 +8,8 @@ require 'active_support/core_ext/date_and_time/calculations' class Date include DateAndTime::Calculations + @beginning_of_week_default = nil + class << self attr_accessor :beginning_of_week_default diff --git a/activesupport/lib/active_support/core_ext/time/zones.rb b/activesupport/lib/active_support/core_ext/time/zones.rb index 139d48f59c..796c5f9805 100644 --- a/activesupport/lib/active_support/core_ext/time/zones.rb +++ b/activesupport/lib/active_support/core_ext/time/zones.rb @@ -1,6 +1,8 @@ require 'active_support/time_with_zone' class Time + @zone_default = nil + class << self attr_accessor :zone_default diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index 3910a2dc42..1eb2b4212b 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -286,10 +286,12 @@ module ActiveSupport # ordinal(-11) # => "th" # ordinal(-1021) # => "st" def ordinal(number) - if (11..13).include?(number.to_i.abs % 100) + abs_number = number.to_i.abs + + if (11..13).include?(abs_number % 100) "th" else - case number.to_i.abs % 10 + case abs_number % 10 when 1; "st" when 2; "nd" when 3; "rd" diff --git a/activesupport/lib/active_support/testing/mocha_module.rb b/activesupport/lib/active_support/testing/mocha_module.rb index ed2942d23a..833dc867f0 100644 --- a/activesupport/lib/active_support/testing/mocha_module.rb +++ b/activesupport/lib/active_support/testing/mocha_module.rb @@ -2,7 +2,7 @@ module ActiveSupport module Testing module MochaModule begin - require 'mocha_standalone' + require 'mocha/api' include Mocha::API def before_setup diff --git a/activesupport/lib/active_support/testing/tagged_logging.rb b/activesupport/lib/active_support/testing/tagged_logging.rb index 899467c45f..8ea2605733 100644 --- a/activesupport/lib/active_support/testing/tagged_logging.rb +++ b/activesupport/lib/active_support/testing/tagged_logging.rb @@ -1,10 +1,6 @@ -require 'active_support/concern' - module ActiveSupport module Testing module TaggedLogging - extend ActiveSupport::Concern - attr_writer :tagged_logger def before_setup diff --git a/activesupport/test/constantize_test_cases.rb b/activesupport/test/constantize_test_cases.rb index ec05213409..9b62295c96 100644 --- a/activesupport/test/constantize_test_cases.rb +++ b/activesupport/test/constantize_test_cases.rb @@ -24,52 +24,52 @@ end module ConstantizeTestCases def run_constantize_tests_on - assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") } - assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") } - assert_nothing_raised { assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") } - assert_nothing_raised { assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") } - assert_nothing_raised { assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") } - assert_nothing_raised { assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice") } - assert_nothing_raised { assert_equal Case::Dice, yield("Case::Dice") } - assert_nothing_raised { assert_equal Case::Dice, yield("Object::Case::Dice") } - assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } - assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } - assert_nothing_raised { assert_equal Object, yield("") } - assert_nothing_raised { assert_equal Object, yield("::") } - assert_raise(NameError) { yield("UnknownClass") } - assert_raise(NameError) { yield("UnknownClass::Ace") } - assert_raise(NameError) { yield("UnknownClass::Ace::Base") } - assert_raise(NameError) { yield("An invalid string") } - assert_raise(NameError) { yield("InvalidClass\n") } - assert_raise(NameError) { yield("Ace::ConstantizeTestCases") } - assert_raise(NameError) { yield("Ace::Base::ConstantizeTestCases") } - assert_raise(NameError) { yield("Ace::Gas::Base") } - assert_raise(NameError) { yield("Ace::Gas::ConstantizeTestCases") } + assert_equal Ace::Base::Case, yield("Ace::Base::Case") + assert_equal Ace::Base::Case, yield("::Ace::Base::Case") + assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") + assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") + assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") + assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice") + assert_equal Case::Dice, yield("Case::Dice") + assert_equal Case::Dice, yield("Object::Case::Dice") + assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") + assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") + assert_equal Object, yield("") + assert_equal Object, yield("::") + assert_raises(NameError) { yield("UnknownClass") } + assert_raises(NameError) { yield("UnknownClass::Ace") } + assert_raises(NameError) { yield("UnknownClass::Ace::Base") } + assert_raises(NameError) { yield("An invalid string") } + assert_raises(NameError) { yield("InvalidClass\n") } + assert_raises(NameError) { yield("Ace::ConstantizeTestCases") } + assert_raises(NameError) { yield("Ace::Base::ConstantizeTestCases") } + assert_raises(NameError) { yield("Ace::Gas::Base") } + assert_raises(NameError) { yield("Ace::Gas::ConstantizeTestCases") } end def run_safe_constantize_tests_on - assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") } - assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") } - assert_nothing_raised { assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") } - assert_nothing_raised { assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") } - assert_nothing_raised { assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") } - assert_nothing_raised { assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice") } - assert_nothing_raised { assert_equal Case::Dice, yield("Case::Dice") } - assert_nothing_raised { assert_equal Case::Dice, yield("Object::Case::Dice") } - assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } - assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } - assert_nothing_raised { assert_equal Object, yield("") } - assert_nothing_raised { assert_equal Object, yield("::") } - assert_nothing_raised { assert_equal nil, yield("UnknownClass") } - assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace") } - assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace::Base") } - assert_nothing_raised { assert_equal nil, yield("An invalid string") } - assert_nothing_raised { assert_equal nil, yield("InvalidClass\n") } - assert_nothing_raised { assert_equal nil, yield("blargle") } - assert_nothing_raised { assert_equal nil, yield("Ace::ConstantizeTestCases") } - assert_nothing_raised { assert_equal nil, yield("Ace::Base::ConstantizeTestCases") } - assert_nothing_raised { assert_equal nil, yield("Ace::Gas::Base") } - assert_nothing_raised { assert_equal nil, yield("Ace::Gas::ConstantizeTestCases") } - assert_nothing_raised { assert_equal nil, yield("#<Class:0x7b8b718b>::Nested_1") } + assert_equal Ace::Base::Case, yield("Ace::Base::Case") + assert_equal Ace::Base::Case, yield("::Ace::Base::Case") + assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") + assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") + assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") + assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice") + assert_equal Case::Dice, yield("Case::Dice") + assert_equal Case::Dice, yield("Object::Case::Dice") + assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") + assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") + assert_equal Object, yield("") + assert_equal Object, yield("::") + assert_nil yield("UnknownClass") + assert_nil yield("UnknownClass::Ace") + assert_nil yield("UnknownClass::Ace::Base") + assert_nil yield("An invalid string") + assert_nil yield("InvalidClass\n") + assert_nil yield("blargle") + assert_nil yield("Ace::ConstantizeTestCases") + assert_nil yield("Ace::Base::ConstantizeTestCases") + assert_nil yield("Ace::Gas::Base") + assert_nil yield("Ace::Gas::ConstantizeTestCases") + assert_nil yield("#<Class:0x7b8b718b>::Nested_1") end end diff --git a/activesupport/test/spec_type_test.rb b/activesupport/test/spec_type_test.rb index 95a982d8fd..9a6cb4ded2 100644 --- a/activesupport/test/spec_type_test.rb +++ b/activesupport/test/spec_type_test.rb @@ -4,7 +4,6 @@ require "active_record" class SomeRandomModel < ActiveRecord::Base; end class SpecTypeTest < ActiveSupport::TestCase - def assert_support actual assert_equal ActiveSupport::TestCase, actual end @@ -13,7 +12,7 @@ class SpecTypeTest < ActiveSupport::TestCase assert_equal MiniTest::Spec, actual end - def test_spec_type_resolves_for_actitive_record_constants + def test_spec_type_resolves_for_active_record_constants assert_support MiniTest::Spec.spec_type(SomeRandomModel) end diff --git a/activesupport/test/test_case_test.rb b/activesupport/test/test_case_test.rb index c02bfa8497..64426d02e9 100644 --- a/activesupport/test/test_case_test.rb +++ b/activesupport/test/test_case_test.rb @@ -16,6 +16,9 @@ module ActiveSupport def options nil end + + def record(*args) + end end def test_standard_error_raised_within_setup_callback_is_puked diff --git a/activesupport/test/testing/constant_lookup_test.rb b/activesupport/test/testing/constant_lookup_test.rb index c56c032cde..19280ba74a 100644 --- a/activesupport/test/testing/constant_lookup_test.rb +++ b/activesupport/test/testing/constant_lookup_test.rb @@ -1,7 +1,7 @@ require 'abstract_unit' class Foo; end -class Bar < Foo; +class Bar < Foo def index; end def self.index; end end diff --git a/guides/assets/stylesheets/main.css b/guides/assets/stylesheets/main.css index 9f5e101d1c..589c96e0e9 100644 --- a/guides/assets/stylesheets/main.css +++ b/guides/assets/stylesheets/main.css @@ -26,11 +26,13 @@ dl { margin: 0 0 1.5em 0; } dl dt { font-weight: bold; } dd { margin-left: 1.5em;} -pre,code { margin: 1.5em 0; overflow: auto; color: #222;} -pre,code { - font-size: 1em; - font-family: "Anonymous Pro", "Inconsolata", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - line-height: 1.5; +pre, code { + font-size: 1em; + font-family: "Anonymous Pro", "Inconsolata", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + line-height: 1.5; + margin: 1.5em 0; + overflow: auto; + color: #222; } pre,tt,code,.note>p { white-space: pre-wrap; /* css-3 */ @@ -92,14 +94,14 @@ body { line-height: 1.5em; background: #fff; color: #999; - } +} .wrapper { text-align: left; margin: 0 auto; max-width: 960px; padding: 0 1em; - } +} .red-button { display: inline-block; @@ -164,7 +166,6 @@ body { .more-info:last-child:after { content: ""; } - } @media screen and (max-width: 1024px) { @@ -218,7 +219,7 @@ body { color: #FFF; padding: 1.5em 0; z-index: 99; - } +} #feature { background: #d5e9f6 url(../images/feature_tile.gif) repeat-x; @@ -229,12 +230,12 @@ body { #container { color: #333; padding: 0.5em 0 1.5em 0; - } +} #mainCol { max-width: 630px; margin-left: 2em; - } +} #subCol { position: absolute; @@ -247,7 +248,7 @@ body { font-size: 0.9285em; line-height: 1.3846em; margin-right: 1em; - } +} @media screen and (max-width: 800px) { @@ -265,7 +266,7 @@ body { #footer { padding: 2em 0; background: #222 url(../images/footer_tile.gif) repeat-x; - } +} #footer .wrapper { padding-left: 1em; max-width: 960px; @@ -284,12 +285,11 @@ body { a, a:link, a:visited { color: #ee3f3f; text-decoration: underline; - } +} #mainCol a, #subCol a, #feature a {color: #980905;} #mainCol a code, #subCol a code, #feature a code {color: #980905;} - /* Navigation --------------------------------------- */ @@ -313,7 +313,6 @@ a, a:link, a:visited { background: #980905; position: relative; color: white; - cursor: pointer; } .guides-index .guides-index-item { @@ -345,7 +344,6 @@ a, a:link, a:visited { } @media screen and (max-width: 480px) { - .nav { float: none; width: 100%; @@ -408,7 +406,8 @@ a, a:link, a:visited { padding: 0; } #guides dt {padding:0; margin: 0.5em 0 0;} -#guides a {color: #FFF; background: none !important;} +#guides a {color: #FFF; background: none !important; text-decoration: none;} +#guides a:hover {text-decoration: underline;} #guides .L, #guides .R {float: left; width: 50%; margin: 0; padding: 0;} #guides .R {float: right;} #guides hr { @@ -427,14 +426,14 @@ h1 { line-height: 1em; margin: 0.6em 0 .2em; font-weight: bold; - } +} h2 { font-size: 2.1428em; line-height: 1em; margin: 0.7em 0 .2333em; font-weight: bold; - } +} @media screen and (max-width: 480px) { h2 { @@ -447,7 +446,7 @@ h3 { line-height: 1.286em; margin: 0.875em 0 0.2916em; font-weight: bold; - } +} @media screen and (max-width: 480px) { h3 { @@ -460,7 +459,7 @@ h4 { line-height: 1.2em; margin: 1.6667em 0 .3887em; font-weight: bold; - } +} h5 { font-size: 1em; @@ -474,7 +473,7 @@ h6 { line-height: 1.5em; margin: 1em 0 .5em; font-weight: normal; - } +} .section { padding-bottom: 0.25em; @@ -542,13 +541,19 @@ h6 { } #mainCol dt, #subCol dt { - font-size: 1em; + font-size: 1.2857em; padding: 0.125em 0 0.25em 0; margin-bottom: 0; /*background: url(../images/book_icon.gif) no-repeat left top; padding: 0.125em 0 0.25em 28px;*/ } +@media screen and (max-width: 480px) { + #mainCol dt, #subCol dt { + font-size: 1em; + } +} + #mainCol dd.work-in-progress, #subCol dd.work-in-progress { background: #fff9d8 url(../images/tab_yellow.gif) no-repeat left top; border: none; @@ -609,10 +614,10 @@ div.code_container { } #mainCol div.todo { - background: #fff9d8 url(../images/tab_yellow.gif) no-repeat left top; - border: none; - padding: 1em 1em 0.25em 48px; - margin: 0.25em 0 1.5em 0; + background: #fff9d8 url(../images/tab_yellow.gif) no-repeat left top; + border: none; + padding: 1em 1em 0.25em 48px; + margin: 0.25em 0 1.5em 0; } .note code, .info code, .todo code {border:none; background: none; padding: 0;} @@ -640,11 +645,11 @@ div.code_container { --------------------------------------- */ .clearfix:after { - content: "."; - display: block; - height: 0; - clear: both; - visibility: hidden; + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; } .clearfix {display: inline-block;} @@ -655,13 +660,13 @@ div.code_container { /* Same bottom margin for special boxes than for regular paragraphs, this way intermediate whitespace looks uniform. */ div.code_container, div.important, div.caution, div.warning, div.note, div.info { - margin-bottom: 1.5em; + margin-bottom: 1.5em; } /* Remove bottom margin of paragraphs in special boxes, otherwise they get a spurious blank area below with the box background. */ div.important p, div.caution p, div.warning p, div.note p, div.info p { - margin-bottom: 1em; + margin-bottom: 1em; } /* Edge Badge @@ -683,19 +688,18 @@ table td, table th { padding: 9px 10px; text-align: left; } /* Mobile */ @media only screen and (max-width: 767px) { - - table.responsive { margin-bottom: 0; } - - .pinned { position: absolute; left: 0; top: 0; background: #fff; width: 35%; overflow: hidden; overflow-x: scroll; border-right: 1px solid #ccc; border-left: 1px solid #ccc; } - .pinned table { border-right: none; border-left: none; width: 100%; } - .pinned table th, .pinned table td { white-space: nowrap; } - .pinned td:last-child { border-bottom: 0; } - - div.table-wrapper { position: relative; margin-bottom: 20px; overflow: hidden; border-right: 1px solid #ccc; } - div.table-wrapper div.scrollable table { margin-left: 35%; } - div.table-wrapper div.scrollable { overflow: scroll; overflow-y: hidden; } - - table.responsive td, table.responsive th { position: relative; white-space: nowrap; overflow: hidden; } - table.responsive th:first-child, table.responsive td:first-child, table.responsive td:first-child, table.responsive.pinned td { display: none; } - + table.responsive { margin-bottom: 0; } + + .pinned { position: absolute; left: 0; top: 0; background: #fff; width: 35%; overflow: hidden; overflow-x: scroll; border-right: 1px solid #ccc; border-left: 1px solid #ccc; } + .pinned table { border-right: none; border-left: none; width: 100%; } + .pinned table th, .pinned table td { white-space: nowrap; } + .pinned td:last-child { border-bottom: 0; } + + div.table-wrapper { position: relative; margin-bottom: 20px; overflow: hidden; border-right: 1px solid #ccc; } + div.table-wrapper div.scrollable table { margin-left: 35%; } + div.table-wrapper div.scrollable { overflow: scroll; overflow-y: hidden; } + + table.responsive td, table.responsive th { position: relative; white-space: nowrap; overflow: hidden; } + table.responsive th:first-child, table.responsive td:first-child, table.responsive td:first-child, table.responsive.pinned td { display: none; } + } diff --git a/guides/rails_guides/markdown/renderer.rb b/guides/rails_guides/markdown/renderer.rb index 2f36af1fb3..c3fe5b8799 100644 --- a/guides/rails_guides/markdown/renderer.rb +++ b/guides/rails_guides/markdown/renderer.rb @@ -9,7 +9,7 @@ module RailsGuides <<-HTML <div class="code_container"> <pre class="brush: #{brush_for(language)}; gutter: false; toolbar: false"> -#{ERB::Util.h(code).strip} +#{ERB::Util.h(code)} </pre> </div> HTML diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index cc77d08684..8538d5fbfa 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,5 +1,10 @@ ## Rails 4.0.0 (unreleased) ## +* Add dummy app Rake tasks when --skip-test-unit and --dummy-path is passed to the plugin generator. + Fix #8121 + + *Yves Senn* + * Ensure that RAILS_ENV is set when accessing Rails.env *Steve Klabnik* * Don't eager-load app/assets and app/views *Elia Schito* @@ -9,7 +14,7 @@ * 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 +* Set a different cache per environment for assets pipeline through `config.assets.cache`. *Guillermo Iguaran* 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 4a0bcc35a4..48ce3e86a1 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 @@ -225,7 +225,7 @@ task default: :test end def create_test_dummy_files - return if options[:skip_test_unit] && options[:dummy_path] == 'test/dummy' + return unless with_dummy_app? create_dummy_app end @@ -279,6 +279,10 @@ task default: :test options[:mountable] end + def with_dummy_app? + options[:skip_test_unit].blank? || options[:dummy_path] != 'test/dummy' + end + def self.banner "rails plugin new #{self.arguments.map(&:usage).join(' ')} [options]" end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile index 1369140537..65a5bae712 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile +++ b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile @@ -14,7 +14,7 @@ RDoc::Task.new(:rdoc) do |rdoc| rdoc.rdoc_files.include('lib/**/*.rb') end -<% if full? && !options[:skip_active_record] && !options[:skip_test_unit] -%> +<% if full? && !options[:skip_active_record] && with_dummy_app? -%> APP_RAKEFILE = File.expand_path("../<%= dummy_path -%>/Rakefile", __FILE__) load 'rails/tasks/engine.rake' <% end %> 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 121205b254..a0e5553e44 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 @@ -32,7 +32,7 @@ module Rails # route prepends two spaces onto the front of the string that is passed, this corrects that route route_string[2..-1] end - + private def route_string @route_string ||= "" diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb index 4b168ae110..9e7626647e 100644 --- a/railties/test/generators/namespaced_generators_test.rb +++ b/railties/test/generators/namespaced_generators_test.rb @@ -244,13 +244,9 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase /module TestApp\n class ProductLinesControllerTest < ActionController::TestCase/ # Views - %w( - index - edit - new - show - _form - ).each { |view| assert_file "app/views/test_app/product_lines/#{view}.html.erb" } + %w(index edit new show _form).each do |view| + assert_file "app/views/test_app/product_lines/#{view}.html.erb" + end assert_no_file "app/views/layouts/test_app/product_lines.html.erb" # Helpers @@ -316,13 +312,9 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase /module TestApp\n class Admin::RolesControllerTest < ActionController::TestCase/ # Views - %w( - index - edit - new - show - _form - ).each { |view| assert_file "app/views/test_app/admin/roles/#{view}.html.erb" } + %w(index edit new show _form).each do |view| + assert_file "app/views/test_app/admin/roles/#{view}.html.erb" + end assert_no_file "app/views/layouts/admin/roles.html.erb" # Helpers @@ -389,13 +381,9 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase /module TestApp\n class Admin::User::Special::RolesControllerTest < ActionController::TestCase/ # Views - %w( - index - edit - new - show - _form - ).each { |view| assert_file "app/views/test_app/admin/user/special/roles/#{view}.html.erb" } + %w(index edit new show _form).each do |view| + assert_file "app/views/test_app/admin/user/special/roles/#{view}.html.erb" + end assert_no_file "app/views/layouts/admin/user/special/roles.html.erb" # Helpers diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index 6974db5751..ab78800a4e 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -66,6 +66,12 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase assert_no_match(/APP_RAKEFILE/, File.read(File.join(destination_root, "Rakefile"))) end + def test_generating_adds_dummy_app_rake_tasks_without_unit_test_files + run_generator [destination_root, "-T", "--mountable", '--dummy-path', 'my_dummy_app'] + + assert_match(/APP_RAKEFILE/, File.read(File.join(destination_root, "Rakefile"))) + end + def test_ensure_that_plugin_options_are_not_passed_to_app_generator FileUtils.cd(Rails.root) assert_no_match(/It works from file!.*It works_from_file/, run_generator([destination_root, "-m", "lib/template.rb"])) diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 38454dfb8b..8cacca668f 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -63,12 +63,9 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_views_are_generated run_generator - %w( - index - edit - new - show - ).each { |view| assert_file "app/views/users/#{view}.html.erb" } + %w(index edit new show).each do |view| + assert_file "app/views/users/#{view}.html.erb" + end assert_no_file "app/views/layouts/users.html.erb" end diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index efe47cdfcb..54d5a9db6f 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -67,13 +67,9 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase end # Views - %w( - index - edit - new - show - _form - ).each { |view| assert_file "app/views/product_lines/#{view}.html.erb" } + %w(index edit new show _form).each do |view| + assert_file "app/views/product_lines/#{view}.html.erb" + end assert_no_file "app/views/layouts/product_lines.html.erb" # Helpers @@ -187,13 +183,9 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase /class Admin::RolesControllerTest < ActionController::TestCase/ # Views - %w( - index - edit - new - show - _form - ).each { |view| assert_file "app/views/admin/roles/#{view}.html.erb" } + %w(index edit new show _form).each do |view| + assert_file "app/views/admin/roles/#{view}.html.erb" + end assert_no_file "app/views/layouts/admin/roles.html.erb" # Helpers |