diff options
30 files changed, 121 insertions, 160 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 7da58ca4e7..6a50565de5 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -115,7 +115,7 @@ *Boris Kuznetsov* * Swapped the parameters of assert_equal in `assert_select` so that the - proper values were printed correctly + proper values were printed correctly. Fixes #14422. diff --git a/actionview/lib/action_view/helpers/asset_url_helper.rb b/actionview/lib/action_view/helpers/asset_url_helper.rb index d86e7e490c..006b15be91 100644 --- a/actionview/lib/action_view/helpers/asset_url_helper.rb +++ b/actionview/lib/action_view/helpers/asset_url_helper.rb @@ -88,9 +88,12 @@ module ActionView # still sending assets for plain HTTP requests from asset hosts. If you don't # have SSL certificates for each of the asset hosts this technique allows you # to avoid warnings in the client about mixed media. + # Note that the request parameter might not be supplied, e.g. when the assets + # are precompiled via a Rake task. Make sure to use a Proc instead of a lambda, + # since a Proc allows missing parameters and sets them to nil. # # config.action_controller.asset_host = Proc.new { |source, request| - # if request.ssl? + # if request && request.ssl? # "#{request.protocol}#{request.host_with_port}" # else # "#{request.protocol}assets.example.com" diff --git a/actionview/lib/action_view/helpers/debug_helper.rb b/actionview/lib/action_view/helpers/debug_helper.rb index c29c1b1eea..16cddec339 100644 --- a/actionview/lib/action_view/helpers/debug_helper.rb +++ b/actionview/lib/action_view/helpers/debug_helper.rb @@ -11,20 +11,16 @@ module ActionView # If the object cannot be converted to YAML using +to_yaml+, +inspect+ will be called instead. # Useful for inspecting an object at the time of rendering. # - # @user = User.new({ username: 'testing', password: 'xyz', age: 42}) %> + # @user = User.new({ username: 'testing', password: 'xyz', age: 42}) # debug(@user) # # => # <pre class='debug_dump'>--- !ruby/object:User # attributes: # updated_at: # username: testing - # # age: 42 # password: xyz # created_at: - # attributes_cache: {} - # - # new_record: true # </pre> def debug(object) Marshal::dump(object) diff --git a/activerecord/README.rdoc b/activerecord/README.rdoc index c813b22f3b..969e97913d 100644 --- a/activerecord/README.rdoc +++ b/activerecord/README.rdoc @@ -19,9 +19,9 @@ A short rundown of some of the major features: class Product < ActiveRecord::Base end - + {Learn more}[link:classes/ActiveRecord/Base.html] - + The Product class is automatically mapped to the table named "products", which might look like this: @@ -33,7 +33,7 @@ which might look like this: This would also define the following accessors: `Product#name` and `Product#name=(new_name)`. - + * Associations between objects defined by simple class methods. diff --git a/activerecord/lib/active_record/attribute_assignment.rb b/activerecord/lib/active_record/attribute_assignment.rb index 816fb51942..c4cf084a04 100644 --- a/activerecord/lib/active_record/attribute_assignment.rb +++ b/activerecord/lib/active_record/attribute_assignment.rb @@ -13,9 +13,9 @@ module ActiveRecord # exception is raised. # # cat = Cat.new(name: "Gorby", status: "yawning") - # cat.attributes # => { "name" => "Gorby", "status" => "yawning" } + # cat.attributes # => { "name" => "Gorby", "status" => "yawning", "created_at" => nil, "updated_at" => nil} # cat.assign_attributes(status: "sleeping") - # cat.attributes # => { "name" => "Gorby", "status" => "sleeping" } + # cat.attributes # => { "name" => "Gorby", "status" => "sleeping", "created_at" => nil, "updated_at" => nil } # # New attributes will be persisted in the database when the object is saved. # diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index fb6473b7c7..b6520b9b3d 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -287,11 +287,6 @@ module ActiveRecord } end - # Placeholder so it can be overriden when needed by serialization - def attributes_for_coder # :nodoc: - attributes - end - # Returns an <tt>#inspect</tt>-like string for the value of the # attribute +attr_name+. String attributes are truncated upto 50 # characters, Date and Time attributes are returned in the diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index 99b95b1fc4..ae3785638a 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -94,7 +94,7 @@ module ActiveRecord def cacheable_column?(column) if attribute_types_cached_by_default == ATTRIBUTE_TYPES_CACHED_BY_DEFAULT - ! serialized_attributes.include? column.name + true else attribute_types_cached_by_default.include?(column.type) end diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index b247bf8a45..425c33f2c6 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -76,21 +76,6 @@ module ActiveRecord module Behavior # :nodoc: extend ActiveSupport::Concern - module ClassMethods # :nodoc: - def initialize_attributes(attributes, options = {}) - serialized = (options.delete(:serialized) { true }) ? :serialized : :unserialized - super(attributes, options) - - serialized_attributes.each do |key, coder| - if attributes.key?(key) - attributes[key] = Type::Serialized::Attribute.new(coder, attributes[key], serialized) - end - end - - attributes - end - end - def should_record_timestamps? super || (self.record_timestamps && (attributes.keys & self.class.serialized_attributes.keys).present?) end @@ -106,42 +91,6 @@ module ActiveRecord super end end - - def read_attribute_before_type_cast(attr_name) - if self.class.serialized_attributes.include?(attr_name) - super.unserialized_value - else - super - end - end - - def attributes_before_type_cast - super.dup.tap do |attributes| - self.class.serialized_attributes.each_key do |key| - if attributes.key?(key) - attributes[key] = attributes[key].unserialized_value - end - end - end - end - - def typecasted_attribute_value(name) - if self.class.serialized_attributes.include?(name) - @raw_attributes[name].serialized_value - else - super - end - end - - def attributes_for_coder - attribute_names.each_with_object({}) do |name, attrs| - attrs[name] = if self.class.serialized_attributes.include?(name) - @raw_attributes[name].serialized_value - else - read_attribute(name) - end - end - end end end end diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb index 3b9b9c81e8..c3e601a208 100644 --- a/activerecord/lib/active_record/attribute_methods/write.rb +++ b/activerecord/lib/active_record/attribute_methods/write.rb @@ -53,11 +53,11 @@ module ActiveRecord # specified +value+. Empty strings for fixnum and float columns are # turned into +nil+. def write_attribute(attr_name, value) - write_attribute_with_type_cast(attr_name, value, :type_cast_for_write) + write_attribute_with_type_cast(attr_name, value, true) end def raw_write_attribute(attr_name, value) - write_attribute_with_type_cast(attr_name, value, :raw_type_cast_for_write) + write_attribute_with_type_cast(attr_name, value, false) end private @@ -66,7 +66,7 @@ module ActiveRecord write_attribute(attribute_name, value) end - def write_attribute_with_type_cast(attr_name, value, type_cast_method) + def write_attribute_with_type_cast(attr_name, value, should_type_cast) attr_name = attr_name.to_s attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key @attributes.delete(attr_name) @@ -78,9 +78,9 @@ module ActiveRecord @attributes[attr_name] = value end - if column - @raw_attributes[attr_name] = column.public_send(type_cast_method, value) - elsif @raw_attributes.has_key?(attr_name) + if column && should_type_cast + @raw_attributes[attr_name] = column.type_cast_for_write(value) + elsif !should_type_cast || @raw_attributes.has_key?(attr_name) @raw_attributes[attr_name] = value else raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{attr_name}'" diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb index 4fbc55a07e..60da541e3d 100644 --- a/activerecord/lib/active_record/connection_adapters/column.rb +++ b/activerecord/lib/active_record/connection_adapters/column.rb @@ -17,7 +17,7 @@ module ActiveRecord delegate :type, :precision, :scale, :limit, :klass, :accessor, :text?, :number?, :binary?, :serialized?, - :type_cast, :type_cast_for_write, :raw_type_cast_for_write, :type_cast_for_database, + :type_cast, :type_cast_for_write, :type_cast_for_database, :type_cast_for_schema, to: :cast_type @@ -52,7 +52,7 @@ module ActiveRecord end def extract_default(default) - type_cast(default) + type_cast_for_write(type_cast(default)) end end end diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index e99e235fe8..205cae9b2a 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -353,7 +353,7 @@ module ActiveRecord # Post.new.encode_with(coder) # coder # => {"attributes" => {"id" => nil, ... }} def encode_with(coder) - coder['attributes'] = attributes_for_coder + coder['attributes'] = @raw_attributes end # Returns true if +comparison_object+ is the same exact object, or +comparison_object+ diff --git a/activerecord/lib/active_record/properties.rb b/activerecord/lib/active_record/properties.rb index 21ff906fec..e70f84808d 100644 --- a/activerecord/lib/active_record/properties.rb +++ b/activerecord/lib/active_record/properties.rb @@ -75,7 +75,7 @@ module ActiveRecord # store_listing.price_in_cents # => 1000 def property(name, cast_type, options = {}) name = name.to_s - clear_properties_cache + clear_caches_calculated_from_columns # Assign a new hash to ensure that subclasses do not share a hash self.user_provided_columns = user_provided_columns.merge(name => connection.new_column(name, options[:default], cast_type)) end @@ -92,7 +92,7 @@ module ActiveRecord def reset_column_information # :nodoc: super - clear_properties_cache + clear_caches_calculated_from_columns end private @@ -108,9 +108,13 @@ module ActiveRecord existing_columns + new_columns end - def clear_properties_cache + def clear_caches_calculated_from_columns @columns = nil @columns_hash = nil + @column_types = nil + @column_defaults = nil + @column_names = nil + @content_columns = nil end end end diff --git a/activerecord/lib/active_record/type/serialized.rb b/activerecord/lib/active_record/type/serialized.rb index 4052ac0fa0..eac31f6cc3 100644 --- a/activerecord/lib/active_record/type/serialized.rb +++ b/activerecord/lib/active_record/type/serialized.rb @@ -10,20 +10,21 @@ module ActiveRecord end def type_cast(value) - if value.respond_to?(:unserialized_value) - value.unserialized_value(super(value.value)) + if is_default_value?(value) + value else - super + coder.load(super) end end def type_cast_for_write(value) - Attribute.new(coder, value, :unserialized) + return if value.nil? + unless is_default_value?(value) + coder.dump(value) + end end - def raw_type_cast_for_write(value) - Attribute.new(coder, value, :serialized) - end + alias type_cast_for_database type_cast_for_write def serialized? true @@ -33,24 +34,10 @@ module ActiveRecord ActiveRecord::Store::IndifferentHashAccessor end - class Attribute < Struct.new(:coder, :value, :state) # :nodoc: - def unserialized_value(v = value) - state == :serialized ? unserialize(v) : value - end - - def serialized_value - state == :unserialized ? serialize : value - end - - def unserialize(v) - self.state = :unserialized - self.value = coder.load(v) - end + private - def serialize - self.state = :serialized - self.value = coder.dump(value) - end + def is_default_value?(value) + value == coder.load(nil) end end end diff --git a/activerecord/lib/active_record/type/value.rb b/activerecord/lib/active_record/type/value.rb index 9c1e9dc01e..8cd99df2b4 100644 --- a/activerecord/lib/active_record/type/value.rb +++ b/activerecord/lib/active_record/type/value.rb @@ -54,7 +54,6 @@ module ActiveRecord def type_cast_for_write(value) # :nodoc: value end - alias_method :raw_type_cast_for_write, :type_cast_for_write # :internal: private diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index b6fccc9b94..2e7b1d7206 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -14,7 +14,6 @@ module ActiveRecord finder_class = find_finder_class_for(record) table = finder_class.arel_table value = map_enum_attribute(finder_class, attribute, value) - value = deserialize_attribute(record, attribute, value) relation = build_relation(finder_class, table, attribute, value) relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted? @@ -86,12 +85,6 @@ module ActiveRecord relation end - def deserialize_attribute(record, attribute, value) - coder = record.class.serialized_attributes[attribute.to_s] - value = coder.dump value if value && coder - value - end - def map_enum_attribute(klass, attribute, value) mapping = klass.defined_enums[attribute.to_s] value = mapping[value] if value && mapping diff --git a/activerecord/test/cases/adapters/postgresql/composite_test.rb b/activerecord/test/cases/adapters/postgresql/composite_test.rb index ecccbf10e6..d804d1fa97 100644 --- a/activerecord/test/cases/adapters/postgresql/composite_test.rb +++ b/activerecord/test/cases/adapters/postgresql/composite_test.rb @@ -93,6 +93,7 @@ class PostgresqlCompositeWithCustomOIDTest < ActiveRecord::TestCase end def type_cast_for_write(value) + return if value.nil? "(#{value.city},#{value.street})" end end diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index da2876170e..139fe9c04b 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -870,7 +870,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end def cached_columns - Topic.columns.map(&:name) - Topic.serialized_attributes.keys + Topic.columns.map(&:name) end def time_related_columns_on_topic diff --git a/activerecord/test/cases/custom_properties_test.rb b/activerecord/test/cases/custom_properties_test.rb index a406704114..9ba1e83df6 100644 --- a/activerecord/test/cases/custom_properties_test.rb +++ b/activerecord/test/cases/custom_properties_test.rb @@ -87,5 +87,25 @@ module ActiveRecord column_names = OverloadedType.column_names assert_equal %w(id overloaded_float unoverloaded_float overloaded_string_with_limit string_with_default non_existent_decimal), column_names end + + def test_caches_are_cleared + klass = Class.new(OverloadedType) + + assert_equal 6, klass.columns.length + assert_not klass.columns_hash.key?('wibble') + assert_equal 6, klass.column_types.length + assert_equal 6, klass.column_defaults.length + assert_not klass.column_names.include?('wibble') + assert_equal 5, klass.content_columns.length + + klass.property :wibble, Type::Value.new + + assert_equal 7, klass.columns.length + assert klass.columns_hash.key?('wibble') + assert_equal 7, klass.column_types.length + assert_equal 7, klass.column_defaults.length + assert klass.column_names.include?('wibble') + assert_equal 6, klass.content_columns.length + end end end diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb index eaa28148f4..5ea62c9f59 100644 --- a/activerecord/test/cases/serialized_attribute_test.rb +++ b/activerecord/test/cases/serialized_attribute_test.rb @@ -59,8 +59,9 @@ class SerializedAttributeTest < ActiveRecord::TestCase def test_serialized_attribute_calling_dup_method Topic.serialize :content, JSON - t = Topic.new(:content => { :foo => :bar }).dup - assert_equal({ :foo => :bar }, t.content_before_type_cast) + orig = Topic.new(content: { foo: :bar }) + clone = orig.dup + assert_equal(orig.content, clone.content) end def test_serialized_attribute_declared_in_subclass @@ -103,8 +104,10 @@ class SerializedAttributeTest < ActiveRecord::TestCase def test_serialized_attribute_should_raise_exception_on_save_with_wrong_type Topic.serialize(:content, Hash) - topic = Topic.new(:content => "string") - assert_raise(ActiveRecord::SerializationTypeMismatch) { topic.save } + assert_raise(ActiveRecord::SerializationTypeMismatch) do + topic = Topic.new(content: 'string') + topic.save + end end def test_should_raise_exception_on_serialized_attribute_with_type_mismatch diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb index 6a34c55011..f841b1c983 100644 --- a/activerecord/test/cases/store_test.rb +++ b/activerecord/test/cases/store_test.rb @@ -183,20 +183,6 @@ class StoreTest < ActiveRecord::TestCase assert_equal({}, @john.params) end - test "attributes_for_coder should return stored fields already serialized" do - attributes = { - "id" => @john.id, - "name"=> @john.name, - "settings" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ncolor: black\n", - "preferences" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\nremember_login: true\n", - "json_data" => "{\"height\":\"tall\"}", "json_data_empty"=>"{\"is_a_good_guy\":true}", - "params" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess {}\n", - "account_id"=> @john.account_id - } - - assert_equal attributes, @john.attributes_for_coder - end - test "dump, load and dump again a model" do dumped = YAML.dump(@john) loaded = YAML.load(dumped) diff --git a/activerecord/test/cases/yaml_serialization_test.rb b/activerecord/test/cases/yaml_serialization_test.rb index 15815d56e4..f7af9a35cd 100644 --- a/activerecord/test/cases/yaml_serialization_test.rb +++ b/activerecord/test/cases/yaml_serialization_test.rb @@ -23,13 +23,6 @@ class YamlSerializationTest < ActiveRecord::TestCase assert_equal({:omg=>:lol}, YAML.load(YAML.dump(topic)).content) end - def test_encode_with_coder - topic = Topic.first - coder = {} - topic.encode_with coder - assert_equal({'attributes' => topic.attributes}, coder) - end - def test_psych_roundtrip topic = Topic.first assert topic @@ -47,4 +40,16 @@ class YamlSerializationTest < ActiveRecord::TestCase def test_active_record_relation_serialization [Topic.all].to_yaml end + + def test_raw_types_are_not_changed_on_round_trip + topic = Topic.new(parent_id: "123") + assert_equal "123", topic.parent_id_before_type_cast + assert_equal "123", YAML.load(YAML.dump(topic)).parent_id_before_type_cast + end + + def test_cast_types_are_not_changed_on_round_trip + topic = Topic.new(parent_id: "123") + assert_equal 123, topic.parent_id + assert_equal 123, YAML.load(YAML.dump(topic)).parent_id + end end diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 68bfc8062b..38ec3c0753 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -2,10 +2,10 @@ Replacements: - 5.ago => 5.seconds.ago - 5.until => 5.seconds.until - 5.since => 5.seconds.since - 5.from_now => 5.seconds.from_now + 5.ago => 5.seconds.ago + 5.until => 5.seconds.until + 5.since => 5.seconds.since + 5.from_now => 5.seconds.from_now See #12389 for the history and rationale behind this. diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb index 28536e32a4..5934c578ea 100644 --- a/activesupport/lib/active_support/core_ext/hash/keys.rb +++ b/activesupport/lib/active_support/core_ext/hash/keys.rb @@ -27,7 +27,7 @@ class Hash # hash = { name: 'Rob', age: '28' } # # hash.stringify_keys - # # => { "name" => "Rob", "age" => "28" } + # # => {"name"=>"Rob", "age"=>"28"} def stringify_keys transform_keys{ |key| key.to_s } end @@ -44,7 +44,7 @@ class Hash # hash = { 'name' => 'Rob', 'age' => '28' } # # hash.symbolize_keys - # # => { name: "Rob", age: "28" } + # # => {:name=>"Rob", :age=>"28"} def symbolize_keys transform_keys{ |key| key.to_sym rescue key } end diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb index ed41b28d54..e782cfa2f5 100644 --- a/activesupport/lib/active_support/hash_with_indifferent_access.rb +++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb @@ -182,8 +182,8 @@ module ActiveSupport # dup = hash.dup # dup[:a][:c] = 'c' # - # hash[:a][:c] #=> "c" - # dup[:a][:c] #=> "c" + # hash[:a][:c] # => nil + # dup[:a][:c] # => "c" def dup self.class.new(self).tap do |new_hash| new_hash.default = default diff --git a/guides/source/3_2_release_notes.md b/guides/source/3_2_release_notes.md index cdcde67869..2416e1a228 100644 --- a/guides/source/3_2_release_notes.md +++ b/guides/source/3_2_release_notes.md @@ -562,4 +562,4 @@ Credits See the [full list of contributors to Rails](http://contributors.rubyonrails.org/) for the many people who spent many hours making Rails, the stable and robust framework it is. Kudos to all of them. -Rails 3.2 Release Notes were compiled by [Vijay Dev](https://github.com/vijaydev.) +Rails 3.2 Release Notes were compiled by [Vijay Dev](https://github.com/vijaydev). diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index ee8cf4ade6..673dcfc1d3 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -659,6 +659,23 @@ FROM orders GROUP BY date(created_at) ``` +### Total of grouped items + +To get the total of grouped items on a single query call `count` after the `group`. + +```ruby +Order.group(:status).count +# => { 'awaiting_approval' => 7, 'paid' => 12 } +``` + +The SQL that would be executed would be something like this: + +```sql +SELECT COUNT (*) AS count_all, status AS status +FROM "orders" +GROUP BY status +``` + Having ------ diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md index 984480c70f..559d3f5e7d 100644 --- a/guides/source/asset_pipeline.md +++ b/guides/source/asset_pipeline.md @@ -580,7 +580,7 @@ config.assets.raise_runtime_errors = false When this option is true, the asset pipeline will check if all the assets loaded in your application are included in the `config.assets.precompile` list. -If `config.assets.digests` is also true, the asset pipeline will require that +If `config.assets.digest` is also true, the asset pipeline will require that all requests for assets include digests. ### Turning Digests Off @@ -589,7 +589,7 @@ You can turn off digests by updating `config/environments/development.rb` to include: ```ruby -config.assets.digests = false +config.assets.digest = false ``` When this option is true, digests will be generated for asset URLs. diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml index e365435b50..5138412312 100644 --- a/guides/source/documents.yaml +++ b/guides/source/documents.yaml @@ -96,11 +96,6 @@ url: command_line.html description: This guide covers the command line tools and rake tasks provided by Rails. - - name: Caching with Rails - work_in_progress: true - url: caching_with_rails.html - description: Various caching techniques provided by Rails. - - name: Asset Pipeline url: asset_pipeline.html description: This guide documents the asset pipeline. diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index 04ce38f841..2a0148fe9d 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -161,6 +161,11 @@ module Rails end end + # Returns an array of generator namespaces that are hidden. + # Generator namespaces may be hidden for a variety of reasons. + # Some are aliased such as "rails:migration" and can be + # invoked with the shorter "migration", others are private to other generators + # such as "css:scaffold". def self.hidden_namespaces @hidden_namespaces ||= begin orm = options[:rails][:orm] diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb index 8e198d5fe1..b998fef42e 100644 --- a/railties/test/generators/shared_generator_tests.rb +++ b/railties/test/generators/shared_generator_tests.rb @@ -78,9 +78,12 @@ module SharedGeneratorTests end def test_template_raises_an_error_with_invalid_path - content = capture(:stderr){ run_generator([destination_root, "-m", "non/existent/path"]) } - assert_match(/The template \[.*\] could not be loaded/, content) - assert_match(/non\/existent\/path/, content) + quietly do + content = capture(:stderr){ run_generator([destination_root, "-m", "non/existent/path"]) } + + assert_match(/The template \[.*\] could not be loaded/, content) + assert_match(/non\/existent\/path/, content) + end end def test_template_is_executed_when_supplied @@ -89,7 +92,7 @@ module SharedGeneratorTests template.instance_eval "def read; self; end" # Make the string respond to read generator([destination_root], template: path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template) - assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) + quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) } end def test_template_is_executed_when_supplied_an_https_path @@ -98,7 +101,7 @@ module SharedGeneratorTests template.instance_eval "def read; self; end" # Make the string respond to read generator([destination_root], template: path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template) - assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) + quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) } end def test_dev_option |