aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.travis.yml23
-rw-r--r--actioncable/lib/rails/generators/channel/templates/javascript/index.js.tt4
-rw-r--r--activejob/test/support/integration/adapters/backburner.rb3
-rw-r--r--activejob/test/support/integration/adapters/que.rb3
-rw-r--r--activejob/test/support/integration/adapters/queue_classic.rb3
-rw-r--r--activejob/test/support/integration/adapters/sneakers.rb16
-rw-r--r--activemodel/lib/active_model/type/date_time.rb6
-rw-r--r--activemodel/test/cases/type/date_time_test.rb11
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb7
-rw-r--r--activerecord/lib/active_record/attribute_methods/write.rb7
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb18
-rw-r--r--activesupport/CHANGELOG.md5
-rw-r--r--activesupport/lib/active_support/configurable.rb11
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb19
-rw-r--r--activesupport/lib/active_support/core_ext/numeric/conversions.rb244
-rw-r--r--activesupport/lib/active_support/core_ext/range/conversions.rb60
-rw-r--r--activesupport/lib/active_support/current_attributes.rb2
-rw-r--r--activesupport/lib/active_support/execution_wrapper.rb1
-rw-r--r--activesupport/lib/active_support/multibyte/chars.rb14
-rw-r--r--activesupport/lib/active_support/multibyte/unicode.rb10
-rw-r--r--activesupport/lib/active_support/number_helper.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_currency_converter.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_delimited_converter.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_human_converter.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_percentage_converter.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_phone_converter.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb2
-rw-r--r--activesupport/lib/active_support/subscriber.rb8
-rw-r--r--activesupport/test/multibyte_chars_test.rb18
-rw-r--r--activesupport/test/multibyte_grapheme_break_conformance_test.rb10
-rw-r--r--guides/assets/images/rails_guides_logo_1x.pngbin0 -> 2340 bytes
-rw-r--r--guides/assets/images/rails_guides_logo_2x.pngbin0 -> 3107 bytes
-rw-r--r--guides/assets/stylesheets/main.css60
-rw-r--r--guides/source/association_basics.md5
-rw-r--r--guides/source/configuring.md2
-rw-r--r--guides/source/debugging_rails_applications.md49
-rw-r--r--guides/source/documents.yaml32
-rw-r--r--guides/source/i18n.md4
-rw-r--r--guides/source/layout.html.erb18
-rw-r--r--guides/source/testing.md2
-rw-r--r--railties/CHANGELOG.md32
-rw-r--r--railties/lib/rails/generators.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/gitignore.tt7
-rw-r--r--railties/lib/rails/generators/rails/plugin/plugin_generator.rb2
-rw-r--r--railties/test/generators/app_generator_test.rb24
-rw-r--r--railties/test/generators/shared_generator_tests.rb18
53 files changed, 427 insertions, 363 deletions
diff --git a/.gitignore b/.gitignore
index d44875ed9a..35440cb54f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,4 +15,5 @@ node_modules/
package-lock.json
pkg/
/tmp/
-/yarn.lock \ No newline at end of file
+/yarn-error.log
+/yarn.lock
diff --git a/.travis.yml b/.travis.yml
index f703ed0f90..3db4e9cd94 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,8 +36,6 @@ before_install:
- "rm ${BUNDLE_GEMFILE}.lock"
- "travis_retry gem update --system"
- "travis_retry gem install bundler"
- - "[ -f /tmp/beanstalkd-1.10/Makefile ] || (curl -L https://github.com/kr/beanstalkd/archive/v1.10.tar.gz | tar xz -C /tmp)"
- - "pushd /tmp/beanstalkd-1.10 && make && (./beanstalkd &); popd"
- "[[ -z $encrypted_0fb9444d0374_key && -z $encrypted_0fb9444d0374_iv ]] || openssl aes-256-cbc -K $encrypted_0fb9444d0374_key -iv $encrypted_0fb9444d0374_iv -in activestorage/test/service/configurations.yml.enc -out activestorage/test/service/configurations.yml -d"
- "[[ $GEM != 'av:ujs' ]] || nvm install node"
- "[[ $GEM != 'av:ujs' ]] || node --version"
@@ -101,23 +99,44 @@ matrix:
- rvm: 2.5.1
env: "GEM=av:ujs"
- rvm: 2.4.4
+ sudo: required
env: "GEM=aj:integration"
services:
- memcached
- redis-server
- rabbitmq
+ before_install:
+ - sudo sed -i -e '/local.*peer/s/postgres/all/' -e 's/peer\|md5/trust/g' /etc/postgresql/*/main/pg_hba.conf
+ - "sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/10/main/postgresql.conf"
+ - "sudo service postgresql restart 10"
+ - "[ -f /tmp/beanstalkd-1.10/Makefile ] || (curl -L https://github.com/kr/beanstalkd/archive/v1.10.tar.gz | tar xz -C /tmp)"
+ - "pushd /tmp/beanstalkd-1.10 && make && (./beanstalkd &); popd"
- rvm: 2.5.1
+ sudo: required
env: "GEM=aj:integration"
services:
- memcached
- redis-server
- rabbitmq
+ before_install:
+ - sudo sed -i -e '/local.*peer/s/postgres/all/' -e 's/peer\|md5/trust/g' /etc/postgresql/*/main/pg_hba.conf
+ - "sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/10/main/postgresql.conf"
+ - "sudo service postgresql restart 10"
+ - "[ -f /tmp/beanstalkd-1.10/Makefile ] || (curl -L https://github.com/kr/beanstalkd/archive/v1.10.tar.gz | tar xz -C /tmp)"
+ - "pushd /tmp/beanstalkd-1.10 && make && (./beanstalkd &); popd"
- rvm: ruby-head
+ sudo: required
env: "GEM=aj:integration"
services:
- memcached
- redis-server
- rabbitmq
+ before_install:
+ - sudo sed -i -e '/local.*peer/s/postgres/all/' -e 's/peer\|md5/trust/g' /etc/postgresql/*/main/pg_hba.conf
+ - "sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/10/main/postgresql.conf"
+ - "sudo service postgresql restart 10"
+ - "[ -f /tmp/beanstalkd-1.10/Makefile ] || (curl -L https://github.com/kr/beanstalkd/archive/v1.10.tar.gz | tar xz -C /tmp)"
+ - "pushd /tmp/beanstalkd-1.10 && make && (./beanstalkd &); popd"
- rvm: 2.4.4
env: "GEM=ar:mysql2"
sudo: required
diff --git a/actioncable/lib/rails/generators/channel/templates/javascript/index.js.tt b/actioncable/lib/rails/generators/channel/templates/javascript/index.js.tt
index 5da1ce2dce..0cfcf74919 100644
--- a/actioncable/lib/rails/generators/channel/templates/javascript/index.js.tt
+++ b/actioncable/lib/rails/generators/channel/templates/javascript/index.js.tt
@@ -1,5 +1,5 @@
-// Load all the channels within this directory and all subdirectories.
+// Load all the channels within this directory and all subdirectories.
// Channel files must be named *_channel.js.
-const channels = require.context('.', true, /\_channel\.js$/)
+const channels = require.context('.', true, /_channel\.js$/)
channels.keys().forEach(channels)
diff --git a/activejob/test/support/integration/adapters/backburner.rb b/activejob/test/support/integration/adapters/backburner.rb
index eb179011d9..1163ae8178 100644
--- a/activejob/test/support/integration/adapters/backburner.rb
+++ b/activejob/test/support/integration/adapters/backburner.rb
@@ -8,7 +8,8 @@ module BackburnerJobsManager
end
unless can_run?
puts "Cannot run integration tests for backburner. To be able to run integration tests for backburner you need to install and start beanstalkd.\n"
- exit
+ status = ENV["CI"] ? false : true
+ exit status
end
end
diff --git a/activejob/test/support/integration/adapters/que.rb b/activejob/test/support/integration/adapters/que.rb
index 2e7d327b37..f231e5e12d 100644
--- a/activejob/test/support/integration/adapters/que.rb
+++ b/activejob/test/support/integration/adapters/que.rb
@@ -32,7 +32,8 @@ module QueJobsManager
rescue Sequel::DatabaseConnectionError
puts "Cannot run integration tests for que. To be able to run integration tests for que you need to install and start postgresql.\n"
- exit
+ status = ENV["CI"] ? false : true
+ exit status
end
def stop_workers
diff --git a/activejob/test/support/integration/adapters/queue_classic.rb b/activejob/test/support/integration/adapters/queue_classic.rb
index dbbdc12b9d..2b5375461a 100644
--- a/activejob/test/support/integration/adapters/queue_classic.rb
+++ b/activejob/test/support/integration/adapters/queue_classic.rb
@@ -30,7 +30,8 @@ module QueueClassicJobsManager
rescue PG::ConnectionBad
puts "Cannot run integration tests for queue_classic. To be able to run integration tests for queue_classic you need to install and start postgresql.\n"
- exit
+ status = ENV["CI"] ? false : true
+ exit status
end
def stop_workers
diff --git a/activejob/test/support/integration/adapters/sneakers.rb b/activejob/test/support/integration/adapters/sneakers.rb
index 965e6e2e6c..eb8d4cc2d5 100644
--- a/activejob/test/support/integration/adapters/sneakers.rb
+++ b/activejob/test/support/integration/adapters/sneakers.rb
@@ -1,19 +1,8 @@
# frozen_string_literal: true
require "sneakers/runner"
-require "sneakers/publisher"
require "timeout"
-module Sneakers
- class Publisher
- def safe_ensure_connected
- @mutex.synchronize do
- ensure_connection! unless connected?
- end
- end
- end
-end
-
module SneakersJobsManager
def setup
ActiveJob::Base.queue_adapter = :sneakers
@@ -29,7 +18,8 @@ module SneakersJobsManager
log: Rails.root.join("log/sneakers.log").to_s
unless can_run?
puts "Cannot run integration tests for sneakers. To be able to run integration tests for sneakers you need to install and start rabbitmq.\n"
- exit
+ status = ENV["CI"] ? false : true
+ exit status
end
end
@@ -79,7 +69,7 @@ module SneakersJobsManager
def bunny_publisher
@bunny_publisher ||= begin
p = ActiveJob::QueueAdapters::SneakersAdapter::JobWrapper.send(:publisher)
- p.safe_ensure_connected
+ p.ensure_connection!
p
end
end
diff --git a/activemodel/lib/active_model/type/date_time.rb b/activemodel/lib/active_model/type/date_time.rb
index 9641bf45ee..d48598376e 100644
--- a/activemodel/lib/active_model/type/date_time.rb
+++ b/activemodel/lib/active_model/type/date_time.rb
@@ -39,9 +39,9 @@ module ActiveModel
end
def value_from_multiparameter_assignment(values_hash)
- missing_parameter = (1..3).detect { |key| !values_hash.key?(key) }
- if missing_parameter
- raise ArgumentError, missing_parameter
+ missing_parameters = (1..3).select { |key| !values_hash.key?(key) }
+ if missing_parameters.any?
+ raise ArgumentError, "Provided hash #{values_hash} doesn't contain necessary keys: #{missing_parameters}"
end
super
end
diff --git a/activemodel/test/cases/type/date_time_test.rb b/activemodel/test/cases/type/date_time_test.rb
index 60f62becc2..74b47d1b4d 100644
--- a/activemodel/test/cases/type/date_time_test.rb
+++ b/activemodel/test/cases/type/date_time_test.rb
@@ -25,6 +25,17 @@ module ActiveModel
end
end
+ def test_hash_to_time
+ type = Type::DateTime.new
+ assert_equal ::Time.utc(2018, 10, 15, 0, 0, 0), type.cast(1 => 2018, 2 => 10, 3 => 15)
+ end
+
+ def test_hash_with_wrong_keys
+ type = Type::DateTime.new
+ error = assert_raises(ArgumentError) { type.cast(a: 1) }
+ assert_equal "Provided hash {:a=>1} doesn't contain necessary keys: [1, 2, 3]", error.message
+ end
+
private
def with_timezone_config(default:)
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 08b7c9274d..811fbfd927 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -1125,7 +1125,7 @@ module ActiveRecord
SpawnMethods,
].flat_map { |klass|
klass.public_instance_methods(false)
- } - self.public_instance_methods(false) - [:select] + [:scoping]
+ } - self.public_instance_methods(false) - [:select] + [:scoping, :values]
delegate(*delegate_methods, to: :scope)
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index ff0e863529..6e1275e990 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -29,10 +29,9 @@ module ActiveRecord
# it has been typecast (for example, "2004-12-12" in a date column is cast
# to a date object, like Date.new(2004, 12, 12)).
def read_attribute(attr_name, &block)
- name = if self.class.attribute_alias?(attr_name)
- self.class.attribute_alias(attr_name).to_s
- else
- attr_name.to_s
+ name = attr_name.to_s
+ if self.class.attribute_alias?(name)
+ name = self.class.attribute_alias(name)
end
primary_key = self.class.primary_key
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb
index 7f246eed46..455e67e19b 100644
--- a/activerecord/lib/active_record/attribute_methods/write.rb
+++ b/activerecord/lib/active_record/attribute_methods/write.rb
@@ -33,10 +33,9 @@ module ActiveRecord
# specified +value+. Empty strings for Integer and Float columns are
# turned into +nil+.
def write_attribute(attr_name, value)
- name = if self.class.attribute_alias?(attr_name)
- self.class.attribute_alias(attr_name).to_s
- else
- attr_name.to_s
+ name = attr_name.to_s
+ if self.class.attribute_alias?(name)
+ name = self.class.attribute_alias(name)
end
primary_key = self.class.primary_key
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index b12497fd0a..94c42fb630 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -923,21 +923,18 @@ module ActiveRecord
@arel ||= build_arel(aliases)
end
- # Returns a relation value with a given name
- def get_value(name) # :nodoc:
- @values.fetch(name, DEFAULT_VALUES[name])
- end
-
- protected
+ private
+ # Returns a relation value with a given name
+ def get_value(name)
+ @values.fetch(name, DEFAULT_VALUES[name])
+ end
# Sets the relation value with the given name
- def set_value(name, value) # :nodoc:
+ def set_value(name, value)
assert_mutability!
@values[name] = value
end
- private
-
def assert_mutability!
raise ImmutableRelation if @loaded
raise ImmutableRelation if defined?(@arel) && @arel
@@ -1202,8 +1199,9 @@ module ActiveRecord
STRUCTURAL_OR_METHODS = Relation::VALUE_METHODS - [:extending, :where, :having, :unscope, :references]
def structurally_incompatible_values_for_or(other)
+ values = other.values
STRUCTURAL_OR_METHODS.reject do |method|
- get_value(method) == other.get_value(method)
+ get_value(method) == values.fetch(method, DEFAULT_VALUES[method])
end
end
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 88dfc64ed1..a53e4eb5a2 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Deprecate `ActiveSupport::Multibyte::Unicode#pack_graphemes(array)` and `ActiveSuppport::Multibyte::Unicode#unpack_graphemes(string)`
+ in favor of `array.flatten.pack("U*")` and `string.scan(/\X/).map(&:codepoints)`, respectively.
+
+ *Francesco Rodríguez*
+
* Deprecate `ActiveSupport::Multibyte::Chars.consumes?` in favor of `String#is_utf8?`.
*Francesco Rodríguez*
diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb
index 6159e45230..9acf674c40 100644
--- a/activesupport/lib/active_support/configurable.rb
+++ b/activesupport/lib/active_support/configurable.rb
@@ -2,7 +2,6 @@
require "active_support/concern"
require "active_support/ordered_options"
-require "active_support/core_ext/array/extract_options"
module ActiveSupport
# Configurable provides a <tt>config</tt> method to store and retrieve
@@ -105,9 +104,7 @@ module ActiveSupport
# end
#
# User.hair_colors # => [:brown, :black, :blonde, :red]
- def config_accessor(*names) #:doc:
- options = names.extract_options!
-
+ def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true) # :doc:
names.each do |name|
raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
@@ -117,9 +114,9 @@ module ActiveSupport
singleton_class.class_eval reader, __FILE__, reader_line
singleton_class.class_eval writer, __FILE__, writer_line
- unless options[:instance_accessor] == false
- class_eval reader, __FILE__, reader_line unless options[:instance_reader] == false
- class_eval writer, __FILE__, writer_line unless options[:instance_writer] == false
+ if instance_accessor
+ class_eval reader, __FILE__, reader_line if instance_reader
+ class_eval writer, __FILE__, writer_line if instance_writer
end
send("#{name}=", yield) if block_given?
end
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
index 281eaa7d5f..5850e0193f 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require "active_support/core_ext/array/extract_options"
-
# Extends the module object with class/module and instance accessors for
# class/module attributes, just like the native attr* accessors for instance
# attributes.
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
index b1788a000b..cb996e9e6d 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require "active_support/core_ext/array/extract_options"
-
# Extends the module object with class/module and instance accessors for
# class/module attributes, just like the native attr* accessors for instance
# attributes, but does so on a per-thread basis.
@@ -35,9 +33,7 @@ class Module
# end
#
# Current.new.user # => NoMethodError
- def thread_mattr_reader(*syms) # :nodoc:
- options = syms.extract_options!
-
+ def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true) # :nodoc:
syms.each do |sym|
raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
@@ -49,7 +45,7 @@ class Module
end
EOS
- unless options[:instance_reader] == false || options[:instance_accessor] == false
+ if instance_reader && instance_accessor
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
def #{sym}
self.class.#{sym}
@@ -78,8 +74,7 @@ class Module
# end
#
# Current.new.user = "DHH" # => NoMethodError
- def thread_mattr_writer(*syms) # :nodoc:
- options = syms.extract_options!
+ def thread_mattr_writer(*syms, instance_writer: true, instance_accessor: true) # :nodoc:
syms.each do |sym|
raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
@@ -91,7 +86,7 @@ class Module
end
EOS
- unless options[:instance_writer] == false || options[:instance_accessor] == false
+ if instance_writer && instance_accessor
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
def #{sym}=(obj)
self.class.#{sym} = obj
@@ -141,9 +136,9 @@ class Module
#
# Current.new.user = "DHH" # => NoMethodError
# Current.new.user # => NoMethodError
- def thread_mattr_accessor(*syms)
- thread_mattr_reader(*syms)
- thread_mattr_writer(*syms)
+ def thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true)
+ thread_mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor)
+ thread_mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor)
end
alias :thread_cattr_accessor :thread_mattr_accessor
end
diff --git a/activesupport/lib/active_support/core_ext/numeric/conversions.rb b/activesupport/lib/active_support/core_ext/numeric/conversions.rb
index 7fcd0d0311..8acad6164a 100644
--- a/activesupport/lib/active_support/core_ext/numeric/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/numeric/conversions.rb
@@ -4,127 +4,129 @@ require "active_support/core_ext/big_decimal/conversions"
require "active_support/number_helper"
require "active_support/core_ext/module/deprecation"
-module ActiveSupport::NumericWithFormat
- # Provides options for converting numbers into formatted strings.
- # Options are provided for phone numbers, currency, percentage,
- # precision, positional notation, file size and pretty printing.
- #
- # ==== Options
- #
- # For details on which formats use which options, see ActiveSupport::NumberHelper
- #
- # ==== Examples
- #
- # Phone Numbers:
- # 5551234.to_s(:phone) # => "555-1234"
- # 1235551234.to_s(:phone) # => "123-555-1234"
- # 1235551234.to_s(:phone, area_code: true) # => "(123) 555-1234"
- # 1235551234.to_s(:phone, delimiter: ' ') # => "123 555 1234"
- # 1235551234.to_s(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
- # 1235551234.to_s(:phone, country_code: 1) # => "+1-123-555-1234"
- # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
- # # => "+1.123.555.1234 x 1343"
- #
- # Currency:
- # 1234567890.50.to_s(:currency) # => "$1,234,567,890.50"
- # 1234567890.506.to_s(:currency) # => "$1,234,567,890.51"
- # 1234567890.506.to_s(:currency, precision: 3) # => "$1,234,567,890.506"
- # 1234567890.506.to_s(:currency, locale: :fr) # => "1 234 567 890,51 €"
- # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
- # # => "($1,234,567,890.50)"
- # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
- # # => "&pound;1234567890,50"
- # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
- # # => "1234567890,50 &pound;"
- #
- # Percentage:
- # 100.to_s(:percentage) # => "100.000%"
- # 100.to_s(:percentage, precision: 0) # => "100%"
- # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
- # 302.24398923423.to_s(:percentage, precision: 5) # => "302.24399%"
- # 1000.to_s(:percentage, locale: :fr) # => "1 000,000%"
- # 100.to_s(:percentage, format: '%n %') # => "100.000 %"
- #
- # Delimited:
- # 12345678.to_s(:delimited) # => "12,345,678"
- # 12345678.05.to_s(:delimited) # => "12,345,678.05"
- # 12345678.to_s(:delimited, delimiter: '.') # => "12.345.678"
- # 12345678.to_s(:delimited, delimiter: ',') # => "12,345,678"
- # 12345678.05.to_s(:delimited, separator: ' ') # => "12,345,678 05"
- # 12345678.05.to_s(:delimited, locale: :fr) # => "12 345 678,05"
- # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
- # # => "98 765 432,98"
- #
- # Rounded:
- # 111.2345.to_s(:rounded) # => "111.235"
- # 111.2345.to_s(:rounded, precision: 2) # => "111.23"
- # 13.to_s(:rounded, precision: 5) # => "13.00000"
- # 389.32314.to_s(:rounded, precision: 0) # => "389"
- # 111.2345.to_s(:rounded, significant: true) # => "111"
- # 111.2345.to_s(:rounded, precision: 1, significant: true) # => "100"
- # 13.to_s(:rounded, precision: 5, significant: true) # => "13.000"
- # 111.234.to_s(:rounded, locale: :fr) # => "111,234"
- # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
- # # => "13"
- # 389.32314.to_s(:rounded, precision: 4, significant: true) # => "389.3"
- # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
- # # => "1.111,23"
- #
- # Human-friendly size in Bytes:
- # 123.to_s(:human_size) # => "123 Bytes"
- # 1234.to_s(:human_size) # => "1.21 KB"
- # 12345.to_s(:human_size) # => "12.1 KB"
- # 1234567.to_s(:human_size) # => "1.18 MB"
- # 1234567890.to_s(:human_size) # => "1.15 GB"
- # 1234567890123.to_s(:human_size) # => "1.12 TB"
- # 1234567890123456.to_s(:human_size) # => "1.1 PB"
- # 1234567890123456789.to_s(:human_size) # => "1.07 EB"
- # 1234567.to_s(:human_size, precision: 2) # => "1.2 MB"
- # 483989.to_s(:human_size, precision: 2) # => "470 KB"
- # 1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
- # 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
- # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
- #
- # Human-friendly format:
- # 123.to_s(:human) # => "123"
- # 1234.to_s(:human) # => "1.23 Thousand"
- # 12345.to_s(:human) # => "12.3 Thousand"
- # 1234567.to_s(:human) # => "1.23 Million"
- # 1234567890.to_s(:human) # => "1.23 Billion"
- # 1234567890123.to_s(:human) # => "1.23 Trillion"
- # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
- # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
- # 489939.to_s(:human, precision: 2) # => "490 Thousand"
- # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
- # 1234567.to_s(:human, precision: 4,
- # significant: false) # => "1.2346 Million"
- # 1234567.to_s(:human, precision: 1,
- # separator: ',',
- # significant: false) # => "1,2 Million"
- def to_s(format = nil, options = nil)
- case format
- when nil
- super()
- when Integer, String
- super(format)
- when :phone
- ActiveSupport::NumberHelper.number_to_phone(self, options || {})
- when :currency
- ActiveSupport::NumberHelper.number_to_currency(self, options || {})
- when :percentage
- ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
- when :delimited
- ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
- when :rounded
- ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
- when :human
- ActiveSupport::NumberHelper.number_to_human(self, options || {})
- when :human_size
- ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
- when Symbol
- super()
- else
- super(format)
+module ActiveSupport
+ module NumericWithFormat
+ # Provides options for converting numbers into formatted strings.
+ # Options are provided for phone numbers, currency, percentage,
+ # precision, positional notation, file size and pretty printing.
+ #
+ # ==== Options
+ #
+ # For details on which formats use which options, see ActiveSupport::NumberHelper
+ #
+ # ==== Examples
+ #
+ # Phone Numbers:
+ # 5551234.to_s(:phone) # => "555-1234"
+ # 1235551234.to_s(:phone) # => "123-555-1234"
+ # 1235551234.to_s(:phone, area_code: true) # => "(123) 555-1234"
+ # 1235551234.to_s(:phone, delimiter: ' ') # => "123 555 1234"
+ # 1235551234.to_s(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
+ # 1235551234.to_s(:phone, country_code: 1) # => "+1-123-555-1234"
+ # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
+ # # => "+1.123.555.1234 x 1343"
+ #
+ # Currency:
+ # 1234567890.50.to_s(:currency) # => "$1,234,567,890.50"
+ # 1234567890.506.to_s(:currency) # => "$1,234,567,890.51"
+ # 1234567890.506.to_s(:currency, precision: 3) # => "$1,234,567,890.506"
+ # 1234567890.506.to_s(:currency, locale: :fr) # => "1 234 567 890,51 €"
+ # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
+ # # => "($1,234,567,890.50)"
+ # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
+ # # => "&pound;1234567890,50"
+ # 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
+ # # => "1234567890,50 &pound;"
+ #
+ # Percentage:
+ # 100.to_s(:percentage) # => "100.000%"
+ # 100.to_s(:percentage, precision: 0) # => "100%"
+ # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
+ # 302.24398923423.to_s(:percentage, precision: 5) # => "302.24399%"
+ # 1000.to_s(:percentage, locale: :fr) # => "1 000,000%"
+ # 100.to_s(:percentage, format: '%n %') # => "100.000 %"
+ #
+ # Delimited:
+ # 12345678.to_s(:delimited) # => "12,345,678"
+ # 12345678.05.to_s(:delimited) # => "12,345,678.05"
+ # 12345678.to_s(:delimited, delimiter: '.') # => "12.345.678"
+ # 12345678.to_s(:delimited, delimiter: ',') # => "12,345,678"
+ # 12345678.05.to_s(:delimited, separator: ' ') # => "12,345,678 05"
+ # 12345678.05.to_s(:delimited, locale: :fr) # => "12 345 678,05"
+ # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
+ # # => "98 765 432,98"
+ #
+ # Rounded:
+ # 111.2345.to_s(:rounded) # => "111.235"
+ # 111.2345.to_s(:rounded, precision: 2) # => "111.23"
+ # 13.to_s(:rounded, precision: 5) # => "13.00000"
+ # 389.32314.to_s(:rounded, precision: 0) # => "389"
+ # 111.2345.to_s(:rounded, significant: true) # => "111"
+ # 111.2345.to_s(:rounded, precision: 1, significant: true) # => "100"
+ # 13.to_s(:rounded, precision: 5, significant: true) # => "13.000"
+ # 111.234.to_s(:rounded, locale: :fr) # => "111,234"
+ # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
+ # # => "13"
+ # 389.32314.to_s(:rounded, precision: 4, significant: true) # => "389.3"
+ # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
+ # # => "1.111,23"
+ #
+ # Human-friendly size in Bytes:
+ # 123.to_s(:human_size) # => "123 Bytes"
+ # 1234.to_s(:human_size) # => "1.21 KB"
+ # 12345.to_s(:human_size) # => "12.1 KB"
+ # 1234567.to_s(:human_size) # => "1.18 MB"
+ # 1234567890.to_s(:human_size) # => "1.15 GB"
+ # 1234567890123.to_s(:human_size) # => "1.12 TB"
+ # 1234567890123456.to_s(:human_size) # => "1.1 PB"
+ # 1234567890123456789.to_s(:human_size) # => "1.07 EB"
+ # 1234567.to_s(:human_size, precision: 2) # => "1.2 MB"
+ # 483989.to_s(:human_size, precision: 2) # => "470 KB"
+ # 1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
+ # 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
+ # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
+ #
+ # Human-friendly format:
+ # 123.to_s(:human) # => "123"
+ # 1234.to_s(:human) # => "1.23 Thousand"
+ # 12345.to_s(:human) # => "12.3 Thousand"
+ # 1234567.to_s(:human) # => "1.23 Million"
+ # 1234567890.to_s(:human) # => "1.23 Billion"
+ # 1234567890123.to_s(:human) # => "1.23 Trillion"
+ # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
+ # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
+ # 489939.to_s(:human, precision: 2) # => "490 Thousand"
+ # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
+ # 1234567.to_s(:human, precision: 4,
+ # significant: false) # => "1.2346 Million"
+ # 1234567.to_s(:human, precision: 1,
+ # separator: ',',
+ # significant: false) # => "1,2 Million"
+ def to_s(format = nil, options = nil)
+ case format
+ when nil
+ super()
+ when Integer, String
+ super(format)
+ when :phone
+ ActiveSupport::NumberHelper.number_to_phone(self, options || {})
+ when :currency
+ ActiveSupport::NumberHelper.number_to_currency(self, options || {})
+ when :percentage
+ ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
+ when :delimited
+ ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
+ when :rounded
+ ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
+ when :human
+ ActiveSupport::NumberHelper.number_to_human(self, options || {})
+ when :human_size
+ ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
+ when Symbol
+ super()
+ else
+ super(format)
+ end
end
end
end
diff --git a/activesupport/lib/active_support/core_ext/range/conversions.rb b/activesupport/lib/active_support/core_ext/range/conversions.rb
index 8832fbcb3c..024e32db40 100644
--- a/activesupport/lib/active_support/core_ext/range/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/range/conversions.rb
@@ -1,39 +1,41 @@
# frozen_string_literal: true
-module ActiveSupport::RangeWithFormat
- RANGE_FORMATS = {
- db: -> (start, stop) do
- case start
- when String then "BETWEEN '#{start}' AND '#{stop}'"
+module ActiveSupport
+ module RangeWithFormat
+ RANGE_FORMATS = {
+ db: -> (start, stop) do
+ case start
+ when String then "BETWEEN '#{start}' AND '#{stop}'"
+ else
+ "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'"
+ end
+ end
+ }
+
+ # Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
+ #
+ # range = (1..100) # => 1..100
+ #
+ # range.to_s # => "1..100"
+ # range.to_s(:db) # => "BETWEEN '1' AND '100'"
+ #
+ # == Adding your own range formats to to_s
+ # You can add your own formats to the Range::RANGE_FORMATS hash.
+ # Use the format name as the hash key and a Proc instance.
+ #
+ # # config/initializers/range_formats.rb
+ # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
+ def to_s(format = :default)
+ if formatter = RANGE_FORMATS[format]
+ formatter.call(first, last)
else
- "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'"
+ super()
end
end
- }
- # Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
- #
- # range = (1..100) # => 1..100
- #
- # range.to_s # => "1..100"
- # range.to_s(:db) # => "BETWEEN '1' AND '100'"
- #
- # == Adding your own range formats to to_s
- # You can add your own formats to the Range::RANGE_FORMATS hash.
- # Use the format name as the hash key and a Proc instance.
- #
- # # config/initializers/range_formats.rb
- # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
- def to_s(format = :default)
- if formatter = RANGE_FORMATS[format]
- formatter.call(first, last)
- else
- super()
- end
+ alias_method :to_default_s, :to_s
+ alias_method :to_formatted_s, :to_s
end
-
- alias_method :to_default_s, :to_s
- alias_method :to_formatted_s, :to_s
end
Range.prepend(ActiveSupport::RangeWithFormat)
diff --git a/activesupport/lib/active_support/current_attributes.rb b/activesupport/lib/active_support/current_attributes.rb
index 4e6d8e4585..3145ff87a1 100644
--- a/activesupport/lib/active_support/current_attributes.rb
+++ b/activesupport/lib/active_support/current_attributes.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/callbacks"
+
module ActiveSupport
# Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
# before and after each request. This allows you to keep all the per-request attributes easily
diff --git a/activesupport/lib/active_support/execution_wrapper.rb b/activesupport/lib/active_support/execution_wrapper.rb
index f48c586cad..ca810db584 100644
--- a/activesupport/lib/active_support/execution_wrapper.rb
+++ b/activesupport/lib/active_support/execution_wrapper.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require "active_support/callbacks"
+require "concurrent/hash"
module ActiveSupport
class ExecutionWrapper
diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index bd8cab3460..a1e23aeaca 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -122,7 +122,7 @@ module ActiveSupport #:nodoc:
#
# 'こんにちは'.mb_chars.limit(7).to_s # => "こん"
def limit(limit)
- slice(0...translate_offset(limit))
+ truncate_bytes(limit, omission: nil)
end
# Capitalizes the first letter of every word, when possible.
@@ -208,18 +208,6 @@ module ActiveSupport #:nodoc:
private
- def translate_offset(byte_offset)
- return nil if byte_offset.nil?
- return 0 if @wrapped_string == ""
-
- begin
- @wrapped_string.byteslice(0...byte_offset).unpack("U*").length
- rescue ArgumentError
- byte_offset -= 1
- retry
- end
- end
-
def chars(string)
self.class.new(string)
end
diff --git a/activesupport/lib/active_support/multibyte/unicode.rb b/activesupport/lib/active_support/multibyte/unicode.rb
index 43d196eeeb..ce8ecece69 100644
--- a/activesupport/lib/active_support/multibyte/unicode.rb
+++ b/activesupport/lib/active_support/multibyte/unicode.rb
@@ -34,6 +34,11 @@ module ActiveSupport
# Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
# Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
def unpack_graphemes(string)
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ ActiveSupport::Multibyte::Unicode#unpack_graphemes is deprecated and will be
+ removed from Rails 6.1. Use string.scan(/\X/).map(&:codepoints) instead.
+ MSG
+
string.scan(/\X/).map(&:codepoints)
end
@@ -41,6 +46,11 @@ module ActiveSupport
#
# Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
def pack_graphemes(unpacked)
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ ActiveSupport::Multibyte::Unicode#pack_graphemes is deprecated and will be
+ removed from Rails 6.1. Use array.flatten.pack("U*") instead.
+ MSG
+
unpacked.flatten.pack("U*")
end
diff --git a/activesupport/lib/active_support/number_helper.rb b/activesupport/lib/active_support/number_helper.rb
index c75ad52b0c..d19a2f64d4 100644
--- a/activesupport/lib/active_support/number_helper.rb
+++ b/activesupport/lib/active_support/number_helper.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/dependencies/autoload"
+
module ActiveSupport
module NumberHelper
extend ActiveSupport::Autoload
diff --git a/activesupport/lib/active_support/number_helper/number_to_currency_converter.rb b/activesupport/lib/active_support/number_helper/number_to_currency_converter.rb
index aef5b62aed..0e8ae82dd5 100644
--- a/activesupport/lib/active_support/number_helper/number_to_currency_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_currency_converter.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/number_helper/number_converter"
+
module ActiveSupport
module NumberHelper
class NumberToCurrencyConverter < NumberConverter # :nodoc:
diff --git a/activesupport/lib/active_support/number_helper/number_to_delimited_converter.rb b/activesupport/lib/active_support/number_helper/number_to_delimited_converter.rb
index 05427fef53..467a580a2e 100644
--- a/activesupport/lib/active_support/number_helper/number_to_delimited_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_delimited_converter.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/number_helper/number_converter"
+
module ActiveSupport
module NumberHelper
class NumberToDelimitedConverter < NumberConverter #:nodoc:
diff --git a/activesupport/lib/active_support/number_helper/number_to_human_converter.rb b/activesupport/lib/active_support/number_helper/number_to_human_converter.rb
index 908f788ee3..494408fc01 100644
--- a/activesupport/lib/active_support/number_helper/number_to_human_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_human_converter.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/number_helper/number_converter"
+
module ActiveSupport
module NumberHelper
class NumberToHumanConverter < NumberConverter # :nodoc:
diff --git a/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb b/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
index 0c72096b72..91262fa656 100644
--- a/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/number_helper/number_converter"
+
module ActiveSupport
module NumberHelper
class NumberToHumanSizeConverter < NumberConverter #:nodoc:
diff --git a/activesupport/lib/active_support/number_helper/number_to_percentage_converter.rb b/activesupport/lib/active_support/number_helper/number_to_percentage_converter.rb
index 6618ecffd5..0c2e190f8a 100644
--- a/activesupport/lib/active_support/number_helper/number_to_percentage_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_percentage_converter.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/number_helper/number_converter"
+
module ActiveSupport
module NumberHelper
class NumberToPercentageConverter < NumberConverter # :nodoc:
diff --git a/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb b/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb
index 96410f4995..d5e72981b4 100644
--- a/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/number_helper/number_converter"
+
module ActiveSupport
module NumberHelper
class NumberToPhoneConverter < NumberConverter #:nodoc:
diff --git a/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb b/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb
index 0ee5ef92dd..6ceb9a572e 100644
--- a/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/number_helper/number_converter"
+
module ActiveSupport
module NumberHelper
class NumberToRoundedConverter < NumberConverter # :nodoc:
diff --git a/activesupport/lib/active_support/subscriber.rb b/activesupport/lib/active_support/subscriber.rb
index 9562149f8d..f3e902f9dd 100644
--- a/activesupport/lib/active_support/subscriber.rb
+++ b/activesupport/lib/active_support/subscriber.rb
@@ -79,12 +79,12 @@ module ActiveSupport
end
def start(name, id, payload)
- e = ActiveSupport::Notifications::Event.new(name, nil, nil, id, payload)
- e.start!
+ event = ActiveSupport::Notifications::Event.new(name, nil, nil, id, payload)
+ event.start!
parent = event_stack.last
- parent << e if parent
+ parent << event if parent
- event_stack.push e
+ event_stack.push event
end
def finish(name, id, payload)
diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb
index 6b33f5f9b2..f87099566b 100644
--- a/activesupport/test/multibyte_chars_test.rb
+++ b/activesupport/test/multibyte_chars_test.rb
@@ -785,21 +785,3 @@ class MultibyteCharsExtrasTest < ActiveSupport::TestCase
end.pack("U*")
end
end
-
-class MultibyteInternalsTest < ActiveSupport::TestCase
- include MultibyteTestHelpers
-
- test "Chars translates a character offset to a byte offset" do
- example = chars("Puisque c'était son erreur, il m'a aidé")
- [
- [0, 0],
- [3, 3],
- [12, 11],
- [14, 13],
- [41, 39]
- ].each do |byte_offset, character_offset|
- assert_equal character_offset, example.send(:translate_offset, byte_offset),
- "Expected byte offset #{byte_offset} to translate to #{character_offset}"
- end
- end
-end
diff --git a/activesupport/test/multibyte_grapheme_break_conformance_test.rb b/activesupport/test/multibyte_grapheme_break_conformance_test.rb
index 61b171a8d4..97963279af 100644
--- a/activesupport/test/multibyte_grapheme_break_conformance_test.rb
+++ b/activesupport/test/multibyte_grapheme_break_conformance_test.rb
@@ -17,10 +17,12 @@ class MultibyteGraphemeBreakConformanceTest < ActiveSupport::TestCase
end
def test_breaks
- each_line_of_break_tests do |*cols|
- *clusters, comment = *cols
- packed = ActiveSupport::Multibyte::Unicode.pack_graphemes(clusters)
- assert_equal clusters, ActiveSupport::Multibyte::Unicode.unpack_graphemes(packed), comment
+ ActiveSupport::Deprecation.silence do
+ each_line_of_break_tests do |*cols|
+ *clusters, comment = *cols
+ packed = ActiveSupport::Multibyte::Unicode.pack_graphemes(clusters)
+ assert_equal clusters, ActiveSupport::Multibyte::Unicode.unpack_graphemes(packed), comment
+ end
end
end
diff --git a/guides/assets/images/rails_guides_logo_1x.png b/guides/assets/images/rails_guides_logo_1x.png
new file mode 100644
index 0000000000..8c6810c312
--- /dev/null
+++ b/guides/assets/images/rails_guides_logo_1x.png
Binary files differ
diff --git a/guides/assets/images/rails_guides_logo_2x.png b/guides/assets/images/rails_guides_logo_2x.png
new file mode 100644
index 0000000000..accc6bbfa4
--- /dev/null
+++ b/guides/assets/images/rails_guides_logo_2x.png
Binary files differ
diff --git a/guides/assets/stylesheets/main.css b/guides/assets/stylesheets/main.css
index 2657a84a91..bdc3e21977 100644
--- a/guides/assets/stylesheets/main.css
+++ b/guides/assets/stylesheets/main.css
@@ -401,14 +401,10 @@ a, a:link, a:visited {
}
#guides {
- width: 27em;
+ width: 37em;
display: block;
background: #980905;
border-radius: 1em;
- -webkit-border-radius: 1em;
- -moz-border-radius: 1em;
- -webkit-box-shadow: 0.25em 0.25em 1em rgba(0,0,0,0.25);
- -moz-box-shadow: rgba(0,0,0,0.25) 0.25em 0.25em 1em;
color: #f1938c;
padding: 1.5em 2em;
position: absolute;
@@ -422,17 +418,44 @@ a, a:link, a:visited {
display: block !important;
}
-#guides dt, #guides dd {
+.guides-section dt, .guides-section dd {
font-weight: normal;
font-size: 0.722em;
margin: 0;
padding: 0;
}
-#guides dt {padding:0; margin: 0.5em 0 0;}
-#guides a {color: #FFF; background: none !important; text-decoration: none;}
-#guides a:hover {text-decoration: underline;}
-#guides .L, #guides .R {float: left; width: 50%; margin: 0; padding: 0;}
-#guides .R {float: right;}
+.guides-section dt {
+ margin: 0.5em 0 0;
+ padding:0;
+}
+#guides a {
+ background: none !important;
+ color: #FFF;
+ text-decoration: none;
+}
+#guides a:hover {
+ text-decoration: underline;
+}
+.guides-section-container {
+ display: flex;
+ flex-direction: column;
+ flex-wrap: wrap;
+ width: 100%;
+ max-height: 35em;
+}
+
+.guides-section {
+ min-width: 5em;
+ margin: 0 2em 0.5em 0;
+ flex: auto;
+ max-width: 12em;
+}
+
+.guides-section dd {
+ line-height: 1.3;
+ margin-bottom: 0.5em;
+}
+
#guides hr {
display: block;
border: none;
@@ -515,13 +538,26 @@ h6 {
#header h1 {
float: left;
- background: url(../images/rails_guides_logo.gif) no-repeat;
+ background: url(../images/rails_guides_logo_1x.png) no-repeat;
width: 297px;
text-indent: -9999em;
margin: 0;
padding: 0;
}
+@media
+only screen and (-webkit-min-device-pixel-ratio: 2),
+only screen and ( min--moz-device-pixel-ratio: 2),
+only screen and ( -o-min-device-pixel-ratio: 2/1),
+only screen and ( min-device-pixel-ratio: 2),
+only screen and ( min-resolution: 192dpi),
+only screen and ( min-resolution: 2dppx) {
+ #header h1 {
+ background: url(../images/rails_guides_logo_2x.png) no-repeat;
+ background-size: 160%;
+ }
+}
+
@media screen and (max-width: 480px) {
#header h1 {
float: none;
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index b0a905c754..78a1f47407 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -868,7 +868,7 @@ While Rails uses intelligent defaults that will work well in most situations, th
```ruby
class Book < ApplicationRecord
- belongs_to :author, dependent: :destroy,
+ belongs_to :author, touch: :books_updated_at,
counter_cache: true
end
```
@@ -1048,8 +1048,7 @@ There may be times when you wish to customize the query used by `belongs_to`. Su
```ruby
class Book < ApplicationRecord
- belongs_to :author, -> { where active: true },
- dependent: :destroy
+ belongs_to :author, -> { where active: true }
end
```
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 812565b207..61bb35cf93 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -200,8 +200,6 @@ The full set of methods that can be used in this block are as follows:
* `helper` defines whether or not to generate helpers. Defaults to `true`.
* `integration_tool` defines which integration tool to use to generate integration tests. Defaults to `:test_unit`.
* `system_tests` defines which integration tool to use to generate system tests. Defaults to `:test_unit`.
-* `javascripts` turns on the hook for JavaScript files in generators. Used in Rails for when the `scaffold` generator is run. Defaults to `true`.
-* `javascript_engine` configures the engine to be used (for eg. coffee) when generating assets. Defaults to `:js`.
* `orm` defines which orm to use. Defaults to `false` and will use Active Record by default.
* `resource_controller` defines which generator to use for generating a controller when using `rails generate resource`. Defaults to `:controller`.
* `resource_route` defines whether a resource route definition should be generated
diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md
index 88d205e1ab..7f7766e7d7 100644
--- a/guides/source/debugging_rails_applications.md
+++ b/guides/source/debugging_rails_applications.md
@@ -186,14 +186,17 @@ end
Here's an example of the log generated when this controller action is executed:
```
-Started POST "/articles" for 127.0.0.1 at 2017-08-20 20:53:10 +0900
+Started POST "/articles" for 127.0.0.1 at 2018-10-18 20:09:23 -0400
Processing by ArticlesController#create as HTML
- Parameters: {"utf8"=>"✓", "authenticity_token"=>"xhuIbSBFytHCE1agHgvrlKnSVIOGD6jltW2tO+P6a/ACjQ3igjpV4OdbsZjIhC98QizWH9YdKokrqxBCJrtoqQ==", "article"=>{"title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs!!!", "published"=>"0"}, "commit"=>"Create Article"}
-New article: {"id"=>nil, "title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs!!!", "published"=>false, "created_at"=>nil, "updated_at"=>nil}
+ Parameters: {"utf8"=>"✓", "authenticity_token"=>"XLveDrKzF1SwaiNRPTaMtkrsTzedtebPPkmxEFIU0ordLjICSnXsSNfrdMa4ccyBjuGwnnEiQhEoMN6H1Gtz3A==", "article"=>{"title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs.", "published"=>"0"}, "commit"=>"Create Article"}
+New article: {"id"=>nil, "title"=>"Debugging Rails", "body"=>"I'm learning how to print in logs.", "published"=>false, "created_at"=>nil, "updated_at"=>nil}
Article should be valid: true
- (0.1ms) BEGIN
- SQL (0.4ms) INSERT INTO "articles" ("title", "body", "published", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["title", "Debugging Rails"], ["body", "I'm learning how to print in logs!!!"], ["published", "f"], ["created_at", "2017-08-20 11:53:10.010435"], ["updated_at", "2017-08-20 11:53:10.010435"]]
- (0.3ms) COMMIT
+ (0.0ms) begin transaction
+ ↳ app/controllers/articles_controller.rb:31
+ Article Create (0.5ms) INSERT INTO "articles" ("title", "body", "published", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["title", "Debugging Rails"], ["body", "I'm learning how to print in logs."], ["published", 0], ["created_at", "2018-10-19 00:09:23.216549"], ["updated_at", "2018-10-19 00:09:23.216549"]]
+ ↳ app/controllers/articles_controller.rb:31
+ (2.3ms) commit transaction
+ ↳ app/controllers/articles_controller.rb:31
The article was saved and now the user is going to be redirected...
Redirected to http://localhost:3000/articles/1
Completed 302 Found in 4ms (ActiveRecord: 0.8ms)
@@ -201,6 +204,40 @@ Completed 302 Found in 4ms (ActiveRecord: 0.8ms)
Adding extra logging like this makes it easy to search for unexpected or unusual behavior in your logs. If you add extra logging, be sure to make sensible use of log levels to avoid filling your production logs with useless trivia.
+### Verbose Query Logs
+
+When looking at database query output in logs, it may not be immediately clear why multiple database queries are triggered when a single method is called:
+
+```
+irb(main):001:0> Article.pamplemousse
+ Article Load (0.4ms) SELECT "articles".* FROM "articles"
+ Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 1]]
+ Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 2]]
+ Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 3]]
+=> #<Comment id: 2, author: "1", body: "Well, actually...", article_id: 1, created_at: "2018-10-19 00:56:10", updated_at: "2018-10-19 00:56:10">
+```
+
+After running `ActiveRecord::Base.verbose_query_logs = true` in the `rails console` session to enable verbose query logs and running the method again, it becomes obvious what single line of code is generating all these discrete database calls:
+
+```
+irb(main):003:0> Article.pamplemousse
+ Article Load (0.2ms) SELECT "articles".* FROM "articles"
+ ↳ app/models/article.rb:5
+ Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 1]]
+ ↳ app/models/article.rb:6
+ Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 2]]
+ ↳ app/models/article.rb:6
+ Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 3]]
+ ↳ app/models/article.rb:6
+=> #<Comment id: 2, author: "1", body: "Well, actually...", article_id: 1, created_at: "2018-10-19 00:56:10", updated_at: "2018-10-19 00:56:10">
+```
+
+Below each database statement you can see arrows pointing to the specific source filename (and line number) of the method that resulted in a database call. This can help you identity and address performance problems caused by N+1 queries: single database queries that generates multiple additional queries.
+
+Verbose query logs are enabled by default in the development environment logs after Rails 5.2.
+
+WARNING: We recommend against using this setting in production environments. It relies on Ruby's `Kernel#caller` method which tends to allocate a lot of memory in order to generate stacktraces of method calls.
+
### Tagged Logging
When running multi-user, multi-account applications, it's often useful
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 8f2312458d..551179c523 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -173,7 +173,7 @@
description: This guide describes the considerations needed and tools available when working directly with concurrency in a Rails application.
work_in_progress: true
-
- name: Contributing to Ruby on Rails
+ name: Contributions
documents:
-
name: Contributing to Ruby on Rails
@@ -184,14 +184,14 @@
url: api_documentation_guidelines.html
description: This guide documents the Ruby on Rails API documentation guidelines.
-
- name: Ruby on Rails Guides Guidelines
+ name: Guides Guidelines
url: ruby_on_rails_guides_guidelines.html
description: This guide documents the Ruby on Rails guides guidelines.
-
- name: Maintenance Policy
+ name: Policies
documents:
-
- name: Maintenance Policy for Ruby on Rails
+ name: Maintenance Policy
url: maintenance_policy.html
description: What versions of Ruby on Rails are currently supported, and when to expect new versions.
-
@@ -202,51 +202,51 @@
url: upgrading_ruby_on_rails.html
description: This guide helps in upgrading applications to latest Ruby on Rails versions.
-
- name: Ruby on Rails 6.0 Release Notes
+ name: 6.0 Release Notes
work_in_progress: true
url: 6_0_release_notes.html
description: Release notes for Rails 6.0.
-
- name: Ruby on Rails 5.2 Release Notes
+ name: 5.2 Release Notes
url: 5_2_release_notes.html
description: Release notes for Rails 5.2.
-
- name: Ruby on Rails 5.1 Release Notes
+ name: 5.1 Release Notes
url: 5_1_release_notes.html
description: Release notes for Rails 5.1.
-
- name: Ruby on Rails 5.0 Release Notes
+ name: 5.0 Release Notes
url: 5_0_release_notes.html
description: Release notes for Rails 5.0.
-
- name: Ruby on Rails 4.2 Release Notes
+ name: 4.2 Release Notes
url: 4_2_release_notes.html
description: Release notes for Rails 4.2.
-
- name: Ruby on Rails 4.1 Release Notes
+ name: 4.1 Release Notes
url: 4_1_release_notes.html
description: Release notes for Rails 4.1.
-
- name: Ruby on Rails 4.0 Release Notes
+ name: 4.0 Release Notes
url: 4_0_release_notes.html
description: Release notes for Rails 4.0.
-
- name: Ruby on Rails 3.2 Release Notes
+ name: 3.2 Release Notes
url: 3_2_release_notes.html
description: Release notes for Rails 3.2.
-
- name: Ruby on Rails 3.1 Release Notes
+ name: 3.1 Release Notes
url: 3_1_release_notes.html
description: Release notes for Rails 3.1.
-
- name: Ruby on Rails 3.0 Release Notes
+ name: 3.0 Release Notes
url: 3_0_release_notes.html
description: Release notes for Rails 3.0.
-
- name: Ruby on Rails 2.3 Release Notes
+ name: 2.3 Release Notes
url: 2_3_release_notes.html
description: Release notes for Rails 2.3.
-
- name: Ruby on Rails 2.2 Release Notes
+ name: 2.2 Release Notes
url: 2_2_release_notes.html
description: Release notes for Rails 2.2.
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index 78e5f27448..eba71eec60 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -116,7 +116,7 @@ NOTE: The backend lazy-loads these translations when a translation is looked up
You can change the default locale as well as configure the translations load paths in `config/application.rb` as follows:
```ruby
- config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
+ config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
config.i18n.default_locale = :de
```
@@ -135,6 +135,8 @@ I18n.available_locales = [:en, :pt]
I18n.default_locale = :pt
```
+Note that appending directly to `I18n.load_paths` instead of to the application's configured i18n will _not_ override translations from external gems.
+
### Managing the Locale across Requests
The default locale is used for all translations unless `I18n.locale` is explicitly set.
diff --git a/guides/source/layout.html.erb b/guides/source/layout.html.erb
index dd9175e312..1f42d72756 100644
--- a/guides/source/layout.html.erb
+++ b/guides/source/layout.html.erb
@@ -45,16 +45,16 @@
<a href="index.html" id="guidesMenu" class="guides-index-item nav-item">Guides Index</a>
<div id="guides" class="clearfix" style="display: none;">
<hr />
- <% ['L', 'R'].each do |position| %>
- <dl class="<%= position %>">
- <% docs_for_menu(position).each do |section| %>
- <dt><%= section['name'] %></dt>
- <% finished_documents(section['documents']).each do |document| %>
- <dd><a href="<%= document['url'] %>"><%= document['name'] %></a></dd>
- <% end %>
+ <div class="guides-section-container">
+ <% documents_by_section.each do |section| %>
+ <div class="guides-section">
+ <dt><%= section['name'] %></dt>
+ <% finished_documents(section['documents']).each do |document| %>
+ <dd><a href="<%= document['url'] %>"><%= document['name'] %></a></dd>
+ <% end %>
+ </div>
<% end %>
- </dl>
- <% end %>
+ </div>
</div>
</li>
<li><a class="nav-item" href="contributing_to_ruby_on_rails.html">Contribute</a></li>
diff --git a/guides/source/testing.md b/guides/source/testing.md
index 9de2229672..8c21ccfba6 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -1562,7 +1562,7 @@ class UserMailerTest < ActionMailer::TestCase
end
```
-In the test we send the email and store the returned object in the `email`
+In the test we create the email and store the returned object in the `email`
variable. We then ensure that it was sent (the first assert), then, in the
second batch of assertions, we ensure that the email does indeed contain what we
expect. The helper `read_fixture` is used to read in the content from this file.
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index eaa2353701..f94b67a0ac 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -17,34 +17,18 @@
*DHH*, *Lachlan Sylvester*
-* Refactors `migrations_paths` command option in generators
- to `database` (aliased as `db`). Now, the migrations paths
- will be read from the specified database configuration in the
- current environment.
+* Add `database` (aliased as `db`) option to model generator to allow
+ setting the database. This is useful for applications that use
+ multiple databases and put migrations per database in their own directories.
```
- bin/rails g model Chair brand:string --database=kingston
- invoke active_record
- create db/kingston_migrate/20180830151055_create_chairs.rb
- ```
-
- `--database` can be used with the migration, model, and scaffold generators.
-
- *Gannon McGibbon*
-
-* Adds an option to the model generator to allow setting the
- migrations paths for that migration. This is useful for
- applications that use multiple databases and put migrations
- per database in their own directories.
-
- ```
- bin/rails g model Room capacity:integer --migrations-paths=db/kingston_migrate
+ bin/rails g model Room capacity:integer --database=kingston
invoke active_record
create db/kingston_migrate/20180830151055_create_rooms.rb
```
Because rails scaffolding uses the model generator, you can
- also specify migrations paths with the scaffold generator.
+ also specify a database with the scaffold generator.
*Gannon McGibbon*
@@ -72,15 +56,15 @@
*Yoshiyuki Kinjo*
-* Add `--migrations_paths` option to migration generator.
+* Add `database` (aliased as `db`) option to migration generator.
If you're using multiple databases and have a folder for each database
for migrations (ex db/migrate and db/new_db_migrate) you can now pass the
- `--migrations_paths` option to the generator to make sure the the migration
+ `--database` option to the generator to make sure the the migration
is inserted into the correct folder.
```
- rails g migration CreateHouses --migrations_paths=db/kingston_migrate
+ rails g migration CreateHouses --database=kingston
invoke active_record
create db/kingston_migrate/20180830151055_create_houses.rb
```
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index cd8f16e247..5e8cebc50a 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -54,8 +54,6 @@ module Rails
force_plural: false,
helper: true,
integration_tool: nil,
- javascripts: true,
- javascript_engine: :js,
orm: false,
resource_controller: :controller,
resource_route: true,
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index b118ea989b..1c7cf1a951 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -438,7 +438,6 @@ module Rails
def delete_action_cable_files_skipping_action_cable
if options[:skip_action_cable]
- remove_file "app/javascript/channels/consumer.js"
remove_dir "app/javascript/channels"
remove_dir "app/channels"
end
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
index 1567333023..fb264935bd 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
@@ -45,6 +45,7 @@ group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
+<% end -%>
group :development do
<%- unless options.api? -%>
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
@@ -75,7 +76,6 @@ group :test do
gem 'chromedriver-helper'
end
<%- end -%>
-<% end -%>
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
diff --git a/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js b/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js
index 5da1ce2dce..0cfcf74919 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js
+++ b/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js
@@ -1,5 +1,5 @@
-// Load all the channels within this directory and all subdirectories.
+// Load all the channels within this directory and all subdirectories.
// Channel files must be named *_channel.js.
-const channels = require.context('.', true, /\_channel\.js$/)
+const channels = require.context('.', true, /_channel\.js$/)
channels.keys().forEach(channels)
diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore.tt b/railties/lib/rails/generators/rails/app/templates/gitignore.tt
index 4e114fb1d9..38c3ab1319 100644
--- a/railties/lib/rails/generators/rails/app/templates/gitignore.tt
+++ b/railties/lib/rails/generators/rails/app/templates/gitignore.tt
@@ -28,13 +28,8 @@
!/storage/.keep
<% end -%>
<% end -%>
-
-<% unless options.skip_yarn? -%>
-/node_modules
-/yarn-error.log
-
-<% end -%>
<% unless options.api? -%>
+
/public/assets
<% end -%>
.byebug_history
diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
index a018a98c53..532278f215 100644
--- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
@@ -88,7 +88,7 @@ task default: :test
PASSTHROUGH_OPTIONS = [
:skip_active_record, :skip_active_storage, :skip_action_mailer, :skip_javascript, :skip_action_cable, :skip_sprockets, :database,
- :javascript, :skip_yarn, :api, :quiet, :pretend, :skip
+ :skip_yarn, :api, :quiet, :pretend, :skip
]
def generate_test_dummy(force = false)
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index be97abfa52..f5356a358f 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -15,6 +15,8 @@ DEFAULT_APP_FILES = %w(
app/assets/images
app/javascript
app/javascript/channels
+ app/javascript/channels/consumer.js
+ app/javascript/channels/index.js
app/javascript/packs/application.js
app/assets/stylesheets
app/assets/stylesheets/application.css
@@ -104,7 +106,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_skip_bundle
- assert_not_called(generator([destination_root], skip_bundle: true), :bundle_command) do
+ assert_not_called(generator([destination_root], skip_bundle: true, skip_webpack_install: true), :bundle_command) do
quietly { generator.invoke_all }
# skip_bundle is only about running bundle install, ensure the Gemfile is still
# generated.
@@ -608,7 +610,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "app/views/layouts/application.html.erb" do |contents|
assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents)
- assert_no_match(/javascript_include_tag\s+'application' \%>/, contents)
+ assert_no_match(/javascript_pack_tag\s+'application'/, contents)
end
end
@@ -710,7 +712,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_web_console_with_dev_option
- run_generator [destination_root, "--dev"]
+ run_generator [destination_root, "--dev", "--skip-bundle"]
assert_file "Gemfile" do |content|
assert_match(/gem 'web-console',\s+github: 'rails\/web-console'/, content)
@@ -728,13 +730,13 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_generation_runs_bundle_install
- generator([destination_root], {})
+ generator([destination_root], skip_webpack_install: true)
assert_bundler_command_called("install")
end
def test_dev_option
- generator([destination_root], dev: true)
+ generator([destination_root], dev: true, skip_webpack_install: true)
assert_bundler_command_called("install")
rails_path = File.expand_path("../../..", Rails.root)
@@ -742,7 +744,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_edge_option
- generator([destination_root], edge: true)
+ generator([destination_root], edge: true, skip_webpack_install: true)
assert_bundler_command_called("install")
assert_file "Gemfile", %r{^gem\s+["']rails["'],\s+github:\s+["']#{Regexp.escape("rails/rails")}["']$}
@@ -754,12 +756,16 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_bundler_binstub
+ generator([destination_root], skip_webpack_install: true)
+
assert_bundler_command_called("binstubs bundler")
end
def test_spring_binstubs
jruby_skip "spring doesn't run on JRuby"
+ generator([destination_root], skip_webpack_install: true)
+
assert_bundler_command_called("exec spring binstub --all")
end
@@ -780,7 +786,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_spring_with_dev_option
- run_generator [destination_root, "--dev"]
+ run_generator [destination_root, "--dev", "--skip-bundle"]
assert_no_gem "spring"
end
@@ -790,7 +796,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
@called ||= 0
if command == "webpacker:install"
@called += 1
- assert_equal 0, @called, "webpacker:install expected not to be called once, but was called #{@called} times."
+ assert_equal 0, @called, "webpacker:install expected not to be called, but was called #{@called} times."
end
end
@@ -878,7 +884,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_bootsnap_with_dev_option
- run_generator [destination_root, "--dev"]
+ run_generator [destination_root, "--dev", "--skip-bundle"]
assert_no_gem "bootsnap"
assert_file "config/boot.rb" do |content|
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
index fc654e867b..9b980bd52b 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -91,7 +91,7 @@ module SharedGeneratorTests
template
end
- generator([destination_root], template: path).stub(:open, check_open, template) do
+ generator([destination_root], template: path, skip_webpack_install: true).stub(:open, check_open, template) do
generator.stub :bundle_command, nil do
quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) }
end
@@ -99,7 +99,7 @@ module SharedGeneratorTests
end
def test_skip_gemfile
- assert_not_called(generator([destination_root], skip_gemfile: true), :bundle_command) do
+ assert_not_called(generator([destination_root], skip_gemfile: true, skip_webpack_install: true), :bundle_command) do
quietly { generator.invoke_all }
assert_no_file "Gemfile"
end
@@ -231,7 +231,7 @@ module SharedGeneratorTests
assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/
assert_file "#{application_path}/app/javascript/packs/application.js" do |content|
- assert_no_match(/^\/\/= require activestorage/, content)
+ assert_no_match(/activestorage/, content)
end
assert_file "#{application_path}/config/environments/development.rb" do |content|
@@ -261,7 +261,7 @@ module SharedGeneratorTests
assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/
assert_file "#{application_path}/app/javascript/packs/application.js" do |content|
- assert_no_match(/^import * as ActiveStorage from "activestorage"\nActiveStorage.start()/, content)
+ assert_no_match(/^import * as ActiveStorage from "activestorage"\nActiveStorage.start\(\)/, content)
end
assert_file "#{application_path}/config/environments/development.rb" do |content|
@@ -339,11 +339,6 @@ module SharedGeneratorTests
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
@@ -354,10 +349,5 @@ module SharedGeneratorTests
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