Upgraded Rails and RSpec
[monkeycharger.git] / vendor / rails / activesupport / test / multibyte_chars_test.rb
blob6e87ea885119630359326a5a0ea18ecfc34e2ade
1 require File.dirname(__FILE__) + '/abstract_unit'
3 $KCODE = 'UTF8'
5 class CharsTest < Test::Unit::TestCase
6   
7   def setup
8     @s = {
9       :utf8 => "Abcd Блå ffi блa  埋",
10       :ascii => "asci ias c iia s",
11       :bytes => "\270\236\010\210\245"
12     }
13   end
14   
15   def test_sanity
16     @s.each do |t, s|
17       assert s.respond_to?(:chars), "All string should have the chars method (#{t})"
18       assert s.respond_to?(:to_s), "All string should have the to_s method (#{t})"
19       assert_kind_of ActiveSupport::Multibyte::Chars, s.chars, "#chars should return an instance of Chars (#{t})"
20     end
21   end
22   
23   def test_comparability
24     @s.each do |t, s|
25       assert_equal s, s.chars.to_s, "Chars#to_s should return enclosed string unchanged"
26     end
27     assert_nothing_raised do
28       assert_equal "a", "a", "Normal string comparisons should be unaffected"
29       assert_not_equal "a", "b", "Normal string comparisons should be unaffected"
30       assert_not_equal "a".chars, "b".chars, "Chars objects should be comparable"
31       assert_equal "a".chars, "A".downcase.chars, "Chars objects should be comparable to each other"
32       assert_equal "a".chars, "A".downcase, "Chars objects should be comparable to strings coming from elsewhere"
33     end
34     
35     assert !@s[:utf8].eql?(@s[:utf8].chars), "Strict comparison is not supported"
36     assert_equal @s[:utf8], @s[:utf8].chars, "Chars should be compared by their enclosed string"
38     other_string = @s[:utf8].dup
39     assert_equal other_string, @s[:utf8].chars, "Chars should be compared by their enclosed string"
40     assert_equal other_string.chars, @s[:utf8].chars, "Chars should be compared by their enclosed string"
41     
42     strings = ['builder'.chars, 'armor'.chars, 'zebra'.chars]
43     strings.sort!
44     assert_equal ['armor', 'builder', 'zebra'], strings, "Chars should be sortable based on their enclosed string"
46     # This leads to a StackLevelTooDeep exception if the comparison is not wired properly
47     assert_raise(NameError) do
48       Chars
49     end
50   end
51   
52   def test_utf8?
53     assert @s[:utf8].is_utf8?, "UTF-8 strings are UTF-8"
54     assert @s[:ascii].is_utf8?, "All ASCII strings are also valid UTF-8"
55     assert !@s[:bytes].is_utf8?, "This bytestring isn't UTF-8"
56   end
57   
58   # The test for the following methods are defined here because they can only be defined on the Chars class for
59   # various reasons 
60   
61   def test_gsub
62     assert_equal 'éxa', 'éda'.chars.gsub(/d/, 'x')
63     with_kcode('none') do
64       assert_equal 'éxa', 'éda'.chars.gsub(/d/, 'x')
65     end
66   end
67   
68   def test_split
69     word = "efficient"
70     chars = ["e", "ffi", "c", "i", "e", "n", "t"]
71     assert_equal chars, word.split(//)
72     assert_equal chars, word.chars.split(//)
73     assert_kind_of ActiveSupport::Multibyte::Chars, word.chars.split(//).first, "Split should return Chars instances"
74   end
75   
76   def test_regexp
77     with_kcode('none') do
78       assert_equal 12, (@s[:utf8].chars =~ /ffi/),
79         "Regex matching should be bypassed to String"
80     end
81     with_kcode('UTF8') do
82       assert_equal 9, (@s[:utf8].chars =~ /ffi/),
83         "Regex matching should be unicode aware"
84       assert_nil((''.chars =~ /\d+/),
85         "Non-matching regular expressions should return nil")
86     end
87   end
88   
89   def test_pragma
90     with_kcode('UTF8') do
91       assert " ".chars.send(:utf8_pragma?), "UTF8 pragma should be on because KCODE is UTF8"
92     end
93     with_kcode('none') do
94       assert !" ".chars.send(:utf8_pragma?), "UTF8 pragma should be off"
95     end
96   end
97   
98   def test_handler_setting
99     handler = ''.chars.handler
100     
101     ActiveSupport::Multibyte::Chars.handler = :first
102     assert_equal :first, ''.chars.handler
103     ActiveSupport::Multibyte::Chars.handler = :second
104     assert_equal :second, ''.chars.handler
105     assert_raise(NoMethodError) do
106       ''.chars.handler.split
107     end
108     
109     ActiveSupport::Multibyte::Chars.handler = handler
110   end
111   
112   def test_method_chaining
113     assert_kind_of ActiveSupport::Multibyte::Chars, ''.chars.downcase
114     assert_kind_of ActiveSupport::Multibyte::Chars, ''.chars.strip, "Strip should return a Chars object"
115     assert_kind_of ActiveSupport::Multibyte::Chars, ''.chars.downcase.strip, "The Chars object should be " +
116         "forwarded down the call path for chaining"
117     assert_equal 'foo', "  FOO   ".chars.normalize.downcase.strip, "The Chars that results from the " +
118       " operations should be comparable to the string value of the result"
119   end
120   
121   def test_passthrough_on_kcode
122     # The easiest way to check if the passthrough is in place is through #size
123     with_kcode('none') do
124       assert_equal 26, @s[:utf8].chars.size
125     end
126     with_kcode('UTF8') do
127       assert_equal 17, @s[:utf8].chars.size
128     end
129   end
130     
131   def test_destructiveness  
132     # Note that we're testing the destructiveness here and not the correct behaviour of the methods
133     str = 'ac'
134     str.chars.insert(1, 'b')
135     assert_equal 'abc', str, 'Insert should be destructive for a string'
136     
137     str = 'ac'
138     str.chars.reverse!
139     assert_equal 'ca', str, 'reverse! should be destructive for a string'
140   end
141   
142   def test_resilience
143     assert_nothing_raised do
144       assert_equal 5, @s[:bytes].chars.size, "The sequence contains five interpretable bytes"
145     end
146     reversed = [0xb8, 0x17e, 0x8, 0x2c6, 0xa5].reverse.pack('U*')
147     assert_nothing_raised do
148       assert_equal reversed, @s[:bytes].chars.reverse.to_s, "Reversing the string should only yield interpretable bytes"
149     end
150     assert_nothing_raised do
151       @s[:bytes].chars.reverse!
152       assert_equal reversed, @s[:bytes].to_s, "Reversing the string should only yield interpretable bytes"
153     end
154   end
155   
156   def test_duck_typing
157     assert_equal true,  'test'.chars.respond_to?(:strip)
158     assert_equal true,  'test'.chars.respond_to?(:normalize)
159     assert_equal true,  'test'.chars.respond_to?(:normalize!)
160     assert_equal false, 'test'.chars.respond_to?(:a_method_that_doesnt_exist)
161   end
162   
163   protected
165   def with_kcode(kcode)
166     old_kcode, $KCODE = $KCODE, kcode
167     begin
168       yield
169     ensure
170       $KCODE = old_kcode
171     end
172   end