Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

root/trunk/activesupport/test/multibyte_chars_test.rb

Revision 8789, 6.1 kB (checked in by bitsweat, 9 months ago)

Ruby 1.9 compat: declare utf-8 file encoding

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