提交 afb66a5a 编写于 作者: M Matthew Draper

Merge pull request #29506 from pat/frozen-string-literals

Make ActiveSupport frozen-string-literal friendly.
......@@ -120,7 +120,7 @@ class BaseTest < ActiveSupport::TestCase
email = BaseMailer.attachment_with_hash
assert_equal(1, email.attachments.length)
assert_equal("invoice.jpg", email.attachments[0].filename)
expected = "\312\213\254\232)b"
expected = "\312\213\254\232)b".dup
expected.force_encoding(Encoding::BINARY)
assert_equal expected, email.attachments["invoice.jpg"].decoded
end
......@@ -129,7 +129,7 @@ class BaseTest < ActiveSupport::TestCase
email = BaseMailer.attachment_with_hash_default_encoding
assert_equal(1, email.attachments.length)
assert_equal("invoice.jpg", email.attachments[0].filename)
expected = "\312\213\254\232)b"
expected = "\312\213\254\232)b".dup
expected.force_encoding(Encoding::BINARY)
assert_equal expected, email.attachments["invoice.jpg"].decoded
end
......
......@@ -24,7 +24,7 @@ def process_action(event)
exception_class_name = payload[:exception].first
status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
end
message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms".dup
message << " (#{additions.join(" | ".freeze)})" unless additions.empty?
message << "\n\n" if defined?(Rails.env) && Rails.env.development?
......
......@@ -103,7 +103,7 @@ def initialize(response, buf)
def body
@str_body ||= begin
buf = ""
buf = "".dup
each { |chunk| buf << chunk }
buf
end
......
......@@ -14,11 +14,11 @@ class Utils # :nodoc:
# normalize_path("/%ab") # => "/%AB"
def self.normalize_path(path)
encoding = path.encoding
path = "/#{path}"
path = "/#{path}".dup
path.squeeze!("/".freeze)
path.sub!(%r{/+\Z}, "".freeze)
path.gsub!(/(%[a-f0-9]{2})/) { $1.upcase }
path = "/" if path == "".freeze
path = "/".dup if path == "".freeze
path.force_encoding(encoding)
path
end
......@@ -29,7 +29,7 @@ class UriEncoder # :nodoc:
ENCODE = "%%%02X".freeze
US_ASCII = Encoding::US_ASCII
UTF_8 = Encoding::UTF_8
EMPTY = "".force_encoding(US_ASCII).freeze
EMPTY = "".dup.force_encoding(US_ASCII).freeze
DEC2HEX = (0..255).to_a.map { |i| ENCODE % i }.map { |s| s.force_encoding(US_ASCII) }
ALPHA = "a-zA-Z".freeze
......
......@@ -79,7 +79,7 @@ def normalize_argument_to_redirection(fragment)
def generate_response_message(expected, actual = @response.response_code)
"Expected response to be a <#{code_with_name(expected)}>,"\
" but was a <#{code_with_name(actual)}>"
.concat(location_if_redirected).concat(response_body_if_short)
.dup.concat(location_if_redirected).concat(response_body_if_short)
end
def response_body_if_short
......
......@@ -1007,7 +1007,7 @@ def build_select(type, select_options_as_html)
select_options[:disabled] = "disabled" if @options[:disabled]
select_options[:class] = css_class_attribute(type, select_options[:class], @options[:with_css_classes]) if @options[:with_css_classes]
select_html = "\n"
select_html = "\n".dup
select_html << content_tag("option".freeze, "", value: "") + "\n" if @options[:include_blank]
select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt]
select_html << select_options_as_html
......@@ -1089,7 +1089,7 @@ def input_id_from_type(type)
# Given an ordering of datetime components, create the selection HTML
# and join them with their appropriate separators.
def build_selects_from_types(order)
select = ""
select = "".dup
first_visible = order.find { |type| !@options[:"discard_#{type}"] }
order.reverse_each do |type|
separator = separator(type) unless type == first_visible # don't add before first visible field
......
......@@ -13,8 +13,8 @@ module JavaScriptHelper
"'" => "\\'"
}
JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = "&#x2028;"
JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = "&#x2029;"
JS_ESCAPE_MAP["\342\200\250".dup.force_encoding(Encoding::UTF_8).encode!] = "&#x2028;"
JS_ESCAPE_MAP["\342\200\251".dup.force_encoding(Encoding::UTF_8).encode!] = "&#x2029;"
# Escapes carriage returns and single and double quotes for JavaScript segments.
#
......
......@@ -95,7 +95,7 @@ def translate(key, options = {})
raise e if raise_error
keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
title = "translation missing: #{keys.join('.')}"
title = "translation missing: #{keys.join('.')}".dup
interpolations = options.except(:default, :scope)
if interpolations.any?
......
......@@ -14,7 +14,7 @@ def initialize
def render_template(event)
info do
message = " Rendered #{from_rails_root(event.payload[:identifier])}"
message = " Rendered #{from_rails_root(event.payload[:identifier])}".dup
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
message << " (#{event.duration.round(1)}ms)"
end
......@@ -22,7 +22,7 @@ def render_template(event)
def render_partial(event)
info do
message = " Rendered #{from_rails_root(event.payload[:identifier])}"
message = " Rendered #{from_rails_root(event.payload[:identifier])}".dup
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
message << " (#{event.duration.round(1)}ms)"
message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil?
......
......@@ -282,7 +282,7 @@ def compile(mod)
# Make sure that the resulting String to be eval'd is in the
# encoding of the code
source = <<-end_src
source = <<-end_src.dup
def #{method_name}(local_assigns, output_buffer)
_old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}
ensure
......@@ -329,12 +329,12 @@ def locals_code
locals = locals.grep(/\A@?(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/)
# Double assign to suppress the dreaded 'assigned but unused variable' warning
locals.each_with_object("") { |key, code| code << "#{key} = #{key} = local_assigns[:#{key}];" }
locals.each_with_object("".dup) { |key, code| code << "#{key} = #{key} = local_assigns[:#{key}];" }
end
def method_name
@method_name ||= begin
m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}".dup
m.tr!("-".freeze, "_".freeze)
m
end
......
......@@ -14,7 +14,7 @@ class Path
alias_method :partial?, :partial
def self.build(name, prefix, partial)
virtual = ""
virtual = "".dup
virtual << "#{prefix}/" unless prefix.empty?
virtual << (partial ? "_#{name}" : name)
new name, prefix, partial, virtual
......
......@@ -104,7 +104,7 @@ def setup_with_controller
# empty string ensures buffer has UTF-8 encoding as
# new without arguments returns ASCII-8BIT encoded buffer like String#new
@output_buffer = ActiveSupport::SafeBuffer.new ""
@rendered = ""
@rendered = "".dup
make_test_case_available_to_view!
say_no_to_protect_against_forgery!
......
......@@ -20,7 +20,7 @@ def to_s
private
def query(path, exts, _, _)
query = ""
query = "".dup
EXTENSIONS.each_key do |ext|
query << "(" << exts[ext].map { |e| e && Regexp.escape(".#{e}") }.join("|") << "|)"
end
......
......@@ -55,7 +55,7 @@ def test_nested_fields_for_with_child_index_option_override_on_a_nested_attribut
private
def hidden_fields(method = nil)
txt = %{<input name="utf8" type="hidden" value="&#x2713;" />}
txt = %{<input name="utf8" type="hidden" value="&#x2713;" />}.dup
if method && !%w(get post).include?(method.to_s)
txt << %{<input name="_method" type="hidden" value="#{method}" />}
......@@ -65,7 +65,7 @@ def hidden_fields(method = nil)
end
def form_text(action = "/", id = nil, html_class = nil, remote = nil, multipart = nil, method = nil)
txt = %{<form accept-charset="UTF-8" action="#{action}"}
txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup
txt << %{ enctype="multipart/form-data"} if multipart
txt << %{ data-remote="true"} if remote
txt << %{ class="#{html_class}"} if html_class
......
body = ""
body = "".dup
body << ["Hello", "from", "Ruby", "code"].join(" ")
......@@ -194,7 +194,7 @@ class ScrollsController < ActionController::Base
FEEDS["provide_builder"] = <<-'EOT'
# we pass in the new_xml to the helper so it doesn't
# call anything on the original builder
new_xml = Builder::XmlMarkup.new(:target=>'')
new_xml = Builder::XmlMarkup.new(:target=>''.dup)
atom_feed(:xml => new_xml) do |feed|
feed.title("My great blog!")
feed.updated(@scrolls.first.created_at)
......
......@@ -16,7 +16,7 @@ def hidden_fields(options = {})
method = options[:method]
skip_enforcing_utf8 = options.fetch(:skip_enforcing_utf8, false)
"".tap do |txt|
"".dup.tap do |txt|
unless skip_enforcing_utf8
txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
end
......@@ -32,7 +32,7 @@ def form_text(action = "http://www.example.com", local: false, **options)
method = method.to_s == "get" ? "get" : "post"
txt = %{<form accept-charset="UTF-8" action="#{action}"}
txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup
txt << %{ enctype="multipart/form-data"} if enctype
txt << %{ data-remote="true"} unless local
txt << %{ class="#{html_class}"} if html_class
......@@ -2194,9 +2194,9 @@ def hidden_fields(options = {})
method = options[:method]
if options.fetch(:skip_enforcing_utf8, false)
txt = ""
txt = "".dup
else
txt = %{<input name="utf8" type="hidden" value="&#x2713;" />}
txt = %{<input name="utf8" type="hidden" value="&#x2713;" />}.dup
end
if method && !%w(get post).include?(method.to_s)
......@@ -2207,7 +2207,7 @@ def hidden_fields(options = {})
end
def form_text(action = "/", id = nil, html_class = nil, local = nil, multipart = nil, method = nil)
txt = %{<form accept-charset="UTF-8" action="#{action}"}
txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup
txt << %{ enctype="multipart/form-data"} if multipart
txt << %{ data-remote="true"} unless local
txt << %{ class="#{html_class}"} if html_class
......
......@@ -3446,9 +3446,9 @@ def hidden_fields(options = {})
method = options[:method]
if options.fetch(:enforce_utf8, true)
txt = %{<input name="utf8" type="hidden" value="&#x2713;" />}
txt = %{<input name="utf8" type="hidden" value="&#x2713;" />}.dup
else
txt = ""
txt = "".dup
end
if method && !%w(get post).include?(method.to_s)
......@@ -3459,7 +3459,7 @@ def hidden_fields(options = {})
end
def form_text(action = "/", id = nil, html_class = nil, remote = nil, multipart = nil, method = nil)
txt = %{<form accept-charset="UTF-8" action="#{action}"}
txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup
txt << %{ enctype="multipart/form-data"} if multipart
txt << %{ data-remote="true"} if remote
txt << %{ class="#{html_class}"} if html_class
......
......@@ -14,7 +14,7 @@ def hidden_fields(options = {})
method = options[:method]
enforce_utf8 = options.fetch(:enforce_utf8, true)
"".tap do |txt|
"".dup.tap do |txt|
if enforce_utf8
txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
end
......@@ -30,7 +30,7 @@ def form_text(action = "http://www.example.com", options = {})
method = method.to_s == "get" ? "get" : "post"
txt = %{<form accept-charset="UTF-8" action="#{action}"}
txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup
txt << %{ enctype="multipart/form-data"} if enctype
txt << %{ data-remote="true"} if remote
txt << %{ class="#{html_class}"} if html_class
......
......@@ -20,8 +20,8 @@ def test_escape_javascript
assert_equal %(This \\"thing\\" is really\\n netos\\'), escape_javascript(%(This "thing" is really\n netos'))
assert_equal %(backslash\\\\test), escape_javascript(%(backslash\\test))
assert_equal %(dont <\\/close> tags), escape_javascript(%(dont </close> tags))
assert_equal %(unicode &#x2028; newline), escape_javascript(%(unicode \342\200\250 newline).force_encoding(Encoding::UTF_8).encode!)
assert_equal %(unicode &#x2029; newline), escape_javascript(%(unicode \342\200\251 newline).force_encoding(Encoding::UTF_8).encode!)
assert_equal %(unicode &#x2028; newline), escape_javascript(%(unicode \342\200\250 newline).dup.force_encoding(Encoding::UTF_8).encode!)
assert_equal %(unicode &#x2029; newline), escape_javascript(%(unicode \342\200\251 newline).dup.force_encoding(Encoding::UTF_8).encode!)
assert_equal %(dont <\\/close> tags), j(%(dont </close> tags))
end
......
......@@ -439,7 +439,7 @@ def test_render_fallbacks_to_erb_for_unknown_types
end
CustomHandler = lambda do |template|
"@output_buffer = ''\n" \
"@output_buffer = ''.dup\n" \
"@output_buffer << 'source: #{template.source.inspect}'\n"
end
......@@ -583,7 +583,7 @@ def test_render_layout_with_object
def test_render_with_passing_couple_extensions_to_one_register_template_handler_function_call
ActionView::Template.register_template_handler :foo1, :foo2, CustomHandler
assert_equal @view.render(inline: "Hello, World!", type: :foo1), @view.render(inline: "Hello, World!", type: :foo2)
assert_equal @view.render(inline: "Hello, World!".dup, type: :foo1), @view.render(inline: "Hello, World!".dup, type: :foo2)
ensure
ActionView::Template.unregister_template_handler :foo1, :foo2
end
......
......@@ -17,7 +17,7 @@ def render_body(options)
def buffered_render(options)
body = render_body(options)
string = ""
string = "".dup
body.each do |piece|
string << piece
end
......
......@@ -53,7 +53,7 @@ def my_buffer
end
def new_template(body = "<%= hello %>", details = { format: :html })
ActionView::Template.new(body, "hello template", details.fetch(:handler) { ERBHandler }, { virtual_path: "hello" }.merge!(details))
ActionView::Template.new(body.dup, "hello template", details.fetch(:handler) { ERBHandler }, { virtual_path: "hello" }.merge!(details))
end
def render(locals = {})
......
......@@ -11,7 +11,7 @@ def setup
end
def test_concat
self.output_buffer = "foo"
self.output_buffer = "foo".dup
assert_equal "foobar", concat("bar")
assert_equal "foobar", output_buffer
end
......@@ -104,8 +104,8 @@ def test_truncate_with_options_hash
end
def test_truncate_multibyte
assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding(Encoding::UTF_8),
truncate("\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding(Encoding::UTF_8), length: 10)
assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".dup.force_encoding(Encoding::UTF_8),
truncate("\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".dup.force_encoding(Encoding::UTF_8), length: 10)
end
def test_truncate_does_not_modify_the_options_hash
......@@ -325,7 +325,7 @@ def test_excerpt_with_omission
end
def test_excerpt_with_utf8
assert_equal("...\357\254\203ciency could not be...".force_encoding(Encoding::UTF_8), excerpt("That's why e\357\254\203ciency could not be helped".force_encoding(Encoding::UTF_8), "could", radius: 8))
assert_equal("...\357\254\203ciency could not be...".dup.force_encoding(Encoding::UTF_8), excerpt("That's why e\357\254\203ciency could not be helped".dup.force_encoding(Encoding::UTF_8), "could", radius: 8))
end
def test_excerpt_does_not_modify_the_options_hash
......
......@@ -539,7 +539,7 @@ def test_current_page_with_escaped_params
def test_current_page_with_escaped_params_with_different_encoding
@request = request_for_url("/")
@request.stub(:path, "/category/administra%c3%a7%c3%a3o".force_encoding(Encoding::ASCII_8BIT)) do
@request.stub(:path, "/category/administra%c3%a7%c3%a3o".dup.force_encoding(Encoding::ASCII_8BIT)) do
assert current_page?(controller: "foo", action: "category", category: "administração")
assert current_page?("http://www.example.com/category/administra%c3%a7%c3%a3o")
end
......
......@@ -96,7 +96,7 @@ def reload
end
test "attribute mutation" do
@model.instance_variable_set("@name", "Yam")
@model.instance_variable_set("@name", "Yam".dup)
assert !@model.name_changed?
@model.name.replace("Hadad")
assert !@model.name_changed?
......
......@@ -14,7 +14,7 @@ class StringTest < ActiveModel::TestCase
test "cast strings are mutable" do
type = Type::String.new
s = "foo"
s = "foo".dup
assert_equal false, type.cast(s).frozen?
assert_equal false, s.frozen?
......
......@@ -198,8 +198,7 @@ def construct_tables!(parent, node)
def table_alias_for(reflection, parent, join)
name = "#{reflection.plural_name}_#{parent.table_name}"
name << "_join" if join
name
join ? "#{name}_join" : name
end
def walk(left, right)
......
......@@ -679,7 +679,7 @@ def checkout_for_exclusive_access(checkout_timeout)
# this block can't be easily moved into attempt_to_checkout_all_existing_connections's
# rescue block, because doing so would put it outside of synchronize section, without
# being in a critical section thread_report might become inaccurate
msg = "could not obtain ownership of all database connections in #{checkout_timeout} seconds"
msg = "could not obtain ownership of all database connections in #{checkout_timeout} seconds".dup
thread_report = []
@connections.each do |conn|
......
......@@ -22,7 +22,7 @@ def accept(o)
private
def visit_AlterTable(o)
sql = "ALTER TABLE #{quote_table_name(o.name)} "
sql = "ALTER TABLE #{quote_table_name(o.name)} ".dup
sql << o.adds.map { |col| accept col }.join(" ")
sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(" ")
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
......@@ -30,17 +30,17 @@ def visit_AlterTable(o)
def visit_ColumnDefinition(o)
o.sql_type = type_to_sql(o.type, o.options)
column_sql = "#{quote_column_name(o.name)} #{o.sql_type}"
column_sql = "#{quote_column_name(o.name)} #{o.sql_type}".dup
add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
column_sql
end
def visit_AddColumnDefinition(o)
"ADD #{accept(o.column)}"
"ADD #{accept(o.column)}".dup
end
def visit_TableDefinition(o)
create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(o.name)} "
create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(o.name)} ".dup
statements = o.columns.map { |c| accept c }
statements << accept(o.primary_keys) if o.primary_keys
......
......@@ -1348,7 +1348,7 @@ def insert_versions_sql(versions)
sm_table = quote_table_name(ActiveRecord::SchemaMigration.table_name)
if versions.is_a?(Array)
sql = "INSERT INTO #{sm_table} (version) VALUES\n"
sql = "INSERT INTO #{sm_table} (version) VALUES\n".dup
sql << versions.map { |v| "(#{quote(v)})" }.join(",\n")
sql << ";\n\n"
sql
......
......@@ -147,7 +147,7 @@ def valid_type?(type) # :nodoc:
# this method must only be called while holding connection pool's mutex
def lease
if in_use?
msg = "Cannot lease connection, "
msg = "Cannot lease connection, ".dup
if @owner == Thread.current
msg << "it is already leased by the current thread."
else
......
......@@ -132,7 +132,7 @@ def native_database_types
end
def index_algorithms
{ default: "ALGORITHM = DEFAULT", copy: "ALGORITHM = COPY", inplace: "ALGORITHM = INPLACE" }
{ default: "ALGORITHM = DEFAULT".dup, copy: "ALGORITHM = COPY".dup, inplace: "ALGORITHM = INPLACE".dup }
end
# HELPER METHODS ===========================================
......@@ -379,7 +379,7 @@ def rename_column(table_name, column_name, new_column_name) #:nodoc:
def add_index(table_name, column_name, options = {}) #:nodoc:
index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, options)
sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}"
sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}".dup
execute add_sql_comment!(sql, comment)
end
......@@ -464,7 +464,7 @@ def type_to_sql(type, limit: nil, precision: nil, scale: nil, unsigned: nil, **)
super
end
sql << " unsigned" if unsigned && type != :primary_key
sql = "#{sql} unsigned" if unsigned && type != :primary_key
sql
end
......@@ -778,7 +778,7 @@ def configure_connection
# http://dev.mysql.com/doc/refman/5.7/en/set-statement.html#id944430
# (trailing comma because variable_assignments will always have content)
if @config[:encoding]
encoding = "NAMES #{@config[:encoding]}"
encoding = "NAMES #{@config[:encoding]}".dup
encoding << " COLLATE #{@config[:collation]}" if @config[:collation]
encoding << ", "
end
......
......@@ -16,7 +16,7 @@ def visit_AddColumnDefinition(o)
end
def visit_ChangeColumnDefinition(o)
change_column_sql = "CHANGE #{quote_column_name(o.name)} #{accept(o.column)}"
change_column_sql = "CHANGE #{quote_column_name(o.name)} #{accept(o.column)}".dup
add_column_position!(change_column_sql, column_options(o.column))
end
......@@ -63,7 +63,7 @@ def add_column_position!(sql, options)
def index_in_create(table_name, column_name, options)
index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, options)
add_sql_comment!("#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})", comment)
add_sql_comment!("#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})".dup, comment)
end
end
end
......
......@@ -102,7 +102,7 @@ def extract_foreign_key_action(specifier)
def data_source_sql(name = nil, type: nil)
scope = quoted_scope(name, type: type)
sql = "SELECT table_name FROM information_schema.tables"
sql = "SELECT table_name FROM information_schema.tables".dup
sql << " WHERE table_schema = #{scope[:schema]}"
sql << " AND table_name = #{scope[:name]}" if scope[:name]
sql << " AND table_type = #{scope[:type]}" if scope[:type]
......
......@@ -406,7 +406,7 @@ def change_column(table_name, column_name, type, options = {}) #:nodoc:
quoted_table_name = quote_table_name(table_name)
quoted_column_name = quote_column_name(column_name)
sql_type = type_to_sql(type, options)
sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}"
sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quoted_column_name} TYPE #{sql_type}".dup
if options[:collation]
sql << " COLLATE \"#{options[:collation]}\""
end
......@@ -566,7 +566,7 @@ def type_to_sql(type, limit: nil, precision: nil, scale: nil, array: nil, **) #
super
end
sql << "[]" if array && type != :primary_key
sql = "#{sql}[]" if array && type != :primary_key
sql
end
......@@ -635,7 +635,7 @@ def data_source_sql(name = nil, type: nil)
scope = quoted_scope(name, type: type)
scope[:type] ||= "'r','v','m'" # (r)elation/table, (v)iew, (m)aterialized view
sql = "SELECT c.relname FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace"
sql = "SELECT c.relname FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace".dup
sql << " WHERE n.nspname = #{scope[:schema]}"
sql << " AND c.relname = #{scope[:name]}" if scope[:name]
sql << " AND c.relkind IN (#{scope[:type]})"
......
......@@ -67,7 +67,7 @@ def data_source_sql(name = nil, type: nil)
scope = quoted_scope(name, type: type)
scope[:type] ||= "'table','view'"
sql = "SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'"
sql = "SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'".dup
sql << " AND name = #{scope[:name]}" if scope[:name]
sql << " AND type IN (#{scope[:type]})"
sql
......
......@@ -16,7 +16,7 @@ def collecting_queries_for_explain # :nodoc:
# Returns a formatted string ready to be logged.
def exec_explain(queries) # :nodoc:
str = queries.map do |sql, binds|
msg = "EXPLAIN for: #{sql}"
msg = "EXPLAIN for: #{sql}".dup
unless binds.empty?
msg << " "
msg << binds.map { |attr| render_bind(attr) }.inspect
......
......@@ -157,7 +157,7 @@ def initialize
class ProtectedEnvironmentError < ActiveRecordError #:nodoc:
def initialize(env = "production")
msg = "You are attempting to run a destructive action against your '#{env}' database.\n"
msg = "You are attempting to run a destructive action against your '#{env}' database.\n".dup
msg << "If you are sure you want to continue, run the same command with the environment variable:\n"
msg << "DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
super(msg)
......@@ -166,7 +166,7 @@ def initialize(env = "production")
class EnvironmentMismatchError < ActiveRecordError
def initialize(current: nil, stored: nil)
msg = "You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
msg = "You are attempting to modify a database that was last run in `#{ stored }` environment.\n".dup
msg << "You are running in `#{ current }` environment. "
msg << "If you are sure you want to continue, first set the environment using:\n\n"
msg << " bin/rails db:environment:set"
......@@ -1239,7 +1239,7 @@ def execute_migration_in_transaction(migration, direction)
record_version_state_after_migrating(migration.version)
end
rescue => e
msg = "An error has occurred, "
msg = "An error has occurred, ".dup
msg << "this and " if use_transaction?(migration)
msg << "all later migrations canceled:\n\n#{e}"
raise StandardError, msg, e.backtrace
......
......@@ -334,14 +334,14 @@ def raise_record_not_found_exception!(ids = nil, result_size = nil, expected_siz
name = @klass.name
if ids.nil?
error = "Couldn't find #{name}"
error = "Couldn't find #{name}".dup
error << " with#{conditions}" if conditions
raise RecordNotFound.new(error, name)
elsif Array(ids).size == 1
error = "Couldn't find #{name} with '#{key}'=#{ids}#{conditions}"
raise RecordNotFound.new(error, name, key, ids)
else
error = "Couldn't find all #{name.pluralize} with '#{key}': "
error = "Couldn't find all #{name.pluralize} with '#{key}': ".dup
error << "(#{ids.join(", ")})#{conditions} (found #{result_size} results, but was looking for #{expected_size})"
raise RecordNotFound.new(error, name, primary_key, ids)
......
......@@ -151,7 +151,7 @@ def run_cmd(cmd, args, action)
end
def run_cmd_error(cmd, args, action)
msg = "failed to execute: `#{cmd}`\n"
msg = "failed to execute: `#{cmd}`\n".dup
msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
msg
end
......
......@@ -47,7 +47,7 @@ def test_type_cast_binary_converts_the_encoding
end
def test_type_cast_binary_value
data = "\u001F\x8B".force_encoding("BINARY")
data = "\u001F\x8B".dup.force_encoding("BINARY")
assert_equal(data, @type.deserialize(data))
end
......
......@@ -47,10 +47,10 @@ def test_money_values
def test_money_type_cast
type = PostgresqlMoney.type_for_attribute("wealth")
assert_equal(12345678.12, type.cast("$12,345,678.12"))
assert_equal(12345678.12, type.cast("$12.345.678,12"))
assert_equal(-1.15, type.cast("-$1.15"))
assert_equal(-2.25, type.cast("($2.25)"))
assert_equal(12345678.12, type.cast("$12,345,678.12".dup))
assert_equal(12345678.12, type.cast("$12.345.678,12".dup))
assert_equal(-1.15, type.cast("-$1.15".dup))
assert_equal(-2.25, type.cast("($2.25)".dup))
end
def test_schema_dumping
......@@ -60,7 +60,7 @@ def test_schema_dumping
end
def test_create_and_update_money
money = PostgresqlMoney.create(wealth: "987.65")
money = PostgresqlMoney.create(wealth: "987.65".dup)
assert_equal 987.65, money.wealth
new_value = BigDecimal.new("123.45")
......
......@@ -165,7 +165,7 @@ def test_quote_binary_column_escapes_it
data binary
)
eosql
str = "\x80".force_encoding("ASCII-8BIT")
str = "\x80".dup.force_encoding("ASCII-8BIT")
binary = DualEncoding.new name: "いただきます!", data: str
binary.save!
assert_equal str, binary.data
......@@ -174,7 +174,7 @@ def test_quote_binary_column_escapes_it
end
def test_type_cast_should_not_mutate_encoding
name = "hello".force_encoding(Encoding::ASCII_8BIT)
name = "hello".dup.force_encoding(Encoding::ASCII_8BIT)
Owner.create(name: name)
assert_equal Encoding::ASCII_8BIT, name.encoding
ensure
......
......@@ -76,7 +76,7 @@ class AttributeTest < ActiveRecord::TestCase
end
test "duping dups the value" do
@type.expect(:deserialize, "type cast", ["a value"])
@type.expect(:deserialize, "type cast".dup, ["a value"])
attribute = Attribute.from_database(nil, "a value", @type)
value_from_orig = attribute.value
......@@ -244,7 +244,7 @@ def assert_valid_value(*)
end
test "with_type preserves mutations" do
attribute = Attribute.from_database(:foo, "", Type::Value.new)
attribute = Attribute.from_database(:foo, "".dup, Type::Value.new)
attribute.value << "1"
assert_equal 1, attribute.with_type(Type::Integer.new).value
......
......@@ -152,7 +152,7 @@ def test_find_in_batches_should_quote_batch_order
end
def test_find_in_batches_should_not_use_records_after_yielding_them_in_case_original_array_is_modified
not_a_post = "not a post"
not_a_post = "not a post".dup
def not_a_post.id; end
not_a_post.stub(:id, -> { raise StandardError.new("not_a_post had #id called on it") }) do
assert_nothing_raised do
......@@ -417,7 +417,7 @@ def test_in_batches_should_quote_batch_order
end
def test_in_batches_should_not_use_records_after_yielding_them_in_case_original_array_is_modified
not_a_post = "not a post"
not_a_post = "not a post".dup
def not_a_post.id
raise StandardError.new("not_a_post had #id called on it")
end
......
......@@ -10,7 +10,7 @@ class BinaryTest < ActiveRecord::TestCase
FIXTURES = %w(flowers.jpg example.log test.txt)
def test_mixed_encoding
str = "\x80"
str = "\x80".dup
str.force_encoding("ASCII-8BIT")
binary = Binary.new name: "いただきます!", data: str
......
......@@ -35,7 +35,7 @@ def test_inspect_class_without_table
def test_pretty_print_new
topic = Topic.new
actual = ""
actual = "".dup
PP.pp(topic, StringIO.new(actual))
expected = <<-PRETTY.strip_heredoc
#<Topic:0xXXXXXX
......@@ -64,7 +64,7 @@ def test_pretty_print_new
def test_pretty_print_persisted
topic = topics(:first)
actual = ""
actual = "".dup
PP.pp(topic, StringIO.new(actual))
expected = <<-PRETTY.strip_heredoc
#<Topic:0x\\w+
......@@ -92,7 +92,7 @@ def test_pretty_print_persisted
def test_pretty_print_uninitialized
topic = Topic.allocate
actual = ""
actual = "".dup
PP.pp(topic, StringIO.new(actual))
expected = "#<Topic:XXXXXX not initialized>\n"
assert actual.start_with?(expected.split("XXXXXX").first)
......@@ -105,7 +105,7 @@ def inspect
"inspecting topic"
end
end
actual = ""
actual = "".dup
PP.pp(subtopic.new, StringIO.new(actual))
assert_equal "inspecting topic\n", actual
end
......
......@@ -75,7 +75,7 @@ def lookup_store(*store_option)
#
# The +key+ argument can also respond to +cache_key+ or +to_param+.
def expand_cache_key(key, namespace = nil)
expanded_cache_key = namespace ? "#{namespace}/" : ""
expanded_cache_key = (namespace ? "#{namespace}/" : "").dup
if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
expanded_cache_key << "#{prefix}/"
......
......@@ -15,12 +15,12 @@ def serialize
parts, sign = normalize
return "PT0S".freeze if parts.empty?
output = "P"
output = "P".dup
output << "#{parts[:years]}Y" if parts.key?(:years)
output << "#{parts[:months]}M" if parts.key?(:months)
output << "#{parts[:weeks]}W" if parts.key?(:weeks)
output << "#{parts[:days]}D" if parts.key?(:days)
time = ""
time = "".dup
time << "#{parts[:hours]}H" if parts.key?(:hours)
time << "#{parts[:minutes]}M" if parts.key?(:minutes)
if parts.key?(:seconds)
......
......@@ -114,7 +114,7 @@ def _encrypt(value)
encrypted_data << cipher.final
blob = "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}"
blob << "--#{::Base64.strict_encode64 cipher.auth_tag}" if aead_mode?
blob = "#{blob}--#{::Base64.strict_encode64 cipher.auth_tag}" if aead_mode?
blob
end
......
......@@ -2,7 +2,7 @@ module ActiveSupport
module NumberHelper
class NumberToPhoneConverter < NumberConverter #:nodoc:
def convert
str = country_code(opts[:country_code])
str = country_code(opts[:country_code]).dup
str << convert_to_phone_number(number.to_s.strip)
str << phone_ext(opts[:extension])
end
......
......@@ -53,7 +53,7 @@ def to_hash(hash = {})
if c.element?
c.to_hash(node_hash)
elsif c.text? || c.cdata?
node_hash[CONTENT_ROOT] ||= ""
node_hash[CONTENT_ROOT] ||= "".dup
node_hash[CONTENT_ROOT] << c.content
end
end
......
......@@ -21,7 +21,7 @@ def current_hash
end
def on_start_document
@hash = { CONTENT_KEY => "" }
@hash = { CONTENT_KEY => "".dup }
@hash_stack = [@hash]
end
......@@ -31,7 +31,7 @@ def on_end_document
end
def on_start_element(name, attrs = {})
new_hash = { CONTENT_KEY => "" }.merge!(attrs)
new_hash = { CONTENT_KEY => "".dup }.merge!(attrs)
new_hash[HASH_SIZE_KEY] = new_hash.size + 1
case current_hash[name]
......
......@@ -57,7 +57,7 @@ def to_hash(hash = {})
if c.element?
c.to_hash(node_hash)
elsif c.text? || c.cdata?
node_hash[CONTENT_ROOT] ||= ""
node_hash[CONTENT_ROOT] ||= "".dup
node_hash[CONTENT_ROOT] << c.content
end
end
......
......@@ -37,7 +37,7 @@ def error(error_message)
end
def start_element(name, attrs = [])
new_hash = { CONTENT_KEY => "" }.merge!(Hash[attrs])
new_hash = { CONTENT_KEY => "".dup }.merge!(Hash[attrs])
new_hash[HASH_SIZE_KEY] = new_hash.size + 1
case current_hash[name]
......
......@@ -74,7 +74,7 @@ def merge_texts!(hash, element)
hash
else
# must use value to prevent double-escaping
texts = ""
texts = "".dup
element.texts.each { |t| texts << t.value }
merge!(hash, CONTENT_KEY, texts)
end
......
......@@ -196,7 +196,7 @@ def test_delete
end
def test_original_store_objects_should_not_be_immutable
bar = "bar"
bar = "bar".dup
@cache.write("foo", bar)
assert_nothing_raised { bar.gsub!(/.*/, "baz") }
end
......@@ -285,7 +285,7 @@ def test_crazy_key_characters
end
def test_really_long_keys
key = ""
key = "".dup
900.times { key << "x" }
assert @cache.write(key, "bar")
assert_equal "bar", @cache.read(key)
......
......@@ -4,7 +4,7 @@
module EncodedKeyCacheBehavior
Encoding.list.each do |encoding|
define_method "test_#{encoding.name.underscore}_encoded_values" do
key = "foo".force_encoding(encoding)
key = "foo".dup.force_encoding(encoding)
assert @cache.write(key, "1", raw: true)
assert_equal "1", @cache.read(key)
assert_equal "1", @cache.fetch(key)
......@@ -16,7 +16,7 @@ module EncodedKeyCacheBehavior
end
def test_common_utf8_values
key = "\xC3\xBCmlaut".force_encoding(Encoding::UTF_8)
key = "\xC3\xBCmlaut".dup.force_encoding(Encoding::UTF_8)
assert @cache.write(key, "1", raw: true)
assert_equal "1", @cache.read(key)
assert_equal "1", @cache.fetch(key)
......@@ -27,7 +27,7 @@ def test_common_utf8_values
end
def test_retains_encoding
key = "\xC3\xBCmlaut".force_encoding(Encoding::UTF_8)
key = "\xC3\xBCmlaut".dup.force_encoding(Encoding::UTF_8)
assert @cache.write(key, "1", raw: true)
assert_equal Encoding::UTF_8, key.encoding
end
......
......@@ -45,7 +45,7 @@ def test_expand_cache_key_rails_cache_id_should_win_over_rails_app_version
end
def test_expand_cache_key_respond_to_cache_key
key = "foo"
key = "foo".dup
def key.cache_key
:foo_key
end
......@@ -53,7 +53,7 @@ def key.cache_key
end
def test_expand_cache_key_array_with_something_that_responds_to_cache_key
key = "foo"
key = "foo".dup
def key.cache_key
:foo_key
end
......
......@@ -233,7 +233,7 @@ def test_starts_ends_with_alias
def test_string_squish
original = %{\u205f\u3000 A string surrounded by various unicode spaces,
with tabs(\t\t), newlines(\n\n), unicode nextlines(\u0085\u0085) and many spaces( ). \u00a0\u2007}
with tabs(\t\t), newlines(\n\n), unicode nextlines(\u0085\u0085) and many spaces( ). \u00a0\u2007}.dup
expected = "A string surrounded by various unicode spaces, " \
"with tabs( ), newlines( ), unicode nextlines( ) and many spaces( )."
......@@ -303,8 +303,8 @@ def test_truncate_words_with_complex_string
end
def test_truncate_multibyte
assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding(Encoding::UTF_8),
"\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding(Encoding::UTF_8).truncate(10)
assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".dup.force_encoding(Encoding::UTF_8),
"\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".dup.force_encoding(Encoding::UTF_8).truncate(10)
end
def test_truncate_should_not_be_html_safe
......@@ -325,7 +325,7 @@ def test_remove_for_multiple_occurrences
end
def test_remove!
original = "This is a very good day to die"
original = "This is a very good day to die".dup
assert_equal "This is a good day to die", original.remove!(" very")
assert_equal "This is a good day to die", original
assert_equal "This is a good day", original.remove!(" to ", /die/)
......@@ -658,7 +658,7 @@ def test_mb_chars_returns_instance_of_proxy_class
class OutputSafetyTest < ActiveSupport::TestCase
def setup
@string = "hello"
@string = "hello".dup
@object = Class.new(Object) do
def to_s
"other"
......@@ -734,7 +734,7 @@ def to_s
end
test "Concatting safe onto unsafe yields unsafe" do
@other_string = "other"
@other_string = "other".dup
string = @string.html_safe
@other_string.concat(string)
......@@ -757,7 +757,7 @@ def to_s
end
test "Concatting safe onto unsafe with << yields unsafe" do
@other_string = "other"
@other_string = "other".dup
string = @string.html_safe
@other_string << string
......@@ -813,7 +813,7 @@ def to_s
test "Concatting an integer to safe always yields safe" do
string = @string.html_safe
string = string.concat(13)
assert_equal "hello".concat(13), string
assert_equal "hello".dup.concat(13), string
assert string.html_safe?
end
......@@ -868,7 +868,8 @@ class StringExcludeTest < ActiveSupport::TestCase
class StringIndentTest < ActiveSupport::TestCase
test "does not indent strings that only contain newlines (edge cases)" do
["", "\n", "\n" * 7].each do |str|
["", "\n", "\n" * 7].each do |string|
str = string.dup
assert_nil str.indent!(8)
assert_equal str, str.indent(8)
assert_equal str, str.indent(1, "\t")
......
......@@ -37,7 +37,7 @@ def test_write_binary_data_to_existing_file
logger = Logger.new f
logger.level = Logger::DEBUG
str = "\x80"
str = "\x80".dup
str.force_encoding("ASCII-8BIT")
logger.add Logger::DEBUG, str
......@@ -55,7 +55,7 @@ def test_write_binary_data_create_file
logger = Logger.new f
logger.level = Logger::DEBUG
str = "\x80"
str = "\x80".dup
str.force_encoding("ASCII-8BIT")
logger.add Logger::DEBUG, str
......
......@@ -51,7 +51,7 @@ def test_methods_are_forwarded_to_wrapped_string_for_byte_strings
end
def test_forwarded_method_with_non_string_result_should_be_returned_verbatim
str = ""
str = "".dup
str.singleton_class.class_eval { def __method_for_multibyte_testing_with_integer_result; 1; end }
@chars.wrapped_string.singleton_class.class_eval { def __method_for_multibyte_testing_with_integer_result; 1; end }
......@@ -59,14 +59,14 @@ def test_forwarded_method_with_non_string_result_should_be_returned_verbatim
end
def test_should_concatenate
mb_a = "a".mb_chars
mb_b = "b".mb_chars
mb_a = "a".dup.mb_chars
mb_b = "b".dup.mb_chars
assert_equal "ab", mb_a + "b"
assert_equal "ab", "a" + mb_b
assert_equal "ab", mb_a + mb_b
assert_equal "ab", mb_a << "b"
assert_equal "ab", "a" << mb_b
assert_equal "ab", "a".dup << mb_b
assert_equal "abb", mb_a << mb_b
end
......@@ -78,7 +78,7 @@ def test_consumes_utf8_strings
def test_concatenation_should_return_a_proxy_class_instance
assert_equal ActiveSupport::Multibyte.proxy_class, ("a".mb_chars + "b").class
assert_equal ActiveSupport::Multibyte.proxy_class, ("a".mb_chars << "b").class
assert_equal ActiveSupport::Multibyte.proxy_class, ("a".dup.mb_chars << "b").class
end
def test_ascii_strings_are_treated_at_utf8_strings
......@@ -88,8 +88,8 @@ def test_ascii_strings_are_treated_at_utf8_strings
def test_concatenate_should_return_proxy_instance
assert(("a".mb_chars + "b").kind_of?(@proxy_class))
assert(("a".mb_chars + "b".mb_chars).kind_of?(@proxy_class))
assert(("a".mb_chars << "b").kind_of?(@proxy_class))
assert(("a".mb_chars << "b".mb_chars).kind_of?(@proxy_class))
assert(("a".dup.mb_chars << "b").kind_of?(@proxy_class))
assert(("a".dup.mb_chars << "b".mb_chars).kind_of?(@proxy_class))
end
def test_should_return_string_as_json
......@@ -115,12 +115,12 @@ def test_split_should_return_an_array_of_chars_instances
%w{capitalize downcase lstrip reverse rstrip swapcase upcase}.each do |method|
class_eval(<<-EOTESTS, __FILE__, __LINE__ + 1)
def test_#{method}_bang_should_return_self_when_modifying_wrapped_string
chars = ' él piDió Un bUen café '
chars = ' él piDió Un bUen café '.dup
assert_equal chars.object_id, chars.send("#{method}!").object_id
end
def test_#{method}_bang_should_change_wrapped_string
original = ' él piDió Un bUen café '
original = ' él piDió Un bUen café '.dup
proxy = chars(original.dup)
proxy.send("#{method}!")
assert_not_equal original, proxy.to_s
......@@ -133,7 +133,7 @@ def test_tidy_bytes_bang_should_return_self
end
def test_tidy_bytes_bang_should_change_wrapped_string
original = " Un bUen café \x92"
original = " Un bUen café \x92".dup
proxy = chars(original.dup)
proxy.tidy_bytes!
assert_not_equal original, proxy.to_s
......@@ -150,7 +150,7 @@ def test_identity
end
def test_string_methods_are_chainable
assert chars("").insert(0, "").kind_of?(ActiveSupport::Multibyte.proxy_class)
assert chars("".dup).insert(0, "").kind_of?(ActiveSupport::Multibyte.proxy_class)
assert chars("").rjust(1).kind_of?(ActiveSupport::Multibyte.proxy_class)
assert chars("").ljust(1).kind_of?(ActiveSupport::Multibyte.proxy_class)
assert chars("").center(1).kind_of?(ActiveSupport::Multibyte.proxy_class)
......@@ -195,7 +195,7 @@ def test_should_return_character_offset_for_regexp_matches
end
def test_should_use_character_offsets_for_insert_offsets
assert_equal "", "".mb_chars.insert(0, "")
assert_equal "", "".dup.mb_chars.insert(0, "")
assert_equal "こわにちわ", @chars.insert(1, "わ")
assert_equal "こわわわにちわ", @chars.insert(2, "わわ")
assert_equal "わこわわわにちわ", @chars.insert(0, "わ")
......@@ -418,13 +418,13 @@ def test_slice_bang_returns_nil_on_out_of_bound_arguments
end
def test_slice_bang_removes_the_slice_from_the_receiver
chars = "úüù".mb_chars
chars = "úüù".dup.mb_chars
chars.slice!(0, 2)
assert_equal "ù", chars
end
def test_slice_bang_returns_nil_and_does_not_modify_receiver_if_out_of_bounds
string = "úüù"
string = "úüù".dup
chars = string.mb_chars
assert_nil chars.slice!(4, 5)
assert_equal "úüù", chars
......
......@@ -23,7 +23,7 @@ def self.download(from, to)
UNICODE_STRING = "こにちわ".freeze
ASCII_STRING = "ohayo".freeze
BYTE_STRING = "\270\236\010\210\245".force_encoding("ASCII-8BIT").freeze
BYTE_STRING = "\270\236\010\210\245".dup.force_encoding("ASCII-8BIT").freeze
def chars(str)
ActiveSupport::Multibyte::Chars.new(str)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册