Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement #swapcase and #swapcase! for multibyte strings #4351

Merged
merged 2 commits into from Jan 6, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 11 additions & 3 deletions activesupport/lib/active_support/multibyte/chars.rb
Expand Up @@ -93,7 +93,7 @@ def reverse
chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack('U*'))
end

# Limit the byte size of the string to a number of bytes without breaking characters. Usable
# Limits the byte size of the string to a number of bytes without breaking characters. Usable
# when the storage for a string is limited for some reason.
#
# Example:
Expand All @@ -102,22 +102,30 @@ def limit(limit)
slice(0...translate_offset(limit))
end

# Convert characters in the string to uppercase.
# Converts characters in the string to uppercase.
#
# Example:
# 'Laurent, où sont les tests ?'.mb_chars.upcase.to_s # => "LAURENT, OÙ SONT LES TESTS ?"
def upcase
chars Unicode.upcase(@wrapped_string)
end

# Convert characters in the string to lowercase.
# Converts characters in the string to lowercase.
#
# Example:
# 'VĚDA A VÝZKUM'.mb_chars.downcase.to_s # => "věda a výzkum"
def downcase
chars Unicode.downcase(@wrapped_string)
end

# Converts characters in the string to the opposite case.
#
# Example:
# 'El Cañón".mb_chars.swapcase.to_s # => "eL cAÑÓN"
def swapcase
chars Unicode.swapcase(@wrapped_string)
end

# Converts the first character to uppercase and the remainder to lowercase.
#
# Example:
Expand Down
8 changes: 8 additions & 0 deletions activesupport/lib/active_support/multibyte/unicode.rb
Expand Up @@ -293,9 +293,17 @@ def upcase(string)
apply_mapping string, :uppercase_mapping
end

def swapcase(string)
apply_mapping string, :swapcase_mapping
end

# Holds data about a codepoint in the Unicode database
class Codepoint
attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping

def swapcase_mapping
uppercase_mapping > 0 ? uppercase_mapping : lowercase_mapping
end
end

# Holds static data from the Unicode database
Expand Down
15 changes: 13 additions & 2 deletions activesupport/test/multibyte_chars_test.rb
Expand Up @@ -106,7 +106,7 @@ def test_split_should_return_an_array_of_chars_instances
end
end

%w{capitalize downcase lstrip reverse rstrip upcase}.each do |method|
%w{capitalize downcase lstrip reverse rstrip swapcase upcase}.each do |method|
class_eval(<<-EOTESTS)
def test_#{method}_bang_should_return_self_when_modifying_wrapped_string
chars = ' él piDió Un bUen café '
Expand Down Expand Up @@ -161,6 +161,7 @@ def test_string_methods_are_chainable
assert chars('').decompose.kind_of?(ActiveSupport::Multibyte.proxy_class)
assert chars('').compose.kind_of?(ActiveSupport::Multibyte.proxy_class)
assert chars('').tidy_bytes.kind_of?(ActiveSupport::Multibyte.proxy_class)
assert chars('').swapcase.kind_of?(ActiveSupport::Multibyte.proxy_class)
end

def test_should_be_equal_to_the_wrapped_string
Expand Down Expand Up @@ -432,6 +433,11 @@ def test_downcase_should_downcase_ascii_characters
assert_equal 'abc', 'aBc'.mb_chars.downcase
end

def test_swapcase_should_swap_ascii_characters
assert_equal '', ''.mb_chars.swapcase
assert_equal 'AbC', 'aBc'.mb_chars.swapcase
end

def test_capitalize_should_work_on_ascii_characters
assert_equal '', ''.mb_chars.capitalize
assert_equal 'Abc', 'abc'.mb_chars.capitalize
Expand Down Expand Up @@ -466,10 +472,15 @@ def test_upcase_should_be_unicode_aware
end

def test_downcase_should_be_unicode_aware
assert_equal "абвгд\0f", chars("аБвгд\0f").downcase
assert_equal "абвгд\0f", chars("аБвгд\0F").downcase
assert_equal 'こにちわ', chars('こにちわ').downcase
end

def test_swapcase_should_be_unicode_aware
assert_equal "аaéÜ\0f", chars("АAÉü\0F").swapcase
assert_equal 'こにちわ', chars('こにちわ').swapcase
end

def test_capitalize_should_be_unicode_aware
{ 'аБвг аБвг' => 'Абвг абвг',
'аБвг АБВГ' => 'Абвг абвг',
Expand Down