aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.rubocop.yml1
-rw-r--r--Gemfile1
-rw-r--r--Gemfile.lock63
-rw-r--r--actioncable/test/channel/stream_test.rb2
-rw-r--r--actionpack/lib/action_controller/railtie.rb2
-rw-r--r--actionpack/test/controller/live_stream_test.rb4
-rw-r--r--actionpack/test/controller/redirect_test.rb2
-rw-r--r--actionpack/test/controller/resources_test.rb20
-rw-r--r--actionpack/test/controller/test_case_test.rb8
-rw-r--r--actionpack/test/dispatch/routing_assertions_test.rb12
-rw-r--r--actionpack/test/journey/router_test.rb10
-rw-r--r--actionview/test/actionpack/abstract/abstract_controller_test.rb4
-rw-r--r--actionview/test/template/date_helper_test.rb52
-rw-r--r--actionview/test/template/form_collections_helper_test.rb8
-rw-r--r--actionview/test/template/form_helper_test.rb2
-rw-r--r--actionview/test/template/form_options_helper_test.rb48
-rw-r--r--actionview/test/template/form_tag_helper_test.rb16
-rw-r--r--actionview/test/template/text_helper_test.rb8
-rw-r--r--activerecord/CHANGELOG.md4
-rw-r--r--activerecord/lib/active_record/associations/preloader/association.rb12
-rw-r--r--activerecord/lib/active_record/associations/through_association.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb11
-rw-r--r--activerecord/lib/active_record/reflection.rb9
-rw-r--r--activerecord/lib/active_record/scoping/named.rb10
-rw-r--r--activerecord/lib/active_record/transactions.rb2
-rw-r--r--activerecord/lib/rails/generators/active_record/application_record/application_record_generator.rb11
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb19
-rw-r--r--activerecord/test/cases/attribute_set_test.rb2
-rw-r--r--activerecord/test/cases/enum_test.rb14
-rw-r--r--activestorage/README.md29
-rw-r--r--activestorage/app/jobs/active_storage/purge_job.rb2
-rw-r--r--activestorage/app/models/active_storage/attachment.rb6
-rw-r--r--activestorage/app/models/active_storage/blob.rb30
-rw-r--r--activestorage/app/models/active_storage/variant.rb10
-rw-r--r--activestorage/app/models/active_storage/variation.rb6
-rw-r--r--activestorage/lib/active_storage/attached.rb4
-rw-r--r--activestorage/lib/active_storage/attached/macros.rb2
-rw-r--r--activestorage/lib/active_storage/gem_version.rb2
-rw-r--r--activestorage/lib/active_storage/log_subscriber.rb2
-rw-r--r--activestorage/lib/active_storage/service/azure_storage_service.rb2
-rw-r--r--activestorage/lib/active_storage/service/disk_service.rb6
-rw-r--r--activestorage/lib/active_storage/service/gcs_service.rb2
-rw-r--r--activestorage/lib/active_storage/service/s3_service.rb2
-rw-r--r--activestorage/lib/tasks/activestorage.rake2
-rw-r--r--activesupport/lib/active_support/lazy_load_hooks.rb34
-rw-r--r--activesupport/test/json/encoding_test.rb4
-rw-r--r--activesupport/test/lazy_load_hooks_test.rb37
-rw-r--r--guides/source/active_record_callbacks.md2
-rw-r--r--guides/source/engines.md3
-rw-r--r--guides/source/generators.md6
-rw-r--r--guides/source/plugins.md57
-rw-r--r--guides/source/security.md6
-rw-r--r--guides/source/upgrading_ruby_on_rails.md2
-rw-r--r--railties/CHANGELOG.md8
-rw-r--r--railties/lib/rails/engine/updater.rb2
-rw-r--r--railties/lib/rails/generators/actions.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/gitignore1
-rw-r--r--railties/lib/rails/generators/rails/plugin/plugin_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/gitignore4
-rw-r--r--railties/lib/rails/tasks/framework.rake2
-rw-r--r--railties/test/application/assets_test.rb4
-rw-r--r--railties/test/application/configuration_test.rb14
-rw-r--r--railties/test/application/mailer_previews_test.rb4
-rw-r--r--railties/test/application/middleware/cache_test.rb10
-rw-r--r--railties/test/application/middleware_test.rb2
-rw-r--r--railties/test/generators/api_app_generator_test.rb6
-rw-r--r--railties/test/generators/app_generator_test.rb28
-rw-r--r--railties/test/generators/create_migration_test.rb8
-rw-r--r--railties/test/generators/plugin_generator_test.rb4
-rw-r--r--railties/test/generators/shared_generator_tests.rb30
-rw-r--r--railties/test/railties/engine_test.rb8
-rw-r--r--railties/test/railties/mounted_engine_test.rb12
72 files changed, 437 insertions, 331 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index d9c1e28878..c1101d849b 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -16,6 +16,7 @@ Style/AndOr:
# method call.
Style/BracesAroundHashParameters:
Enabled: true
+ EnforcedStyle: context_dependent
# Align `when` with `case`.
Layout/CaseIndentation:
diff --git a/Gemfile b/Gemfile
index 7fc8aa7552..0b98dc1f75 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,7 +10,6 @@ gem "arel", github: "rails/arel"
# We need a newish Rake since Active Job sets its test tasks' descriptions.
gem "rake", ">= 11.1"
-gem "thor", github: "erikhuda/thor"
# This needs to be with require false to ensure correct loading order, as it has to
# be loaded after loading the test library.
diff --git a/Gemfile.lock b/Gemfile.lock
index 0738e1c35d..2096465a8b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -7,12 +7,6 @@ GIT
pg (>= 0.17, < 0.20)
GIT
- remote: https://github.com/erikhuda/thor.git
- revision: df5ba2b653a28087b3617d6c082b00866b0c0d6c
- specs:
- thor (0.19.4)
-
-GIT
remote: https://github.com/matthewd/rb-inotify.git
revision: 856730aad4b285969e8dd621e44808a7c5af4242
branch: close-handling
@@ -31,7 +25,7 @@ GIT
GIT
remote: https://github.com/rails/arel.git
- revision: f4227bf20a16a1d688afc24cf0038e2f98905dd4
+ revision: 42510bf71472e2e35d9becb546edd05562672344
specs:
arel (9.0.0.alpha)
@@ -117,23 +111,21 @@ GEM
public_suffix (~> 2.0, >= 2.0.2)
amq-protocol (2.2.0)
ast (2.3.0)
- aws-sdk (2.10.19)
- aws-sdk-resources (= 2.10.19)
- aws-sdk-core (2.10.19)
+ aws-sdk (2.10.27)
+ aws-sdk-resources (= 2.10.27)
+ aws-sdk-core (2.10.27)
aws-sigv4 (~> 1.0)
jmespath (~> 1.0)
- aws-sdk-resources (2.10.19)
- aws-sdk-core (= 2.10.19)
+ aws-sdk-resources (2.10.27)
+ aws-sdk-core (= 2.10.27)
aws-sigv4 (1.0.1)
- azure-core (0.1.9)
+ azure-core (0.1.10)
faraday (~> 0.9)
faraday_middleware (~> 0.10)
- nokogiri (~> 1.7)
- azure-storage (0.11.4.preview)
+ azure-storage (0.12.3.preview)
azure-core (~> 0.1)
faraday (~> 0.9)
faraday_middleware (~> 0.10)
- nokogiri (~> 1.6)
backburner (1.4.1)
beaneater (~> 1.0)
concurrent-ruby (~> 1.0.1)
@@ -156,7 +148,7 @@ GEM
thor (~> 0.19.1)
useragent (~> 0.16.7)
blade-qunit_adapter (2.0.1)
- blade-sauce_labs_plugin (0.7.1)
+ blade-sauce_labs_plugin (0.7.2)
childprocess
faraday
selenium-webdriver
@@ -166,9 +158,9 @@ GEM
bunny (2.6.6)
amq-protocol (>= 2.1.0)
byebug (9.0.6)
- capybara (2.14.4)
+ capybara (2.15.1)
addressable
- mime-types (>= 1.16)
+ mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
@@ -213,13 +205,13 @@ GEM
et-orbi (1.0.5)
tzinfo
event_emitter (0.2.6)
- eventmachine (1.2.3)
- eventmachine (1.2.3-x64-mingw32)
- eventmachine (1.2.3-x86-mingw32)
+ eventmachine (1.2.5)
+ eventmachine (1.2.5-x64-mingw32)
+ eventmachine (1.2.5-x86-mingw32)
execjs (2.7.0)
- faraday (0.12.2)
+ faraday (0.13.0)
multipart-post (>= 1.2, < 3)
- faraday_middleware (0.12.0)
+ faraday_middleware (0.12.2)
faraday (>= 0.7.4, < 1.0)
faye (1.2.4)
cookiejar (>= 0.3.0)
@@ -249,7 +241,7 @@ GEM
googleauth (~> 0.5.1)
google-cloud-env (1.0.1)
faraday (~> 0.11)
- google-cloud-storage (1.3.0)
+ google-cloud-storage (1.4.0)
digest-crc (~> 0.4)
google-api-client (~> 0.13.0)
google-cloud-core (~> 1.0)
@@ -295,8 +287,9 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mini_magick (4.8.0)
+ mini_mime (0.1.4)
mini_portile2 (2.2.0)
- minitest (5.10.2)
+ minitest (5.10.3)
minitest-bisect (1.4.0)
minitest-server (~> 1.0)
path_expander (~> 1.0)
@@ -312,9 +305,9 @@ GEM
multipart-post (2.0.0)
mustache (1.0.5)
mustermann (1.0.0)
- mysql2 (0.4.8)
- mysql2 (0.4.8-x64-mingw32)
- mysql2 (0.4.8-x86-mingw32)
+ mysql2 (0.4.9)
+ mysql2 (0.4.9-x64-mingw32)
+ mysql2 (0.4.9-x86-mingw32)
nio4r (2.1.0)
nokogiri (1.8.0)
mini_portile2 (~> 2.2.0)
@@ -323,10 +316,10 @@ GEM
nokogiri (1.8.0-x86-mingw32)
mini_portile2 (~> 2.2.0)
os (0.9.6)
- parallel (1.11.2)
+ parallel (1.12.0)
parser (2.4.0.0)
ast (~> 2.2)
- path_expander (1.0.1)
+ path_expander (1.0.2)
pg (0.19.0)
pg (0.19.0-x64-mingw32)
pg (0.19.0-x86-mingw32)
@@ -340,7 +333,7 @@ GEM
qu (= 0.2.0)
redis-namespace
simple_uuid
- que (0.13.1)
+ que (0.14.0)
racc (1.4.14)
rack (2.0.3)
rack-cache (1.7.0)
@@ -398,10 +391,10 @@ GEM
rb-inotify (~> 0.9, >= 0.9.7)
sdoc (1.0.0.rc2)
rdoc (~> 5.0)
- selenium-webdriver (3.4.4)
+ selenium-webdriver (3.5.1)
childprocess (~> 0.5)
rubyzip (~> 1.0)
- sequel (4.48.0)
+ sequel (4.49.0)
serverengine (1.5.11)
sigdump (~> 0.2.2)
sidekiq (5.0.4)
@@ -444,6 +437,7 @@ GEM
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
+ thor (0.19.4)
thread (0.1.7)
thread_safe (0.3.6)
tilt (2.0.8)
@@ -535,7 +529,6 @@ DEPENDENCIES
sqlite3 (~> 1.3.6)
stackprof
sucker_punch
- thor!
turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
diff --git a/actioncable/test/channel/stream_test.rb b/actioncable/test/channel/stream_test.rb
index 79c25d936f..eca06fe365 100644
--- a/actioncable/test/channel/stream_test.rb
+++ b/actioncable/test/channel/stream_test.rb
@@ -154,7 +154,7 @@ module ActionCable::StreamTests
subscribe_to connection, identifiers: { id: 1 }
connection.websocket.expects(:transmit)
- @server.broadcast "test_room_1", { foo: "bar" }, coder: DummyEncoder
+ @server.broadcast "test_room_1", { foo: "bar" }, { coder: DummyEncoder }
wait_for_async
wait_for_executor connection.server.worker_pool.executor
end
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index cc02c9a53a..769be39004 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -24,7 +24,7 @@ module ActionController
initializer "action_controller.parameters_config" do |app|
options = app.config.action_controller
- ActiveSupport.on_load(:action_controller) do
+ ActiveSupport.on_load(:action_controller, run_once: true) do
ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
if app.config.action_controller[:always_permitted_parameters]
ActionController::Parameters.always_permitted_parameters =
diff --git a/actionpack/test/controller/live_stream_test.rb b/actionpack/test/controller/live_stream_test.rb
index 1ccbee8a0f..8cfb43a6bc 100644
--- a/actionpack/test/controller/live_stream_test.rb
+++ b/actionpack/test/controller/live_stream_test.rb
@@ -30,7 +30,7 @@ module ActionController
def sse_with_retry
sse = SSE.new(response.stream, retry: 1000)
sse.write("{\"name\":\"John\"}")
- sse.write({ name: "Ryan" }, retry: 1500)
+ sse.write({ name: "Ryan" }, { retry: 1500 })
ensure
sse.close
end
@@ -38,7 +38,7 @@ module ActionController
def sse_with_id
sse = SSE.new(response.stream)
sse.write("{\"name\":\"John\"}", id: 1)
- sse.write({ name: "Ryan" }, id: 2)
+ sse.write({ name: "Ryan" }, { id: 2 })
ensure
sse.close
end
diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb
index 7546b36bc3..e447b66486 100644
--- a/actionpack/test/controller/redirect_test.rb
+++ b/actionpack/test/controller/redirect_test.rb
@@ -35,7 +35,7 @@ class RedirectController < ActionController::Base
end
def redirect_with_status_hash
- redirect_to({ action: "hello_world" }, status: 301)
+ redirect_to({ action: "hello_world" }, { status: 301 })
end
def redirect_with_protocol
diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb
index 871fba7e73..3d98237003 100644
--- a/actionpack/test/controller/resources_test.rb
+++ b/actionpack/test/controller/resources_test.rb
@@ -943,8 +943,8 @@ class ResourcesTest < ActionController::TestCase
assert_resource_allowed_routes("products", {}, { id: "1" }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
- assert_recognizes({ controller: "products", action: "sale" }, path: "products/sale", method: :get)
- assert_recognizes({ controller: "products", action: "sale", format: "xml" }, path: "products/sale.xml", method: :get)
+ assert_recognizes({ controller: "products", action: "sale" }, { path: "products/sale", method: :get })
+ assert_recognizes({ controller: "products", action: "sale", format: "xml" }, { path: "products/sale.xml", method: :get })
end
end
@@ -959,8 +959,8 @@ class ResourcesTest < ActionController::TestCase
assert_resource_allowed_routes("products", {}, { id: "1" }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
assert_resource_allowed_routes("products", { format: "xml" }, { id: "1" }, [], [:index, :new, :create, :show, :edit, :update, :destroy])
- assert_recognizes({ controller: "products", action: "preview", id: "1" }, path: "products/1/preview", method: :get)
- assert_recognizes({ controller: "products", action: "preview", id: "1", format: "xml" }, path: "products/1/preview.xml", method: :get)
+ assert_recognizes({ controller: "products", action: "preview", id: "1" }, { path: "products/1/preview", method: :get })
+ assert_recognizes({ controller: "products", action: "preview", id: "1", format: "xml" }, { path: "products/1/preview.xml", method: :get })
end
end
@@ -977,8 +977,8 @@ class ResourcesTest < ActionController::TestCase
assert_singleton_resource_allowed_routes("accounts", {}, [], [:new, :create, :show, :edit, :update, :destroy])
assert_singleton_resource_allowed_routes("accounts", { format: "xml" }, [], [:new, :create, :show, :edit, :update, :destroy])
- assert_recognizes({ controller: "accounts", action: "signup" }, path: "account/signup", method: :get)
- assert_recognizes({ controller: "accounts", action: "signup", format: "xml" }, path: "account/signup.xml", method: :get)
+ assert_recognizes({ controller: "accounts", action: "signup" }, { path: "account/signup", method: :get })
+ assert_recognizes({ controller: "accounts", action: "signup", format: "xml" }, { path: "account/signup.xml", method: :get })
end
end
@@ -995,8 +995,8 @@ class ResourcesTest < ActionController::TestCase
assert_resource_allowed_routes("images", { product_id: "1" }, { id: "2" }, :show, [:index, :new, :create, :edit, :update, :destroy], "products/1/images")
assert_resource_allowed_routes("images", { product_id: "1", format: "xml" }, { id: "2" }, :show, [:index, :new, :create, :edit, :update, :destroy], "products/1/images")
- assert_recognizes({ controller: "images", action: "thumbnail", product_id: "1", id: "2" }, path: "products/1/images/2/thumbnail", method: :get)
- assert_recognizes({ controller: "images", action: "thumbnail", product_id: "1", id: "2", format: "jpg" }, path: "products/1/images/2/thumbnail.jpg", method: :get)
+ assert_recognizes({ controller: "images", action: "thumbnail", product_id: "1", id: "2" }, { path: "products/1/images/2/thumbnail", method: :get })
+ assert_recognizes({ controller: "images", action: "thumbnail", product_id: "1", id: "2", format: "jpg" }, { path: "products/1/images/2/thumbnail.jpg", method: :get })
end
end
@@ -1069,7 +1069,7 @@ class ResourcesTest < ActionController::TestCase
match "/products", to: "products#show", via: :all
end
- assert_routing({ method: "all", path: "/products" }, controller: "products", action: "show")
+ assert_routing({ method: "all", path: "/products" }, { controller: "products", action: "show" })
end
end
@@ -1080,7 +1080,7 @@ class ResourcesTest < ActionController::TestCase
end
assert_raises(Minitest::Assertion) do
- assert_routing({ method: "all", path: "/products" }, controller: "products", action: "show")
+ assert_routing({ method: "all", path: "/products" }, { controller: "products", action: "show" })
end
end
end
diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb
index 92b1c75443..46369ebbb0 100644
--- a/actionpack/test/controller/test_case_test.rb
+++ b/actionpack/test/controller/test_case_test.rb
@@ -392,9 +392,9 @@ XML
def test_assert_generates
assert_generates "controller/action/5", controller: "controller", action: "action", id: "5"
- assert_generates "controller/action/7", { id: "7" }, controller: "controller", action: "action"
- assert_generates "controller/action/5", { controller: "controller", action: "action", id: "5", name: "bob" }, {}, name: "bob"
- assert_generates "controller/action/7", { id: "7", name: "bob" }, { controller: "controller", action: "action" }, name: "bob"
+ assert_generates "controller/action/7", { id: "7" }, { controller: "controller", action: "action" }
+ assert_generates "controller/action/5", { controller: "controller", action: "action", id: "5", name: "bob" }, {}, { name: "bob" }
+ assert_generates "controller/action/7", { id: "7", name: "bob" }, { controller: "controller", action: "action" }, { name: "bob" }
assert_generates "controller/action/7", { id: "7" }, { controller: "controller", action: "action", name: "bob" }, {}
end
@@ -405,7 +405,7 @@ XML
def test_assert_routing_with_method
with_routing do |set|
set.draw { resources(:content) }
- assert_routing({ method: "post", path: "content" }, controller: "content", action: "create")
+ assert_routing({ method: "post", path: "content" }, { controller: "content", action: "create" })
end
end
diff --git a/actionpack/test/dispatch/routing_assertions_test.rb b/actionpack/test/dispatch/routing_assertions_test.rb
index a196fec7e9..e492a56653 100644
--- a/actionpack/test/dispatch/routing_assertions_test.rb
+++ b/actionpack/test/dispatch/routing_assertions_test.rb
@@ -33,11 +33,11 @@ class RoutingAssertionsTest < ActionController::TestCase
end
def test_assert_generates_with_defaults
- assert_generates("/articles/1/edit", { controller: "articles", action: "edit" }, id: "1")
+ assert_generates("/articles/1/edit", { controller: "articles", action: "edit" }, { id: "1" })
end
def test_assert_generates_with_extras
- assert_generates("/articles", { controller: "articles", action: "index", page: "1" }, {}, page: "1")
+ assert_generates("/articles", { controller: "articles", action: "index", page: "1" }, {}, { page: "1" })
end
def test_assert_recognizes
@@ -50,8 +50,8 @@ class RoutingAssertionsTest < ActionController::TestCase
end
def test_assert_recognizes_with_method
- assert_recognizes({ controller: "articles", action: "create" }, path: "/articles", method: :post)
- assert_recognizes({ controller: "articles", action: "update", id: "1" }, path: "/articles/1", method: :put)
+ assert_recognizes({ controller: "articles", action: "create" }, { path: "/articles", method: :post })
+ assert_recognizes({ controller: "articles", action: "update", id: "1" }, { path: "/articles/1", method: :put })
end
def test_assert_recognizes_with_hash_constraint
@@ -96,11 +96,11 @@ class RoutingAssertionsTest < ActionController::TestCase
end
def test_assert_routing_with_defaults
- assert_routing("/articles/1/edit", { controller: "articles", action: "edit", id: "1" }, id: "1")
+ assert_routing("/articles/1/edit", { controller: "articles", action: "edit", id: "1" }, { id: "1" })
end
def test_assert_routing_with_extras
- assert_routing("/articles", { controller: "articles", action: "index", page: "1" }, {}, page: "1")
+ assert_routing("/articles", { controller: "articles", action: "index", page: "1" }, {}, { page: "1" })
end
def test_assert_routing_with_hash_constraint
diff --git a/actionpack/test/journey/router_test.rb b/actionpack/test/journey/router_test.rb
index 27f4f42aab..29cc74471d 100644
--- a/actionpack/test/journey/router_test.rb
+++ b/actionpack/test/journey/router_test.rb
@@ -186,14 +186,14 @@ module ActionDispatch
def test_required_part_in_recall
get "/messages/:a/:b", to: "foo#bar"
- path, _ = @formatter.generate(nil, { controller: "foo", action: "bar", a: "a" }, b: "b")
+ path, _ = @formatter.generate(nil, { controller: "foo", action: "bar", a: "a" }, { b: "b" })
assert_equal "/messages/a/b", path
end
def test_splat_in_recall
get "/*path", to: "foo#bar"
- path, _ = @formatter.generate(nil, { controller: "foo", action: "bar" }, path: "b")
+ path, _ = @formatter.generate(nil, { controller: "foo", action: "bar" }, { path: "b" })
assert_equal "/b", path
end
@@ -201,7 +201,7 @@ module ActionDispatch
get "/messages/:action(/:id(.:format))", to: "foo#bar"
get "/messages/:id(.:format)", to: "bar#baz"
- path, _ = @formatter.generate(nil, { controller: "foo", id: 10 }, action: "index")
+ path, _ = @formatter.generate(nil, { controller: "foo", id: 10 }, { action: "index" })
assert_equal "/messages/index/10", path
end
@@ -314,7 +314,7 @@ module ActionDispatch
path, params = @formatter.generate(
nil,
{ controller: "tasks", id: 10 },
- action: "index")
+ { action: "index" })
assert_equal "/tasks/index/10", path
assert_equal({}, params)
end
@@ -325,7 +325,7 @@ module ActionDispatch
path, params = @formatter.generate(
"tasks",
{ controller: "tasks" },
- controller: "tasks", action: "index")
+ { controller: "tasks", action: "index" })
assert_equal "/tasks", path
assert_equal({}, params)
end
diff --git a/actionview/test/actionpack/abstract/abstract_controller_test.rb b/actionview/test/actionpack/abstract/abstract_controller_test.rb
index 2bf2ddcc70..468a6376c7 100644
--- a/actionview/test/actionpack/abstract/abstract_controller_test.rb
+++ b/actionview/test/actionpack/abstract/abstract_controller_test.rb
@@ -191,10 +191,10 @@ module AbstractController
private
def self.layout(formats)
- find_template(name.underscore, { formats: formats }, _prefixes: ["layouts"])
+ find_template(name.underscore, { formats: formats }, { _prefixes: ["layouts"] })
rescue ActionView::MissingTemplate
begin
- find_template("application", { formats: formats }, _prefixes: ["layouts"])
+ find_template("application", { formats: formats }, { _prefixes: ["layouts"] })
rescue ActionView::MissingTemplate
end
end
diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb
index 35a08ea672..5a5550438b 100644
--- a/actionview/test/template/date_helper_test.rb
+++ b/actionview/test/template/date_helper_test.rb
@@ -255,8 +255,8 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_day(Time.mktime(2003, 8, 16), {}, class: "selector")
- assert_dom_equal expected, select_day(16, {}, class: "selector")
+ assert_dom_equal expected, select_day(Time.mktime(2003, 8, 16), {}, { class: "selector" })
+ assert_dom_equal expected, select_day(16, {}, { class: "selector" })
end
def test_select_day_with_default_prompt
@@ -425,7 +425,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_month(Time.mktime(2003, 8, 16), {}, class: "selector", accesskey: "M")
+ assert_dom_equal expected, select_month(Time.mktime(2003, 8, 16), {}, { class: "selector", accesskey: "M" })
end
def test_select_month_with_default_prompt
@@ -520,7 +520,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_year(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005 }, class: "selector", accesskey: "M")
+ assert_dom_equal expected, select_year(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005 }, { class: "selector", accesskey: "M" })
end
def test_select_year_with_default_prompt
@@ -615,7 +615,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_hour(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector", accesskey: "M")
+ assert_dom_equal expected, select_hour(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector", accesskey: "M" })
end
def test_select_hour_with_default_prompt
@@ -719,7 +719,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector", accesskey: "M")
+ assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector", accesskey: "M" })
end
def test_select_minute_with_default_prompt
@@ -799,7 +799,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_second(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector", accesskey: "M")
+ assert_dom_equal expected, select_second(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector", accesskey: "M" })
end
def test_select_second_with_default_prompt
@@ -1066,7 +1066,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, prefix: "date[first]" }, class: "selector")
+ assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, prefix: "date[first]" }, { class: "selector" })
end
def test_select_date_with_separator
@@ -1170,7 +1170,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, prefix: "date[first]", with_css_classes: true }, class: "datetime optional")
+ assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, prefix: "date[first]", with_css_classes: true }, { class: "datetime optional" })
end
def test_select_date_with_custom_with_css_classes_and_html_class_option
@@ -1186,7 +1186,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, with_css_classes: { year: "my-year", month: "my-month", day: "my-day" } }, class: "date optional")
+ assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, with_css_classes: { year: "my-year", month: "my-month", day: "my-day" } }, { class: "date optional" })
end
def test_select_date_with_partial_with_css_classes_and_html_class_option
@@ -1202,7 +1202,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, with_css_classes: { month: "my-month custom-grid" } }, class: "date optional")
+ assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, with_css_classes: { month: "my-month custom-grid" } }, { class: "date optional" })
end
def test_select_date_with_html_class_option
@@ -1218,7 +1218,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005 }, class: "date optional custom-grid")
+ assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005 }, { class: "date optional custom-grid" })
end
def test_select_datetime
@@ -1358,7 +1358,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), { start_year: 2003, end_year: 2005, prefix: "date[first]" }, class: "selector")
+ assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), { start_year: 2003, end_year: 2005, prefix: "date[first]" }, { class: "selector" })
end
def test_select_datetime_with_all_separators
@@ -1390,7 +1390,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), { datetime_separator: "&mdash;", date_separator: "/", time_separator: ":", start_year: 2003, end_year: 2005, prefix: "date[first]" }, class: "selector")
+ assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), { datetime_separator: "&mdash;", date_separator: "/", time_separator: ":", start_year: 2003, end_year: 2005, prefix: "date[first]" }, { class: "selector" })
end
def test_select_datetime_should_work_with_date
@@ -1670,8 +1670,8 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector")
- assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), { include_seconds: false }, class: "selector")
+ assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector" })
+ assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), { include_seconds: false }, { class: "selector" })
end
def test_select_time_should_work_with_date
@@ -1928,7 +1928,7 @@ class DateHelperTest < ActionView::TestCase
expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n}
expected << "</select>\n"
- assert_dom_equal expected, date_select("post", "written_on", { order: [ :month, :year ] }, disabled: true)
+ assert_dom_equal expected, date_select("post", "written_on", { order: [ :month, :year ] }, { disabled: true })
end
def test_date_select_within_fields_for
@@ -2170,7 +2170,7 @@ class DateHelperTest < ActionView::TestCase
expected << "</select>\n"
- assert_dom_equal expected, date_select("post", "written_on", {}, class: "selector")
+ assert_dom_equal expected, date_select("post", "written_on", {}, { class: "selector" })
end
def test_date_select_with_html_options_within_fields_for
@@ -2178,7 +2178,7 @@ class DateHelperTest < ActionView::TestCase
@post.written_on = Date.new(2004, 6, 15)
output_buffer = fields_for :post, @post do |f|
- concat f.date_select(:written_on, {}, class: "selector")
+ concat f.date_select(:written_on, {}, { class: "selector" })
end
expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="selector">\n}.dup
@@ -2453,7 +2453,7 @@ class DateHelperTest < ActionView::TestCase
0.upto(59) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 16}>#{sprintf("%02d", i)}</option>\n) }
expected << "</select>\n"
- assert_dom_equal expected, time_select("post", "written_on", {}, class: "selector")
+ assert_dom_equal expected, time_select("post", "written_on", {}, { class: "selector" })
end
def test_time_select_with_html_options_within_fields_for
@@ -2461,7 +2461,7 @@ class DateHelperTest < ActionView::TestCase
@post.written_on = Time.local(2004, 6, 15, 15, 16, 35)
output_buffer = fields_for :post, @post do |f|
- concat f.time_select(:written_on, {}, class: "selector")
+ concat f.time_select(:written_on, {}, { class: "selector" })
end
expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup
@@ -2606,7 +2606,7 @@ class DateHelperTest < ActionView::TestCase
0.upto(59) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 16}>#{sprintf("%02d", i)}</option>\n) }
expected << "</select>\n"
- assert_dom_equal expected, time_select("post", "written_on", {}, disabled: true)
+ assert_dom_equal expected, time_select("post", "written_on", {}, { disabled: true })
end
def test_datetime_select
@@ -2740,7 +2740,7 @@ class DateHelperTest < ActionView::TestCase
@post.updated_at = Time.local(2004, 6, 15, 16, 35)
output_buffer = fields_for :post, @post do |f|
- concat f.datetime_select(:updated_at, {}, class: "selector")
+ concat f.datetime_select(:updated_at, {}, { class: "selector" })
end
expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]" class="selector">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n}.dup
@@ -3222,7 +3222,7 @@ class DateHelperTest < ActionView::TestCase
0.upto(59) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 16}>#{sprintf("%02d", i)}</option>\n) }
expected << "</select>\n"
- assert_dom_equal expected, datetime_select("post", "updated_at", { discard_year: true, discard_month: true }, disabled: true)
+ assert_dom_equal expected, datetime_select("post", "updated_at", { discard_year: true, discard_month: true }, { disabled: true })
end
def test_datetime_select_discard_hour
@@ -3442,7 +3442,7 @@ class DateHelperTest < ActionView::TestCase
expected << %{<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35" selected="selected">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n}
expected << "</select>\n"
- assert_dom_equal expected, datetime_select("post", "updated_at", {}, class: "selector")
+ assert_dom_equal expected, datetime_select("post", "updated_at", {}, { class: "selector" })
end
def test_date_select_should_not_change_passed_options_hash
@@ -3602,7 +3602,7 @@ class DateHelperTest < ActionView::TestCase
assert select_minute(8, use_hidden: true).html_safe?
assert select_month(8, prompt: "Choose month").html_safe?
- assert select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector").html_safe?
+ assert select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector" }).html_safe?
assert select_date(Time.mktime(2003, 8, 16), date_separator: " / ", start_year: 2003, end_year: 2005, prefix: "date[first]").html_safe?
end
diff --git a/actionview/test/template/form_collections_helper_test.rb b/actionview/test/template/form_collections_helper_test.rb
index bba529a98a..6db55a1447 100644
--- a/actionview/test/template/form_collections_helper_test.rb
+++ b/actionview/test/template/form_collections_helper_test.rb
@@ -95,7 +95,7 @@ class FormCollectionsHelperTest < ActionView::TestCase
test "collection radio accepts html options as input" do
collection = [[1, true], [0, false]]
- with_collection_radio_buttons :user, :active, collection, :last, :first, {}, class: "special-radio"
+ with_collection_radio_buttons :user, :active, collection, :last, :first, {}, { class: "special-radio" }
assert_select "input[type=radio][value=true].special-radio#user_active_true"
assert_select "input[type=radio][value=false].special-radio#user_active_false"
@@ -215,7 +215,7 @@ class FormCollectionsHelperTest < ActionView::TestCase
test "collection radio buttons generates a hidden field using the given :name in :html_options" do
collection = [Category.new(1, "Category 1"), Category.new(2, "Category 2")]
- with_collection_radio_buttons :user, :category_ids, collection, :id, :name, {}, name: "user[other_category_ids]"
+ with_collection_radio_buttons :user, :category_ids, collection, :id, :name, {}, { name: "user[other_category_ids]" }
assert_select "input[type=hidden][name='user[other_category_ids]'][value='']", count: 1
end
@@ -259,7 +259,7 @@ class FormCollectionsHelperTest < ActionView::TestCase
test "collection check boxes generates a hidden field using the given :name in :html_options" do
collection = [Category.new(1, "Category 1"), Category.new(2, "Category 2")]
- with_collection_check_boxes :user, :category_ids, collection, :id, :name, {}, name: "user[other_category_ids][]"
+ with_collection_check_boxes :user, :category_ids, collection, :id, :name, {}, { name: "user[other_category_ids][]" }
assert_select "input[type=hidden][name='user[other_category_ids][]'][value='']", count: 1
end
@@ -446,7 +446,7 @@ class FormCollectionsHelperTest < ActionView::TestCase
test "collection check boxes accepts html options" do
collection = [[1, "Category 1"], [2, "Category 2"]]
- with_collection_check_boxes :user, :category_ids, collection, :first, :last, {}, class: "check"
+ with_collection_check_boxes :user, :category_ids, collection, :first, :last, {}, { class: "check" }
assert_select 'input.check[type=checkbox][value="1"]'
assert_select 'input.check[type=checkbox][value="2"]'
diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb
index 246f52588d..ac64096908 100644
--- a/actionview/test/template/form_helper_test.rb
+++ b/actionview/test/template/form_helper_test.rb
@@ -1386,7 +1386,7 @@ class FormHelperTest < ActionView::TestCase
)
assert_dom_equal(
'<select name="post[secret]"></select>',
- select("post", "secret", [], {}, "id" => nil)
+ select("post", "secret", [], {}, { "id" => nil })
)
assert_dom_equal(
text_field("post", "title", "id" => nil),
diff --git a/actionview/test/template/form_options_helper_test.rb b/actionview/test/template/form_options_helper_test.rb
index 56a8a125e5..a66db2f3dc 100644
--- a/actionview/test/template/form_options_helper_test.rb
+++ b/actionview/test/template/form_options_helper_test.rb
@@ -491,7 +491,7 @@ class FormOptionsHelperTest < ActionView::TestCase
def test_select_without_multiple
assert_dom_equal(
"<select id=\"post_category\" name=\"post[category]\"></select>",
- select(:post, :category, "", {}, multiple: false)
+ select(:post, :category, "", {}, { multiple: false })
)
end
@@ -639,7 +639,7 @@ class FormOptionsHelperTest < ActionView::TestCase
end
def test_select_with_multiple_to_add_hidden_input
- output_buffer = select(:post, :category, "", {}, multiple: true)
+ output_buffer = select(:post, :category, "", {}, { multiple: true })
assert_dom_equal(
"<input type=\"hidden\" name=\"post[category][]\" value=\"\"/><select multiple=\"multiple\" id=\"post_category\" name=\"post[category][]\"></select>",
output_buffer
@@ -647,7 +647,7 @@ class FormOptionsHelperTest < ActionView::TestCase
end
def test_select_with_multiple_and_without_hidden_input
- output_buffer = select(:post, :category, "", { include_hidden: false }, multiple: true)
+ output_buffer = select(:post, :category, "", { include_hidden: false }, { multiple: true })
assert_dom_equal(
"<select multiple=\"multiple\" id=\"post_category\" name=\"post[category][]\"></select>",
output_buffer
@@ -655,7 +655,7 @@ class FormOptionsHelperTest < ActionView::TestCase
end
def test_select_with_multiple_and_with_explicit_name_ending_with_brackets
- output_buffer = select(:post, :category, [], { include_hidden: false }, multiple: true, name: "post[category][]")
+ output_buffer = select(:post, :category, [], { include_hidden: false }, { multiple: true, name: "post[category][]" })
assert_dom_equal(
"<select multiple=\"multiple\" id=\"post_category\" name=\"post[category][]\"></select>",
output_buffer
@@ -663,7 +663,7 @@ class FormOptionsHelperTest < ActionView::TestCase
end
def test_select_with_multiple_and_disabled_to_add_disabled_hidden_input
- output_buffer = select(:post, :category, "", {}, multiple: true, disabled: true)
+ output_buffer = select(:post, :category, "", {}, { multiple: true, disabled: true })
assert_dom_equal(
"<input disabled=\"disabled\"type=\"hidden\" name=\"post[category][]\" value=\"\"/><select multiple=\"multiple\" disabled=\"disabled\" id=\"post_category\" name=\"post[category][]\"></select>",
output_buffer
@@ -682,7 +682,7 @@ class FormOptionsHelperTest < ActionView::TestCase
def test_select_with_include_blank_false_and_required
@post = Post.new
@post.category = "<mus>"
- e = assert_raises(ArgumentError) { select("post", "category", %w( abe <mus> hest), { include_blank: false }, required: "required") }
+ e = assert_raises(ArgumentError) { select("post", "category", %w( abe <mus> hest), { include_blank: false }, { required: "required" }) }
assert_match(/include_blank cannot be false for a required field./, e.message)
end
@@ -762,7 +762,7 @@ class FormOptionsHelperTest < ActionView::TestCase
@post.category = ""
assert_dom_equal(
"<select class=\"disabled\" disabled=\"disabled\" name=\"post[category]\" id=\"post_category\"><option value=\"\">Please select</option>\n<option value=\"\"></option>\n</select>",
- select("post", "category", [], { prompt: true, include_blank: true }, class: "disabled", disabled: true)
+ select("post", "category", [], { prompt: true, include_blank: true }, { class: "disabled", disabled: true })
)
end
@@ -778,42 +778,42 @@ class FormOptionsHelperTest < ActionView::TestCase
def test_required_select
assert_dom_equal(
%(<select id="post_category" name="post[category]" required="required"><option value=""></option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
- select("post", "category", %w(abe mus hest), {}, required: true)
+ select("post", "category", %w(abe mus hest), {}, { required: true })
)
end
def test_required_select_with_include_blank_prompt
assert_dom_equal(
%(<select id="post_category" name="post[category]" required="required"><option value="">Select one</option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
- select("post", "category", %w(abe mus hest), { include_blank: "Select one" }, required: true)
+ select("post", "category", %w(abe mus hest), { include_blank: "Select one" }, { required: true })
)
end
def test_required_select_with_prompt
assert_dom_equal(
%(<select id="post_category" name="post[category]" required="required"><option value="">Select one</option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
- select("post", "category", %w(abe mus hest), { prompt: "Select one" }, required: true)
+ select("post", "category", %w(abe mus hest), { prompt: "Select one" }, { required: true })
)
end
def test_required_select_display_size_equals_to_one
assert_dom_equal(
%(<select id="post_category" name="post[category]" required="required" size="1"><option value=""></option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
- select("post", "category", %w(abe mus hest), {}, required: true, size: 1)
+ select("post", "category", %w(abe mus hest), {}, { required: true, size: 1 })
)
end
def test_required_select_with_display_size_bigger_than_one
assert_dom_equal(
%(<select id="post_category" name="post[category]" required="required" size="2"><option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
- select("post", "category", %w(abe mus hest), {}, required: true, size: 2)
+ select("post", "category", %w(abe mus hest), {}, { required: true, size: 2 })
)
end
def test_required_select_with_multiple_option
assert_dom_equal(
%(<input name="post[category][]" type="hidden" value=""/><select id="post_category" multiple="multiple" name="post[category][]" required="required"><option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
- select("post", "category", %w(abe mus hest), {}, required: true, multiple: true)
+ select("post", "category", %w(abe mus hest), {}, { required: true, multiple: true })
)
end
@@ -852,7 +852,7 @@ class FormOptionsHelperTest < ActionView::TestCase
assert_dom_equal(
expected,
- select("album[]", "genre", %w[rap rock country], {}, index: nil)
+ select("album[]", "genre", %w[rap rock country], {}, { index: nil })
)
end
@@ -982,7 +982,7 @@ class FormOptionsHelperTest < ActionView::TestCase
assert_dom_equal(
"<select id=\"post_author_name\" name=\"post[author_name]\" style=\"width: 200px\"><option value=\"\"></option>\n<option value=\"&lt;Abe&gt;\">&lt;Abe&gt;</option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>",
- collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true }, "style" => "width: 200px")
+ collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true }, { "style" => "width: 200px" })
)
end
@@ -992,7 +992,7 @@ class FormOptionsHelperTest < ActionView::TestCase
assert_dom_equal(
"<select id=\"post_author_name\" name=\"post[author_name]\" style=\"width: 200px\"><option value=\"\">No Selection</option>\n<option value=\"&lt;Abe&gt;\">&lt;Abe&gt;</option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>",
- collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: "No Selection" }, "style" => "width: 200px")
+ collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: "No Selection" }, { "style" => "width: 200px" })
)
end
@@ -1003,10 +1003,10 @@ class FormOptionsHelperTest < ActionView::TestCase
expected = "<input type=\"hidden\" name=\"post[author_name][]\" value=\"\"/><select id=\"post_author_name\" name=\"post[author_name][]\" multiple=\"multiple\"><option value=\"\"></option>\n<option value=\"&lt;Abe&gt;\">&lt;Abe&gt;</option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>"
# Should suffix default name with [].
- assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true }, multiple: true)
+ assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true }, { multiple: true })
# Shouldn't suffix custom name with [].
- assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true, name: "post[author_name][]" }, multiple: true)
+ assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true, name: "post[author_name][]" }, { multiple: true })
end
def test_collection_select_with_blank_and_selected
@@ -1149,7 +1149,7 @@ class FormOptionsHelperTest < ActionView::TestCase
def test_time_zone_select_with_style
@firm = Firm.new("D")
html = time_zone_select("firm", "time_zone", nil, {},
- "style" => "color: red")
+ { "style" => "color: red" })
assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" \
"<option value=\"A\">A</option>\n" \
"<option value=\"B\">B</option>\n" \
@@ -1159,13 +1159,13 @@ class FormOptionsHelperTest < ActionView::TestCase
"</select>",
html
assert_dom_equal html, time_zone_select("firm", "time_zone", nil, {},
- style: "color: red")
+ { style: "color: red" })
end
def test_time_zone_select_with_blank_and_style
@firm = Firm.new("D")
html = time_zone_select("firm", "time_zone", nil,
- { include_blank: true }, "style" => "color: red")
+ { include_blank: true }, { "style" => "color: red" })
assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" \
"<option value=\"\"></option>\n" \
"<option value=\"A\">A</option>\n" \
@@ -1176,13 +1176,13 @@ class FormOptionsHelperTest < ActionView::TestCase
"</select>",
html
assert_dom_equal html, time_zone_select("firm", "time_zone", nil,
- { include_blank: true }, style: "color: red")
+ { include_blank: true }, { style: "color: red" })
end
def test_time_zone_select_with_blank_as_string_and_style
@firm = Firm.new("D")
html = time_zone_select("firm", "time_zone", nil,
- { include_blank: "No Zone" }, "style" => "color: red")
+ { include_blank: "No Zone" }, { "style" => "color: red" })
assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" \
"<option value=\"\">No Zone</option>\n" \
"<option value=\"A\">A</option>\n" \
@@ -1193,7 +1193,7 @@ class FormOptionsHelperTest < ActionView::TestCase
"</select>",
html
assert_dom_equal html, time_zone_select("firm", "time_zone", nil,
- { include_blank: "No Zone" }, style: "color: red")
+ { include_blank: "No Zone" }, { style: "color: red" })
end
def test_time_zone_select_with_priority_zones
diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb
index b985b9789b..48c567008d 100644
--- a/actionview/test/template/form_tag_helper_test.rb
+++ b/actionview/test/template/form_tag_helper_test.rb
@@ -100,53 +100,53 @@ class FormTagHelperTest < ActionView::TestCase
end
def test_form_tag_multipart
- actual = form_tag({}, "multipart" => true)
+ actual = form_tag({}, { "multipart" => true })
expected = whole_form("http://www.example.com", enctype: true)
assert_dom_equal expected, actual
end
def test_form_tag_with_method_patch
- actual = form_tag({}, method: :patch)
+ actual = form_tag({}, { method: :patch })
expected = whole_form("http://www.example.com", method: :patch)
assert_dom_equal expected, actual
end
def test_form_tag_with_method_put
- actual = form_tag({}, method: :put)
+ actual = form_tag({}, { method: :put })
expected = whole_form("http://www.example.com", method: :put)
assert_dom_equal expected, actual
end
def test_form_tag_with_method_delete
- actual = form_tag({}, method: :delete)
+ actual = form_tag({}, { method: :delete })
expected = whole_form("http://www.example.com", method: :delete)
assert_dom_equal expected, actual
end
def test_form_tag_with_remote
- actual = form_tag({}, remote: true)
+ actual = form_tag({}, { remote: true })
expected = whole_form("http://www.example.com", remote: true)
assert_dom_equal expected, actual
end
def test_form_tag_with_remote_false
- actual = form_tag({}, remote: false)
+ actual = form_tag({}, { remote: false })
expected = whole_form
assert_dom_equal expected, actual
end
def test_form_tag_enforce_utf8_true
- actual = form_tag({}, enforce_utf8: true)
+ actual = form_tag({}, { enforce_utf8: true })
expected = whole_form("http://www.example.com", enforce_utf8: true)
assert_dom_equal expected, actual
assert actual.html_safe?
end
def test_form_tag_enforce_utf8_false
- actual = form_tag({}, enforce_utf8: false)
+ actual = form_tag({}, { enforce_utf8: false })
expected = whole_form("http://www.example.com", enforce_utf8: false)
assert_dom_equal expected, actual
assert actual.html_safe?
diff --git a/actionview/test/template/text_helper_test.rb b/actionview/test/template/text_helper_test.rb
index adb923d93b..f247de066f 100644
--- a/actionview/test/template/text_helper_test.rb
+++ b/actionview/test/template/text_helper_test.rb
@@ -50,19 +50,19 @@ class TextHelperTest < ActionView::TestCase
def test_simple_format_should_sanitize_input_when_sanitize_option_is_true
assert_equal "<p><b> test with unsafe string </b>code!</p>",
- simple_format("<b> test with unsafe string </b><script>code!</script>", {}, sanitize: true)
+ simple_format("<b> test with unsafe string </b><script>code!</script>", {}, { sanitize: true })
end
def test_simple_format_should_not_sanitize_input_when_sanitize_option_is_false
- assert_equal "<p><b> test with unsafe string </b><script>code!</script></p>", simple_format("<b> test with unsafe string </b><script>code!</script>", {}, sanitize: false)
+ assert_equal "<p><b> test with unsafe string </b><script>code!</script></p>", simple_format("<b> test with unsafe string </b><script>code!</script>", {}, { sanitize: false })
end
def test_simple_format_with_custom_wrapper
- assert_equal "<div></div>", simple_format(nil, {}, wrapper_tag: "div")
+ assert_equal "<div></div>", simple_format(nil, {}, { wrapper_tag: "div" })
end
def test_simple_format_with_custom_wrapper_and_multi_line_breaks
- assert_equal "<div>We want to put a wrapper...</div>\n\n<div>...right there.</div>", simple_format("We want to put a wrapper...\n\n...right there.", {}, wrapper_tag: "div")
+ assert_equal "<div>We want to put a wrapper...</div>\n\n<div>...right there.</div>", simple_format("We want to put a wrapper...\n\n...right there.", {}, { wrapper_tag: "div" })
end
def test_simple_format_should_not_change_the_text_passed
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 9f95b30122..b39d28ca31 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,8 +1,8 @@
* Ensure `sum` honors `distinct` on `has_many :through` associations
- Fixes #16791
+ Fixes #16791.
- *Aaron Wortham
+ *Aaron Wortham*
* Add `binary` fixture helper method.
diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb
index 5ba03c555a..4915a37f06 100644
--- a/activerecord/lib/active_record/associations/preloader/association.rb
+++ b/activerecord/lib/active_record/associations/preloader/association.rb
@@ -116,18 +116,8 @@ module ActiveRecord
@reflection_scope ||= reflection.scope_for(klass)
end
- def klass_scope
- current_scope = klass.current_scope
-
- if current_scope && current_scope.empty_scope?
- klass.unscoped
- else
- klass.default_scoped
- end
- end
-
def build_scope
- scope = klass_scope
+ scope = klass.scope_for_association
if reflection.type
scope.where!(reflection.type => model.base_class.sti_name)
diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb
index 76237c4a0c..cba565448f 100644
--- a/activerecord/lib/active_record/associations/through_association.rb
+++ b/activerecord/lib/active_record/associations/through_association.rb
@@ -15,7 +15,7 @@ module ActiveRecord
def target_scope
scope = super
reflection.chain.drop(1).each do |reflection|
- relation = reflection.klass.all
+ relation = reflection.klass.scope_for_association
scope.merge!(
relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load)
)
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 48d33e6744..c622df132e 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -62,12 +62,6 @@ module ActiveRecord
clear_mutation_trackers
end
- def write_attribute_without_type_cast(attr_name, *) # :nodoc:
- result = super
- clear_attribute_change(attr_name)
- result
- end
-
def clear_attribute_changes(attr_names) # :nodoc:
super
attr_names.each do |attr_name|
@@ -183,6 +177,11 @@ module ActiveRecord
end
private
+ def write_attribute_without_type_cast(attr_name, _)
+ result = super
+ clear_attribute_change(attr_name)
+ result
+ end
def mutation_tracker
unless defined?(@mutation_tracker)
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index b2c62cd686..b847933b2e 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -221,13 +221,8 @@ module ActiveRecord
end
def klass_join_scope(table, predicate_builder) # :nodoc:
- current_scope = klass.current_scope
-
- if current_scope && current_scope.empty_scope?
- build_scope(table, predicate_builder)
- else
- klass.default_scoped(build_scope(table, predicate_builder))
- end
+ relation = build_scope(table, predicate_builder)
+ klass.scope_for_association(relation)
end
def constraints
diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb
index 43cce19c1f..6fa096c1fe 100644
--- a/activerecord/lib/active_record/scoping/named.rb
+++ b/activerecord/lib/active_record/scoping/named.rb
@@ -31,6 +31,16 @@ module ActiveRecord
end
end
+ def scope_for_association(scope = relation) # :nodoc:
+ current_scope = self.current_scope
+
+ if current_scope && current_scope.empty_scope?
+ scope
+ else
+ default_scoped(scope)
+ end
+ end
+
def default_scoped(scope = relation) # :nodoc:
build_default_scope(scope) || scope
end
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index b2f5e39e09..603dee8c0d 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -190,7 +190,7 @@ module ActiveRecord
#
# === Caveats
#
- # If you're on MySQL, then do not use Data Definition Language(DDL) operations in nested
+ # If you're on MySQL, then do not use Data Definition Language (DDL) operations in nested
# transactions blocks that are emulated with savepoints. That is, do not execute statements
# like 'CREATE TABLE' inside such blocks. This is because MySQL automatically
# releases all savepoints upon executing a DDL operation. When +transaction+
diff --git a/activerecord/lib/rails/generators/active_record/application_record/application_record_generator.rb b/activerecord/lib/rails/generators/active_record/application_record/application_record_generator.rb
index d18330f5b2..35d5664400 100644
--- a/activerecord/lib/rails/generators/active_record/application_record/application_record_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/application_record/application_record_generator.rb
@@ -15,11 +15,12 @@ module ActiveRecord
private
def application_record_file_name
- @application_record_file_name ||= if namespaced?
- "app/models/#{namespaced_path}/application_record.rb"
- else
- "app/models/application_record.rb"
- end
+ @application_record_file_name ||=
+ if namespaced?
+ "app/models/#{namespaced_path}/application_record.rb"
+ else
+ "app/models/application_record.rb"
+ end
end
end
end
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index 968c0eb944..f8ea51225a 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -1261,6 +1261,25 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_equal 0, users[2].family_members.to_a.size
end
+ def test_through_scope_is_affected_by_unscoping
+ author = authors(:david)
+
+ expected = author.comments.to_a
+ FirstPost.unscoped do
+ assert_equal expected.sort_by(&:id), author.comments_on_first_posts.sort_by(&:id)
+ end
+ end
+
+ def test_through_scope_isnt_affected_by_scoping
+ author = authors(:david)
+
+ expected = author.comments_on_first_posts.to_a
+ FirstPost.where(id: 2).scoping do
+ author.comments_on_first_posts.reset
+ assert_equal expected.sort_by(&:id), author.comments_on_first_posts.sort_by(&:id)
+ end
+ end
+
def test_incorrectly_ordered_through_associations
assert_raises(ActiveRecord::HasManyThroughOrderError) do
DeveloperWithIncorrectlyOrderedHasManyThrough.create(
diff --git a/activerecord/test/cases/attribute_set_test.rb b/activerecord/test/cases/attribute_set_test.rb
index 006372a757..8be77ed88f 100644
--- a/activerecord/test/cases/attribute_set_test.rb
+++ b/activerecord/test/cases/attribute_set_test.rb
@@ -16,7 +16,7 @@ module ActiveRecord
test "building with custom types" do
builder = AttributeSet::Builder.new(foo: Type::Float.new)
- attributes = builder.build_from_database({ foo: "3.3", bar: "4.4" }, bar: Type::Integer.new)
+ attributes = builder.build_from_database({ foo: "3.3", bar: "4.4" }, { bar: Type::Integer.new })
assert_equal 3.3, attributes[:foo].value
assert_equal 4, attributes[:bar].value
diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb
index abbc011b34..68a1190d68 100644
--- a/activerecord/test/cases/enum_test.rb
+++ b/activerecord/test/cases/enum_test.rb
@@ -255,12 +255,14 @@ class EnumTest < ActiveRecord::TestCase
assert Book.illustrator_visibility_invisible.create.illustrator_visibility_invisible?
end
- test "_before_type_cast returns the enum label (required for form fields)" do
- if @book.status_came_from_user?
- assert_equal "published", @book.status_before_type_cast
- else
- assert_equal "published", @book.status
- end
+ test "_before_type_cast" do
+ assert_equal 2, @book.status_before_type_cast
+ assert_equal "published", @book.status
+
+ @book.status = "published"
+
+ assert_equal "published", @book.status_before_type_cast
+ assert_equal "published", @book.status
end
test "reserved enum names" do
diff --git a/activestorage/README.md b/activestorage/README.md
index d4ffe0c484..17d98978bb 100644
--- a/activestorage/README.md
+++ b/activestorage/README.md
@@ -1,17 +1,16 @@
# Active Storage
-Active Storage makes it simple to upload and reference files in cloud services, like Amazon S3, Google Cloud Storage or Microsoft Azure Storage and attach those files to Active Records. It also provides a disk service for testing or local deployments, but the focus is on cloud storage.
+Active Storage makes it simple to upload and reference files in cloud services like Amazon S3, Google Cloud Storage, or Microsoft Azure Storage, and attach those files to Active Records. Supports having one main service and mirrors in other services for redundancy. It also provides a disk service for testing or local deployments, but the focus is on cloud storage.
Files can be uploaded from the server to the cloud or directly from the client to the cloud.
-Image files can further more be transformed using on-demand variants for quality, aspect ratio, size, or any other
-MiniMagick supported transformation.
+Image files can furthermore be transformed using on-demand variants for quality, aspect ratio, size, or any other [MiniMagick](https://github.com/minimagick/minimagick) supported transformation.
## Compared to other storage solutions
-A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/blob.rb) and [Attachment](https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/attachment.rb) models (backed by Active Record). This means existing application models do not need to be modified with additional columns to associate with files. Active Storage uses polymorphic associations via the join model of `Attachment`, which then connects to the actual `Blob`.
+A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/blob.rb) and [Attachment](https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/attachment.rb) models (backed by Active Record). This means existing application models do not need to be modified with additional columns to associate with files. Active Storage uses polymorphic associations via the `Attachment` join model, which then connects to the actual `Blob`.
-These `Blob` models are intended to be immutable in spirit. One file, one blob. You can associate the same blob with multiple application models as well. And if you want to do transformations of a given `Blob`, the idea is that you'll simply create a new one, rather than attempt to mutate the existing (though of course you can delete that later if you don't need it).
+`Blob` models store attachment metadata (filename, content-type, etc.), and their identifier key in the storage service. Blob models do not store the actual binary data. They are intended to be immutable in spirit. One file, one blob. You can associate the same blob with multiple application models as well. And if you want to do transformations of a given `Blob`, the idea is that you'll simply create a new one, rather than attempt to mutate the existing one (though of course you can delete the previous version later if you don't need it).
## Examples
@@ -19,16 +18,32 @@ One attachment:
```ruby
class User < ApplicationRecord
+ # Associates an attachment and a blob. When the user is destroyed they are
+ # purged by default (models destroyed, and resource files deleted).
has_one_attached :avatar
end
-user.avatar.attach io: File.open("~/face.jpg"), filename: "avatar.jpg", content_type: "image/jpg"
+# Attach an avatar to the user.
+user.avatar.attach(io: File.open("~/face.jpg"), filename: "avatar.jpg", content_type: "image/jpg")
+
+# Does the user have an avatar?
user.avatar.attached? # => true
+# Synchronously destroy the avatar and actual resource files.
user.avatar.purge
+
+# Destroy the associated models and actual resource files async, via Active Job.
+user.avatar.purge_later
+
+# Does the user have an avatar?
user.avatar.attached? # => false
-url_for(user.avatar) # Generate a permanent URL for the blob, which upon access will redirect to a temporary service URL.
+# Generate a permanent URL for the blob that points to the application.
+# Upon access, a redirect to the actual service endpoint is returned.
+# This indirection decouples the public URL from the actual one, and
+# allows for example mirroring attachments in different services for
+# high-availability. The redirection has an HTTP expiration of 5 min.
+url_for(user.avatar)
class AvatarsController < ApplicationController
def update
diff --git a/activestorage/app/jobs/active_storage/purge_job.rb b/activestorage/app/jobs/active_storage/purge_job.rb
index 404ccefd05..369c07929d 100644
--- a/activestorage/app/jobs/active_storage/purge_job.rb
+++ b/activestorage/app/jobs/active_storage/purge_job.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-# Provides delayed purging of attachments or blobs using their +#purge_later+ method.
+# Provides delayed purging of attachments or blobs using their +purge_later+ method.
class ActiveStorage::PurgeJob < ActiveJob::Base
# FIXME: Limit this to a custom ActiveStorage error
retry_on StandardError
diff --git a/activestorage/app/models/active_storage/attachment.rb b/activestorage/app/models/active_storage/attachment.rb
index adfa6d4aa5..ad43845e4e 100644
--- a/activestorage/app/models/active_storage/attachment.rb
+++ b/activestorage/app/models/active_storage/attachment.rb
@@ -4,7 +4,7 @@ require "active_support/core_ext/module/delegation"
# Attachments associate records with blobs. Usually that's a one record-many blobs relationship,
# but it is possible to associate many different records with the same blob. If you're doing that,
-# you'll want to declare with `has_one/many_attached :thingy, dependent: false`, so that destroying
+# you'll want to declare with <tt>has_one/many_attached :thingy, dependent: false</tt>, so that destroying
# any one record won't destroy the blob as well. (Then you'll need to do your own garbage collecting, though).
class ActiveStorage::Attachment < ActiveRecord::Base
self.table_name = "active_storage_attachments"
@@ -22,8 +22,8 @@ class ActiveStorage::Attachment < ActiveRecord::Base
end
# Purging an attachment means purging the blob, which means talking to the service, which means
- # talking over the internet. Whenever you're doing that, it's a good idea to put that work in a job,
- # so it doesn't hold up other operations. That's what +#purge_later+ provides.
+ # talking over the Internet. Whenever you're doing that, it's a good idea to put that work in a job,
+ # so it doesn't hold up other operations. That's what +purge_later+ provides.
def purge_later
ActiveStorage::PurgeJob.perform_later(self)
end
diff --git a/activestorage/app/models/active_storage/blob.rb b/activestorage/app/models/active_storage/blob.rb
index dc91a9265f..9f2ed1e5ac 100644
--- a/activestorage/app/models/active_storage/blob.rb
+++ b/activestorage/app/models/active_storage/blob.rb
@@ -3,8 +3,8 @@
# A blob is a record that contains the metadata about a file and a key for where that file resides on the service.
# Blobs can be created in two ways:
#
-# 1) Subsequent to the file being uploaded server-side to the service via #create_after_upload!
-# 2) Ahead of the file being directly uploaded client-side to the service via #create_before_direct_upload!
+# 1) Subsequent to the file being uploaded server-side to the service via <tt>create_after_upload!</tt>.
+# 2) Ahead of the file being directly uploaded client-side to the service via <tt>create_before_direct_upload!</tt>.
#
# The first option doesn't require any client-side JavaScript integration, and can be used by any other back-end
# service that deals with files. The second option is faster, since you're not using your own server as a staging
@@ -12,7 +12,7 @@
#
# Blobs are intended to be immutable in as-so-far as their reference to a specific file goes. You're allowed to
# update a blob's metadata on a subsequent pass, but you should not update the key or change the uploaded file.
-# If you need to create a derivative or otherwise change the blob, simply create a new blob and purge the old.
+# If you need to create a derivative or otherwise change the blob, simply create a new blob and purge the old one.
class ActiveStorage::Blob < ActiveRecord::Base
self.table_name = "active_storage_blobs"
@@ -22,11 +22,11 @@ class ActiveStorage::Blob < ActiveRecord::Base
class_attribute :service
class << self
- # You can used the signed id of a blob to refer to it on the client side without fear of tampering.
- # This is particularly helpful for direct uploads where the client side needs to refer to the blob
+ # You can used the signed ID of a blob to refer to it on the client side without fear of tampering.
+ # This is particularly helpful for direct uploads where the client-side needs to refer to the blob
# that was created ahead of the upload itself on form submission.
#
- # The signed id is also used to create stable URLs for the blob through the BlobsController.
+ # The signed ID is also used to create stable URLs for the blob through the BlobsController.
def find_signed(id)
find ActiveStorage.verifier.verify(id, purpose: :blob_id)
end
@@ -43,8 +43,8 @@ class ActiveStorage::Blob < ActiveRecord::Base
end
# Returns a saved blob instance after the +io+ has been uploaded to the service. Note, the blob is first built,
- # then the +io+ is uploaded, then the blob is saved. This is doing to avoid opening a transaction and talking to
- # the service during that (which is a bad idea and leads to deadlocks).
+ # then the +io+ is uploaded, then the blob is saved. This is done this way to avoid uploading (which may take
+ # time), while having an open database transaction.
def create_after_upload!(io:, filename:, content_type: nil, metadata: nil)
build_after_upload(io: io, filename: filename, content_type: content_type, metadata: metadata).tap(&:save!)
end
@@ -61,7 +61,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
# Returns a signed ID for this blob that's suitable for reference on the client-side without fear of tampering.
- # It uses the framework-wide verifier on `ActiveStorage.verifier`, but with a dedicated purpose.
+ # It uses the framework-wide verifier on <tt>ActiveStorage.verifier</tt>, but with a dedicated purpose.
def signed_id
ActiveStorage.verifier.generate(id, purpose: :blob_id)
end
@@ -74,8 +74,9 @@ class ActiveStorage::Blob < ActiveRecord::Base
self[:key] ||= self.class.generate_unique_secure_token
end
- # Returns a ActiveStorage::Filename instance of the filename that can be queried for basename, extension, and
- # a sanitized version of the filename that's safe to use in URLs.
+ # Returns an ActiveStorage::Filename instance of the filename that can be
+ # queried for basename, extension, and a sanitized version of the filename
+ # that's safe to use in URLs.
def filename
ActiveStorage::Filename.new(self[:filename])
end
@@ -100,8 +101,9 @@ class ActiveStorage::Blob < ActiveRecord::Base
content_type.start_with?("text")
end
- # Returns a ActiveStorage::Variant instance with the set of +transformations+ passed in. This is only relevant
- # for image files, and it allows any image to be transformed for size, colors, and the like. Example:
+ # Returns an ActiveStorage::Variant instance with the set of +transformations+
+ # passed in. This is only relevant for image files, and it allows any image to
+ # be transformed for size, colors, and the like. Example:
#
# avatar.variant(resize: "100x100").processed.service_url
#
@@ -178,7 +180,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
destroy
end
- # Enqueues a ActiveStorage::PurgeJob job that'll call +#purge+. This is the recommended way to purge blobs when the call
+ # Enqueues an ActiveStorage::PurgeJob job that'll call +purge+. This is the recommended way to purge blobs when the call
# needs to be made from a transaction, a callback, or any other real-time scenario.
def purge_later
ActiveStorage::PurgeJob.perform_later(self)
diff --git a/activestorage/app/models/active_storage/variant.rb b/activestorage/app/models/active_storage/variant.rb
index 7b4ca18c8c..40648a27f7 100644
--- a/activestorage/app/models/active_storage/variant.rb
+++ b/activestorage/app/models/active_storage/variant.rb
@@ -4,8 +4,8 @@
# These variants are used to create thumbnails, fixed-size avatars, or any other derivative image from the
# original.
#
-# Variants rely on `MiniMagick` for the actual transformations of the file, so you must add `gem "mini_magick"`
-# to your Gemfile if you wish to use variants.
+# Variants rely on {MiniMagick}(https://github.com/minimagick/minimagick) for the actual transformations
+# of the file, so you must add <tt>gem "mini_magick"</tt> to your Gemfile if you wish to use variants.
#
# Note that to create a variant it's necessary to download the entire blob file from the service and load it
# into memory. The larger the image, the more memory is used. Because of this process, you also want to be
@@ -21,7 +21,7 @@
# This will create a URL for that specific blob with that specific variant, which the ActiveStorage::VariantsController
# can then produce on-demand.
#
-# When you do want to actually produce the variant needed, call +#processed+. This will check that the variant
+# When you do want to actually produce the variant needed, call +processed+. This will check that the variant
# has already been processed and uploaded to the service, and, if so, just return that. Otherwise it will perform
# the transformations, upload the variant to the service, and return itself again. Example:
#
@@ -58,8 +58,8 @@ class ActiveStorage::Variant
# Hiding the +service_url+ behind a redirect also gives you the power to change services without updating all URLs. And
# it allows permanent URLs that redirect to the +service_url+ to be cached in the view.
#
- # Use `url_for(variant)` (or the implied form, like `link_to variant` or `redirect_to variant`) to get the stable URL
- # for a variant that points to the ActiveStorage::VariantsController, which in turn will use this +#service_call+ method
+ # Use <tt>url_for(variant)</tt> (or the implied form, like +link_to variant+ or +redirect_to variant+) to get the stable URL
+ # for a variant that points to the ActiveStorage::VariantsController, which in turn will use this +service_call+ method
# for its redirection.
def service_url(expires_in: 5.minutes, disposition: :inline)
service.url key, expires_in: expires_in, disposition: disposition, filename: blob.filename, content_type: blob.content_type
diff --git a/activestorage/app/models/active_storage/variation.rb b/activestorage/app/models/active_storage/variation.rb
index 396ce85ef1..f657d90db4 100644
--- a/activestorage/app/models/active_storage/variation.rb
+++ b/activestorage/app/models/active_storage/variation.rb
@@ -15,13 +15,13 @@ class ActiveStorage::Variation
attr_reader :transformations
class << self
- # Returns a variation instance with the transformations that were encoded by +#encode+.
+ # Returns a variation instance with the transformations that were encoded by +encode+.
def decode(key)
new ActiveStorage.verifier.verify(key, purpose: :variation)
end
# Returns a signed key for the +transformations+, which can be used to refer to a specific
- # variation in a URL or combined key (like `ActiveStorage::Variant#key`).
+ # variation in a URL or combined key (like <tt>ActiveStorage::Variant#key</tt>).
def encode(transformations)
ActiveStorage.verifier.generate(transformations, purpose: :variation)
end
@@ -31,7 +31,7 @@ class ActiveStorage::Variation
@transformations = transformations
end
- # Accepts an open MiniMagick image instance, like what's return by `MiniMagick::Image.read(io)`,
+ # Accepts an open MiniMagick image instance, like what's returned by <tt>MiniMagick::Image.read(io)</tt>,
# and performs the +transformations+ against it. The transformed image instance is then returned.
def transform(image)
transformations.each do |(method, argument)|
diff --git a/activestorage/lib/active_storage/attached.rb b/activestorage/lib/active_storage/attached.rb
index e90b75afd0..9c4b6d5d1d 100644
--- a/activestorage/lib/active_storage/attached.rb
+++ b/activestorage/lib/active_storage/attached.rb
@@ -5,8 +5,8 @@ require "action_dispatch/http/upload"
require "active_support/core_ext/module/delegation"
module ActiveStorage
-# Abstract baseclass for the concrete ActiveStorage::Attached::One and ActiveStorage::Attached::Many
-# classes that both provide proxy access to the blob association for a record.
+ # Abstract base class for the concrete ActiveStorage::Attached::One and ActiveStorage::Attached::Many
+ # classes that both provide proxy access to the blob association for a record.
class Attached
attr_reader :name, :record
diff --git a/activestorage/lib/active_storage/attached/macros.rb b/activestorage/lib/active_storage/attached/macros.rb
index 027112195f..f3879ee2e3 100644
--- a/activestorage/lib/active_storage/attached/macros.rb
+++ b/activestorage/lib/active_storage/attached/macros.rb
@@ -19,7 +19,7 @@ module ActiveStorage
# most circumstances.
#
# The system has been designed to having you go through the ActiveStorage::Attached::One
- # proxy that provides the dynamic proxy to the associations and factory methods, like +#attach+.
+ # proxy that provides the dynamic proxy to the associations and factory methods, like +attach+.
#
# If the +:dependent+ option isn't set, the attachment will be purged
# (i.e. destroyed) whenever the record is destroyed.
diff --git a/activestorage/lib/active_storage/gem_version.rb b/activestorage/lib/active_storage/gem_version.rb
index bb6241ae47..e1d7b3493a 100644
--- a/activestorage/lib/active_storage/gem_version.rb
+++ b/activestorage/lib/active_storage/gem_version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ActiveStorage
- # Returns the version of the currently loaded Active Storage as a <tt>Gem::Version</tt>
+ # Returns the version of the currently loaded Active Storage as a <tt>Gem::Version</tt>.
def self.gem_version
Gem::Version.new VERSION::STRING
end
diff --git a/activestorage/lib/active_storage/log_subscriber.rb b/activestorage/lib/active_storage/log_subscriber.rb
index 80cc5d5c80..0d00a75c0e 100644
--- a/activestorage/lib/active_storage/log_subscriber.rb
+++ b/activestorage/lib/active_storage/log_subscriber.rb
@@ -19,7 +19,7 @@ module ActiveStorage
end
def service_exist(event)
- debug event, color("Checked if file exist at key: #{key_in(event)} (#{event.payload[:exist] ? "yes" : "no"})", BLUE)
+ debug event, color("Checked if file exists at key: #{key_in(event)} (#{event.payload[:exist] ? "yes" : "no"})", BLUE)
end
def service_url(event)
diff --git a/activestorage/lib/active_storage/service/azure_storage_service.rb b/activestorage/lib/active_storage/service/azure_storage_service.rb
index d066deaa20..d0ee2273c5 100644
--- a/activestorage/lib/active_storage/service/azure_storage_service.rb
+++ b/activestorage/lib/active_storage/service/azure_storage_service.rb
@@ -5,7 +5,7 @@ require "azure/storage"
require "azure/storage/core/auth/shared_access_signature"
module ActiveStorage
- # Wraps the Microsoft Azure Storage Blob Service as a Active Storage service.
+ # Wraps the Microsoft Azure Storage Blob Service as an Active Storage service.
# See ActiveStorage::Service for the generic API documentation that applies to all services.
class Service::AzureStorageService < Service
attr_reader :client, :path, :blobs, :container, :signer
diff --git a/activestorage/lib/active_storage/service/disk_service.rb b/activestorage/lib/active_storage/service/disk_service.rb
index cf4019966f..1d121dcb6c 100644
--- a/activestorage/lib/active_storage/service/disk_service.rb
+++ b/activestorage/lib/active_storage/service/disk_service.rb
@@ -6,7 +6,7 @@ require "digest/md5"
require "active_support/core_ext/numeric/bytes"
module ActiveStorage
- # Wraps a local disk path as a Active Storage service. See ActiveStorage::Service for the generic API
+ # Wraps a local disk path as an Active Storage service. See ActiveStorage::Service for the generic API
# documentation that applies to all services.
class Service::DiskService < Service
attr_reader :root
@@ -84,8 +84,8 @@ module ActiveStorage
content_length: content_length,
checksum: checksum
},
- expires_in: expires_in,
- purpose: :blob_token
+ { expires_in: expires_in,
+ purpose: :blob_token }
)
generated_url =
diff --git a/activestorage/lib/active_storage/service/gcs_service.rb b/activestorage/lib/active_storage/service/gcs_service.rb
index 32dfb4851b..e656f2c69f 100644
--- a/activestorage/lib/active_storage/service/gcs_service.rb
+++ b/activestorage/lib/active_storage/service/gcs_service.rb
@@ -4,7 +4,7 @@ require "google/cloud/storage"
require "active_support/core_ext/object/to_query"
module ActiveStorage
- # Wraps the Google Cloud Storage as a Active Storage service. See ActiveStorage::Service for the generic API
+ # Wraps the Google Cloud Storage as an Active Storage service. See ActiveStorage::Service for the generic API
# documentation that applies to all services.
class Service::GCSService < Service
attr_reader :client, :bucket
diff --git a/activestorage/lib/active_storage/service/s3_service.rb b/activestorage/lib/active_storage/service/s3_service.rb
index 98c9dd2972..bef2ecbea9 100644
--- a/activestorage/lib/active_storage/service/s3_service.rb
+++ b/activestorage/lib/active_storage/service/s3_service.rb
@@ -4,7 +4,7 @@ require "aws-sdk"
require "active_support/core_ext/numeric/bytes"
module ActiveStorage
- # Wraps the Amazon Simple Storage Service (S3) as a Active Storage service.
+ # Wraps the Amazon Simple Storage Service (S3) as an Active Storage service.
# See ActiveStorage::Service for the generic API documentation that applies to all services.
class Service::S3Service < Service
attr_reader :client, :bucket, :upload_options
diff --git a/activestorage/lib/tasks/activestorage.rake b/activestorage/lib/tasks/activestorage.rake
index 746bc5b28a..ef923e5926 100644
--- a/activestorage/lib/tasks/activestorage.rake
+++ b/activestorage/lib/tasks/activestorage.rake
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-namespace :activestorage do
+namespace :active_storage do
desc "Copy over the migration needed to the application"
task install: :environment do
Rake::Task["active_storage:install:migrations"].invoke
diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb
index c23b319046..c124416595 100644
--- a/activesupport/lib/active_support/lazy_load_hooks.rb
+++ b/activesupport/lib/active_support/lazy_load_hooks.rb
@@ -27,11 +27,17 @@ module ActiveSupport
base.class_eval do
@load_hooks = Hash.new { |h, k| h[k] = [] }
@loaded = Hash.new { |h, k| h[k] = [] }
+ @run_once = Hash.new { |h, k| h[k] = [] }
end
end
# Declares a block that will be executed when a Rails component is fully
# loaded.
+ #
+ # Options:
+ #
+ # * <tt>:yield</tt> - Yields the object that run_load_hooks to +block+.
+ # * <tt>:run_once</tt> - Given +block+ will run only once.
def on_load(name, options = {}, &block)
@loaded[name].each do |base|
execute_hook(base, options, block)
@@ -40,20 +46,32 @@ module ActiveSupport
@load_hooks[name] << [block, options]
end
- def execute_hook(base, options, block)
- if options[:yield]
- block.call(base)
- else
- base.instance_eval(&block)
- end
- end
-
def run_load_hooks(name, base = Object)
@loaded[name] << base
@load_hooks[name].each do |hook, options|
execute_hook(base, options, hook)
end
end
+
+ private
+
+ def with_execution_control(name, block, once)
+ unless @run_once[name].include?(block)
+ @run_once[name] << block if once
+
+ yield
+ end
+ end
+
+ def execute_hook(base, options, block)
+ with_execution_control(name, block, options[:run_once]) do
+ if options[:yield]
+ block.call(base)
+ else
+ base.instance_eval(&block)
+ end
+ end
+ end
end
extend LazyLoadHooks
diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb
index 80d03ec9d6..eafa2e1712 100644
--- a/activesupport/test/json/encoding_test.rb
+++ b/activesupport/test/json/encoding_test.rb
@@ -100,11 +100,11 @@ class TestJSONEncoding < ActiveSupport::TestCase
end
def test_hash_should_allow_key_filtering_with_only
- assert_equal %({"a":1}), ActiveSupport::JSON.encode({ "a" => 1, :b => 2, :c => 3 }, only: "a")
+ assert_equal %({"a":1}), ActiveSupport::JSON.encode({ "a" => 1, :b => 2, :c => 3 }, { only: "a" })
end
def test_hash_should_allow_key_filtering_with_except
- assert_equal %({"b":2}), ActiveSupport::JSON.encode({ "foo" => "bar", :b => 2, :c => 3 }, except: ["foo", :c])
+ assert_equal %({"b":2}), ActiveSupport::JSON.encode({ "foo" => "bar", :b => 2, :c => 3 }, { except: ["foo", :c] })
end
def test_time_to_json_includes_local_offset
diff --git a/activesupport/test/lazy_load_hooks_test.rb b/activesupport/test/lazy_load_hooks_test.rb
index 9c9264e8fc..c161005100 100644
--- a/activesupport/test/lazy_load_hooks_test.rb
+++ b/activesupport/test/lazy_load_hooks_test.rb
@@ -20,6 +20,18 @@ class LazyLoadHooksTest < ActiveSupport::TestCase
assert_equal 7, i
end
+ def test_basic_hook_with_two_registrations_only_once
+ i = 0
+ ActiveSupport.on_load(:basic_hook_with_two_once, run_once: true) do
+ i += incr
+ end
+ assert_equal 0, i
+ ActiveSupport.run_load_hooks(:basic_hook_with_two_once, FakeContext.new(2))
+ assert_equal 2, i
+ ActiveSupport.run_load_hooks(:basic_hook_with_two_once, FakeContext.new(5))
+ assert_equal 2, i
+ end
+
def test_hook_registered_after_run
i = 0
ActiveSupport.run_load_hooks(:registered_after)
@@ -37,6 +49,15 @@ class LazyLoadHooksTest < ActiveSupport::TestCase
assert_equal 7, i
end
+ def test_hook_registered_after_run_with_two_registrations_only_once
+ i = 0
+ ActiveSupport.run_load_hooks(:registered_after_with_two_once, FakeContext.new(2))
+ ActiveSupport.run_load_hooks(:registered_after_with_two_once, FakeContext.new(5))
+ assert_equal 0, i
+ ActiveSupport.on_load(:registered_after_with_two_once, run_once: true) { i += incr }
+ assert_equal 2, i
+ end
+
def test_hook_registered_interleaved_run_with_two_registrations
i = 0
ActiveSupport.run_load_hooks(:registered_interleaved_with_two, FakeContext.new(2))
@@ -47,6 +68,22 @@ class LazyLoadHooksTest < ActiveSupport::TestCase
assert_equal 7, i
end
+ def test_hook_registered_interleaved_run_with_two_registrations_once
+ i = 0
+ ActiveSupport
+ .run_load_hooks(:registered_interleaved_with_two_once, FakeContext.new(2))
+ assert_equal 0, i
+
+ ActiveSupport.on_load(:registered_interleaved_with_two_once, run_once: true) do
+ i += incr
+ end
+ assert_equal 2, i
+
+ ActiveSupport
+ .run_load_hooks(:registered_interleaved_with_two_once, FakeContext.new(5))
+ assert_equal 2, i
+ end
+
def test_hook_receives_a_context
i = 0
ActiveSupport.on_load(:contextual) { i += incr }
diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md
index fc4f773e3c..53417f012e 100644
--- a/guides/source/active_record_callbacks.md
+++ b/guides/source/active_record_callbacks.md
@@ -429,7 +429,7 @@ end
WARNING. The `after_commit` and `after_rollback` callbacks are called for all models created, updated, or destroyed within a transaction block. However, if an exception is raised within one of these callbacks, the exception will bubble up and any remaining `after_commit` or `after_rollback` methods will _not_ be executed. As such, if your callback code could raise an exception, you'll need to rescue it and handle it within the callback in order to allow other callbacks to run.
-WARNING. Using `after_create_commit` and `after_update_commit` both in the same model will override the callback which was registered first amongst them.
+WARNING. Using both `after_create_commit` and `after_update_commit` in the same model will only allow the last callback defined to take effect, and will override all others.
```ruby
class User < ApplicationRecord
diff --git a/guides/source/engines.md b/guides/source/engines.md
index 2276f348a1..c7331b6ca4 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -346,6 +346,9 @@ invoke test_unit
create test/controllers/blorgh/articles_controller_test.rb
invoke helper
create app/helpers/blorgh/articles_helper.rb
+invoke test_unit
+create test/application_system_test_case.rb
+create test/system/articles_test.rb
invoke assets
invoke js
create app/assets/javascripts/blorgh/articles.js
diff --git a/guides/source/generators.md b/guides/source/generators.md
index 389224d908..37af7a1310 100644
--- a/guides/source/generators.md
+++ b/guides/source/generators.md
@@ -197,6 +197,9 @@ $ bin/rails generate scaffold User name:string
invoke jbuilder
create app/views/users/index.json.jbuilder
create app/views/users/show.json.jbuilder
+ invoke test_unit
+ create test/application_system_test_case.rb
+ create test/system/users_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/users.coffee
@@ -415,6 +418,9 @@ $ bin/rails generate scaffold Comment body:text
invoke jbuilder
create app/views/comments/index.json.jbuilder
create app/views/comments/show.json.jbuilder
+ invoke test_unit
+ create test/application_system_test_case.rb
+ create test/system/comments_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/comments.coffee
diff --git a/guides/source/plugins.md b/guides/source/plugins.md
index 8c2d56ceb8..164207a9f9 100644
--- a/guides/source/plugins.md
+++ b/guides/source/plugins.md
@@ -74,7 +74,7 @@ In this example you will add a method to String named `to_squawk`. To begin, cre
```ruby
# yaffle/test/core_ext_test.rb
-require 'test_helper'
+require "test_helper"
class CoreExtTest < ActiveSupport::TestCase
def test_to_squawk_prepends_the_word_squawk
@@ -104,14 +104,16 @@ Finished in 0.003358s, 595.6483 runs/s, 297.8242 assertions/s.
Great - now you are ready to start development.
-In `lib/yaffle.rb`, add `require 'yaffle/core_ext'`:
+In `lib/yaffle.rb`, add `require "yaffle/core_ext"`:
```ruby
# yaffle/lib/yaffle.rb
-require 'yaffle/core_ext'
+require "yaffle/railtie"
+require "yaffle/core_ext"
module Yaffle
+ # Your code goes here...
end
```
@@ -120,7 +122,7 @@ Finally, create the `core_ext.rb` file and add the `to_squawk` method:
```ruby
# yaffle/lib/yaffle/core_ext.rb
-String.class_eval do
+class String
def to_squawk
"squawk! #{self}".strip
end
@@ -152,7 +154,7 @@ To begin, set up your files so that you have:
```ruby
# yaffle/test/acts_as_yaffle_test.rb
-require 'test_helper'
+require "test_helper"
class ActsAsYaffleTest < ActiveSupport::TestCase
end
@@ -161,10 +163,12 @@ end
```ruby
# yaffle/lib/yaffle.rb
-require 'yaffle/core_ext'
-require 'yaffle/acts_as_yaffle'
+require "yaffle/railtie"
+require "yaffle/core_ext"
+require "yaffle/acts_as_yaffle"
module Yaffle
+ # Your code goes here...
end
```
@@ -173,7 +177,6 @@ end
module Yaffle
module ActsAsYaffle
- # your code will go here
end
end
```
@@ -189,7 +192,7 @@ To start out, write a failing test that shows the behavior you'd like:
```ruby
# yaffle/test/acts_as_yaffle_test.rb
-require 'test_helper'
+require "test_helper"
class ActsAsYaffleTest < ActiveSupport::TestCase
def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
@@ -276,12 +279,8 @@ module Yaffle
module ActsAsYaffle
extend ActiveSupport::Concern
- included do
- end
-
- module ClassMethods
+ class_methods do
def acts_as_yaffle(options = {})
- # your code will go here
end
end
end
@@ -335,10 +334,7 @@ module Yaffle
module ActsAsYaffle
extend ActiveSupport::Concern
- included do
- end
-
- module ClassMethods
+ class_methods do
def acts_as_yaffle(options = {})
cattr_accessor :yaffle_text_field, default: (options[:yaffle_text_field] || :last_squawk).to_s
end
@@ -370,7 +366,7 @@ To start out, write a failing test that shows the behavior you'd like:
```ruby
# yaffle/test/acts_as_yaffle_test.rb
-require 'test_helper'
+require "test_helper"
class ActsAsYaffleTest < ActiveSupport::TestCase
def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
@@ -406,19 +402,14 @@ module Yaffle
extend ActiveSupport::Concern
included do
+ def squawk(string)
+ write_attribute(self.class.yaffle_text_field, string.to_squawk)
+ end
end
- module ClassMethods
+ class_methods do
def acts_as_yaffle(options = {})
cattr_accessor :yaffle_text_field, default: (options[:yaffle_text_field] || :last_squawk).to_s
-
- include Yaffle::ActsAsYaffle::LocalInstanceMethods
- end
- end
-
- module LocalInstanceMethods
- def squawk(string)
- write_attribute(self.class.yaffle_text_field, string.to_squawk)
end
end
end
@@ -449,7 +440,7 @@ Generators
----------
Generators can be included in your gem simply by creating them in a lib/generators directory of your plugin. More information about
-the creation of generators can be found in the [Generators Guide](generators.html)
+the creation of generators can be found in the [Generators Guide](generators.html).
Publishing Your Gem
-------------------
@@ -458,13 +449,13 @@ Gem plugins currently in development can easily be shared from any Git repositor
commit the code to a Git repository (like GitHub) and add a line to the Gemfile of the application in question:
```ruby
-gem 'yaffle', git: 'git://github.com/yaffle_watcher/yaffle.git'
+gem "yaffle", git: "https://github.com/rails/yaffle.git"
```
After running `bundle install`, your gem functionality will be available to the application.
-When the gem is ready to be shared as a formal release, it can be published to [RubyGems](http://www.rubygems.org).
-For more information about publishing gems to RubyGems, see: [Creating and Publishing Your First Ruby Gem](http://blog.thepete.net/2010/11/creating-and-publishing-your-first-ruby.html).
+When the gem is ready to be shared as a formal release, it can be published to [RubyGems](https://rubygems.org).
+For more information about publishing gems to RubyGems, see: [Publishing your gem](http://guides.rubygems.org/publishing).
RDoc Documentation
------------------
@@ -478,7 +469,7 @@ The first step is to update the README file with detailed information about how
* How to add the functionality to the app (several examples of common use cases)
* Warnings, gotchas or tips that might help users and save them time
-Once your README is solid, go through and add rdoc comments to all of the methods that developers will use. It's also customary to add '#:nodoc:' comments to those parts of the code that are not included in the public API.
+Once your README is solid, go through and add rdoc comments to all of the methods that developers will use. It's also customary to add `#:nodoc:` comments to those parts of the code that are not included in the public API.
Once your comments are good to go, navigate to your plugin directory and run:
diff --git a/guides/source/security.md b/guides/source/security.md
index 297680b176..56969c7aea 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -1060,7 +1060,7 @@ Additional Resources
The security landscape shifts and it is important to keep up to date, because missing a new vulnerability can be catastrophic. You can find additional resources about (Rails) security here:
-* Subscribe to the Rails security [mailing list.](http://groups.google.com/group/rubyonrails-security)
+* Subscribe to the Rails security [mailing list](http://groups.google.com/group/rubyonrails-security).
* [Brakeman - Rails Security Scanner](http://brakemanscanner.org/) - To perform static security analysis for Rails applications.
-* [Keep up to date on the other application layers.](http://secunia.com/) (they have a weekly newsletter, too)
-* A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet.](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet)
+* [Keep up to date on the other application layers](http://secunia.com/) (they have a weekly newsletter, too).
+* A [good security blog](https://www.owasp.org) including the [Cross-Site scripting Cheat Sheet](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet).
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 6e927d7244..49a0584d51 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -278,7 +278,7 @@ You can now just call the dependency once with a wildcard.
### `ActionView::Helpers::RecordTagHelper` moved to external gem (record_tag_helper)
-`content_tag_for` and `div_for` has been removed in favor of just using `content_tag`. To continue using it, add the `record_tag_helper` gem to your Gemfile:
+`content_tag_for` and `div_for` have been removed in favor of just using `content_tag`. To continue using the older methods, add the `record_tag_helper` gem to your Gemfile:
```ruby
gem 'record_tag_helper', '~> 1.0'
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 17d9ff8116..7b720d6e18 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Add `--skip-yarn` option to the plugin generator.
+
+ *bogdanvlviv*
+
* Optimize routes indentation.
*Yoshiyuki Hirano*
@@ -10,7 +14,7 @@
*Yoshiyuki Hirano*
-* Add git_source to `Gemfile` for plugin generator.
+* Add `git_source` to `Gemfile` for plugin generator.
*Yoshiyuki Hirano*
@@ -80,7 +84,7 @@
* Load environment file in `dbconsole` command.
- Fixes #29717
+ Fixes #29717.
*Yuji Yaginuma*
diff --git a/railties/lib/rails/engine/updater.rb b/railties/lib/rails/engine/updater.rb
index 2e0aef8aa7..21a0fc5562 100644
--- a/railties/lib/rails/engine/updater.rb
+++ b/railties/lib/rails/engine/updater.rb
@@ -9,7 +9,7 @@ module Rails
class << self
def generator
@generator ||= Rails::Generators::PluginGenerator.new ["plugin"],
- { engine: true }, destination_root: ENGINE_ROOT
+ { engine: true }, { destination_root: ENGINE_ROOT }
end
def run(action)
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index eda12b6da2..c773e07eba 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -145,7 +145,7 @@ module Rails
create_file("vendor/#{filename}", optimize_indentation(data), verbose: false)
end
- # Create a new file in the lib/ directory. Code can be specified
+ # Create a new file in the <tt>lib/</tt> directory. Code can be specified
# in a block or a data string can be given.
#
# lib("crypto.rb") do
diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore
index d8eeb1772d..83a7b211aa 100644
--- a/railties/lib/rails/generators/rails/app/templates/gitignore
+++ b/railties/lib/rails/generators/rails/app/templates/gitignore
@@ -27,7 +27,6 @@
<% unless options.skip_yarn? -%>
/node_modules
/yarn-error.log
-
<% end -%>
<% unless options.api? -%>
diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
index a0de708913..eb941adf95 100644
--- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
@@ -89,7 +89,7 @@ task default: :test
PASSTHROUGH_OPTIONS = [
:skip_active_record, :skip_action_mailer, :skip_javascript, :skip_action_cable, :skip_sprockets, :database,
- :javascript, :api, :quiet, :pretend, :skip
+ :javascript, :skip_yarn, :api, :quiet, :pretend, :skip
]
def generate_test_dummy(force = false)
diff --git a/railties/lib/rails/generators/rails/plugin/templates/gitignore b/railties/lib/rails/generators/rails/plugin/templates/gitignore
index 757172e6a6..8c7cad74ed 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/gitignore
+++ b/railties/lib/rails/generators/rails/plugin/templates/gitignore
@@ -5,5 +5,9 @@ pkg/
<%= dummy_path %>/db/*.sqlite3
<%= dummy_path %>/db/*.sqlite3-journal
<%= dummy_path %>/log/*.log
+<% unless options[:skip_yarn] -%>
+<%= dummy_path %>/node_modules/
+<%= dummy_path %>/yarn-error.log
+<% end -%>
<%= dummy_path %>/tmp/
<% end -%>
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index 0f578fe270..8931aabcda 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -11,7 +11,7 @@ namespace :app do
template = File.expand_path(template) if template !~ %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://}
require_relative "../generators"
require_relative "../generators/rails/app/app_generator"
- generator = Rails::Generators::AppGenerator.new [Rails.root], {}, destination_root: Rails.root
+ generator = Rails::Generators::AppGenerator.new [Rails.root], {}, { destination_root: Rails.root }
generator.apply template, verbose: false
end
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index e0afc67174..99fe6749d9 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -477,9 +477,9 @@ module ApplicationTests
class ::PostsController < ActionController::Base; end
- get "/posts", {}, "HTTPS" => "off"
+ get "/posts", {}, { "HTTPS" => "off" }
assert_match('src="http://example.com/assets/application.self.js', last_response.body)
- get "/posts", {}, "HTTPS" => "on"
+ get "/posts", {}, { "HTTPS" => "on" }
assert_match('src="https://example.com/assets/application.self.js', last_response.body)
end
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 72942a527c..ebe019f6a9 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -1191,6 +1191,7 @@ module ApplicationTests
app "development"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal :raise, ActionController::Parameters.action_on_unpermitted_parameters
@@ -1202,6 +1203,7 @@ module ApplicationTests
app "development"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal %w(controller action), ActionController::Parameters.always_permitted_parameters
end
@@ -1214,6 +1216,7 @@ module ApplicationTests
app "development"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal %w( controller action format ), ActionController::Parameters.always_permitted_parameters
end
@@ -1238,6 +1241,7 @@ module ApplicationTests
app "development"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal :raise, ActionController::Parameters.action_on_unpermitted_parameters
@@ -1249,6 +1253,7 @@ module ApplicationTests
app "development"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal :log, ActionController::Parameters.action_on_unpermitted_parameters
end
@@ -1257,6 +1262,7 @@ module ApplicationTests
app "test"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal :log, ActionController::Parameters.action_on_unpermitted_parameters
end
@@ -1265,6 +1271,7 @@ module ApplicationTests
app "production"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal false, ActionController::Parameters.action_on_unpermitted_parameters
end
@@ -1284,6 +1291,7 @@ module ApplicationTests
app "development"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal true, ActionController::Parameters.permit_all_parameters
end
@@ -1295,6 +1303,7 @@ module ApplicationTests
app "development"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal [], ActionController::Parameters.always_permitted_parameters
end
@@ -1306,6 +1315,7 @@ module ApplicationTests
app "development"
force_lazy_load_hooks { ActionController::Base }
+ force_lazy_load_hooks { ActionController::API }
assert_equal :raise, ActionController::Parameters.action_on_unpermitted_parameters
end
@@ -1323,10 +1333,10 @@ module ApplicationTests
end
end
- get "/", {}, "HTTP_ACCEPT" => "application/xml"
+ get "/", {}, { "HTTP_ACCEPT" => "application/xml" }
assert_equal "HTML", last_response.body
- get "/", { format: :xml }, "HTTP_ACCEPT" => "application/xml"
+ get "/", { format: :xml }, { "HTTP_ACCEPT" => "application/xml" }
assert_equal "XML", last_response.body
end
diff --git a/railties/test/application/mailer_previews_test.rb b/railties/test/application/mailer_previews_test.rb
index 6b872151b8..4e77cece1b 100644
--- a/railties/test/application/mailer_previews_test.rb
+++ b/railties/test/application/mailer_previews_test.rb
@@ -32,7 +32,7 @@ module ApplicationTests
test "/rails/mailers is accessible with correct configuration" do
add_to_config "config.action_mailer.show_previews = true"
app("production")
- get "/rails/mailers", {}, "REMOTE_ADDR" => "4.2.42.42"
+ get "/rails/mailers", {}, { "REMOTE_ADDR" => "4.2.42.42" }
assert_equal 200, last_response.status
end
@@ -482,7 +482,7 @@ module ApplicationTests
app("development")
- get "/rails/mailers", {}, "SCRIPT_NAME" => "/my_app"
+ get "/rails/mailers", {}, { "SCRIPT_NAME" => "/my_app" }
assert_match '<h3><a href="/my_app/rails/mailers/notifier">Notifier</a></h3>', last_response.body
assert_match '<li><a href="/my_app/rails/mailers/notifier/foo">foo</a></li>', last_response.body
end
diff --git a/railties/test/application/middleware/cache_test.rb b/railties/test/application/middleware/cache_test.rb
index 05f4317ad3..9822ec563d 100644
--- a/railties/test/application/middleware/cache_test.rb
+++ b/railties/test/application/middleware/cache_test.rb
@@ -56,7 +56,7 @@ module ApplicationTests
simple_controller
expected = "Wed, 30 May 1984 19:43:31 GMT"
- get "/expires/keeps_if_modified_since", {}, "HTTP_IF_MODIFIED_SINCE" => expected
+ get "/expires/keeps_if_modified_since", {}, { "HTTP_IF_MODIFIED_SINCE" => expected }
assert_equal 200, last_response.status
assert_equal expected, last_response.body, "cache should have kept If-Modified-Since"
@@ -121,7 +121,7 @@ module ApplicationTests
etag = last_response.headers["ETag"]
- get "/expires/expires_etag", {}, "HTTP_IF_NONE_MATCH" => etag
+ get "/expires/expires_etag", {}, { "HTTP_IF_NONE_MATCH" => etag }
assert_equal "stale, valid, store", last_response.headers["X-Rack-Cache"]
assert_equal 304, last_response.status
assert_equal "", last_response.body
@@ -139,7 +139,7 @@ module ApplicationTests
body = last_response.body
etag = last_response.headers["ETag"]
- get "/expires/expires_etag", { private: true }, "HTTP_IF_NONE_MATCH" => etag
+ get "/expires/expires_etag", { private: true }, { "HTTP_IF_NONE_MATCH" => etag }
assert_equal "miss", last_response.headers["X-Rack-Cache"]
assert_not_equal body, last_response.body
end
@@ -155,7 +155,7 @@ module ApplicationTests
last = last_response.headers["Last-Modified"]
- get "/expires/expires_last_modified", {}, "HTTP_IF_MODIFIED_SINCE" => last
+ get "/expires/expires_last_modified", {}, { "HTTP_IF_MODIFIED_SINCE" => last }
assert_equal "stale, valid, store", last_response.headers["X-Rack-Cache"]
assert_equal 304, last_response.status
assert_equal "", last_response.body
@@ -173,7 +173,7 @@ module ApplicationTests
body = last_response.body
last = last_response.headers["Last-Modified"]
- get "/expires/expires_last_modified", { private: true }, "HTTP_IF_MODIFIED_SINCE" => last
+ get "/expires/expires_last_modified", { private: true }, { "HTTP_IF_MODIFIED_SINCE" => last }
assert_equal "miss", last_response.headers["X-Rack-Cache"]
assert_not_equal body, last_response.body
end
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index b998e8a0bd..0a5a524692 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -276,7 +276,7 @@ module ApplicationTests
assert_equal "max-age=0, private, must-revalidate", last_response.headers["Cache-Control"]
assert_equal etag, last_response.headers["Etag"]
- get "/", {}, "HTTP_IF_NONE_MATCH" => etag
+ get "/", {}, { "HTTP_IF_NONE_MATCH" => etag }
assert_equal 304, last_response.status
assert_equal "", last_response.body
assert_nil last_response.headers["Content-Type"]
diff --git a/railties/test/generators/api_app_generator_test.rb b/railties/test/generators/api_app_generator_test.rb
index ba7f7bb5f3..d141b1d4b4 100644
--- a/railties/test/generators/api_app_generator_test.rb
+++ b/railties/test/generators/api_app_generator_test.rb
@@ -36,7 +36,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
run_generator
assert_file ".gitignore" do |content|
- assert_no_match(/\/public\/asserts/, content)
+ assert_no_match(/\/public\/assets/, content)
end
assert_file "Gemfile" do |content|
@@ -67,7 +67,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
run_generator
generator = Rails::Generators::AppGenerator.new ["rails"],
- { api: true, update: true }, destination_root: destination_root, shell: @shell
+ { api: true, update: true }, { destination_root: destination_root, shell: @shell }
quietly { generator.send(:update_config_files) }
assert_no_file "config/initializers/cookies_serializer.rb"
@@ -78,7 +78,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
run_generator
generator = Rails::Generators::AppGenerator.new ["rails"],
- { api: true, update: true }, destination_root: destination_root, shell: @shell
+ { api: true, update: true }, { destination_root: destination_root, shell: @shell }
quietly { generator.send(:update_bin_files) }
assert_no_file "bin/yarn"
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 1183dcd34d..b50b9364d0 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -248,7 +248,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_no_file "#{app_root}/config/initializers/new_framework_defaults_5_2.rb"
stub_rails_application(app_root) do
- generator = Rails::Generators::AppGenerator.new ["rails"], { update: true }, destination_root: app_root, shell: @shell
+ generator = Rails::Generators::AppGenerator.new ["rails"], { update: true }, { destination_root: app_root, shell: @shell }
generator.send(:app_const)
quietly { generator.send(:update_config_files) }
@@ -584,32 +584,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
- def test_generator_for_yarn
- run_generator([destination_root])
- assert_file "package.json", /dependencies/
- assert_file "config/initializers/assets.rb", /node_modules/
-
- assert_file ".gitignore" do |content|
- assert_match(/node_modules/, content)
- assert_match(/yarn-error\.log/, content)
- end
- end
-
- def test_generator_for_yarn_skipped
- run_generator([destination_root, "--skip-yarn"])
- assert_no_file "package.json"
- assert_no_file "bin/yarn"
-
- assert_file "config/initializers/assets.rb" do |content|
- assert_no_match(/node_modules/, content)
- end
-
- assert_file ".gitignore" do |content|
- assert_no_match(/node_modules/, content)
- assert_no_match(/yarn-error\.log/, content)
- end
- end
-
def test_inclusion_of_jbuilder
run_generator
assert_gem "jbuilder"
diff --git a/railties/test/generators/create_migration_test.rb b/railties/test/generators/create_migration_test.rb
index ce7bd3f5a0..3cb7fd6baa 100644
--- a/railties/test/generators/create_migration_test.rb
+++ b/railties/test/generators/create_migration_test.rb
@@ -53,7 +53,7 @@ class CreateMigrationTest < Rails::Generators::TestCase
end
def test_invoke_pretended
- create_migration(default_destination_path, {}, pretend: true)
+ create_migration(default_destination_path, {}, { pretend: true })
assert_no_file @migration.destination
end
@@ -94,7 +94,7 @@ class CreateMigrationTest < Rails::Generators::TestCase
def test_invoke_forced_pretended_when_exists_not_identical
migration_exists!
- create_migration(default_destination_path, { force: true }, pretend: true) do
+ create_migration(default_destination_path, { force: true }, { pretend: true }) do
"different content"
end
@@ -106,7 +106,7 @@ class CreateMigrationTest < Rails::Generators::TestCase
def test_invoke_skipped_when_exists_not_identical
migration_exists!
- create_migration(default_destination_path, {}, skip: true) { "different content" }
+ create_migration(default_destination_path, {}, { skip: true }) { "different content" }
assert_match(/skip db\/migrate\/2_create_articles\.rb\n/, invoke!)
assert_no_file @migration.destination
@@ -122,7 +122,7 @@ class CreateMigrationTest < Rails::Generators::TestCase
def test_revoke_pretended
migration_exists!
- create_migration(default_destination_path, {}, pretend: true)
+ create_migration(default_destination_path, {}, { pretend: true })
assert_match(/remove db\/migrate\/1_create_articles\.rb\n/, revoke!)
assert_file @existing_migration.destination
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index bd76af86e1..e94b1ac8fe 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -26,6 +26,10 @@ class PluginGeneratorTest < Rails::Generators::TestCase
destination File.join(Rails.root, "tmp/bukkits")
arguments [destination_root]
+ def application_path
+ "#{destination_root}/test/dummy"
+ end
+
# brings setup, teardown, and some tests
include SharedGeneratorTests
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
index c73b91e3f8..6c0775b50e 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -22,6 +22,10 @@ module SharedGeneratorTests
Rails.application = TestApp::Application.instance
end
+ def application_path
+ destination_root
+ end
+
def test_skeleton_is_created
run_generator
@@ -123,4 +127,30 @@ module SharedGeneratorTests
assert_no_file("app/models/concerns/.keep")
end
+
+ def test_generator_for_yarn
+ run_generator
+ assert_file "#{application_path}/package.json", /dependencies/
+ assert_file "#{application_path}/config/initializers/assets.rb", /node_modules/
+
+ assert_file ".gitignore" do |content|
+ assert_match(/node_modules/, content)
+ assert_match(/yarn-error\.log/, content)
+ end
+ end
+
+ def test_generator_for_yarn_skipped
+ run_generator([destination_root, "--skip-yarn"])
+ assert_no_file "#{application_path}/package.json"
+ assert_no_file "#{application_path}/bin/yarn"
+
+ assert_file "#{application_path}/config/initializers/assets.rb" do |content|
+ assert_no_match(/node_modules/, content)
+ end
+
+ assert_file ".gitignore" do |content|
+ assert_no_match(/node_modules/, content)
+ assert_no_match(/yarn-error\.log/, content)
+ end
+ end
end
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index 350d39ad09..e6964b4b18 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -1297,10 +1297,10 @@ YAML
boot_rails
- get("/bukkits/bukkit", {}, "SCRIPT_NAME" => "/foo")
+ get("/bukkits/bukkit", {}, { "SCRIPT_NAME" => "/foo" })
assert_equal "/foo/bar", last_response.body
- get("/bar", {}, "SCRIPT_NAME" => "/foo")
+ get("/bar", {}, { "SCRIPT_NAME" => "/foo" })
assert_equal "/foo/bukkits/bukkit", last_response.body
end
@@ -1346,10 +1346,10 @@ YAML
boot_rails
- get("/bukkits/bukkit", {}, "SCRIPT_NAME" => "/foo")
+ get("/bukkits/bukkit", {}, { "SCRIPT_NAME" => "/foo" })
assert_equal "/foo/bar", last_response.body
- get("/bar", {}, "SCRIPT_NAME" => "/foo")
+ get("/bar", {}, { "SCRIPT_NAME" => "/foo" })
assert_equal "/foo/bukkits/bukkit", last_response.body
end
diff --git a/railties/test/railties/mounted_engine_test.rb b/railties/test/railties/mounted_engine_test.rb
index 6b40a085ae..48f0fbc80f 100644
--- a/railties/test/railties/mounted_engine_test.rb
+++ b/railties/test/railties/mounted_engine_test.rb
@@ -208,7 +208,7 @@ module ApplicationTests
assert_equal "/ada/blog/posts/1", last_response.body
# test generating engine's route from engine with default_url_options
- get "/john/blog/posts", {}, "SCRIPT_NAME" => "/foo"
+ get "/john/blog/posts", {}, { "SCRIPT_NAME" => "/foo" }
assert_equal "/foo/john/blog/posts/1", last_response.body
# test generating engine's route from application
@@ -222,10 +222,10 @@ module ApplicationTests
assert_equal "/john/blog/posts", last_response.body
# test generating engine's route from application with default_url_options
- get "/engine_route", {}, "SCRIPT_NAME" => "/foo"
+ get "/engine_route", {}, { "SCRIPT_NAME" => "/foo" }
assert_equal "/foo/anonymous/blog/posts", last_response.body
- get "/url_for_engine_route", {}, "SCRIPT_NAME" => "/foo"
+ get "/url_for_engine_route", {}, { "SCRIPT_NAME" => "/foo" }
assert_equal "/foo/john/blog/posts", last_response.body
# test generating application's route from engine
@@ -243,14 +243,14 @@ module ApplicationTests
assert_equal "/anonymous/blog/posts/1", last_response.body
# test generating engine's route from other engine with default_url_options
- get "/metrics/generate_blog_route", {}, "SCRIPT_NAME" => "/foo"
+ get "/metrics/generate_blog_route", {}, { "SCRIPT_NAME" => "/foo" }
assert_equal "/foo/anonymous/blog/posts/1", last_response.body
- get "/metrics/generate_blog_route_in_view", {}, "SCRIPT_NAME" => "/foo"
+ get "/metrics/generate_blog_route_in_view", {}, { "SCRIPT_NAME" => "/foo" }
assert_equal "/foo/anonymous/blog/posts/1", last_response.body
# test generating application's route from engine with default_url_options
- get "/someone/blog/generate_application_route", {}, "SCRIPT_NAME" => "/foo"
+ get "/someone/blog/generate_application_route", {}, { "SCRIPT_NAME" => "/foo" }
assert_equal "/foo/", last_response.body
# test polymorphic routes