1require 'test/unit' 2 3require 'tmpdir' 4require 'fileutils' 5require 'pathname' 6 7class TestDir < Test::Unit::TestCase 8 9 def setup 10 @verbose = $VERBOSE 11 $VERBOSE = nil 12 @root = Pathname.new(Dir.mktmpdir('__test_dir__')).realpath.to_s 13 @nodir = File.join(@root, "dummy") 14 for i in ?a..?z 15 if i.ord % 2 == 0 16 FileUtils.touch(File.join(@root, i)) 17 else 18 FileUtils.mkdir(File.join(@root, i)) 19 end 20 end 21 end 22 23 def teardown 24 $VERBOSE = @verbose 25 FileUtils.remove_entry_secure @root if File.directory?(@root) 26 end 27 28 def test_seek 29 dir = Dir.open(@root) 30 begin 31 cache = [] 32 loop do 33 pos = dir.tell 34 break unless name = dir.read 35 cache << [pos, name] 36 end 37 for x,y in cache.sort_by {|z| z[0] % 3 } # shuffle 38 dir.seek(x) 39 assert_equal(y, dir.read) 40 end 41 ensure 42 dir.close 43 end 44 end 45 46 def test_JVN_13947696 47 b = lambda { 48 d = Dir.open('.') 49 $SAFE = 4 50 d.close 51 } 52 assert_raise(SecurityError) { b.call } 53 end 54 55 def test_nodir 56 assert_raise(Errno::ENOENT) { Dir.open(@nodir) } 57 end 58 59 def test_inspect 60 d = Dir.open(@root) 61 assert_match(/^#<Dir:#{ Regexp.quote(@root) }>$/, d.inspect) 62 assert_match(/^#<Dir:.*>$/, Dir.allocate.inspect) 63 ensure 64 d.close 65 end 66 67 def test_path 68 d = Dir.open(@root) 69 assert_equal(@root, d.path) 70 assert_nil(Dir.allocate.path) 71 ensure 72 d.close 73 end 74 75 def test_set_pos 76 d = Dir.open(@root) 77 loop do 78 i = d.pos 79 break unless x = d.read 80 d.pos = i 81 assert_equal(x, d.read) 82 end 83 ensure 84 d.close 85 end 86 87 def test_rewind 88 d = Dir.open(@root) 89 a = (0..5).map { d.read } 90 d.rewind 91 b = (0..5).map { d.read } 92 assert_equal(a, b) 93 assert_raise(SecurityError) do 94 Thread.new do 95 $SAFE = 4 96 d.rewind 97 end.join 98 end 99 ensure 100 d.close 101 end 102 103 def test_chdir 104 @pwd = Dir.pwd 105 @env_home = ENV["HOME"] 106 @env_logdir = ENV["LOGDIR"] 107 ENV.delete("HOME") 108 ENV.delete("LOGDIR") 109 110 assert_raise(Errno::ENOENT) { Dir.chdir(@nodir) } 111 assert_raise(ArgumentError) { Dir.chdir } 112 ENV["HOME"] = @pwd 113 Dir.chdir do 114 assert_equal(@pwd, Dir.pwd) 115 Dir.chdir(@root) 116 assert_equal(@root, Dir.pwd) 117 end 118 119 ensure 120 begin 121 Dir.chdir(@pwd) 122 rescue 123 abort("cannot return the original directory: #{ @pwd }") 124 end 125 if @env_home 126 ENV["HOME"] = @env_home 127 else 128 ENV.delete("HOME") 129 end 130 if @env_logdir 131 ENV["LOGDIR"] = @env_logdir 132 else 133 ENV.delete("LOGDIR") 134 end 135 end 136 137 def test_chroot_nodir 138 assert_raise(NotImplementedError, Errno::ENOENT, Errno::EPERM 139 ) { Dir.chroot(File.join(@nodir, "")) } 140 end 141 142 def test_close 143 d = Dir.open(@root) 144 d.close 145 assert_raise(IOError) { d.read } 146 end 147 148 def test_glob 149 assert_equal((%w(. ..) + (?a..?z).to_a).map{|f| File.join(@root, f) }, 150 Dir.glob(File.join(@root, "*"), File::FNM_DOTMATCH).sort) 151 assert_equal([@root] + (?a..?z).map {|f| File.join(@root, f) }.sort, 152 Dir.glob([@root, File.join(@root, "*")]).sort) 153 assert_equal([@root] + (?a..?z).map {|f| File.join(@root, f) }.sort, 154 Dir.glob(@root + "\0\0\0" + File.join(@root, "*")).sort) 155 156 assert_equal((?a..?z).step(2).map {|f| File.join(File.join(@root, f), "") }.sort, 157 Dir.glob(File.join(@root, "*/")).sort) 158 159 FileUtils.touch(File.join(@root, "{}")) 160 assert_equal(%w({} a).map{|f| File.join(@root, f) }, 161 Dir.glob(File.join(@root, '{\{\},a}'))) 162 assert_equal([], Dir.glob(File.join(@root, '['))) 163 assert_equal([], Dir.glob(File.join(@root, '[a-\\'))) 164 165 assert_equal([File.join(@root, "a")], Dir.glob(File.join(@root, 'a\\'))) 166 assert_equal((?a..?f).map {|f| File.join(@root, f) }.sort, Dir.glob(File.join(@root, '[abc/def]')).sort) 167 end 168 169 def test_glob_recursive 170 bug6977 = '[ruby-core:47418]' 171 bug8006 = '[ruby-core:53108] [Bug #8006]' 172 Dir.chdir(@root) do 173 assert_include(Dir.glob("a/**/*", File::FNM_DOTMATCH), "a/.", bug8006) 174 175 FileUtils.mkdir_p("a/b/c/d/e/f") 176 assert_equal(["a/b/c/d/e/f"], Dir.glob("a/**/e/f"), bug6977) 177 assert_equal(["a/b/c/d/e/f"], Dir.glob("a/**/d/e/f"), bug6977) 178 assert_equal(["a/b/c/d/e/f"], Dir.glob("a/**/c/d/e/f"), bug6977) 179 assert_equal(["a/b/c/d/e/f"], Dir.glob("a/**/b/c/d/e/f"), bug6977) 180 assert_equal(["a/b/c/d/e/f"], Dir.glob("a/**/c/?/e/f"), bug6977) 181 assert_equal(["a/b/c/d/e/f"], Dir.glob("a/**/c/**/d/e/f"), bug6977) 182 assert_equal(["a/b/c/d/e/f"], Dir.glob("a/**/c/**/d/e/f"), bug6977) 183 184 bug8283 = '[ruby-core:54387] [Bug #8283]' 185 dirs = ["a/.x", "a/b/.y"] 186 FileUtils.mkdir_p(dirs) 187 dirs.map {|dir| open("#{dir}/z", "w") {}} 188 assert_equal([], Dir.glob("a/**/z").sort, bug8283) 189 assert_equal(["a/.x/z"], Dir.glob("a/**/.x/z"), bug8283) 190 assert_equal(["a/.x/z"], Dir.glob("a/.x/**/z"), bug8283) 191 assert_equal(["a/b/.y/z"], Dir.glob("a/**/.y/z"), bug8283) 192 end 193 end 194 195 def test_foreach 196 assert_equal(Dir.foreach(@root).to_a.sort, %w(. ..) + (?a..?z).to_a) 197 end 198 199 def test_dir_enc 200 dir = Dir.open(@root, encoding: "UTF-8") 201 begin 202 while name = dir.read 203 assert_equal(Encoding.find("UTF-8"), name.encoding) 204 end 205 ensure 206 dir.close 207 end 208 209 dir = Dir.open(@root, encoding: "ASCII-8BIT") 210 begin 211 while name = dir.read 212 assert_equal(Encoding.find("ASCII-8BIT"), name.encoding) 213 end 214 ensure 215 dir.close 216 end 217 end 218 219 def test_symlink 220 begin 221 ["dummy", *?a..?z].each do |f| 222 File.symlink(File.join(@root, f), 223 File.join(@root, "symlink-#{ f }")) 224 end 225 rescue NotImplementedError 226 return 227 end 228 229 assert_equal([*?a..?z, *"symlink-a".."symlink-z"].each_slice(2).map {|f, _| File.join(@root, f + "/") }.sort, 230 Dir.glob(File.join(@root, "*/")).sort) 231 232 Dir.glob(File.join(@root, "**/")) 233 end 234 235end 236