aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/test/transliterate_test.rb
blob: 2e02b5e938f5acecdee915adf65a3baa4e804580 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# frozen_string_literal: true

require "abstract_unit"
require "active_support/inflector/transliterate"

class TransliterateTest < ActiveSupport::TestCase
  def test_transliterate_should_not_change_ascii_chars
    (0..127).each do |byte|
      char = [byte].pack("U")
      assert_equal char, ActiveSupport::Inflector.transliterate(char)
    end
  end

  def test_transliterate_should_approximate_ascii
    # create string with range of Unicode's western characters with
    # diacritics, excluding the division and multiplication signs which for
    # some reason or other are floating in the middle of all the letters.
    string = (0xC0..0x17E).to_a.reject { |c| [0xD7, 0xF7].include?(c) }.pack("U*")
    string.each_char do |char|
      assert_match %r{^[a-zA-Z']*$}, ActiveSupport::Inflector.transliterate(char)
    end
  end

  def test_transliterate_should_work_with_custom_i18n_rules_and_uncomposed_utf8
    char = [117, 776].pack("U*") # "ü" as ASCII "u" plus COMBINING DIAERESIS
    I18n.backend.store_translations(:de, i18n: { transliterate: { rule: { "ü" => "ue" } } })
    default_locale, I18n.locale = I18n.locale, :de
    assert_equal "ue", ActiveSupport::Inflector.transliterate(char)
  ensure
    I18n.locale = default_locale
  end

  def test_transliterate_respects_the_locale_argument
    char = [117, 776].pack("U*") # "ü" as ASCII "u" plus COMBINING DIAERESIS
    I18n.backend.store_translations(:de, i18n: { transliterate: { rule: { "ü" => "ue" } } })
    assert_equal "ue", ActiveSupport::Inflector.transliterate(char, locale: :de)
  end

  def test_transliterate_should_allow_a_custom_replacement_char
    assert_equal "a*b", ActiveSupport::Inflector.transliterate("a索b", "*")
  end

  def test_transliterate_handles_empty_string
    assert_equal "", ActiveSupport::Inflector.transliterate("")
  end

  def test_transliterate_handles_nil
    exception = assert_raises ArgumentError do
      ActiveSupport::Inflector.transliterate(nil)
    end
    assert_equal "Can only transliterate strings. Received NilClass", exception.message
  end

  def test_transliterate_handles_unknown_object
    exception = assert_raises ArgumentError do
      ActiveSupport::Inflector.transliterate(Object.new)
    end
    assert_equal "Can only transliterate strings. Received Object", exception.message
  end

  def test_transliterate_handles_strings_with_valid_utf8_encodings
    string = String.new("A", encoding: Encoding::UTF_8)
    assert_equal "A", ActiveSupport::Inflector.transliterate(string)
  end

  def test_transliterate_handles_strings_with_valid_us_ascii_encodings
    string = String.new("A", encoding: Encoding::US_ASCII)
    transcoded = ActiveSupport::Inflector.transliterate(string)
    assert_equal "A", transcoded
    assert_equal Encoding::US_ASCII, transcoded.encoding
  end

  def test_transliterate_handles_strings_with_valid_gb18030_encodings
    string = String.new("A", encoding: Encoding::GB18030)
    transcoded = ActiveSupport::Inflector.transliterate(string)
    assert_equal "A", transcoded
    assert_equal Encoding::GB18030, transcoded.encoding
  end

  def test_transliterate_handles_strings_with_incompatible_encodings
    incompatible_encodings = Encoding.list - [
      Encoding::UTF_8,
      Encoding::US_ASCII,
      Encoding::GB18030
    ]
    incompatible_encodings.each do |encoding|
      string = String.new("", encoding: encoding)
      exception = assert_raises ArgumentError do
        ActiveSupport::Inflector.transliterate(string)
      end
      assert_equal "Can not transliterate strings with #{encoding} encoding", exception.message
    end
  end

  def test_transliterate_handles_strings_with_invalid_utf8_bytes
    string = String.new("\255", encoding: Encoding::UTF_8)
    assert_equal "?", ActiveSupport::Inflector.transliterate(string)
  end

  def test_transliterate_handles_strings_with_invalid_us_ascii_bytes
    string = String.new("\255", encoding: Encoding::US_ASCII)
    assert_equal "?", ActiveSupport::Inflector.transliterate(string)
  end

  def test_transliterate_handles_strings_with_invalid_gb18030_bytes
    string = String.new("\255", encoding: Encoding::GB18030)
    assert_equal "?", ActiveSupport::Inflector.transliterate(string)
  end
end