| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library io_test; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 import 'dart:io'; | |
| 9 | |
| 10 import 'package:path/path.dart' as path; | |
| 11 import 'package:unittest/unittest.dart'; | |
| 12 | |
| 13 import '../lib/src/io.dart'; | |
| 14 import 'test_pub.dart'; | |
| 15 | |
| 16 main() { | |
| 17 initConfig(); | |
| 18 | |
| 19 group('listDir', () { | |
| 20 test('ignores hidden files by default', () { | |
| 21 expect(withTempDir((temp) { | |
| 22 writeTextFile(path.join(temp, 'file1.txt'), ''); | |
| 23 writeTextFile(path.join(temp, 'file2.txt'), ''); | |
| 24 writeTextFile(path.join(temp, '.file3.txt'), ''); | |
| 25 createDir(path.join(temp, '.subdir')); | |
| 26 writeTextFile(path.join(temp, '.subdir', 'file3.txt'), ''); | |
| 27 | |
| 28 expect( | |
| 29 listDir(temp, recursive: true), | |
| 30 unorderedEquals([path.join(temp, 'file1.txt'), path.join(temp, 'file
2.txt')])); | |
| 31 }), completes); | |
| 32 }); | |
| 33 | |
| 34 test('includes hidden files when told to', () { | |
| 35 expect(withTempDir((temp) { | |
| 36 writeTextFile(path.join(temp, 'file1.txt'), ''); | |
| 37 writeTextFile(path.join(temp, 'file2.txt'), ''); | |
| 38 writeTextFile(path.join(temp, '.file3.txt'), ''); | |
| 39 createDir(path.join(temp, '.subdir')); | |
| 40 writeTextFile(path.join(temp, '.subdir', 'file3.txt'), ''); | |
| 41 | |
| 42 expect( | |
| 43 listDir(temp, recursive: true, includeHidden: true), | |
| 44 unorderedEquals( | |
| 45 [ | |
| 46 path.join(temp, 'file1.txt'), | |
| 47 path.join(temp, 'file2.txt'), | |
| 48 path.join(temp, '.file3.txt'), | |
| 49 path.join(temp, '.subdir'), | |
| 50 path.join(temp, '.subdir', 'file3.txt')])); | |
| 51 }), completes); | |
| 52 }); | |
| 53 | |
| 54 test("doesn't ignore hidden files above the directory being listed", () { | |
| 55 expect(withTempDir((temp) { | |
| 56 var dir = path.join(temp, '.foo', 'bar'); | |
| 57 ensureDir(dir); | |
| 58 writeTextFile(path.join(dir, 'file1.txt'), ''); | |
| 59 writeTextFile(path.join(dir, 'file2.txt'), ''); | |
| 60 writeTextFile(path.join(dir, 'file3.txt'), ''); | |
| 61 | |
| 62 expect( | |
| 63 listDir(dir, recursive: true), | |
| 64 unorderedEquals( | |
| 65 [ | |
| 66 path.join(dir, 'file1.txt'), | |
| 67 path.join(dir, 'file2.txt'), | |
| 68 path.join(dir, 'file3.txt')])); | |
| 69 }), completes); | |
| 70 }); | |
| 71 }); | |
| 72 | |
| 73 group('canonicalize', () { | |
| 74 test('resolves a non-link', () { | |
| 75 expect(withCanonicalTempDir((temp) { | |
| 76 var filePath = path.join(temp, 'file'); | |
| 77 writeTextFile(filePath, ''); | |
| 78 expect(canonicalize(filePath), equals(filePath)); | |
| 79 }), completes); | |
| 80 }); | |
| 81 | |
| 82 test('resolves a non-existent file', () { | |
| 83 expect(withCanonicalTempDir((temp) { | |
| 84 expect( | |
| 85 canonicalize(path.join(temp, 'nothing')), | |
| 86 equals(path.join(temp, 'nothing'))); | |
| 87 }), completes); | |
| 88 }); | |
| 89 | |
| 90 test('resolves a symlink', () { | |
| 91 expect(withCanonicalTempDir((temp) { | |
| 92 createDir(path.join(temp, 'linked-dir')); | |
| 93 createSymlink(path.join(temp, 'linked-dir'), path.join(temp, 'dir')); | |
| 94 expect( | |
| 95 canonicalize(path.join(temp, 'dir')), | |
| 96 equals(path.join(temp, 'linked-dir'))); | |
| 97 }), completes); | |
| 98 }); | |
| 99 | |
| 100 test('resolves a relative symlink', () { | |
| 101 expect(withCanonicalTempDir((temp) { | |
| 102 createDir(path.join(temp, 'linked-dir')); | |
| 103 createSymlink( | |
| 104 path.join(temp, 'linked-dir'), | |
| 105 path.join(temp, 'dir'), | |
| 106 relative: true); | |
| 107 expect( | |
| 108 canonicalize(path.join(temp, 'dir')), | |
| 109 equals(path.join(temp, 'linked-dir'))); | |
| 110 }), completes); | |
| 111 }); | |
| 112 | |
| 113 test('resolves a single-level horizontally recursive symlink', () { | |
| 114 expect(withCanonicalTempDir((temp) { | |
| 115 var linkPath = path.join(temp, 'foo'); | |
| 116 createSymlink(linkPath, linkPath); | |
| 117 expect(canonicalize(linkPath), equals(linkPath)); | |
| 118 }), completes); | |
| 119 }); | |
| 120 | |
| 121 test('resolves a multi-level horizontally recursive symlink', () { | |
| 122 expect(withCanonicalTempDir((temp) { | |
| 123 var fooPath = path.join(temp, 'foo'); | |
| 124 var barPath = path.join(temp, 'bar'); | |
| 125 var bazPath = path.join(temp, 'baz'); | |
| 126 createSymlink(barPath, fooPath); | |
| 127 createSymlink(bazPath, barPath); | |
| 128 createSymlink(fooPath, bazPath); | |
| 129 expect(canonicalize(fooPath), equals(fooPath)); | |
| 130 expect(canonicalize(barPath), equals(barPath)); | |
| 131 expect(canonicalize(bazPath), equals(bazPath)); | |
| 132 | |
| 133 createSymlink(fooPath, path.join(temp, 'outer')); | |
| 134 expect(canonicalize(path.join(temp, 'outer')), equals(fooPath)); | |
| 135 }), completes); | |
| 136 }); | |
| 137 | |
| 138 test('resolves a broken symlink', () { | |
| 139 expect(withCanonicalTempDir((temp) { | |
| 140 createSymlink(path.join(temp, 'nonexistent'), path.join(temp, 'foo')); | |
| 141 expect( | |
| 142 canonicalize(path.join(temp, 'foo')), | |
| 143 equals(path.join(temp, 'nonexistent'))); | |
| 144 }), completes); | |
| 145 }); | |
| 146 | |
| 147 test('resolves multiple nested symlinks', () { | |
| 148 expect(withCanonicalTempDir((temp) { | |
| 149 var dir1 = path.join(temp, 'dir1'); | |
| 150 var dir2 = path.join(temp, 'dir2'); | |
| 151 var subdir1 = path.join(dir1, 'subdir1'); | |
| 152 var subdir2 = path.join(dir2, 'subdir2'); | |
| 153 createDir(dir2); | |
| 154 createDir(subdir2); | |
| 155 createSymlink(dir2, dir1); | |
| 156 createSymlink(subdir2, subdir1); | |
| 157 expect( | |
| 158 canonicalize(path.join(subdir1, 'file')), | |
| 159 equals(path.join(subdir2, 'file'))); | |
| 160 }), completes); | |
| 161 }); | |
| 162 | |
| 163 test('resolves a nested vertical symlink', () { | |
| 164 expect(withCanonicalTempDir((temp) { | |
| 165 var dir1 = path.join(temp, 'dir1'); | |
| 166 var dir2 = path.join(temp, 'dir2'); | |
| 167 var subdir = path.join(dir1, 'subdir'); | |
| 168 createDir(dir1); | |
| 169 createDir(dir2); | |
| 170 createSymlink(dir2, subdir); | |
| 171 expect( | |
| 172 canonicalize(path.join(subdir, 'file')), | |
| 173 equals(path.join(dir2, 'file'))); | |
| 174 }), completes); | |
| 175 }); | |
| 176 | |
| 177 test('resolves a vertically recursive symlink', () { | |
| 178 expect(withCanonicalTempDir((temp) { | |
| 179 var dir = path.join(temp, 'dir'); | |
| 180 var subdir = path.join(dir, 'subdir'); | |
| 181 createDir(dir); | |
| 182 createSymlink(dir, subdir); | |
| 183 expect( | |
| 184 canonicalize( | |
| 185 path.join(temp, 'dir', 'subdir', 'subdir', 'subdir', 'subdir', '
file')), | |
| 186 equals(path.join(dir, 'file'))); | |
| 187 }), completes); | |
| 188 }); | |
| 189 | |
| 190 test( | |
| 191 'resolves a symlink that links to a path that needs more resolving', | |
| 192 () { | |
| 193 expect(withCanonicalTempDir((temp) { | |
| 194 var dir = path.join(temp, 'dir'); | |
| 195 var linkdir = path.join(temp, 'linkdir'); | |
| 196 var linkfile = path.join(dir, 'link'); | |
| 197 createDir(dir); | |
| 198 createSymlink(dir, linkdir); | |
| 199 createSymlink(path.join(linkdir, 'file'), linkfile); | |
| 200 expect(canonicalize(linkfile), equals(path.join(dir, 'file'))); | |
| 201 }), completes); | |
| 202 }); | |
| 203 | |
| 204 test('resolves a pair of pathologically-recursive symlinks', () { | |
| 205 expect(withCanonicalTempDir((temp) { | |
| 206 var foo = path.join(temp, 'foo'); | |
| 207 var subfoo = path.join(foo, 'subfoo'); | |
| 208 var bar = path.join(temp, 'bar'); | |
| 209 var subbar = path.join(bar, 'subbar'); | |
| 210 createSymlink(subbar, foo); | |
| 211 createSymlink(subfoo, bar); | |
| 212 expect( | |
| 213 canonicalize(subfoo), | |
| 214 equals(path.join(subfoo, 'subbar', 'subfoo'))); | |
| 215 }), completes); | |
| 216 }); | |
| 217 }); | |
| 218 | |
| 219 testExistencePredicate( | |
| 220 "entryExists", | |
| 221 entryExists, | |
| 222 forFile: true, | |
| 223 forFileSymlink: true, | |
| 224 forMultiLevelFileSymlink: true, | |
| 225 forDirectory: true, | |
| 226 forDirectorySymlink: true, | |
| 227 forMultiLevelDirectorySymlink: true, | |
| 228 forBrokenSymlink: true, | |
| 229 forMultiLevelBrokenSymlink: true); | |
| 230 | |
| 231 testExistencePredicate( | |
| 232 "linkExists", | |
| 233 linkExists, | |
| 234 forFile: false, | |
| 235 forFileSymlink: true, | |
| 236 forMultiLevelFileSymlink: true, | |
| 237 forDirectory: false, | |
| 238 forDirectorySymlink: true, | |
| 239 forMultiLevelDirectorySymlink: true, | |
| 240 forBrokenSymlink: true, | |
| 241 forMultiLevelBrokenSymlink: true); | |
| 242 | |
| 243 testExistencePredicate( | |
| 244 "fileExists", | |
| 245 fileExists, | |
| 246 forFile: true, | |
| 247 forFileSymlink: true, | |
| 248 forMultiLevelFileSymlink: true, | |
| 249 forDirectory: false, | |
| 250 forDirectorySymlink: false, | |
| 251 forMultiLevelDirectorySymlink: false, | |
| 252 forBrokenSymlink: false, | |
| 253 forMultiLevelBrokenSymlink: false); | |
| 254 | |
| 255 testExistencePredicate( | |
| 256 "dirExists", | |
| 257 dirExists, | |
| 258 forFile: false, | |
| 259 forFileSymlink: false, | |
| 260 forMultiLevelFileSymlink: false, | |
| 261 forDirectory: true, | |
| 262 forDirectorySymlink: true, | |
| 263 forMultiLevelDirectorySymlink: true, | |
| 264 forBrokenSymlink: false, | |
| 265 forMultiLevelBrokenSymlink: false); | |
| 266 } | |
| 267 | |
| 268 void testExistencePredicate(String name, bool predicate(String path), | |
| 269 {bool forFile, bool forFileSymlink, bool forMultiLevelFileSymlink, | |
| 270 bool forDirectory, bool forDirectorySymlink, bool forMultiLevelDirectorySyml
ink, | |
| 271 bool forBrokenSymlink, bool forMultiLevelBrokenSymlink}) { | |
| 272 group(name, () { | |
| 273 test('returns $forFile for a file', () { | |
| 274 expect(withTempDir((temp) { | |
| 275 var file = path.join(temp, "test.txt"); | |
| 276 writeTextFile(file, "contents"); | |
| 277 expect(predicate(file), equals(forFile)); | |
| 278 }), completes); | |
| 279 }); | |
| 280 | |
| 281 test('returns $forDirectory for a directory', () { | |
| 282 expect(withTempDir((temp) { | |
| 283 var file = path.join(temp, "dir"); | |
| 284 createDir(file); | |
| 285 expect(predicate(file), equals(forDirectory)); | |
| 286 }), completes); | |
| 287 }); | |
| 288 | |
| 289 test('returns $forDirectorySymlink for a symlink to a directory', () { | |
| 290 expect(withTempDir((temp) { | |
| 291 var targetPath = path.join(temp, "dir"); | |
| 292 var symlinkPath = path.join(temp, "linkdir"); | |
| 293 createDir(targetPath); | |
| 294 createSymlink(targetPath, symlinkPath); | |
| 295 expect(predicate(symlinkPath), equals(forDirectorySymlink)); | |
| 296 }), completes); | |
| 297 }); | |
| 298 | |
| 299 test( | |
| 300 'returns $forMultiLevelDirectorySymlink for a multi-level symlink to ' | |
| 301 'a directory', | |
| 302 () { | |
| 303 expect(withTempDir((temp) { | |
| 304 var targetPath = path.join(temp, "dir"); | |
| 305 var symlink1Path = path.join(temp, "link1dir"); | |
| 306 var symlink2Path = path.join(temp, "link2dir"); | |
| 307 createDir(targetPath); | |
| 308 createSymlink(targetPath, symlink1Path); | |
| 309 createSymlink(symlink1Path, symlink2Path); | |
| 310 expect(predicate(symlink2Path), equals(forMultiLevelDirectorySymlink)); | |
| 311 }), completes); | |
| 312 }); | |
| 313 | |
| 314 test('returns $forBrokenSymlink for a broken symlink', () { | |
| 315 expect(withTempDir((temp) { | |
| 316 var targetPath = path.join(temp, "dir"); | |
| 317 var symlinkPath = path.join(temp, "linkdir"); | |
| 318 createDir(targetPath); | |
| 319 createSymlink(targetPath, symlinkPath); | |
| 320 deleteEntry(targetPath); | |
| 321 expect(predicate(symlinkPath), equals(forBrokenSymlink)); | |
| 322 }), completes); | |
| 323 }); | |
| 324 | |
| 325 test( | |
| 326 'returns $forMultiLevelBrokenSymlink for a multi-level broken symlink', | |
| 327 () { | |
| 328 expect(withTempDir((temp) { | |
| 329 var targetPath = path.join(temp, "dir"); | |
| 330 var symlink1Path = path.join(temp, "link1dir"); | |
| 331 var symlink2Path = path.join(temp, "link2dir"); | |
| 332 createDir(targetPath); | |
| 333 createSymlink(targetPath, symlink1Path); | |
| 334 createSymlink(symlink1Path, symlink2Path); | |
| 335 deleteEntry(targetPath); | |
| 336 expect(predicate(symlink2Path), equals(forMultiLevelBrokenSymlink)); | |
| 337 }), completes); | |
| 338 }); | |
| 339 | |
| 340 // Windows doesn't support symlinking to files. | |
| 341 if (Platform.operatingSystem != 'windows') { | |
| 342 test('returns $forFileSymlink for a symlink to a file', () { | |
| 343 expect(withTempDir((temp) { | |
| 344 var targetPath = path.join(temp, "test.txt"); | |
| 345 var symlinkPath = path.join(temp, "link.txt"); | |
| 346 writeTextFile(targetPath, "contents"); | |
| 347 createSymlink(targetPath, symlinkPath); | |
| 348 expect(predicate(symlinkPath), equals(forFileSymlink)); | |
| 349 }), completes); | |
| 350 }); | |
| 351 | |
| 352 test( | |
| 353 'returns $forMultiLevelFileSymlink for a multi-level symlink to a ' 'f
ile', | |
| 354 () { | |
| 355 expect(withTempDir((temp) { | |
| 356 var targetPath = path.join(temp, "test.txt"); | |
| 357 var symlink1Path = path.join(temp, "link1.txt"); | |
| 358 var symlink2Path = path.join(temp, "link2.txt"); | |
| 359 writeTextFile(targetPath, "contents"); | |
| 360 createSymlink(targetPath, symlink1Path); | |
| 361 createSymlink(symlink1Path, symlink2Path); | |
| 362 expect(predicate(symlink2Path), equals(forMultiLevelFileSymlink)); | |
| 363 }), completes); | |
| 364 }); | |
| 365 } | |
| 366 }); | |
| 367 } | |
| 368 | |
| 369 /// Like [withTempDir], but canonicalizes the path before passing it to [fn]. | |
| 370 Future withCanonicalTempDir(Future fn(String path)) => | |
| 371 withTempDir((temp) => fn(canonicalize(temp))); | |
| OLD | NEW |