Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Use old-style hashes to pass keyword arguments #394

Merged
merged 3 commits into from
Dec 30, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 19 additions & 48 deletions lib/rspec/support/encoded_string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,11 @@ class EncodedString
# Reduce allocations by storing constants.
UTF_8 = "UTF-8"
US_ASCII = "US-ASCII"
#
# In MRI 2.1 'invalid: :replace' changed to also replace an invalid byte sequence
# see https://github.com/ruby/ruby/blob/v2_1_0/NEWS#L176
# https://www.ruby-forum.com/topic/6861247
# https://twitter.com/nalsh/status/553413844685438976
#
# For example, given:
# "\x80".force_encoding("Emacs-Mule").encode(:invalid => :replace).bytes.to_a
#
# On MRI 2.1 or above: 63 # '?'
# else : 128 # "\x80"
#

# Ruby's default replacement string is:
# U+FFFD ("\xEF\xBF\xBD"), for Unicode encoding forms, else
# ? ("\x3F")
REPLACE = "?"
ENCODE_UNCONVERTABLE_BYTES = {
:invalid => :replace,
:undef => :replace,
:replace => REPLACE
}
ENCODE_NO_CONVERTER = {
:invalid => :replace,
:replace => REPLACE
}

def initialize(string, encoding=nil)
@encoding = encoding
Expand Down Expand Up @@ -112,34 +92,25 @@ def matching_encoding(string)
string = remove_invalid_bytes(string)
string.encode(@encoding)
rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
encode_unconvertable_bytes(string)
# Originally defined as a constant to avoid uneeded allocations, this hash must
# be defined inline (without {}) to avoid warnings on Ruby 2.7
#
# In MRI 2.1 'invalid: :replace' changed to also replace an invalid byte sequence
# see https://github.com/ruby/ruby/blob/v2_1_0/NEWS#L176
# https://www.ruby-forum.com/topic/6861247
# https://twitter.com/nalsh/status/553413844685438976
#
# For example, given:
# "\x80".force_encoding("Emacs-Mule").encode(:invalid => :replace).bytes.to_a
#
# On MRI 2.1 or above: 63 # '?'
# else : 128 # "\x80"
#
string.encode(@encoding, :invalid => :replace, :undef => :replace, :replace => REPLACE)
rescue Encoding::ConverterNotFoundError
encode_no_converter(string.dup.force_encoding(@encoding))
end

# On Ruby 2.7.0 keyword arguments mixed with conventional cause a warning to
# be issued requiring us to be explicit by using a ** to pass the hash as
# keyword arguments. Any keyword argument supporting Ruby supports this.
if RubyFeatures.kw_args_supported?
# Note on non keyword supporting Ruby ** causes a syntax error hence
# we must use eval. To be removed in RSpec 4.
binding.eval(<<-CODE, __FILE__, __LINE__)
def encode_unconvertable_bytes(string)
string.encode(@encoding, **ENCODE_UNCONVERTABLE_BYTES)
end

def encode_no_converter(string)
string.encode(**ENCODE_NO_CONVERTER)
end
CODE
else
def encode_unconvertable_bytes(string)
string.encode(@encoding, ENCODE_UNCONVERTABLE_BYTES)
end

def encode_no_converter(string)
string.encode(ENCODE_NO_CONVERTER)
end
# Originally defined as a constant to avoid uneeded allocations, this hash must
# be defined inline (without {}) to avoid warnings on Ruby 2.7
string.dup.force_encoding(@encoding).encode(:invalid => :replace, :replace => REPLACE)
end

# Prevents raising ArgumentError
Expand Down