From 401aef2d43dab0f687acf9c8b7fc890792422c18 Mon Sep 17 00:00:00 2001 From: Manfred Stienstra Date: Sun, 1 Nov 2009 17:18:27 +0100 Subject: [PATCH] Add ActiveSupport::Multibyte::Chars#limit. The limit method limits the number of bytes in a string. Useful when the storage space of the string is limited, for instance in a database column definition. --- .../lib/active_support/multibyte/chars.rb | 10 +++++++ activesupport/test/multibyte_chars_test.rb | 29 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index 579ccc1..d418bb5 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -363,6 +363,16 @@ module ActiveSupport #:nodoc: slice end + # Limit 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: + # s = 'こんにちは' + # s.mb_chars.limit(7) #=> "こに" + def limit(limit) + slice(0, translate_offset(limit)) + end + # Returns the codepoint of the first character in the string. # # Example: diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index 680936d..7100c2f 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -163,6 +163,7 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase assert chars('').strip.kind_of?(ActiveSupport::Multibyte.proxy_class) assert chars('').reverse.kind_of?(ActiveSupport::Multibyte.proxy_class) assert chars(' ').slice(0).kind_of?(ActiveSupport::Multibyte.proxy_class) + assert chars('').limit(0).kind_of?(ActiveSupport::Multibyte.proxy_class) assert chars('').upcase.kind_of?(ActiveSupport::Multibyte.proxy_class) assert chars('').downcase.kind_of?(ActiveSupport::Multibyte.proxy_class) assert chars('').capitalize.kind_of?(ActiveSupport::Multibyte.proxy_class) @@ -412,6 +413,34 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase assert_raise(ArgumentError) { @chars.slice(1, 1, 1) } end + def test_limit_should_not_break_on_blank_strings + assert_equal '', @chars.limit(0) + assert_equal '', @chars.limit(1) + end + + def test_limit_should_work_on_a_multibyte_string + assert_equal '', @chars.limit(0) + assert_equal '', @chars.limit(1) + assert_equal '', @chars.limit(2) + assert_equal 'こ', @chars.limit(5) + assert_equal 'こに', @chars.limit(8) + assert_equal 'こにち', @chars.limit(50) + end + + def test_limit_should_work_on_an_ascii_string + ascii = ASCII_STRING.mb_chars + assert_equal '', ascii.limit(0) + assert_equal 'o', ascii.limit(1) + assert_equal 'oh', ascii.limit(2) + assert_equal 'ohay', ascii.limit(50) + end + + def test_limit_should_keep_under_the_specified_byte_limit + (1..UNICODE_STRING.length).each do |limit| + assert @chars.limit(limit).to_s.length <= limit + end + end + def test_ord_should_return_unicode_value_for_first_character assert_equal 12371, @chars.ord end -- 1.6.4.4