blob: 47a7b38bc0068551a79fda454ff1f6cd72b70aa6 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// Directory listing test.
import "dart:async";
import "dart:io";
import "dart:isolate";
class DirectoryTest {
static void testListing() {
bool listedDir = false;
bool listedFile = false;
Directory directory = new Directory("").createTempSync();
Directory subDirectory = new Directory("${directory.path}/subdir");
Expect.isTrue('$directory'.contains(directory.path));
Expect.isFalse(subDirectory.existsSync());
subDirectory.createSync();
Expect.isTrue(subDirectory.existsSync());
File f = new File('${subDirectory.path}/file.txt');
File fLong = new File('${directory.path}/subdir/../subdir/file.txt');
Expect.isFalse(f.existsSync());
f.createSync();
void testSyncListing(bool recursive) {
for (var entry in directory.listSync(recursive: recursive)) {
if (entry is File) {
Expect.isTrue(entry.path.contains(directory.path));
Expect.isTrue(entry.path.contains('subdir'));
Expect.isTrue(entry.path.contains('file.txt'));
Expect.isFalse(listedFile);
listedFile = true;
} else {
Expect.isTrue(entry is Directory);
Expect.isTrue(entry.path.contains(directory.path));
Expect.isTrue(entry.path.contains('subdir'));
Expect.isFalse(listedDir);
listedDir = true;
}
}
Expect.equals(listedFile, recursive);
Expect.isTrue(listedDir);
listedFile = false;
listedDir = false;
}
testSyncListing(true);
testSyncListing(false);
Expect.equals(f.fullPathSync(), fLong.fullPathSync());
var listingDonePort = new ReceivePort();
directory.list(recursive: true).listen(
(FileSystemEntity entity) {
if (entity is File) {
var path = entity.path;
listedFile = true;
Expect.isTrue(path.contains(directory.path));
Expect.isTrue(path.contains('subdir'));
Expect.isTrue(path.contains('file.txt'));
} else {
var path = entity.path;
Expect.isTrue(entity is Directory);
listedDir = true;
Expect.isTrue(path.contains(directory.path));
Expect.isTrue(path.contains('subdir'));
}
},
onDone: () {
Expect.isTrue(listedDir, "directory not found");
Expect.isTrue(listedFile, "file not found");
directory.delete(recursive: true).then((ignore) {
f.exists().then((exists) => Expect.isFalse(exists));
directory.exists().then((exists) => Expect.isFalse(exists));
subDirectory.exists().then((exists) => Expect.isFalse(exists));
listingDonePort.close();
});
});
// Listing is asynchronous, so nothing should be listed at this
// point.
Expect.isFalse(listedDir);
Expect.isFalse(listedFile);
}
static void testListNonExistent() {
setupListerHandlers(Stream<FileSystemEntity> stream) {
stream.listen(
(_) => Expect.fail("Listing of non-existing directory should fail"),
onError: (e) {
Expect.isTrue(e is AsyncError);
Expect.isTrue(e.error is DirectoryIOException);
});
}
new Directory("").createTemp().then((d) {
d.delete().then((ignore) {
setupListerHandlers(d.list());
setupListerHandlers(d.list(recursive: true));
});
});
}
static void testListTooLongName() {
new Directory("").createTemp().then((d) {
var errors = 0;
var port = new ReceivePort();
setupListHandlers(Stream<FileSystemEntity> stream) {
stream.listen(
(_) => Expect.fail("Listing of non-existing directory should fail"),
onError: (e) {
Expect.isTrue(e is AsyncError);
Expect.isTrue(e.error is DirectoryIOException);
if (++errors == 2) {
d.delete(recursive: true).then((_) {
port.close();
});
}
});
}
var subDirName = 'subdir';
var subDir = new Directory("${d.path}/$subDirName");
subDir.create().then((ignore) {
// Construct a long string of the form
// 'tempdir/subdir/../subdir/../subdir'.
var buffer = new StringBuffer();
buffer.add(subDir.path);
for (var i = 0; i < 1000; i++) {
buffer.add("/../${subDirName}");
}
var long = new Directory("${buffer.toString()}");
setupListHandlers(long.list());
setupListHandlers(long.list(recursive: true));
});
});
}
static void testDeleteNonExistent() {
// Test that deleting a non-existing directory fails.
setupFutureHandlers(future) {
future.then((ignore) {
Expect.fail("Deletion of non-existing directory should fail");
}).catchError((e) {
Expect.isTrue(e.error is DirectoryIOException);
});
}
new Directory("").createTemp().then((d) {
d.delete().then((ignore) {
setupFutureHandlers(d.delete());
setupFutureHandlers(d.delete(recursive: true));
});
});
}
static void testDeleteTooLongName() {
var port = new ReceivePort();
new Directory("").createTemp().then((d) {
var subDirName = 'subdir';
var subDir = new Directory("${d.path}/$subDirName");
subDir.create().then((ignore) {
// Construct a long string of the form
// 'tempdir/subdir/../subdir/../subdir'.
var buffer = new StringBuffer();
buffer.add(subDir.path);
for (var i = 0; i < 1000; i++) {
buffer.add("/../${subDirName}");
}
var long = new Directory("${buffer.toString()}");
var errors = 0;
onError(e) {
Expect.isTrue(e.error is DirectoryIOException);
if (++errors == 2) {
d.delete(recursive: true).then((ignore) => port.close());
}
return true;
}
long.delete().catchError(onError);
long.delete(recursive: true).catchError(onError);
});
});
}
static void testDeleteNonExistentSync() {
Directory d = new Directory("").createTempSync();
d.deleteSync();
Expect.throws(d.deleteSync);
Expect.throws(() => d.deleteSync(recursive: true));
}
static void testDeleteTooLongNameSync() {
Directory d = new Directory("").createTempSync();
var subDirName = 'subdir';
var subDir = new Directory("${d.path}/$subDirName");
subDir.createSync();
// Construct a long string of the form
// 'tempdir/subdir/../subdir/../subdir'.
var buffer = new StringBuffer();
buffer.add(subDir.path);
for (var i = 0; i < 1000; i++) {
buffer.add("/../${subDirName}");
}
var long = new Directory("${buffer.toString()}");
Expect.throws(long.deleteSync);
Expect.throws(() => long.deleteSync(recursive: true));
d.deleteSync(recursive: true);
}
static void testExistsCreateDelete() {
new Directory("").createTemp().then((d) {
d.exists().then((bool exists) {
Expect.isTrue(exists);
Directory created = new Directory("${d.path}/subdir");
created.create().then((ignore) {
created.exists().then((bool exists) {
Expect.isTrue(exists);
created.delete().then((ignore) {
created.exists().then((bool exists) {
Expect.isFalse(exists);
d.delete().then((ignore) {
d.exists().then((bool exists) {
Expect.isFalse(exists);
});
});
});
});
});
});
});
});
}
static void testExistsCreateDeleteSync() {
Directory d = new Directory("").createTempSync();
Directory d2 = new Directory('${d.path}/');
Expect.isTrue(d.existsSync());
Expect.isTrue(d2.existsSync());
Directory created = new Directory("${d.path}/subdir");
created.createSync();
Expect.isTrue(created.existsSync());
created.deleteSync();
Expect.isFalse(created.existsSync());
d.deleteSync();
Expect.isFalse(d.existsSync());
}
static void testCreateTemp([String template = ""]) {
var port = new ReceivePort();
Directory dir = new Directory(template);
Future.wait([dir.createTemp(), dir.createTemp()])
.then((tempDirs) {
Expect.notEquals(tempDirs[0].path, tempDirs[1].path);
for (Directory t in tempDirs) {
Expect.isTrue(t.existsSync());
t.deleteSync();
Expect.isFalse(t.existsSync());
}
port.close();
});
}
static void testCreateTempTemplate() {
if (new Directory("/tmp").existsSync()) {
testCreateTemp("/tmp/dart_temp_dir_");
}
}
static void testCreateDeleteTemp() {
new Directory("").createTemp().then((tempDirectory) {
String filename =
"${tempDirectory.path}${Platform.pathSeparator}dart_testfile";
File file = new File(filename);
Expect.isFalse(file.existsSync());
file.create().then((ignore) {
file.exists().then((exists) {
Expect.isTrue(exists);
// Try to delete the directory containing the file - should throw.
Expect.throws(tempDirectory.deleteSync);
Expect.isTrue(tempDirectory.existsSync());
// Delete the file, and then delete the directory.
file.delete().then((ignore) {
tempDirectory.deleteSync();
Expect.isFalse(tempDirectory.existsSync());
});
});
});
});
}
static void testCurrent() {
Directory current = new Directory.current();
if (Platform.operatingSystem != "windows") {
Expect.equals("/", current.path.substring(0, 1));
}
}
static void testFromPath() {
var name = new File('.').fullPathSync();
Directory current1 = new Directory(name);
var path = new Path(name);
Directory current2 = new Directory.fromPath(path);
Expect.equals(current1.path, current2.path);
Expect.isTrue(current1.existsSync());
}
static void testMain() {
testListing();
testListNonExistent();
testListTooLongName();
testDeleteNonExistent();
testDeleteTooLongName();
testDeleteNonExistentSync();
testDeleteTooLongNameSync();
testExistsCreateDelete();
testExistsCreateDeleteSync();
testCreateTemp();
testCreateDeleteTemp();
testCurrent();
testFromPath();
}
}
class NestedTempDirectoryTest {
List<Directory> createdDirectories;
Directory current;
NestedTempDirectoryTest.run()
: createdDirectories = new List<Directory>() {
new Directory("").createTemp().then(createPhaseCallback);
}
void createPhaseCallback(temp) {
createdDirectories.add(temp);
int nestingDepth = 6;
var os = Platform.operatingSystem;
if (os == "windows") nestingDepth = 2;
if (createdDirectories.length < nestingDepth) {
temp = new Directory(
'${temp.path}/nested_temp_dir_${createdDirectories.length}_');
temp.createTemp().then(createPhaseCallback);
} else {
deletePhaseCallback();
}
}
void deletePhaseCallback() {
if (!createdDirectories.isEmpty) {
current = createdDirectories.removeLast();
current.deleteSync();
deletePhaseCallback();
}
}
static void testMain() {
new NestedTempDirectoryTest.run();
new NestedTempDirectoryTest.run();
}
}
String illegalTempDirectoryLocation() {
// Determine a platform specific illegal location for a temporary directory.
var os = Platform.operatingSystem;
if (os == "linux" || os == "macos") {
return "/dev/zero/";
}
if (os == "windows") {
return "*";
}
return null;
}
testCreateTempErrorSync() {
var location = illegalTempDirectoryLocation();
if (location != null) {
Expect.throws(new Directory(location).createTempSync,
(e) => e is DirectoryIOException);
}
}
testCreateTempError() {
var location = illegalTempDirectoryLocation();
if (location == null) return;
var port = new ReceivePort();
var future = new Directory(location).createTemp();
future.catchError((e) => port.close());
}
testCreateExistingSync() {
// Test that creating an existing directory succeeds.
var d = new Directory('');
var temp = d.createTempSync();
var subDir = new Directory('${temp.path}/flaf');
Expect.isFalse(subDir.existsSync());
subDir.createSync();
Expect.isTrue(subDir.existsSync());
subDir.createSync();
Expect.isTrue(subDir.existsSync());
temp.deleteSync(recursive: true);
}
testCreateExisting() {
// Test that creating an existing directory succeeds.
var port = new ReceivePort();
var d = new Directory('');
d.createTemp().then((temp) {
var subDir = new Directory('${temp.path}/flaf');
subDir.exists().then((dirExists) {
Expect.isFalse(dirExists);
subDir.create().then((_) {
subDir.exists().then((dirExists) {
Expect.isTrue(dirExists);
subDir.create().then((_) {
subDir.exists().then((dirExists) {
Expect.isTrue(dirExists);
temp.delete(recursive: true).then((_) {
port.close();
});
});
});
});
});
});
});
}
testCreateDirExistingFileSync() {
// Test that creating an existing directory succeeds.
var d = new Directory('');
var temp = d.createTempSync();
var path = '${temp.path}/flaf';
var file = new File(path);
file.createSync();
Expect.isTrue(file.existsSync());
Expect.throws(new Directory(path).createSync,
(e) => e is DirectoryIOException);
temp.deleteSync(recursive: true);
}
testCreateDirExistingFile() {
// Test that creating an existing directory succeeds.
var port = new ReceivePort();
var d = new Directory('');
d.createTemp().then((temp) {
var path = '${temp.path}/flaf';
var file = new File(path);
var subDir = new Directory(path);
file.create().then((_) {
subDir.create()
.then((_) { Expect.fail("dir create should fail on existing file"); })
.catchError((e) {
Expect.isTrue(e.error is DirectoryIOException);
temp.delete(recursive: true).then((_) {
port.close();
});
});
});
});
}
testCreateRecursiveSync() {
var temp = new Directory('').createTempSync();
var d = new Directory('${temp.path}/a/b/c');
d.createSync(recursive: true);
Expect.isTrue(new Directory('${temp.path}/a').existsSync());
Expect.isTrue(new Directory('${temp.path}/a/b').existsSync());
Expect.isTrue(new Directory('${temp.path}/a/b/c').existsSync());
temp.deleteSync(recursive: true);
}
testCreateRecursive() {
var port = new ReceivePort();
new Directory('').createTemp().then((temp) {
var d = new Directory('${temp.path}/a/b/c');
d.create(recursive: true).then((_) {
Expect.isTrue(new Directory('${temp.path}/a').existsSync());
Expect.isTrue(new Directory('${temp.path}/a/b').existsSync());
Expect.isTrue(new Directory('${temp.path}/a/b/c').existsSync());
temp.deleteSync(recursive: true);
port.close();
});
});
}
testRename() {
var d = new Directory('');
var temp1 = d.createTempSync();
var temp2 = d.createTempSync();
var temp3 = temp1.renameSync(temp2.path);
Expect.isFalse(temp1.existsSync());
Expect.isTrue(temp2.existsSync());
Expect.equals(temp3.path, temp2.path);
temp2.rename(temp1.path).then((temp4) {
Expect.isFalse(temp3.existsSync());
Expect.isFalse(temp2.existsSync());
Expect.isTrue(temp1.existsSync());
Expect.isTrue(temp4.existsSync());
Expect.equals(temp1.path, temp4.path);
temp1.deleteSync(recursive: true);
});
}
main() {
DirectoryTest.testMain();
NestedTempDirectoryTest.testMain();
testCreateTempErrorSync();
testCreateTempError();
testCreateExistingSync();
testCreateExisting();
testCreateDirExistingFileSync();
testCreateDirExistingFile();
testCreateRecursive();
testCreateRecursiveSync();
testRename();
}