1require 'test/unit' 2require 'find' 3require 'tmpdir' 4 5class TestFind < Test::Unit::TestCase 6 def test_empty 7 Dir.mktmpdir {|d| 8 a = [] 9 Find.find(d) {|f| a << f } 10 assert_equal([d], a) 11 } 12 end 13 14 def test_rec 15 Dir.mktmpdir {|d| 16 File.open("#{d}/a", "w"){} 17 Dir.mkdir("#{d}/b") 18 File.open("#{d}/b/a", "w"){} 19 File.open("#{d}/b/b", "w"){} 20 Dir.mkdir("#{d}/c") 21 a = [] 22 Find.find(d) {|f| a << f } 23 assert_equal([d, "#{d}/a", "#{d}/b", "#{d}/b/a", "#{d}/b/b", "#{d}/c"], a) 24 } 25 end 26 27 def test_relative 28 Dir.mktmpdir {|d| 29 File.open("#{d}/a", "w"){} 30 Dir.mkdir("#{d}/b") 31 File.open("#{d}/b/a", "w"){} 32 File.open("#{d}/b/b", "w"){} 33 Dir.mkdir("#{d}/c") 34 a = [] 35 Dir.chdir(d) { 36 Find.find(".") {|f| a << f } 37 } 38 assert_equal([".", "./a", "./b", "./b/a", "./b/b", "./c"], a) 39 } 40 end 41 42 def test_dont_follow_symlink 43 Dir.mktmpdir {|d| 44 File.open("#{d}/a", "w"){} 45 Dir.mkdir("#{d}/b") 46 File.open("#{d}/b/a", "w"){} 47 File.open("#{d}/b/b", "w"){} 48 begin 49 File.symlink("#{d}/b", "#{d}/c") 50 rescue NotImplementedError 51 skip "symlink is not supported." 52 end 53 a = [] 54 Find.find(d) {|f| a << f } 55 assert_equal([d, "#{d}/a", "#{d}/b", "#{d}/b/a", "#{d}/b/b", "#{d}/c"], a) 56 } 57 end 58 59 def test_prune 60 Dir.mktmpdir {|d| 61 File.open("#{d}/a", "w"){} 62 Dir.mkdir("#{d}/b") 63 File.open("#{d}/b/a", "w"){} 64 File.open("#{d}/b/b", "w"){} 65 Dir.mkdir("#{d}/c") 66 a = [] 67 Find.find(d) {|f| 68 a << f 69 Find.prune if f == "#{d}/b" 70 } 71 assert_equal([d, "#{d}/a", "#{d}/b", "#{d}/c"], a) 72 } 73 end 74 75 def test_countup3 76 Dir.mktmpdir {|d| 77 1.upto(3) {|n| File.open("#{d}/#{n}", "w"){} } 78 a = [] 79 Find.find(d) {|f| a << f } 80 assert_equal([d, "#{d}/1", "#{d}/2", "#{d}/3"], a) 81 } 82 end 83 84 def test_countdown3 85 Dir.mktmpdir {|d| 86 3.downto(1) {|n| File.open("#{d}/#{n}", "w"){} } 87 a = [] 88 Find.find(d) {|f| a << f } 89 assert_equal([d, "#{d}/1", "#{d}/2", "#{d}/3"], a) 90 } 91 end 92 93 def test_unreadable_dir 94 skip "no meaning test on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM 95 Dir.mktmpdir {|d| 96 Dir.mkdir(dir = "#{d}/dir") 97 File.open(file = "#{dir}/foo", "w"){} 98 begin 99 File.chmod(0300, dir) 100 a = [] 101 Find.find(d) {|f| a << f } 102 assert_equal([d, dir], a) 103 ensure 104 File.chmod(0700, dir) 105 end 106 } 107 end 108 109 def test_unsearchable_dir 110 Dir.mktmpdir {|d| 111 Dir.mkdir(dir = "#{d}/dir") 112 File.open(file = "#{dir}/foo", "w"){} 113 begin 114 File.chmod(0600, dir) 115 a = [] 116 Find.find(d) {|f| a << f } 117 assert_equal([d, dir, file], a) 118 skip "no meaning test on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM 119 assert_raise(Errno::EACCES) { File.lstat(file) } 120 ensure 121 File.chmod(0700, dir) 122 end 123 } 124 end 125 126 def test_dangling_symlink 127 Dir.mktmpdir {|d| 128 begin 129 File.symlink("foo", "#{d}/bar") 130 rescue NotImplementedError 131 skip "symlink is not supported." 132 end 133 a = [] 134 Find.find(d) {|f| a << f } 135 assert_equal([d, "#{d}/bar"], a) 136 assert_raise(Errno::ENOENT) { File.stat("#{d}/bar") } 137 } 138 end 139 140 def test_dangling_symlink_stat_error 141 Dir.mktmpdir {|d| 142 begin 143 File.symlink("foo", "#{d}/bar") 144 rescue NotImplementedError 145 skip "symlink is not supported." 146 end 147 assert_raise(Errno::ENOENT) { 148 Find.find(d) {|f| File.stat(f) } 149 } 150 } 151 end 152 153 def test_change_dir_to_file 154 Dir.mktmpdir {|d| 155 Dir.mkdir(dir_1 = "#{d}/d1") 156 File.open(file_a = "#{dir_1}/a", "w"){} 157 File.open(file_b = "#{dir_1}/b", "w"){} 158 File.open(file_c = "#{dir_1}/c", "w"){} 159 Dir.mkdir(dir_d = "#{dir_1}/d") 160 File.open(file_de = "#{dir_d}/e", "w"){} 161 dir_2 = "#{d}/d2" 162 a = [] 163 Find.find(d) {|f| 164 a << f 165 if f == file_b 166 File.rename(dir_1, dir_2) 167 File.open(dir_1, "w") {} 168 end 169 } 170 assert_equal([d, dir_1, file_a, file_b, file_c, dir_d], a) 171 } 172 end 173 174 def test_change_dir_to_symlink_loop 175 Dir.mktmpdir {|d| 176 Dir.mkdir(dir_1 = "#{d}/d1") 177 File.open(file_a = "#{dir_1}/a", "w"){} 178 File.open(file_b = "#{dir_1}/b", "w"){} 179 File.open(file_c = "#{dir_1}/c", "w"){} 180 Dir.mkdir(dir_d = "#{dir_1}/d") 181 File.open(file_de = "#{dir_d}/e", "w"){} 182 dir_2 = "#{d}/d2" 183 a = [] 184 Find.find(d) {|f| 185 a << f 186 if f == file_b 187 File.rename(dir_1, dir_2) 188 begin 189 File.symlink("d1", dir_1) 190 rescue NotImplementedError 191 skip "symlink is not supported." 192 end 193 end 194 } 195 assert_equal([d, dir_1, file_a, file_b, file_c, dir_d], a) 196 } 197 end 198 199 def test_enumerator 200 Dir.mktmpdir {|d| 201 File.open("#{d}/a", "w"){} 202 Dir.mkdir("#{d}/b") 203 File.open("#{d}/b/a", "w"){} 204 File.open("#{d}/b/b", "w"){} 205 Dir.mkdir("#{d}/c") 206 e = Find.find(d) 207 a = [] 208 e.each {|f| a << f } 209 assert_equal([d, "#{d}/a", "#{d}/b", "#{d}/b/a", "#{d}/b/b", "#{d}/c"], a) 210 } 211 end 212 213 class TestInclude < Test::Unit::TestCase 214 include Find 215 216 def test_functional_call 217 Dir.mktmpdir {|d| 218 File.open("#{d}/a", "w"){} 219 a = [] 220 find(d) {|f| a << f } 221 assert_equal([d, "#{d}/a"], a) 222 } 223 end 224 end 225 226end 227