1require 'test/unit' 2require 'tmpdir' 3require_relative 'envutil' 4 5class TestDir_M17N < Test::Unit::TestCase 6 def with_tmpdir 7 Dir.mktmpdir {|dir| 8 Dir.chdir(dir) { 9 yield dir 10 } 11 } 12 end 13 14 def create_and_check_raw_file_name(code, encoding) 15 with_tmpdir { |dir| 16 create_file_program = %Q[ 17 filename = #{code}.chr('UTF-8').force_encoding("#{encoding}") 18 File.open(filename, "w") {} 19 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 20 ents = Dir.entries(".", opts) 21 exit ents.include?(filename) 22 ] 23 assert_ruby_status(["-E#{encoding}"], create_file_program, nil, :chdir=>dir) 24 25 test_file_program = %Q[ 26 filename = #{code}.chr('UTF-8').force_encoding("ASCII-8BIT") 27 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 28 ents = Dir.entries(".", opts) 29 expected_filename = #{code}.chr('UTF-8').encode(Encoding.find("filesystem")) rescue expected_filename = "?" 30 expected_filename = expected_filename.force_encoding("ASCII-8BIT") 31 result = ents.include?(filename) || (/mswin|mingw/ =~ RUBY_PLATFORM && ents.include?(expected_filename)) 32 if !result && /mswin|mingw/ =~ RUBY_PLATFORM 33 exit Dir.entries(".", {:encoding => Encoding.find("filesystem")}).include?(expected_filename) 34 end 35 exit result 36 ] 37 assert_ruby_status(%w[-EASCII-8BIT], test_file_program, nil, :chdir=>dir) 38 } 39 end 40 41 ## UTF-8 default_external, no default_internal 42 43 def test_filename_extutf8 44 with_tmpdir {|d| 45 assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d) 46 filename = "\u3042" 47 File.open(filename, "w") {} 48 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 49 ents = Dir.entries(".", opts) 50 exit ents.include?(filename) 51 EOS 52 } 53 end 54 55 def test_filename_extutf8_invalid 56 with_tmpdir {|d| 57 assert_ruby_status(%w[-EASCII-8BIT], <<-'EOS', nil, :chdir=>d) 58 filename = "\xff".force_encoding("ASCII-8BIT") # invalid byte sequence as UTF-8 59 File.open(filename, "w") {} 60 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 61 ents = Dir.entries(".", opts) 62 exit ents.include?(filename) || (/darwin/ =~ RUBY_PLATFORM && ents.include?("%FF")) 63 EOS 64 assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d) 65 filename = "\xff".force_encoding("UTF-8") # invalid byte sequence as UTF-8 66 File.open(filename, "w") {} 67 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 68 ents = Dir.entries(".", opts) 69 exit ents.include?(filename) || (/darwin/ =~ RUBY_PLATFORM && ents.include?("%FF")) 70 EOS 71 } 72 end unless /mswin|mingw/ =~ RUBY_PLATFORM 73 74 def test_filename_as_bytes_extutf8 75 with_tmpdir {|d| 76 assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d) 77 filename = "\xc2\xa1".force_encoding("utf-8") 78 File.open(filename, "w") {} 79 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 80 ents = Dir.entries(".", opts) 81 exit ents.include?(filename) 82 EOS 83 assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d) 84 if /mswin|mingw/ =~ RUBY_PLATFORM 85 filename = "\x8f\xa2\xc2".force_encoding("euc-jp") 86 else 87 filename = "\xc2\xa1".force_encoding("euc-jp") 88 end 89 begin 90 open(filename) {} 91 exit true 92 rescue Errno::ENOENT 93 exit false 94 end 95 EOS 96 # no meaning test on windows 97 unless /mswin|mingw/ =~ RUBY_PLATFORM 98 assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d) 99 filename1 = "\xc2\xa1".force_encoding("utf-8") 100 filename2 = "\xc2\xa1".force_encoding("euc-jp") 101 filename3 = filename1.encode("euc-jp") 102 filename4 = filename2.encode("utf-8") 103 s1 = File.stat(filename1) rescue nil 104 s2 = File.stat(filename2) rescue nil 105 s3 = File.stat(filename3) rescue nil 106 s4 = File.stat(filename4) rescue nil 107 exit((s1 && s2 && !s3 && !s4) ? true : false) 108 EOS 109 end 110 } 111 end 112 113 ## UTF-8 default_external, EUC-JP default_internal 114 115 def test_filename_extutf8_inteucjp_representable 116 with_tmpdir {|d| 117 assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d) 118 filename = "\u3042" 119 File.open(filename, "w") {} 120 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 121 ents = Dir.entries(".", opts) 122 exit ents.include?(filename) 123 EOS 124 assert_ruby_status(%w[-EUTF-8:EUC-JP], <<-'EOS', nil, :chdir=>d) 125 filename = "\xA4\xA2".force_encoding("euc-jp") 126 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 127 ents = Dir.entries(".", opts) 128 exit ents.include?(filename) 129 EOS 130 assert_ruby_status(%w[-EUTF-8:EUC-JP], <<-'EOS', nil, :chdir=>d) 131 filename = "\xA4\xA2".force_encoding("euc-jp") 132 begin 133 open(filename) {} 134 exit true 135 rescue Errno::ENOENT 136 exit false 137 end 138 EOS 139 } 140 end 141 142 def test_filename_extutf8_inteucjp_unrepresentable 143 with_tmpdir {|d| 144 assert_ruby_status(%w[-EUTF-8], <<-'EOS', nil, :chdir=>d) 145 filename1 = "\u2661" # WHITE HEART SUIT which is not representable in EUC-JP 146 filename2 = "\u3042" # HIRAGANA LETTER A which is representable in EUC-JP 147 File.open(filename1, "w") {} 148 File.open(filename2, "w") {} 149 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 150 ents = Dir.entries(".", opts) 151 exit ents.include?(filename1) && ents.include?(filename2) 152 EOS 153 assert_ruby_status(%w[-EUTF-8:EUC-JP], <<-'EOS', nil, :chdir=>d) 154 filename1 = "\u2661" # WHITE HEART SUIT which is not representable in EUC-JP 155 filename2 = "\xA4\xA2".force_encoding("euc-jp") # HIRAGANA LETTER A in EUC-JP 156 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 157 ents = Dir.entries(".", opts) 158 exit ents.include?(filename1) && ents.include?(filename2) 159 EOS 160 assert_ruby_status(%w[-EUTF-8:EUC-JP], <<-'EOS', nil, :chdir=>d) 161 filename1 = "\u2661" # WHITE HEART SUIT which is not representable in EUC-JP 162 filename2 = "\u3042" # HIRAGANA LETTER A which is representable in EUC-JP 163 filename3 = "\xA4\xA2".force_encoding("euc-jp") # HIRAGANA LETTER A in EUC-JP 164 s1 = File.stat(filename1) rescue nil 165 s2 = File.stat(filename2) rescue nil 166 s3 = File.stat(filename3) rescue nil 167 exit((s1 && s2 && s3) ? true : false) 168 EOS 169 } 170 end 171 172 ## others 173 174 def test_filename_bytes_euc_jp 175 with_tmpdir {|d| 176 assert_ruby_status(%w[-EEUC-JP], <<-'EOS', nil, :chdir=>d) 177 filename = "\xA4\xA2".force_encoding("euc-jp") 178 File.open(filename, "w") {} 179 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 180 ents = Dir.entries(".", opts) 181 ents.each {|e| e.force_encoding("ASCII-8BIT") } 182 exit ents.include?(filename.force_encoding("ASCII-8BIT")) || 183 (/darwin/ =~ RUBY_PLATFORM && ents.include?("%A4%A2".force_encoding("ASCII-8BIT"))) 184 EOS 185 } 186 end 187 188 def test_filename_euc_jp 189 with_tmpdir {|d| 190 assert_ruby_status(%w[-EEUC-JP], <<-'EOS', nil, :chdir=>d) 191 filename = "\xA4\xA2".force_encoding("euc-jp") 192 File.open(filename, "w") {} 193 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 194 ents = Dir.entries(".", opts) 195 exit ents.include?(filename) || (/darwin/ =~ RUBY_PLATFORM && ents.include?("%A4%A2".force_encoding("euc-jp"))) 196 EOS 197 assert_ruby_status(%w[-EASCII-8BIT], <<-'EOS', nil, :chdir=>d) 198 filename = "\xA4\xA2".force_encoding('ASCII-8BIT') 199 win_expected_filename = filename.encode(Encoding.find("filesystem"), "euc-jp") rescue "?" 200 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 201 ents = Dir.entries(".", opts) 202 result = ents.include?(filename) || 203 (/darwin/ =~ RUBY_PLATFORM && ents.include?("%A4%A2".force_encoding("ASCII-8BIT"))) || 204 (/mswin|mingw/ =~ RUBY_PLATFORM && ents.include?(win_expected_filename.force_encoding("ASCII-8BIT"))) 205 if !result && /mswin|mingw/ =~ RUBY_PLATFORM 206 exit Dir.entries(".", {:encoding => Encoding.find("filesystem")}).include?(win_expected_filename) 207 end 208 exit result 209 EOS 210 } 211 end 212 213 def test_filename_utf8_raw_jp_name 214 create_and_check_raw_file_name(0x3042, "UTF-8") 215 end 216 217 def test_filename_utf8_raw_windows_1251_name 218 create_and_check_raw_file_name(0x0424, "UTF-8") 219 end 220 221 def test_filename_utf8_raw_windows_1252_name 222 create_and_check_raw_file_name(0x00c6, "UTF-8") 223 end 224 225 def test_filename_ext_euc_jp_and_int_utf_8 226 with_tmpdir {|d| 227 assert_ruby_status(%w[-EEUC-JP], <<-'EOS', nil, :chdir=>d) 228 filename = "\xA4\xA2".force_encoding("euc-jp") 229 File.open(filename, "w") {} 230 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 231 ents = Dir.entries(".", opts) 232 exit ents.include?(filename) || (/darwin/ =~ RUBY_PLATFORM && ents.include?("%A4%A2".force_encoding("euc-jp"))) 233 EOS 234 assert_ruby_status(%w[-EEUC-JP:UTF-8], <<-'EOS', nil, :chdir=>d) 235 filename = "\u3042" 236 opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM 237 ents = Dir.entries(".", opts) 238 exit ents.include?(filename) || (/darwin/ =~ RUBY_PLATFORM && ents.include?("%A4%A2")) 239 EOS 240 } 241 end 242 243 def test_error_nonascii 244 bug6071 = '[ruby-dev:45279]' 245 paths = ["\u{3042}".encode("sjis"), "\u{ff}".encode("iso-8859-1")] 246 encs = with_tmpdir { 247 paths.map {|path| 248 Dir.open(path) rescue $!.message.encoding 249 } 250 } 251 assert_equal(paths.map(&:encoding), encs, bug6071) 252 end 253 254 def test_inspect_nonascii 255 bug6072 = '[ruby-dev:45280]' 256 paths = ["\u{3042}".encode("sjis"), "\u{ff}".encode("iso-8859-1")] 257 encs = with_tmpdir { 258 paths.map {|path| 259 Dir.mkdir(path) 260 Dir.open(path) {|d| d.inspect.encoding} 261 } 262 } 263 assert_equal(paths.map(&:encoding), encs, bug6072) 264 end 265 266 def test_glob_incompatible 267 d = "\u{3042}\u{3044}".encode("utf-16le") 268 assert_raise(Encoding::CompatibilityError) {Dir.glob(d)} 269 m = Class.new {define_method(:to_path) {d}} 270 assert_raise(Encoding::CompatibilityError) {Dir.glob(m.new)} 271 end 272end 273