aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--Gemfile.lock2
-rw-r--r--actionmailer/CHANGELOG.md5
-rw-r--r--actionmailer/lib/action_mailer/base.rb2
-rw-r--r--actionmailer/lib/action_mailer/delivery_job.rb2
-rw-r--r--actionmailer/lib/action_mailer/delivery_methods.rb3
-rw-r--r--actionmailer/test/message_delivery_test.rb14
-rw-r--r--actionpack/CHANGELOG.md17
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb2
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb2
-rw-r--r--actionpack/lib/action_controller/template_assertions.rb185
-rw-r--r--actionpack/lib/action_controller/test_case.rb8
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb4
-rw-r--r--actionpack/lib/action_dispatch/journey/router/utils.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/remote_ip.rb8
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb6
-rw-r--r--actionpack/lib/action_dispatch/routing.rb1
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb3
-rw-r--r--actionpack/lib/action_dispatch/testing/test_process.rb6
-rw-r--r--actionpack/test/controller/action_pack_assertions_test.rb209
-rw-r--r--actionpack/test/controller/caching_test.rb10
-rw-r--r--actionpack/test/controller/filters_test.rb151
-rw-r--r--actionpack/test/controller/flash_test.rb49
-rw-r--r--actionpack/test/controller/force_ssl_test.rb4
-rw-r--r--actionpack/test/controller/http_basic_authentication_test.rb3
-rw-r--r--actionpack/test/controller/http_digest_authentication_test.rb11
-rw-r--r--actionpack/test/controller/http_token_authentication_test.rb9
-rw-r--r--actionpack/test/controller/integration_test.rb2
-rw-r--r--actionpack/test/controller/redirect_test.rb11
-rw-r--r--actionpack/test/controller/test_case_test.rb41
-rw-r--r--actionpack/test/dispatch/template_assertions_test.rb110
-rw-r--r--actionpack/test/fixtures/customers/_commented_customer.html.erb1
-rw-r--r--actionpack/test/fixtures/customers/_customer.html.erb1
-rw-r--r--actionpack/test/fixtures/layouts/standard.html.erb2
-rw-r--r--actionview/lib/action_view/helpers/number_helper.rb2
-rw-r--r--actionview/lib/action_view/layouts.rb25
-rw-r--r--actionview/test/actionpack/controller/layout_test.rb40
-rw-r--r--actionview/test/actionpack/controller/render_test.rb66
-rw-r--r--actionview/test/activerecord/render_partial_with_record_identification_test.rb18
-rw-r--r--actionview/test/fixtures/actionpack/layout_tests/alt/layouts/alt.erb1
-rw-r--r--actionview/test/fixtures/actionpack/test/hyphen-ated.erb2
-rw-r--r--actionview/test/template/test_case_test.rb58
-rw-r--r--activejob/CHANGELOG.md2
-rw-r--r--activejob/lib/active_job/queue_adapter.rb2
-rw-r--r--activejob/lib/active_job/queue_adapters.rb4
-rw-r--r--activemodel/lib/active_model/serialization.rb31
-rw-r--r--activerecord/CHANGELOG.md40
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb15
-rw-r--r--activerecord/lib/active_record/attributes.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb50
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb2
-rw-r--r--activerecord/lib/active_record/fixtures.rb1
-rw-r--r--activerecord/lib/active_record/model_schema.rb23
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb4
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb16
-rw-r--r--activerecord/lib/active_record/schema_migration.rb1
-rw-r--r--activerecord/lib/active_record/suppressor.rb3
-rw-r--r--activerecord/lib/active_record/transactions.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/geometric_test.rb119
-rw-r--r--activerecord/test/cases/calculations_test.rb21
-rw-r--r--activerecord/test/cases/connection_adapters/type_lookup_test.rb6
-rw-r--r--activerecord/test/cases/migration/change_schema_test.rb2
-rw-r--r--activerecord/test/cases/relation_test.rb24
-rw-r--r--activerecord/test/cases/suppressor_test.rb33
-rw-r--r--activesupport/CHANGELOG.md6
-rw-r--r--activesupport/lib/active_support/backtrace_cleaner.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb2
-rw-r--r--activesupport/lib/active_support/deprecation/behaviors.rb6
-rw-r--r--activesupport/lib/active_support/deprecation/proxy_wrappers.rb2
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb4
-rw-r--r--activesupport/lib/active_support/test_case.rb10
-rw-r--r--activesupport/lib/active_support/testing/assertions.rb2
-rw-r--r--activesupport/lib/active_support/testing/composite_filter.rb54
-rw-r--r--activesupport/lib/active_support/testing/time_helpers.rb2
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb1
-rw-r--r--activesupport/test/abstract_unit.rb1
-rw-r--r--activesupport/test/caching_test.rb92
-rw-r--r--activesupport/test/core_ext/date_ext_test.rb33
-rw-r--r--activesupport/test/core_ext/date_time_ext_test.rb68
-rw-r--r--activesupport/test/core_ext/duration_test.rb34
-rw-r--r--activesupport/test/core_ext/enumerable_test.rb9
-rw-r--r--activesupport/test/core_ext/string_ext_test.rb178
-rw-r--r--activesupport/test/core_ext/time_ext_test.rb96
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb63
-rw-r--r--activesupport/test/time_travel_test.rb100
-rw-r--r--activesupport/test/time_zone_test.rb14
-rwxr-xr-xci/travis.rb32
-rw-r--r--guides/bug_report_templates/action_controller_gem.rb15
-rw-r--r--guides/bug_report_templates/action_controller_master.rb21
-rw-r--r--guides/bug_report_templates/active_record_gem.rb16
-rw-r--r--guides/bug_report_templates/active_record_master.rb22
-rw-r--r--guides/bug_report_templates/generic_gem.rb16
-rw-r--r--guides/bug_report_templates/generic_master.rb20
-rw-r--r--guides/source/3_1_release_notes.md2
-rw-r--r--guides/source/action_view_overview.md3
-rw-r--r--guides/source/active_support_core_extensions.md4
-rw-r--r--guides/source/active_support_instrumentation.md14
-rw-r--r--guides/source/association_basics.md13
-rw-r--r--guides/source/configuring.md10
-rw-r--r--guides/source/debugging_rails_applications.md7
-rw-r--r--guides/source/development_dependencies_install.md4
-rw-r--r--guides/source/documents.yaml10
-rw-r--r--guides/source/form_helpers.md6
-rw-r--r--guides/source/getting_started.md6
-rw-r--r--guides/source/i18n.md5
-rw-r--r--guides/source/kindle/welcome.html.erb4
-rw-r--r--guides/source/rails_application_templates.md2
-rw-r--r--guides/source/routing.md7
-rw-r--r--guides/source/testing.md70
-rw-r--r--install.rb4
-rw-r--r--railties/CHANGELOG.md4
-rw-r--r--railties/lib/rails/commands/test.rb4
-rw-r--r--railties/lib/rails/console/app.rb5
-rw-r--r--railties/lib/rails/generators/app_base.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb6
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb9
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb5
-rw-r--r--railties/lib/rails/test_help.rb6
-rw-r--r--railties/lib/rails/test_unit/minitest_plugin.rb51
-rw-r--r--railties/lib/rails/test_unit/reporter.rb6
-rw-r--r--railties/lib/rails/test_unit/runner.rb137
-rw-r--r--railties/lib/rails/test_unit/test_requirer.rb28
-rw-r--r--railties/lib/rails/test_unit/testing.rake15
-rw-r--r--railties/test/application/configuration_test.rb13
-rw-r--r--railties/test/application/console_test.rb12
-rw-r--r--railties/test/application/multiple_applications_test.rb2
-rw-r--r--railties/test/application/test_runner_test.rb165
-rw-r--r--railties/test/application/test_test.rb6
-rw-r--r--railties/test/generators/actions_test.rb79
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb11
-rw-r--r--railties/test/generators/scaffold_generator_test.rb14
-rw-r--r--railties/test/generators/shared_generator_tests.rb9
-rw-r--r--railties/test/test_unit/runner_test.rb111
-rwxr-xr-xtools/profile4
138 files changed, 1615 insertions, 1710 deletions
diff --git a/.travis.yml b/.travis.yml
index 6c870d8797..2237ca85d9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,7 @@ env:
- "GEM=ar:sqlite3"
- "GEM=ar:postgresql"
- "GEM=aj:integration"
+ - "GEM=guides"
rvm:
- 2.2.2
- ruby-head
diff --git a/Gemfile.lock b/Gemfile.lock
index 6c900835cb..3cc20f1c9c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -308,4 +308,4 @@ DEPENDENCIES
w3c_validators
BUNDLED WITH
- 1.10.1
+ 1.10.2
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md
index acdc4c7dc9..7c1b0b215a 100644
--- a/actionmailer/CHANGELOG.md
+++ b/actionmailer/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Add `config.action_mailer.deliver_later_queue_name` configuration to set the
+ mailer queue name.
+
+ *Chris McGrath*
+
* `assert_emails` in block form use the given number as expected value.
This makes the error message much easier to understand.
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 4a5229fe18..3c522ce707 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -413,6 +413,8 @@ module ActionMailer
#
# * <tt>deliveries</tt> - Keeps an array of all the emails sent out through the Action Mailer with
# <tt>delivery_method :test</tt>. Most useful for unit and functional testing.
+ #
+ # * <tt>deliver_later_queue_name</tt> - The name of the queue used with <tt>deliver_later</tt>
class Base < AbstractController::Base
include DeliveryMethods
include Previews
diff --git a/actionmailer/lib/action_mailer/delivery_job.rb b/actionmailer/lib/action_mailer/delivery_job.rb
index e864ab7a4d..52772af2d3 100644
--- a/actionmailer/lib/action_mailer/delivery_job.rb
+++ b/actionmailer/lib/action_mailer/delivery_job.rb
@@ -4,7 +4,7 @@ module ActionMailer
# The <tt>ActionMailer::DeliveryJob</tt> class is used when you
# want to send emails outside of the request-response cycle.
class DeliveryJob < ActiveJob::Base # :nodoc:
- queue_as :mailers
+ queue_as { ActionMailer::Base.deliver_later_queue_name }
def perform(mailer, mail_method, delivery_method, *args) #:nodoc:
mailer.constantize.public_send(mail_method, *args).send(delivery_method)
diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb
index aedcd81e52..4758b55a2a 100644
--- a/actionmailer/lib/action_mailer/delivery_methods.rb
+++ b/actionmailer/lib/action_mailer/delivery_methods.rb
@@ -16,6 +16,9 @@ module ActionMailer
cattr_accessor :perform_deliveries
self.perform_deliveries = true
+ cattr_accessor :deliver_later_queue_name
+ self.deliver_later_queue_name = :mailers
+
self.delivery_methods = {}.freeze
self.delivery_method = :smtp
diff --git a/actionmailer/test/message_delivery_test.rb b/actionmailer/test/message_delivery_test.rb
index aaa3f218b5..862ce26187 100644
--- a/actionmailer/test/message_delivery_test.rb
+++ b/actionmailer/test/message_delivery_test.rb
@@ -9,6 +9,8 @@ class MessageDeliveryTest < ActiveSupport::TestCase
setup do
@previous_logger = ActiveJob::Base.logger
@previous_delivery_method = ActionMailer::Base.delivery_method
+ @previous_deliver_later_queue_name = ActionMailer::Base.deliver_later_queue_name
+ ActionMailer::Base.deliver_later_queue_name = :test_queue
ActionMailer::Base.delivery_method = :test
ActiveJob::Base.logger = Logger.new(nil)
@mail = DelayedMailer.test_message(1, 2, 3)
@@ -20,6 +22,7 @@ class MessageDeliveryTest < ActiveSupport::TestCase
teardown do
ActiveJob::Base.logger = @previous_logger
ActionMailer::Base.delivery_method = @previous_delivery_method
+ ActionMailer::Base.deliver_later_queue_name = @previous_deliver_later_queue_name
end
test 'should have a message' do
@@ -80,4 +83,15 @@ class MessageDeliveryTest < ActiveSupport::TestCase
end
end
+ test 'should enqueue the job on the correct queue' do
+ assert_performed_with(job: ActionMailer::DeliveryJob, args: ['DelayedMailer', 'test_message', 'deliver_now', 1, 2, 3], queue: "test_queue") do
+ @mail.deliver_later
+ end
+ end
+
+ test 'can override the queue when enqueuing mail' do
+ assert_performed_with(job: ActionMailer::DeliveryJob, args: ['DelayedMailer', 'test_message', 'deliver_now', 1, 2, 3], queue: "another_queue") do
+ @mail.deliver_later(queue: :another_queue)
+ end
+ end
end
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 4e26a2a60e..66f1d8c6a6 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Remove `assigns` and `assert_template`. Both methods have been extracted
+ into a gem at https://github.com/rails/rails-controller-testing.
+
+ See #18950.
+
+ *Alan Guo Xiang Tan*
+
* `FileHandler` and `Static` middleware initializers accept `index` argument
to configure the directory index file name. Defaults to `index` (as in
`index.html`).
@@ -62,6 +69,16 @@
*Adam Forsyth*
+* Allow `Bearer` as token-keyword in `Authorization-Header`.
+
+ Aditionally to `Token`, the keyword `Bearer` is acceptable as a keyword
+ for the auth-token. The `Bearer` keyword is described in the original
+ OAuth RFC and used in libraries like Angular-JWT.
+
+ See #19094.
+
+ *Peter Schröder*
+
* Drop request class from RouteSet constructor.
If you would like to use a custom request class, please subclass and implement
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 32c3c9652f..fb0a52b076 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -397,7 +397,7 @@ module ActionController
# RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
module Token
TOKEN_KEY = 'token='
- TOKEN_REGEX = /^Token /
+ TOKEN_REGEX = /^(Token|Bearer) /
AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/
extend self
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index a7bd3622ee..4cb634477e 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -258,7 +258,7 @@ module ActionController #:nodoc:
# Returns true or false if a request is verified. Checks:
#
- # * is it a GET or HEAD request? Gets should be safe and idempotent
+ # * Is it a GET or HEAD request? Gets should be safe and idempotent
# * Does the form_authenticity_token match the given token value from the params?
# * Does the X-CSRF-Token header match the form_authenticity_token
def verified_request?
diff --git a/actionpack/lib/action_controller/template_assertions.rb b/actionpack/lib/action_controller/template_assertions.rb
index 304012d24d..0179f4afcd 100644
--- a/actionpack/lib/action_controller/template_assertions.rb
+++ b/actionpack/lib/action_controller/template_assertions.rb
@@ -1,188 +1,9 @@
module ActionController
module TemplateAssertions
- extend ActiveSupport::Concern
-
- included do
- setup :setup_subscriptions
- teardown :teardown_subscriptions
- end
-
- RENDER_TEMPLATE_INSTANCE_VARIABLES = %w{partials templates layouts files}.freeze
-
- def setup_subscriptions
- RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
- instance_variable_set("@_#{instance_variable}", Hash.new(0))
- end
-
- @_subscribers = []
-
- @_subscribers << ActiveSupport::Notifications.subscribe("render_template.action_view") do |_name, _start, _finish, _id, payload|
- path = payload[:layout]
- if path
- @_layouts[path] += 1
- if path =~ /^layouts\/(.*)/
- @_layouts[$1] += 1
- end
- end
- end
-
- @_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload|
- if virtual_path = payload[:virtual_path]
- partial = virtual_path =~ /^.*\/_[^\/]*$/
-
- if partial
- @_partials[virtual_path] += 1
- @_partials[virtual_path.split("/").last] += 1
- end
-
- @_templates[virtual_path] += 1
- else
- path = payload[:identifier]
- if path
- @_files[path] += 1
- @_files[path.split("/").last] += 1
- end
- end
- end
- end
-
- def teardown_subscriptions
- @_subscribers.each do |subscriber|
- ActiveSupport::Notifications.unsubscribe(subscriber)
- end
- end
-
- def process(*args)
- reset_template_assertion
- super
- end
-
- def reset_template_assertion
- RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
- ivar_name = "@_#{instance_variable}"
- if instance_variable_defined?(ivar_name)
- instance_variable_get(ivar_name).clear
- end
- end
- end
-
- # Asserts that the request was rendered with the appropriate template file or partials.
- #
- # # assert that the "new" view template was rendered
- # assert_template "new"
- #
- # # assert that the exact template "admin/posts/new" was rendered
- # assert_template %r{\Aadmin/posts/new\Z}
- #
- # # assert that the layout 'admin' was rendered
- # assert_template layout: 'admin'
- # assert_template layout: 'layouts/admin'
- # assert_template layout: :admin
- #
- # # assert that no layout was rendered
- # assert_template layout: nil
- # assert_template layout: false
- #
- # # assert that the "_customer" partial was rendered twice
- # assert_template partial: '_customer', count: 2
- #
- # # assert that no partials were rendered
- # assert_template partial: false
- #
- # # assert that a file was rendered
- # assert_template file: "README.rdoc"
- #
- # # assert that no file was rendered
- # assert_template file: nil
- # assert_template file: false
- #
- # In a view test case, you can also assert that specific locals are passed
- # to partials:
- #
- # # assert that the "_customer" partial was rendered with a specific object
- # assert_template partial: '_customer', locals: { customer: @customer }
def assert_template(options = {}, message = nil)
- # Force body to be read in case the template is being streamed.
- response.body
-
- case options
- when NilClass, Regexp, String, Symbol
- options = options.to_s if Symbol === options
- rendered = @_templates
- msg = message || sprintf("expecting <%s> but rendering with <%s>",
- options.inspect, rendered.keys)
- matches_template =
- case options
- when String
- !options.empty? && rendered.any? do |t, num|
- options_splited = options.split(File::SEPARATOR)
- t_splited = t.split(File::SEPARATOR)
- t_splited.last(options_splited.size) == options_splited
- end
- when Regexp
- rendered.any? { |t,num| t.match(options) }
- when NilClass
- rendered.blank?
- end
- assert matches_template, msg
- when Hash
- options.assert_valid_keys(:layout, :partial, :locals, :count, :file)
-
- if options.key?(:layout)
- expected_layout = options[:layout]
- msg = message || sprintf("expecting layout <%s> but action rendered <%s>",
- expected_layout, @_layouts.keys)
-
- case expected_layout
- when String, Symbol
- assert_includes @_layouts.keys, expected_layout.to_s, msg
- when Regexp
- assert(@_layouts.keys.any? {|l| l =~ expected_layout }, msg)
- when nil, false
- assert(@_layouts.empty?, msg)
- else
- raise ArgumentError, "assert_template only accepts a String, Symbol, Regexp, nil or false for :layout"
- end
- end
-
- if options[:file]
- assert_includes @_files.keys, options[:file]
- elsif options.key?(:file)
- assert @_files.blank?, "expected no files but #{@_files.keys} was rendered"
- end
-
- if expected_partial = options[:partial]
- if expected_locals = options[:locals]
- if defined?(@_rendered_views)
- view = expected_partial.to_s.sub(/^_/, '').sub(/\/_(?=[^\/]+\z)/, '/')
-
- partial_was_not_rendered_msg = "expected %s to be rendered but it was not." % view
- assert_includes @_rendered_views.rendered_views, view, partial_was_not_rendered_msg
-
- msg = 'expecting %s to be rendered with %s but was with %s' % [expected_partial,
- expected_locals,
- @_rendered_views.locals_for(view)]
- assert(@_rendered_views.view_rendered?(view, options[:locals]), msg)
- else
- warn "the :locals option to #assert_template is only supported in a ActionView::TestCase"
- end
- elsif expected_count = options[:count]
- actual_count = @_partials[expected_partial]
- msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
- expected_partial, expected_count, actual_count)
- assert(actual_count == expected_count.to_i, msg)
- else
- msg = message || sprintf("expecting partial <%s> but action rendered <%s>",
- options[:partial], @_partials.keys)
- assert_includes @_partials, expected_partial, msg
- end
- elsif options.key?(:partial)
- assert @_partials.empty?,
- "Expected no partials to be rendered"
- end
- else
- raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil"
- end
+ raise NoMethodError,
+ "assert_template has been extracted to a gem. To continue using it,
+ add `gem 'rails-controller-testing'` to your Gemfile."
end
end
end
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index bd88b20cea..d34149143f 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -218,21 +218,15 @@ module ActionController
# In addition to these specific assertions, you also have easy access to various collections that the regular test/unit assertions
# can be used against. These collections are:
#
- # * assigns: Instance variables assigned in the action that are available for the view.
# * session: Objects being saved in the session.
# * flash: The flash objects currently in the session.
# * cookies: \Cookies being sent to the user on this request.
#
# These collections can be used just like any other hash:
#
- # assert_not_nil assigns(:person) # makes sure that a @person instance variable was set
# assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave"
# assert flash.empty? # makes sure that there's nothing in the flash
#
- # For historic reasons, the assigns hash uses string-based keys. So <tt>assigns[:person]</tt> won't work, but <tt>assigns["person"]</tt> will. To
- # appease our yearning for symbols, though, an alternative accessor has been devised using a method call instead of index referencing.
- # So <tt>assigns(:person)</tt> will work just like <tt>assigns["person"]</tt>, but again, <tt>assigns[:person]</tt> will not work.
- #
# On top of the collections, you have the complete url that a given action redirected to available in <tt>redirect_to_url</tt>.
#
# For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another
@@ -556,7 +550,7 @@ module ActionController
args.first.merge!(method: http_method)
process(action, *args)
else
- non_kwarg_request_warning if args.present?
+ non_kwarg_request_warning if args.any?
args = args.unshift(http_method)
process(action, *args)
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index fe83c01562..3c62c055e5 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -228,7 +228,7 @@ module ActionDispatch
alias_method :uuid, :request_id
- def x_request_id # :nodoc
+ def x_request_id # :nodoc:
@env[HTTP_X_REQUEST_ID]
end
@@ -259,7 +259,7 @@ module ActionDispatch
end
end
- # returns true if request content mime type is
+ # Returns true if the request's content MIME type is
# +application/x-www-form-urlencoded+ or +multipart/form-data+.
def form_data?
FORM_DATA_MEDIA_TYPES.include?(content_mime_type.to_s)
diff --git a/actionpack/lib/action_dispatch/journey/router/utils.rb b/actionpack/lib/action_dispatch/journey/router/utils.rb
index 2b0a6575d4..d02ed96d0d 100644
--- a/actionpack/lib/action_dispatch/journey/router/utils.rb
+++ b/actionpack/lib/action_dispatch/journey/router/utils.rb
@@ -55,7 +55,7 @@ module ActionDispatch
def unescape_uri(uri)
encoding = uri.encoding == US_ASCII ? UTF_8 : uri.encoding
- uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(encoding)
+ uri.gsub(ESCAPED) { |match| [match[1, 2].hex].pack('C') }.force_encoding(encoding)
end
protected
diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb
index 7c4236518d..9f894e2ec6 100644
--- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb
+++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb
@@ -74,7 +74,7 @@ module ActionDispatch
# requests. For those requests that do need to know the IP, the
# GetIp#calculate_ip method will calculate the memoized client IP address.
def call(env)
- env["action_dispatch.remote_ip"] = GetIp.new(env, self)
+ env["action_dispatch.remote_ip"] = GetIp.new(env, check_ip, proxies)
@app.call(env)
end
@@ -82,10 +82,10 @@ module ActionDispatch
# into an actual IP address. If the ActionDispatch::Request#remote_ip method
# is called, this class will calculate the value and then memoize it.
class GetIp
- def initialize(env, middleware)
+ def initialize(env, check_ip, proxies)
@env = env
- @check_ip = middleware.check_ip
- @proxies = middleware.proxies
+ @check_ip = check_ip
+ @proxies = proxies
end
# Sort through the various IP address headers, looking for the IP most
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
index f20f6ca865..3aa0eef4ad 100644
--- a/actionpack/lib/action_dispatch/middleware/static.rb
+++ b/actionpack/lib/action_dispatch/middleware/static.rb
@@ -13,7 +13,7 @@ module ActionDispatch
# located at `public/assets/application.js` if the file exists. If the file
# does not exist, a 404 "File not Found" response will be returned.
class FileHandler
- def initialize(root, cache_control, index)
+ def initialize(root, cache_control, index = 'index')
@root = root.chomp('/')
@compiled_root = /^#{Regexp.escape(root)}/
headers = cache_control && { 'Cache-Control' => cache_control }
@@ -105,7 +105,7 @@ module ActionDispatch
# produce a directory traversal using this middleware. Only 'GET' and 'HEAD'
# requests will result in a file being returned.
class Static
- def initialize(app, path, cache_control=nil, index="index")
+ def initialize(app, path, cache_control = nil, index = 'index')
@app = app
@file_handler = FileHandler.new(path, cache_control, index)
end
@@ -115,7 +115,7 @@ module ActionDispatch
when 'GET', 'HEAD'
path = env['PATH_INFO'].chomp('/')
if match = @file_handler.match?(path)
- env["PATH_INFO"] = match
+ env['PATH_INFO'] = match
return @file_handler.call(env)
end
end
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index ce03164ca9..a42cf72f60 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -232,7 +232,6 @@ module ActionDispatch
# def send_to_jail
# get '/jail'
# assert_response :success
- # assert_template "jail/front"
# end
#
# def goes_to_login
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index f953429e96..dc664d5540 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -294,7 +294,7 @@ module ActionDispatch
if kwarg_request?(args)
process(http_method, path, *args)
else
- non_kwarg_request_warning if args.present?
+ non_kwarg_request_warning if args.any?
process(http_method, path, { params: args[0], headers: args[1] })
end
end
@@ -429,7 +429,6 @@ module ActionDispatch
# reset the html_document variable, except for cookies/assigns calls
unless method == 'cookies' || method == 'assigns'
@html_document = nil
- reset_template_assertion
end
integration_session.__send__(method, *args).tap do
diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb
index 630e6a9b78..415ef80cd2 100644
--- a/actionpack/lib/action_dispatch/testing/test_process.rb
+++ b/actionpack/lib/action_dispatch/testing/test_process.rb
@@ -5,9 +5,9 @@ require 'active_support/core_ext/hash/indifferent_access'
module ActionDispatch
module TestProcess
def assigns(key = nil)
- assigns = {}.with_indifferent_access
- @controller.view_assigns.each { |k, v| assigns.regular_writer(k, v) }
- key.nil? ? assigns : assigns[key]
+ raise NoMethodError,
+ "assigns has been extracted to a gem. To continue using it,
+ add `gem 'rails-controller-testing'` to your Gemfile."
end
def session
diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb
index cbf333c772..5b85e83045 100644
--- a/actionpack/test/controller/action_pack_assertions_test.rb
+++ b/actionpack/test/controller/action_pack_assertions_test.rb
@@ -5,9 +5,6 @@ class ActionPackAssertionsController < ActionController::Base
def nothing() head :ok end
- def hello_world() render :template => "test/hello_world"; end
- def hello_repeating_in_path() render :template => "test/hello/hello"; end
-
def hello_xml_world() render :template => "test/hello_xml_world"; end
def hello_xml_world_pdf
@@ -20,8 +17,6 @@ class ActionPackAssertionsController < ActionController::Base
render :template => "test/hello_xml_world"
end
- def partial() render :partial => 'test/partial'; end
-
def redirect_internal() redirect_to "/nothing"; end
def redirect_to_action() redirect_to :action => "flash_me", :id => 1, :params => { "panda" => "fun" }; end
@@ -73,16 +68,6 @@ class ActionPackAssertionsController < ActionController::Base
render :text => "Hello!", :content_type => Mime::RSS
end
- def render_with_layout
- @variable_for_layout = nil
- render "test/hello_world", :layout => "layouts/standard"
- end
-
- def render_with_layout_and_partial
- @variable_for_layout = nil
- render "test/hello_world_with_partial", :layout => "layouts/standard"
- end
-
def session_stuffing
session['xmas'] = 'turkey'
render :text => "ho ho ho"
@@ -304,14 +289,6 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
assert session.empty?
end
- def test_render_template_action
- process :nothing
- assert_template nil
-
- process :hello_world
- assert_template 'hello_world'
- end
-
def test_redirection_location
process :redirect_internal
assert_equal 'http://test.host/nothing', @response.redirect_url
@@ -455,192 +432,6 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
end
end
-class AssertTemplateTest < ActionController::TestCase
- tests ActionPackAssertionsController
-
- def test_with_invalid_hash_keys_raises_argument_error
- assert_raise(ArgumentError) do
- assert_template foo: "bar"
- end
- end
-
- def test_with_partial
- get :partial
- assert_template :partial => '_partial'
- end
-
- def test_file_with_absolute_path_success
- get :render_file_absolute_path
- assert_template :file => File.expand_path('../../../README.rdoc', __FILE__)
- end
-
- def test_file_with_relative_path_success
- get :render_file_relative_path
- assert_template :file => 'README.rdoc'
- end
-
- def test_with_file_failure
- get :render_file_absolute_path
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template :file => 'test/hello_world'
- end
-
- get :render_file_absolute_path
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template file: nil
- end
- end
-
- def test_with_nil_passes_when_no_template_rendered
- get :nothing
- assert_template nil
- end
-
- def test_with_nil_fails_when_template_rendered
- get :hello_world
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template nil
- end
- end
-
- def test_with_empty_string_fails_when_template_rendered
- get :hello_world
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template ""
- end
- end
-
- def test_with_empty_string_fails_when_no_template_rendered
- get :nothing
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template ""
- end
- end
-
- def test_passes_with_correct_string
- get :hello_world
- assert_template 'hello_world'
- assert_template 'test/hello_world'
- end
-
- def test_passes_with_correct_symbol
- get :hello_world
- assert_template :hello_world
- end
-
- def test_fails_with_incorrect_string
- get :hello_world
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template 'hello_planet'
- end
- end
-
- def test_fails_with_incorrect_string_that_matches
- get :hello_world
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template 'est/he'
- end
- end
-
- def test_fails_with_repeated_name_in_path
- get :hello_repeating_in_path
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template 'test/hello'
- end
- end
-
- def test_fails_with_incorrect_symbol
- get :hello_world
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template :hello_planet
- end
- end
-
- def test_fails_with_incorrect_symbol_that_matches
- get :hello_world
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template :"est/he"
- end
- end
-
- def test_fails_with_wrong_layout
- get :render_with_layout
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template :layout => "application"
- end
- end
-
- def test_fails_expecting_no_layout
- get :render_with_layout
- assert_raise(ActiveSupport::TestCase::Assertion) do
- assert_template :layout => nil
- end
- end
-
- def test_fails_expecting_not_known_layout
- get :render_with_layout
- assert_raise(ArgumentError) do
- assert_template :layout => 1
- end
- end
-
- def test_passes_with_correct_layout
- get :render_with_layout
- assert_template :layout => "layouts/standard"
- end
-
- def test_passes_with_layout_and_partial
- get :render_with_layout_and_partial
- assert_template :layout => "layouts/standard"
- end
-
- def test_passed_with_no_layout
- get :hello_world
- assert_template :layout => nil
- end
-
- def test_passed_with_no_layout_false
- get :hello_world
- assert_template :layout => false
- end
-
- def test_passes_with_correct_layout_without_layouts_prefix
- get :render_with_layout
- assert_template :layout => "standard"
- end
-
- def test_passes_with_correct_layout_symbol
- get :render_with_layout
- assert_template :layout => :standard
- end
-
- def test_assert_template_reset_between_requests
- get :hello_world
- assert_template 'test/hello_world'
-
- get :nothing
- assert_template nil
-
- get :partial
- assert_template partial: 'test/_partial'
-
- get :nothing
- assert_template partial: nil
-
- get :render_with_layout
- assert_template layout: 'layouts/standard'
-
- get :nothing
- assert_template layout: nil
-
- get :render_file_relative_path
- assert_template file: 'README.rdoc'
-
- get :nothing
- assert_template file: nil
- end
-end
-
class ActionPackHeaderTest < ActionController::TestCase
tests ActionPackAssertionsController
diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb
index 2d6607041d..de697858c3 100644
--- a/actionpack/test/controller/caching_test.rb
+++ b/actionpack/test/controller/caching_test.rb
@@ -352,6 +352,8 @@ class ViewCacheDependencyTest < ActionController::TestCase
end
class CollectionCacheController < ActionController::Base
+ attr_accessor :partial_rendered_times
+
def index
@customers = [Customer.new('david', params[:id] || 1)]
end
@@ -377,14 +379,15 @@ class AutomaticCollectionCacheTest < ActionController::TestCase
super
@controller = CollectionCacheController.new
@controller.perform_caching = true
- @controller.cache_store = ActiveSupport::Cache::MemoryStore.new
+ @controller.partial_rendered_times = 0
end
def test_collection_fetches_cached_views
get :index
+ assert_equal 1, @controller.partial_rendered_times
- ActionView::PartialRenderer.expects(:collection_with_template).never
get :index
+ assert_equal 1, @controller.partial_rendered_times
end
def test_preserves_order_when_reading_from_cache_plus_rendering
@@ -402,8 +405,9 @@ class AutomaticCollectionCacheTest < ActionController::TestCase
def test_caching_works_with_beginning_comment
get :index_with_comment
+ assert_equal 1, @controller.partial_rendered_times
- ActionView::PartialRenderer.expects(:collection_with_template).never
get :index_with_comment
+ assert_equal 1, @controller.partial_rendered_times
end
end
diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb
index a1ce12a13e..9b0487841f 100644
--- a/actionpack/test/controller/filters_test.rb
+++ b/actionpack/test/controller/filters_test.rb
@@ -13,16 +13,6 @@ class ActionController::Base
filters.map!(&:raw_filter)
end
end
-
- def assigns(key = nil)
- assigns = {}
- instance_variables.each do |ivar|
- next if ActionController::Base.protected_instance_variables.include?(ivar)
- assigns[ivar[1..-1]] = instance_variable_get(ivar)
- end
-
- key.nil? ? assigns : assigns[key.to_s]
- end
end
class FilterTest < ActionController::TestCase
@@ -560,7 +550,7 @@ class FilterTest < ActionController::TestCase
def test_after_actions_are_not_run_if_around_action_does_not_yield
controller = NonYieldingAroundFilterController.new
test_process(controller, "index")
- assert_equal ["filter_one", "it didn't yield"], controller.assigns['filters']
+ assert_equal ["filter_one", "it didn't yield"], controller.instance_variable_get(:@filters)
end
def test_added_action_to_inheritance_graph
@@ -577,140 +567,141 @@ class FilterTest < ActionController::TestCase
def test_running_actions
test_process(PrependingController)
- assert_equal %w( wonderful_life ensure_login ), assigns["ran_filter"]
+ assert_equal %w( wonderful_life ensure_login ),
+ @controller.instance_variable_get(:@ran_filter)
end
def test_running_actions_with_proc
test_process(ProcController)
- assert assigns["ran_proc_action"]
+ assert @controller.instance_variable_get(:@ran_proc_action)
end
def test_running_actions_with_implicit_proc
test_process(ImplicitProcController)
- assert assigns["ran_proc_action"]
+ assert @controller.instance_variable_get(:@ran_proc_action)
end
def test_running_actions_with_class
test_process(AuditController)
- assert assigns["was_audited"]
+ assert @controller.instance_variable_get(:@was_audited)
end
def test_running_anomolous_yet_valid_condition_actions
test_process(AnomolousYetValidConditionController)
- assert_equal %w( ensure_login ), assigns["ran_filter"]
- assert assigns["ran_class_action"]
- assert assigns["ran_proc_action1"]
- assert assigns["ran_proc_action2"]
+ assert_equal %w( ensure_login ), @controller.instance_variable_get(:@ran_filter)
+ assert @controller.instance_variable_get(:@ran_class_action)
+ assert @controller.instance_variable_get(:@ran_proc_action1)
+ assert @controller.instance_variable_get(:@ran_proc_action2)
test_process(AnomolousYetValidConditionController, "show_without_action")
- assert_nil assigns["ran_filter"]
- assert !assigns["ran_class_action"]
- assert !assigns["ran_proc_action1"]
- assert !assigns["ran_proc_action2"]
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
+ assert_not @controller.instance_variable_defined?(:@ran_class_action)
+ assert_not @controller.instance_variable_defined?(:@ran_proc_action1)
+ assert_not @controller.instance_variable_defined?(:@ran_proc_action2)
end
def test_running_conditional_options
test_process(ConditionalOptionsFilter)
- assert_equal %w( ensure_login ), assigns["ran_filter"]
+ assert_equal %w( ensure_login ), @controller.instance_variable_get(:@ran_filter)
end
def test_running_conditional_skip_options
test_process(ConditionalOptionsSkipFilter)
- assert_equal %w( ensure_login ), assigns["ran_filter"]
+ assert_equal %w( ensure_login ), @controller.instance_variable_get(:@ran_filter)
end
def test_if_is_ignored_when_used_with_only
test_process(SkipFilterUsingOnlyAndIf, 'login')
- assert_nil assigns['ran_filter']
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
end
def test_except_is_ignored_when_used_with_if
test_process(SkipFilterUsingIfAndExcept, 'login')
- assert_equal %w(ensure_login), assigns["ran_filter"]
+ assert_equal %w(ensure_login), @controller.instance_variable_get(:@ran_filter)
end
def test_skipping_class_actions
test_process(ClassController)
- assert_equal true, assigns["ran_class_action"]
+ assert_equal true, @controller.instance_variable_get(:@ran_class_action)
skipping_class_controller = Class.new(ClassController) do
skip_before_action ConditionalClassFilter
end
test_process(skipping_class_controller)
- assert_nil assigns['ran_class_action']
+ assert_not @controller.instance_variable_defined?(:@ran_class_action)
end
def test_running_collection_condition_actions
test_process(ConditionalCollectionFilterController)
- assert_equal %w( ensure_login ), assigns["ran_filter"]
+ assert_equal %w( ensure_login ), @controller.instance_variable_get(:@ran_filter)
test_process(ConditionalCollectionFilterController, "show_without_action")
- assert_nil assigns["ran_filter"]
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
test_process(ConditionalCollectionFilterController, "another_action")
- assert_nil assigns["ran_filter"]
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
end
def test_running_only_condition_actions
test_process(OnlyConditionSymController)
- assert_equal %w( ensure_login ), assigns["ran_filter"]
+ assert_equal %w( ensure_login ), @controller.instance_variable_get(:@ran_filter)
test_process(OnlyConditionSymController, "show_without_action")
- assert_nil assigns["ran_filter"]
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
test_process(OnlyConditionProcController)
- assert assigns["ran_proc_action"]
+ assert @controller.instance_variable_get(:@ran_proc_action)
test_process(OnlyConditionProcController, "show_without_action")
- assert !assigns["ran_proc_action"]
+ assert_not @controller.instance_variable_defined?(:@ran_proc_action)
test_process(OnlyConditionClassController)
- assert assigns["ran_class_action"]
+ assert @controller.instance_variable_get(:@ran_class_action)
test_process(OnlyConditionClassController, "show_without_action")
- assert !assigns["ran_class_action"]
+ assert_not @controller.instance_variable_defined?(:@ran_class_action)
end
def test_running_except_condition_actions
test_process(ExceptConditionSymController)
- assert_equal %w( ensure_login ), assigns["ran_filter"]
+ assert_equal %w( ensure_login ), @controller.instance_variable_get(:@ran_filter)
test_process(ExceptConditionSymController, "show_without_action")
- assert_nil assigns["ran_filter"]
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
test_process(ExceptConditionProcController)
- assert assigns["ran_proc_action"]
+ assert @controller.instance_variable_get(:@ran_proc_action)
test_process(ExceptConditionProcController, "show_without_action")
- assert !assigns["ran_proc_action"]
+ assert_not @controller.instance_variable_defined?(:@ran_proc_action)
test_process(ExceptConditionClassController)
- assert assigns["ran_class_action"]
+ assert @controller.instance_variable_get(:@ran_class_action)
test_process(ExceptConditionClassController, "show_without_action")
- assert !assigns["ran_class_action"]
+ assert_not @controller.instance_variable_defined?(:@ran_class_action)
end
def test_running_only_condition_and_conditional_options
test_process(OnlyConditionalOptionsFilter, "show")
- assert_not assigns["ran_conditional_index_proc"]
+ assert_not @controller.instance_variable_defined?(:@ran_conditional_index_proc)
end
def test_running_before_and_after_condition_actions
test_process(BeforeAndAfterConditionController)
- assert_equal %w( ensure_login clean_up_tmp), assigns["ran_filter"]
+ assert_equal %w( ensure_login clean_up_tmp), @controller.instance_variable_get(:@ran_filter)
test_process(BeforeAndAfterConditionController, "show_without_action")
- assert_nil assigns["ran_filter"]
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
end
def test_around_action
test_process(AroundFilterController)
- assert assigns["before_ran"]
- assert assigns["after_ran"]
+ assert @controller.instance_variable_get(:@before_ran)
+ assert @controller.instance_variable_get(:@after_ran)
end
def test_before_after_class_action
test_process(BeforeAfterClassFilterController)
- assert assigns["before_ran"]
- assert assigns["after_ran"]
+ assert @controller.instance_variable_get(:@before_ran)
+ assert @controller.instance_variable_get(:@after_ran)
end
def test_having_properties_in_around_action
test_process(AroundFilterController)
- assert_equal "before and after", assigns["execution_log"]
+ assert_equal "before and after", @controller.instance_variable_get(:@execution_log)
end
def test_prepending_and_appending_around_action
@@ -723,33 +714,33 @@ class FilterTest < ActionController::TestCase
def test_rendering_breaks_actioning_chain
response = test_process(RenderingController)
assert_equal "something else", response.body
- assert !assigns["ran_action"]
+ assert_not @controller.instance_variable_defined?(:@ran_action)
end
def test_before_action_rendering_breaks_actioning_chain_for_after_action
test_process(RenderingController)
- assert_equal %w( before_action_rendering ), assigns["ran_filter"]
- assert !assigns["ran_action"]
+ assert_equal %w( before_action_rendering ), @controller.instance_variable_get(:@ran_filter)
+ assert_not @controller.instance_variable_defined?(:@ran_action)
end
def test_before_action_redirects_breaks_actioning_chain_for_after_action
test_process(BeforeActionRedirectionController)
assert_response :redirect
assert_equal "http://test.host/filter_test/before_action_redirection/target_of_redirection", redirect_to_url
- assert_equal %w( before_action_redirects ), assigns["ran_filter"]
+ assert_equal %w( before_action_redirects ), @controller.instance_variable_get(:@ran_filter)
end
def test_before_action_rendering_breaks_actioning_chain_for_preprend_after_action
test_process(RenderingForPrependAfterActionController)
- assert_equal %w( before_action_rendering ), assigns["ran_filter"]
- assert !assigns["ran_action"]
+ assert_equal %w( before_action_rendering ), @controller.instance_variable_get(:@ran_filter)
+ assert_not @controller.instance_variable_defined?(:@ran_action)
end
def test_before_action_redirects_breaks_actioning_chain_for_preprend_after_action
test_process(BeforeActionRedirectionForPrependAfterActionController)
assert_response :redirect
assert_equal "http://test.host/filter_test/before_action_redirection_for_prepend_after_action/target_of_redirection", redirect_to_url
- assert_equal %w( before_action_redirects ), assigns["ran_filter"]
+ assert_equal %w( before_action_redirects ), @controller.instance_variable_get(:@ran_filter)
end
def test_actions_with_mixed_specialization_run_in_order
@@ -775,26 +766,26 @@ class FilterTest < ActionController::TestCase
def test_running_prepended_before_and_after_action
test_process(PrependingBeforeAndAfterController)
- assert_equal %w( before_all between_before_all_and_after_all after_all ), assigns["ran_filter"]
+ assert_equal %w( before_all between_before_all_and_after_all after_all ), @controller.instance_variable_get(:@ran_filter)
end
def test_skipping_and_limiting_controller
test_process(SkippingAndLimitedController, "index")
- assert_equal %w( ensure_login ), assigns["ran_filter"]
+ assert_equal %w( ensure_login ), @controller.instance_variable_get(:@ran_filter)
test_process(SkippingAndLimitedController, "public")
- assert_nil assigns["ran_filter"]
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
end
def test_skipping_and_reordering_controller
test_process(SkippingAndReorderingController, "index")
- assert_equal %w( find_record ensure_login ), assigns["ran_filter"]
+ assert_equal %w( find_record ensure_login ), @controller.instance_variable_get(:@ran_filter)
end
def test_conditional_skipping_of_actions
test_process(ConditionalSkippingController, "login")
- assert_nil assigns["ran_filter"]
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
test_process(ConditionalSkippingController, "change_password")
- assert_equal %w( ensure_login find_user ), assigns["ran_filter"]
+ assert_equal %w( ensure_login find_user ), @controller.instance_variable_get(:@ran_filter)
test_process(ConditionalSkippingController, "login")
assert !@controller.instance_variable_defined?("@ran_after_action")
@@ -804,23 +795,23 @@ class FilterTest < ActionController::TestCase
def test_conditional_skipping_of_actions_when_parent_action_is_also_conditional
test_process(ChildOfConditionalParentController)
- assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), assigns['ran_filter']
+ assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), @controller.instance_variable_get(:@ran_filter)
test_process(ChildOfConditionalParentController, 'another_action')
- assert_nil assigns['ran_filter']
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
end
def test_condition_skipping_of_actions_when_siblings_also_have_conditions
test_process(ChildOfConditionalParentController)
- assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), assigns['ran_filter']
+ assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), @controller.instance_variable_get(:@ran_filter)
test_process(AnotherChildOfConditionalParentController)
- assert_equal %w( conditional_in_parent_after ), assigns['ran_filter']
+ assert_equal %w( conditional_in_parent_after ), @controller.instance_variable_get(:@ran_filter)
test_process(ChildOfConditionalParentController)
- assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), assigns['ran_filter']
+ assert_equal %w( conditional_in_parent_before conditional_in_parent_after ), @controller.instance_variable_get(:@ran_filter)
end
def test_changing_the_requirements
test_process(ChangingTheRequirementsController, "go_wild")
- assert_nil assigns['ran_filter']
+ assert_not @controller.instance_variable_defined?(:@ran_filter)
end
def test_a_rescuing_around_action
@@ -835,13 +826,13 @@ class FilterTest < ActionController::TestCase
def test_actions_obey_only_and_except_for_implicit_actions
test_process(ImplicitActionsController, 'show')
- assert_equal 'Except', assigns(:except)
- assert_nil assigns(:only)
+ assert_equal 'Except', @controller.instance_variable_get(:@except)
+ assert_not @controller.instance_variable_defined?(:@only)
assert_equal 'show', response.body
test_process(ImplicitActionsController, 'edit')
- assert_equal 'Only', assigns(:only)
- assert_nil assigns(:except)
+ assert_equal 'Only', @controller.instance_variable_get(:@only)
+ assert_not @controller.instance_variable_defined?(:@except)
assert_equal 'edit', response.body
end
@@ -1010,8 +1001,8 @@ class YieldingAroundFiltersTest < ActionController::TestCase
def test_with_proc
test_process(ControllerWithProcFilter,'no_raise')
- assert assigns['before']
- assert assigns['after']
+ assert @controller.instance_variable_get(:@before)
+ assert @controller.instance_variable_get(:@after)
end
def test_nested_actions
@@ -1032,12 +1023,12 @@ class YieldingAroundFiltersTest < ActionController::TestCase
def test_action_order_with_all_action_types
test_process(ControllerWithAllTypesOfFilters,'no_raise')
- assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) after around (after yield)', assigns['ran_filter'].join(' ')
+ assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) after around (after yield)', @controller.instance_variable_get(:@ran_filter).join(' ')
end
def test_action_order_with_skip_action_method
test_process(ControllerWithTwoLessFilters,'no_raise')
- assert_equal 'before around (before yield) around (after yield)', assigns['ran_filter'].join(' ')
+ assert_equal 'before around (before yield) around (after yield)', @controller.instance_variable_get(:@ran_filter).join(' ')
end
def test_first_action_in_multiple_before_action_chain_halts
@@ -1063,7 +1054,7 @@ class YieldingAroundFiltersTest < ActionController::TestCase
def test_skipping_with_skip_action_callback
test_process(SkipFilterUsingSkipActionCallback,'no_raise')
- assert_equal 'before around (before yield) around (after yield)', assigns['ran_filter'].join(' ')
+ assert_equal 'before around (before yield) around (after yield)', @controller.instance_variable_get(:@ran_filter).join(' ')
end
def test_deprecated_skip_action_callback
diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb
index 60a000c160..64543f0659 100644
--- a/actionpack/test/controller/flash_test.rb
+++ b/actionpack/test/controller/flash_test.rb
@@ -103,54 +103,55 @@ class FlashTest < ActionController::TestCase
get :set_flash
get :use_flash
- assert_equal "hello", assigns["flash_copy"]["that"]
- assert_equal "hello", assigns["flashy"]
+ assert_equal "hello", @controller.instance_variable_get(:@flash_copy)["that"]
+ assert_equal "hello", @controller.instance_variable_get(:@flashy)
get :use_flash
- assert_nil assigns["flash_copy"]["that"], "On second flash"
+ assert_nil @controller.instance_variable_get(:@flash_copy)["that"], "On second flash"
end
def test_keep_flash
get :set_flash
get :use_flash_and_keep_it
- assert_equal "hello", assigns["flash_copy"]["that"]
- assert_equal "hello", assigns["flashy"]
+ assert_equal "hello", @controller.instance_variable_get(:@flash_copy)["that"]
+ assert_equal "hello", @controller.instance_variable_get(:@flashy)
get :use_flash
- assert_equal "hello", assigns["flash_copy"]["that"], "On second flash"
+ assert_equal "hello", @controller.instance_variable_get(:@flash_copy)["that"], "On second flash"
get :use_flash
- assert_nil assigns["flash_copy"]["that"], "On third flash"
+ assert_nil @controller.instance_variable_get(:@flash_copy)["that"], "On third flash"
end
def test_flash_now
get :set_flash_now
- assert_equal "hello", assigns["flash_copy"]["that"]
- assert_equal "bar" , assigns["flash_copy"]["foo"]
- assert_equal "hello", assigns["flashy"]
+ assert_equal "hello", @controller.instance_variable_get(:@flash_copy)["that"]
+ assert_equal "bar", @controller.instance_variable_get(:@flash_copy)["foo"]
+ assert_equal "hello", @controller.instance_variable_get(:@flashy)
get :attempt_to_use_flash_now
- assert_nil assigns["flash_copy"]["that"]
- assert_nil assigns["flash_copy"]["foo"]
- assert_nil assigns["flashy"]
+ assert_nil @controller.instance_variable_get(:@flash_copy)["that"]
+ assert_nil @controller.instance_variable_get(:@flash_copy)["foo"]
+ assert_nil @controller.instance_variable_get(:@flashy)
end
def test_update_flash
get :set_flash
get :use_flash_and_update_it
- assert_equal "hello", assigns["flash_copy"]["that"]
- assert_equal "hello again", assigns["flash_copy"]["this"]
+ assert_equal "hello", @controller.instance_variable_get(:@flash_copy)["that"]
+ assert_equal "hello again", @controller.instance_variable_get(:@flash_copy)["this"]
get :use_flash
- assert_nil assigns["flash_copy"]["that"], "On second flash"
- assert_equal "hello again", assigns["flash_copy"]["this"], "On second flash"
+ assert_nil @controller.instance_variable_get(:@flash_copy)["that"], "On second flash"
+ assert_equal "hello again",
+ @controller.instance_variable_get(:@flash_copy)["this"], "On second flash"
end
def test_flash_after_reset_session
get :use_flash_after_reset_session
- assert_equal "hello", assigns["flashy_that"]
- assert_equal "good-bye", assigns["flashy_this"]
- assert_nil assigns["flashy_that_reset"]
+ assert_equal "hello", @controller.instance_variable_get(:@flashy_that)
+ assert_equal "good-bye", @controller.instance_variable_get(:@flashy_this)
+ assert_nil @controller.instance_variable_get(:@flashy_that_reset)
end
def test_does_not_set_the_session_if_the_flash_is_empty
@@ -160,13 +161,13 @@ class FlashTest < ActionController::TestCase
def test_sweep_after_halted_action_chain
get :std_action
- assert_nil assigns["flash_copy"]["foo"]
+ assert_nil @controller.instance_variable_get(:@flash_copy)["foo"]
get :filter_halting_action
- assert_equal "bar", assigns["flash_copy"]["foo"]
+ assert_equal "bar", @controller.instance_variable_get(:@flash_copy)["foo"]
get :std_action # follow redirection
- assert_equal "bar", assigns["flash_copy"]["foo"]
+ assert_equal "bar", @controller.instance_variable_get(:@flash_copy)["foo"]
get :std_action
- assert_nil assigns["flash_copy"]["foo"]
+ assert_nil @controller.instance_variable_get(:@flash_copy)["foo"]
end
def test_keep_and_discard_return_values
diff --git a/actionpack/test/controller/force_ssl_test.rb b/actionpack/test/controller/force_ssl_test.rb
index 5639abdc56..72ae30eb39 100644
--- a/actionpack/test/controller/force_ssl_test.rb
+++ b/actionpack/test/controller/force_ssl_test.rb
@@ -240,8 +240,8 @@ class ForceSSLFlashTest < ActionController::TestCase
@request.env.delete('PATH_INFO')
get :use_flash
- assert_equal "hello", assigns["flash_copy"]["that"]
- assert_equal "hello", assigns["flashy"]
+ assert_equal "hello", @controller.instance_variable_get("@flash_copy")["that"]
+ assert_equal "hello", @controller.instance_variable_get("@flashy")
end
end
diff --git a/actionpack/test/controller/http_basic_authentication_test.rb b/actionpack/test/controller/http_basic_authentication_test.rb
index 10fbee7582..adaf19c2dc 100644
--- a/actionpack/test/controller/http_basic_authentication_test.rb
+++ b/actionpack/test/controller/http_basic_authentication_test.rb
@@ -13,7 +13,7 @@ class HttpBasicAuthenticationTest < ActionController::TestCase
end
def display
- render :text => 'Definitely Maybe'
+ render :text => 'Definitely Maybe' if @logged_in
end
def show
@@ -122,7 +122,6 @@ class HttpBasicAuthenticationTest < ActionController::TestCase
get :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb
index 52a0bc9aa3..57964769a7 100644
--- a/actionpack/test/controller/http_digest_authentication_test.rb
+++ b/actionpack/test/controller/http_digest_authentication_test.rb
@@ -14,7 +14,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
end
def display
- render :text => 'Definitely Maybe'
+ render :text => 'Definitely Maybe' if @logged_in
end
private
@@ -124,7 +124,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
get :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
@@ -134,7 +133,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
get :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
@@ -144,7 +142,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
get :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
@@ -156,7 +153,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
get :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
@@ -167,7 +163,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
get :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
@@ -180,7 +175,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
get :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
@@ -191,7 +185,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
get :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
@@ -201,7 +194,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
put :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
@@ -244,7 +236,6 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
get :display
assert_response :success
- assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
diff --git a/actionpack/test/controller/http_token_authentication_test.rb b/actionpack/test/controller/http_token_authentication_test.rb
index 2521f0322c..802c17b6bf 100644
--- a/actionpack/test/controller/http_token_authentication_test.rb
+++ b/actionpack/test/controller/http_token_authentication_test.rb
@@ -80,13 +80,20 @@ class HttpTokenAuthenticationTest < ActionController::TestCase
end
test "authentication request with badly formatted header" do
- @request.env['HTTP_AUTHORIZATION'] = "Token foobar"
+ @request.env['HTTP_AUTHORIZATION'] = 'Token token$"lifo"'
get :index
assert_response :unauthorized
assert_equal "HTTP Token: Access denied.\n", @response.body, "Authentication header was not properly parsed"
end
+ test "successful authentication request with Bearer instead of Token" do
+ @request.env['HTTP_AUTHORIZATION'] = 'Bearer lifo'
+ get :index
+
+ assert_response :success
+ end
+
test "authentication request without credential" do
get :display
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index a87059bee4..a6460168cb 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -315,8 +315,6 @@ class IntegrationTestTest < ActiveSupport::TestCase
session1 = @test.open_session { |sess| }
session2 = @test.open_session # implicit session
- assert_respond_to session1, :assert_template, "open_session makes assert_template available"
- assert_respond_to session2, :assert_template, "open_session makes assert_template available"
assert !session1.equal?(session2)
end
diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb
index ef30f1ea0f..4f5ca46b04 100644
--- a/actionpack/test/controller/redirect_test.rb
+++ b/actionpack/test/controller/redirect_test.rb
@@ -50,11 +50,6 @@ class RedirectController < ActionController::Base
redirect_to :controller => 'module_test/module_redirect', :action => "hello_world"
end
- def redirect_with_assigns
- @hello = "world"
- redirect_to :action => "hello_world"
- end
-
def redirect_to_url
redirect_to "http://www.rubyonrails.org/"
end
@@ -215,12 +210,6 @@ class RedirectTest < ActionController::TestCase
assert_redirected_to :controller => 'module_test/module_redirect', :action => 'hello_world'
end
- def test_redirect_with_assigns
- get :redirect_with_assigns
- assert_response :redirect
- assert_equal "world", assigns["hello"]
- end
-
def test_redirect_to_url
get :redirect_to_url
assert_response :redirect
diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb
index fbfc891d19..86ffb898ad 100644
--- a/actionpack/test/controller/test_case_test.rb
+++ b/actionpack/test/controller/test_case_test.rb
@@ -140,12 +140,6 @@ XML
head :ok
end
- def test_assigns
- @foo = "foo"
- @foo_hash = { foo: :bar }
- head :ok
- end
-
def test_without_body
render html: '<div class="foo"></div>'.html_safe
end
@@ -174,17 +168,6 @@ XML
end
end
- class ViewAssignsController < ActionController::Base
- def test_assigns
- @foo = "foo"
- head :ok
- end
-
- def view_assigns
- { "bar" => "bar" }
- end
- end
-
class DefaultUrlOptionsCachingController < ActionController::Base
before_action { @dynamic_opt = 'opt' }
@@ -446,30 +429,6 @@ XML
assert_equal "OK", @response.body
end
- def test_assigns
- process :test_assigns
- # assigns can be accessed using assigns(key)
- # or assigns[key], where key is a string or
- # a symbol
- assert_equal "foo", assigns(:foo)
- assert_equal "foo", assigns("foo")
- assert_equal "foo", assigns[:foo]
- assert_equal "foo", assigns["foo"]
-
- # but the assigned variable should not have its own keys stringified
- expected_hash = { foo: :bar }
- assert_equal expected_hash, assigns(:foo_hash)
- end
-
- def test_view_assigns
- @controller = ViewAssignsController.new
- process :test_assigns
- assert_equal nil, assigns(:foo)
- assert_equal nil, assigns[:foo]
- assert_equal "bar", assigns(:bar)
- assert_equal "bar", assigns[:bar]
- end
-
def test_should_not_impose_childless_html_tags_in_xml
process :test_xml_output
diff --git a/actionpack/test/dispatch/template_assertions_test.rb b/actionpack/test/dispatch/template_assertions_test.rb
deleted file mode 100644
index 7278754b49..0000000000
--- a/actionpack/test/dispatch/template_assertions_test.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-require 'abstract_unit'
-
-class AssertTemplateController < ActionController::Base
- def render_with_partial
- render partial: 'test/partial'
- end
-
- def render_with_template
- render 'test/hello_world'
- end
-
- def render_with_layout
- @variable_for_layout = 'hello'
- render 'test/hello_world', layout: "layouts/standard"
- end
-
- def render_with_file
- render file: 'README.rdoc'
- end
-
- def render_nothing
- head :ok
- end
-end
-
-class AssertTemplateControllerTest < ActionDispatch::IntegrationTest
- def test_template_reset_between_requests
- get '/assert_template/render_with_template'
- assert_template 'test/hello_world'
-
- get '/assert_template/render_nothing'
- assert_template nil
- end
-
- def test_partial_reset_between_requests
- get '/assert_template/render_with_partial'
- assert_template partial: 'test/_partial'
-
- get '/assert_template/render_nothing'
- assert_template partial: nil
- end
-
- def test_layout_reset_between_requests
- get '/assert_template/render_with_layout'
- assert_template layout: 'layouts/standard'
-
- get '/assert_template/render_nothing'
- assert_template layout: nil
- end
-
- def test_file_reset_between_requests
- get '/assert_template/render_with_file'
- assert_template file: 'README.rdoc'
-
- get '/assert_template/render_nothing'
- assert_template file: nil
- end
-
- def test_template_reset_between_requests_when_opening_a_session
- open_session do |session|
- session.get '/assert_template/render_with_template'
- session.assert_template 'test/hello_world'
-
- session.get '/assert_template/render_nothing'
- session.assert_template nil
- end
- end
-
- def test_partial_reset_between_requests_when_opening_a_session
- open_session do |session|
- session.get '/assert_template/render_with_partial'
- session.assert_template partial: 'test/_partial'
-
- session.get '/assert_template/render_nothing'
- session.assert_template partial: nil
- end
- end
-
- def test_layout_reset_between_requests_when_opening_a_session
- open_session do |session|
- session.get '/assert_template/render_with_layout'
- session.assert_template layout: 'layouts/standard'
-
- session.get '/assert_template/render_nothing'
- session.assert_template layout: nil
- end
- end
-
- def test_file_reset_between_requests_when_opening_a_session
- open_session do |session|
- session.get '/assert_template/render_with_file'
- session.assert_template file: 'README.rdoc'
-
- session.get '/assert_template/render_nothing'
- session.assert_template file: nil
- end
- end
-
- def test_assigns_do_not_reset_template_assertion
- get '/assert_template/render_with_layout'
- assert_equal 'hello', assigns(:variable_for_layout)
- assert_template layout: 'layouts/standard'
- end
-
- def test_cookies_do_not_reset_template_assertion
- get '/assert_template/render_with_layout'
- cookies
- assert_template layout: 'layouts/standard'
- end
-end
diff --git a/actionpack/test/fixtures/customers/_commented_customer.html.erb b/actionpack/test/fixtures/customers/_commented_customer.html.erb
index d5f6e3b491..8cc9c1ec13 100644
--- a/actionpack/test/fixtures/customers/_commented_customer.html.erb
+++ b/actionpack/test/fixtures/customers/_commented_customer.html.erb
@@ -1,4 +1,5 @@
<%# I'm a comment %>
<% cache customer do %>
+ <% controller.partial_rendered_times += 1 %>
<%= customer.name %>, <%= customer.id %>
<% end %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/customers/_customer.html.erb b/actionpack/test/fixtures/customers/_customer.html.erb
index 67e9f6d411..5105090d4b 100644
--- a/actionpack/test/fixtures/customers/_customer.html.erb
+++ b/actionpack/test/fixtures/customers/_customer.html.erb
@@ -1,3 +1,4 @@
<% cache customer do %>
+ <% controller.partial_rendered_times += 1 %>
<%= customer.name %>, <%= customer.id %>
<% end %> \ No newline at end of file
diff --git a/actionpack/test/fixtures/layouts/standard.html.erb b/actionpack/test/fixtures/layouts/standard.html.erb
index 5e6c24fe39..48882dca35 100644
--- a/actionpack/test/fixtures/layouts/standard.html.erb
+++ b/actionpack/test/fixtures/layouts/standard.html.erb
@@ -1 +1 @@
-<html><%= yield %><%= @variable_for_layout %></html> \ No newline at end of file
+<html><%= yield %><%= @variable_for_layout %></html>
diff --git a/actionview/lib/action_view/helpers/number_helper.rb b/actionview/lib/action_view/helpers/number_helper.rb
index ca8d30e4ef..13effa592d 100644
--- a/actionview/lib/action_view/helpers/number_helper.rb
+++ b/actionview/lib/action_view/helpers/number_helper.rb
@@ -279,7 +279,7 @@ module ActionView
# See <tt>number_to_human_size</tt> if you want to print a file
# size.
#
- # You can also define you own unit-quantifier names if you want
+ # You can also define your own unit-quantifier names if you want
# to use other decimal units (eg.: 1500 becomes "1.5
# kilometers", 0.150 becomes "150 milliliters", etc). You may
# define a wide range of unit quantifiers, even fractional ones
diff --git a/actionview/lib/action_view/layouts.rb b/actionview/lib/action_view/layouts.rb
index 1fc609f2cd..9d636c8c9e 100644
--- a/actionview/lib/action_view/layouts.rb
+++ b/actionview/lib/action_view/layouts.rb
@@ -315,25 +315,16 @@ module ActionView
name_clause
end
- if self._layout_conditions.empty?
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
- def _layout
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def _layout
+ if _conditional_layout?
#{layout_definition}
+ else
+ #{name_clause}
end
- private :_layout
- RUBY
- else
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
- def _layout
- if _conditional_layout?
- #{layout_definition}
- else
- #{name_clause}
- end
- end
- private :_layout
- RUBY
- end
+ end
+ private :_layout
+ RUBY
end
private
diff --git a/actionview/test/actionpack/controller/layout_test.rb b/actionview/test/actionpack/controller/layout_test.rb
index 64ab125637..64bc4c41d6 100644
--- a/actionview/test/actionpack/controller/layout_test.rb
+++ b/actionview/test/actionpack/controller/layout_test.rb
@@ -122,14 +122,6 @@ class PrependsViewPathController < LayoutTest
end
end
-class ParentController < LayoutTest
- layout 'item'
-end
-
-class ChildController < ParentController
- layout 'layout_test', only: :hello
-end
-
class OnlyLayoutController < LayoutTest
layout 'item', :only => "hello"
end
@@ -157,75 +149,75 @@ class LayoutSetInResponseTest < ActionController::TestCase
def test_layout_set_when_using_default_layout
@controller = DefaultLayoutController.new
get :hello
- assert_template :layout => "layouts/layout_test"
+ assert_includes @response.body, 'layout_test.erb'
end
def test_layout_set_when_using_streaming_layout
@controller = StreamingLayoutController.new
get :hello
- assert_template :hello
+ assert_includes @response.body, 'layout_test.erb'
end
def test_layout_set_when_set_in_controller
@controller = HasOwnLayoutController.new
get :hello
- assert_template :layout => "layouts/item"
+ assert_includes @response.body, 'item.erb'
end
def test_layout_symbol_set_in_controller_returning_nil_falls_back_to_default
@controller = HasNilLayoutSymbol.new
get :hello
- assert_template layout: "layouts/layout_test"
+ assert_includes @response.body, 'layout_test.erb'
end
def test_layout_proc_set_in_controller_returning_nil_falls_back_to_default
@controller = HasNilLayoutProc.new
get :hello
- assert_template layout: "layouts/layout_test"
+ assert_includes @response.body, 'layout_test.erb'
end
def test_layout_only_exception_when_included
@controller = OnlyLayoutController.new
get :hello
- assert_template :layout => "layouts/item"
+ assert_includes @response.body, 'item.erb'
end
def test_layout_only_exception_when_excepted
@controller = OnlyLayoutController.new
get :goodbye
- assert !@response.body.include?("item.erb"), "#{@response.body.inspect} included 'item.erb'"
+ assert_not_includes @response.body, 'item.erb'
end
def test_layout_except_exception_when_included
@controller = ExceptLayoutController.new
get :hello
- assert_template :layout => "layouts/item"
+ assert_includes @response.body, 'item.erb'
end
def test_layout_except_exception_when_excepted
@controller = ExceptLayoutController.new
get :goodbye
- assert !@response.body.include?("item.erb"), "#{@response.body.inspect} included 'item.erb'"
+ assert_not_includes @response.body, 'item.erb'
end
def test_layout_set_when_using_render
with_template_handler :mab, lambda { |template| template.source.inspect } do
@controller = SetsLayoutInRenderController.new
get :hello
- assert_template :layout => "layouts/third_party_template_library"
+ assert_includes @response.body, 'layouts/third_party_template_library.mab'
end
end
def test_layout_is_not_set_when_none_rendered
@controller = RendersNoLayoutController.new
get :hello
- assert_template :layout => nil
+ assert_equal 'hello.erb', @response.body
end
def test_layout_is_picked_from_the_controller_instances_view_path
@controller = PrependsViewPathController.new
get :hello
- assert_template :layout => /layouts\/alt/
+ assert_includes @response.body, 'alt.erb'
end
def test_absolute_pathed_layout
@@ -233,12 +225,6 @@ class LayoutSetInResponseTest < ActionController::TestCase
get :hello
assert_equal "layout_test.erb hello.erb", @response.body.strip
end
-
- def test_respect_to_parent_layout
- @controller = ChildController.new
- get :goodbye
- assert_template :layout => "layouts/item"
- end
end
class SetsNonExistentLayoutFile < LayoutTest
@@ -276,7 +262,7 @@ unless RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
@controller = LayoutSymlinkedTest.new
get :hello
assert_response 200
- assert_template :layout => "layouts/symlinked/symlinked_layout"
+ assert_includes @response.body, 'This is my layout'
end
end
end
diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb
index d69c070ede..c4228b5683 100644
--- a/actionview/test/actionpack/controller/render_test.rb
+++ b/actionview/test/actionpack/controller/render_test.rb
@@ -692,20 +692,19 @@ class RenderTest < ActionController::TestCase
get :hello_world
assert_response 200
assert_response :success
- assert_template "test/hello_world"
assert_equal "<html>Hello world!</html>", @response.body
end
# :ported:
def test_renders_default_template_for_missing_action
get :'hyphen-ated'
- assert_template 'test/hyphen-ated'
+ assert_equal "hyphen-ated.erb", @response.body
end
# :ported:
def test_render
get :render_hello_world
- assert_template "test/hello_world"
+ assert_equal "Hello world!", @response.body
end
def test_line_offset
@@ -721,20 +720,18 @@ class RenderTest < ActionController::TestCase
# :ported: compatibility
def test_render_with_forward_slash
get :render_hello_world_with_forward_slash
- assert_template "test/hello_world"
+ assert_equal "Hello world!", @response.body
end
# :ported:
def test_render_in_top_directory
get :render_template_in_top_directory
- assert_template "shared"
assert_equal "Elastica", @response.body
end
# :ported:
def test_render_in_top_directory_with_slash
get :render_template_in_top_directory_with_slash
- assert_template "shared"
assert_equal "Elastica", @response.body
end
@@ -752,7 +749,7 @@ class RenderTest < ActionController::TestCase
# :ported:
def test_render_action
get :render_action_hello_world
- assert_template "test/hello_world"
+ assert_equal "Hello world!", @response.body
end
def test_render_action_upcased
@@ -764,7 +761,7 @@ class RenderTest < ActionController::TestCase
end
else
get action
- assert_template 'test/Hello_world'
+ assert_equal 'Hello world!', @response.body
end
end
@@ -772,13 +769,12 @@ class RenderTest < ActionController::TestCase
def test_render_action_hello_world_as_string
get :render_action_hello_world_as_string
assert_equal "Hello world!", @response.body
- assert_template "test/hello_world"
end
# :ported:
def test_render_action_with_symbol
get :render_action_hello_world_with_symbol
- assert_template "test/hello_world"
+ assert_equal "Hello world!", @response.body
end
# :ported:
@@ -966,7 +962,7 @@ class RenderTest < ActionController::TestCase
def test_render_to_string_inline
get :render_to_string_with_inline_and_render
- assert_template "test/hello_world"
+ assert_equal 'Hello world!', @response.body
end
# :ported:
@@ -1051,8 +1047,8 @@ class RenderTest < ActionController::TestCase
def test_render_to_string_doesnt_break_assigns
get :render_to_string_with_assigns
- assert_equal "i'm before the render", assigns(:before)
- assert_equal "i'm after the render", assigns(:after)
+ assert_equal "i'm before the render", @controller.instance_variable_get(:@before)
+ assert_equal "i'm after the render", @controller.instance_variable_get(:@after)
end
def test_bad_render_to_string_still_throws_exception
@@ -1061,8 +1057,8 @@ class RenderTest < ActionController::TestCase
def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns
assert_nothing_raised { get :render_to_string_with_caught_exception }
- assert_equal "i'm before the render", assigns(:before)
- assert_equal "i'm after the render", assigns(:after)
+ assert_equal "i'm before the render", @controller.instance_variable_get(:@before)
+ assert_equal "i'm after the render", @controller.instance_variable_get(:@after)
end
def test_accessing_params_in_template_with_layout
@@ -1123,7 +1119,7 @@ class RenderTest < ActionController::TestCase
# :addressed:
def test_render_text_with_assigns
get :render_text_with_assigns
- assert_equal "world", assigns["hello"]
+ assert_equal "world", @controller.instance_variable_get(:@hello)
end
def test_render_text_with_assigns_option
@@ -1189,22 +1185,22 @@ class RenderTest < ActionController::TestCase
def test_render_to_string_partial
get :render_to_string_with_partial
- assert_equal "only partial", assigns(:partial_only)
- assert_equal "Hello: david", assigns(:partial_with_locals)
+ assert_equal "only partial", @controller.instance_variable_get(:@partial_only)
+ assert_equal "Hello: david", @controller.instance_variable_get(:@partial_with_locals)
assert_equal "text/html", @response.content_type
end
def test_render_to_string_with_template_and_html_partial
get :render_to_string_with_template_and_html_partial
- assert_equal "**only partial**\n", assigns(:text)
- assert_equal "<strong>only partial</strong>\n", assigns(:html)
+ assert_equal "**only partial**\n", @controller.instance_variable_get(:@text)
+ assert_equal "<strong>only partial</strong>\n", @controller.instance_variable_get(:@html)
assert_equal "<strong>only html partial</strong>\n", @response.body
assert_equal "text/html", @response.content_type
end
def test_render_to_string_and_render_with_different_formats
get :render_to_string_and_render_with_different_formats
- assert_equal "<strong>only partial</strong>\n", assigns(:html)
+ assert_equal "<strong>only partial</strong>\n", @controller.instance_variable_get(:@html)
assert_equal "**only partial**\n", @response.body
assert_equal "text/plain", @response.content_type
end
@@ -1228,21 +1224,18 @@ class RenderTest < ActionController::TestCase
def test_partial_with_form_builder
get :partial_with_form_builder
- assert_match(/<label/, @response.body)
- assert_template('test/_form')
+ assert_equal "<label for=\"post_title\">Title</label>\n", @response.body
end
def test_partial_with_form_builder_subclass
get :partial_with_form_builder_subclass
- assert_match(/<label/, @response.body)
- assert_template('test/_labelling_form')
+ assert_equal "<label for=\"post_title\">Title</label>\n", @response.body
end
def test_nested_partial_with_form_builder
@controller = Fun::GamesController.new
get :nested_partial_with_form_builder
- assert_match(/<label/, @response.body)
- assert_template('fun/games/_form')
+ assert_equal "<label for=\"post_title\">Title</label>\n", @response.body
end
def test_namespaced_object_partial
@@ -1286,48 +1279,29 @@ class RenderTest < ActionController::TestCase
assert_equal "Bonjour: davidBonjour: mary", @response.body
end
- def test_locals_option_to_assert_template_is_not_supported
- get :partial_collection_with_locals
-
- warning_buffer = StringIO.new
- $stderr = warning_buffer
-
- assert_template partial: 'customer_greeting', locals: { greeting: 'Bonjour' }
- assert_equal "the :locals option to #assert_template is only supported in a ActionView::TestCase\n", warning_buffer.string
- ensure
- $stderr = STDERR
- end
-
def test_partial_collection_with_spacer
get :partial_collection_with_spacer
assert_equal "Hello: davidonly partialHello: mary", @response.body
- assert_template :partial => '_customer'
end
def test_partial_collection_with_spacer_which_uses_render
get :partial_collection_with_spacer_which_uses_render
assert_equal "Hello: davidpartial html\npartial with partial\nHello: mary", @response.body
- assert_template :partial => '_customer'
end
def test_partial_collection_shorthand_with_locals
get :partial_collection_shorthand_with_locals
assert_equal "Bonjour: davidBonjour: mary", @response.body
- assert_template :partial => 'customers/_customer', :count => 2
- assert_template :partial => '_completely_fake_and_made_up_template_that_cannot_possibly_be_rendered', :count => 0
end
def test_partial_collection_shorthand_with_different_types_of_records
get :partial_collection_shorthand_with_different_types_of_records
assert_equal "Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body
- assert_template :partial => 'good_customers/_good_customer', :count => 3
- assert_template :partial => 'bad_customers/_bad_customer', :count => 3
end
def test_empty_partial_collection
get :empty_partial_collection
assert_equal " ", @response.body
- assert_template :partial => false
end
def test_partial_with_hash_object
diff --git a/actionview/test/activerecord/render_partial_with_record_identification_test.rb b/actionview/test/activerecord/render_partial_with_record_identification_test.rb
index 409370104d..9772ebb39e 100644
--- a/actionview/test/activerecord/render_partial_with_record_identification_test.rb
+++ b/actionview/test/activerecord/render_partial_with_record_identification_test.rb
@@ -52,43 +52,37 @@ class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase
def test_rendering_partial_with_has_many_and_belongs_to_association
get :render_with_has_many_and_belongs_to_association
- assert_template 'projects/_project'
- assert_equal assigns(:developer).projects.map(&:name).join, @response.body
+ assert_equal Developer.find(1).projects.map(&:name).join, @response.body
end
def test_rendering_partial_with_has_many_association
get :render_with_has_many_association
- assert_template 'replies/_reply'
assert_equal 'Birdman is better!', @response.body
end
def test_rendering_partial_with_scope
get :render_with_scope
- assert_template 'replies/_reply'
assert_equal 'Birdman is better!Nuh uh!', @response.body
end
def test_render_with_record
get :render_with_record
- assert_template 'developers/_developer'
assert_equal 'David', @response.body
end
def test_render_with_record_collection
get :render_with_record_collection
- assert_template 'developers/_developer'
assert_equal 'DavidJamisfixture_3fixture_4fixture_5fixture_6fixture_7fixture_8fixture_9fixture_10Jamis', @response.body
end
def test_render_with_record_collection_and_spacer_template
get :render_with_record_collection_and_spacer_template
- assert_equal assigns(:developer).projects.map(&:name).join('only partial'), @response.body
+ assert_equal Developer.find(1).projects.map(&:name).join('only partial'), @response.body
end
def test_rendering_partial_with_has_one_association
mascot = Company.find(1).mascot
get :render_with_has_one_association
- assert_template 'mascots/_mascot'
assert_equal mascot.name, @response.body
end
end
@@ -130,13 +124,11 @@ class RenderPartialWithRecordIdentificationAndNestedControllersTest < ActiveReco
def test_render_with_record_in_nested_controller
get :render_with_record_in_nested_controller
- assert_template %r{\Afun/games/_game\Z}
assert_equal "Fun Pong\n", @response.body
end
def test_render_with_record_collection_in_nested_controller
get :render_with_record_collection_in_nested_controller
- assert_template %r{\Afun/games/_game\Z}
assert_equal "Fun Pong\nFun Tank\n", @response.body
end
end
@@ -149,7 +141,6 @@ class RenderPartialWithRecordIdentificationAndNestedControllersWithoutPrefixTest
ActionView::Base.prefix_partial_path_with_controller_namespace = false
get :render_with_record_in_nested_controller
- assert_template %r{\Agames/_game\Z}
assert_equal "Just Pong\n", @response.body
ensure
ActionView::Base.prefix_partial_path_with_controller_namespace = old_config
@@ -160,7 +151,6 @@ class RenderPartialWithRecordIdentificationAndNestedControllersWithoutPrefixTest
ActionView::Base.prefix_partial_path_with_controller_namespace = false
get :render_with_record_collection_in_nested_controller
- assert_template %r{\Agames/_game\Z}
assert_equal "Just Pong\nJust Tank\n", @response.body
ensure
ActionView::Base.prefix_partial_path_with_controller_namespace = old_config
@@ -172,13 +162,11 @@ class RenderPartialWithRecordIdentificationAndNestedDeeperControllersTest < Acti
def test_render_with_record_in_deeper_nested_controller
get :render_with_record_in_deeper_nested_controller
- assert_template %r{\Afun/serious/games/_game\Z}
assert_equal "Serious Chess\n", @response.body
end
def test_render_with_record_collection_in_deeper_nested_controller
get :render_with_record_collection_in_deeper_nested_controller
- assert_template %r{\Afun/serious/games/_game\Z}
assert_equal "Serious Chess\nSerious Sudoku\nSerious Solitaire\n", @response.body
end
end
@@ -191,7 +179,6 @@ class RenderPartialWithRecordIdentificationAndNestedDeeperControllersWithoutPref
ActionView::Base.prefix_partial_path_with_controller_namespace = false
get :render_with_record_in_deeper_nested_controller
- assert_template %r{\Agames/_game\Z}
assert_equal "Just Chess\n", @response.body
ensure
ActionView::Base.prefix_partial_path_with_controller_namespace = old_config
@@ -202,7 +189,6 @@ class RenderPartialWithRecordIdentificationAndNestedDeeperControllersWithoutPref
ActionView::Base.prefix_partial_path_with_controller_namespace = false
get :render_with_record_collection_in_deeper_nested_controller
- assert_template %r{\Agames/_game\Z}
assert_equal "Just Chess\nJust Sudoku\nJust Solitaire\n", @response.body
ensure
ActionView::Base.prefix_partial_path_with_controller_namespace = old_config
diff --git a/actionview/test/fixtures/actionpack/layout_tests/alt/layouts/alt.erb b/actionview/test/fixtures/actionpack/layout_tests/alt/layouts/alt.erb
index e69de29bb2..60b81525b5 100644
--- a/actionview/test/fixtures/actionpack/layout_tests/alt/layouts/alt.erb
+++ b/actionview/test/fixtures/actionpack/layout_tests/alt/layouts/alt.erb
@@ -0,0 +1 @@
+alt.erb
diff --git a/actionview/test/fixtures/actionpack/test/hyphen-ated.erb b/actionview/test/fixtures/actionpack/test/hyphen-ated.erb
index cd0875583a..28dbe94ee1 100644
--- a/actionview/test/fixtures/actionpack/test/hyphen-ated.erb
+++ b/actionview/test/fixtures/actionpack/test/hyphen-ated.erb
@@ -1 +1 @@
-Hello world!
+hyphen-ated.erb \ No newline at end of file
diff --git a/actionview/test/template/test_case_test.rb b/actionview/test/template/test_case_test.rb
index c6cc47fb4f..05c3dc0613 100644
--- a/actionview/test/template/test_case_test.rb
+++ b/actionview/test/template/test_case_test.rb
@@ -306,64 +306,6 @@ module ActionView
end
end
- class RenderTemplateTest < ActionView::TestCase
- test "supports specifying templates with a Regexp" do
- controller.controller_path = "fun"
- render(:template => "fun/games/hello_world")
- assert_template %r{\Afun/games/hello_world\Z}
- end
-
- test "supports specifying partials" do
- controller.controller_path = "test"
- render(:template => "test/calling_partial_with_layout")
- assert_template :partial => "_partial_for_use_in_layout"
- end
-
- test "supports specifying locals (passing)" do
- controller.controller_path = "test"
- render(:template => "test/calling_partial_with_layout")
- assert_template :partial => "_partial_for_use_in_layout", :locals => { :name => "David" }
- end
-
- test "supports specifying locals (failing)" do
- controller.controller_path = "test"
- render(:template => "test/calling_partial_with_layout")
- e = assert_raise ActiveSupport::TestCase::Assertion do
- assert_template :partial => "_partial_for_use_in_layout", :locals => { :name => "Somebody Else" }
- end
- assert_match(/Somebody Else.*David/m, e.message)
- end
-
- test 'supports different locals on the same partial' do
- controller.controller_path = "test"
- render(:template => "test/render_two_partials")
- assert_template partial: '_partial', locals: { 'first' => '1' }
- assert_template partial: '_partial', locals: { 'second' => '2' }
- end
-
- test 'raises descriptive error message when template was not rendered' do
- controller.controller_path = "test"
- render(template: "test/hello_world_with_partial")
- e = assert_raise ActiveSupport::TestCase::Assertion do
- assert_template partial: 'i_was_never_rendered', locals: { 'did_not' => 'happen' }
- end
- assert_match "i_was_never_rendered to be rendered but it was not.", e.message
- assert_match 'Expected ["/test/partial"] to include "i_was_never_rendered"', e.message
- end
-
- test 'specifying locals works when the partial is inside a directory with underline prefix' do
- controller.controller_path = "test"
- render(template: 'test/render_partial_inside_directory')
- assert_template partial: 'test/_directory/_partial_with_locales', locals: { 'name' => 'Jane' }
- end
-
- test 'specifying locals works when the partial is inside a directory without underline prefix' do
- controller.controller_path = "test"
- render(template: 'test/render_partial_inside_directory')
- assert_template partial: 'test/_directory/partial_with_locales', locals: { 'name' => 'Jane' }
- end
- end
-
module AHelperWithInitialize
def initialize(*)
super
diff --git a/activejob/CHANGELOG.md b/activejob/CHANGELOG.md
index aba386c18e..c523723fc4 100644
--- a/activejob/CHANGELOG.md
+++ b/activejob/CHANGELOG.md
@@ -3,7 +3,7 @@
Fixes #18821.
- *Kevin Deisz* And *Jeroen van Baarsen*
+ *Kevin Deisz*, *Jeroen van Baarsen*
* `assert_enqueued_jobs` and `assert_performed_jobs` in block form use the
given number as expected value. This makes the error message much easier to
diff --git a/activejob/lib/active_job/queue_adapter.rb b/activejob/lib/active_job/queue_adapter.rb
index 054a5d93b4..457015b741 100644
--- a/activejob/lib/active_job/queue_adapter.rb
+++ b/activejob/lib/active_job/queue_adapter.rb
@@ -15,6 +15,8 @@ module ActiveJob
# Includes the setter method for changing the active queue adapter.
module ClassMethods
+ # Returns the backend queue provider. The default queue adapter
+ # is the +:inline+ queue. See QueueAdapters for more information.
def queue_adapter
_queue_adapter
end
diff --git a/activejob/lib/active_job/queue_adapters.rb b/activejob/lib/active_job/queue_adapters.rb
index bd69e525bb..1335e3236e 100644
--- a/activejob/lib/active_job/queue_adapters.rb
+++ b/activejob/lib/active_job/queue_adapters.rb
@@ -116,6 +116,10 @@ module ActiveJob
private_constant :ADAPTER
class << self
+ # Returns adapter for specified name.
+ #
+ # ActiveJob::QueueAdapters.lookup(:sidekiq)
+ # # => ActiveJob::QueueAdapters::SidekiqAdapter
def lookup(name)
const_get(name.to_s.camelize << ADAPTER)
end
diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb
index c06a64c75f..f95849eb84 100644
--- a/activemodel/lib/active_model/serialization.rb
+++ b/activemodel/lib/active_model/serialization.rb
@@ -94,6 +94,37 @@ module ActiveModel
# person.serializable_hash(except: :name) # => {"age"=>22}
# person.serializable_hash(methods: :capitalized_name)
# # => {"name"=>"bob", "age"=>22, "capitalized_name"=>"Bob"}
+ #
+ # Example with <tt>:include</tt> option
+ #
+ # class User
+ # include ActiveModel::Serializers::JSON
+ # attr_accessor :name, :notes # Emulate has_many :notes
+ # def attributes
+ # {'name' => nil}
+ # end
+ # end
+ #
+ # class Note
+ # include ActiveModel::Serializers::JSON
+ # attr_accessor :title, :text
+ # def attributes
+ # {'title' => nil, 'text' => nil}
+ # end
+ # end
+ #
+ # note = Note.new
+ # note.title = 'Battle of Austerlitz'
+ # note.text = 'Some text here'
+ #
+ # user = User.new
+ # user.name = 'Napoleon'
+ # user.notes = [note]
+ #
+ # user.serializable_hash
+ # # => {"name" => "Napoleon"}
+ # user.serializable_hash(include: { notes: { only: 'title' }})
+ # # => {"name" => "Napoleon", "notes" => [{"title"=>"Battle of Austerlitz"}]}
def serializable_hash(options = nil)
options ||= {}
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index edbfe38753..02b2096ef6 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,33 @@
+* Deprecate the PG `:point` type in favor of a new one which will return
+ `Point` objects instead of an `Array`
+
+ *Sean Griffin*
+
+* Ensure symbols passed to `ActiveRecord::Relation#select` are always treated
+ as columns.
+
+ Fixes #20360.
+
+ *Sean Griffin*
+
+* Do not set `sql_mode` if `strict: :default` is specified.
+
+ ```
+ # database.yml
+ production:
+ adapter: mysql2
+ database: foo_prod
+ user: foo
+ strict: :default
+ ```
+
+ *Ryuta Kamizono*
+
+* Allow proc defaults to be passed to the attributes API. See documentation
+ for examples.
+
+ *Sean Griffin*, *Kir Shatrov*
+
* SQLite: `:collation` support for string and text columns.
Example:
@@ -265,7 +295,7 @@
*Josef Šimánek*
-* Fixed ActiveRecord::Relation#becomes! and changed_attributes issues for type
+* Fixed `ActiveRecord::Relation#becomes!` and `changed_attributes` issues for type
columns.
Fixes #17139.
@@ -448,8 +478,8 @@
*Henrik Nygren*
-* Fixed ActiveRecord::Relation#group method when an argument is an SQL
- reserved key word:
+* Fixed `ActiveRecord::Relation#group` method when an argument is an SQL
+ reserved keyword:
Example:
@@ -458,7 +488,7 @@
*Bogdan Gusiev*
-* Added the `#or` method on ActiveRecord::Relation, allowing use of the OR
+* Added the `#or` method on `ActiveRecord::Relation`, allowing use of the OR
operator to combine WHERE or HAVING clauses.
Example:
@@ -658,7 +688,7 @@
The preferred method to halt a callback chain from now on is to explicitly
`throw(:abort)`.
- In the past, returning `false` in an ActiveRecord `before_` callback had the
+ In the past, returning `false` in an Active Record `before_` callback had the
side effect of halting the callback chain.
This is not recommended anymore and, depending on the value of the
`config.active_support.halt_callback_chains_on_return_false` option, will
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 685c3a5f17..ddeafb40ea 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -470,15 +470,16 @@ module ActiveRecord
@association.destroy_all
end
- # Deletes the +records+ supplied and removes them from the collection. For
- # +has_many+ associations, the deletion is done according to the strategy
- # specified by the <tt>:dependent</tt> option. Returns an array with the
+ # Deletes the +records+ supplied from the collection according to the strategy
+ # specified by the +:dependent+ option. If no +:dependent+ option is given,
+ # then it will follow the default strategy. Returns an array with the
# deleted records.
#
- # If no <tt>:dependent</tt> option is given, then it will follow the default
- # strategy. The default strategy is <tt>:nullify</tt>. This sets the foreign
- # keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>, the default
- # strategy is +delete_all+.
+ # For +has_many :through+ associations, the default deletion strategy is
+ # +:delete_all+.
+ #
+ # For +has_many+ associations, the default deletion strategy is +:nullify+.
+ # This sets the foreign keys to +NULL+.
#
# class Person < ActiveRecord::Base
# has_many :pets # dependent: :nullify option by default
diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb
index c89099589e..8b2c4c7170 100644
--- a/activerecord/lib/active_record/attributes.rb
+++ b/activerecord/lib/active_record/attributes.rb
@@ -82,6 +82,14 @@ module ActiveRecord
#
# StoreListing.new.my_string # => "new default"
#
+ # class Product < ActiveRecord::Base
+ # attribute :my_default_proc, :datetime, default: -> { Time.now }
+ # end
+ #
+ # Product.new.my_default_proc # => 2015-05-30 11:04:48 -0600
+ # sleep 1
+ # Product.new.my_default_proc # => 2015-05-30 11:04:49 -0600
+ #
# Attributes do not need to be backed by a database column.
#
# class MyModel < ActiveRecord::Base
@@ -204,7 +212,8 @@ module ActiveRecord
#
# +default+ The default value to use when no value is provided. If this option
# is not passed, the previous default value (if any) will be used.
- # Otherwise, the default will be +nil+.
+ # Otherwise, the default will be +nil+. A proc can also be passed, and
+ # will be called once each time a new value is needed.
#
# +user_provided_default+ Whether the default value should be cast using
# +cast+ or +deserialize+.
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index ed19819d63..dd7dcb9cdd 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -662,7 +662,7 @@ module ActiveRecord
# [<tt>:foreign_key</tt>]
# Add an appropriate foreign key. Defaults to false.
# [<tt>:polymorphic</tt>]
- # Wether an additional +_type+ column should be added. Defaults to false.
+ # Whether an additional +_type+ column should be added. Defaults to false.
#
# ====== Create a user_id integer column
#
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index 92349e2f9b..68752cdd80 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -12,6 +12,7 @@ require 'active_record/connection_adapters/postgresql/oid/json'
require 'active_record/connection_adapters/postgresql/oid/jsonb'
require 'active_record/connection_adapters/postgresql/oid/money'
require 'active_record/connection_adapters/postgresql/oid/point'
+require 'active_record/connection_adapters/postgresql/oid/rails_5_1_point'
require 'active_record/connection_adapters/postgresql/oid/range'
require 'active_record/connection_adapters/postgresql/oid/specialized_string'
require 'active_record/connection_adapters/postgresql/oid/uuid'
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
index afc9383f91..87391b5dc7 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
@@ -9,7 +9,7 @@ module ActiveRecord
def changed_in_place?(raw_old_value, new_value)
# Postgres does not preserve insignificant whitespaces when
- # roundtripping jsonb columns. This causes some false positives for
+ # round-tripping jsonb columns. This causes some false positives for
# the comparison here. Therefore, we need to parse and re-dump the
# raw value here to ensure the insignificant whitespaces are
# consistent with our encoder's output.
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb
new file mode 100644
index 0000000000..7427a25ad5
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb
@@ -0,0 +1,50 @@
+module ActiveRecord
+ Point = Struct.new(:x, :y)
+
+ module ConnectionAdapters
+ module PostgreSQL
+ module OID # :nodoc:
+ class Rails51Point < Type::Value # :nodoc:
+ include Type::Helpers::Mutable
+
+ def type
+ :point
+ end
+
+ def cast(value)
+ case value
+ when ::String
+ if value[0] == '(' && value[-1] == ')'
+ value = value[1...-1]
+ end
+ x, y = value.split(",")
+ build_point(x, y)
+ when ::Array
+ build_point(*value)
+ else
+ value
+ end
+ end
+
+ def serialize(value)
+ if value.is_a?(ActiveRecord::Point)
+ "(#{number_for_point(value.x)},#{number_for_point(value.y)})"
+ else
+ super
+ end
+ end
+
+ private
+
+ def number_for_point(number)
+ number.to_s.gsub(/\.0$/, '')
+ end
+
+ def build_point(x, y)
+ ActiveRecord::Point.new(Float(x), Float(y))
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 93fa3984e6..2c43c46a3d 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -838,6 +838,8 @@ module ActiveRecord
ActiveRecord::Type.register(:jsonb, OID::Jsonb, adapter: :postgresql)
ActiveRecord::Type.register(:money, OID::Money, adapter: :postgresql)
ActiveRecord::Type.register(:point, OID::Point, adapter: :postgresql)
+ ActiveRecord::Type.register(:legacy_point, OID::Point, adapter: :postgresql)
+ ActiveRecord::Type.register(:rails_5_1_point, OID::Rails51Point, adapter: :postgresql)
ActiveRecord::Type.register(:uuid, OID::Uuid, adapter: :postgresql)
ActiveRecord::Type.register(:vector, OID::Vector, adapter: :postgresql)
ActiveRecord::Type.register(:xml, OID::Xml, adapter: :postgresql)
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 1ec8f818cd..7760fd33b7 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -615,7 +615,6 @@ module ActiveRecord
# a list of rows to insert to that table.
def table_rows
now = config.default_timezone == :utc ? Time.now.utc : Time.now
- now = now.to_s(:db)
# allow a standard key to be used for doing defaults in YAML
fixtures.delete('DEFAULTS')
diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb
index 3674f672cb..5a6f42ba09 100644
--- a/activerecord/lib/active_record/model_schema.rb
+++ b/activerecord/lib/active_record/model_schema.rb
@@ -310,6 +310,7 @@ module ActiveRecord
def load_schema!
@columns_hash = connection.schema_cache.columns_hash(table_name)
@columns_hash.each do |name, column|
+ warn_if_deprecated_type(column)
define_attribute(
name,
connection.lookup_cast_type_from_column(column),
@@ -356,6 +357,28 @@ module ActiveRecord
base.table_name
end
end
+
+ def warn_if_deprecated_type(column)
+ return if attributes_to_define_after_schema_loads.key?(column.name)
+ if column.respond_to?(:oid) && column.sql_type.start_with?("point")
+ if column.array?
+ array_arguments = ", array: true"
+ else
+ array_arguments = ""
+ end
+ ActiveSupport::Deprecation.warn(<<-WARNING.strip_heredoc)
+ The behavior of the `:point` type will be changing in Rails 5.1 to
+ return a `Point` object, rather than an `Array`. If you'd like to
+ keep the old behavior, you can add this line to #{self.name}:
+
+ attribute :#{column.name}, :legacy_point#{array_arguments}
+
+ If you'd like the new behavior today, you can add this line:
+
+ attribute :#{column.name}, :rails_5_1_point#{array_arguments}
+ WARNING
+ end
+ end
end
end
end
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index 402b317d9c..7a28a98721 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -161,6 +161,10 @@ module ActiveRecord
end
end
+ if loaded? && (column_names - @klass.column_names).empty?
+ return @records.pluck(*column_names)
+ end
+
if has_include?(column_names.first)
construct_relation_for_association_calculations.pluck(*column_names)
else
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index fd78db2e95..f85dc35e89 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -1001,15 +1001,13 @@ module ActiveRecord
end
def arel_columns(columns)
- if from_clause.value
- columns
- else
- columns.map do |field|
- if (Symbol === field || String === field) && columns_hash.key?(field.to_s)
- arel_table[field]
- else
- field
- end
+ columns.map do |field|
+ if (Symbol === field || String === field) && columns_hash.key?(field.to_s) && !from_clause.value
+ arel_table[field]
+ elsif Symbol === field
+ connection.quote_table_name(field.to_s)
+ else
+ field
end
end
end
diff --git a/activerecord/lib/active_record/schema_migration.rb b/activerecord/lib/active_record/schema_migration.rb
index b5038104ac..cb47bf23f7 100644
--- a/activerecord/lib/active_record/schema_migration.rb
+++ b/activerecord/lib/active_record/schema_migration.rb
@@ -1,6 +1,5 @@
require 'active_record/scoping/default'
require 'active_record/scoping/named'
-require 'active_record/base'
module ActiveRecord
class SchemaMigration < ActiveRecord::Base
diff --git a/activerecord/lib/active_record/suppressor.rb b/activerecord/lib/active_record/suppressor.rb
index b0b86865fd..b3644bf569 100644
--- a/activerecord/lib/active_record/suppressor.rb
+++ b/activerecord/lib/active_record/suppressor.rb
@@ -37,8 +37,7 @@ module ActiveRecord
end
end
- # Ignore saving events if we're in suppression mode.
- def save!(*args) # :nodoc:
+ def create_or_update(*args) # :nodoc:
SuppressorRegistry.suppressed[self.class.name] ? true : super
end
end
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 311dacb449..6f2def0df1 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -196,9 +196,9 @@ module ActiveRecord
# automatically released. The following example demonstrates the problem:
#
# Model.connection.transaction do # BEGIN
- # Model.connection.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1
+ # Model.connection.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1
# Model.connection.create_table(...) # active_record_1 now automatically released
- # end # RELEASE savepoint active_record_1
+ # end # RELEASE SAVEPOINT active_record_1
# # ^^^^ BOOM! database error!
# end
#
diff --git a/activerecord/test/cases/adapters/postgresql/geometric_test.rb b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
index 41e9572907..7057848eb0 100644
--- a/activerecord/test/cases/adapters/postgresql/geometric_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
@@ -6,7 +6,15 @@ class PostgresqlPointTest < ActiveRecord::TestCase
include ConnectionHelper
include SchemaDumpingHelper
- class PostgresqlPoint < ActiveRecord::Base; end
+ class PostgresqlPoint < ActiveRecord::Base
+ attribute :x, :rails_5_1_point
+ attribute :y, :rails_5_1_point
+ attribute :z, :rails_5_1_point
+ attribute :array_of_points, :rails_5_1_point, array: true
+ attribute :legacy_x, :legacy_point
+ attribute :legacy_y, :legacy_point
+ attribute :legacy_z, :legacy_point
+ end
def setup
@connection = ActiveRecord::Base.connection
@@ -14,11 +22,27 @@ class PostgresqlPointTest < ActiveRecord::TestCase
t.point :x
t.point :y, default: [12.2, 13.3]
t.point :z, default: "(14.4,15.5)"
+ t.point :array_of_points, array: true
+ t.point :legacy_x
+ t.point :legacy_y, default: [12.2, 13.3]
+ t.point :legacy_z, default: "(14.4,15.5)"
+ end
+ @connection.create_table('deprecated_points') do |t|
+ t.point :x
end
end
teardown do
@connection.drop_table 'postgresql_points', if_exists: true
+ @connection.drop_table 'deprecated_points', if_exists: true
+ end
+
+ class DeprecatedPoint < ActiveRecord::Base; end
+
+ def test_deprecated_legacy_type
+ assert_deprecated do
+ DeprecatedPoint.new
+ end
end
def test_column
@@ -32,11 +56,11 @@ class PostgresqlPointTest < ActiveRecord::TestCase
end
def test_default
- assert_equal [12.2, 13.3], PostgresqlPoint.column_defaults['y']
- assert_equal [12.2, 13.3], PostgresqlPoint.new.y
+ assert_equal ActiveRecord::Point.new(12.2, 13.3), PostgresqlPoint.column_defaults['y']
+ assert_equal ActiveRecord::Point.new(12.2, 13.3), PostgresqlPoint.new.y
- assert_equal [14.4, 15.5], PostgresqlPoint.column_defaults['z']
- assert_equal [14.4, 15.5], PostgresqlPoint.new.z
+ assert_equal ActiveRecord::Point.new(14.4, 15.5), PostgresqlPoint.column_defaults['z']
+ assert_equal ActiveRecord::Point.new(14.4, 15.5), PostgresqlPoint.new.z
end
def test_schema_dumping
@@ -49,22 +73,95 @@ class PostgresqlPointTest < ActiveRecord::TestCase
def test_roundtrip
PostgresqlPoint.create! x: [10, 25.2]
record = PostgresqlPoint.first
- assert_equal [10, 25.2], record.x
+ assert_equal ActiveRecord::Point.new(10, 25.2), record.x
- record.x = [1.1, 2.2]
+ record.x = ActiveRecord::Point.new(1.1, 2.2)
record.save!
assert record.reload
- assert_equal [1.1, 2.2], record.x
+ assert_equal ActiveRecord::Point.new(1.1, 2.2), record.x
end
def test_mutation
- p = PostgresqlPoint.create! x: [10, 20]
+ p = PostgresqlPoint.create! x: ActiveRecord::Point.new(10, 20)
+
+ p.x.y = 25
+ p.save!
+ p.reload
+
+ assert_equal ActiveRecord::Point.new(10.0, 25.0), p.x
+ assert_not p.changed?
+ end
+
+ def test_array_assignment
+ p = PostgresqlPoint.new(x: [1, 2])
+
+ assert_equal ActiveRecord::Point.new(1, 2), p.x
+ end
+
+ def test_string_assignment
+ p = PostgresqlPoint.new(x: "(1, 2)")
+
+ assert_equal ActiveRecord::Point.new(1, 2), p.x
+ end
+
+ def test_array_of_points_round_trip
+ expected_value = [
+ ActiveRecord::Point.new(1, 2),
+ ActiveRecord::Point.new(2, 3),
+ ActiveRecord::Point.new(3, 4),
+ ]
+ p = PostgresqlPoint.new(array_of_points: expected_value)
+
+ assert_equal expected_value, p.array_of_points
+ p.save!
+ p.reload
+ assert_equal expected_value, p.array_of_points
+ end
+
+ def test_legacy_column
+ column = PostgresqlPoint.columns_hash["legacy_x"]
+ assert_equal :point, column.type
+ assert_equal "point", column.sql_type
+ assert_not column.array?
+
+ type = PostgresqlPoint.type_for_attribute("legacy_x")
+ assert_not type.binary?
+ end
+
+ def test_legacy_default
+ assert_equal [12.2, 13.3], PostgresqlPoint.column_defaults['legacy_y']
+ assert_equal [12.2, 13.3], PostgresqlPoint.new.legacy_y
+
+ assert_equal [14.4, 15.5], PostgresqlPoint.column_defaults['legacy_z']
+ assert_equal [14.4, 15.5], PostgresqlPoint.new.legacy_z
+ end
+
+ def test_legacy_schema_dumping
+ output = dump_table_schema("postgresql_points")
+ assert_match %r{t\.point\s+"legacy_x"$}, output
+ assert_match %r{t\.point\s+"legacy_y",\s+default: \[12\.2, 13\.3\]$}, output
+ assert_match %r{t\.point\s+"legacy_z",\s+default: \[14\.4, 15\.5\]$}, output
+ end
+
+ def test_legacy_roundtrip
+ PostgresqlPoint.create! legacy_x: [10, 25.2]
+ record = PostgresqlPoint.first
+ assert_equal [10, 25.2], record.legacy_x
+
+ record.legacy_x = [1.1, 2.2]
+ record.save!
+ assert record.reload
+ assert_equal [1.1, 2.2], record.legacy_x
+ end
+
+ def test_legacy_mutation
+ p = PostgresqlPoint.create! legacy_x: [10, 20]
- p.x[1] = 25
+ p.legacy_x[1] = 25
p.save!
p.reload
- assert_equal [10.0, 25.0], p.x
+ assert_equal [10.0, 25.0], p.legacy_x
assert_not p.changed?
end
end
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index b246eae5f5..cb4681109c 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -632,6 +632,27 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal [part.id], ShipPart.joins(:trinkets).pluck(:id)
end
+ def test_pluck_loaded_relation
+ companies = Company.order(:id).limit(3).load
+ assert_no_queries do
+ assert_equal ['37signals', 'Summit', 'Microsoft'], companies.pluck(:name)
+ end
+ end
+
+ def test_pluck_loaded_relation_multiple_columns
+ companies = Company.order(:id).limit(3).load
+ assert_no_queries do
+ assert_equal [[1, '37signals'], [2, 'Summit'], [3, 'Microsoft']], companies.pluck(:id, :name)
+ end
+ end
+
+ def test_pluck_loaded_relation_sql_fragment
+ companies = Company.order(:name).limit(3).load
+ assert_queries 1 do
+ assert_equal ['37signals', 'Apex', 'Ex Nihilo'], companies.pluck('DISTINCT name')
+ end
+ end
+
def test_grouped_calculation_with_polymorphic_relation
part = ShipPart.create!(name: "has trinket")
part.trinkets.create!
diff --git a/activerecord/test/cases/connection_adapters/type_lookup_test.rb b/activerecord/test/cases/connection_adapters/type_lookup_test.rb
index 05c57985a1..7566863653 100644
--- a/activerecord/test/cases/connection_adapters/type_lookup_test.rb
+++ b/activerecord/test/cases/connection_adapters/type_lookup_test.rb
@@ -81,7 +81,11 @@ module ActiveRecord
def test_bigint_limit
cast_type = @connection.type_map.lookup("bigint")
- assert_equal 8, cast_type.limit
+ if current_adapter?(:OracleAdapter)
+ assert_equal 19, cast_type.limit
+ else
+ assert_equal 8, cast_type.limit
+ end
end
def test_decimal_without_scale
diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb
index 46a62c272f..83e50048ec 100644
--- a/activerecord/test/cases/migration/change_schema_test.rb
+++ b/activerecord/test/cases/migration/change_schema_test.rb
@@ -105,7 +105,7 @@ module ActiveRecord
eight = columns.detect { |c| c.name == "eight_int" }
if current_adapter?(:OracleAdapter)
- assert_equal 'NUMBER(8)', eight.sql_type
+ assert_equal 'NUMBER(19)', eight.sql_type
elsif current_adapter?(:SQLite3Adapter)
assert_equal 'bigint', eight.sql_type
else
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
index 9353be1ba7..37d3965022 100644
--- a/activerecord/test/cases/relation_test.rb
+++ b/activerecord/test/cases/relation_test.rb
@@ -242,6 +242,19 @@ module ActiveRecord
assert_equal false, post.respond_to?(:title), "post should not respond_to?(:body) since invoking it raises exception"
end
+ def test_select_quotes_when_using_from_clause
+ if sqlite3_version_includes_quoting_bug?
+ skip <<-ERROR.squish
+ You are using an outdated version of SQLite3 which has a bug in
+ quoted column names. Please update SQLite3 and rebuild the sqlite3
+ ruby gem
+ ERROR
+ end
+ quoted_join = ActiveRecord::Base.connection.quote_table_name("join")
+ selected = Post.select(:join).from(Post.select("id as #{quoted_join}")).map(&:join)
+ assert_equal Post.pluck(:id), selected
+ end
+
def test_relation_merging_with_merged_joins_as_strings
join_string = "LEFT OUTER JOIN #{Rating.quoted_table_name} ON #{SpecialComment.quoted_table_name}.id = #{Rating.quoted_table_name}.comment_id"
special_comments_with_ratings = SpecialComment.joins join_string
@@ -276,5 +289,16 @@ module ActiveRecord
assert_equal "type cast from database", UpdateAllTestModel.first.body
end
+
+ private
+
+ def sqlite3_version_includes_quoting_bug?
+ if current_adapter?(:SQLite3Adapter)
+ selected_quoted_column_names = ActiveRecord::Base.connection.exec_query(
+ 'SELECT "join" FROM (SELECT id AS "join" FROM posts) subquery'
+ ).columns
+ ["join"] != selected_quoted_column_names
+ end
+ end
end
end
diff --git a/activerecord/test/cases/suppressor_test.rb b/activerecord/test/cases/suppressor_test.rb
index 1c449d42fe..72c5c16555 100644
--- a/activerecord/test/cases/suppressor_test.rb
+++ b/activerecord/test/cases/suppressor_test.rb
@@ -3,7 +3,38 @@ require 'models/notification'
require 'models/user'
class SuppressorTest < ActiveRecord::TestCase
- def test_suppresses_creation_of_record_generated_by_callback
+ def test_suppresses_create
+ assert_no_difference -> { Notification.count } do
+ Notification.suppress do
+ Notification.create
+ Notification.create!
+ Notification.new.save
+ Notification.new.save!
+ end
+ end
+ end
+
+ def test_suppresses_update
+ user = User.create! token: 'asdf'
+
+ User.suppress do
+ user.update token: 'ghjkl'
+ assert_equal 'asdf', user.reload.token
+
+ user.update! token: 'zxcvbnm'
+ assert_equal 'asdf', user.reload.token
+
+ user.token = 'qwerty'
+ user.save
+ assert_equal 'asdf', user.reload.token
+
+ user.token = 'uiop'
+ user.save!
+ assert_equal 'asdf', user.reload.token
+ end
+ end
+
+ def test_suppresses_create_in_callback
assert_difference -> { User.count } do
assert_no_difference -> { Notification.count } do
Notification.suppress { UserWithNotification.create! }
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index e77ebcb2f2..6ebbdbc3db 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Fix a range of values for parameters of the Time#change
+
+ *Nikolay Kondratyev*
+
* Add `Enumerable#pluck` to get the same values from arrays as from ActiveRecord
associations.
@@ -10,7 +14,7 @@
Before:
- if (slack_url = Rails.application.secrets.slack_url).present?)
+ if (slack_url = Rails.application.secrets.slack_url).present?
# Do something worthwhile
else
# Raise as important secret password is not specified
diff --git a/activesupport/lib/active_support/backtrace_cleaner.rb b/activesupport/lib/active_support/backtrace_cleaner.rb
index d06f22ad5c..e161ec4cca 100644
--- a/activesupport/lib/active_support/backtrace_cleaner.rb
+++ b/activesupport/lib/active_support/backtrace_cleaner.rb
@@ -25,7 +25,7 @@ module ActiveSupport
# of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!</tt>
# These two methods will give you a completely untouched backtrace.
#
- # Inspired by the Quiet Backtrace gem by Thoughtbot.
+ # Inspired by the Quiet Backtrace gem by thoughtbot.
class BacktraceCleaner
def initialize
@filters, @silencers = [], []
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index d28f26260e..fc7531d088 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -76,8 +76,15 @@ module Enumerable
#
# [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
# => ["David", "Rafael", "Aaron"]
- def pluck(key)
- map { |element| element[key] }
+ #
+ # [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name)
+ # => [[1, "David"], [2, "Rafael"]]
+ def pluck(*keys)
+ if keys.many?
+ map { |element| keys.map { |key| element[key] } }
+ else
+ map { |element| element[keys.first] }
+ end
end
end
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index 1ce68ea7c7..c554501893 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -98,7 +98,7 @@ class Time
elsif zone
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
else
- raise ArgumentError, 'argument out of range' if new_usec > 999999
+ raise ArgumentError, 'argument out of range' if new_usec >= 1000000
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
end
end
diff --git a/activesupport/lib/active_support/deprecation/behaviors.rb b/activesupport/lib/active_support/deprecation/behaviors.rb
index 0cdc7e96f7..28d2d78643 100644
--- a/activesupport/lib/active_support/deprecation/behaviors.rb
+++ b/activesupport/lib/active_support/deprecation/behaviors.rb
@@ -39,8 +39,8 @@ module ActiveSupport
}
# Behavior module allows to determine how to display deprecation messages.
- # You can set any behaviors from +DEFAULT_BEHAVIORS+ constant or create
- # custom behavior. Available behaviors:
+ # You can create a custom behavior or set any from the +DEFAULT_BEHAVIORS+
+ # constant. Available behaviors are:
#
# [+raise+] Raise <tt>ActiveSupport::DeprecationException</tt>.
# [+stderr+] Log all deprecation warnings to +$stderr+.
@@ -49,7 +49,7 @@ module ActiveSupport
# [+silence+] Do nothing.
#
# Setting behaviors only affects deprecations that happen after boot time.
- # For more information you can read documentation for +behavior=+ method.
+ # For more information you can read the documentation of the +behavior=+ method.
module Behavior
# Whether to print a backtrace along with the warning.
attr_accessor :debug
diff --git a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
index c6d2b5e795..9b264cbb79 100644
--- a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
@@ -127,7 +127,7 @@ module ActiveSupport
@deprecator = deprecator
end
- # Returns class of a new constant.
+ # Returns the class of the new constant.
#
# PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
# PLANETS = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('PLANETS', 'PLANETS_POST_2006')
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index bde70d772d..49fd1723e2 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -68,9 +68,9 @@ module ActiveSupport
def camelize(term, uppercase_first_letter = true)
string = term.to_s
if uppercase_first_letter
- string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
+ string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize }
else
- string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
+ string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { |match| match.downcase }
end
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
string.gsub!('/'.freeze, '::'.freeze)
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index d9a668c0ea..ae6f00b861 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -9,6 +9,7 @@ require 'active_support/testing/isolation'
require 'active_support/testing/constant_lookup'
require 'active_support/testing/time_helpers'
require 'active_support/testing/file_fixtures'
+require 'active_support/testing/composite_filter'
require 'active_support/core_ext/kernel/reporting'
module ActiveSupport
@@ -38,6 +39,15 @@ module ActiveSupport
def test_order
ActiveSupport.test_order ||= :random
end
+
+ def run(reporter, options = {})
+ if options[:patterns] && options[:patterns].any? { |p| p =~ /:\d+/ }
+ options[:filter] = \
+ Testing::CompositeFilter.new(self, options[:filter], options[:patterns])
+ end
+
+ super
+ end
end
alias_method :method_name, :name
diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb
index 411dd29df5..d87ce3474d 100644
--- a/activesupport/lib/active_support/testing/assertions.rb
+++ b/activesupport/lib/active_support/testing/assertions.rb
@@ -28,7 +28,7 @@ module ActiveSupport
#
# An arbitrary expression is passed in and evaluated.
#
- # assert_difference 'assigns(:article).comments(:reload).size' do
+ # assert_difference 'Article.last.comments(:reload).size' do
# post :create, params: { comment: {...} }
# end
#
diff --git a/activesupport/lib/active_support/testing/composite_filter.rb b/activesupport/lib/active_support/testing/composite_filter.rb
new file mode 100644
index 0000000000..bde723e30b
--- /dev/null
+++ b/activesupport/lib/active_support/testing/composite_filter.rb
@@ -0,0 +1,54 @@
+require 'method_source'
+
+module ActiveSupport
+ module Testing
+ class CompositeFilter # :nodoc:
+ def initialize(runnable, filter, patterns)
+ @runnable = runnable
+ @filters = [ derive_regexp(filter), *derive_line_filters(patterns) ].compact
+ end
+
+ def ===(method)
+ @filters.any? { |filter| filter === method }
+ end
+
+ private
+ def derive_regexp(filter)
+ filter =~ %r%/(.*)/% ? Regexp.new($1) : filter
+ end
+
+ def derive_line_filters(patterns)
+ patterns.map do |file_and_line|
+ file, line = file_and_line.split(':')
+ Filter.new(@runnable, file, line) if file
+ end
+ end
+
+ class Filter # :nodoc:
+ def initialize(runnable, file, line)
+ @runnable, @file = runnable, File.expand_path(file)
+ @line = line.to_i if line
+ end
+
+ def ===(method)
+ return unless @runnable.method_defined?(method)
+
+ if @line
+ test_file, test_range = definition_for(@runnable.instance_method(method))
+ test_file == @file && test_range.include?(@line)
+ else
+ @runnable.instance_method(method).source_location.first == @file
+ end
+ end
+
+ private
+ def definition_for(method)
+ file, start_line = method.source_location
+ end_line = method.source.count("\n") + start_line - 1
+
+ return file, start_line..end_line
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb
index 3478b09423..fca0947c5b 100644
--- a/activesupport/lib/active_support/testing/time_helpers.rb
+++ b/activesupport/lib/active_support/testing/time_helpers.rb
@@ -39,7 +39,7 @@ module ActiveSupport
end
end
- # Contain helpers that help you test passage of time.
+ # Contains helpers that help you test passage of time.
module TimeHelpers
# Changes current time to the time in the future or in the past by a given time difference by
# stubbing +Time.now+, +Date.today+, and +DateTime.now+.
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index b0d7f3299f..412c72d27c 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -1,3 +1,4 @@
+require 'active_support/duration'
require 'active_support/values/time_zone'
require 'active_support/core_ext/object/acts_like'
diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb
index 7ffcae6007..9b88a2dcc1 100644
--- a/activesupport/test/abstract_unit.rb
+++ b/activesupport/test/abstract_unit.rb
@@ -37,4 +37,5 @@ def jruby_skip(message = '')
skip message if defined?(JRUBY_VERSION)
end
+require 'minitest/mock'
require 'mocha/setup' # FIXME: stop using mocha
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index dce4e9b051..8e22d4ed2f 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -288,8 +288,9 @@ module CacheStoreBehavior
@cache.write('foo', 'bar', :expires_in => 10)
@cache.write('fu', 'baz')
@cache.write('fud', 'biz')
- Time.stubs(:now).returns(time + 11)
- assert_equal({"fu" => "baz"}, @cache.read_multi('foo', 'fu'))
+ Time.stub(:now, time + 11) do
+ assert_equal({"fu" => "baz"}, @cache.read_multi('foo', 'fu'))
+ end
end
def test_fetch_multi
@@ -387,66 +388,74 @@ module CacheStoreBehavior
def test_expires_in
time = Time.local(2008, 4, 24)
- Time.stubs(:now).returns(time)
- @cache.write('foo', 'bar')
- assert_equal 'bar', @cache.read('foo')
+ Time.stub(:now, time) do
+ @cache.write('foo', 'bar')
+ assert_equal 'bar', @cache.read('foo')
+ end
- Time.stubs(:now).returns(time + 30)
- assert_equal 'bar', @cache.read('foo')
+ Time.stub(:now, time + 30) do
+ assert_equal 'bar', @cache.read('foo')
+ end
- Time.stubs(:now).returns(time + 61)
- assert_nil @cache.read('foo')
+ Time.stub(:now, time + 61) do
+ assert_nil @cache.read('foo')
+ end
end
def test_race_condition_protection_skipped_if_not_defined
@cache.write('foo', 'bar')
time = @cache.send(:read_entry, 'foo', {}).expires_at
- Time.stubs(:now).returns(Time.at(time))
- result = @cache.fetch('foo') do
- assert_equal nil, @cache.read('foo')
- 'baz'
+ Time.stub(:now, Time.at(time)) do
+ result = @cache.fetch('foo') do
+ assert_equal nil, @cache.read('foo')
+ 'baz'
+ end
+ assert_equal 'baz', result
end
- assert_equal 'baz', result
end
def test_race_condition_protection_is_limited
time = Time.now
@cache.write('foo', 'bar', :expires_in => 60)
- Time.stubs(:now).returns(time + 71)
- result = @cache.fetch('foo', :race_condition_ttl => 10) do
- assert_equal nil, @cache.read('foo')
- "baz"
+ Time.stub(:now, time + 71) do
+ result = @cache.fetch('foo', :race_condition_ttl => 10) do
+ assert_equal nil, @cache.read('foo')
+ "baz"
+ end
+ assert_equal "baz", result
end
- assert_equal "baz", result
end
def test_race_condition_protection_is_safe
time = Time.now
@cache.write('foo', 'bar', :expires_in => 60)
- Time.stubs(:now).returns(time + 61)
- begin
- @cache.fetch('foo', :race_condition_ttl => 10) do
- assert_equal 'bar', @cache.read('foo')
- raise ArgumentError.new
+ Time.stub(:now, time + 61) do
+ begin
+ @cache.fetch('foo', :race_condition_ttl => 10) do
+ assert_equal 'bar', @cache.read('foo')
+ raise ArgumentError.new
+ end
+ rescue ArgumentError
end
- rescue ArgumentError
+ assert_equal "bar", @cache.read('foo')
+ end
+ Time.stub(:now, time + 91) do
+ assert_nil @cache.read('foo')
end
- assert_equal "bar", @cache.read('foo')
- Time.stubs(:now).returns(time + 91)
- assert_nil @cache.read('foo')
end
def test_race_condition_protection
time = Time.now
@cache.write('foo', 'bar', :expires_in => 60)
- Time.stubs(:now).returns(time + 61)
- result = @cache.fetch('foo', :race_condition_ttl => 10) do
- assert_equal 'bar', @cache.read('foo')
- "baz"
+ Time.stub(:now, time + 61) do
+ result = @cache.fetch('foo', :race_condition_ttl => 10) do
+ assert_equal 'bar', @cache.read('foo')
+ "baz"
+ end
+ assert_equal "baz", result
end
- assert_equal "baz", result
end
def test_crazy_key_characters
@@ -775,11 +784,12 @@ class FileStoreTest < ActiveSupport::TestCase
@cache.write('foo', 'bar', expires_in: 10)
@cache.write('baz', 'qux')
@cache.write('quux', 'corge', expires_in: 20)
- Time.stubs(:now).returns(time + 15)
- @cache.cleanup
- assert_not @cache.exist?('foo')
- assert @cache.exist?('baz')
- assert @cache.exist?('quux')
+ Time.stub(:now, time + 15) do
+ @cache.cleanup
+ assert_not @cache.exist?('foo')
+ assert @cache.exist?('baz')
+ assert @cache.exist?('quux')
+ end
end
def test_write_with_unless_exist
@@ -1056,9 +1066,9 @@ class CacheEntryTest < ActiveSupport::TestCase
assert !entry.expired?, 'entry not expired'
entry = ActiveSupport::Cache::Entry.new("value", :expires_in => 60)
assert !entry.expired?, 'entry not expired'
- time = Time.now + 61
- Time.stubs(:now).returns(time)
- assert entry.expired?, 'entry is expired'
+ Time.stub(:now, Time.now + 61) do
+ assert entry.expired?, 'entry is expired'
+ end
end
def test_compress_values
diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb
index e89be25b53..0fc3f765f5 100644
--- a/activesupport/test/core_ext/date_ext_test.rb
+++ b/activesupport/test/core_ext/date_ext_test.rb
@@ -191,8 +191,9 @@ class DateExtCalculationsTest < ActiveSupport::TestCase
def test_yesterday_constructor_when_zone_is_set
with_env_tz 'UTC' do
with_tz_default ActiveSupport::TimeZone['Eastern Time (US & Canada)'] do # UTC -5
- Time.stubs(:now).returns Time.local(2000, 1, 1)
- assert_equal Date.new(1999, 12, 30), Date.yesterday
+ Time.stub(:now, Time.local(2000, 1, 1)) do
+ assert_equal Date.new(1999, 12, 30), Date.yesterday
+ end
end
end
end
@@ -212,8 +213,9 @@ class DateExtCalculationsTest < ActiveSupport::TestCase
def test_tomorrow_constructor_when_zone_is_set
with_env_tz 'UTC' do
with_tz_default ActiveSupport::TimeZone['Europe/Paris'] do # UTC +1
- Time.stubs(:now).returns Time.local(1999, 12, 31, 23)
- assert_equal Date.new(2000, 1, 2), Date.tomorrow
+ Time.stub(:now, Time.local(1999, 12, 31, 23)) do
+ assert_equal Date.new(2000, 1, 2), Date.tomorrow
+ end
end
end
end
@@ -317,23 +319,26 @@ class DateExtCalculationsTest < ActiveSupport::TestCase
end
def test_past
- Date.stubs(:current).returns(Date.new(2000, 1, 1))
- assert_equal true, Date.new(1999, 12, 31).past?
- assert_equal false, Date.new(2000,1,1).past?
- assert_equal false, Date.new(2000,1,2).past?
+ Date.stub(:current, Date.new(2000, 1, 1)) do
+ assert_equal true, Date.new(1999, 12, 31).past?
+ assert_equal false, Date.new(2000,1,1).past?
+ assert_equal false, Date.new(2000,1,2).past?
+ end
end
def test_future
- Date.stubs(:current).returns(Date.new(2000, 1, 1))
- assert_equal false, Date.new(1999, 12, 31).future?
- assert_equal false, Date.new(2000,1,1).future?
- assert_equal true, Date.new(2000,1,2).future?
+ Date.stub(:current, Date.new(2000, 1, 1)) do
+ assert_equal false, Date.new(1999, 12, 31).future?
+ assert_equal false, Date.new(2000,1,1).future?
+ assert_equal true, Date.new(2000,1,2).future?
+ end
end
def test_current_returns_date_today_when_zone_not_set
with_env_tz 'US/Central' do
- Time.stubs(:now).returns Time.local(1999, 12, 31, 23)
- assert_equal Date.today, Date.current
+ Time.stub(:now, Time.local(1999, 12, 31, 23)) do
+ assert_equal Date.today, Date.current
+ end
end
end
diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb
index 74319ecd09..58d79f0541 100644
--- a/activesupport/test/core_ext/date_time_ext_test.rb
+++ b/activesupport/test/core_ext/date_time_ext_test.rb
@@ -204,61 +204,69 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
end
def test_today_with_offset
- Date.stubs(:current).returns(Date.new(2000, 1, 1))
- assert_equal false, DateTime.civil(1999,12,31,23,59,59, Rational(-18000, 86400)).today?
- assert_equal true, DateTime.civil(2000,1,1,0,0,0, Rational(-18000, 86400)).today?
- assert_equal true, DateTime.civil(2000,1,1,23,59,59, Rational(-18000, 86400)).today?
- assert_equal false, DateTime.civil(2000,1,2,0,0,0, Rational(-18000, 86400)).today?
+ Date.stub(:current, Date.new(2000, 1, 1)) do
+ assert_equal false, DateTime.civil(1999,12,31,23,59,59, Rational(-18000, 86400)).today?
+ assert_equal true, DateTime.civil(2000,1,1,0,0,0, Rational(-18000, 86400)).today?
+ assert_equal true, DateTime.civil(2000,1,1,23,59,59, Rational(-18000, 86400)).today?
+ assert_equal false, DateTime.civil(2000,1,2,0,0,0, Rational(-18000, 86400)).today?
+ end
end
def test_today_without_offset
- Date.stubs(:current).returns(Date.new(2000, 1, 1))
- assert_equal false, DateTime.civil(1999,12,31,23,59,59).today?
- assert_equal true, DateTime.civil(2000,1,1,0).today?
- assert_equal true, DateTime.civil(2000,1,1,23,59,59).today?
- assert_equal false, DateTime.civil(2000,1,2,0).today?
+ Date.stub(:current, Date.new(2000, 1, 1)) do
+ assert_equal false, DateTime.civil(1999,12,31,23,59,59).today?
+ assert_equal true, DateTime.civil(2000,1,1,0).today?
+ assert_equal true, DateTime.civil(2000,1,1,23,59,59).today?
+ assert_equal false, DateTime.civil(2000,1,2,0).today?
+ end
end
def test_past_with_offset
- DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)))
- assert_equal true, DateTime.civil(2005,2,10,15,30,44, Rational(-18000, 86400)).past?
- assert_equal false, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)).past?
- assert_equal false, DateTime.civil(2005,2,10,15,30,46, Rational(-18000, 86400)).past?
+ DateTime.stub(:current, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400))) do
+ assert_equal true, DateTime.civil(2005,2,10,15,30,44, Rational(-18000, 86400)).past?
+ assert_equal false, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)).past?
+ assert_equal false, DateTime.civil(2005,2,10,15,30,46, Rational(-18000, 86400)).past?
+ end
end
def test_past_without_offset
- DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)))
- assert_equal true, DateTime.civil(2005,2,10,20,30,44).past?
- assert_equal false, DateTime.civil(2005,2,10,20,30,45).past?
- assert_equal false, DateTime.civil(2005,2,10,20,30,46).past?
+ DateTime.stub(:current, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400))) do
+ assert_equal true, DateTime.civil(2005,2,10,20,30,44).past?
+ assert_equal false, DateTime.civil(2005,2,10,20,30,45).past?
+ assert_equal false, DateTime.civil(2005,2,10,20,30,46).past?
+ end
end
def test_future_with_offset
- DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)))
- assert_equal false, DateTime.civil(2005,2,10,15,30,44, Rational(-18000, 86400)).future?
- assert_equal false, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)).future?
- assert_equal true, DateTime.civil(2005,2,10,15,30,46, Rational(-18000, 86400)).future?
+ DateTime.stub(:current, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400))) do
+ assert_equal false, DateTime.civil(2005,2,10,15,30,44, Rational(-18000, 86400)).future?
+ assert_equal false, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)).future?
+ assert_equal true, DateTime.civil(2005,2,10,15,30,46, Rational(-18000, 86400)).future?
+ end
end
def test_future_without_offset
- DateTime.stubs(:current).returns(DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400)))
- assert_equal false, DateTime.civil(2005,2,10,20,30,44).future?
- assert_equal false, DateTime.civil(2005,2,10,20,30,45).future?
- assert_equal true, DateTime.civil(2005,2,10,20,30,46).future?
+ DateTime.stub(:current, DateTime.civil(2005,2,10,15,30,45, Rational(-18000, 86400))) do
+ assert_equal false, DateTime.civil(2005,2,10,20,30,44).future?
+ assert_equal false, DateTime.civil(2005,2,10,20,30,45).future?
+ assert_equal true, DateTime.civil(2005,2,10,20,30,46).future?
+ end
end
def test_current_returns_date_today_when_zone_is_not_set
with_env_tz 'US/Eastern' do
- Time.stubs(:now).returns Time.local(1999, 12, 31, 23, 59, 59)
- assert_equal DateTime.new(1999, 12, 31, 23, 59, 59, Rational(-18000, 86400)), DateTime.current
+ Time.stub(:now, Time.local(1999, 12, 31, 23, 59, 59)) do
+ assert_equal DateTime.new(1999, 12, 31, 23, 59, 59, Rational(-18000, 86400)), DateTime.current
+ end
end
end
def test_current_returns_time_zone_today_when_zone_is_set
Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
with_env_tz 'US/Eastern' do
- Time.stubs(:now).returns Time.local(1999, 12, 31, 23, 59, 59)
- assert_equal DateTime.new(1999, 12, 31, 23, 59, 59, Rational(-18000, 86400)), DateTime.current
+ Time.stub(:now, Time.local(1999, 12, 31, 23, 59, 59)) do
+ assert_equal DateTime.new(1999, 12, 31, 23, 59, 59, Rational(-18000, 86400)), DateTime.current
+ end
end
ensure
Time.zone = nil
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb
index c283b546e6..9e97acaffb 100644
--- a/activesupport/test/core_ext/duration_test.rb
+++ b/activesupport/test/core_ext/duration_test.rb
@@ -140,28 +140,30 @@ class DurationTest < ActiveSupport::TestCase
def test_since_and_ago_anchored_to_time_now_when_time_zone_is_not_set
Time.zone = nil
with_env_tz 'US/Eastern' do
- Time.stubs(:now).returns Time.local(2000)
- # since
- assert_not_instance_of ActiveSupport::TimeWithZone, 5.seconds.since
- assert_equal Time.local(2000,1,1,0,0,5), 5.seconds.since
- # ago
- assert_not_instance_of ActiveSupport::TimeWithZone, 5.seconds.ago
- assert_equal Time.local(1999,12,31,23,59,55), 5.seconds.ago
+ Time.stub(:now, Time.local(2000)) do
+ # since
+ assert_not_instance_of ActiveSupport::TimeWithZone, 5.seconds.since
+ assert_equal Time.local(2000,1,1,0,0,5), 5.seconds.since
+ # ago
+ assert_not_instance_of ActiveSupport::TimeWithZone, 5.seconds.ago
+ assert_equal Time.local(1999,12,31,23,59,55), 5.seconds.ago
+ end
end
end
def test_since_and_ago_anchored_to_time_zone_now_when_time_zone_is_set
Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
with_env_tz 'US/Eastern' do
- Time.stubs(:now).returns Time.local(2000)
- # since
- assert_instance_of ActiveSupport::TimeWithZone, 5.seconds.since
- assert_equal Time.utc(2000,1,1,0,0,5), 5.seconds.since.time
- assert_equal 'Eastern Time (US & Canada)', 5.seconds.since.time_zone.name
- # ago
- assert_instance_of ActiveSupport::TimeWithZone, 5.seconds.ago
- assert_equal Time.utc(1999,12,31,23,59,55), 5.seconds.ago.time
- assert_equal 'Eastern Time (US & Canada)', 5.seconds.ago.time_zone.name
+ Time.stub(:now, Time.local(2000)) do
+ # since
+ assert_instance_of ActiveSupport::TimeWithZone, 5.seconds.since
+ assert_equal Time.utc(2000,1,1,0,0,5), 5.seconds.since.time
+ assert_equal 'Eastern Time (US & Canada)', 5.seconds.since.time_zone.name
+ # ago
+ assert_instance_of ActiveSupport::TimeWithZone, 5.seconds.ago
+ assert_equal Time.utc(1999,12,31,23,59,55), 5.seconds.ago.time
+ assert_equal 'Eastern Time (US & Canada)', 5.seconds.ago.time_zone.name
+ end
end
ensure
Time.zone = nil
diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb
index 21743cdea5..f09b7d8850 100644
--- a/activesupport/test/core_ext/enumerable_test.rb
+++ b/activesupport/test/core_ext/enumerable_test.rb
@@ -3,6 +3,8 @@ require 'active_support/core_ext/array'
require 'active_support/core_ext/enumerable'
Payment = Struct.new(:price)
+ExpandedPayment = Struct.new(:dollars, :cents)
+
class SummablePayment < Payment
def +(p) self.class.new(price + p.price) end
end
@@ -114,5 +116,12 @@ class EnumerableTests < ActiveSupport::TestCase
def test_pluck
payments = GenericEnumerable.new([ Payment.new(5), Payment.new(15), Payment.new(10) ])
assert_equal [5, 15, 10], payments.pluck(:price)
+
+ payments = GenericEnumerable.new([
+ ExpandedPayment.new(5, 99),
+ ExpandedPayment.new(15, 0),
+ ExpandedPayment.new(10, 50)
+ ])
+ assert_equal [[5, 99], [15, 0], [10, 50]], payments.pluck(:dollars, :cents)
end
end
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index cb24147ab3..3a5d6df06d 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -435,117 +435,123 @@ class StringConversionsTest < ActiveSupport::TestCase
def test_standard_time_string_to_time_when_current_time_is_standard_time
with_env_tz "US/Eastern" do
- Time.stubs(:now).returns(Time.local(2012, 1, 1))
- assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time
- assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 -0800".to_time
- assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 -0800".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 -0500".to_time
- assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 -0500".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 5, 0), "2012-01-01 10:00 UTC".to_time
- assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00 UTC".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 PST".to_time
- assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 PST".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 EST".to_time
- assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 EST".to_time(:utc)
+ Time.stub(:now, Time.local(2012, 1, 1)) do
+ assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time
+ assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 -0800".to_time
+ assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 -0800".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 -0500".to_time
+ assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 -0500".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 5, 0), "2012-01-01 10:00 UTC".to_time
+ assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00 UTC".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 PST".to_time
+ assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 PST".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 EST".to_time
+ assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 EST".to_time(:utc)
+ end
end
end
def test_standard_time_string_to_time_when_current_time_is_daylight_savings
with_env_tz "US/Eastern" do
- Time.stubs(:now).returns(Time.local(2012, 7, 1))
- assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time
- assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 -0800".to_time
- assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 -0800".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 -0500".to_time
- assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 -0500".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 5, 0), "2012-01-01 10:00 UTC".to_time
- assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00 UTC".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 PST".to_time
- assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 PST".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 EST".to_time
- assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 EST".to_time(:utc)
+ Time.stub(:now, Time.local(2012, 7, 1)) do
+ assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time
+ assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 -0800".to_time
+ assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 -0800".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 -0500".to_time
+ assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 -0500".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 5, 0), "2012-01-01 10:00 UTC".to_time
+ assert_equal Time.utc(2012, 1, 1, 10, 0), "2012-01-01 10:00 UTC".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 13, 0), "2012-01-01 10:00 PST".to_time
+ assert_equal Time.utc(2012, 1, 1, 18, 0), "2012-01-01 10:00 PST".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 10, 0), "2012-01-01 10:00 EST".to_time
+ assert_equal Time.utc(2012, 1, 1, 15, 0), "2012-01-01 10:00 EST".to_time(:utc)
+ end
end
end
def test_daylight_savings_string_to_time_when_current_time_is_standard_time
with_env_tz "US/Eastern" do
- Time.stubs(:now).returns(Time.local(2012, 1, 1))
- assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time
- assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 -0700".to_time
- assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 -0700".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 -0400".to_time
- assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 -0400".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 6, 0), "2012-07-01 10:00 UTC".to_time
- assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00 UTC".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 PDT".to_time
- assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 PDT".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 EDT".to_time
- assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 EDT".to_time(:utc)
+ Time.stub(:now, Time.local(2012, 1, 1)) do
+ assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time
+ assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 -0700".to_time
+ assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 -0700".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 -0400".to_time
+ assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 -0400".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 6, 0), "2012-07-01 10:00 UTC".to_time
+ assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00 UTC".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 PDT".to_time
+ assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 PDT".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 EDT".to_time
+ assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 EDT".to_time(:utc)
+ end
end
end
def test_daylight_savings_string_to_time_when_current_time_is_daylight_savings
with_env_tz "US/Eastern" do
- Time.stubs(:now).returns(Time.local(2012, 7, 1))
- assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time
- assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 -0700".to_time
- assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 -0700".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 -0400".to_time
- assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 -0400".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 6, 0), "2012-07-01 10:00 UTC".to_time
- assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00 UTC".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 PDT".to_time
- assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 PDT".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 EDT".to_time
- assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 EDT".to_time(:utc)
+ Time.stub(:now, Time.local(2012, 7, 1)) do
+ assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time
+ assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 -0700".to_time
+ assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 -0700".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 -0400".to_time
+ assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 -0400".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 6, 0), "2012-07-01 10:00 UTC".to_time
+ assert_equal Time.utc(2012, 7, 1, 10, 0), "2012-07-01 10:00 UTC".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 13, 0), "2012-07-01 10:00 PDT".to_time
+ assert_equal Time.utc(2012, 7, 1, 17, 0), "2012-07-01 10:00 PDT".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 10, 0), "2012-07-01 10:00 EDT".to_time
+ assert_equal Time.utc(2012, 7, 1, 14, 0), "2012-07-01 10:00 EDT".to_time(:utc)
+ end
end
end
def test_partial_string_to_time_when_current_time_is_standard_time
with_env_tz "US/Eastern" do
- Time.stubs(:now).returns(Time.local(2012, 1, 1))
- assert_equal Time.local(2012, 1, 1, 10, 0), "10:00".to_time
- assert_equal Time.utc(2012, 1, 1, 10, 0), "10:00".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 6, 0), "10:00 -0100".to_time
- assert_equal Time.utc(2012, 1, 1, 11, 0), "10:00 -0100".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 10, 0), "10:00 -0500".to_time
- assert_equal Time.utc(2012, 1, 1, 15, 0), "10:00 -0500".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 5, 0), "10:00 UTC".to_time
- assert_equal Time.utc(2012, 1, 1, 10, 0), "10:00 UTC".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 13, 0), "10:00 PST".to_time
- assert_equal Time.utc(2012, 1, 1, 18, 0), "10:00 PST".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 12, 0), "10:00 PDT".to_time
- assert_equal Time.utc(2012, 1, 1, 17, 0), "10:00 PDT".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 10, 0), "10:00 EST".to_time
- assert_equal Time.utc(2012, 1, 1, 15, 0), "10:00 EST".to_time(:utc)
- assert_equal Time.local(2012, 1, 1, 9, 0), "10:00 EDT".to_time
- assert_equal Time.utc(2012, 1, 1, 14, 0), "10:00 EDT".to_time(:utc)
+ Time.stub(:now, Time.local(2012, 1, 1)) do
+ assert_equal Time.local(2012, 1, 1, 10, 0), "10:00".to_time
+ assert_equal Time.utc(2012, 1, 1, 10, 0), "10:00".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 6, 0), "10:00 -0100".to_time
+ assert_equal Time.utc(2012, 1, 1, 11, 0), "10:00 -0100".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 10, 0), "10:00 -0500".to_time
+ assert_equal Time.utc(2012, 1, 1, 15, 0), "10:00 -0500".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 5, 0), "10:00 UTC".to_time
+ assert_equal Time.utc(2012, 1, 1, 10, 0), "10:00 UTC".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 13, 0), "10:00 PST".to_time
+ assert_equal Time.utc(2012, 1, 1, 18, 0), "10:00 PST".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 12, 0), "10:00 PDT".to_time
+ assert_equal Time.utc(2012, 1, 1, 17, 0), "10:00 PDT".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 10, 0), "10:00 EST".to_time
+ assert_equal Time.utc(2012, 1, 1, 15, 0), "10:00 EST".to_time(:utc)
+ assert_equal Time.local(2012, 1, 1, 9, 0), "10:00 EDT".to_time
+ assert_equal Time.utc(2012, 1, 1, 14, 0), "10:00 EDT".to_time(:utc)
+ end
end
end
def test_partial_string_to_time_when_current_time_is_daylight_savings
with_env_tz "US/Eastern" do
- Time.stubs(:now).returns(Time.local(2012, 7, 1))
- assert_equal Time.local(2012, 7, 1, 10, 0), "10:00".to_time
- assert_equal Time.utc(2012, 7, 1, 10, 0), "10:00".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 7, 0), "10:00 -0100".to_time
- assert_equal Time.utc(2012, 7, 1, 11, 0), "10:00 -0100".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 11, 0), "10:00 -0500".to_time
- assert_equal Time.utc(2012, 7, 1, 15, 0), "10:00 -0500".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 6, 0), "10:00 UTC".to_time
- assert_equal Time.utc(2012, 7, 1, 10, 0), "10:00 UTC".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 14, 0), "10:00 PST".to_time
- assert_equal Time.utc(2012, 7, 1, 18, 0), "10:00 PST".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 13, 0), "10:00 PDT".to_time
- assert_equal Time.utc(2012, 7, 1, 17, 0), "10:00 PDT".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 11, 0), "10:00 EST".to_time
- assert_equal Time.utc(2012, 7, 1, 15, 0), "10:00 EST".to_time(:utc)
- assert_equal Time.local(2012, 7, 1, 10, 0), "10:00 EDT".to_time
- assert_equal Time.utc(2012, 7, 1, 14, 0), "10:00 EDT".to_time(:utc)
+ Time.stub(:now, Time.local(2012, 7, 1)) do
+ assert_equal Time.local(2012, 7, 1, 10, 0), "10:00".to_time
+ assert_equal Time.utc(2012, 7, 1, 10, 0), "10:00".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 7, 0), "10:00 -0100".to_time
+ assert_equal Time.utc(2012, 7, 1, 11, 0), "10:00 -0100".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 11, 0), "10:00 -0500".to_time
+ assert_equal Time.utc(2012, 7, 1, 15, 0), "10:00 -0500".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 6, 0), "10:00 UTC".to_time
+ assert_equal Time.utc(2012, 7, 1, 10, 0), "10:00 UTC".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 14, 0), "10:00 PST".to_time
+ assert_equal Time.utc(2012, 7, 1, 18, 0), "10:00 PST".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 13, 0), "10:00 PDT".to_time
+ assert_equal Time.utc(2012, 7, 1, 17, 0), "10:00 PDT".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 11, 0), "10:00 EST".to_time
+ assert_equal Time.utc(2012, 7, 1, 15, 0), "10:00 EST".to_time(:utc)
+ assert_equal Time.local(2012, 7, 1, 10, 0), "10:00 EDT".to_time
+ assert_equal Time.utc(2012, 7, 1, 14, 0), "10:00 EDT".to_time(:utc)
+ end
end
end
diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb
index d59775001b..e1ac5b3d8d 100644
--- a/activesupport/test/core_ext/time_ext_test.rb
+++ b/activesupport/test/core_ext/time_ext_test.rb
@@ -149,6 +149,9 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
assert_equal Time.local(2006,3,19,23,59,59,Rational(999999999, 1000)), Time.local(2006,3,19,10,10,10).end_of_day, 'ends DST'
assert_equal Time.local(2006,10,1,23,59,59,Rational(999999999, 1000)), Time.local(2006,10,1,10,10,10).end_of_day, 'start DST'
end
+ with_env_tz 'Asia/Yekaterinburg' do
+ assert_equal Time.local(2015, 2, 8, 23, 59, 59, Rational(999999999, 1000)), Time.new(2015, 2, 8, 8, 0, 0, '+05:00').end_of_day
+ end
end
def test_end_of_hour
@@ -389,6 +392,7 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
assert_equal Time.local(2005,1,2,11,22,33, 8), Time.local(2005,1,2,11,22,33,44).change(:usec => 8)
assert_equal Time.local(2005,1,2,11,22,33, 8), Time.local(2005,1,2,11,22,33,2).change(:nsec => 8000)
assert_raise(ArgumentError) { Time.local(2005,1,2,11,22,33, 8).change(:usec => 1, :nsec => 1) }
+ assert_nothing_raised(ArgumentError) { Time.new(2015, 5, 9, 10, 00, 00, '+03:00').change(nsec: 999999999) }
end
def test_utc_change
@@ -601,13 +605,15 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
end
def test_days_in_month_feb_in_common_year_without_year_arg
- Time.stubs(:now).returns(Time.utc(2007))
- assert_equal 28, Time.days_in_month(2)
+ Time.stub(:now, Time.utc(2007)) do
+ assert_equal 28, Time.days_in_month(2)
+ end
end
def test_days_in_month_feb_in_leap_year_without_year_arg
- Time.stubs(:now).returns(Time.utc(2008))
- assert_equal 29, Time.days_in_month(2)
+ Time.stub(:now, Time.utc(2008)) do
+ assert_equal 29, Time.days_in_month(2)
+ end
end
def test_last_month_on_31st
@@ -619,68 +625,74 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
end
def test_today_with_time_local
- Date.stubs(:current).returns(Date.new(2000, 1, 1))
- assert_equal false, Time.local(1999,12,31,23,59,59).today?
- assert_equal true, Time.local(2000,1,1,0).today?
- assert_equal true, Time.local(2000,1,1,23,59,59).today?
- assert_equal false, Time.local(2000,1,2,0).today?
+ Date.stub(:current, Date.new(2000, 1, 1)) do
+ assert_equal false, Time.local(1999,12,31,23,59,59).today?
+ assert_equal true, Time.local(2000,1,1,0).today?
+ assert_equal true, Time.local(2000,1,1,23,59,59).today?
+ assert_equal false, Time.local(2000,1,2,0).today?
+ end
end
def test_today_with_time_utc
- Date.stubs(:current).returns(Date.new(2000, 1, 1))
- assert_equal false, Time.utc(1999,12,31,23,59,59).today?
- assert_equal true, Time.utc(2000,1,1,0).today?
- assert_equal true, Time.utc(2000,1,1,23,59,59).today?
- assert_equal false, Time.utc(2000,1,2,0).today?
+ Date.stub(:current, Date.new(2000, 1, 1)) do
+ assert_equal false, Time.utc(1999,12,31,23,59,59).today?
+ assert_equal true, Time.utc(2000,1,1,0).today?
+ assert_equal true, Time.utc(2000,1,1,23,59,59).today?
+ assert_equal false, Time.utc(2000,1,2,0).today?
+ end
end
def test_past_with_time_current_as_time_local
with_env_tz 'US/Eastern' do
- Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
- assert_equal true, Time.local(2005,2,10,15,30,44).past?
- assert_equal false, Time.local(2005,2,10,15,30,45).past?
- assert_equal false, Time.local(2005,2,10,15,30,46).past?
- assert_equal true, Time.utc(2005,2,10,20,30,44).past?
- assert_equal false, Time.utc(2005,2,10,20,30,45).past?
- assert_equal false, Time.utc(2005,2,10,20,30,46).past?
+ Time.stub(:current, Time.local(2005,2,10,15,30,45)) do
+ assert_equal true, Time.local(2005,2,10,15,30,44).past?
+ assert_equal false, Time.local(2005,2,10,15,30,45).past?
+ assert_equal false, Time.local(2005,2,10,15,30,46).past?
+ assert_equal true, Time.utc(2005,2,10,20,30,44).past?
+ assert_equal false, Time.utc(2005,2,10,20,30,45).past?
+ assert_equal false, Time.utc(2005,2,10,20,30,46).past?
+ end
end
end
def test_past_with_time_current_as_time_with_zone
with_env_tz 'US/Eastern' do
twz = Time.utc(2005,2,10,15,30,45).in_time_zone('Central Time (US & Canada)')
- Time.stubs(:current).returns(twz)
- assert_equal true, Time.local(2005,2,10,10,30,44).past?
- assert_equal false, Time.local(2005,2,10,10,30,45).past?
- assert_equal false, Time.local(2005,2,10,10,30,46).past?
- assert_equal true, Time.utc(2005,2,10,15,30,44).past?
- assert_equal false, Time.utc(2005,2,10,15,30,45).past?
- assert_equal false, Time.utc(2005,2,10,15,30,46).past?
+ Time.stub(:current, twz) do
+ assert_equal true, Time.local(2005,2,10,10,30,44).past?
+ assert_equal false, Time.local(2005,2,10,10,30,45).past?
+ assert_equal false, Time.local(2005,2,10,10,30,46).past?
+ assert_equal true, Time.utc(2005,2,10,15,30,44).past?
+ assert_equal false, Time.utc(2005,2,10,15,30,45).past?
+ assert_equal false, Time.utc(2005,2,10,15,30,46).past?
+ end
end
end
def test_future_with_time_current_as_time_local
with_env_tz 'US/Eastern' do
- Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
- assert_equal false, Time.local(2005,2,10,15,30,44).future?
- assert_equal false, Time.local(2005,2,10,15,30,45).future?
- assert_equal true, Time.local(2005,2,10,15,30,46).future?
- assert_equal false, Time.utc(2005,2,10,20,30,44).future?
- assert_equal false, Time.utc(2005,2,10,20,30,45).future?
- assert_equal true, Time.utc(2005,2,10,20,30,46).future?
+ Time.stub(:current, Time.local(2005,2,10,15,30,45)) do
+ assert_equal false, Time.local(2005,2,10,15,30,44).future?
+ assert_equal false, Time.local(2005,2,10,15,30,45).future?
+ assert_equal true, Time.local(2005,2,10,15,30,46).future?
+ assert_equal false, Time.utc(2005,2,10,20,30,44).future?
+ assert_equal false, Time.utc(2005,2,10,20,30,45).future?
+ assert_equal true, Time.utc(2005,2,10,20,30,46).future?
+ end
end
end
def test_future_with_time_current_as_time_with_zone
with_env_tz 'US/Eastern' do
twz = Time.utc(2005,2,10,15,30,45).in_time_zone('Central Time (US & Canada)')
- Time.stubs(:current).returns(twz)
- assert_equal false, Time.local(2005,2,10,10,30,44).future?
- assert_equal false, Time.local(2005,2,10,10,30,45).future?
- assert_equal true, Time.local(2005,2,10,10,30,46).future?
- assert_equal false, Time.utc(2005,2,10,15,30,44).future?
- assert_equal false, Time.utc(2005,2,10,15,30,45).future?
- assert_equal true, Time.utc(2005,2,10,15,30,46).future?
+ Time.stub(:current, twz) do
+ assert_equal false, Time.local(2005,2,10,10,30,44).future?
+ assert_equal false, Time.local(2005,2,10,10,30,45).future?
+ assert_equal true, Time.local(2005,2,10,10,30,46).future?
+ assert_equal false, Time.utc(2005,2,10,15,30,44).future?
+ assert_equal false, Time.utc(2005,2,10,15,30,45).future?
+ assert_equal true, Time.utc(2005,2,10,15,30,46).future?
+ end
end
end
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index 79d78c02cd..5b48bf328c 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -205,45 +205,50 @@ class TimeWithZoneTest < ActiveSupport::TestCase
end
def test_today
- Date.stubs(:current).returns(Date.new(2000, 1, 1))
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(1999,12,31,23,59,59) ).today?
- assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(2000,1,1,0) ).today?
- assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(2000,1,1,23,59,59) ).today?
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(2000,1,2,0) ).today?
+ Date.stub(:current, Date.new(2000, 1, 1)) do
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(1999,12,31,23,59,59) ).today?
+ assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(2000,1,1,0) ).today?
+ assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(2000,1,1,23,59,59) ).today?
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.utc(2000,1,2,0) ).today?
+ end
end
def test_past_with_time_current_as_time_local
with_env_tz 'US/Eastern' do
- Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
- assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).past?
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).past?
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).past?
+ Time.stub(:current, Time.local(2005,2,10,15,30,45)) do
+ assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).past?
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).past?
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).past?
+ end
end
end
def test_past_with_time_current_as_time_with_zone
twz = ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45) )
- Time.stubs(:current).returns(twz)
- assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).past?
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).past?
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).past?
+ Time.stub(:current, twz) do
+ assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).past?
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).past?
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).past?
+ end
end
def test_future_with_time_current_as_time_local
with_env_tz 'US/Eastern' do
- Time.stubs(:current).returns(Time.local(2005,2,10,15,30,45))
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).future?
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).future?
- assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).future?
+ Time.stub(:current, Time.local(2005,2,10,15,30,45)) do
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).future?
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).future?
+ assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).future?
+ end
end
end
def test_future_with_time_current_as_time_with_zone
twz = ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45) )
- Time.stubs(:current).returns(twz)
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).future?
- assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).future?
- assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).future?
+ Time.stub(:current, twz) do
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).future?
+ assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45)).future?
+ assert_equal true, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,46)).future?
+ end
end
def test_eql?
@@ -1033,19 +1038,21 @@ class TimeWithZoneMethodsForTimeAndDateTimeTest < ActiveSupport::TestCase
def test_current_returns_time_now_when_zone_not_set
with_env_tz 'US/Eastern' do
- Time.stubs(:now).returns Time.local(2000)
- assert_equal false, Time.current.is_a?(ActiveSupport::TimeWithZone)
- assert_equal Time.local(2000), Time.current
+ Time.stub(:now, Time.local(2000)) do
+ assert_equal false, Time.current.is_a?(ActiveSupport::TimeWithZone)
+ assert_equal Time.local(2000), Time.current
+ end
end
end
def test_current_returns_time_zone_now_when_zone_set
Time.zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
with_env_tz 'US/Eastern' do
- Time.stubs(:now).returns Time.local(2000)
- assert_equal true, Time.current.is_a?(ActiveSupport::TimeWithZone)
- assert_equal 'Eastern Time (US & Canada)', Time.current.time_zone.name
- assert_equal Time.utc(2000), Time.current.time
+ Time.stub(:now, Time.local(2000)) do
+ assert_equal true, Time.current.is_a?(ActiveSupport::TimeWithZone)
+ assert_equal 'Eastern Time (US & Canada)', Time.current.time_zone.name
+ assert_equal Time.utc(2000), Time.current.time
+ end
end
end
diff --git a/activesupport/test/time_travel_test.rb b/activesupport/test/time_travel_test.rb
index 869bc09991..59c3e52c2f 100644
--- a/activesupport/test/time_travel_test.rb
+++ b/activesupport/test/time_travel_test.rb
@@ -3,80 +3,88 @@ require 'active_support/core_ext/date_time'
require 'active_support/core_ext/numeric/time'
class TimeTravelTest < ActiveSupport::TestCase
- setup do
- Time.stubs now: Time.now
- end
-
teardown do
travel_back
end
def test_time_helper_travel
- expected_time = Time.now + 1.day
- travel 1.day
-
- assert_equal expected_time.to_s(:db), Time.now.to_s(:db)
- assert_equal expected_time.to_date, Date.today
- assert_equal expected_time.to_datetime.to_s(:db), DateTime.now.to_s(:db)
- end
-
- def test_time_helper_travel_with_block
- expected_time = Time.now + 1.day
+ Time.stub(:now, Time.now) do
+ expected_time = Time.now + 1.day
+ travel 1.day
- travel 1.day do
assert_equal expected_time.to_s(:db), Time.now.to_s(:db)
assert_equal expected_time.to_date, Date.today
assert_equal expected_time.to_datetime.to_s(:db), DateTime.now.to_s(:db)
end
-
- assert_not_equal expected_time.to_s(:db), Time.now.to_s(:db)
- assert_not_equal expected_time.to_date, Date.today
- assert_not_equal expected_time.to_datetime.to_s(:db), DateTime.now.to_s(:db)
end
- def test_time_helper_travel_to
- expected_time = Time.new(2004, 11, 24, 01, 04, 44)
- travel_to expected_time
-
- assert_equal expected_time, Time.now
- assert_equal Date.new(2004, 11, 24), Date.today
- assert_equal expected_time.to_datetime, DateTime.now
+ def test_time_helper_travel_with_block
+ Time.stub(:now, Time.now) do
+ expected_time = Time.now + 1.day
+
+ travel 1.day do
+ assert_equal expected_time.to_s(:db), Time.now.to_s(:db)
+ assert_equal expected_time.to_date, Date.today
+ assert_equal expected_time.to_datetime.to_s(:db), DateTime.now.to_s(:db)
+ end
+
+ assert_not_equal expected_time.to_s(:db), Time.now.to_s(:db)
+ assert_not_equal expected_time.to_date, Date.today
+ assert_not_equal expected_time.to_datetime.to_s(:db), DateTime.now.to_s(:db)
+ end
end
- def test_time_helper_travel_to_with_block
- expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+ def test_time_helper_travel_to
+ Time.stub(:now, Time.now) do
+ expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+ travel_to expected_time
- travel_to expected_time do
assert_equal expected_time, Time.now
assert_equal Date.new(2004, 11, 24), Date.today
assert_equal expected_time.to_datetime, DateTime.now
end
+ end
- assert_not_equal expected_time, Time.now
- assert_not_equal Date.new(2004, 11, 24), Date.today
- assert_not_equal expected_time.to_datetime, DateTime.now
+ def test_time_helper_travel_to_with_block
+ Time.stub(:now, Time.now) do
+ expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+
+ travel_to expected_time do
+ assert_equal expected_time, Time.now
+ assert_equal Date.new(2004, 11, 24), Date.today
+ assert_equal expected_time.to_datetime, DateTime.now
+ end
+
+ assert_not_equal expected_time, Time.now
+ assert_not_equal Date.new(2004, 11, 24), Date.today
+ assert_not_equal expected_time.to_datetime, DateTime.now
+ end
end
def test_time_helper_travel_back
- expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+ Time.stub(:now, Time.now) do
+ expected_time = Time.new(2004, 11, 24, 01, 04, 44)
- travel_to expected_time
- assert_equal expected_time, Time.now
- assert_equal Date.new(2004, 11, 24), Date.today
- assert_equal expected_time.to_datetime, DateTime.now
- travel_back
+ travel_to expected_time
+ assert_equal expected_time, Time.now
+ assert_equal Date.new(2004, 11, 24), Date.today
+ assert_equal expected_time.to_datetime, DateTime.now
+ travel_back
- assert_not_equal expected_time, Time.now
- assert_not_equal Date.new(2004, 11, 24), Date.today
- assert_not_equal expected_time.to_datetime, DateTime.now
+ assert_not_equal expected_time, Time.now
+ assert_not_equal Date.new(2004, 11, 24), Date.today
+ assert_not_equal expected_time.to_datetime, DateTime.now
+ end
end
def test_travel_to_will_reset_the_usec_to_avoid_mysql_rouding
- travel_to Time.utc(2014, 10, 10, 10, 10, 50, 999999) do
- assert_equal 50, Time.now.sec
- assert_equal 0, Time.now.usec
- assert_equal 50, DateTime.now.sec
- assert_equal 0, DateTime.now.usec
+ Time.stub(:now, Time.now) do
+ travel_to Time.utc(2014, 10, 10, 10, 10, 50, 999999) do
+ assert_equal 50, Time.now.sec
+ assert_equal 0, Time.now.usec
+ assert_equal 50, DateTime.now.sec
+ assert_equal 0, DateTime.now.usec
+ end
end
end
end
diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb
index 5e0474f449..34bb0e2995 100644
--- a/activesupport/test/time_zone_test.rb
+++ b/activesupport/test/time_zone_test.rb
@@ -252,9 +252,10 @@ class TimeZoneTest < ActiveSupport::TestCase
def test_parse_with_incomplete_date
zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
- zone.stubs(:now).returns zone.local(1999,12,31)
- twz = zone.parse('19:00:00')
- assert_equal Time.utc(1999,12,31,19), twz.time
+ zone.stub(:now, zone.local(1999,12,31)) do
+ twz = zone.parse('19:00:00')
+ assert_equal Time.utc(1999,12,31,19), twz.time
+ end
end
def test_parse_with_day_omitted
@@ -284,9 +285,10 @@ class TimeZoneTest < ActiveSupport::TestCase
def test_parse_with_missing_time_components
zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
- zone.stubs(:now).returns zone.local(1999, 12, 31, 12, 59, 59)
- twz = zone.parse('2012-12-01')
- assert_equal Time.utc(2012, 12, 1), twz.time
+ zone.stub(:now, zone.local(1999, 12, 31, 12, 59, 59)) do
+ twz = zone.parse('2012-12-01')
+ assert_equal Time.utc(2012, 12, 1), twz.time
+ end
end
def test_parse_with_javascript_date
diff --git a/ci/travis.rb b/ci/travis.rb
index b62f90a59e..52fef05fbf 100755
--- a/ci/travis.rb
+++ b/ci/travis.rb
@@ -16,13 +16,14 @@ end
class Build
MAP = {
'railties' => 'railties',
- 'ap' => 'actionpack',
- 'am' => 'actionmailer',
- 'amo' => 'activemodel',
- 'as' => 'activesupport',
- 'ar' => 'activerecord',
- 'av' => 'actionview',
- 'aj' => 'activejob'
+ 'ap' => 'actionpack',
+ 'am' => 'actionmailer',
+ 'amo' => 'activemodel',
+ 'as' => 'activesupport',
+ 'ar' => 'activerecord',
+ 'av' => 'actionview',
+ 'aj' => 'activejob',
+ 'guides' => 'guides'
}
attr_reader :component, :options
@@ -36,7 +37,11 @@ class Build
self.options.update(options)
Dir.chdir(dir) do
announce(heading)
- rake(*tasks)
+ if guides?
+ run_bug_report_templates
+ else
+ rake(*tasks)
+ end
end
end
@@ -71,6 +76,10 @@ class Build
gem == 'activerecord'
end
+ def guides?
+ gem == 'guides'
+ end
+
def isolated?
options[:isolated]
end
@@ -96,6 +105,12 @@ class Build
end
true
end
+
+ def run_bug_report_templates
+ Dir.glob('bug_report_templates/*.rb').all? do |file|
+ system(Gem.ruby, '-w', file)
+ end
+ end
end
if ENV['GEM']=='aj:integration'
@@ -110,6 +125,7 @@ ENV['GEM'].split(',').each do |gem|
next if ENV['TRAVIS_PULL_REQUEST'] && ENV['TRAVIS_PULL_REQUEST'] != 'false' && isolated
next if gem == 'railties' && isolated
next if gem == 'aj:integration' && isolated
+ next if gem == 'guides' && isolated
build = Build.new(gem, :isolated => isolated)
results[build.key] = build.run!
diff --git a/guides/bug_report_templates/action_controller_gem.rb b/guides/bug_report_templates/action_controller_gem.rb
index 032e6bfe11..11561c55f9 100644
--- a/guides/bug_report_templates/action_controller_gem.rb
+++ b/guides/bug_report_templates/action_controller_gem.rb
@@ -1,7 +1,16 @@
-# Activate the gem you are reporting the issue against.
-gem 'rails', '4.2.0'
+begin
+ require 'bundler/inline'
+rescue LoadError => e
+ $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
+ raise e
+end
+
+gemfile(true) do
+ source 'https://rubygems.org'
+ # Activate the gem you are reporting the issue against.
+ gem 'rails', '4.2.0'
+end
-require 'rails'
require 'rack/test'
require 'action_controller/railtie'
diff --git a/guides/bug_report_templates/action_controller_master.rb b/guides/bug_report_templates/action_controller_master.rb
index 9be8130884..66887398b9 100644
--- a/guides/bug_report_templates/action_controller_master.rb
+++ b/guides/bug_report_templates/action_controller_master.rb
@@ -1,17 +1,16 @@
-unless File.exist?('Gemfile')
- File.write('Gemfile', <<-GEMFILE)
- source 'https://rubygems.org'
- gem 'rails', github: 'rails/rails'
- gem 'arel', github: 'rails/arel'
- GEMFILE
-
- system 'bundle'
+begin
+ require 'bundler/inline'
+rescue LoadError => e
+ $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
+ raise e
end
-require 'bundler'
-Bundler.setup(:default)
+gemfile(true) do
+ source 'https://rubygems.org'
+ gem 'rails', github: 'rails/rails'
+ gem 'arel', github: 'rails/arel'
+end
-require 'rails'
require 'action_controller/railtie'
class TestApp < Rails::Application
diff --git a/guides/bug_report_templates/active_record_gem.rb b/guides/bug_report_templates/active_record_gem.rb
index b295d9d21f..09d6e7b331 100644
--- a/guides/bug_report_templates/active_record_gem.rb
+++ b/guides/bug_report_templates/active_record_gem.rb
@@ -1,5 +1,17 @@
-# Activate the gem you are reporting the issue against.
-gem 'activerecord', '4.2.0'
+begin
+ require 'bundler/inline'
+rescue LoadError => e
+ $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
+ raise e
+end
+
+gemfile(true) do
+ source 'https://rubygems.org'
+ # Activate the gem you are reporting the issue against.
+ gem 'activerecord', '4.2.0'
+ gem 'sqlite3'
+end
+
require 'active_record'
require 'minitest/autorun'
require 'logger'
diff --git a/guides/bug_report_templates/active_record_master.rb b/guides/bug_report_templates/active_record_master.rb
index 9557f0b7c5..270dbe7df7 100644
--- a/guides/bug_report_templates/active_record_master.rb
+++ b/guides/bug_report_templates/active_record_master.rb
@@ -1,16 +1,16 @@
-unless File.exist?('Gemfile')
- File.write('Gemfile', <<-GEMFILE)
- source 'https://rubygems.org'
- gem 'rails', github: 'rails/rails'
- gem 'arel', github: 'rails/arel'
- gem 'sqlite3'
- GEMFILE
-
- system 'bundle'
+begin
+ require 'bundler/inline'
+rescue LoadError => e
+ $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
+ raise e
end
-require 'bundler'
-Bundler.setup(:default)
+gemfile(true) do
+ source 'https://rubygems.org'
+ gem 'rails', github: 'rails/rails'
+ gem 'arel', github: 'rails/arel'
+ gem 'sqlite3'
+end
require 'active_record'
require 'minitest/autorun'
diff --git a/guides/bug_report_templates/generic_gem.rb b/guides/bug_report_templates/generic_gem.rb
index 3e3f8593d4..a4fe51156d 100644
--- a/guides/bug_report_templates/generic_gem.rb
+++ b/guides/bug_report_templates/generic_gem.rb
@@ -1,6 +1,16 @@
-# Activate the gems you are reporting the issue against.
-gem 'activesupport', '4.2.0'
-require 'active_support'
+begin
+ require 'bundler/inline'
+rescue LoadError => e
+ $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
+ raise e
+end
+
+gemfile(true) do
+ source 'https://rubygems.org'
+ # Activate the gem you are reporting the issue against.
+ gem 'activesupport', '4.2.0'
+end
+
require 'active_support/core_ext/object/blank'
require 'minitest/autorun'
diff --git a/guides/bug_report_templates/generic_master.rb b/guides/bug_report_templates/generic_master.rb
index d930482d4e..b6b4562751 100644
--- a/guides/bug_report_templates/generic_master.rb
+++ b/guides/bug_report_templates/generic_master.rb
@@ -1,15 +1,15 @@
-unless File.exist?('Gemfile')
- File.write('Gemfile', <<-GEMFILE)
- source 'https://rubygems.org'
- gem 'rails', github: 'rails/rails'
- gem 'arel', github: 'rails/arel'
- GEMFILE
-
- system 'bundle'
+begin
+ require 'bundler/inline'
+rescue LoadError => e
+ $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
+ raise e
end
-require 'bundler'
-Bundler.setup(:default)
+gemfile(true) do
+ source 'https://rubygems.org'
+ gem 'rails', github: 'rails/rails'
+ gem 'arel', github: 'rails/arel'
+end
require 'active_support'
require 'active_support/core_ext/object/blank'
diff --git a/guides/source/3_1_release_notes.md b/guides/source/3_1_release_notes.md
index 537aa5a371..d753346fa3 100644
--- a/guides/source/3_1_release_notes.md
+++ b/guides/source/3_1_release_notes.md
@@ -199,7 +199,7 @@ Railties
* jQuery is the new default JavaScript library.
-* jQuery and Prototype are no longer vendored and is provided from now on by the jquery-rails and prototype-rails gems.
+* jQuery and Prototype are no longer vendored and is provided from now on by the `jquery-rails` and `prototype-rails` gems.
* The application generator accepts an option `-j` which can be an arbitrary string. If passed "foo", the gem "foo-rails" is added to the `Gemfile`, and the application JavaScript manifest requires "foo" and "foo_ujs". Currently only "prototype-rails" and "jquery-rails" exist and provide those files via the asset pipeline.
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index 950bb5e358..eff64fad20 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -214,7 +214,8 @@ By default `ActionView::Partials::PartialRenderer` has its object in a local var
<%= render partial: "product" %>
```
-within product we'll get `@product` in the local variable `product`, as if we had written:
+within `_product` partial we'll get `@product` in the local variable `product`,
+as if we had written:
```erb
<%= render partial: "product", locals: { product: @product } %>
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index e6475f2bb5..01bf928407 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -1936,6 +1936,8 @@ as well as adding or subtracting their results from a Time object. For example:
(4.months + 5.years).from_now
```
+NOTE: Defined in `active_support/core_ext/numeric/time.rb`
+
### Formatting
Enables the formatting of numbers in a variety of ways.
@@ -2893,7 +2895,7 @@ The method `transform_values` accepts a block and returns a hash that has applie
```
There's also the bang variant `transform_values!` that applies the block operations to values in the very receiver.
-NOTE: Defined in `active_support/core_text/hash/transform_values.rb`.
+NOTE: Defined in `active_support/core_ext/hash/transform_values.rb`.
### Slicing
diff --git a/guides/source/active_support_instrumentation.md b/guides/source/active_support_instrumentation.md
index 1b14bedfbf..373dbbb9aa 100644
--- a/guides/source/active_support_instrumentation.md
+++ b/guides/source/active_support_instrumentation.md
@@ -252,6 +252,20 @@ INFO. The adapters will add their own data as well.
| `:name` | Record's class |
| `:connection_id` | `self.object_id` |
+### instantiation.active_record
+
+| Key | Value |
+| ---------------- | ----------------------------------------- |
+| `:record_count` | Number of records that instantiated |
+| `:class_name` | Record's class |
+
+```ruby
+{
+ record_count: 1,
+ class_name: "User"
+}
+```
+
Action Mailer
-------------
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index 1fe111f2a0..05dd0d2a04 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -435,7 +435,7 @@ end
The simplest rule of thumb is that you should set up a `has_many :through` relationship if you need to work with the relationship model as an independent entity. If you don't need to do anything with the relationship model, it may be simpler to set up a `has_and_belongs_to_many` relationship (though you'll need to remember to create the joining table in the database).
-You should use `has_many :through` if you need validations, callbacks, or extra attributes on the join model.
+You should use `has_many :through` if you need validations, callbacks or extra attributes on the join model.
### Polymorphic Associations
@@ -1467,7 +1467,14 @@ The `collection_singular_ids=` method makes the collection contain only the obje
##### `collection.clear`
-The `collection.clear` method removes every object from the collection. This destroys the associated objects if they are associated with `dependent: :destroy`, deletes them directly from the database if `dependent: :delete_all`, and otherwise sets their foreign keys to `NULL`.
+The `collection.clear` method removes all objects from the collection according to the strategy specified by the `dependent` option. If no option is given, it follows the default strategy. The default strategy for `has_many :through` associations is `delete_all`, and for `has_many` associations is to set the foreign keys to `NULL`.
+
+```ruby
+@customer.orders.clear
+```
+
+WARNING: Objects will be deleted if they're associated with `dependent: :destroy`,
+just like `dependent: :delete_all`.
##### `collection.empty?`
@@ -1506,7 +1513,7 @@ The `collection.where` method finds objects within the collection based on the c
##### `collection.exists?(...)`
-The `collection.exists?` method checks whether an object meeting the supplied
+The `collection.exists?` method checks whether an object meeting the supplied
conditions exists in the collection. It uses the same syntax and options as
[`ActiveRecord::Base.exists?`](http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F).
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 0e669ed597..bb6c395c96 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -88,8 +88,6 @@ application. Accepts a valid week day symbol (e.g. `:monday`).
end
```
-* `config.dependency_loading` is a flag that allows you to disable constant autoloading setting it to false. It only has effect if `config.cache_classes` is true, which it is by default in production mode.
-
* `config.eager_load` when true, eager loads all registered `config.eager_load_namespaces`. This includes your application, engines, Rails frameworks and any other registered namespace.
* `config.eager_load_namespaces` registers namespaces that are eager loaded when `config.eager_load` is true. All namespaces in the list must respond to the `eager_load!` method.
@@ -163,8 +161,6 @@ pipeline is enabled. It is set to true by default.
* `config.assets.cache_store` defines the cache store that Sprockets will use. The default is the Rails file store.
-* `config.assets.version` is an option string that is used in MD5 hash generation. This can be changed to force all files to be recompiled.
-
* `config.assets.compile` is a boolean that can be used to turn on live Sprockets compilation in production.
* `config.assets.logger` accepts a logger conforming to the interface of Log4r or the default Ruby `Logger` class. Defaults to the same configured at `config.logger`. Setting `config.assets.logger` to false will turn off served assets logging.
@@ -190,7 +186,8 @@ The full set of methods that can be used in this block are as follows:
* `javascript_engine` configures the engine to be used (for eg. coffee) when generating assets. Defaults to `:js`.
* `orm` defines which orm to use. Defaults to `false` and will use Active Record by default.
* `resource_controller` defines which generator to use for generating a controller when using `rails generate resource`. Defaults to `:controller`.
-* `resource_route` defines whether inject resource route definition in routes or not. Defaults to `true`.
+* `resource_route` defines whether a resource route definition should be generated
+ or not. Defaults to `true`.
* `scaffold_controller` different from `resource_controller`, defines which generator to use for generating a _scaffolded_ controller when using `rails generate scaffold`. Defaults to `:scaffold_controller`.
* `stylesheets` turns on the hook for stylesheets in generators. Used in Rails for when the `scaffold` generator is run, but this hook can be used in other generates as well. Defaults to `true`.
* `stylesheet_engine` configures the stylesheet engine (for eg. sass) to be used when generating assets. Defaults to `:css`.
@@ -519,6 +516,9 @@ There are a number of settings available on `config.action_mailer`:
config.action_mailer.show_previews = false
```
+* `config.action_mailer.deliver_later_queue_name` specifies the queue name for
+ mailers. By default this is `mailers`.
+
### Configuring Active Support
There are a few configuration options available in Active Support:
diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md
index 96bf532868..dc1df8f229 100644
--- a/guides/source/debugging_rails_applications.md
+++ b/guides/source/debugging_rails_applications.md
@@ -531,8 +531,11 @@ command later in this guide).
And then ask again for the instance_variables:
```
-(byebug) instance_variables.include? "@articles"
-true
+(byebug) instance_variables
+[:@_action_has_layout, :@_routes, :@_headers, :@_status, :@_request,
+ :@_response, :@_env, :@_prefixes, :@_lookup_context, :@_action_name,
+ :@_response_body, :@marked_for_same_origin_verification, :@_config,
+ :@articles]
```
Now `@articles` is included in the instance variables, because the line defining it
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index 989b29956c..295e48f493 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -21,14 +21,14 @@ The easiest and recommended way to get a development environment ready to hack i
The Hard Way
------------
-In case you can't use the Rails development box, see section above, these are the steps to manually build a development box for Ruby on Rails core development.
+In case you can't use the Rails development box, see section below, these are the steps to manually build a development box for Ruby on Rails core development.
### Install Git
Ruby on Rails uses Git for source code control. The [Git homepage](http://git-scm.com/) has installation instructions. There are a variety of resources on the net that will help you get familiar with Git:
* [Try Git course](http://try.github.io/) is an interactive course that will teach you the basics.
-* The [official Documentation](http://git-scm.com/documentation) is pretty comprehensive and also contains some videos with the basics of Git
+* The [official Documentation](http://git-scm.com/documentation) is pretty comprehensive and also contains some videos with the basics of Git.
* [Everyday Git](http://schacon.github.io/git/everyday.html) will teach you just enough about Git to get by.
* The [PeepCode screencast](https://peepcode.com/products/git) on Git is easier to follow.
* [GitHub](http://help.github.com) offers links to a variety of Git resources.
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 7ae3640937..9145aee009 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -11,7 +11,7 @@
-
name: Active Record Basics
url: active_record_basics.html
- description: This guide will get you started with models, persistence to database and the Active Record pattern and library.
+ description: This guide will get you started with models, persistence to database, and the Active Record pattern and library.
-
name: Active Record Migrations
url: active_record_migrations.html
@@ -19,7 +19,7 @@
-
name: Active Record Validations
url: active_record_validations.html
- description: This guide covers how you can use Active Record validations
+ description: This guide covers how you can use Active Record validations.
-
name: Active Record Callbacks
url: active_record_callbacks.html
@@ -74,7 +74,7 @@
-
name: Rails Internationalization API
url: i18n.html
- description: This guide covers how to add internationalization to your applications. Your application will be able to translate content to different languages, change pluralization rules, use correct date formats for each country and so on.
+ description: This guide covers how to add internationalization to your applications. Your application will be able to translate content to different languages, change pluralization rules, use correct date formats for each country, and so on.
-
name: Action Mailer Basics
url: action_mailer_basics.html
@@ -82,7 +82,7 @@
-
name: Active Job Basics
url: active_job_basics.html
- description: This guide provides you with all you need to get started in creating, enqueueing and executing background jobs.
+ description: This guide provides you with all you need to get started creating, enqueuing, and executing background jobs.
-
name: Testing Rails Applications
work_in_progress: true
@@ -116,7 +116,7 @@
name: The Rails Initialization Process
work_in_progress: true
url: initialization.html
- description: This guide explains the internals of the Rails initialization process as of Rails 4
+ description: This guide explains the internals of the Rails initialization process as of Rails 4.
-
name: Autoloading and Reloading Constants
url: autoloading_and_reloading_constants.html
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index 853227e2a1..8f7d97844e 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -291,8 +291,8 @@ You can create a similar binding without actually creating `<form>` tags with th
```erb
<%= form_for @person, url: {action: "create"} do |person_form| %>
<%= person_form.text_field :name %>
- <%= fields_for @person.contact_detail do |contact_details_form| %>
- <%= contact_details_form.text_field :phone_number %>
+ <%= fields_for @person.contact_detail do |contact_detail_form| %>
+ <%= contact_detail_form.text_field :phone_number %>
<% end %>
<% end %>
```
@@ -441,7 +441,7 @@ Whenever Rails sees that the internal value of an option being generated matches
TIP: The second argument to `options_for_select` must be exactly equal to the desired internal value. In particular if the value is the integer `2` you cannot pass `"2"` to `options_for_select` - you must pass `2`. Be aware of values extracted from the `params` hash as they are all strings.
-WARNING: when `:include_blank` or `:prompt` are not present, `:include_blank` is forced true if the select attribute `required` is true, display `size` is one and `multiple` is not true.
+WARNING: When `:include_blank` or `:prompt` are not present, `:include_blank` is forced true if the select attribute `required` is true, display `size` is one and `multiple` is not true.
You can add arbitrary attributes to the options using hashes:
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index 5ef376531d..e64a788ac2 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -400,7 +400,7 @@ a controller called `ArticlesController`. You can do this by running this
command:
```bash
-$ bin/rails g controller articles
+$ bin/rails generate controller articles
```
If you open up the newly generated `app/controllers/articles_controller.rb`
@@ -1240,7 +1240,9 @@ article we want to show the form back to the user.
We reuse the `article_params` method that we defined earlier for the create
action.
-TIP: It is not necessary to pass all the attributes to `update`. For example, if `@article.update(title: 'A new title')` were called, Rails would only update the `title` attribute, leaving all other attributes untouched.
+TIP: It is not necessary to pass all the attributes to `update`. For example,
+if `@article.update(title: 'A new title')` was called, Rails would only update
+the `title` attribute, leaving all other attributes untouched.
Finally, we want to show a link to the `edit` action in the list of all the
articles, so let's add that now to `app/views/articles/index.html.erb` to make
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index 51eaf4ba5a..9f0ed1a85b 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -500,7 +500,10 @@ You can make use of this feature, e.g. when working with a large amount of stati
### Organization of Locale Files
-When you are using the default SimpleStore shipped with the i18n library, dictionaries are stored in plain-text files on the disc. Putting translations for all parts of your application in one file per locale could be hard to manage. You can store these files in a hierarchy which makes sense to you.
+When you are using the default SimpleStore shipped with the i18n library,
+dictionaries are stored in plain-text files on the disk. Putting translations
+for all parts of your application in one file per locale could be hard to
+manage. You can store these files in a hierarchy which makes sense to you.
For example, your `config/locales` directory could look like this:
diff --git a/guides/source/kindle/welcome.html.erb b/guides/source/kindle/welcome.html.erb
index 610a71570f..ef3397f58f 100644
--- a/guides/source/kindle/welcome.html.erb
+++ b/guides/source/kindle/welcome.html.erb
@@ -2,4 +2,6 @@
<h3>Kindle Edition</h3>
-The Kindle Edition of the Rails Guides should be considered a work in progress. Feedback is really welcome. Please see the "Feedback" section at the end of each guide for instructions.
+<div>
+ The Kindle Edition of the Rails Guides should be considered a work in progress. Feedback is really welcome. Please see the "Feedback" section at the end of each guide for instructions.
+</div>
diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md
index b3e1874048..b7364536c3 100644
--- a/guides/source/rails_application_templates.md
+++ b/guides/source/rails_application_templates.md
@@ -215,7 +215,7 @@ CODE
### yes?(question) or no?(question)
-These methods let you ask questions from templates and decide the flow based on the user's answer. Let's say you want to freeze rails only if the user wants to:
+These methods let you ask questions from templates and decide the flow based on the user's answer. Let's say you want to Freeze Rails only if the user wants to:
```ruby
rake("rails:freeze:gems") if yes?("Freeze rails gems?")
diff --git a/guides/source/routing.md b/guides/source/routing.md
index b1e4c8ad86..52f11f92bd 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -809,13 +809,16 @@ As long as `Sprockets` responds to `call` and returns a `[status, headers, body]
NOTE: For the curious, `'articles#index'` actually expands out to `ArticlesController.action(:index)`, which returns a valid Rack application.
-If you specify a rack application as the endpoint for a matcher remember that the route will be unchanged in the receiving application. With the following route your rack application should expect the route to be '/admin':
+If you specify a Rack application as the endpoint for a matcher, remember that
+the route will be unchanged in the receiving application. With the following
+route your Rack application should expect the route to be '/admin':
```ruby
match '/admin', to: AdminApp, via: :all
```
-If you would prefer to have your rack application receive requests at the root path instead use mount:
+If you would prefer to have your Rack application receive requests at the root
+path instead, use mount:
```ruby
mount AdminApp, at: '/admin'
diff --git a/guides/source/testing.md b/guides/source/testing.md
index 2067fdb383..230e8162f3 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -467,7 +467,6 @@ Rails adds some custom assertions of its own to the `minitest` framework:
| `assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)` | Asserts that the provided options can be used to generate the provided path. This is the inverse of assert_recognizes. The extras parameter is used to tell the request the names and values of additional request parameters that would be in a query string. The message parameter allows you to specify a custom error message for assertion failures.|
| `assert_response(type, message = nil)` | Asserts that the response comes with a specific status code. You can specify `:success` to indicate 200-299, `:redirect` to indicate 300-399, `:missing` to indicate 404, or `:error` to match the 500-599 range. You can also pass an explicit status number or its symbolic equivalent. For more information, see [full list of status codes](http://rubydoc.info/github/rack/rack/master/Rack/Utils#HTTP_STATUS_CODES-constant) and how their [mapping](http://rubydoc.info/github/rack/rack/master/Rack/Utils#SYMBOL_TO_STATUS_CODE-constant) works.|
| `assert_redirected_to(options = {}, message=nil)` | Assert that the redirection options passed in match those of the redirect called in the latest action. This match can be partial, such that `assert_redirected_to(controller: "weblog")` will also match the redirection of `redirect_to(controller: "weblog", action: "show")` and so on. You can also pass named routes such as `assert_redirected_to root_path` and Active Record objects such as `assert_redirected_to @article`.|
-| `assert_template(expected = nil, message=nil)` | Asserts that the request was rendered with the appropriate template file.|
You'll see the usage of some of these assertions in the next chapter.
@@ -506,16 +505,18 @@ Now that we have used Rails scaffold generator for our `Article` resource, it ha
Let me take you through one such test, `test_should_get_index` from the file `articles_controller_test.rb`.
```ruby
+# articles_controller_test.rb
class ArticlesControllerTest < ActionController::TestCase
test "should get index" do
get :index
assert_response :success
- assert_not_nil assigns(:articles)
+ assert_includes @response.body, 'Articles'
end
end
```
-In the `test_should_get_index` test, Rails simulates a request on the action called `index`, making sure the request was successful and also ensuring that it assigns a valid `articles` instance variable.
+In the `test_should_get_index` test, Rails simulates a request on the action called `index`, making sure the request was successful
+and also ensuring that the right response body has been generated.
The `get` method kicks off the web request and populates the results into the response. It accepts 4 arguments:
@@ -553,7 +554,7 @@ test "should create article" do
post :create, params: { article: { title: 'Some title' } }
end
- assert_redirected_to article_path(assigns(:article))
+ assert_redirected_to article_path(Article.last)
end
```
@@ -580,11 +581,11 @@ To test AJAX requests, you can specify the `xhr: true` option to `get`, `post`,
`patch`, `put`, and `delete` methods:
```ruby
-test "ajax request responds with no layout" do
+test "ajax request" do
get :show, params: { id: articles(:first).id }, xhr: true
- assert_template :index
- assert_template layout: nil
+ assert_equal 'hello world', @response.body
+ assert_equal "text/javascript", @response.content_type
end
```
@@ -592,20 +593,16 @@ end
After a request has been made and processed, you will have 4 Hash objects ready for use:
-* `assigns` - Any objects that are stored as instance variables in actions for use in views.
* `cookies` - Any cookies that are set.
* `flash` - Any objects living in the flash.
* `session` - Any object living in session variables.
-As is the case with normal Hash objects, you can access the values by referencing the keys by string. You can also reference them by symbol name, except for `assigns`. For example:
+As is the case with normal Hash objects, you can access the values by referencing the keys by string. You can also reference them by symbol name. For example:
```ruby
flash["gordon"] flash[:gordon]
session["shmession"] session[:shmession]
cookies["are_good_for_u"] cookies[:are_good_for_u]
-
-# Because you can't use assigns[:something] for historical reasons:
-assigns["something"] assigns(:something)
```
### Instance Variables Available
@@ -633,46 +630,6 @@ get :index # simulate the request with custom header
post :create # simulate the request with custom env variable
```
-### Testing Templates and Layouts
-
-Eventually, you may want to test whether a specific layout is rendered in the view of a response.
-
-#### Asserting Templates
-
-If you want to make sure that the response rendered the correct template and layout, you can use the `assert_template`
-method:
-
-```ruby
-test "index should render correct template and layout" do
- get :index
- assert_template :index
- assert_template layout: "layouts/application"
-
- # You can also pass a regular expression.
- assert_template layout: /layouts\/application/
-end
-```
-
-NOTE: You cannot test for template and layout at the same time, with a single call to `assert_template`.
-
-WARNING: You must include the "layouts" directory name even if you save your layout file in this standard layout directory. Hence, `assert_template layout: "application"` will not work.
-
-#### Asserting Partials
-
-If your view renders any partial, when asserting for the layout, you can to assert for the partial at the same time.
-Otherwise, assertion will fail.
-
-Remember, we added the "_form" partial to our new Article view? Let's write an assertion for that in the `:new` action now:
-
-```ruby
-test "new should render correct layout" do
- get :new
- assert_template layout: "layouts/application", partial: "_form"
-end
-```
-
-This is the correct way to assert for when the view renders a partial with a given name. As identified by the `:partial` key passed to the `assert_template` call.
-
### Testing `flash` notices
If you remember from earlier one of the Four Hashes of the Apocalypse was `flash`.
@@ -688,7 +645,7 @@ test "should create article" do
post :create, params: { article: { title: 'Some title' } }
end
- assert_redirected_to article_path(assigns(:article))
+ assert_redirected_to article_path(Article.last)
assert_equal 'Article was successfully created.', flash[:notice]
end
```
@@ -781,7 +738,7 @@ We can also add a test for updating an existing Article.
test "should update article" do
article = articles(:one)
patch :update, params: { id: article.id, article: { title: "updated" } }
- assert_redirected_to article_path(assigns(:article))
+ assert_redirected_to article_path(article)
end
```
@@ -820,7 +777,7 @@ class ArticlesControllerTest < ActionController::TestCase
test "should update article" do
patch :update, params: { id: @article.id, article: { title: "updated" } }
- assert_redirected_to article_path(assigns(:article))
+ assert_redirected_to article_path(@article)
end
end
```
@@ -857,7 +814,6 @@ class ProfileControllerTest < ActionController::TestCase
get :show
assert_response :success
- assert_equal users(:david), assigns(:user)
end
end
```
@@ -1071,14 +1027,12 @@ How about testing our ability to create a new article in our blog and see the re
test "can create an article" do
get "/articles/new"
assert_response :success
- assert_template "articles/new", partial: "articles/_form"
post "/articles",
params: { article: { title: "can create", body: "article successfully." } }
assert_response :redirect
follow_redirect!
assert_response :success
- assert_template "articles/show"
assert_select "p", "Title:\n can create"
end
```
diff --git a/install.rb b/install.rb
index 96e4153165..933e5ee9a2 100644
--- a/install.rb
+++ b/install.rb
@@ -7,10 +7,10 @@ end
%w( activesupport activemodel activerecord actionpack actionview actionmailer railties activejob ).each do |framework|
puts "Installing #{framework}..."
- `cd #{framework} && gem build #{framework}.gemspec && gem install #{framework}-#{version}.gem --no-ri --no-rdoc && rm #{framework}-#{version}.gem`
+ `cd #{framework} && gem build #{framework}.gemspec && gem install #{framework}-#{version}.gem --no-document && rm #{framework}-#{version}.gem`
end
puts "Installing rails..."
`gem build rails.gemspec`
-`gem install rails-#{version}.gem --no-ri --no-rdoc `
+`gem install rails-#{version}.gem --no-document `
`rm rails-#{version}.gem`
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index d2662d61da..a0fb612cba 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Make generated scaffold functional tests work inside engines.
+
+ *Yuji Yaginuma*
+
* Generator a `.keep` file in the `tmp` folder by default as many scripts
assume the existence of this folder and most would fail if it is absent.
diff --git a/railties/lib/rails/commands/test.rb b/railties/lib/rails/commands/test.rb
index 598e224a6f..fe5307788a 100644
--- a/railties/lib/rails/commands/test.rb
+++ b/railties/lib/rails/commands/test.rb
@@ -1,5 +1,5 @@
-require "rails/test_unit/runner"
+require "rails/test_unit/minitest_plugin"
$: << File.expand_path("../../test", APP_PATH)
-Rails::TestRunner.run(ARGV)
+exit Minitest.run(ARGV)
diff --git a/railties/lib/rails/console/app.rb b/railties/lib/rails/console/app.rb
index 2a69c26deb..ac5836a588 100644
--- a/railties/lib/rails/console/app.rb
+++ b/railties/lib/rails/console/app.rb
@@ -18,6 +18,11 @@ module Rails
app = Rails.application
session = ActionDispatch::Integration::Session.new(app)
yield session if block_given?
+
+ # This makes app.url_for and app.foo_path available in the console
+ session.extend(app.routes.url_helpers)
+ session.extend(app.routes.mounted_helpers)
+
session
end
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 061fafb156..c02b39d203 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -208,11 +208,13 @@ module Rails
if options.dev?
[
GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH),
+ GemfileEntry.github('sprockets-rails', 'rails/sprockets-rails'),
GemfileEntry.github('arel', 'rails/arel')
]
elsif options.edge?
[
GemfileEntry.github('rails', 'rails/rails'),
+ GemfileEntry.github('sprockets-rails', 'rails/sprockets-rails'),
GemfileEntry.github('arel', 'rails/arel')
]
else
diff --git a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
index 509bd60564..7106096b60 100644
--- a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
@@ -2,6 +2,12 @@ require 'test_helper'
<% module_namespacing do -%>
class <%= class_name %>ControllerTest < ActionController::TestCase
+<% if defined?(ENGINE_ROOT) -%>
+ setup do
+ @routes = Engine.routes
+ end
+
+<% end -%>
<% if actions.empty? -%>
# test "the truth" do
# assert true
diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
index 2e1f55f2a6..c36a64db31 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
@@ -15,6 +15,15 @@ module TestUnit # :nodoc:
File.join("test/controllers", controller_class_path, "#{controller_file_name}_controller_test.rb")
end
+ def fixture_name
+ @fixture_name ||=
+ if defined?(ENGINE_ROOT)
+ "%s_%s" % [namespaced_path, table_name]
+ else
+ table_name
+ end
+ end
+
private
def attributes_hash
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
index 76313575e9..d12a5ba733 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -3,7 +3,10 @@ require 'test_helper'
<% module_namespacing do -%>
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
setup do
- @<%= singular_table_name %> = <%= table_name %>(:one)
+ @<%= singular_table_name %> = <%= fixture_name %>(:one)
+<% if defined?(ENGINE_ROOT) -%>
+ @routes = Engine.routes
+<% end -%>
end
test "should get index" do
diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb
index a83e39faee..3b444b0932 100644
--- a/railties/lib/rails/test_help.rb
+++ b/railties/lib/rails/test_help.rb
@@ -3,13 +3,17 @@
abort("Abort testing: Your Rails environment is running in production mode!") if Rails.env.production?
require "rails/test_unit/minitest_plugin"
-require 'active_support/testing/autorun'
require 'active_support/test_case'
require 'action_controller'
require 'action_controller/test_case'
require 'action_dispatch/testing/integration'
require 'rails/generators/test_case'
+unless Minitest.run_with_rails_extension
+ Minitest.run_with_autorun = true
+ require 'active_support/testing/autorun'
+end
+
if defined?(ActiveRecord::Base)
ActiveRecord::Migration.maintain_test_schema!
diff --git a/railties/lib/rails/test_unit/minitest_plugin.rb b/railties/lib/rails/test_unit/minitest_plugin.rb
index 70ce9d3360..421f032d81 100644
--- a/railties/lib/rails/test_unit/minitest_plugin.rb
+++ b/railties/lib/rails/test_unit/minitest_plugin.rb
@@ -1,14 +1,51 @@
-require "minitest"
+require "active_support/core_ext/module/attribute_accessors"
require "rails/test_unit/reporter"
+require "rails/test_unit/test_requirer"
-def Minitest.plugin_rails_init(options)
- self.reporter << Rails::TestUnitReporter.new(options[:io], options)
- if $rails_test_runner && (method = $rails_test_runner.find_method)
- options[:filter] = method
+module Minitest
+ def self.plugin_rails_options(opts, options)
+ opts.separator ""
+ opts.separator "Usage: bin/rails test [options] [files or directories]"
+ opts.separator "You can run a single test by appending a line number to a filename:"
+ opts.separator ""
+ opts.separator " bin/rails test test/models/user_test.rb:27"
+ opts.separator ""
+ opts.separator "You can run multiple files and directories at the same time:"
+ opts.separator ""
+ opts.separator " bin/rails test test/controllers test/integration/login_test.rb"
+ opts.separator ""
+
+ opts.separator "Rails options:"
+ opts.on("-e", "--environment [ENV]",
+ "Run tests in the ENV environment") do |env|
+ options[:environment] = env.strip
+ end
+
+ opts.on("-b", "--backtrace",
+ "Show the complete backtrace") do
+ options[:full_backtrace] = true
+ end
+
+ options[:patterns] = opts.order!
end
- if !($rails_test_runner && $rails_test_runner.show_backtrace?)
- Minitest.backtrace_filter = Rails.backtrace_cleaner
+ def self.plugin_rails_init(options)
+ self.run_with_rails_extension = true
+
+ ENV["RAILS_ENV"] = options[:environment] || "test"
+
+ Rails::TestRequirer.require_files options[:patterns] unless run_with_autorun
+
+ unless options[:full_backtrace] || ENV["BACKTRACE"]
+ # Plugin can run without Rails loaded, check before filtering.
+ Minitest.backtrace_filter = Rails.backtrace_cleaner if Rails.respond_to?(:backtrace_cleaner)
+ end
+
+ self.reporter << Rails::TestUnitReporter.new(options[:io], options)
end
+
+ mattr_accessor(:run_with_autorun) { false }
+ mattr_accessor(:run_with_rails_extension) { false }
end
+
Minitest.extensions << 'rails'
diff --git a/railties/lib/rails/test_unit/reporter.rb b/railties/lib/rails/test_unit/reporter.rb
index 64e99626eb..bfdc9754d4 100644
--- a/railties/lib/rails/test_unit/reporter.rb
+++ b/railties/lib/rails/test_unit/reporter.rb
@@ -15,8 +15,12 @@ module Rails
filtered_results.reject!(&:skipped?) unless options[:verbose]
filtered_results.map do |result|
location, line = result.method(result.name).source_location
- "bin/rails test #{location}:#{line}"
+ "bin/rails test #{relative_path_for(location)}:#{line}"
end.join "\n"
end
+
+ def relative_path_for(file)
+ file.sub(/^#{Rails.root}\/?/, '')
+ end
end
end
diff --git a/railties/lib/rails/test_unit/runner.rb b/railties/lib/rails/test_unit/runner.rb
deleted file mode 100644
index 5573fa6904..0000000000
--- a/railties/lib/rails/test_unit/runner.rb
+++ /dev/null
@@ -1,137 +0,0 @@
-require "optparse"
-require "rake/file_list"
-require "method_source"
-
-module Rails
- class TestRunner
- class Options
- def self.parse(args)
- options = { backtrace: !ENV["BACKTRACE"].nil?, name: nil, environment: "test" }
-
- opt_parser = ::OptionParser.new do |opts|
- opts.banner = "Usage: bin/rails test [options] [file or directory]"
-
- opts.separator ""
- opts.on("-e", "--environment [ENV]",
- "Run tests in the ENV environment") do |env|
- options[:environment] = env.strip
- end
- opts.separator ""
- opts.separator "Filter options:"
- opts.separator ""
- opts.separator <<-DESC
- You can run a single test by appending the line number to filename:
-
- bin/rails test test/models/user_test.rb:27
-
- DESC
-
- opts.on("-n", "--name [NAME]",
- "Only run tests matching NAME") do |name|
- options[:name] = name
- end
- opts.on("-p", "--pattern [PATTERN]",
- "Only run tests matching PATTERN") do |pattern|
- options[:name] = "/#{pattern}/"
- end
-
- opts.separator ""
- opts.separator "Output options:"
-
- opts.on("-b", "--backtrace",
- "Show the complete backtrace") do
- options[:backtrace] = true
- end
-
- opts.separator ""
- opts.separator "Common options:"
-
- opts.on_tail("-h", "--help", "Show this message") do
- puts opts
- exit
- end
- end
-
- opt_parser.order!(args)
-
- options[:patterns] = []
- while arg = args.shift
- if (file_and_line = arg.split(':')).size > 1
- options[:filename], options[:line] = file_and_line
- options[:filename] = File.expand_path options[:filename]
- options[:line] &&= options[:line].to_i
- else
- arg = arg.gsub(':', '')
- if Dir.exist?("#{arg}")
- options[:patterns] << File.expand_path("#{arg}/**/*_test.rb")
- elsif File.file?(arg)
- options[:patterns] << File.expand_path(arg)
- end
- end
- end
- options
- end
- end
-
- def initialize(options = {})
- @options = options
- end
-
- def self.run(arguments)
- options = Rails::TestRunner::Options.parse(arguments)
- Rails::TestRunner.new(options).run
- end
-
- def run
- $rails_test_runner = self
- ENV["RAILS_ENV"] = @options[:environment]
- run_tests
- end
-
- def find_method
- return @options[:name] if @options[:name]
- return unless @options[:line]
- method = test_methods.find do |location, test_method, start_line, end_line|
- location == @options[:filename] &&
- (start_line..end_line).include?(@options[:line].to_i)
- end
- method[1] if method
- end
-
- def show_backtrace?
- @options[:backtrace]
- end
-
- def test_files
- return [@options[:filename]] if @options[:filename]
- if @options[:patterns] && @options[:patterns].count > 0
- pattern = @options[:patterns]
- else
- pattern = "test/**/*_test.rb"
- end
- Rake::FileList[pattern]
- end
-
- private
- def run_tests
- test_files.to_a.each do |file|
- require File.expand_path file
- end
- end
-
- def test_methods
- methods_map = []
- suites = Minitest::Runnable.runnables.shuffle
- suites.each do |suite_class|
- suite_class.runnable_methods.each do |test_method|
- method = suite_class.instance_method(test_method)
- location = method.source_location
- start_line = location.last
- end_line = method.source.split("\n").size + start_line - 1
- methods_map << [File.expand_path(location.first), test_method, start_line, end_line]
- end
- end
- methods_map
- end
- end
-end
diff --git a/railties/lib/rails/test_unit/test_requirer.rb b/railties/lib/rails/test_unit/test_requirer.rb
new file mode 100644
index 0000000000..84c2256729
--- /dev/null
+++ b/railties/lib/rails/test_unit/test_requirer.rb
@@ -0,0 +1,28 @@
+require 'active_support/core_ext/object/blank'
+require 'rake/file_list'
+
+module Rails
+ class TestRequirer # :nodoc:
+ class << self
+ def require_files(patterns)
+ patterns = expand_patterns(patterns)
+
+ Rake::FileList[patterns.compact.presence || 'test/**/*_test.rb'].to_a.each do |file|
+ require File.expand_path(file)
+ end
+ end
+
+ private
+ def expand_patterns(patterns)
+ patterns.map do |arg|
+ arg = arg.gsub(/:(\d+)?$/, '')
+ if Dir.exist?(arg)
+ "#{arg}/**/*_test.rb"
+ elsif File.file?(arg)
+ arg
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake
index 0f26621b59..dda492f974 100644
--- a/railties/lib/rails/test_unit/testing.rake
+++ b/railties/lib/rails/test_unit/testing.rake
@@ -1,12 +1,13 @@
-require "rails/test_unit/runner"
+gem 'minitest'
+require 'minitest'
+require 'rails/test_unit/minitest_plugin'
task default: :test
desc "Runs all tests in test folder"
task :test do
$: << "test"
- args = ARGV[0] == "test" ? ARGV[1..-1] : []
- Rails::TestRunner.run(args)
+ Minitest.run(['test'])
end
namespace :test do
@@ -23,22 +24,22 @@ namespace :test do
["models", "helpers", "controllers", "mailers", "integration", "jobs"].each do |name|
task name => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/#{name}"])
+ Minitest.run(["test/#{name}"])
end
end
task :generators => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/lib/generators"])
+ Minitest.run(["test/lib/generators"])
end
task :units => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/models", "test/helpers", "test/unit"])
+ Minitest.run(["test/models", "test/helpers", "test/unit"])
end
task :functionals => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/controllers", "test/mailers", "test/functional"])
+ Minitest.run(["test/controllers", "test/mailers", "test/functional"])
end
end
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 38516a1c1a..f677a7c42a 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -745,6 +745,19 @@ module ApplicationTests
assert_equal [::MyMailObserver, ::MyOtherMailObserver], ::Mail.send(:class_variable_get, "@@delivery_notification_observers")
end
+ test "allows setting the queue name for the ActionMailer::DeliveryJob" do
+ add_to_config <<-RUBY
+ config.action_mailer.deliver_later_queue_name = 'test_default'
+ RUBY
+
+ require "#{app_path}/config/environment"
+ require "mail"
+
+ _ = ActionMailer::Base
+
+ assert_equal 'test_default', ActionMailer::Base.send(:class_variable_get, "@@deliver_later_queue_name")
+ end
+
test "valid timezone is setup correctly" do
add_to_config <<-RUBY
config.root = "#{app_path}"
diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb
index 31bc003dcb..7bf123d12b 100644
--- a/railties/test/application/console_test.rb
+++ b/railties/test/application/console_test.rb
@@ -29,6 +29,18 @@ class ConsoleTest < ActiveSupport::TestCase
assert_instance_of ActionDispatch::Integration::Session, console_session
end
+ def test_app_can_access_path_helper_method
+ app_file 'config/routes.rb', <<-RUBY
+ Rails.application.routes.draw do
+ get 'foo', to: 'foo#index'
+ end
+ RUBY
+
+ load_environment
+ console_session = irb_context.app
+ assert_equal '/foo', console_session.foo_path
+ end
+
def test_new_session_should_return_integration_session
load_environment
session = irb_context.new_session
diff --git a/railties/test/application/multiple_applications_test.rb b/railties/test/application/multiple_applications_test.rb
index cddc79cc85..f2770a9cb4 100644
--- a/railties/test/application/multiple_applications_test.rb
+++ b/railties/test/application/multiple_applications_test.rb
@@ -118,7 +118,7 @@ module ApplicationTests
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!
+ AppTemplate::Application.create { config.eager_load = false }.initialize!
assert_equal 3, run_count, "There should have been three initializers that incremented the count"
end
diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb
index c122b315c0..bbaab42a7f 100644
--- a/railties/test/application/test_runner_test.rb
+++ b/railties/test/application/test_runner_test.rb
@@ -1,9 +1,10 @@
require 'isolation/abstract_unit'
require 'active_support/core_ext/string/strip'
+require 'env_helpers'
module ApplicationTests
class TestRunnerTest < ActiveSupport::TestCase
- include ActiveSupport::Testing::Isolation
+ include ActiveSupport::Testing::Isolation, EnvHelpers
def setup
build_app
@@ -14,20 +15,6 @@ module ApplicationTests
teardown_app
end
- def test_run_in_test_environment
- app_file 'test/unit/env_test.rb', <<-RUBY
- require 'test_helper'
-
- class EnvTest < ActiveSupport::TestCase
- def test_env
- puts "Current Environment: \#{Rails.env}"
- end
- end
- RUBY
-
- assert_match "Current Environment: test", run_test_command('test/unit/env_test.rb')
- end
-
def test_run_single_file
create_test_file :models, 'foo'
create_test_file :models, 'bar'
@@ -187,7 +174,7 @@ module ApplicationTests
end
RUBY
- run_test_command('-p rikka test/unit/chu_2_koi_test.rb').tap do |output|
+ run_test_command('-n /rikka/ test/unit/chu_2_koi_test.rb').tap do |output|
assert_match "Rikka", output
assert_no_match "Sanae", output
end
@@ -229,24 +216,128 @@ module ApplicationTests
assert_match "development", run_test_command('test/unit/env_test.rb')
end
+ def test_run_in_test_environment_by_default
+ create_env_test
+
+ assert_match "Current Environment: test", run_test_command('test/unit/env_test.rb')
+ end
+
def test_run_different_environment
- env = "development"
- app_file 'test/unit/env_test.rb', <<-RUBY
+ create_env_test
+
+ assert_match "Current Environment: development",
+ run_test_command("-e development test/unit/env_test.rb")
+ end
+
+ def test_generated_scaffold_works_with_rails_test
+ create_scaffold
+ assert_match "0 failures, 0 errors, 0 skips", run_test_command('')
+ end
+
+ def test_run_multiple_folders
+ create_test_file :models, 'account'
+ create_test_file :controllers, 'accounts_controller'
+
+ run_test_command('test/models test/controllers').tap do |output|
+ assert_match 'AccountTest', output
+ assert_match 'AccountsControllerTest', output
+ assert_match '2 runs, 2 assertions, 0 failures, 0 errors, 0 skips', output
+ end
+ end
+
+ def test_run_with_ruby_command
+ app_file 'test/models/post_test.rb', <<-RUBY
require 'test_helper'
- class EnvTest < ActiveSupport::TestCase
- def test_env
- puts Rails.env
+ class PostTest < ActiveSupport::TestCase
+ test 'declarative syntax works' do
+ puts 'PostTest'
+ assert true
end
end
RUBY
- assert_match env, run_test_command("-e #{env} test/unit/env_test.rb")
+ Dir.chdir(app_path) do
+ `ruby -Itest test/models/post_test.rb`.tap do |output|
+ assert_match 'PostTest', output
+ assert_no_match 'is already defined in', output
+ end
+ end
end
- def test_generated_scaffold_works_with_rails_test
- create_scaffold
- assert_match "0 failures, 0 errors, 0 skips", run_test_command('')
+ def test_mix_files_and_line_filters
+ create_test_file :models, 'account'
+ app_file 'test/models/post_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class PostTest < ActiveSupport::TestCase
+ def test_post
+ puts 'PostTest'
+ assert true
+ end
+
+ def test_line_filter_does_not_run_this
+ assert true
+ end
+ end
+ RUBY
+
+ run_test_command('test/models/account_test.rb test/models/post_test.rb:4').tap do |output|
+ assert_match 'AccountTest', output
+ assert_match 'PostTest', output
+ assert_match '2 runs, 2 assertions', output
+ end
+ end
+
+ def test_multiple_line_filters
+ create_test_file :models, 'account'
+ create_test_file :models, 'post'
+
+ run_test_command('test/models/account_test.rb:4 test/models/post_test.rb:4').tap do |output|
+ assert_match 'AccountTest', output
+ assert_match 'PostTest', output
+ end
+ end
+
+ def test_line_filter_without_line_runs_all_tests
+ create_test_file :models, 'account'
+
+ run_test_command('test/models/account_test.rb:').tap do |output|
+ assert_match 'AccountTest', output
+ end
+ end
+
+ def test_shows_filtered_backtrace_by_default
+ create_backtrace_test
+
+ assert_match 'Rails::BacktraceCleaner', run_test_command('test/unit/backtrace_test.rb')
+ end
+
+ def test_backtrace_option
+ create_backtrace_test
+
+ assert_match 'Minitest::BacktraceFilter', run_test_command('test/unit/backtrace_test.rb -b')
+ assert_match 'Minitest::BacktraceFilter',
+ run_test_command('test/unit/backtrace_test.rb --backtrace')
+ end
+
+ def test_show_full_backtrace_using_backtrace_environment_variable
+ create_backtrace_test
+
+ switch_env 'BACKTRACE', 'true' do
+ assert_match 'Minitest::BacktraceFilter', run_test_command('test/unit/backtrace_test.rb')
+ end
+ end
+
+ def test_run_app_without_rails_loaded
+ # Simulate a real Rails app boot.
+ app_file 'config/boot.rb', <<-RUBY
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+
+ require 'bundler/setup' # Set up gems listed in the Gemfile.
+ RUBY
+
+ assert_match '0 runs, 0 assertions', run_test_command('')
end
private
@@ -284,6 +375,18 @@ module ApplicationTests
RUBY
end
+ def create_backtrace_test
+ app_file 'test/unit/backtrace_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class BacktraceTest < ActiveSupport::TestCase
+ def test_backtrace
+ puts Minitest.backtrace_filter
+ end
+ end
+ RUBY
+ end
+
def create_schema
app_file 'db/schema.rb', ''
end
@@ -301,6 +404,18 @@ module ApplicationTests
RUBY
end
+ def create_env_test
+ app_file 'test/unit/env_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class EnvTest < ActiveSupport::TestCase
+ def test_env
+ puts "Current Environment: \#{Rails.env}"
+ end
+ end
+ RUBY
+ end
+
def create_scaffold
script 'generate scaffold user name:string'
Dir.chdir(app_path) { File.exist?('app/models/user.rb') }
diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb
index 61652e5052..0e997f4ba7 100644
--- a/railties/test/application/test_test.rb
+++ b/railties/test/application/test_test.rb
@@ -44,7 +44,7 @@ module ApplicationTests
def test_index
get '/posts'
assert_response :success
- assert_template "index"
+ assert_includes @response.body, 'Posts#index'
end
end
RUBY
@@ -64,8 +64,8 @@ module ApplicationTests
RUBY
output = run_test_file('unit/failing_test.rb', env: { "BACKTRACE" => "1" })
- assert_match %r{/app/test/unit/failing_test\.rb}, output
- assert_match %r{/app/test/unit/failing_test\.rb:4}, output
+ assert_match %r{test/unit/failing_test\.rb}, output
+ assert_match %r{test/unit/failing_test\.rb:4}, output
end
test "ruby schema migrations" do
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index c0b88089b3..4a4317c4f4 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -1,7 +1,7 @@
require 'generators/generators_test_helper'
require 'rails/generators/rails/app/app_generator'
require 'env_helpers'
-require 'mocha/setup' # FIXME: stop using mocha
+require 'minitest/mock'
class ActionsTest < Rails::Generators::TestCase
include GeneratorsTestHelper
@@ -12,11 +12,13 @@ class ActionsTest < Rails::Generators::TestCase
def setup
Rails.application = TestApp::Application
+ @mock_generator = Minitest::Mock.new
super
end
def teardown
Rails.application = TestApp::Application.instance
+ @mock_generator.verify
end
def test_invoke_other_generator_with_shortcut
@@ -140,13 +142,18 @@ class ActionsTest < Rails::Generators::TestCase
end
def test_git_with_symbol_should_run_command_using_git_scm
- generator.expects(:run).once.with('git init')
- action :git, :init
+ @mock_generator.expect(:call, nil, ['git init'])
+ generator.stub(:run, @mock_generator) do
+ action :git, :init
+ end
end
def test_git_with_hash_should_run_each_command_using_git_scm
- generator.expects(:run).times(2)
- action :git, rm: 'README', add: '.'
+ @mock_generator.expect(:call, nil, ["git rm README"])
+ @mock_generator.expect(:call, nil, ["git add ."])
+ generator.stub(:run, @mock_generator) do
+ action :git, rm: 'README', add: '.'
+ end
end
def test_vendor_should_write_data_to_file_in_vendor
@@ -170,46 +177,60 @@ class ActionsTest < Rails::Generators::TestCase
end
def test_generate_should_run_script_generate_with_argument_and_options
- generator.expects(:run_ruby_script).once.with('bin/rails generate model MyModel', verbose: false)
- action :generate, 'model', 'MyModel'
+ @mock_generator.expect(:call, nil, ['bin/rails generate model MyModel', verbose: false])
+ generator.stub(:run_ruby_script, @mock_generator) do
+ action :generate, 'model', 'MyModel'
+ end
end
def test_rake_should_run_rake_command_with_default_env
- generator.expects(:run).once.with("rake log:clear RAILS_ENV=development", verbose: false)
- with_rails_env nil do
- action :rake, 'log:clear'
+ @mock_generator.expect(:call, nil, ["rake log:clear RAILS_ENV=development", verbose: false])
+ generator.stub(:run, @mock_generator) do
+ with_rails_env nil do
+ action :rake, 'log:clear'
+ end
end
end
def test_rake_with_env_option_should_run_rake_command_in_env
- generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', verbose: false)
- action :rake, 'log:clear', env: 'production'
+ @mock_generator.expect(:call, nil, ['rake log:clear RAILS_ENV=production', verbose: false])
+ generator.stub(:run, @mock_generator) do
+ action :rake, 'log:clear', env: 'production'
+ end
end
def test_rake_with_rails_env_variable_should_run_rake_command_in_env
- generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', verbose: false)
- with_rails_env "production" do
- action :rake, 'log:clear'
+ @mock_generator.expect(:call, nil, ['rake log:clear RAILS_ENV=production', verbose: false])
+ generator.stub(:run, @mock_generator) do
+ with_rails_env "production" do
+ action :rake, 'log:clear'
+ end
end
end
def test_env_option_should_win_over_rails_env_variable_when_running_rake
- generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', verbose: false)
- with_rails_env "staging" do
- action :rake, 'log:clear', env: 'production'
+ @mock_generator.expect(:call, nil, ['rake log:clear RAILS_ENV=production', verbose: false])
+ generator.stub(:run, @mock_generator) do
+ with_rails_env "staging" do
+ action :rake, 'log:clear', env: 'production'
+ end
end
end
def test_rake_with_sudo_option_should_run_rake_command_with_sudo
- generator.expects(:run).once.with("sudo rake log:clear RAILS_ENV=development", verbose: false)
- with_rails_env nil do
- action :rake, 'log:clear', sudo: true
+ @mock_generator.expect(:call, nil, ["sudo rake log:clear RAILS_ENV=development", verbose: false])
+ generator.stub(:run, @mock_generator) do
+ with_rails_env nil do
+ action :rake, 'log:clear', sudo: true
+ end
end
end
def test_capify_should_run_the_capify_command
- generator.expects(:run).once.with('capify .', verbose: false)
- action :capify!
+ @mock_generator.expect(:call, nil, ['capify .', verbose: false])
+ generator.stub(:run, @mock_generator) do
+ action :capify!
+ end
end
def test_route_should_add_data_to_the_routes_block_in_config_routes
@@ -245,15 +266,19 @@ F
def test_readme
run_generator
- Rails::Generators::AppGenerator.expects(:source_root).times(2).returns(destination_root)
- assert_match "application up and running", action(:readme, "README.md")
+ 2.times { @mock_generator.expect(:call, destination_root,[]) }
+ Rails::Generators::AppGenerator.stub(:source_root, @mock_generator) do
+ assert_match "application up and running", action(:readme, "README.md")
+ end
end
def test_readme_with_quiet
generator(default_arguments, quiet: true)
run_generator
- Rails::Generators::AppGenerator.expects(:source_root).times(2).returns(destination_root)
- assert_no_match "application up and running", action(:readme, "README.md")
+ 2.times { @mock_generator.expect(:call, destination_root,[]) }
+ Rails::Generators::AppGenerator.stub(:source_root, @mock_generator) do
+ assert_no_match "application up and running", action(:readme, "README.md")
+ end
end
def test_log
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index 34e752cea1..7c282377d7 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -174,4 +174,15 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
end
end
end
+
+ def test_controller_tests_pass_by_default_inside_mountable_engine
+ Dir.chdir(destination_root) { `bundle exec rails plugin new bukkits --mountable` }
+
+ engine_path = File.join(destination_root, "bukkits")
+
+ Dir.chdir(engine_path) do
+ quietly { `bin/rails g controller dashboard foo` }
+ assert_match(/2 runs, 2 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`)
+ end
+ end
end
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index ee06802874..8f43747b9e 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -393,4 +393,18 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_match(/password_digest: <%= BCrypt::Password.create\('secret'\) %>/, content)
end
end
+
+ def test_scaffold_tests_pass_by_default_inside_mountable_engine
+ Dir.chdir(destination_root) { `bundle exec rails plugin new bukkits --mountable` }
+
+ engine_path = File.join(destination_root, "bukkits")
+
+ Dir.chdir(engine_path) do
+ quietly do
+ `bin/rails g scaffold User name:string age:integer;
+ bundle exec rake db:migrate`
+ end
+ assert_match(/8 runs, 13 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`)
+ end
+ end
end
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
index 3a2195035f..f983b45d2b 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -86,15 +86,6 @@ module SharedGeneratorTests
end
end
- def test_template_is_executed_when_supplied
- path = "https://gist.github.com/josevalim/103208/raw/"
- template = %{ say "It works!" }
- template.instance_eval "def read; self; end" # Make the string respond to read
-
- generator([destination_root], template: path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
- quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) }
- end
-
def test_template_is_executed_when_supplied_an_https_path
path = "https://gist.github.com/josevalim/103208/raw/"
template = %{ say "It works!" }
diff --git a/railties/test/test_unit/runner_test.rb b/railties/test/test_unit/runner_test.rb
deleted file mode 100644
index 9ea8b2c114..0000000000
--- a/railties/test/test_unit/runner_test.rb
+++ /dev/null
@@ -1,111 +0,0 @@
-require 'abstract_unit'
-require 'env_helpers'
-require 'rails/test_unit/runner'
-
-class TestUnitTestRunnerTest < ActiveSupport::TestCase
- include EnvHelpers
-
- setup do
- @options = Rails::TestRunner::Options
- end
-
- test "shows the filtered backtrace by default" do
- options = @options.parse([])
- assert_not options[:backtrace]
- end
-
- test "has --backtrace (-b) option to show the full backtrace" do
- options = @options.parse(["-b"])
- assert options[:backtrace]
-
- options = @options.parse(["--backtrace"])
- assert options[:backtrace]
- end
-
- test "show full backtrace using BACKTRACE environment variable" do
- switch_env "BACKTRACE", "true" do
- options = @options.parse([])
- assert options[:backtrace]
- end
- end
-
- test "tests run in the test environment by default" do
- options = @options.parse([])
- assert_equal "test", options[:environment]
- end
-
- test "can run in a specific environment" do
- options = @options.parse(["-e development"])
- assert_equal "development", options[:environment]
- end
-
- test "parse the filename and line" do
- file = "test/test_unit/runner_test.rb"
- absolute_file = File.expand_path __FILE__
- options = @options.parse(["#{file}:20"])
- assert_equal absolute_file, options[:filename]
- assert_equal 20, options[:line]
-
- options = @options.parse(["#{file}:"])
- assert_equal [absolute_file], options[:patterns]
- assert_nil options[:line]
-
- options = @options.parse([file])
- assert_equal [absolute_file], options[:patterns]
- assert_nil options[:line]
- end
-
- test "find_method on same file" do
- options = @options.parse(["#{__FILE__}:#{__LINE__}"])
- runner = Rails::TestRunner.new(options)
- assert_equal "test_find_method_on_same_file", runner.find_method
- end
-
- test "find_method on a different file" do
- options = @options.parse(["foobar.rb:#{__LINE__}"])
- runner = Rails::TestRunner.new(options)
- assert_nil runner.find_method
- end
-
- test "run all tests in a directory" do
- options = @options.parse([__dir__])
-
- assert_equal ["#{__dir__}/**/*_test.rb"], options[:patterns]
- assert_nil options[:filename]
- assert_nil options[:line]
- end
-
- test "run multiple folders" do
- application_dir = File.expand_path("#{__dir__}/../application")
-
- options = @options.parse([__dir__, application_dir])
-
- assert_equal ["#{__dir__}/**/*_test.rb", "#{application_dir}/**/*_test.rb"], options[:patterns]
- assert_nil options[:filename]
- assert_nil options[:line]
-
- runner = Rails::TestRunner.new(options)
- assert runner.test_files.size > 0
- end
-
- test "run multiple files and run one file by line" do
- line = __LINE__
- absolute_file = File.expand_path(__FILE__)
- options = @options.parse([__dir__, "#{__FILE__}:#{line}"])
-
- assert_equal ["#{__dir__}/**/*_test.rb"], options[:patterns]
- assert_equal absolute_file, options[:filename]
- assert_equal line, options[:line]
-
- runner = Rails::TestRunner.new(options)
- assert_equal [absolute_file], runner.test_files, 'Only returns the file that running by line'
- end
-
- test "running multiple files passing line number" do
- line = __LINE__
- options = @options.parse(["foobar.rb:8", "#{__FILE__}:#{line}"])
-
- assert_equal File.expand_path(__FILE__), options[:filename], 'Returns the last file'
- assert_equal line, options[:line]
- end
-end
diff --git a/tools/profile b/tools/profile
index eb7fc7792b..191e73b3dd 100755
--- a/tools/profile
+++ b/tools/profile
@@ -117,9 +117,9 @@ rescue LoadError
def camelize(uppercase_first_letter = true)
string = self
if uppercase_first_letter
- string = string.sub(/^[a-z\d]*/) { $&.capitalize }
+ string = string.sub(/^[a-z\d]*/) { |match| match.capitalize }
else
- string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
+ string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { |match| match.downcase }
end
string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
end