blob: 58ddf69d064e1f2ec6785d3f5cc0254ae11410e6 [file] [log] [blame]
// Copyright (c) 2013, 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.
//
// Dart test program for testing FileSystemEntity.resolveSymbolicLinks
// @dart = 2.9
import "package:expect/expect.dart";
import "package:path/path.dart";
import "package:async_helper/async_helper.dart";
import 'dart:async';
import 'dart:io';
main() {
String testsDir = Directory.current.uri.resolve('tests').toFilePath();
// All of these tests test that resolveSymbolicLinks gives a path
// that points to the same place as the original, and that it removes
// all links, .., and . segments, and that it produces an absolute path.
asyncTest(() => testFile(join(
testsDir, 'standalone_2', 'io', 'resolve_symbolic_links_test.dart')));
asyncTest(() => testFile(join(testsDir, 'standalone_2', 'io', '..', 'io',
'resolve_symbolic_links_test.dart')));
asyncTest(() => testDir(join(testsDir, 'standalone_2', 'io')));
asyncTest(() => testDir(join(testsDir, 'lib_2', '..', 'standalone_2', 'io')));
// Test a relative path.
if (Platform.isWindows) {
asyncTest(() => testFile(join('\\\\?\\$testsDir', 'standalone_2', 'io',
'resolve_symbolic_links_test.dart')));
asyncTest(() => testDir('\\\\?\\$testsDir'));
}
asyncTest(() => Directory.systemTemp
.createTemp('dart_resolve_symbolic_links')
.then((tempDir) {
String temp = tempDir.path;
return makeEntities(temp)
.then((_) => Future.wait([
testFile(join(temp, 'dir1', 'file1')),
testFile(join(temp, 'link1', 'file2')),
testDir(join(temp, 'dir1', 'dir2', '..', '.', '..', 'dir1')),
testDir(join(temp, 'dir1', 'dir2', '..', '.', '..', 'dir1')),
testLink(join(temp, 'link1')),
testDir('.')
]))
.then((_) {
if (Platform.isWindows) {
// Windows applies '..' to a link without resolving the link first.
return Future.wait([
testFile(join(
temp, 'dir1', '..', 'link1', '..', 'dir1', 'dir2', 'file2')),
testDir(join(temp, 'dir1', '..', 'link1', '..', 'dir1')),
testLink(join(temp, 'link1', '..', 'link1'))
]);
} else {
// Non-Windows platforms resolve the link before adding the '..'.
return Future.wait([
testFile(
join(temp, 'dir1', '..', 'link1', '..', 'dir2', 'file2')),
testDir(join(temp, 'dir1', '..', 'link1', '..', 'dir2')),
testLink(join(temp, 'link1', '..', '..', 'link1'))
]);
}
}).then((_) {
Directory.current = temp;
return Future.wait([
testFile('dir1/dir2/file2'), // Test forward slashes on Windows too.
testFile('link1/file2'),
testFile(join('dir1', '..', 'dir1', '.', 'file1')),
testDir('.'),
testLink('link1')
]);
}).then((_) {
Directory.current = 'link1';
if (Platform.isWindows) {
return Future.wait([
testFile('file2'),
// Windows applies '..' to a link without resolving the link first.
testFile('..\\dir1\\file1'),
testLink('.'),
testDir('..'),
testLink('..\\link1')
]);
} else {
return Future.wait([
testFile('file2'),
// On non-Windows the link is changed to dir1/dir2 before .. happens.
testFile('../dir2/file2'),
testDir('.'),
testDir('..'),
testLink('../../link1')
]);
}
}).whenComplete(() {
Directory.current = testsDir;
tempDir.delete(recursive: true);
});
}));
}
Future makeEntities(String temp) {
return new Directory(join(temp, 'dir1', 'dir2'))
.create(recursive: true)
.then((_) => new File(join(temp, 'dir1', 'dir2', 'file2')).create())
.then((_) => new File(join(temp, 'dir1', 'file1')).create())
.then((_) =>
new Link(join(temp, 'link1')).create(join(temp, 'dir1', 'dir2')));
}
Future testFile(String name) {
// We test that f.resolveSymbolicLinks points to the same place
// as f, because the actual resolved path is not easily predictable.
// The location of the temp directory varies from system to system,
// and its path includes symbolic links on some systems.
//Expect.isTrue(FileSystemEntity.identicalSync(name,
// new File(name).resolveSymbolicLinksSync()));
return new File(name).resolveSymbolicLinks().then((String resolved) {
//Expect.isTrue(FileSystemEntity.identicalSync(name, resolved));
Expect.isTrue(isAbsolute(resolved));
// Test that resolveSymbolicLinks removes all links, .., and . segments.
Expect.isFalse(resolved.contains('..'));
Expect.isFalse(resolved.contains('./'));
Expect.isFalse(resolved.contains('link1'));
});
}
Future testDir(String name) {
Expect.isTrue(FileSystemEntity.identicalSync(
name, new Directory(name).resolveSymbolicLinksSync()));
return new Directory(name).resolveSymbolicLinks().then((String resolved) {
Expect.isTrue(FileSystemEntity.identicalSync(name, resolved));
Expect.isTrue(isAbsolute(resolved));
// Test that resolveSymbolicLinks removes all links, .., and . segments.
Expect.isFalse(resolved.contains('..'));
Expect.isFalse(resolved.contains('./'));
Expect.isFalse(resolved.contains('link1'));
});
}
Future testLink(String name) {
Expect.isFalse(FileSystemEntity.identicalSync(
name, new Link(name).resolveSymbolicLinksSync()));
Expect.isTrue(FileSystemEntity.identicalSync(
new Link(name).targetSync(), new Link(name).resolveSymbolicLinksSync()));
return new Link(name).resolveSymbolicLinks().then((String resolved) {
Expect.isFalse(FileSystemEntity.identicalSync(name, resolved));
Expect.isTrue(isAbsolute(resolved));
// Test that resolveSymbolicLinks removes all links, .., and . segments.
Expect.isFalse(resolved.contains('..'));
Expect.isFalse(resolved.contains('./'));
Expect.isFalse(resolved.contains('link1'));
return new Link(name)
.target()
.then((targetName) => FileSystemEntity.identical(targetName, resolved))
.then((identical) => Expect.isTrue(identical));
});
}