diff options
50 files changed, 418 insertions, 418 deletions
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 9a427ebfdb..bfbc15a901 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -182,7 +182,8 @@ module ActionController body = [body] unless body.nil? || body.respond_to?(:each) super end - + + # Tests if render or redirect has already happened. def performed? response_body || (response && response.committed?) end diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb index a2cb6d1e66..d920668184 100644 --- a/actionpack/lib/action_controller/metal/force_ssl.rb +++ b/actionpack/lib/action_controller/metal/force_ssl.rb @@ -85,7 +85,7 @@ module ActionController if host_or_options.is_a?(Hash) options.merge!(host_or_options) elsif host_or_options - options.merge!(:host => host_or_options) + options[:host] = host_or_options end secure_url = ActionDispatch::Http::URL.url_for(options.slice(*URL_OPTIONS)) diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 473f692b05..6b8dcaf497 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -49,31 +49,26 @@ module ActionDispatch end def path_for(options) - result = options[:script_name].to_s.chomp("/") - result << options[:path].to_s + path = options[:script_name].to_s.chomp("/") + path << options[:path] if options.key?(:path) - result = add_trailing_slash(result) if options[:trailing_slash] + add_trailing_slash(path) if options[:trailing_slash] + add_params(path, options[:params]) if options.key?(:params) + add_anchor(path, options[:anchor]) if options.key?(:anchor) - result = add_params options, result - add_anchor options, result + path end private - def add_params(options, result) - if options.key? :params - param = options[:params] - params = param.is_a?(Hash) ? param : { params: param } - - params.reject! { |_,v| v.to_param.nil? } - result << "?#{params.to_query}" unless params.empty? - end - result + def add_params(path, params) + params = { params: params } unless params.is_a?(Hash) + params.reject! { |_,v| v.to_param.nil? } + path << "?#{params.to_query}" unless params.empty? end - def add_anchor(options, result) - result << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor] - result + def add_anchor(path, anchor) + path << "##{Journey::Router::Utils.escape_fragment(anchor.to_param.to_s)}" end def extract_domain_from(host, tld_length) @@ -93,19 +88,17 @@ module ActionDispatch elsif !path.include?(".") path.sub!(/[^\/]\z|\A\z/, '\&/') end - - path end def build_host_url(host, port, protocol, options, path) if match = host.match(HOST_REGEXP) - protocol ||= match[1] unless protocol == false - host = match[2] - port = match[3] unless options.key? :port + protocol ||= match[1] unless protocol == false + host = match[2] + port = match[3] unless options.key? :port end - protocol = normalize_protocol protocol - host = normalize_host(host, options) + protocol = normalize_protocol protocol + host = normalize_host(host, options) result = protocol.dup diff --git a/actionpack/lib/action_dispatch/journey/parser.rb b/actionpack/lib/action_dispatch/journey/parser.rb index d129ba7e16..9012297400 100644 --- a/actionpack/lib/action_dispatch/journey/parser.rb +++ b/actionpack/lib/action_dispatch/journey/parser.rb @@ -86,7 +86,7 @@ racc_token_table = { racc_nt_base = 10 -racc_use_result_var = true +racc_use_result_var = false Racc_arg = [ racc_action_table, @@ -133,14 +133,12 @@ Racc_debug_parser = false # reduce 0 omitted -def _reduce_1(val, _values, result) - result = Cat.new(val.first, val.last) - result +def _reduce_1(val, _values) + Cat.new(val.first, val.last) end -def _reduce_2(val, _values, result) - result = val.first - result +def _reduce_2(val, _values) + val.first end # reduce 3 omitted @@ -151,24 +149,20 @@ end # reduce 6 omitted -def _reduce_7(val, _values, result) - result = Group.new(val[1]) - result +def _reduce_7(val, _values) + Group.new(val[1]) end -def _reduce_8(val, _values, result) - result = Or.new([val.first, val.last]) - result +def _reduce_8(val, _values) + Or.new([val.first, val.last]) end -def _reduce_9(val, _values, result) - result = Or.new([val.first, val.last]) - result +def _reduce_9(val, _values) + Or.new([val.first, val.last]) end -def _reduce_10(val, _values, result) - result = Star.new(Symbol.new(val.last)) - result +def _reduce_10(val, _values) + Star.new(Symbol.new(val.last)) end # reduce 11 omitted @@ -179,27 +173,23 @@ end # reduce 14 omitted -def _reduce_15(val, _values, result) - result = Slash.new('/') - result +def _reduce_15(val, _values) + Slash.new('/') end -def _reduce_16(val, _values, result) - result = Symbol.new(val.first) - result +def _reduce_16(val, _values) + Symbol.new(val.first) end -def _reduce_17(val, _values, result) - result = Literal.new(val.first) - result +def _reduce_17(val, _values) + Literal.new(val.first) end -def _reduce_18(val, _values, result) - result = Dot.new(val.first) - result +def _reduce_18(val, _values) + Dot.new(val.first) end -def _reduce_none(val, _values, result) +def _reduce_none(val, _values) val[0] end diff --git a/actionpack/lib/action_dispatch/journey/parser.y b/actionpack/lib/action_dispatch/journey/parser.y index 0ead222551..d3f7c4d765 100644 --- a/actionpack/lib/action_dispatch/journey/parser.y +++ b/actionpack/lib/action_dispatch/journey/parser.y @@ -1,11 +1,11 @@ class ActionDispatch::Journey::Parser - + options no_result_var token SLASH LITERAL SYMBOL LPAREN RPAREN DOT STAR OR rule expressions - : expression expressions { result = Cat.new(val.first, val.last) } - | expression { result = val.first } + : expression expressions { Cat.new(val.first, val.last) } + | expression { val.first } | or ; expression @@ -14,14 +14,14 @@ rule | star ; group - : LPAREN expressions RPAREN { result = Group.new(val[1]) } + : LPAREN expressions RPAREN { Group.new(val[1]) } ; or - : expression OR expression { result = Or.new([val.first, val.last]) } - | expression OR or { result = Or.new([val.first, val.last]) } + : expression OR expression { Or.new([val.first, val.last]) } + | expression OR or { Or.new([val.first, val.last]) } ; star - : STAR { result = Star.new(Symbol.new(val.last)) } + : STAR { Star.new(Symbol.new(val.last)) } ; terminal : symbol @@ -30,16 +30,16 @@ rule | dot ; slash - : SLASH { result = Slash.new('/') } + : SLASH { Slash.new('/') } ; symbol - : SYMBOL { result = Symbol.new(val.first) } + : SYMBOL { Symbol.new(val.first) } ; literal - : LITERAL { result = Literal.new(val.first) } + : LITERAL { Literal.new(val.first) } ; dot - : DOT { result = Dot.new(val.first) } + : DOT { Dot.new(val.first) } ; end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 6f7e6f3128..cd94f35e8f 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -614,17 +614,19 @@ module ActionDispatch end def define_generate_prefix(app, name) - _route = @set.named_routes.routes[name.to_sym] + _route = @set.named_routes.get name _routes = @set app.routes.define_mounted_helper(name) app.routes.extend Module.new { def optimize_routes_generation?; false; end define_method :find_script_name do |options| - super(options) || begin - prefix_options = options.slice(*_route.segment_keys) - # we must actually delete prefix segment keys to avoid passing them to next url_for - _route.segment_keys.each { |k| options.delete(k) } - _routes.url_helpers.send("#{name}_path", prefix_options) + if options.key? :script_name + super(options) + else + prefix_options = options.slice(*_route.segment_keys) + # we must actually delete prefix segment keys to avoid passing them to next url_for + _route.segment_keys.each { |k| options.delete(k) } + _routes.url_helpers.send("#{name}_path", prefix_options) end end } @@ -1765,7 +1767,7 @@ module ActionDispatch # and return nil in case it isn't. Otherwise, we pass the invalid name # forward so the underlying router engine treats it and raises an exception. if as.nil? - candidate unless @set.routes.find { |r| r.name == candidate } || candidate !~ /\A[_a-z]/i + candidate unless candidate !~ /\A[_a-z]/i || @set.named_routes.key?(candidate) else candidate end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 96e23c2464..ce1fe2e451 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -140,6 +140,10 @@ module ActionDispatch routes[name.to_sym] end + def key?(name) + routes.key? name.to_sym + end + alias []= add alias [] get alias clear clear! @@ -690,7 +694,7 @@ module ActionDispatch end def find_script_name(options) - options.delete :script_name + options.delete(:script_name) { '' } end # The +options+ argument must be a hash whose keys are *symbols*. @@ -709,7 +713,7 @@ module ActionDispatch original_script_name = options.delete(:original_script_name) script_name = find_script_name options - if script_name && original_script_name + if original_script_name script_name = original_script_name + script_name end diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 252532c768..9043542fda 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,7 +1,15 @@ -* Fix Type casting to Decimal from Float with large precision. +* Fix type casting to Decimal from Float with large precision. *Tomohiro Hashidate* +* Deprecate `Reflection#source_macro` + + `Reflection#source_macro` is no longer needed in Active Record + source so it has been deprecated. Code that used `source_macro` + was removed in #16353. + + *Eileen M. Uchtitelle*, *Aaron Patterson* + * No verbose backtrace by db:drop when database does not exist. Fixes #16295. diff --git a/activerecord/lib/active_record/associations/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/join_dependency/join_association.rb index 719eff9acc..c3bbdccad8 100644 --- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb @@ -37,14 +37,9 @@ module ActiveRecord table = tables.shift klass = reflection.klass - case reflection.source_macro - when :belongs_to - key = reflection.association_primary_key - foreign_key = reflection.foreign_key - else - key = reflection.foreign_key - foreign_key = reflection.active_record_primary_key - end + join_keys = reflection.join_keys(klass) + key = join_keys.key + foreign_key = join_keys.foreign_key constraint = build_constraint(klass, table, key, foreign_table, foreign_key) @@ -95,7 +90,7 @@ module ActiveRecord # end # # If I execute `Physician.joins(:appointments).to_a` then - # reflection # => #<ActiveRecord::Reflection::HasManyReflection ...> + # klass # => Physician # table # => #<Arel::Table @name="appointments" ...> # key # => physician_id # foreign_table # => #<Arel::Table @name="physicians" ...> diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb index f00fef8b9e..24cb5ab545 100644 --- a/activerecord/lib/active_record/associations/through_association.rb +++ b/activerecord/lib/active_record/associations/through_association.rb @@ -77,7 +77,7 @@ module ActiveRecord end def ensure_mutable - if source_reflection.macro != :belongs_to + unless source_reflection.belongs_to? raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection) end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index cb75070e3a..a5fa9d6adc 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -462,23 +462,44 @@ module ActiveRecord # # For example, suppose that you have 5 models, with the following hierarchy: # - # | - # +-- Book - # | | - # | +-- ScaryBook - # | +-- GoodBook - # +-- Author - # +-- BankAccount + # class Author < ActiveRecord::Base + # end # - # Suppose that Book is to connect to a separate database (i.e. one other - # than the default database). Then Book, ScaryBook and GoodBook will all use - # the same connection pool. Likewise, Author and BankAccount will use the - # same connection pool. However, the connection pool used by Author/BankAccount - # is not the same as the one used by Book/ScaryBook/GoodBook. + # class BankAccount < ActiveRecord::Base + # end # - # Normally there is only a single ConnectionHandler instance, accessible via - # ActiveRecord::Base.connection_handler. Active Record models use this to - # determine the connection pool that they should use. + # class Book < ActiveRecord::Base + # establish_connection "library_db" + # end + # + # class ScaryBook < Book + # end + # + # class GoodBook < Book + # end + # + # And a database.yml that looked like this: + # + # development: + # database: my_application + # host: localhost + # + # library_db: + # database: library + # host: some.library.org + # + # Your primary database in the development environment is "my_application" + # but the Book model connects to a separate database called "library_db" + # (this can even be a database on a different machine). + # + # Book, ScaryBook and GoodBook will all use the same connection pool to + # "library_db" while Author, BankAccount, and any other models you create + # will use the default connection pool to "my_application". + # + # The various connection pools are managed by a single instance of + # ConnectionHandler accessible via ActiveRecord::Base.connection_handler. + # All Active Record models use this handler to determine the connection pool that they + # should use. class ConnectionHandler def initialize # These caches are keyed by klass.name, NOT klass. Keying them by klass diff --git a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb index 33cc22425d..46aaaae2ec 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb @@ -1,76 +1,5 @@ module ActiveRecord module ConnectionAdapters - class TransactionManager #:nodoc: - def initialize(connection) - @stack = [] - @connection = connection - end - - def begin_transaction(options = {}) - transaction_class = @stack.empty? ? RealTransaction : SavepointTransaction - transaction = transaction_class.new(@connection, current_transaction, options) - - @stack.push(transaction) - transaction - end - - def commit_transaction - @stack.pop.commit - end - - def rollback_transaction - @stack.pop.rollback - end - - def within_new_transaction(options = {}) - transaction = begin_transaction options - yield - rescue Exception => error - transaction.rollback if transaction - raise - ensure - begin - transaction.commit unless error - rescue Exception - transaction.rollback - raise - ensure - @stack.pop if transaction - end - end - - def open_transactions - @stack.size - end - - def current_transaction - @stack.last || closed_transaction - end - - private - - def closed_transaction - @closed_transaction ||= ClosedTransaction.new(@connection) - end - end - - class Transaction #:nodoc: - attr_reader :connection - - def initialize(connection) - @connection = connection - @state = TransactionState.new - end - - def state - @state - end - - def savepoint_name - nil - end - end - class TransactionState attr_reader :parent @@ -101,65 +30,49 @@ module ActiveRecord end end - class ClosedTransaction < Transaction #:nodoc: - def number - 0 - end - - def begin(options = {}) - RealTransaction.new(connection, self, options) - end - - def closed? - true - end + class Transaction #:nodoc: + attr_reader :connection, :state - def open? - false + def initialize(connection) + @connection = connection + @state = TransactionState.new end - def joinable? - false + def savepoint_name + nil end + end + class NullTransaction < Transaction #:nodoc: + def initialize; end + def closed?; true; end + def open?; false; end + def joinable?; false; end # This is a noop when there are no open transactions - def add_record(record) - end + def add_record(record); end end class OpenTransaction < Transaction #:nodoc: - attr_reader :parent, :records + attr_reader :records attr_writer :joinable - def initialize(connection, parent, options = {}) + def initialize(connection, options = {}) super connection - @parent = parent @records = [] @joinable = options.fetch(:joinable, true) end - def joinable? @joinable end - def number - parent.number + 1 - end - - def begin(options = {}) - SavepointTransaction.new(connection, self, options) - end - def rollback perform_rollback - parent end def commit perform_commit - parent end def add_record(record) @@ -174,7 +87,7 @@ module ActiveRecord @state.set_state(:rolledback) records.uniq.each do |record| begin - record.rolledback!(parent.closed?) + record.rolledback!(self.is_a?(RealTransaction)) rescue => e record.logger.error(e) if record.respond_to?(:logger) && record.logger end @@ -202,8 +115,8 @@ module ActiveRecord end class RealTransaction < OpenTransaction #:nodoc: - def initialize(connection, parent, options = {}) - super + def initialize(connection, _, options = {}) + super(connection, options) if options[:isolation] connection.begin_isolated_db_transaction(options[:isolation]) @@ -226,27 +139,75 @@ module ActiveRecord class SavepointTransaction < OpenTransaction #:nodoc: attr_reader :savepoint_name - def initialize(connection, parent, options = {}) + def initialize(connection, savepoint_name, options = {}) if options[:isolation] raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction" end - super - - # Savepoint name only counts the Savepoint transactions, so we need to subtract 1 - @savepoint_name = "active_record_#{number - 1}" - connection.create_savepoint(@savepoint_name) + super(connection, options) + connection.create_savepoint(@savepoint_name = savepoint_name) end def perform_rollback - connection.rollback_to_savepoint(@savepoint_name) + connection.rollback_to_savepoint(savepoint_name) rollback_records end def perform_commit @state.set_state(:committed) - connection.release_savepoint(@savepoint_name) + connection.release_savepoint(savepoint_name) + end + end + + class TransactionManager #:nodoc: + def initialize(connection) + @stack = [] + @connection = connection + end + + def begin_transaction(options = {}) + transaction_class = @stack.empty? ? RealTransaction : SavepointTransaction + transaction = transaction_class.new(@connection, "active_record_#{@stack.size}", options) + + @stack.push(transaction) + transaction end + + def commit_transaction + @stack.pop.commit + end + + def rollback_transaction + @stack.pop.rollback + end + + def within_new_transaction(options = {}) + transaction = begin_transaction options + yield + rescue Exception => error + transaction.rollback if transaction + raise + ensure + begin + transaction.commit unless error + rescue Exception + transaction.rollback + raise + ensure + @stack.pop if transaction + end + end + + def open_transactions + @stack.size + end + + def current_transaction + @stack.last || NULL_TRANSACTION + end + + private + NULL_TRANSACTION = NullTransaction.new end end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 99c728814a..a1b6671664 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -46,7 +46,7 @@ module ActiveRecord autoload_at 'active_record/connection_adapters/abstract/transaction' do autoload :TransactionManager - autoload :ClosedTransaction + autoload :NullTransaction autoload :RealTransaction autoload :SavepointTransaction autoload :TransactionState diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index fa94df7a52..ac385817e4 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -41,10 +41,7 @@ db_namespace = namespace :db do desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)." task :migrate => [:environment, :load_config] do - ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true - ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) do |migration| - ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope) - end + ActiveRecord::Tasks::DatabaseTasks.migrate db_namespace['_dump'].invoke if ActiveRecord::Base.dump_schema_after_migration end diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 21da011e8a..1547c8e3f4 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -38,7 +38,7 @@ module ActiveRecord ar.aggregate_reflections = ar.aggregate_reflections.merge(name.to_s => reflection) end - # \Reflection enables to interrogate Active Record classes and objects + # \Reflection enables interrogating Active Record classes and objects # about their associations and aggregations. This information can, # for example, be used in a form builder that takes an Active Record object # and creates input fields for all of the attributes depending on their type @@ -149,18 +149,13 @@ module ActiveRecord JoinKeys = Struct.new(:key, :foreign_key) # :nodoc: def join_keys(assoc_klass) - if source_macro == :belongs_to - if polymorphic? - reflection_key = association_primary_key(assoc_klass) - else - reflection_key = association_primary_key - end - reflection_foreign_key = foreign_key - else - reflection_foreign_key = active_record_primary_key - reflection_key = foreign_key - end - JoinKeys.new(reflection_key, reflection_foreign_key) + JoinKeys.new(foreign_key, active_record_primary_key) + end + + def source_macro + ActiveSupport::Deprecation.warn("ActiveRecord::Base.source_macro is deprecated and " \ + "will be removed without replacement.") + macro end end # Base class for AggregateReflection and AssociationReflection. Objects of @@ -354,9 +349,8 @@ Joining, Preloading and eager loading of these associations is deprecated and wi end alias :check_eager_loadable! :check_preloadable! - def join_id_for(owner) #:nodoc: - key = (source_macro == :belongs_to) ? foreign_key : active_record_primary_key - owner[key] + def join_id_for(owner) # :nodoc: + owner[active_record_primary_key] end def through_reflection @@ -383,8 +377,6 @@ Joining, Preloading and eager loading of these associations is deprecated and wi scope ? [[scope]] : [[]] end - def source_macro; macro; end - def has_inverse? inverse_name end @@ -574,7 +566,7 @@ Joining, Preloading and eager loading of these associations is deprecated and wi end end - class HasManyReflection < AssociationReflection #:nodoc: + class HasManyReflection < AssociationReflection # :nodoc: def initialize(name, scope, options, active_record) super(name, scope, options, active_record) end @@ -584,7 +576,7 @@ Joining, Preloading and eager loading of these associations is deprecated and wi def collection?; true; end end - class HasOneReflection < AssociationReflection #:nodoc: + class HasOneReflection < AssociationReflection # :nodoc: def initialize(name, scope, options, active_record) super(name, scope, options, active_record) end @@ -594,7 +586,7 @@ Joining, Preloading and eager loading of these associations is deprecated and wi def has_one?; true; end end - class BelongsToReflection < AssociationReflection #:nodoc: + class BelongsToReflection < AssociationReflection # :nodoc: def initialize(name, scope, options, active_record) super(name, scope, options, active_record) end @@ -602,9 +594,18 @@ Joining, Preloading and eager loading of these associations is deprecated and wi def macro; :belongs_to; end def belongs_to?; true; end + + def join_keys(assoc_klass) + key = polymorphic? ? association_primary_key(assoc_klass) : association_primary_key + JoinKeys.new(key, foreign_key) + end + + def join_id_for(owner) # :nodoc: + owner[foreign_key] + end end - class HasAndBelongsToManyReflection < AssociationReflection #:nodoc: + class HasAndBelongsToManyReflection < AssociationReflection # :nodoc: def initialize(name, scope, options, active_record) super end @@ -735,8 +736,14 @@ Joining, Preloading and eager loading of these associations is deprecated and wi end end + def join_keys(assoc_klass) + source_reflection.join_keys(assoc_klass) + end + # The macro used by the source association def source_macro + ActiveSupport::Deprecation.warn("ActiveRecord::Base.source_macro is deprecated and " \ + "will be removed without replacement.") source_reflection.source_macro end @@ -802,6 +809,10 @@ directive on your declaration like: through_reflection.options end + def join_id_for(owner) # :nodoc: + source_reflection.join_id_for(owner) + end + def check_validity! if through_reflection.nil? raise HasManyThroughAssociationNotFoundError.new(active_record.name, self) diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index b7315ed4b3..72e0cf3723 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -127,6 +127,16 @@ module ActiveRecord } end + def migrate + verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true + version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil + scope = ENV['SCOPE'] + Migration.verbose = verbose + Migrator.migrate(Migrator.migrations_paths, version) do |migration| + scope.blank? || scope == migration.scope + end + end + def charset_current(environment = env) charset ActiveRecord::Base.configurations[environment] end diff --git a/activerecord/lib/active_record/type/serialized.rb b/activerecord/lib/active_record/type/serialized.rb index 42bbed7103..abeea769c4 100644 --- a/activerecord/lib/active_record/type/serialized.rb +++ b/activerecord/lib/active_record/type/serialized.rb @@ -12,7 +12,7 @@ module ActiveRecord end def type_cast_from_database(value) - if is_default_value?(value) + if default_value?(value) value else coder.load(super) @@ -21,7 +21,7 @@ module ActiveRecord def type_cast_for_database(value) return if value.nil? - unless is_default_value?(value) + unless default_value?(value) super coder.dump(value) end end @@ -43,7 +43,7 @@ module ActiveRecord private - def is_default_value?(value) + def default_value?(value) value == coder.load(nil) end end diff --git a/activerecord/test/cases/attribute_test.rb b/activerecord/test/cases/attribute_test.rb index 24452fdec2..91f6aee931 100644 --- a/activerecord/test/cases/attribute_test.rb +++ b/activerecord/test/cases/attribute_test.rb @@ -4,7 +4,7 @@ require 'minitest/mock' module ActiveRecord class AttributeTest < ActiveRecord::TestCase setup do - @type = MiniTest::Mock.new + @type = Minitest::Mock.new end teardown do diff --git a/activerecord/test/cases/migration/pending_migrations_test.rb b/activerecord/test/cases/migration/pending_migrations_test.rb index 517ee695ce..7afac83bd2 100644 --- a/activerecord/test/cases/migration/pending_migrations_test.rb +++ b/activerecord/test/cases/migration/pending_migrations_test.rb @@ -6,8 +6,8 @@ module ActiveRecord class PendingMigrationsTest < ActiveRecord::TestCase def setup super - @connection = MiniTest::Mock.new - @app = MiniTest::Mock.new + @connection = Minitest::Mock.new + @app = Minitest::Mock.new conn = @connection @pending = Class.new(CheckPending) { define_method(:connection) { conn } diff --git a/activerecord/test/cases/tasks/database_tasks_test.rb b/activerecord/test/cases/tasks/database_tasks_test.rb index 0f48c8d5fc..01d373b691 100644 --- a/activerecord/test/cases/tasks/database_tasks_test.rb +++ b/activerecord/test/cases/tasks/database_tasks_test.rb @@ -273,6 +273,19 @@ module ActiveRecord end end + class DatabaseTasksMigrateTest < ActiveRecord::TestCase + def test_migrate_receives_correct_env_vars + verbose, version = ENV['VERBOSE'], ENV['VERSION'] + + ENV['VERBOSE'] = 'false' + ENV['VERSION'] = '4' + + ActiveRecord::Migrator.expects(:migrate).with(ActiveRecord::Migrator.migrations_paths, 4) + ActiveRecord::Tasks::DatabaseTasks.migrate + ensure + ENV['VERBOSE'], ENV['VERSION'] = verbose, version + end + end class DatabaseTasksPurgeTest < ActiveRecord::TestCase include DatabaseTasksSetupper diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index f28a7b00e2..e518033192 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -546,7 +546,7 @@ class TransactionTest < ActiveRecord::TestCase def test_transactions_state_from_rollback connection = Topic.connection - transaction = ActiveRecord::ConnectionAdapters::ClosedTransaction.new(connection).begin + transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction assert transaction.open? assert !transaction.state.rolledback? @@ -560,7 +560,7 @@ class TransactionTest < ActiveRecord::TestCase def test_transactions_state_from_commit connection = Topic.connection - transaction = ActiveRecord::ConnectionAdapters::ClosedTransaction.new(connection).begin + transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction assert transaction.open? assert !transaction.state.rolledback? diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 61e9927a07..72fa6722b5 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,9 @@ +* Added Object#itself which returns the object itself. Useful when dealing with a chaining scenario, like Active Record scopes: + + Event.public_send(state.presence_in?([ :trashed, :drafted ]) || :itself).order(:created_at) + + *DHH* + * `Object#with_options` executes block in merging option context when explicit receiver in not passed. diff --git a/activesupport/lib/active_support/core_ext/object.rb b/activesupport/lib/active_support/core_ext/object.rb index f4f9152d6a..f1106cca9b 100644 --- a/activesupport/lib/active_support/core_ext/object.rb +++ b/activesupport/lib/active_support/core_ext/object.rb @@ -2,6 +2,7 @@ require 'active_support/core_ext/object/acts_like' require 'active_support/core_ext/object/blank' require 'active_support/core_ext/object/duplicable' require 'active_support/core_ext/object/deep_dup' +require 'active_support/core_ext/object/itself' require 'active_support/core_ext/object/try' require 'active_support/core_ext/object/inclusion' diff --git a/activesupport/lib/active_support/core_ext/object/itself.rb b/activesupport/lib/active_support/core_ext/object/itself.rb new file mode 100644 index 0000000000..df613c4e4f --- /dev/null +++ b/activesupport/lib/active_support/core_ext/object/itself.rb @@ -0,0 +1,10 @@ +class Object + # Returns the object itself. Useful when dealing with a chaining scenario, like Active Record scopes: + # + # Event.public_send(state.presence_in?([ :trashed, :drafted ]) || :itself).order(:created_at) + # + # @return Object + def itself + self + end +end
\ No newline at end of file diff --git a/activesupport/test/core_ext/object/itself_test.rb b/activesupport/test/core_ext/object/itself_test.rb new file mode 100644 index 0000000000..65db0ddf40 --- /dev/null +++ b/activesupport/test/core_ext/object/itself_test.rb @@ -0,0 +1,9 @@ +require 'abstract_unit' +require 'active_support/core_ext/object' + +class Object::ItselfTest < ActiveSupport::TestCase + test 'itself returns self' do + object = 'fun' + assert_equal object, object.itself + end +end diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index c9e265de08..35467fe95b 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -267,23 +267,6 @@ This is equivalent to writing: Client.where(first_name: 'does not exist').take! ``` -#### `last!` - -`Model.last!` finds the last record ordered by the primary key. For example: - -```ruby -client = Client.last! -# => #<Client id: 221, first_name: "Russel"> -``` - -The SQL equivalent of the above is: - -```sql -SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1 -``` - -`Model.last!` raises `ActiveRecord::RecordNotFound` if no matching record is found. - ### Retrieving Multiple Objects in Batches We often need to iterate over a large set of records, as when we send a newsletter to a large set of users, or when we export data. @@ -293,7 +276,7 @@ This may appear straightforward: ```ruby # This is very inefficient when the users table has thousands of rows. User.all.each do |user| - NewsLetter.weekly_deliver(user) + NewsMailer.weekly(user).deliver end ``` @@ -333,7 +316,7 @@ The `:batch_size` option allows you to specify the number of records to be retri ```ruby User.find_each(batch_size: 5000) do |user| - NewsLetter.weekly_deliver(user) + NewsMailer.weekly(user).deliver end ``` @@ -345,7 +328,7 @@ For example, to send newsletters only to users with the primary key starting fro ```ruby User.find_each(start: 2000, batch_size: 5000) do |user| - NewsLetter.weekly_deliver(user) + NewsMailer.weekly(user).deliver end ``` diff --git a/guides/source/command_line.md b/guides/source/command_line.md index 3a78c3bb3f..a074b849c6 100644 --- a/guides/source/command_line.md +++ b/guides/source/command_line.md @@ -149,8 +149,6 @@ $ bin/rails generate controller Greetings hello create test/controllers/greetings_controller_test.rb invoke helper create app/helpers/greetings_helper.rb - invoke test_unit - create test/helpers/greetings_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/greetings.js.coffee @@ -236,8 +234,6 @@ $ bin/rails generate scaffold HighScore game:string score:integer create test/controllers/high_scores_controller_test.rb invoke helper create app/helpers/high_scores_helper.rb - invoke test_unit - create test/helpers/high_scores_helper_test.rb invoke jbuilder create app/views/high_scores/index.json.jbuilder create app/views/high_scores/show.json.jbuilder diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 13020fb286..305adb0608 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -137,7 +137,7 @@ numbers. New applications filter out passwords by adding the following `config.f * `config.assets.enabled` a flag that controls whether the asset pipeline is enabled. It is set to true by default. -*`config.assets.raise_runtime_errors`* Set this flag to `true` to enable additional runtime error checking. Recommended in `config/environments/development.rb` to minimize unexpected behavior when deploying to `production`. +* `config.assets.raise_runtime_errors`* Set this flag to `true` to enable additional runtime error checking. Recommended in `config/environments/development.rb` to minimize unexpected behavior when deploying to `production`. * `config.assets.compress` a flag that enables the compression of compiled assets. It is explicitly set to true in `config/environments/production.rb`. @@ -996,3 +996,24 @@ If you get the above error, you might want to increase the size of connection pool by incrementing the `pool` option in `database.yml` NOTE. If you are running in a multi-threaded environment, there could be a chance that several threads may be accessing multiple connections simultaneously. So depending on your current request load, you could very well have multiple threads contending for a limited amount of connections. + + +Custom configuration +-------------------- + +You can configure your own code through the Rails configuration object with custom configuration. It works like this: + + ```ruby + config.x.payment_processing.schedule = :daily + config.x.payment_processing.retries = 3 + config.x.super_debugger = true + ``` + +These configuration points are then available through the configuration object: + + ```ruby + Rails.configuration.x.payment_processing.schedule # => :daily + Rails.configuration.x.payment_processing.retries # => 3 + Rails.configuration.x.super_debugger # => true + Rails.configuration.x.super_debugger.not_set # => nil + ``` diff --git a/guides/source/engines.md b/guides/source/engines.md index a5f8ee27b8..e9cce3f159 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -322,8 +322,6 @@ invoke test_unit create test/controllers/blorgh/articles_controller_test.rb invoke helper create app/helpers/blorgh/articles_helper.rb -invoke test_unit -create test/helpers/blorgh/articles_helper_test.rb invoke assets invoke js create app/assets/javascripts/blorgh/articles.js @@ -560,8 +558,6 @@ invoke test_unit create test/controllers/blorgh/comments_controller_test.rb invoke helper create app/helpers/blorgh/comments_helper.rb -invoke test_unit -create test/helpers/blorgh/comments_helper_test.rb invoke assets invoke js create app/assets/javascripts/blorgh/comments.js diff --git a/guides/source/generators.md b/guides/source/generators.md index be64f1638d..5e88fa0c70 100644 --- a/guides/source/generators.md +++ b/guides/source/generators.md @@ -191,8 +191,6 @@ $ bin/rails generate scaffold User name:string create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb - invoke test_unit - create test/helpers/users_helper_test.rb invoke jbuilder create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder @@ -387,8 +385,6 @@ $ bin/rails generate scaffold Comment body:text create test/controllers/comments_controller_test.rb invoke my_helper create app/helpers/comments_helper.rb - invoke shoulda - create test/helpers/comments_helper_test.rb invoke jbuilder create app/views/comments/index.json.jbuilder create app/views/comments/show.json.jbuilder diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 656d74ef06..1f91352c82 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -191,14 +191,15 @@ following in the `blog` directory: $ bin/rails server ``` -TIP: Compiling CoffeeScript to JavaScript requires a JavaScript runtime and the -absence of a runtime will give you an `execjs` error. Usually Mac OS X and -Windows come with a JavaScript runtime installed. Rails adds the `therubyracer` -gem to the generated `Gemfile` in a commented line for new apps and you can -uncomment if you need it. `therubyrhino` is the recommended runtime for JRuby -users and is added by default to the `Gemfile` in apps generated under JRuby. -You can investigate about all the supported runtimes at -[ExecJS](https://github.com/sstephenson/execjs#readme). +TIP: Compiling CoffeeScript and JavaScript asset compression requires you +have a JavaScript runtime available on your system, in the absence +of a runtime you will see an `execjs` error during asset compilation. +Usually Mac OS X and Windows come with a JavaScript runtime installed. +Rails adds the `therubyracer` gem to the generated `Gemfile` in a +commented line for new apps and you can uncomment if you need it. +`therubyrhino` is the recommended runtime for JRuby users and is added by +default to the `Gemfile` in apps generated under JRuby. You can investigate +about all the supported runtimes at [ExecJS](https://github.com/sstephenson/execjs#readme). This will fire up WEBrick, a web server distributed with Ruby by default. To see your application in action, open a browser window and navigate to @@ -256,8 +257,6 @@ invoke test_unit create test/controllers/welcome_controller_test.rb invoke helper create app/helpers/welcome_helper.rb -invoke test_unit -create test/helpers/welcome_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/welcome.js.coffee @@ -909,7 +908,7 @@ And then finally, add the view for this action, located at </table> ``` -Now if you go to `http://localhost:3000/articles` you will see a list of all the +Now if you go to <http://localhost:3000/articles> you will see a list of all the articles that you have created. ### Adding links @@ -1105,7 +1104,7 @@ standout. Now you'll get a nice error message when saving an article without title when you attempt to do just that on the new article form -[(http://localhost:3000/articles/new)](http://localhost:3000/articles/new). +<http://localhost:3000/articles/new>: ![Form With Errors](images/getting_started/form_with_errors.png) @@ -1636,7 +1635,6 @@ This creates six files and one empty directory: | app/views/comments/ | Views of the controller are stored here | | test/controllers/comments_controller_test.rb | The test for the controller | | app/helpers/comments_helper.rb | A view helper file | -| test/helpers/comments_helper_test.rb | The test for the helper | | app/assets/javascripts/comment.js.coffee | CoffeeScript for the controller | | app/assets/stylesheets/comment.css.scss | Cascading style sheet for the controller | diff --git a/guides/source/testing.md b/guides/source/testing.md index b2da25b19f..3e12afc000 100644 --- a/guides/source/testing.md +++ b/guides/source/testing.md @@ -364,13 +364,8 @@ Ideally, you would like to include a test for everything which could possibly br By now you've caught a glimpse of some of the assertions that are available. Assertions are the worker bees of testing. They are the ones that actually perform the checks to ensure that things are going as planned. -There are a bunch of different types of assertions you can use. Here's an -extract of the -[assertions](http://docs.seattlerb.org/minitest/Minitest/Assertions.html) you -can use with [minitest](https://github.com/seattlerb/minitest), the default -testing library used by Rails. The `[msg]` parameter is an optional string -message you can specify to make your test failure messages clearer. It's not -required. +There are a bunch of different types of assertions you can use. +Here's an extract of the assertions you can use with [`Minitest`](https://github.com/seattlerb/minitest), the default testing library used by Rails. The `[msg]` parameter is an optional string message you can specify to make your test failure messages clearer. It's not required. | Assertion | Purpose | | ---------------------------------------------------------------- | ------- | @@ -406,6 +401,8 @@ required. | `assert_send( array, [msg] )` | Ensures that executing the method listed in `array[1]` on the object in `array[0]` with the parameters of `array[2 and up]` is true. This one is weird eh?| | `flunk( [msg] )` | Ensures failure. This is useful to explicitly mark a test that isn't finished yet.| +The above are subset of assertions that minitest supports. For an exhaustive & more up-to-date list, please check [Minitest API documentation](http://docs.seattlerb.org/minitest/), specifically [`Minitest::Assertions`](http://docs.seattlerb.org/minitest/Minitest/Assertions.html) + Because of the modular nature of the testing framework, it is possible to create your own assertions. In fact, that's exactly what Rails does. It includes some specialized assertions to make your life easier. NOTE: Creating your own assertions is an advanced topic that we won't cover in this tutorial. @@ -1017,17 +1014,9 @@ Testing helpers In order to test helpers, all you need to do is check that the output of the helper method matches what you'd expect. Tests related to the helpers are -located under the `test/helpers` directory. Rails provides a generator which -generates both the helper and the test file: - -```bash -$ bin/rails generate helper User - create app/helpers/user_helper.rb - invoke test_unit - create test/helpers/user_helper_test.rb -``` +located under the `test/helpers` directory. -The generated test file contains the following code: +A helper test looks like so: ```ruby require 'test_helper' @@ -1060,7 +1049,6 @@ The built-in `minitest` based testing is not the only way to test Rails applicat * [NullDB](http://avdi.org/projects/nulldb/), a way to speed up testing by avoiding database use. * [Factory Girl](https://github.com/thoughtbot/factory_girl/tree/master), a replacement for fixtures. -* [Machinist](https://github.com/notahat/machinist/tree/master), another replacement for fixtures. * [Fixture Builder](https://github.com/rdy/fixture_builder), a tool that compiles Ruby factories into fixtures before a test run. * [MiniTest::Spec Rails](https://github.com/metaskills/minitest-spec-rails), use the MiniTest::Spec DSL within your rails tests. * [Shoulda](http://www.thoughtbot.com/projects/shoulda), an extension to `test/unit` with additional helpers, macros, and assertions. diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 651f40007e..dac554e015 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,20 @@ +* Pull in the custom configuration concept from dhh/custom_configuration, which allows you to + configure your own code through the Rails configuration object with custom configuration: + + # config/environments/production.rb + config.x.payment_processing.schedule = :daily + config.x.payment_processing.retries = 3 + config.x.super_debugger = true + + These configuration points are then available through the configuration object: + + Rails.configuration.x.payment_processing.schedule # => :daily + Rails.configuration.x.payment_processing.retries # => 3 + Rails.configuration.x.super_debugger # => true + Rails.configuration.x.super_debugger.not_set # => nil + + *DHH* + * Scaffold generator `_form` partial adds `class="field"` for password confirmation fields. diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 5e8f4de847..782bc4b0f1 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -13,7 +13,7 @@ module Rails :railties_order, :relative_url_root, :secret_key_base, :secret_token, :serve_static_assets, :ssl_options, :static_cache_control, :session_options, :time_zone, :reload_classes_only_on_change, - :beginning_of_week, :filter_redirect + :beginning_of_week, :filter_redirect, :x attr_writer :log_level attr_reader :encoding @@ -48,6 +48,7 @@ module Rails @eager_load = nil @secret_token = nil @secret_key_base = nil + @x = Custom.new @assets = ActiveSupport::OrderedOptions.new @assets.enabled = true @@ -154,6 +155,17 @@ module Rails def annotations SourceAnnotationExtractor::Annotation end + + private + class Custom + def initialize + @configurations = Hash.new + end + + def method_missing(method, *args) + @configurations[method] ||= ActiveSupport::OrderedOptions.new + end + end end end end diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt index bbb409616d..35e3035a0b 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt @@ -30,7 +30,8 @@ Rails.application.configure do # number of complex assets. config.assets.debug = true - # Generate digests for assets URLs. + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. config.assets.digest = true # Adds additional error checking when serving assets at runtime. diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt index 5e52f97249..48d1b06674 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt @@ -30,7 +30,8 @@ Rails.application.configure do # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false - # Generate digests for assets URLs. + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. config.assets.digest = true # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb @@ -43,8 +44,8 @@ Rails.application.configure do # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # Set to :debug to see everything in the log. - config.log_level = :info + # Set to :info to see decrease the log volume. + config.log_level = :debug # Prepend all log lines with the following tags. # config.log_tags = [ :subdomain, :uuid ] diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt index d2f4ec33a6..01ef3e6630 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt @@ -3,6 +3,9 @@ # Version of your assets, change this if you want to expire all your assets. Rails.application.config.assets.version = '1.0' +# Add additional assets to the asset load path +# Rails.application.config.assets.paths << Emoji.images_path + # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. # Rails.application.config.assets.precompile += %w( search.js ) diff --git a/railties/lib/rails/generators/rails/controller/USAGE b/railties/lib/rails/generators/rails/controller/USAGE index de33900e0a..64239ad599 100644 --- a/railties/lib/rails/generators/rails/controller/USAGE +++ b/railties/lib/rails/generators/rails/controller/USAGE @@ -16,4 +16,3 @@ Example: Test: test/controllers/credit_cards_controller_test.rb Views: app/views/credit_cards/debit.html.erb [...] Helper: app/helpers/credit_cards_helper.rb - Test: test/helpers/credit_cards_helper_test.rb diff --git a/railties/lib/rails/generators/rails/helper/USAGE b/railties/lib/rails/generators/rails/helper/USAGE index 30e323a858..8855ef3b01 100644 --- a/railties/lib/rails/generators/rails/helper/USAGE +++ b/railties/lib/rails/generators/rails/helper/USAGE @@ -5,13 +5,9 @@ Description: To create a helper within a module, specify the helper name as a path like 'parent_module/helper_name'. - This generates a helper class in app/helpers and invokes the configured - test framework. - Example: `rails generate helper CreditCard` Credit card helper. Helper: app/helpers/credit_card_helper.rb - Test: test/helpers/credit_card_helper_test.rb diff --git a/railties/lib/rails/generators/rails/helper/helper_generator.rb b/railties/lib/rails/generators/rails/helper/helper_generator.rb index 5ff38e4111..419607839a 100644 --- a/railties/lib/rails/generators/rails/helper/helper_generator.rb +++ b/railties/lib/rails/generators/rails/helper/helper_generator.rb @@ -6,8 +6,6 @@ module Rails def create_helper_files template 'helper.rb', File.join('app/helpers', class_path, "#{file_name}_helper.rb") end - - hook_for :test_framework end end end diff --git a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb b/railties/lib/rails/generators/test_unit/helper/helper_generator.rb deleted file mode 100644 index 0db76f9eaf..0000000000 --- a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'rails/generators/test_unit' - -module TestUnit # :nodoc: - module Generators # :nodoc: - class HelperGenerator < Base # :nodoc: - check_class_collision suffix: "HelperTest" - - def create_helper_files - template 'helper_test.rb', File.join('test/helpers', class_path, "#{file_name}_helper_test.rb") - end - end - end -end diff --git a/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb b/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb deleted file mode 100644 index 7d37bda0f9..0000000000 --- a/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'test_helper' - -<% module_namespacing do -%> -class <%= class_name %>HelperTest < ActionView::TestCase -end -<% end -%> diff --git a/railties/test/application/configuration/base_test.rb b/railties/test/application/configuration/base_test.rb new file mode 100644 index 0000000000..d6a82b139d --- /dev/null +++ b/railties/test/application/configuration/base_test.rb @@ -0,0 +1,37 @@ +require 'isolation/abstract_unit' +require 'rack/test' +require 'env_helpers' + +module ApplicationTests + module ConfigurationTests + class BaseTest < ActiveSupport::TestCase + def setup + build_app + boot_rails + FileUtils.rm_rf("#{app_path}/config/environments") + end + + def teardown + teardown_app + FileUtils.rm_rf(new_app) if File.directory?(new_app) + end + + private + def new_app + File.expand_path("#{app_path}/../new_app") + end + + def copy_app + FileUtils.cp_r(app_path, new_app) + end + + def app + @app ||= Rails.application + end + + def require_environment + require "#{app_path}/config/environment" + end + end + end +end
\ No newline at end of file diff --git a/railties/test/application/configuration/custom_test.rb b/railties/test/application/configuration/custom_test.rb new file mode 100644 index 0000000000..045537fc28 --- /dev/null +++ b/railties/test/application/configuration/custom_test.rb @@ -0,0 +1,15 @@ +require 'application/configuration/base_test' + +class ApplicationTests::ConfigurationTests::CustomTest < ApplicationTests::ConfigurationTests::BaseTest + test 'access custom configuration point' do + add_to_config <<-RUBY + config.x.resque.inline_jobs = :always + config.x.resque.timeout = 60 + RUBY + require_environment + + assert_equal :always, Rails.configuration.x.resque.inline_jobs + assert_equal 60, Rails.configuration.x.resque.timeout + assert_nil Rails.configuration.x.resque.nothing + end +end diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb index 28b527cb0e..a7d56dd352 100644 --- a/railties/test/generators/controller_generator_test.rb +++ b/railties/test/generators/controller_generator_test.rb @@ -28,13 +28,11 @@ class ControllerGeneratorTest < Rails::Generators::TestCase def test_invokes_helper run_generator assert_file "app/helpers/account_helper.rb" - assert_file "test/helpers/account_helper_test.rb" end def test_does_not_invoke_helper_if_required run_generator ["account", "--skip-helper"] assert_no_file "app/helpers/account_helper.rb" - assert_no_file "test/helpers/account_helper_test.rb" end def test_invokes_assets diff --git a/railties/test/generators/helper_generator_test.rb b/railties/test/generators/helper_generator_test.rb deleted file mode 100644 index 81d4fcb129..0000000000 --- a/railties/test/generators/helper_generator_test.rb +++ /dev/null @@ -1,54 +0,0 @@ -require 'generators/generators_test_helper' -require 'rails/generators/rails/helper/helper_generator' - -ObjectHelper = Class.new -AnotherObjectHelperTest = Class.new - -class HelperGeneratorTest < Rails::Generators::TestCase - include GeneratorsTestHelper - arguments %w(admin) - - def test_helper_skeleton_is_created - run_generator - assert_file "app/helpers/admin_helper.rb", /module AdminHelper/ - end - - def test_invokes_default_test_framework - run_generator - assert_file "test/helpers/admin_helper_test.rb", /class AdminHelperTest < ActionView::TestCase/ - end - - def test_logs_if_the_test_framework_cannot_be_found - content = run_generator ["admin", "--test-framework=rspec"] - assert_match(/rspec \[not found\]/, content) - end - - def test_check_class_collision - content = capture(:stderr){ run_generator ["object"] } - assert_match(/The name 'ObjectHelper' is either already used in your application or reserved/, content) - end - - def test_check_class_collision_on_tests - content = capture(:stderr){ run_generator ["another_object"] } - assert_match(/The name 'AnotherObjectHelperTest' is either already used in your application or reserved/, content) - end - - def test_namespaced_and_not_namespaced_helpers - run_generator ["products"] - - # We have to require the generated helper to show the problem because - # the test helpers just check for generated files and contents but - # do not actually load them. But they have to be loaded (as in a real environment) - # to make the second generator run fail - require "#{destination_root}/app/helpers/products_helper" - - assert_nothing_raised do - begin - run_generator ["admin::products"] - ensure - # cleanup - Object.send(:remove_const, :ProductsHelper) - end - end - end -end diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb index d677c21f15..7eeb084eab 100644 --- a/railties/test/generators/namespaced_generators_test.rb +++ b/railties/test/generators/namespaced_generators_test.rb @@ -47,7 +47,6 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase def test_helper_is_also_namespaced run_generator assert_file "app/helpers/test_app/account_helper.rb", /module TestApp/, / module AccountHelper/ - assert_file "test/helpers/test_app/account_helper_test.rb", /module TestApp/, / class AccountHelperTest/ end def test_invokes_default_test_framework @@ -229,7 +228,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/product_lines_helper.rb" - assert_file "test/helpers/test_app/product_lines_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -260,7 +258,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/product_lines_helper.rb" - assert_no_file "test/helpers/test_app/product_lines_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" @@ -297,7 +294,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/admin/roles_helper.rb" - assert_file "test/helpers/test_app/admin/roles_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -329,7 +325,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/admin/roles_helper.rb" - assert_no_file "test/helpers/test_app/admin/roles_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" @@ -366,7 +361,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/admin/user/special/roles_helper.rb" - assert_file "test/helpers/test_app/admin/user/special/roles_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -397,7 +391,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/admin/user/special/roles_helper.rb" - assert_no_file "test/helpers/test_app/admin/user/special/roles_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb index dcdff22152..581d80d60e 100644 --- a/railties/test/generators/resource_generator_test.rb +++ b/railties/test/generators/resource_generator_test.rb @@ -36,7 +36,6 @@ class ResourceGeneratorTest < Rails::Generators::TestCase assert_file "test/controllers/accounts_controller_test.rb", /class AccountsControllerTest < ActionController::TestCase/ assert_file "app/helpers/accounts_helper.rb", /module AccountsHelper/ - assert_file "test/helpers/accounts_helper_test.rb", /class AccountsHelperTest < ActionView::TestCase/ end def test_resource_controller_with_actions diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 46eacd2845..ca972a3bdd 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -81,7 +81,6 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_helper_are_invoked_with_a_pluralized_name run_generator assert_file "app/helpers/users_helper.rb", /module UsersHelper/ - assert_file "test/helpers/users_helper_test.rb", /class UsersHelperTest < ActionView::TestCase/ end def test_views_are_generated @@ -126,7 +125,6 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_skip_helper_if_required run_generator ["User", "name:string", "age:integer", "--no-helper"] assert_no_file "app/helpers/users_helper.rb" - assert_no_file "test/helpers/users_helper_test.rb" end def test_skip_layout_if_required diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 524bbde2b7..637bde2a44 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -70,7 +70,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_file "app/helpers/product_lines_helper.rb" - assert_file "test/helpers/product_lines_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css" @@ -114,7 +113,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_no_file "app/helpers/product_lines_helper.rb" - assert_no_file "test/helpers/product_lines_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ @@ -182,7 +180,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_file "app/helpers/admin/roles_helper.rb" - assert_file "test/helpers/admin/roles_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ @@ -216,7 +213,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_no_file "app/helpers/admin/roles_helper.rb" - assert_no_file "test/helpers/admin/roles_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css" |