diff options
43 files changed, 438 insertions, 370 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_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 07265be3fe..0f2fa5fb08 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -28,20 +28,19 @@ module ActionController :port => request.optional_port, :protocol => request.protocol, :_recall => request.path_parameters - }.merge(super).freeze + }.merge!(super).freeze if (same_origin = _routes.equal?(env["action_dispatch.routes".freeze])) || (script_name = env["ROUTES_#{_routes.object_id}_SCRIPT_NAME"]) || (original_script_name = env['ORIGINAL_SCRIPT_NAME'.freeze]) - @_url_options.dup.tap do |options| - if original_script_name - options[:original_script_name] = original_script_name - else - options[:script_name] = same_origin ? request.script_name.dup : script_name - end - options.freeze + options = @_url_options.dup + if original_script_name + options[:original_script_name] = original_script_name + else + options[:script_name] = same_origin ? request.script_name.dup : script_name end + options.freeze else @_url_options end 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/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 95f5f45abe..cd94f35e8f 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -13,9 +13,6 @@ module ActionDispatch module Routing class Mapper URL_OPTIONS = [:protocol, :subdomain, :domain, :host, :port] - SCOPE_OPTIONS = [:path, :shallow_path, :as, :shallow_prefix, :module, - :controller, :action, :path_names, :constraints, - :shallow, :blocks, :defaults, :options] class Constraints < Endpoint #:nodoc: attr_reader :app, :constraints @@ -617,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 } @@ -771,7 +770,7 @@ module ActionDispatch # end def scope(*args) options = args.extract_options!.dup - recover = {} + scope = {} options[:path] = args.flatten.join('/') if args.any? options[:constraints] ||= {} @@ -791,7 +790,7 @@ module ActionDispatch block, options[:constraints] = options[:constraints], {} end - SCOPE_OPTIONS.each do |option| + @scope.options.each do |option| if option == :blocks value = block elsif option == :options @@ -801,15 +800,15 @@ module ActionDispatch end if value - recover[option] = @scope[option] - @scope[option] = send("merge_#{option}_scope", @scope[option], value) + scope[option] = send("merge_#{option}_scope", @scope[option], value) end end + @scope = @scope.new scope yield self ensure - @scope.merge!(recover) + @scope = @scope.parent end # Scopes routes to a specific controller @@ -1645,27 +1644,26 @@ module ActionDispatch def with_exclusive_scope begin - old_name_prefix, old_path = @scope[:as], @scope[:path] - @scope[:as], @scope[:path] = nil, nil + @scope = @scope.new(:as => nil, :path => nil) with_scope_level(:exclusive) do yield end ensure - @scope[:as], @scope[:path] = old_name_prefix, old_path + @scope = @scope.parent end end def with_scope_level(kind) - old, @scope[:scope_level] = @scope[:scope_level], kind + @scope = @scope.new(:scope_level => kind) yield ensure - @scope[:scope_level] = old + @scope = @scope.parent end def resource_scope(kind, resource) #:nodoc: resource.shallow = @scope[:shallow] - old_resource, @scope[:scope_level_resource] = @scope[:scope_level_resource], resource + @scope = @scope.new(:scope_level_resource => resource) @nesting.push(resource) with_scope_level(kind) do @@ -1673,7 +1671,7 @@ module ActionDispatch end ensure @nesting.pop - @scope[:scope_level_resource] = old_resource + @scope = @scope.parent end def nested_options #:nodoc: @@ -1706,12 +1704,13 @@ module ActionDispatch end def shallow_scope(path, options = {}) #:nodoc: - old_name_prefix, old_path = @scope[:as], @scope[:path] - @scope[:as], @scope[:path] = @scope[:shallow_prefix], @scope[:shallow_path] + scope = { :as => @scope[:shallow_prefix], + :path => @scope[:shallow_path] } + @scope = @scope.new scope scope(path, options) { yield } ensure - @scope[:as], @scope[:path] = old_name_prefix, old_path + @scope = @scope.parent end def path_for_action(action, path) #:nodoc: @@ -1768,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 @@ -1893,9 +1892,38 @@ module ActionDispatch end end + class Scope # :nodoc: + OPTIONS = [:path, :shallow_path, :as, :shallow_prefix, :module, + :controller, :action, :path_names, :constraints, + :shallow, :blocks, :defaults, :options] + + attr_reader :parent + + def initialize(hash, parent = {}) + @hash = hash + @parent = parent + end + + def options + OPTIONS + end + + def new(hash) + self.class.new hash, self + end + + def [](key) + @hash.fetch(key) { @parent[key] } + end + + def []=(k,v) + @hash[k] = v + end + end + def initialize(set) #:nodoc: @set = set - @scope = { :path_names => @set.resources_path_names } + @scope = Scope.new({ :path_names => @set.resources_path_names }) @concerns = {} @nesting = [] end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 4155efa03c..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! @@ -327,7 +331,7 @@ module ActionDispatch def initialize(request_class = ActionDispatch::Request) self.named_routes = NamedRouteCollection.new - self.resources_path_names = self.class.default_resources_path_names.dup + self.resources_path_names = self.class.default_resources_path_names self.default_url_options = {} self.request_class = request_class @@ -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/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 269c7b4159..b8e20c52a0 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -4292,11 +4292,9 @@ end class TestCallableConstraintValidation < ActionDispatch::IntegrationTest def test_constraint_with_object_not_callable assert_raises(ArgumentError) do - ActionDispatch::Routing::RouteSet.new.tap do |app| - app.draw do - ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] } - get '/test', to: ok, constraints: Object.new - end + ActionDispatch::Routing::RouteSet.new.draw do + ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] } + get '/test', to: ok, constraints: Object.new end end end diff --git a/actionview/lib/action_view/test_case.rb b/actionview/lib/action_view/test_case.rb index 9e8e6f43d5..d0da415c5d 100644 --- a/actionview/lib/action_view/test_case.rb +++ b/actionview/lib/action_view/test_case.rb @@ -259,7 +259,7 @@ module ActionView def method_missing(selector, *args) if @controller.respond_to?(:_routes) && - ( @controller._routes.named_routes.helpers.include?(selector) || + ( @controller._routes.named_routes.route_defined?(selector) || @controller._routes.mounted_helpers.method_defined?(selector) ) @controller.__send__(selector, *args) else diff --git a/actionview/test/activerecord/polymorphic_routes_test.rb b/actionview/test/activerecord/polymorphic_routes_test.rb index fef27ef492..e220dcb8cb 100644 --- a/actionview/test/activerecord/polymorphic_routes_test.rb +++ b/actionview/test/activerecord/polymorphic_routes_test.rb @@ -158,34 +158,38 @@ class PolymorphicRoutesTest < ActionController::TestCase def test_with_nil with_test_routes do - assert_raise ArgumentError, "Nil location provided. Can't build URI." do + exception = assert_raise ArgumentError do polymorphic_url(nil) end + assert_equal "Nil location provided. Can't build URI.", exception.message end end def test_with_empty_list with_test_routes do - assert_raise ArgumentError, "Nil location provided. Can't build URI." do + exception = assert_raise ArgumentError do polymorphic_url([]) end + assert_equal "Nil location provided. Can't build URI.", exception.message end end def test_with_nil_id with_test_routes do - assert_raise ArgumentError, "Nil location provided. Can't build URI." do + exception = assert_raise ArgumentError do polymorphic_url({ :id => nil }) end + assert_equal "Nil location provided. Can't build URI.", exception.message end end def test_with_nil_in_list with_test_routes do - assert_raise ArgumentError, "Nil location provided. Can't build URI." do + exception = assert_raise ArgumentError do @series.save polymorphic_url([nil, @series]) end + assert_equal "Nil location provided. Can't build URI.", exception.message end end diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index b679d64472..5988ded344 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,11 @@ +* 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/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 2a97d0ed31..79c3d2b0f5 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -124,7 +124,7 @@ module ActiveRecord def inverse_updates_counter_named?(counter_name, reflection = reflection()) reflection.klass._reflections.values.any? { |inverse_reflection| - :belongs_to == inverse_reflection.macro && + inverse_reflection.belongs_to? && inverse_reflection.counter_cache_column == counter_name } end 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..a9d1099871 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) 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/counter_cache.rb b/activerecord/lib/active_record/counter_cache.rb index a33c7c64a7..f0b6afc4b4 100644 --- a/activerecord/lib/active_record/counter_cache.rb +++ b/activerecord/lib/active_record/counter_cache.rb @@ -34,7 +34,7 @@ module ActiveRecord foreign_key = has_many_association.foreign_key.to_s child_class = has_many_association.klass - reflection = child_class._reflections.values.find { |e| :belongs_to == e.macro && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? } + reflection = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? } counter_name = reflection.counter_cache_column stmt = unscoped.where(arel_table[primary_key].eq(object.id)).arel.compile_update({ 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 bb84f388a8..1547c8e3f4 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -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 @@ -431,14 +423,10 @@ Joining, Preloading and eager loading of these associations is deprecated and wi end # Returns +true+ if +self+ is a +belongs_to+ reflection. - def belongs_to? - macro == :belongs_to - end + def belongs_to?; false; end # Returns +true+ if +self+ is a +has_one+ reflection. - def has_one? - macro == :has_one - end + def has_one?; false; end def association_class case macro @@ -578,35 +566,46 @@ 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 def macro; :has_many; end - def collection? - true - end + 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 def macro; :has_one; end + + 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 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 @@ -737,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 @@ -804,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/array/grouping.rb b/activesupport/lib/active_support/core_ext/array/grouping.rb index 3529d57174..87ae052eb0 100644 --- a/activesupport/lib/active_support/core_ext/array/grouping.rb +++ b/activesupport/lib/active_support/core_ext/array/grouping.rb @@ -18,6 +18,11 @@ class Array # ["3", "4"] # ["5"] def in_groups_of(number, fill_with = nil) + if number.to_i <= 0 + raise ArgumentError, + "Group size must be a positive integer, was #{number.inspect}" + end + if fill_with == false collection = self else 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/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb index dc76a77a6c..3d8f2d572b 100644 --- a/activesupport/lib/active_support/hash_with_indifferent_access.rb +++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb @@ -246,11 +246,11 @@ module ActiveSupport # Convert to a regular hash with string keys. def to_hash - _new_hash= {} + _new_hash = Hash.new(default) each do |key, value| - _new_hash[convert_key(key)] = convert_value(value, for: :to_hash) + _new_hash[key] = convert_value(value, for: :to_hash) end - Hash.new(default).merge!(_new_hash) + _new_hash end protected diff --git a/activesupport/test/core_ext/array/grouping_test.rb b/activesupport/test/core_ext/array/grouping_test.rb index b8cfe9728c..2eb0f05141 100644 --- a/activesupport/test/core_ext/array/grouping_test.rb +++ b/activesupport/test/core_ext/array/grouping_test.rb @@ -90,6 +90,12 @@ class GroupingTest < ActiveSupport::TestCase assert_equal [[1, 2, 3], [4, 5], [6, 7]], (1..7).to_a.in_groups(3, false) end + + def test_in_groups_invalid_argument + assert_raises(ArgumentError) { [].in_groups_of(0) } + assert_raises(ArgumentError) { [].in_groups_of(-1) } + assert_raises(ArgumentError) { [].in_groups_of(nil) } + end end class SplitTest < ActiveSupport::TestCase diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index dbbb2d77da..5e9fdfd872 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -586,6 +586,8 @@ class HashExtTest < ActiveSupport::TestCase roundtrip = mixed_with_default.with_indifferent_access.to_hash assert_equal @strings, roundtrip assert_equal '1234', roundtrip.default + + # Ensure nested hashes are not HashWithIndiffereneAccess new_to_hash = @nested_mixed.with_indifferent_access.to_hash assert_not new_to_hash.instance_of?(HashWithIndifferentAccess) assert_not new_to_hash["a"].instance_of?(HashWithIndifferentAccess) @@ -1516,6 +1518,16 @@ class HashToXmlTest < ActiveSupport::TestCase assert_equal expected, Hash.from_trusted_xml('<product><name type="yaml">:value</name></product>') end + def test_should_use_default_proc_for_unknown_key + hash_wia = HashWithIndifferentAccess.new { 1 + 2 } + assert_equal 3, hash_wia[:new_key] + end + + def test_should_use_default_proc_if_no_key_is_supplied + hash_wia = HashWithIndifferentAccess.new { 1 + 2 } + assert_equal 3, hash_wia.default + end + def test_should_use_default_value_for_unknown_key hash_wia = HashWithIndifferentAccess.new(3) assert_equal 3, hash_wia[:new_key] 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/activesupport/test/subscriber_test.rb b/activesupport/test/subscriber_test.rb index 21e4ba0cee..a88d8d9eba 100644 --- a/activesupport/test/subscriber_test.rb +++ b/activesupport/test/subscriber_test.rb @@ -49,6 +49,6 @@ class SubscriberTest < ActiveSupport::TestCase def test_does_not_attach_private_methods ActiveSupport::Notifications.instrument("private_party.doodle") - assert_equal TestSubscriber.events, [] + assert_equal [], TestSubscriber.events 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/configuring.md b/guides/source/configuring.md index 13020fb286..6e897d1714 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`. diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 656d74ef06..32d4a9c9dd 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -909,7 +909,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 +1105,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) diff --git a/guides/source/testing.md b/guides/source/testing.md index b2da25b19f..4ded7818b5 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. diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 21244188dd..e661b6f4cc 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -440,7 +440,7 @@ module ApplicationTests end get "/" - assert last_response.body =~ /_xsrf_token_here/ + assert_match "_xsrf_token_here", last_response.body end test "sets ActionDispatch.test_app" do @@ -891,79 +891,79 @@ module ApplicationTests end test "rake_tasks block works at instance level" do - $ran_block = false - app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do + config.ran_block = false + rake_tasks do - $ran_block = true + config.ran_block = true end end RUBY require "#{app_path}/config/environment" + assert_not Rails.configuration.ran_block - assert !$ran_block require 'rake' require 'rake/testtask' require 'rdoc/task' Rails.application.load_tasks - assert $ran_block + assert Rails.configuration.ran_block end test "generators block works at instance level" do - $ran_block = false - app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do + config.ran_block = false + generators do - $ran_block = true + config.ran_block = true end end RUBY require "#{app_path}/config/environment" + assert_not Rails.configuration.ran_block - assert !$ran_block Rails.application.load_generators - assert $ran_block + assert Rails.configuration.ran_block end test "console block works at instance level" do - $ran_block = false - app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do + config.ran_block = false + console do - $ran_block = true + config.ran_block = true end end RUBY require "#{app_path}/config/environment" + assert_not Rails.configuration.ran_block - assert !$ran_block Rails.application.load_console - assert $ran_block + assert Rails.configuration.ran_block end test "runner block works at instance level" do - $ran_block = false - app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do + config.ran_block = false + runner do - $ran_block = true + config.ran_block = true end end RUBY require "#{app_path}/config/environment" + assert_not Rails.configuration.ran_block - assert !$ran_block Rails.application.load_runner - assert $ran_block + assert Rails.configuration.ran_block end test "loading the first existing database configuration available" do @@ -977,9 +977,7 @@ module ApplicationTests require "#{app_path}/config/environment" - db_config = Rails.application.config.database_configuration - - assert db_config.is_a?(Hash) + assert_kind_of Hash, Rails.application.config.database_configuration end test 'config.action_mailer.show_previews defaults to true in development' do @@ -993,7 +991,7 @@ module ApplicationTests Rails.env = "production" require "#{app_path}/config/environment" - assert_equal Rails.application.config.action_mailer.show_previews, false + assert_equal false, Rails.application.config.action_mailer.show_previews end test 'config.action_mailer.show_previews can be set in the configuration file' do @@ -1003,7 +1001,7 @@ module ApplicationTests RUBY require "#{app_path}/config/environment" - assert_equal Rails.application.config.action_mailer.show_previews, true + assert_equal true, Rails.application.config.action_mailer.show_previews end test "config_for loads custom configuration from yaml files" do diff --git a/railties/test/application/multiple_applications_test.rb b/railties/test/application/multiple_applications_test.rb index f8d8a673ae..98707d22e4 100644 --- a/railties/test/application/multiple_applications_test.rb +++ b/railties/test/application/multiple_applications_test.rb @@ -72,26 +72,26 @@ module ApplicationTests end def test_rake_tasks_defined_on_different_applications_go_to_the_same_class - $run_count = 0 + run_count = 0 application1 = AppTemplate::Application.new application1.rake_tasks do - $run_count += 1 + run_count += 1 end application2 = AppTemplate::Application.new application2.rake_tasks do - $run_count += 1 + run_count += 1 end require "#{app_path}/config/environment" - assert_equal 0, $run_count, "The count should stay at zero without any calls to the rake tasks" + assert_equal 0, run_count, "The count should stay at zero without any calls to the rake tasks" require 'rake' require 'rake/testtask' require 'rdoc/task' Rails.application.load_tasks - assert_equal 2, $run_count, "Calling a rake task should result in two increments to the count" + assert_equal 2, run_count, "Calling a rake task should result in two increments to the count" end def test_multiple_applications_can_be_initialized @@ -100,56 +100,56 @@ module ApplicationTests def test_initializers_run_on_different_applications_go_to_the_same_class application1 = AppTemplate::Application.new - $run_count = 0 + run_count = 0 AppTemplate::Application.initializer :init0 do - $run_count += 1 + run_count += 1 end application1.initializer :init1 do - $run_count += 1 + run_count += 1 end AppTemplate::Application.new.initializer :init2 do - $run_count += 1 + run_count += 1 end - assert_equal 0, $run_count, "Without loading the initializers, the count should be 0" + assert_equal 0, run_count, "Without loading the initializers, the count should be 0" # Set config.eager_load to false so that an eager_load warning doesn't pop up AppTemplate::Application.new { config.eager_load = false }.initialize! - assert_equal 3, $run_count, "There should have been three initializers that incremented the count" + assert_equal 3, run_count, "There should have been three initializers that incremented the count" end def test_consoles_run_on_different_applications_go_to_the_same_class - $run_count = 0 - AppTemplate::Application.console { $run_count += 1 } - AppTemplate::Application.new.console { $run_count += 1 } + run_count = 0 + AppTemplate::Application.console { run_count += 1 } + AppTemplate::Application.new.console { run_count += 1 } - assert_equal 0, $run_count, "Without loading the consoles, the count should be 0" + assert_equal 0, run_count, "Without loading the consoles, the count should be 0" Rails.application.load_console - assert_equal 2, $run_count, "There should have been two consoles that increment the count" + assert_equal 2, run_count, "There should have been two consoles that increment the count" end def test_generators_run_on_different_applications_go_to_the_same_class - $run_count = 0 - AppTemplate::Application.generators { $run_count += 1 } - AppTemplate::Application.new.generators { $run_count += 1 } + run_count = 0 + AppTemplate::Application.generators { run_count += 1 } + AppTemplate::Application.new.generators { run_count += 1 } - assert_equal 0, $run_count, "Without loading the generators, the count should be 0" + assert_equal 0, run_count, "Without loading the generators, the count should be 0" Rails.application.load_generators - assert_equal 2, $run_count, "There should have been two generators that increment the count" + assert_equal 2, run_count, "There should have been two generators that increment the count" end def test_runners_run_on_different_applications_go_to_the_same_class - $run_count = 0 - AppTemplate::Application.runner { $run_count += 1 } - AppTemplate::Application.new.runner { $run_count += 1 } + run_count = 0 + AppTemplate::Application.runner { run_count += 1 } + AppTemplate::Application.new.runner { run_count += 1 } - assert_equal 0, $run_count, "Without loading the runners, the count should be 0" + assert_equal 0, run_count, "Without loading the runners, the count should be 0" Rails.application.load_runner - assert_equal 2, $run_count, "There should have been two runners that increment the count" + assert_equal 2, run_count, "There should have been two runners that increment the count" end def test_isolate_namespace_on_an_application diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index aff484f3eb..184cfc2220 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -194,20 +194,20 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_config_database_is_added_by_default run_generator assert_file "config/database.yml", /sqlite3/ - unless defined?(JRUBY_VERSION) - assert_gem "sqlite3" - else + if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcsqlite3-adapter" + else + assert_gem "sqlite3" end end def test_config_another_database run_generator([destination_root, "-d", "mysql"]) assert_file "config/database.yml", /mysql/ - unless defined?(JRUBY_VERSION) - assert_gem "mysql2" - else + if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcmysql-adapter" + else + assert_gem "mysql2" end end @@ -219,10 +219,10 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_config_postgresql_database run_generator([destination_root, "-d", "postgresql"]) assert_file "config/database.yml", /postgresql/ - unless defined?(JRUBY_VERSION) - assert_gem "pg" - else + if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcpostgresql-adapter" + else + assert_gem "pg" end end @@ -251,9 +251,9 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_gem "activerecord-jdbc-adapter" end - def test_config_jdbc_database_when_no_option_given - if defined?(JRUBY_VERSION) - run_generator([destination_root]) + if defined?(JRUBY_VERSION) + def test_config_jdbc_database_when_no_option_given + run_generator assert_file "config/database.yml", /sqlite3/ assert_gem "activerecord-jdbcsqlite3-adapter" end @@ -295,7 +295,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_inclusion_of_javascript_runtime - run_generator([destination_root]) + run_generator if defined?(JRUBY_VERSION) assert_gem "therubyrhino" else @@ -398,7 +398,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_new_hash_style - run_generator [destination_root] + run_generator assert_file "config/initializers/session_store.rb" do |file| assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file) end diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb index de1e56e7b3..e7990de754 100644 --- a/railties/test/generators/generators_test_helper.rb +++ b/railties/test/generators/generators_test_helper.rb @@ -7,7 +7,7 @@ module Rails class << self remove_possible_method :root def root - @root ||= File.expand_path(File.join(File.dirname(__FILE__), '..', 'fixtures')) + @root ||= File.expand_path('../../fixtures', __FILE__) end end end diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index 0d01931daa..985644e8af 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -95,7 +95,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase end def test_generating_adds_dummy_app_without_javascript_and_assets_deps - run_generator [destination_root] + run_generator assert_file "test/dummy/app/assets/stylesheets/application.css" @@ -335,7 +335,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase Object.const_set('APP_PATH', Rails.root) FileUtils.touch gemfile_path - run_generator [destination_root] + run_generator assert_file gemfile_path, /gem 'bukkits', path: 'tmp\/bukkits'/ ensure @@ -376,19 +376,19 @@ class PluginGeneratorTest < Rails::Generators::TestCase name = `git config user.name`.chomp rescue "TODO: Write your name" email = `git config user.email`.chomp rescue "TODO: Write your email address" - run_generator [destination_root] + run_generator assert_file "bukkits.gemspec" do |contents| - assert_match(/#{Regexp.escape(name)}/, contents) - assert_match(/#{Regexp.escape(email)}/, contents) + assert_match name, contents + assert_match email, contents end end def test_git_name_in_license_file name = `git config user.name`.chomp rescue "TODO: Write your name" - run_generator [destination_root] + run_generator assert_file "MIT-LICENSE" do |contents| - assert_match(/#{Regexp.escape(name)}/, contents) + assert_match name, contents end end @@ -398,11 +398,11 @@ class PluginGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, '--skip-git'] assert_file "MIT-LICENSE" do |contents| - assert_match(/#{Regexp.escape(name)}/, contents) + assert_match name, contents end assert_file "bukkits.gemspec" do |contents| - assert_match(/#{Regexp.escape(name)}/, contents) - assert_match(/#{Regexp.escape(email)}/, contents) + assert_match name, contents + assert_match email, contents end end @@ -416,10 +416,10 @@ protected end def assert_match_sqlite3(contents) - unless defined?(JRUBY_VERSION) - assert_match(/group :development do\n gem 'sqlite3'\nend/, contents) - else + if defined?(JRUBY_VERSION) assert_match(/group :development do\n gem 'activerecord-jdbcsqlite3-adapter'\nend/, contents) + else + assert_match(/group :development do\n gem 'sqlite3'\nend/, contents) end end end |