mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +00:00
Add implementations of the front end FileSystem API.
This required some small changes to the API contract. Note that the tests use supermixins. I'm assuming that supermixin functionality will be available on all platforms by the time this is needed. If not, I will be happy to rewrite them. R=scheglov@google.com, sigmund@google.com Review URL: https://codereview.chromium.org/2471283002 .
This commit is contained in:
parent
4682ea9953
commit
28b6a1f7ea
|
@ -35,6 +35,7 @@ dartdoc:third_party/pkg/dartdoc/lib
|
|||
dev_compiler:pkg/dev_compiler/lib
|
||||
expect:pkg/expect/lib
|
||||
fixnum:third_party/pkg/fixnum/lib
|
||||
front_end:pkg/front_end/lib
|
||||
func:third_party/pkg/func/lib
|
||||
glob:third_party/pkg/glob/lib
|
||||
html:third_party/pkg/html/lib
|
||||
|
|
|
@ -31,10 +31,9 @@ abstract class FileSystem {
|
|||
|
||||
/// Returns a [FileSystemEntity] corresponding to the given [uri].
|
||||
///
|
||||
/// Uses of `..` and `.` in the URI are normalized before returning. Relative
|
||||
/// paths are also converted to absolute paths.
|
||||
/// Uses of `..` and `.` in the URI are normalized before returning.
|
||||
///
|
||||
/// If [uri] is not a `file:` URI, an [Error] will be thrown.
|
||||
/// If [uri] is not an absolute `file:` URI, an [Error] will be thrown.
|
||||
///
|
||||
/// Does not check whether a file or folder exists at the given location.
|
||||
FileSystemEntity entityForUri(Uri uri);
|
||||
|
@ -42,6 +41,9 @@ abstract class FileSystem {
|
|||
|
||||
/// Abstract representation of a file system entity that may or may not exist.
|
||||
///
|
||||
/// Instances of this class have suitable implementations of equality tests and
|
||||
/// hashCode.
|
||||
///
|
||||
/// Not intended to be implemented or extended by clients.
|
||||
abstract class FileSystemEntity {
|
||||
/// Returns the absolute normalized path represented by this file system
|
||||
|
@ -67,7 +69,7 @@ abstract class FileSystemEntity {
|
|||
/// The file is assumed to be UTF-8 encoded.
|
||||
///
|
||||
/// If an error occurs while attempting to read the file (e.g. because no such
|
||||
/// file exists, or the entity is a directory), the future is completed with
|
||||
/// an [Exception].
|
||||
/// file exists, the entity is a directory, or the file is not valid UTF-8),
|
||||
/// the future is completed with an [Exception].
|
||||
Future<String> readAsString();
|
||||
}
|
||||
|
|
100
pkg/front_end/lib/memory_file_system.dart
Normal file
100
pkg/front_end/lib/memory_file_system.dart
Normal file
|
@ -0,0 +1,100 @@
|
|||
// 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.
|
||||
|
||||
library front_end.memory_file_system;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import 'file_system.dart';
|
||||
|
||||
/// Concrete implementation of [FileSystem] which performs its operations on an
|
||||
/// in-memory virtual file system.
|
||||
///
|
||||
/// Not intended to be implemented or extended by clients.
|
||||
class MemoryFileSystem implements FileSystem {
|
||||
@override
|
||||
final p.Context context;
|
||||
|
||||
final Map<String, Uint8List> _files = {};
|
||||
|
||||
/// The "current directory" in the in-memory virtual file system.
|
||||
///
|
||||
/// This is used to convert relative paths to absolute paths.
|
||||
String currentDirectory;
|
||||
|
||||
MemoryFileSystem(this.context, this.currentDirectory);
|
||||
|
||||
@override
|
||||
MemoryFileSystemEntity entityForPath(String path) =>
|
||||
new MemoryFileSystemEntity._(
|
||||
this, context.normalize(context.join(currentDirectory, path)));
|
||||
|
||||
@override
|
||||
MemoryFileSystemEntity entityForUri(Uri uri) {
|
||||
if (uri.scheme != 'file') throw new ArgumentError('File URI expected');
|
||||
// Note: we don't have to verify that the URI's path is absolute, because
|
||||
// URIs with non-empty schemes always have absolute paths.
|
||||
return entityForPath(context.fromUri(uri));
|
||||
}
|
||||
}
|
||||
|
||||
/// Concrete implementation of [FileSystemEntity] for use by
|
||||
/// [MemoryFileSystem].
|
||||
class MemoryFileSystemEntity implements FileSystemEntity {
|
||||
final MemoryFileSystem _fileSystem;
|
||||
|
||||
@override
|
||||
final String path;
|
||||
|
||||
MemoryFileSystemEntity._(this._fileSystem, this.path);
|
||||
|
||||
@override
|
||||
int get hashCode => path.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is MemoryFileSystemEntity &&
|
||||
other.path == path &&
|
||||
identical(other._fileSystem, _fileSystem);
|
||||
|
||||
@override
|
||||
Future<List<int>> readAsBytes() async {
|
||||
List<int> contents = _fileSystem._files[path];
|
||||
if (contents != null) {
|
||||
return contents.toList();
|
||||
}
|
||||
throw new Exception('File does not exist');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> readAsString() async {
|
||||
List<int> contents = await readAsBytes();
|
||||
return UTF8.decode(contents);
|
||||
}
|
||||
|
||||
/// Writes the given raw bytes to this file system entity.
|
||||
///
|
||||
/// If no file exists, one is created. If a file exists already, it is
|
||||
/// overwritten.
|
||||
void writeAsBytesSync(List<int> bytes) {
|
||||
_fileSystem._files[path] = new Uint8List.fromList(bytes);
|
||||
}
|
||||
|
||||
/// Writes the given string to this file system entity.
|
||||
///
|
||||
/// The string is encoded as UTF-8.
|
||||
///
|
||||
/// If no file exists, one is created. If a file exists already, it is
|
||||
/// overwritten.
|
||||
void writeAsStringSync(String s) {
|
||||
// Note: the return type of UTF8.encode is List<int>, but in practice it
|
||||
// always returns Uint8List. We rely on that for efficiency, so that we
|
||||
// don't have to make an extra copy.
|
||||
_fileSystem._files[path] = UTF8.encode(s) as Uint8List;
|
||||
}
|
||||
}
|
59
pkg/front_end/lib/physical_file_system.dart
Normal file
59
pkg/front_end/lib/physical_file_system.dart
Normal file
|
@ -0,0 +1,59 @@
|
|||
// 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.
|
||||
|
||||
library front_end.physical_file_system;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io' as io;
|
||||
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import 'file_system.dart';
|
||||
|
||||
/// Concrete implementation of [FileSystem] which performs its operations using
|
||||
/// I/O.
|
||||
///
|
||||
/// Not intended to be implemented or extended by clients.
|
||||
class PhysicalFileSystem implements FileSystem {
|
||||
static final PhysicalFileSystem instance = new PhysicalFileSystem._();
|
||||
|
||||
PhysicalFileSystem._();
|
||||
|
||||
@override
|
||||
p.Context get context => p.context;
|
||||
|
||||
@override
|
||||
FileSystemEntity entityForPath(String path) =>
|
||||
new _PhysicalFileSystemEntity(context.normalize(context.absolute(path)));
|
||||
|
||||
@override
|
||||
FileSystemEntity entityForUri(Uri uri) {
|
||||
if (uri.scheme != 'file') throw new ArgumentError('File URI expected');
|
||||
// Note: we don't have to verify that the URI's path is absolute, because
|
||||
// URIs with non-empty schemes always have absolute paths.
|
||||
return entityForPath(context.fromUri(uri));
|
||||
}
|
||||
}
|
||||
|
||||
/// Concrete implementation of [FileSystemEntity] for use by
|
||||
/// [PhysicalFileSystem].
|
||||
class _PhysicalFileSystemEntity implements FileSystemEntity {
|
||||
@override
|
||||
final String path;
|
||||
|
||||
_PhysicalFileSystemEntity(this.path);
|
||||
|
||||
@override
|
||||
int get hashCode => path.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is _PhysicalFileSystemEntity && other.path == path;
|
||||
|
||||
@override
|
||||
Future<List<int>> readAsBytes() => new io.File(path).readAsBytes();
|
||||
|
||||
@override
|
||||
Future<String> readAsString() => new io.File(path).readAsString();
|
||||
}
|
|
@ -10,10 +10,12 @@ dependencies:
|
|||
path: '^1.3.9'
|
||||
source_span: '^1.2.3'
|
||||
dev_dependencies:
|
||||
package_config: '^1.0.0'
|
||||
# TODO(sigmund): update to a version constraint once we roll the latest kernel
|
||||
# to the repo.
|
||||
kernel: {path: ../../third_party/pkg/kernel}
|
||||
package_config: '^1.0.0'
|
||||
test: ^0.12.0
|
||||
test_reflective_loader: ^0.1.0
|
||||
# TODO(sigmund): remove once kernel is moved into the sdk repo.
|
||||
dependency_overrides:
|
||||
analyzer: '^0.29.0'
|
||||
|
|
259
pkg/front_end/test/memory_file_system_test.dart
Normal file
259
pkg/front_end/test/memory_file_system_test.dart
Normal file
|
@ -0,0 +1,259 @@
|
|||
// 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 'package:front_end/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';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(MemoryFileSystemTestNative);
|
||||
defineReflectiveTests(MemoryFileSystemTestPosix);
|
||||
defineReflectiveTests(MemoryFileSystemTestWindows);
|
||||
defineReflectiveTests(FileTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class FileTest extends _BaseTestNative {
|
||||
String path;
|
||||
MemoryFileSystemEntity file;
|
||||
|
||||
setUp() {
|
||||
super.setUp();
|
||||
path = join(tempPath, 'file.txt');
|
||||
file = fileSystem.entityForPath(path);
|
||||
}
|
||||
|
||||
test_equals_differentPaths() {
|
||||
expect(
|
||||
file == fileSystem.entityForPath(join(tempPath, 'file2.txt')), isFalse);
|
||||
}
|
||||
|
||||
test_equals_samePath() {
|
||||
expect(
|
||||
file == fileSystem.entityForPath(join(tempPath, 'file.txt')), isTrue);
|
||||
}
|
||||
|
||||
test_hashCode_samePath() {
|
||||
expect(file.hashCode,
|
||||
fileSystem.entityForPath(join(tempPath, 'file.txt')).hashCode);
|
||||
}
|
||||
|
||||
test_path() {
|
||||
expect(file.path, path);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
test_readAsBytes_doesNotExist() {
|
||||
expect(file.readAsBytes(), throwsException);
|
||||
}
|
||||
|
||||
test_readAsBytes_exists() async {
|
||||
var s = 'contents';
|
||||
file.writeAsStringSync(s);
|
||||
expect(await file.readAsBytes(), UTF8.encode(s));
|
||||
}
|
||||
|
||||
test_readAsString_badUtf8() {
|
||||
file.writeAsBytesSync([0xc0, 0x40]); // Invalid UTF-8
|
||||
expect(file.readAsString(), throwsException);
|
||||
}
|
||||
|
||||
test_readAsString_doesNotExist() {
|
||||
expect(file.readAsString(), throwsException);
|
||||
}
|
||||
|
||||
test_readAsString_exists() async {
|
||||
var s = 'contents';
|
||||
file.writeAsStringSync(s);
|
||||
expect(await file.readAsString(), s);
|
||||
}
|
||||
|
||||
test_readAsString_utf8() async {
|
||||
file.writeAsBytesSync([0xe2, 0x82, 0xac]); // Unicode € symbol, in UTF-8
|
||||
expect(await file.readAsString(), '\u20ac');
|
||||
}
|
||||
|
||||
test_writeAsBytesSync_modifyAfterRead() async {
|
||||
file.writeAsBytesSync([1]);
|
||||
(await file.readAsBytes())[0] = 2;
|
||||
expect(await file.readAsBytes(), [1]);
|
||||
}
|
||||
|
||||
test_writeAsBytesSync_modifyAfterWrite() async {
|
||||
var bytes = [1];
|
||||
file.writeAsBytesSync(bytes);
|
||||
bytes[0] = 2;
|
||||
expect(await file.readAsBytes(), [1]);
|
||||
}
|
||||
|
||||
test_writeAsBytesSync_overwrite() async {
|
||||
file.writeAsBytesSync([1]);
|
||||
file.writeAsBytesSync([2]);
|
||||
expect(await file.readAsBytes(), [2]);
|
||||
}
|
||||
|
||||
test_writeAsStringSync_overwrite() async {
|
||||
file.writeAsStringSync('first');
|
||||
file.writeAsStringSync('second');
|
||||
expect(await file.readAsString(), 'second');
|
||||
}
|
||||
|
||||
test_writeAsStringSync_utf8() async {
|
||||
file.writeAsStringSync('\u20ac'); // Unicode € symbol
|
||||
expect(await file.readAsBytes(), [0xe2, 0x82, 0xac]);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class MemoryFileSystemTestMixin extends _BaseTest {
|
||||
Uri tempUri;
|
||||
|
||||
setUp() {
|
||||
super.setUp();
|
||||
tempUri = fileSystem.context.toUri(tempPath);
|
||||
}
|
||||
|
||||
test_entityForPath() {
|
||||
var path = join(tempPath, 'file.txt');
|
||||
expect(fileSystem.entityForPath(path).path, path);
|
||||
}
|
||||
|
||||
test_entityForPath_absolutize() {
|
||||
expect(fileSystem.entityForPath('file.txt').path,
|
||||
join(fileSystem.currentDirectory, 'file.txt'));
|
||||
}
|
||||
|
||||
test_entityForPath_normalize_dot() {
|
||||
expect(fileSystem.entityForPath(join(tempPath, '.', 'file.txt')).path,
|
||||
join(tempPath, 'file.txt'));
|
||||
}
|
||||
|
||||
test_entityForPath_normalize_dotDot() {
|
||||
expect(
|
||||
fileSystem.entityForPath(join(tempPath, 'foo', '..', 'file.txt')).path,
|
||||
join(tempPath, 'file.txt'));
|
||||
}
|
||||
|
||||
test_entityForUri() {
|
||||
expect(fileSystem.entityForUri(Uri.parse('$tempUri/file.txt')).path,
|
||||
join(tempPath, 'file.txt'));
|
||||
}
|
||||
|
||||
test_entityForUri_bareUri_absolute() {
|
||||
expect(() => fileSystem.entityForUri(Uri.parse('/file.txt')),
|
||||
throwsA(new isInstanceOf<Error>()));
|
||||
}
|
||||
|
||||
test_entityForUri_bareUri_relative() {
|
||||
expect(() => fileSystem.entityForUri(Uri.parse('file.txt')),
|
||||
throwsA(new isInstanceOf<Error>()));
|
||||
}
|
||||
|
||||
test_entityForUri_fileUri_relative() {
|
||||
// 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('/')) {
|
||||
expect(() => fileSystem.entityForUri(uri),
|
||||
throwsA(new isInstanceOf<Error>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_entityForUri_nonFileUri() {
|
||||
expect(() => fileSystem.entityForUri(Uri.parse('package:foo/bar.dart')),
|
||||
throwsA(new isInstanceOf<Error>()));
|
||||
}
|
||||
|
||||
test_entityForUri_normalize_dot() {
|
||||
expect(fileSystem.entityForUri(Uri.parse('$tempUri/./file.txt')).path,
|
||||
join(tempPath, 'file.txt'));
|
||||
}
|
||||
|
||||
test_entityForUri_normalize_dotDot() {
|
||||
expect(fileSystem.entityForUri(Uri.parse('$tempUri/foo/../file.txt')).path,
|
||||
join(tempPath, '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 {
|
||||
MemoryFileSystem get fileSystem;
|
||||
String get tempPath;
|
||||
String join(String path1, String path2, [String path3, String path4]);
|
||||
void setUp();
|
||||
}
|
||||
|
||||
class _BaseTestNative extends _BaseTest {
|
||||
MemoryFileSystem fileSystem;
|
||||
String tempPath;
|
||||
|
||||
String join(String path1, String path2, [String path3, String path4]) =>
|
||||
pathos.join(path1, path2, path3, path4);
|
||||
|
||||
setUp() {
|
||||
tempPath = pathos.join(io.Directory.systemTemp.path, 'test_file_system');
|
||||
fileSystem =
|
||||
new MemoryFileSystem(pathos.context, io.Directory.current.path);
|
||||
}
|
||||
}
|
||||
|
||||
class _BaseTestPosix extends _BaseTest {
|
||||
MemoryFileSystem fileSystem;
|
||||
String tempPath;
|
||||
|
||||
String join(String path1, String path2, [String path3, String path4]) =>
|
||||
pathos.posix.join(path1, path2, path3, path4);
|
||||
|
||||
void setUp() {
|
||||
tempPath = '/test_file_system';
|
||||
fileSystem = new MemoryFileSystem(pathos.posix, '/cwd');
|
||||
}
|
||||
}
|
||||
|
||||
class _BaseTestWindows extends _BaseTest {
|
||||
MemoryFileSystem fileSystem;
|
||||
String tempPath;
|
||||
|
||||
String join(String path1, String path2, [String path3, String path4]) =>
|
||||
pathos.windows.join(path1, path2, path3, path4);
|
||||
|
||||
void setUp() {
|
||||
tempPath = r'c:\test_file_system';
|
||||
fileSystem = new MemoryFileSystem(pathos.windows, r'c:\cwd');
|
||||
}
|
||||
}
|
212
pkg/front_end/test/physical_file_system_test.dart
Normal file
212
pkg/front_end/test/physical_file_system_test.dart
Normal file
|
@ -0,0 +1,212 @@
|
|||
// 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.physical_file_system_test;
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io' as io;
|
||||
|
||||
import 'package:front_end/file_system.dart';
|
||||
import 'package:front_end/physical_file_system.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(PhysicalFileSystemTest);
|
||||
defineReflectiveTests(FileTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class FileTest extends _BaseTest {
|
||||
String path;
|
||||
FileSystemEntity file;
|
||||
|
||||
setUp() {
|
||||
super.setUp();
|
||||
path = p.join(tempPath, 'file.txt');
|
||||
file = PhysicalFileSystem.instance.entityForPath(path);
|
||||
}
|
||||
|
||||
test_equals_differentPaths() {
|
||||
expect(
|
||||
file ==
|
||||
PhysicalFileSystem.instance
|
||||
.entityForPath(p.join(tempPath, 'file2.txt')),
|
||||
isFalse);
|
||||
}
|
||||
|
||||
test_equals_samePath() {
|
||||
expect(
|
||||
file ==
|
||||
PhysicalFileSystem.instance
|
||||
.entityForPath(p.join(tempPath, 'file.txt')),
|
||||
isTrue);
|
||||
}
|
||||
|
||||
test_hashCode_samePath() {
|
||||
expect(
|
||||
file.hashCode,
|
||||
PhysicalFileSystem.instance
|
||||
.entityForPath(p.join(tempPath, 'file.txt'))
|
||||
.hashCode);
|
||||
}
|
||||
|
||||
test_path() {
|
||||
expect(file.path, path);
|
||||
}
|
||||
|
||||
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
|
||||
new io.File(path).writeAsBytesSync(bytes);
|
||||
expect(await file.readAsBytes(), bytes);
|
||||
}
|
||||
|
||||
test_readAsBytes_doesNotExist() {
|
||||
expect(file.readAsBytes(), throwsException);
|
||||
}
|
||||
|
||||
test_readAsBytes_exists() async {
|
||||
var s = 'contents';
|
||||
new io.File(path).writeAsStringSync(s);
|
||||
expect(await file.readAsBytes(), UTF8.encode(s));
|
||||
}
|
||||
|
||||
test_readAsString_badUtf8() {
|
||||
new io.File(path).writeAsBytesSync([0xc0, 0x40]); // Invalid UTF-8
|
||||
expect(file.readAsString(), throwsException);
|
||||
}
|
||||
|
||||
test_readAsString_doesNotExist() {
|
||||
expect(file.readAsString(), throwsException);
|
||||
}
|
||||
|
||||
test_readAsString_exists() async {
|
||||
var s = 'contents';
|
||||
new io.File(path).writeAsStringSync(s);
|
||||
expect(await file.readAsString(), s);
|
||||
}
|
||||
|
||||
test_readAsString_utf8() async {
|
||||
var bytes = [0xe2, 0x82, 0xac]; // Unicode € symbol (in UTF-8)
|
||||
new io.File(path).writeAsBytesSync(bytes);
|
||||
expect(await file.readAsString(), '\u20ac');
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class PhysicalFileSystemTest extends _BaseTest {
|
||||
Uri tempUri;
|
||||
|
||||
setUp() {
|
||||
super.setUp();
|
||||
tempUri = new Uri.directory(tempPath);
|
||||
}
|
||||
|
||||
test_entityForPath() {
|
||||
var path = p.join(tempPath, 'file.txt');
|
||||
expect(PhysicalFileSystem.instance.entityForPath(path).path, path);
|
||||
}
|
||||
|
||||
test_entityForPath_absolutize() {
|
||||
expect(PhysicalFileSystem.instance.entityForPath('file.txt').path,
|
||||
new io.File('file.txt').absolute.path);
|
||||
}
|
||||
|
||||
test_entityForPath_normalize_dot() {
|
||||
expect(
|
||||
PhysicalFileSystem.instance
|
||||
.entityForPath(p.join(tempPath, '.', 'file.txt'))
|
||||
.path,
|
||||
p.join(tempPath, 'file.txt'));
|
||||
}
|
||||
|
||||
test_entityForPath_normalize_dotDot() {
|
||||
expect(
|
||||
PhysicalFileSystem.instance
|
||||
.entityForPath(p.join(tempPath, 'foo', '..', 'file.txt'))
|
||||
.path,
|
||||
p.join(tempPath, 'file.txt'));
|
||||
}
|
||||
|
||||
test_entityForUri() {
|
||||
expect(
|
||||
PhysicalFileSystem.instance
|
||||
.entityForUri(Uri.parse('$tempUri/file.txt'))
|
||||
.path,
|
||||
p.join(tempPath, 'file.txt'));
|
||||
}
|
||||
|
||||
test_entityForUri_bareUri_absolute() {
|
||||
expect(
|
||||
() => PhysicalFileSystem.instance.entityForUri(Uri.parse('/file.txt')),
|
||||
throwsA(new isInstanceOf<Error>()));
|
||||
}
|
||||
|
||||
test_entityForUri_bareUri_relative() {
|
||||
expect(
|
||||
() => PhysicalFileSystem.instance.entityForUri(Uri.parse('file.txt')),
|
||||
throwsA(new isInstanceOf<Error>()));
|
||||
}
|
||||
|
||||
test_entityForUri_fileUri_relative() {
|
||||
// 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('/')) {
|
||||
expect(() => PhysicalFileSystem.instance.entityForUri(uri),
|
||||
throwsA(new isInstanceOf<Error>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_entityForUri_nonFileUri() {
|
||||
expect(
|
||||
() => PhysicalFileSystem.instance
|
||||
.entityForUri(Uri.parse('package:foo/bar.dart')),
|
||||
throwsA(new isInstanceOf<Error>()));
|
||||
}
|
||||
|
||||
test_entityForUri_normalize_dot() {
|
||||
expect(
|
||||
PhysicalFileSystem.instance
|
||||
.entityForUri(Uri.parse('$tempUri/./file.txt'))
|
||||
.path,
|
||||
p.join(tempPath, 'file.txt'));
|
||||
}
|
||||
|
||||
test_entityForUri_normalize_dotDot() {
|
||||
expect(
|
||||
PhysicalFileSystem.instance
|
||||
.entityForUri(Uri.parse('$tempUri/foo/../file.txt'))
|
||||
.path,
|
||||
p.join(tempPath, 'file.txt'));
|
||||
}
|
||||
}
|
||||
|
||||
class _BaseTest {
|
||||
io.Directory tempDirectory;
|
||||
String tempPath;
|
||||
|
||||
setUp() {
|
||||
tempDirectory = io.Directory.systemTemp.createTempSync('test_file_system');
|
||||
tempPath = tempDirectory.absolute.path;
|
||||
}
|
||||
|
||||
tearDown() {
|
||||
tempDirectory.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
|
@ -53,6 +53,8 @@ compiler/tool/*: SkipByDesign # Only meant to run on vm
|
|||
front_end/tool/*: SkipByDesign # Only meant to run on vm
|
||||
lookup_map/test/version_check_test: SkipByDesign # Only meant to run in vm.
|
||||
typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
|
||||
front_end/test/memory_file_system_test: CompileTimeError # Issue 23773
|
||||
front_end/test/physical_file_system_test: SkipByDesign # Uses dart:io
|
||||
|
||||
[ $compiler == dart2js && $builder_tag != dart2js_analyzer ]
|
||||
analyzer/test/*: Skip # Issue 26813
|
||||
|
|
Loading…
Reference in a new issue