mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:19:48 +00:00
fb12564ecb
Change-Id: Id5987dfd9d6249c3a5bde57a92ace1f810f6aa60 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305460 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com> Auto-Submit: Paul Berry <paulberry@google.com>
347 lines
10 KiB
Dart
347 lines
10 KiB
Dart
// Copyright (c) 2016, 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.
|
|
// SharedOptions=--supermixin
|
|
|
|
library front_end.test.memory_file_system_test;
|
|
|
|
import 'dart:convert';
|
|
import 'dart:io' as io;
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:front_end/src/api_prototype/file_system.dart'
|
|
show FileSystemException;
|
|
import 'package:front_end/src/api_prototype/memory_file_system.dart';
|
|
import 'package:path/path.dart' as pathos;
|
|
import 'package:test/test.dart';
|
|
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|
|
|
void main() {
|
|
defineReflectiveSuite(() {
|
|
defineReflectiveTests(MemoryFileSystemTestNative);
|
|
defineReflectiveTests(MemoryFileSystemTestPosix);
|
|
defineReflectiveTests(MemoryFileSystemTestWindows);
|
|
defineReflectiveTests(FileTest);
|
|
});
|
|
}
|
|
|
|
final Matcher _throwsFileSystemException =
|
|
throwsA(const TypeMatcher<FileSystemException>());
|
|
|
|
@reflectiveTest
|
|
class FileTest extends _BaseTestNative {
|
|
late String path;
|
|
late MemoryFileSystemEntity file;
|
|
|
|
void setUp() {
|
|
_baseSetUp();
|
|
path = join(tempPath, 'file.txt');
|
|
file = entityForPath(path);
|
|
}
|
|
|
|
Future<void> test_createDirectory_doesNotExist() async {
|
|
file.createDirectory();
|
|
expect(await file.exists(), true);
|
|
}
|
|
|
|
Future<void> test_createDirectory_exists_asDirectory() async {
|
|
file.createDirectory();
|
|
file.createDirectory();
|
|
expect(await file.exists(), true);
|
|
}
|
|
|
|
Future<void> test_createDirectory_exists_asFile() async {
|
|
file.writeAsStringSync('');
|
|
await expectLater(file.createDirectory, _throwsFileSystemException);
|
|
}
|
|
|
|
void test_equals_differentPaths() {
|
|
expect(file == entityForPath(join(tempPath, 'file2.txt')), isFalse);
|
|
}
|
|
|
|
void test_equals_samePath() {
|
|
expect(file == entityForPath(join(tempPath, 'file.txt')), isTrue);
|
|
}
|
|
|
|
Future<void> test_exists_directory_exists() async {
|
|
file.createDirectory();
|
|
expect(await file.exists(), true);
|
|
}
|
|
|
|
Future<void> test_exists_doesNotExist() async {
|
|
expect(await file.exists(), false);
|
|
}
|
|
|
|
Future<void> test_exists_file_exists() async {
|
|
file.writeAsStringSync('x');
|
|
expect(await file.exists(), true);
|
|
}
|
|
|
|
void test_hashCode_samePath() {
|
|
expect(file.hashCode, entityForPath(join(tempPath, 'file.txt')).hashCode);
|
|
}
|
|
|
|
void test_path() {
|
|
expect(file.uri, context.toUri(path));
|
|
}
|
|
|
|
Future<void> test_readAsBytes_badUtf8() async {
|
|
// A file containing invalid UTF-8 can still be read as raw bytes.
|
|
List<int> bytes = [0xc0, 0x40]; // Invalid UTF-8
|
|
file.writeAsBytesSync(bytes);
|
|
expect(await file.readAsBytes(), bytes);
|
|
}
|
|
|
|
Future<void> test_readAsBytes_doesNotExist() async {
|
|
await expectLater(file.readAsBytes, _throwsFileSystemException);
|
|
}
|
|
|
|
Future<void> test_readAsBytes_exists() async {
|
|
var s = 'contents';
|
|
file.writeAsStringSync(s);
|
|
expect(await file.readAsBytes(), utf8.encode(s));
|
|
}
|
|
|
|
Future<void> test_readAsString_badUtf8() async {
|
|
file.writeAsBytesSync([0xc0, 0x40]); // Invalid UTF-8
|
|
await expectLater(file.readAsString, _throwsFileSystemException);
|
|
}
|
|
|
|
Future<void> test_readAsString_doesNotExist() async {
|
|
await expectLater(file.readAsString, _throwsFileSystemException);
|
|
}
|
|
|
|
Future<void> test_readAsString_exists() async {
|
|
var s = 'contents';
|
|
file.writeAsStringSync(s);
|
|
expect(await file.readAsString(), s);
|
|
}
|
|
|
|
Future<void> test_readAsString_utf8() async {
|
|
file.writeAsBytesSync([0xe2, 0x82, 0xac]); // Unicode € symbol, in UTF-8
|
|
expect(await file.readAsString(), '\u20ac');
|
|
}
|
|
|
|
Future<void> test_writeAsBytesSync_directory() async {
|
|
file.createDirectory();
|
|
await expectLater(
|
|
() => file.writeAsBytesSync([0]), _throwsFileSystemException);
|
|
}
|
|
|
|
Future<void> test_writeAsBytesSync_modifyAfterRead() async {
|
|
// For efficiency we do not make defensive copies.
|
|
file.writeAsBytesSync([1]);
|
|
(await file.readAsBytes())[0] = 2;
|
|
expect(await file.readAsBytes(), [2]);
|
|
}
|
|
|
|
Future<void> test_writeAsBytesSync_modifyAfterWrite_Uint8List() async {
|
|
// For efficiency we do not make defensive copies.
|
|
var bytes = new Uint8List.fromList([1]);
|
|
file.writeAsBytesSync(bytes);
|
|
bytes[0] = 2;
|
|
expect(await file.readAsBytes(), [2]);
|
|
}
|
|
|
|
Future<void> test_writeAsBytesSync_modifyAfterWrite() async {
|
|
// For efficiency we generally do not make defensive copies, but on the
|
|
// other hrand we keep everything as `Uint8List`s internally, so in this
|
|
// case a copy is actually made.
|
|
var bytes = [1];
|
|
file.writeAsBytesSync(bytes);
|
|
bytes[0] = 2;
|
|
expect(await file.readAsBytes(), [1]);
|
|
}
|
|
|
|
Future<void> test_writeAsBytesSync_overwrite() async {
|
|
file.writeAsBytesSync([1]);
|
|
file.writeAsBytesSync([2]);
|
|
expect(await file.readAsBytes(), [2]);
|
|
}
|
|
|
|
Future<void> test_writeAsStringSync_directory() async {
|
|
file.createDirectory();
|
|
await expectLater(
|
|
() => file.writeAsStringSync(''), _throwsFileSystemException);
|
|
}
|
|
|
|
Future<void> test_writeAsStringSync_overwrite() async {
|
|
file.writeAsStringSync('first');
|
|
file.writeAsStringSync('second');
|
|
expect(await file.readAsString(), 'second');
|
|
}
|
|
|
|
Future<void> test_writeAsStringSync_utf8() async {
|
|
file.writeAsStringSync('\u20ac'); // Unicode € symbol
|
|
expect(await file.readAsBytes(), [0xe2, 0x82, 0xac]);
|
|
}
|
|
}
|
|
|
|
mixin MemoryFileSystemTestMixin implements _BaseTest {
|
|
late Uri tempUri;
|
|
|
|
void setUp() {
|
|
_baseSetUp();
|
|
tempUri = context.toUri(tempPath);
|
|
}
|
|
|
|
void test_currentDirectory_trailingSlash() {
|
|
// The currentDirectory should already end in a trailing slash.
|
|
expect(fileSystem.currentDirectory.path, endsWith('/'));
|
|
// A trailing slash should automatically be appended when creating a
|
|
// MemoryFileSystem.
|
|
var path = fileSystem.currentDirectory.path;
|
|
var currentDirectoryWithoutSlash = fileSystem.currentDirectory
|
|
.replace(path: path.substring(0, path.length - 1));
|
|
expect(new MemoryFileSystem(currentDirectoryWithoutSlash).currentDirectory,
|
|
fileSystem.currentDirectory);
|
|
// If the currentDirectory supplied to the MemoryFileSystem constructor
|
|
// already has a trailing slash, no further trailing slash should be added.
|
|
expect(new MemoryFileSystem(fileSystem.currentDirectory).currentDirectory,
|
|
fileSystem.currentDirectory);
|
|
}
|
|
|
|
void test_entityForPath_absolutize() {
|
|
expect(entityForPath('file.txt').uri,
|
|
fileSystem.currentDirectory.resolve('file.txt'));
|
|
}
|
|
|
|
void test_entityForPath_normalize_dot() {
|
|
expect(entityForPath(join(tempPath, '.', 'file.txt')).uri,
|
|
Uri.parse('$tempUri/file.txt'));
|
|
}
|
|
|
|
void test_entityForPath_normalize_dotDot() {
|
|
expect(entityForPath(join(tempPath, 'foo', '..', 'file.txt')).uri,
|
|
Uri.parse('$tempUri/file.txt'));
|
|
}
|
|
|
|
void test_entityForUri() {
|
|
expect(fileSystem.entityForUri(Uri.parse('$tempUri/file.txt')).uri,
|
|
Uri.parse('$tempUri/file.txt'));
|
|
}
|
|
|
|
Future<void> test_entityForUri_fileUri_relative() async {
|
|
// A weird quirk of the Uri class is that it doesn't seem possible to create
|
|
// a `file:` uri with a relative path, no matter how many slashes you use or
|
|
// if you populate the fields directly. But just to be certain, try to do
|
|
// so, and make that `file:` uris with relative paths are rejected.
|
|
for (var uri in <Uri>[
|
|
new Uri(scheme: 'file', path: 'file.txt'),
|
|
Uri.parse('file:file.txt'),
|
|
Uri.parse('file:/file.txt'),
|
|
Uri.parse('file://file.txt'),
|
|
Uri.parse('file:///file.txt')
|
|
]) {
|
|
if (!uri.path.startsWith('/')) {
|
|
await expectLater(() => fileSystem.entityForUri(uri),
|
|
throwsA(const TypeMatcher<Error>()));
|
|
}
|
|
}
|
|
}
|
|
|
|
void test_entityForUri_nonFileUri() {
|
|
var uri = Uri.parse('package:foo/bar.dart');
|
|
expect(fileSystem.entityForUri(uri).uri, uri);
|
|
}
|
|
|
|
void test_entityForUri_normalize_dot() {
|
|
expect(fileSystem.entityForUri(Uri.parse('$tempUri/./file.txt')).uri,
|
|
Uri.parse('$tempUri/file.txt'));
|
|
}
|
|
|
|
void test_entityForUri_normalize_dotDot() {
|
|
expect(fileSystem.entityForUri(Uri.parse('$tempUri/foo/../file.txt')).uri,
|
|
Uri.parse('$tempUri/file.txt'));
|
|
}
|
|
}
|
|
|
|
@reflectiveTest
|
|
class MemoryFileSystemTestNative extends _BaseTestNative
|
|
with MemoryFileSystemTestMixin {}
|
|
|
|
@reflectiveTest
|
|
class MemoryFileSystemTestPosix extends _BaseTestPosix
|
|
with MemoryFileSystemTestMixin {}
|
|
|
|
@reflectiveTest
|
|
class MemoryFileSystemTestWindows extends _BaseTestWindows
|
|
with MemoryFileSystemTestMixin {}
|
|
|
|
abstract class _BaseTest {
|
|
pathos.Context get context;
|
|
MemoryFileSystem get fileSystem;
|
|
|
|
String get tempPath;
|
|
|
|
MemoryFileSystemEntity entityForPath(String path) =>
|
|
fileSystem.entityForUri(context.toUri(path));
|
|
|
|
String join(String path1, String path2, [String path3, String path4]);
|
|
|
|
void _baseSetUp();
|
|
}
|
|
|
|
class _BaseTestNative extends _BaseTest {
|
|
@override
|
|
final pathos.Context context = pathos.context;
|
|
|
|
@override
|
|
late MemoryFileSystem fileSystem;
|
|
|
|
@override
|
|
late String tempPath;
|
|
|
|
@override
|
|
String join(String path1, String path2, [String? path3, String? path4]) =>
|
|
pathos.join(path1, path2, path3, path4);
|
|
|
|
@override
|
|
void _baseSetUp() {
|
|
tempPath = pathos.join(io.Directory.systemTemp.path, 'test_file_system');
|
|
fileSystem = new MemoryFileSystem(pathos.toUri(io.Directory.current.path));
|
|
}
|
|
}
|
|
|
|
class _BaseTestPosix extends _BaseTest {
|
|
@override
|
|
final pathos.Context context = pathos.posix;
|
|
|
|
@override
|
|
late MemoryFileSystem fileSystem;
|
|
|
|
@override
|
|
late String tempPath;
|
|
|
|
@override
|
|
String join(String path1, String path2, [String? path3, String? path4]) =>
|
|
pathos.posix.join(path1, path2, path3, path4);
|
|
|
|
@override
|
|
void _baseSetUp() {
|
|
tempPath = '/test_file_system';
|
|
fileSystem = new MemoryFileSystem(Uri.parse('file:///cwd'));
|
|
}
|
|
}
|
|
|
|
class _BaseTestWindows extends _BaseTest {
|
|
@override
|
|
final pathos.Context context = pathos.windows;
|
|
|
|
@override
|
|
late MemoryFileSystem fileSystem;
|
|
|
|
@override
|
|
late String tempPath;
|
|
|
|
@override
|
|
String join(String path1, String path2, [String? path3, String? path4]) =>
|
|
pathos.windows.join(path1, path2, path3, path4);
|
|
|
|
@override
|
|
void _baseSetUp() {
|
|
tempPath = r'c:\test_file_system';
|
|
fileSystem = new MemoryFileSystem(Uri.parse('file:///c:/cwd'));
|
|
}
|
|
}
|