From e0aca538297c9e35ea671ad91f992a02285dfb35 Mon Sep 17 00:00:00 2001 From: Todd Volkert Date: Wed, 1 Feb 2017 10:45:45 -0800 Subject: [PATCH] Turn on stricter analyzer options (#17) (and fix the associated warnings & errors) --- .analysis_options | 20 +- lib/memory.dart | 3 + lib/src/backends/chroot/chroot_directory.dart | 4 +- lib/src/backends/chroot/chroot_file.dart | 18 +- .../backends/chroot/chroot_file_system.dart | 46 ++- .../chroot/chroot_file_system_entity.dart | 10 +- lib/src/backends/chroot/chroot_link.dart | 4 +- lib/src/backends/local/local_file_system.dart | 7 +- lib/src/backends/memory/memory_directory.dart | 4 +- lib/src/backends/memory/memory_file.dart | 28 +- lib/src/backends/memory/memory_file_stat.dart | 14 +- .../backends/memory/memory_file_system.dart | 17 +- .../memory/memory_file_system_entity.dart | 12 +- lib/src/backends/record_replay/encoding.dart | 19 +- lib/src/backends/record_replay/events.dart | 24 +- .../record_replay/mutable_recording.dart | 3 +- lib/src/backends/record_replay/recording.dart | 3 +- .../record_replay/recording_directory.dart | 3 + .../record_replay/recording_file.dart | 16 +- .../record_replay/recording_file_system.dart | 7 +- .../recording_file_system_entity.dart | 21 +- .../record_replay/recording_io_sink.dart | 6 + .../record_replay/recording_link.dart | 3 + .../record_replay/recording_proxy_mixin.dart | 8 +- .../recording_random_access_file.dart | 7 + lib/src/common.dart | 3 +- .../forwarding/forwarding_file_system.dart | 6 +- lib/src/interface/file_system.dart | 19 +- lib/src/io/interface.dart | 337 ++++++++++++++++-- lib/src/io/shim_dart_io.dart | 32 +- lib/src/io/shim_internal.dart | 25 ++ lib/src/testing/core_matchers.dart | 12 +- lib/src/testing/record_replay_matchers.dart | 174 +++++---- test/chroot_test.dart | 1 + test/common_tests.dart | 133 +++---- test/recording_test.dart | 87 ++--- 36 files changed, 813 insertions(+), 323 deletions(-) diff --git a/.analysis_options b/.analysis_options index b941521c7988f..b0163e6cde070 100644 --- a/.analysis_options +++ b/.analysis_options @@ -15,9 +15,9 @@ linter: # === error rules === - avoid_empty_else - # TODO - comment_references + - comment_references - cancel_subscriptions - # TODO - close_sinks + - close_sinks - control_flow_in_finally - empty_statements - hash_and_equals @@ -32,14 +32,14 @@ linter: # === style rules === - always_declare_return_types - # TODO - always_specify_types - # TODO - annotate_overrides + - always_specify_types + - annotate_overrides # TODO - avoid_as - avoid_init_to_null - avoid_return_types_on_setters - await_only_futures - # TODO - camel_case_types - # TODO - constant_identifier_names + - camel_case_types + - constant_identifier_names - control_flow_in_finally - empty_catches - empty_constructor_bodies @@ -53,14 +53,14 @@ linter: - package_api_docs - package_prefixed_library_names - prefer_is_not_empty - # TODO - public_member_api_docs + - public_member_api_docs - slash_for_doc_comments - sort_constructors_first - # TODO - sort_unnamed_constructors_first + - sort_unnamed_constructors_first - super_goes_last - # TODO - type_annotate_public_apis + - type_annotate_public_apis - type_init_formals - # TODO - unawaited_futures + - unawaited_futures - unnecessary_brace_in_string_interp - unnecessary_getters_setters diff --git a/lib/memory.dart b/lib/memory.dart index c5874992b45a4..85dfcc67be251 100644 --- a/lib/memory.dart +++ b/lib/memory.dart @@ -2,6 +2,9 @@ // 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. +import 'src/backends/memory.dart'; +import 'src/interface.dart'; + /// An implementation of [FileSystem] that exists entirely in memory with an /// internal representation loosely based on the Filesystem Hierarchy Standard. /// [MemoryFileSystem] is suitable for mocking and tests, as well as for diff --git a/lib/src/backends/chroot/chroot_directory.dart b/lib/src/backends/chroot/chroot_directory.dart index 901506d1ff5b7..d74376025e031 100644 --- a/lib/src/backends/chroot/chroot_directory.dart +++ b/lib/src/backends/chroot/chroot_directory.dart @@ -6,6 +6,8 @@ part of file.src.backends.chroot; class _ChrootDirectory extends _ChrootFileSystemEntity with ForwardingDirectory { + _ChrootDirectory(ChrootFileSystem fs, String path) : super(fs, path); + factory _ChrootDirectory.wrapped( ChrootFileSystem fs, Directory delegate, { @@ -15,8 +17,6 @@ class _ChrootDirectory extends _ChrootFileSystemEntity return new _ChrootDirectory(fs, localPath); } - _ChrootDirectory(ChrootFileSystem fs, String path) : super(fs, path); - @override FileSystemEntityType get expectedType => FileSystemEntityType.DIRECTORY; diff --git a/lib/src/backends/chroot/chroot_file.dart b/lib/src/backends/chroot/chroot_file.dart index 04b4bea97f1ec..2e556e9bc6716 100644 --- a/lib/src/backends/chroot/chroot_file.dart +++ b/lib/src/backends/chroot/chroot_file.dart @@ -4,8 +4,12 @@ part of file.src.backends.chroot; +typedef dynamic _SetupCallback(); + class _ChrootFile extends _ChrootFileSystemEntity with ForwardingFile { + _ChrootFile(ChrootFileSystem fs, String path) : super(fs, path); + factory _ChrootFile.wrapped( ChrootFileSystem fs, io.File delegate, { @@ -15,8 +19,6 @@ class _ChrootFile extends _ChrootFileSystemEntity return new _ChrootFile(fs, localPath); } - _ChrootFile(ChrootFileSystem fs, String path) : super(fs, path); - @override FileSystemEntityType get expectedType => FileSystemEntityType.FILE; @@ -25,7 +27,7 @@ class _ChrootFile extends _ChrootFileSystemEntity @override Future rename(String newPath) async { - var setUp = () {}; + _SetupCallback setUp = () {}; if (await fileSystem.type(newPath, followLinks: false) == FileSystemEntityType.LINK) { @@ -72,7 +74,7 @@ class _ChrootFile extends _ChrootFileSystemEntity @override File renameSync(String newPath) { - var setUp = () {}; + _SetupCallback setUp = () {}; if (fileSystem.typeSync(newPath, followLinks: false) == FileSystemEntityType.LINK) { @@ -125,7 +127,7 @@ class _ChrootFile extends _ChrootFileSystemEntity String path = fileSystem._resolve( this.path, followLinks: false, - notFound: recursive ? _NotFoundBehavior.MKDIR : _NotFoundBehavior.ALLOW, + notFound: recursive ? _NotFoundBehavior.mkdir : _NotFoundBehavior.allow, ); String real() => fileSystem._real(path, resolve: false); @@ -134,7 +136,7 @@ class _ChrootFile extends _ChrootFileSystemEntity if (await type() == FileSystemEntityType.LINK) { path = fileSystem._resolve(p.basename(path), - from: p.dirname(path), notFound: _NotFoundBehavior.ALLOW_AT_TAIL); + from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail); switch (await type()) { case FileSystemEntityType.NOT_FOUND: await _rawDelegate(real()).create(); @@ -157,7 +159,7 @@ class _ChrootFile extends _ChrootFileSystemEntity String path = fileSystem._resolve( this.path, followLinks: false, - notFound: recursive ? _NotFoundBehavior.MKDIR : _NotFoundBehavior.ALLOW, + notFound: recursive ? _NotFoundBehavior.mkdir : _NotFoundBehavior.allow, ); String real() => fileSystem._real(path, resolve: false); @@ -166,7 +168,7 @@ class _ChrootFile extends _ChrootFileSystemEntity if (type() == FileSystemEntityType.LINK) { path = fileSystem._resolve(p.basename(path), - from: p.dirname(path), notFound: _NotFoundBehavior.ALLOW_AT_TAIL); + from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail); switch (type()) { case FileSystemEntityType.NOT_FOUND: _rawDelegate(real()).createSync(); diff --git a/lib/src/backends/chroot/chroot_file_system.dart b/lib/src/backends/chroot/chroot_file_system.dart index 9ba2b812a3515..bb51210c9da67 100644 --- a/lib/src/backends/chroot/chroot_file_system.dart +++ b/lib/src/backends/chroot/chroot_file_system.dart @@ -60,13 +60,14 @@ class ChrootFileSystem extends FileSystem { String get _localRoot => p.rootPrefix(root); @override - Directory directory(path) => new _ChrootDirectory(this, common.getPath(path)); + Directory directory(dynamic path) => + new _ChrootDirectory(this, common.getPath(path)); @override - File file(path) => new _ChrootFile(this, common.getPath(path)); + File file(dynamic path) => new _ChrootFile(this, common.getPath(path)); @override - Link link(path) => new _ChrootLink(this, common.getPath(path)); + Link link(dynamic path) => new _ChrootLink(this, common.getPath(path)); @override p.Context get path => @@ -99,7 +100,7 @@ class ChrootFileSystem extends FileSystem { /// Gets the path context for this file system given the current working dir. @override - set currentDirectory(path) { + set currentDirectory(dynamic path) { String value; if (path is io.Directory) { value = path.path; @@ -109,7 +110,7 @@ class ChrootFileSystem extends FileSystem { throw new ArgumentError('Invalid type for "path": ${path?.runtimeType}'); } - value = _resolve(value, notFound: _NotFoundBehavior.THROW); + value = _resolve(value, notFound: _NotFoundBehavior.throwError); String realPath = _real(value, resolve: false); switch (delegate.typeSync(realPath, followLinks: false)) { case FileSystemEntityType.DIRECTORY: @@ -128,7 +129,7 @@ class ChrootFileSystem extends FileSystem { try { path = _resolve(path); } on FileSystemException { - return new Future.value(const _NotFoundFileStat()); + return new Future.value(const _NotFoundFileStat()); } return delegate.stat(_real(path, resolve: false)); } @@ -164,7 +165,8 @@ class ChrootFileSystem extends FileSystem { try { realPath = _real(path, followLinks: followLinks); } on FileSystemException { - return new Future.value(FileSystemEntityType.NOT_FOUND); + return new Future.value( + FileSystemEntityType.NOT_FOUND); } return delegate.type(realPath, followLinks: false); } @@ -244,14 +246,20 @@ class ChrootFileSystem extends FileSystem { /// only if [followLinks] is `true`. Symbolic links found in the middle of /// the path will always be resolved. /// - /// If [throwIfNotFound] is `true`, and the path cannot be resolved, a file - /// system exception is thrown - otherwise the resolution will halt and the - /// partially resolved path will be returned. + /// If the path cannot be resolved, and [notFound] is: + /// - [_NotFoundBehavior.throwError]: a [FileSystemException] is thrown. + /// - [_NotFoundBehavior.mkdir]: the path will be created as needed. + /// - [_NotFoundBehavior.allowAtTail]: a [FileSystemException] is thrown, + /// unless only the *tail* path element cannot be resolved, in which case + /// the resolution will halt at the tail element, and the partially + /// resolved path will be returned. + /// - [_NotFoundBehavior.allow] (the default), the resolution will halt and + /// the partially resolved path will be returned. String _resolve( String path, { String from, bool followLinks: true, - _NotFoundBehavior notFound: _NotFoundBehavior.ALLOW, + _NotFoundBehavior notFound: _NotFoundBehavior.allow, }) { p.Context ctx = _context; String root = _localRoot; @@ -304,19 +312,19 @@ class ChrootFileSystem extends FileSystem { } switch (notFound) { - case _NotFoundBehavior.MKDIR: + case _NotFoundBehavior.mkdir: if (parts.isNotEmpty) { delegate.directory(realPath).createSync(); } break; - case _NotFoundBehavior.ALLOW: + case _NotFoundBehavior.allow: return returnEarly(); - case _NotFoundBehavior.ALLOW_AT_TAIL: + case _NotFoundBehavior.allowAtTail: if (parts.isEmpty) { return returnEarly(); } throw notFoundException(); - case _NotFoundBehavior.THROW: + case _NotFoundBehavior.throwError: throw notFoundException(); } break; @@ -351,10 +359,10 @@ class _ChrootJailException implements IOException {} /// What to do when `NOT_FOUND` paths are encountered while resolving. enum _NotFoundBehavior { - ALLOW, - ALLOW_AT_TAIL, - THROW, - MKDIR, + allow, + allowAtTail, + throwError, + mkdir, } /// A [FileStat] representing a `NOT_FOUND` entity. diff --git a/lib/src/backends/chroot/chroot_file_system_entity.dart b/lib/src/backends/chroot/chroot_file_system_entity.dart index 23a6fc507cccb..a7a8388d58388 100644 --- a/lib/src/backends/chroot/chroot_file_system_entity.dart +++ b/lib/src/backends/chroot/chroot_file_system_entity.dart @@ -76,7 +76,7 @@ abstract class _ChrootFileSystemEntity - fileSystem._resolve(path, notFound: _NotFoundBehavior.THROW); + fileSystem._resolve(path, notFound: _NotFoundBehavior.throwError); @override Future stat() { @@ -103,7 +103,7 @@ abstract class _ChrootFileSystemEntity delete({bool recursive: false}) async { String path = fileSystem._resolve(this.path, - followLinks: false, notFound: _NotFoundBehavior.THROW); + followLinks: false, notFound: _NotFoundBehavior.throwError); String real(String path) => fileSystem._real(path, resolve: false); Future type(String path) => @@ -114,7 +114,7 @@ abstract class _ChrootFileSystemEntity fileSystem._real(path, resolve: false); FileSystemEntityType type(String path) => @@ -144,7 +144,7 @@ abstract class _ChrootFileSystemEntity with ForwardingLink { + _ChrootLink(ChrootFileSystem fs, String path) : super(fs, path); + factory _ChrootLink.wrapped( ChrootFileSystem fs, io.Link delegate, { @@ -15,8 +17,6 @@ class _ChrootLink extends _ChrootFileSystemEntity return new _ChrootLink(fs, localPath); } - _ChrootLink(ChrootFileSystem fs, String path) : super(fs, path); - @override Future exists() => delegate.exists(); diff --git a/lib/src/backends/local/local_file_system.dart b/lib/src/backends/local/local_file_system.dart index 7e285a544749f..0751e7959289d 100644 --- a/lib/src/backends/local/local_file_system.dart +++ b/lib/src/backends/local/local_file_system.dart @@ -9,17 +9,18 @@ part of file.src.backends.local; /// Since this implementation of the [FileSystem] interface delegates to /// `dart:io`, is is not suitable for use in the browser. class LocalFileSystem extends FileSystem { + /// Creates a new `LocalFileSystem`. const LocalFileSystem(); @override - Directory directory(path) => + Directory directory(dynamic path) => new _LocalDirectory(this, shim.newDirectory(path)); @override - File file(path) => new _LocalFile(this, shim.newFile(path)); + File file(dynamic path) => new _LocalFile(this, shim.newFile(path)); @override - Link link(path) => new _LocalLink(this, shim.newLink(path)); + Link link(dynamic path) => new _LocalLink(this, shim.newLink(path)); @override p.Context get path => new p.Context(); diff --git a/lib/src/backends/memory/memory_directory.dart b/lib/src/backends/memory/memory_directory.dart index 9be6b39be0e79..34793df3fba11 100644 --- a/lib/src/backends/memory/memory_directory.dart +++ b/lib/src/backends/memory/memory_directory.dart @@ -55,7 +55,7 @@ class _MemoryDirectory extends _MemoryFileSystemEntity implements Directory { _DirectoryNode node = fileSystem._findNode(dirname); _checkExists(node, () => dirname); _checkIsDir(node, () => dirname); - var name = () => '$basename$_tempCounter'; + String name() => '$basename$_tempCounter'; while (node.children.containsKey(name())) { _tempCounter++; } @@ -90,7 +90,7 @@ class _MemoryDirectory extends _MemoryFileSystemEntity implements Directory { bool recursive: false, bool followLinks: true, }) => - new Stream.fromIterable(listSync( + new Stream.fromIterable(listSync( recursive: recursive, followLinks: followLinks, )); diff --git a/lib/src/backends/memory/memory_file.dart b/lib/src/backends/memory/memory_file.dart index 05e6d09e013bb..66e5abc457ad2 100644 --- a/lib/src/backends/memory/memory_file.dart +++ b/lib/src/backends/memory/memory_file.dart @@ -146,9 +146,9 @@ class _MemoryFile extends _MemoryFileSystemEntity implements File { ? content.sublist(start) : content.sublist(start, min(end, content.length)); } - return new Stream.fromIterable(>[content]); + return new Stream>.fromIterable(>[content]); } catch (e) { - return new Stream.fromFuture(new Future.error(e)); + return new Stream>.fromFuture(new Future>.error(e)); } } @@ -262,7 +262,7 @@ class _FileSink implements io.IOSink { io.FileMode mode, Encoding encoding, ) { - Future<_FileNode> node = new Future.microtask(() { + Future<_FileNode> node = new Future<_FileNode>.microtask(() { _FileNode node = file._resolvedBackingOrCreate; file._truncateIfNecessary(node, mode); return node; @@ -288,7 +288,7 @@ class _FileSink implements io.IOSink { void write(Object obj) => add(encoding.encode(obj?.toString() ?? 'null')); @override - void writeAll(Iterable objects, [String separator = ""]) { + void writeAll(Iterable objects, [String separator = ""]) { bool firstIter = true; for (dynamic obj in objects) { if (!firstIter && separator != null) { @@ -309,23 +309,24 @@ class _FileSink implements io.IOSink { void writeCharCode(int charCode) => write(new String.fromCharCode(charCode)); @override - void addError(error, [StackTrace stackTrace]) { + void addError(dynamic error, [StackTrace stackTrace]) { _checkNotStreaming(); _completer.completeError(error, stackTrace); } @override - Future addStream(Stream> stream) { + Future addStream(Stream> stream) { _checkNotStreaming(); _streamCompleter = new Completer(); - var finish = () { + void finish() { _streamCompleter.complete(); _streamCompleter = null; - }; + } + stream.listen( (List data) => _addData(data), cancelOnError: true, - onError: (error, StackTrace stackTrace) { + onError: (dynamic error, StackTrace stackTrace) { _completer.completeError(error, stackTrace); finish(); }, @@ -335,19 +336,20 @@ class _FileSink implements io.IOSink { } @override - Future flush() { + // TODO(tvolkert): Change to Future once Dart 1.22 is stable + Future flush() { _checkNotStreaming(); return _pendingWrites; } @override - Future close() { + Future close() { _checkNotStreaming(); if (!_isClosed) { _isClosed = true; _pendingWrites.then( (_) => _completer.complete(), - onError: (error, stackTrace) => + onError: (dynamic error, StackTrace stackTrace) => _completer.completeError(error, stackTrace), ); } @@ -355,7 +357,7 @@ class _FileSink implements io.IOSink { } @override - Future get done => _completer.future; + Future get done => _completer.future; void _addData(List data) { _pendingWrites = _pendingWrites.then((_FileNode node) { diff --git a/lib/src/backends/memory/memory_file_stat.dart b/lib/src/backends/memory/memory_file_stat.dart index 9497dc563dc51..87d8a6d5a15ff 100644 --- a/lib/src/backends/memory/memory_file_stat.dart +++ b/lib/src/backends/memory/memory_file_stat.dart @@ -5,7 +5,8 @@ part of file.src.backends.memory; class _MemoryFileStat implements io.FileStat { - static const _notFound = const _MemoryFileStat._internalNotFound(); + static const _MemoryFileStat _notFound = + const _MemoryFileStat._internalNotFound(); @override final DateTime changed; @@ -45,7 +46,16 @@ class _MemoryFileStat implements io.FileStat { @override String modeString() { int permissions = mode & 0xFFF; - var codes = const ['---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx']; + List codes = const [ + '---', + '--x', + '-w-', + '-wx', + 'r--', + 'r-x', + 'rw-', + 'rwx', + ]; List result = []; result ..add(codes[(permissions >> 6) & 0x7]) diff --git a/lib/src/backends/memory/memory_file_system.dart b/lib/src/backends/memory/memory_file_system.dart index d37918669b486..4fa8578351a0f 100644 --- a/lib/src/backends/memory/memory_file_system.dart +++ b/lib/src/backends/memory/memory_file_system.dart @@ -8,7 +8,7 @@ const String _separator = '/'; const String _thisDir = '.'; const String _parentDir = '..'; -/// Visitor callback for use with [_findNode]. +/// Visitor callback for use with `_findNode`. /// /// [parent] is the parent node of the current path segment and is guaranteed /// to be non-null. @@ -22,10 +22,10 @@ const String _parentDir = '..'; /// do things like recursively create or delete folders. /// /// [currentSegment] is the index of the current segment within the overall -/// path that's being walked by [_findNode]. +/// path that's being walked by `_findNode`. /// /// [finalSegment] is the index of the final segment that will be walked by -/// [_findNode]. +/// `_findNode`. typedef _Node _SegmentVisitor( _DirectoryNode parent, String childName, @@ -51,18 +51,23 @@ class MemoryFileSystem extends FileSystem { String _systemTemp; String _cwd = _separator; + /// Creates a new `MemoryFileSystem`. + /// + /// The file system will be empty, and the current directory will be the + /// root directory. MemoryFileSystem() { _root = new _RootNode(this); } @override - Directory directory(path) => new _MemoryDirectory(this, common.getPath(path)); + Directory directory(dynamic path) => + new _MemoryDirectory(this, common.getPath(path)); @override - File file(path) => new _MemoryFile(this, common.getPath(path)); + File file(dynamic path) => new _MemoryFile(this, common.getPath(path)); @override - Link link(path) => new _MemoryLink(this, common.getPath(path)); + Link link(dynamic path) => new _MemoryLink(this, common.getPath(path)); @override p.Context get path => new p.Context(style: p.Style.posix, current: _cwd); diff --git a/lib/src/backends/memory/memory_file_system_entity.dart b/lib/src/backends/memory/memory_file_system_entity.dart index c8df73e982b26..b5fdceea1935b 100644 --- a/lib/src/backends/memory/memory_file_system_entity.dart +++ b/lib/src/backends/memory/memory_file_system_entity.dart @@ -4,7 +4,7 @@ part of file.src.backends.memory; -/// Validator function for use with [_renameSync]. This will be invoked if the +/// Validator function for use with `_renameSync`. This will be invoked if the /// rename would overwrite an existing entity at the new path. If this operation /// should not be allowed, this function is expected to throw a /// [io.FileSystemException]. The lack of such an exception will be interpreted @@ -53,7 +53,7 @@ abstract class _MemoryFileSystemEntity implements FileSystemEntity { /// Gets the node that backs this file system entity, or if that node is /// a symbolic link, the target node. This also will check that the type of - /// the node (aftere symlink resolution) matches [expectedType]. If the type + /// the node (after symlink resolution) matches [expectedType]. If the type /// doesn't match, this will throw a [io.FileSystemException]. _Node get _resolvedBacking { _Node node = _backing; @@ -67,8 +67,8 @@ abstract class _MemoryFileSystemEntity implements FileSystemEntity { /// match. Note that since this checks the node's `stat` type, symbolic links /// will be resolved to their target type for the purpose of this validation. /// - /// Protected methods that accept a [checkType] argument will default to this - /// method if the [checkType] argument is unspecified. + /// Protected methods that accept a `checkType` argument will default to this + /// method if the `checkType` argument is unspecified. void _defaultCheckType(_Node node) { _checkType(expectedType, node.stat.type, () => path); } @@ -140,9 +140,9 @@ abstract class _MemoryFileSystemEntity implements FileSystemEntity { /// calling [createChild] for each segment whose child does not already exist. /// /// When [createChild] is invoked: - /// - [parent] will be the parent node for the current segment and is + /// - `parent` will be the parent node for the current segment and is /// guaranteed to be non-null. - /// - [isFinalSegment] will indicate whether the current segment is the tail + /// - `isFinalSegment` will indicate whether the current segment is the tail /// segment, which in turn indicates that this is the segment into which to /// create the node for this entity. /// diff --git a/lib/src/backends/record_replay/encoding.dart b/lib/src/backends/record_replay/encoding.dart index f71dec227b26d..74d075bc9b4f3 100644 --- a/lib/src/backends/record_replay/encoding.dart +++ b/lib/src/backends/record_replay/encoding.dart @@ -5,6 +5,7 @@ import 'dart:convert'; import 'package:file/file.dart'; +import 'package:file/src/io.dart' as io; import 'package:path/path.dart' as p; import 'common.dart'; @@ -35,19 +36,20 @@ class _TypeMatcher { /// When encoding an object, we will walk this map in iteration order looking /// for a matching encoder. Thus, when there are two encoders that match an // object, the first one will win. -const Map<_TypeMatcher, _Encoder> _kEncoders = const <_TypeMatcher, _Encoder>{ +const Map<_TypeMatcher, _Encoder> _kEncoders = + const <_TypeMatcher, _Encoder>{ const _TypeMatcher(): _encodeRaw, const _TypeMatcher(): _encodeRaw, const _TypeMatcher(): _encodeRaw, const _TypeMatcher(): _encodeRaw, - const _TypeMatcher(): _encodeRaw, - const _TypeMatcher(): _encodeMap, - const _TypeMatcher(): _encodeIterable, + const _TypeMatcher>(): _encodeRaw, + const _TypeMatcher>(): _encodeMap, + const _TypeMatcher>(): _encodeIterable, const _TypeMatcher(): getSymbolName, const _TypeMatcher(): _encodeDateTime, const _TypeMatcher(): _encodeUri, const _TypeMatcher(): _encodePathContext, - const _TypeMatcher(): _encodeEvent, + const _TypeMatcher>(): _encodeEvent, const _TypeMatcher(): _encodeFileSystem, const _TypeMatcher(): _encodeFileSystemEntity, const _TypeMatcher(): _encodeFileSystemEntity, @@ -70,7 +72,7 @@ const Map<_TypeMatcher, _Encoder> _kEncoders = const <_TypeMatcher, _Encoder>{ /// - [JsonEncoder.withIndent] dynamic encode(dynamic object) { _Encoder encoder = _encodeDefault; - for (_TypeMatcher matcher in _kEncoders.keys) { + for (_TypeMatcher matcher in _kEncoders.keys) { if (matcher.check(object)) { encoder = _kEncoders[matcher]; break; @@ -112,14 +114,15 @@ Map _encodePathContext(p.Context context) => { 'cwd': context.current, }; -Map _encodeEvent(EventImpl event) => event.encode(); +Map _encodeEvent(EventImpl event) => event.encode(); String _encodeFileSystem(FileSystem fs) => kFileSystemEncodedValue; /// Encodes a file system entity by using its `uid` as a reference identifier. /// During replay, this allows us to tie the return value of of one event to /// the object of another. -String _encodeFileSystemEntity(RecordingFileSystemEntity entity) { +String _encodeFileSystemEntity( + RecordingFileSystemEntity entity) { return '${entity.runtimeType}@${entity.uid}'; } diff --git a/lib/src/backends/record_replay/events.dart b/lib/src/backends/record_replay/events.dart index a0802ea9c15ac..bbb1526cadb60 100644 --- a/lib/src/backends/record_replay/events.dart +++ b/lib/src/backends/record_replay/events.dart @@ -53,7 +53,9 @@ abstract class MethodEvent extends InvocationEvent { Map get namedArguments; } +/// Non-exported implementation of [InvocationEvent]. abstract class EventImpl implements InvocationEvent { + /// Creates a new `EventImpl`. EventImpl(this.object, this.result, this.timestamp); @override @@ -76,8 +78,10 @@ abstract class EventImpl implements InvocationEvent { String toString() => encode().toString(); } +/// Non-exported implementation of [PropertyGetEvent]. class PropertyGetEventImpl extends EventImpl implements PropertyGetEvent { + /// Create a new `PropertyGetEventImpl`. PropertyGetEventImpl(Object object, this.property, T result, int timestamp) : super(object, result, timestamp); @@ -91,8 +95,10 @@ class PropertyGetEventImpl extends EventImpl }..addAll(super.encode()); } +/// Non-exported implementation of [PropertySetEvent]. class PropertySetEventImpl extends EventImpl implements PropertySetEvent { + /// Create a new `PropertySetEventImpl`. PropertySetEventImpl(Object object, this.property, this.value, int timestamp) : super(object, null, timestamp); @@ -110,11 +116,21 @@ class PropertySetEventImpl extends EventImpl }..addAll(super.encode()); } +/// Non-exported implementation of [MethodEvent]. class MethodEventImpl extends EventImpl implements MethodEvent { - MethodEventImpl(Object object, this.method, List positionalArguments, - Map namedArguments, T result, int timestamp) - : this.positionalArguments = new List.unmodifiable(positionalArguments), - this.namedArguments = new Map.unmodifiable(namedArguments), + /// Create a new `MethodEventImpl`. + MethodEventImpl( + Object object, + this.method, + List positionalArguments, + Map namedArguments, + T result, + int timestamp, + ) + : this.positionalArguments = + new List.unmodifiable(positionalArguments), + this.namedArguments = + new Map.unmodifiable(namedArguments), super(object, result, timestamp); @override diff --git a/lib/src/backends/record_replay/mutable_recording.dart b/lib/src/backends/record_replay/mutable_recording.dart index 98a9baf7758c2..d75f91a0ebe16 100644 --- a/lib/src/backends/record_replay/mutable_recording.dart +++ b/lib/src/backends/record_replay/mutable_recording.dart @@ -24,7 +24,8 @@ class MutableRecording implements LiveRecording { final Directory destination; @override - List> get events => new List.unmodifiable(_events); + List> get events => + new List>.unmodifiable(_events); // TODO(tvolkert): Add ability to wait for all Future and Stream results @override diff --git a/lib/src/backends/record_replay/recording.dart b/lib/src/backends/record_replay/recording.dart index 75462c2c511ec..a3e5836c7857c 100644 --- a/lib/src/backends/record_replay/recording.dart +++ b/lib/src/backends/record_replay/recording.dart @@ -20,9 +20,10 @@ abstract class Recording { } /// An [Recording] in progress that can be serialized to disk for later use -/// in [ReplayFileSystem]. +/// in `ReplayFileSystem`. /// /// Live recordings exist only in memory until [flush] is called. +// TODO(tvolkert): Link to ReplayFileSystem in docs once it's implemented abstract class LiveRecording extends Recording { /// The directory in which recording files will be stored. /// diff --git a/lib/src/backends/record_replay/recording_directory.dart b/lib/src/backends/record_replay/recording_directory.dart index db74661459fad..068614127452c 100644 --- a/lib/src/backends/record_replay/recording_directory.dart +++ b/lib/src/backends/record_replay/recording_directory.dart @@ -10,9 +10,12 @@ import 'package:file/src/io.dart' as io; import 'recording_file_system.dart'; import 'recording_file_system_entity.dart'; +/// [Directory] implementation that records all invocation activity to its file +/// system's recording. class RecordingDirectory extends RecordingFileSystemEntity implements Directory { + /// Creates a new `RecordingDirectory`. RecordingDirectory(RecordingFileSystem fileSystem, io.Directory delegate) : super(fileSystem, delegate) { methods.addAll({ diff --git a/lib/src/backends/record_replay/recording_file.dart b/lib/src/backends/record_replay/recording_file.dart index a6bd2c4b5fe07..53656144ec12f 100644 --- a/lib/src/backends/record_replay/recording_file.dart +++ b/lib/src/backends/record_replay/recording_file.dart @@ -13,8 +13,11 @@ import 'recording_file_system_entity.dart'; import 'recording_io_sink.dart'; import 'recording_random_access_file.dart'; +/// [File] implementation that records all invocation activity to its file +/// system's recording. class RecordingFile extends RecordingFileSystemEntity implements File { + /// Creates a new `RecordingFile`. RecordingFile(RecordingFileSystem fileSystem, io.File delegate) : super(fileSystem, delegate) { methods.addAll({ @@ -63,12 +66,17 @@ class RecordingFile extends RecordingFileSystemEntity _wrapRandomAccessFile(delegate.openSync(mode: mode)); IOSink _openWrite({FileMode mode: FileMode.WRITE, Encoding encoding: UTF8}) { - IOSink sink = delegate.openWrite(mode: mode, encoding: encoding); - return new RecordingIOSink(fileSystem, sink); + return new RecordingIOSink( + fileSystem, + delegate.openWrite(mode: mode, encoding: encoding), + ); } - Future _writeAsBytes(List bytes, - {FileMode mode: FileMode.WRITE, bool flush: false}) => + Future _writeAsBytes( + List bytes, { + FileMode mode: FileMode.WRITE, + bool flush: false, + }) => delegate.writeAsBytes(bytes, mode: mode, flush: flush).then(wrap); Future _writeAsString( diff --git a/lib/src/backends/record_replay/recording_file_system.dart b/lib/src/backends/record_replay/recording_file_system.dart index be999636b7064..aad9c452945de 100644 --- a/lib/src/backends/record_replay/recording_file_system.dart +++ b/lib/src/backends/record_replay/recording_file_system.dart @@ -16,7 +16,7 @@ import 'recording_proxy_mixin.dart'; /// /// This will record all invocations (methods, property getters, and property /// setters) that occur on it, in an opaque format that can later be used in -/// [ReplayFileSystem]. All activity in the [File], [Directory], [Link], +/// `ReplayFileSystem`. All activity in the [File], [Directory], [Link], /// [IOSink], and [RandomAccessFile] instances returned from this API will also /// be recorded. /// @@ -35,7 +35,8 @@ import 'recording_proxy_mixin.dart'; /// order. /// /// See also: -/// - [ReplayFileSystem] +/// - `ReplayFileSystem` +// TODO(tvolkert): Link to ReplayFileSystem in docs once it's implemented abstract class RecordingFileSystem extends FileSystem { /// Creates a new `RecordingFileSystem`. /// @@ -73,9 +74,11 @@ abstract class RecordingFileSystem extends FileSystem { Stopwatch get stopwatch; } +/// Non-exported implementation class for `RecordingFileSystem`. class RecordingFileSystemImpl extends FileSystem with RecordingProxyMixin implements RecordingFileSystem { + /// Creates a new `RecordingFileSystemImpl`. RecordingFileSystemImpl( this.delegate, Directory destination, Stopwatch recordingStopwatch) : recording = new MutableRecording(destination), diff --git a/lib/src/backends/record_replay/recording_file_system_entity.dart b/lib/src/backends/record_replay/recording_file_system_entity.dart index 097ba0b54739c..e1f695b79a4e2 100644 --- a/lib/src/backends/record_replay/recording_file_system_entity.dart +++ b/lib/src/backends/record_replay/recording_file_system_entity.dart @@ -16,10 +16,13 @@ import 'recording_file_system.dart'; import 'recording_link.dart'; import 'recording_proxy_mixin.dart'; +/// [FileSystemEntity] implementation that records all invocation activity to +/// its file system's recording. abstract class RecordingFileSystemEntity extends Object with RecordingProxyMixin implements FileSystemEntity { + /// Creates a new `RecordingFileSystemEntity`. RecordingFileSystemEntity(this.fileSystem, this.delegate) { methods.addAll({ #exists: delegate.exists, @@ -56,28 +59,36 @@ abstract class RecordingFileSystemEntity fileSystem.stopwatch; + /// The entity to which this entity delegates its functionality while + /// recording. @protected final D delegate; /// Returns an entity with the same file system and same type as this /// entity but backed by the specified delegate. /// - /// If the specified delegate is the same as this entity's delegate, this - /// will return this entity. - /// - /// Subclasses should override this method to instantiate the correct wrapped - /// type if this super implementation returns `null`. + /// This base implementation checks to see if the specified delegate is the + /// same as this entity's delegate, and if so, it returns this entity. + /// Otherwise it returns `null`. Subclasses should override this method to + /// instantiate the correct wrapped type only if this super implementation + /// returns `null`. @protected @mustCallSuper T wrap(D delegate) => delegate == this.delegate ? this as T : null; + /// Returns a directory with the same file system as this entity but backed + /// by the specified delegate directory. @protected Directory wrapDirectory(io.Directory delegate) => new RecordingDirectory(fileSystem, delegate); + /// Returns a file with the same file system as this entity but backed + /// by the specified delegate file. @protected File wrapFile(io.File delegate) => new RecordingFile(fileSystem, delegate); + /// Returns a link with the same file system as this entity but backed + /// by the specified delegate link. @protected Link wrapLink(io.Link delegate) => new RecordingLink(fileSystem, delegate); diff --git a/lib/src/backends/record_replay/recording_io_sink.dart b/lib/src/backends/record_replay/recording_io_sink.dart index 8cff7487cd007..ea2000404ddd3 100644 --- a/lib/src/backends/record_replay/recording_io_sink.dart +++ b/lib/src/backends/record_replay/recording_io_sink.dart @@ -11,12 +11,18 @@ import 'mutable_recording.dart'; import 'recording_file_system.dart'; import 'recording_proxy_mixin.dart'; +/// [IOSink] implementation that records all invocation activity to its file +/// system's recording. class RecordingIOSink extends Object with RecordingProxyMixin implements IOSink { + /// The file system that owns this sink. final RecordingFileSystem fileSystem; + + /// The sink to which this sink delegates its functionality while recording. final IOSink delegate; + /// Creates a new `RecordingIOSink`. RecordingIOSink(this.fileSystem, this.delegate) { methods.addAll({ #add: delegate.add, diff --git a/lib/src/backends/record_replay/recording_link.dart b/lib/src/backends/record_replay/recording_link.dart index 21545516ab325..011449979ba0c 100644 --- a/lib/src/backends/record_replay/recording_link.dart +++ b/lib/src/backends/record_replay/recording_link.dart @@ -10,8 +10,11 @@ import 'package:file/src/io.dart' as io; import 'recording_file_system.dart'; import 'recording_file_system_entity.dart'; +/// [Link] implementation that records all invocation activity to its file +/// system's recording. class RecordingLink extends RecordingFileSystemEntity implements Link { + /// Creates a new `RecordingLink`. RecordingLink(RecordingFileSystem fileSystem, io.Link delegate) : super(fileSystem, delegate) { methods.addAll({ diff --git a/lib/src/backends/record_replay/recording_proxy_mixin.dart b/lib/src/backends/record_replay/recording_proxy_mixin.dart index 77e6490e2fbfc..bf69f7484d09b 100644 --- a/lib/src/backends/record_replay/recording_proxy_mixin.dart +++ b/lib/src/backends/record_replay/recording_proxy_mixin.dart @@ -113,13 +113,15 @@ abstract class RecordingProxyMixin { T recordEvent(T value) { InvocationEvent event; if (invocation.isGetter) { - event = new PropertyGetEventImpl(this, name, value, time); + event = new PropertyGetEventImpl(this, name, value, time); } else if (invocation.isSetter) { // TODO(tvolkert): Remove indirection once SDK 1.22 is in stable branch - dynamic temp = new PropertySetEventImpl(this, name, args[0], time); + dynamic temp = + new PropertySetEventImpl(this, name, args[0], time); event = temp; } else { - event = new MethodEventImpl(this, name, args, namedArgs, value, time); + event = + new MethodEventImpl(this, name, args, namedArgs, value, time); } recording.add(event); return value; diff --git a/lib/src/backends/record_replay/recording_random_access_file.dart b/lib/src/backends/record_replay/recording_random_access_file.dart index 2b1d9119ea96c..e0bf90d3802d7 100644 --- a/lib/src/backends/record_replay/recording_random_access_file.dart +++ b/lib/src/backends/record_replay/recording_random_access_file.dart @@ -12,12 +12,19 @@ import 'mutable_recording.dart'; import 'recording_file_system.dart'; import 'recording_proxy_mixin.dart'; +/// [RandomAccessFile] implementation that records all invocation activity to +/// its file system's recording. class RecordingRandomAccessFile extends Object with RecordingProxyMixin implements RandomAccessFile { + /// The file system that owns this random access file. final RecordingFileSystem fileSystem; + + /// The random access file to which this random access file delegates its + /// functionality while recording. final RandomAccessFile delegate; + /// Creates a new `RecordingRandomAccessFile`. RecordingRandomAccessFile(this.fileSystem, this.delegate) { methods.addAll({ #close: _close, diff --git a/lib/src/common.dart b/lib/src/common.dart index 27ab4fa1aca11..24dc7be506aba 100644 --- a/lib/src/common.dart +++ b/lib/src/common.dart @@ -4,7 +4,8 @@ import 'package:file/src/io.dart' as io; -String getPath(path) { +/// Gets the string path represented by the specified generic [path]. +String getPath(dynamic path) { if (path is io.FileSystemEntity) { return path.path; } else if (path is String) { diff --git a/lib/src/forwarding/forwarding_file_system.dart b/lib/src/forwarding/forwarding_file_system.dart index ec5efda24bd31..f6c62dc01e872 100644 --- a/lib/src/forwarding/forwarding_file_system.dart +++ b/lib/src/forwarding/forwarding_file_system.dart @@ -15,13 +15,13 @@ abstract class ForwardingFileSystem extends FileSystem { ForwardingFileSystem(this.delegate); @override - Directory directory(path) => delegate.directory(path); + Directory directory(dynamic path) => delegate.directory(path); @override - File file(path) => delegate.file(path); + File file(dynamic path) => delegate.file(path); @override - Link link(path) => delegate.link(path); + Link link(dynamic path) => delegate.link(path); @override p.Context get path => delegate.path; diff --git a/lib/src/interface/file_system.dart b/lib/src/interface/file_system.dart index 56cc004d5e385..abd954e2ba3b3 100644 --- a/lib/src/interface/file_system.dart +++ b/lib/src/interface/file_system.dart @@ -11,22 +11,23 @@ part of file.src.interface; /// dependence on the library (and the associated implications of using that /// implementation in the browser). abstract class FileSystem { + /// Creates a new `FileSystem`. const FileSystem(); /// Returns a reference to a [Directory] at [path]. /// /// [path] can be either a [`String`], a [`Uri`], or a [`FileSystemEntity`]. - Directory directory(path); + Directory directory(dynamic path); /// Returns a reference to a [File] at [path]. /// /// [path] can be either a [`String`], a [`Uri`], or a [`FileSystemEntity`]. - File file(path); + File file(dynamic path); /// Returns a reference to a [Link] at [path]. /// /// [path] can be either a [`String`], a [`Uri`], or a [`FileSystemEntity`]. - Link link(path); + Link link(dynamic path); /// An object for manipulating paths in this file system. path.Context get path; @@ -47,7 +48,7 @@ abstract class FileSystem { /// Relative paths will be resolved by the underlying file system /// implementation (meaning it is up to the underlying implementation to /// decide whether to support relative paths). - set currentDirectory(path); + set currentDirectory(dynamic path); /// Asynchronously calls the operating system's stat() function on [path]. /// Returns a Future which completes with a [FileStat] object containing @@ -86,27 +87,27 @@ abstract class FileSystem { /// exist. bool identicalSync(String path1, String path2); - /// Tests if [watch] is supported on the current system. + /// Tests if [FileSystemEntity.watch] is supported on the current system. bool get isWatchSupported; /// Finds the type of file system object that a [path] points to. Returns /// a Future that completes with the result. /// - /// [FileSystemEntityType.LINK] will only be returned if [followLinks] is + /// [io.FileSystemEntityType.LINK] will only be returned if [followLinks] is /// `false`, and [path] points to a link /// /// If the [path] does not point to a file system object or an error occurs - /// then [FileSystemEntityType.NOT_FOUND] is returned. + /// then [io.FileSystemEntityType.NOT_FOUND] is returned. Future type(String path, {bool followLinks: true}); /// Syncronously finds the type of file system object that a [path] points /// to. Returns a [FileSystemEntityType]. /// - /// [FileSystemEntityType.LINK] will only be returned if [followLinks] is + /// [io.FileSystemEntityType.LINK] will only be returned if [followLinks] is /// `false`, and [path] points to a link /// /// If the [path] does not point to a file system object or an error occurs - /// then [FileSystemEntityType.NOT_FOUND] is returned. + /// then [io.FileSystemEntityType.NOT_FOUND] is returned. io.FileSystemEntityType typeSync(String path, {bool followLinks: true}); /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.FILE]. diff --git a/lib/src/io/interface.dart b/lib/src/io/interface.dart index b2aa6bba62777..46777aac4bfcb 100644 --- a/lib/src/io/interface.dart +++ b/lib/src/io/interface.dart @@ -5,139 +5,307 @@ import 'dart:async'; import 'dart:convert'; +// ignore: public_member_api_docs abstract class Directory implements FileSystemEntity { - String get path; - Uri get uri; + // ignore: public_member_api_docs Future create({bool recursive: false}); + + // ignore: public_member_api_docs void createSync({bool recursive: false}); + + // ignore: public_member_api_docs Future createTemp([String prefix]); + + // ignore: public_member_api_docs Directory createTempSync([String prefix]); - Future resolveSymbolicLinks(); - String resolveSymbolicLinksSync(); + + @override Future rename(String newPath); + + @override Directory renameSync(String newPath); + + @override Directory get absolute; + + // ignore: public_member_api_docs Stream list( {bool recursive: false, bool followLinks: true}); + + // ignore: public_member_api_docs List listSync( {bool recursive: false, bool followLinks: true}); } +// ignore: public_member_api_docs abstract class File implements FileSystemEntity { - String get path; + // ignore: public_member_api_docs Future create({bool recursive: false}); + + // ignore: public_member_api_docs void createSync({bool recursive: false}); + + @override Future rename(String newPath); + + @override File renameSync(String newPath); + + // ignore: public_member_api_docs Future copy(String newPath); + + // ignore: public_member_api_docs File copySync(String newPath); + + // ignore: public_member_api_docs Future length(); + + // ignore: public_member_api_docs int lengthSync(); + + @override File get absolute; + + // ignore: public_member_api_docs Future lastModified(); + + // ignore: public_member_api_docs DateTime lastModifiedSync(); + + // ignore: public_member_api_docs Future open({FileMode mode: FileMode.READ}); + + // ignore: public_member_api_docs RandomAccessFile openSync({FileMode mode: FileMode.READ}); + + // ignore: public_member_api_docs Stream> openRead([int start, int end]); + + // ignore: public_member_api_docs IOSink openWrite({FileMode mode: FileMode.WRITE, Encoding encoding: UTF8}); + + // ignore: public_member_api_docs Future> readAsBytes(); + + // ignore: public_member_api_docs List readAsBytesSync(); + + // ignore: public_member_api_docs Future readAsString({Encoding encoding: UTF8}); + + // ignore: public_member_api_docs String readAsStringSync({Encoding encoding: UTF8}); + + // ignore: public_member_api_docs Future> readAsLines({Encoding encoding: UTF8}); + + // ignore: public_member_api_docs List readAsLinesSync({Encoding encoding: UTF8}); + + // ignore: public_member_api_docs Future writeAsBytes(List bytes, {FileMode mode: FileMode.WRITE, bool flush: false}); + + // ignore: public_member_api_docs void writeAsBytesSync(List bytes, {FileMode mode: FileMode.WRITE, bool flush: false}); + + // ignore: public_member_api_docs Future writeAsString(String contents, {FileMode mode: FileMode.WRITE, Encoding encoding: UTF8, bool flush: false}); + + // ignore: public_member_api_docs void writeAsStringSync(String contents, {FileMode mode: FileMode.WRITE, Encoding encoding: UTF8, bool flush: false}); } +// ignore: public_member_api_docs enum FileLock { + // ignore: constant_identifier_names, public_member_api_docs SHARED, + + // ignore: constant_identifier_names, public_member_api_docs EXCLUSIVE, + + // ignore: constant_identifier_names, public_member_api_docs BLOCKING_SHARED, + + // ignore: constant_identifier_names, public_member_api_docs BLOCKING_EXCLUSIVE, } +// ignore: public_member_api_docs class FileMode { - static const READ = const FileMode._internal(0); - static const WRITE = const FileMode._internal(1); - static const APPEND = const FileMode._internal(2); - static const WRITE_ONLY = const FileMode._internal(3); - static const WRITE_ONLY_APPEND = const FileMode._internal(4); + // ignore: constant_identifier_names, public_member_api_docs + static const FileMode READ = const FileMode._internal(0); + + // ignore: constant_identifier_names, public_member_api_docs + static const FileMode WRITE = const FileMode._internal(1); + + // ignore: constant_identifier_names, public_member_api_docs + static const FileMode APPEND = const FileMode._internal(2); + + // ignore: constant_identifier_names, public_member_api_docs + static const FileMode WRITE_ONLY = const FileMode._internal(3); + + // ignore: constant_identifier_names, public_member_api_docs + static const FileMode WRITE_ONLY_APPEND = const FileMode._internal(4); + final int _mode; // ignore: unused_field + const FileMode._internal(this._mode); } +// ignore: public_member_api_docs abstract class FileStat { + // ignore: public_member_api_docs DateTime get changed; + + // ignore: public_member_api_docs DateTime get modified; + + // ignore: public_member_api_docs DateTime get accessed; + + // ignore: public_member_api_docs FileSystemEntityType get type; + + // ignore: public_member_api_docs int get mode; + + // ignore: public_member_api_docs int get size; + + // ignore: public_member_api_docs String modeString(); } +// ignore: public_member_api_docs abstract class FileSystemEntity { + // ignore: public_member_api_docs String get path; + + // ignore: public_member_api_docs Uri get uri; + + // ignore: public_member_api_docs Future exists(); + + // ignore: public_member_api_docs bool existsSync(); + + // ignore: public_member_api_docs Future rename(String newPath); + + // ignore: public_member_api_docs FileSystemEntity renameSync(String newPath); + + // ignore: public_member_api_docs Future resolveSymbolicLinks(); + + // ignore: public_member_api_docs String resolveSymbolicLinksSync(); + + // ignore: public_member_api_docs Future stat(); + + // ignore: public_member_api_docs FileStat statSync(); + + // ignore: public_member_api_docs Future delete({bool recursive: false}); + + // ignore: public_member_api_docs void deleteSync({bool recursive: false}); + + // ignore: public_member_api_docs Stream watch( {int events: FileSystemEvent.ALL, bool recursive: false}); + + // ignore: public_member_api_docs bool get isAbsolute; + + // ignore: public_member_api_docs FileSystemEntity get absolute; + + // ignore: public_member_api_docs Directory get parent; } +// ignore: public_member_api_docs class FileSystemEntityType { - static const FILE = const FileSystemEntityType._internal(0); - static const DIRECTORY = const FileSystemEntityType._internal(1); - static const LINK = const FileSystemEntityType._internal(2); - static const NOT_FOUND = const FileSystemEntityType._internal(3); + // ignore: constant_identifier_names, public_member_api_docs + static const FileSystemEntityType FILE = + const FileSystemEntityType._internal(0); + + // ignore: constant_identifier_names, public_member_api_docs + static const FileSystemEntityType DIRECTORY = + const FileSystemEntityType._internal(1); + + // ignore: constant_identifier_names, public_member_api_docs + static const FileSystemEntityType LINK = + const FileSystemEntityType._internal(2); + + // ignore: constant_identifier_names, public_member_api_docs + static const FileSystemEntityType NOT_FOUND = + const FileSystemEntityType._internal(3); final int _type; const FileSystemEntityType._internal(this._type); - String toString() => const ['FILE', 'DIRECTORY', 'LINK', 'NOT_FOUND'][_type]; + // ignore: public_member_api_docs + @override + String toString() => + const ['FILE', 'DIRECTORY', 'LINK', 'NOT_FOUND'][_type]; } +// ignore: public_member_api_docs abstract class FileSystemEvent { + // ignore: constant_identifier_names, public_member_api_docs static const int CREATE = 1 << 0; + + // ignore: constant_identifier_names, public_member_api_docs static const int MODIFY = 1 << 1; + + // ignore: constant_identifier_names, public_member_api_docs static const int DELETE = 1 << 2; + + // ignore: constant_identifier_names, public_member_api_docs static const int MOVE = 1 << 3; + + // ignore: constant_identifier_names, public_member_api_docs static const int ALL = CREATE | MODIFY | DELETE | MOVE; + // ignore: public_member_api_docs int get type; + + // ignore: public_member_api_docs String get path; + + // ignore: public_member_api_docs bool get isDirectory; } +// ignore: public_member_api_docs class FileSystemException implements IOException { + // ignore: public_member_api_docs + const FileSystemException([this.message = "", this.path = "", this.osError]); + + // ignore: public_member_api_docs final String message; + + // ignore: public_member_api_docs final String path; - final OSError osError; - const FileSystemException([this.message = "", this.path = "", this.osError]); + // ignore: public_member_api_docs + final OSError osError; + // ignore: public_member_api_docs + @override String toString() { StringBuffer sb = new StringBuffer(); sb.write("FileSystemException"); @@ -161,43 +329,100 @@ class FileSystemException implements IOException { } } +// ignore: public_member_api_docs abstract class IOException implements Exception {} +// ignore: public_member_api_docs abstract class IOSink implements StreamSink>, StringSink { + // ignore: public_member_api_docs Encoding encoding; + + // ignore: public_member_api_docs + @override void add(List data); + + // ignore: public_member_api_docs + @override void write(Object obj); - void writeAll(Iterable objects, [String separator = ""]); + + // ignore: public_member_api_docs + @override + void writeAll(Iterable objects, [String separator = ""]); + + // ignore: public_member_api_docs + @override void writeln([Object obj = ""]); + + // ignore: public_member_api_docs + @override void writeCharCode(int charCode); - void addError(error, [StackTrace stackTrace]); - Future addStream(Stream> stream); - Future flush(); - Future close(); - Future get done; + + // ignore: public_member_api_docs + @override + void addError(dynamic error, [StackTrace stackTrace]); + + // ignore: public_member_api_docs + @override + Future addStream(Stream> stream); + + // ignore: public_member_api_docs + Future flush(); + + // ignore: public_member_api_docs + @override + Future close(); + + // ignore: public_member_api_docs + @override + Future get done; } +// ignore: public_member_api_docs abstract class Link implements FileSystemEntity { + // ignore: public_member_api_docs Future create(String target, {bool recursive: false}); + + // ignore: public_member_api_docs void createSync(String target, {bool recursive: false}); + + // ignore: public_member_api_docs void updateSync(String target); + + // ignore: public_member_api_docs Future update(String target); - Future resolveSymbolicLinks(); - String resolveSymbolicLinksSync(); + + // ignore: public_member_api_docs + @override Future rename(String newPath); + + // ignore: public_member_api_docs + @override Link renameSync(String newPath); + + // ignore: public_member_api_docs + @override Link get absolute; + + // ignore: public_member_api_docs Future target(); + + // ignore: public_member_api_docs String targetSync(); } +// ignore: public_member_api_docs class OSError { + // ignore: public_member_api_docs static const int noErrorCode = -1; + // ignore: public_member_api_docs + const OSError([this.message = "", this.errorCode = noErrorCode]); + + // ignore: public_member_api_docs final String message; - final int errorCode; - const OSError([this.message = "", this.errorCode = noErrorCode]); + // ignore: public_member_api_docs + final int errorCode; @override String toString() { @@ -215,38 +440,96 @@ class OSError { } } +// ignore: public_member_api_docs abstract class RandomAccessFile { + // ignore: public_member_api_docs Future close(); + + // ignore: public_member_api_docs void closeSync(); + + // ignore: public_member_api_docs Future readByte(); + + // ignore: public_member_api_docs int readByteSync(); + + // ignore: public_member_api_docs Future> read(int bytes); + + // ignore: public_member_api_docs List readSync(int bytes); + + // ignore: public_member_api_docs Future readInto(List buffer, [int start = 0, int end]); + + // ignore: public_member_api_docs int readIntoSync(List buffer, [int start = 0, int end]); + + // ignore: public_member_api_docs Future writeByte(int value); + + // ignore: public_member_api_docs int writeByteSync(int value); + + // ignore: public_member_api_docs Future writeFrom(List buffer, [int start = 0, int end]); + + // ignore: public_member_api_docs void writeFromSync(List buffer, [int start = 0, int end]); + + // ignore: public_member_api_docs Future writeString(String string, {Encoding encoding: UTF8}); + + // ignore: public_member_api_docs void writeStringSync(String string, {Encoding encoding: UTF8}); + + // ignore: public_member_api_docs Future position(); + + // ignore: public_member_api_docs int positionSync(); + + // ignore: public_member_api_docs Future setPosition(int position); + + // ignore: public_member_api_docs void setPositionSync(int position); + + // ignore: public_member_api_docs Future truncate(int length); + + // ignore: public_member_api_docs void truncateSync(int length); + + // ignore: public_member_api_docs Future length(); + + // ignore: public_member_api_docs int lengthSync(); + + // ignore: public_member_api_docs Future flush(); + + // ignore: public_member_api_docs void flushSync(); + + // ignore: public_member_api_docs Future lock( [FileLock mode = FileLock.EXCLUSIVE, int start = 0, int end = -1]); + + // ignore: public_member_api_docs void lockSync( [FileLock mode = FileLock.EXCLUSIVE, int start = 0, int end = -1]); + + // ignore: public_member_api_docs Future unlock([int start = 0, int end = -1]); + + // ignore: public_member_api_docs void unlockSync([int start = 0, int end = -1]); + + // ignore: public_member_api_docs String get path; } diff --git a/lib/src/io/shim_dart_io.dart b/lib/src/io/shim_dart_io.dart index 73cbdece91ba1..18744f0399744 100644 --- a/lib/src/io/shim_dart_io.dart +++ b/lib/src/io/shim_dart_io.dart @@ -8,20 +8,46 @@ import 'dart:io' as io; import 'package:file/src/common.dart' as common; -io.Directory newDirectory(path) => new io.Directory(common.getPath(path)); -io.File newFile(path) => new io.File(common.getPath(path)); -io.Link newLink(path) => new io.Link(common.getPath(path)); +/// Creates a new [io.Directory] with the specified [path]. +io.Directory newDirectory(dynamic path) => + new io.Directory(common.getPath(path)); + +/// Creates a new [io.File] with the specified [path]. +io.File newFile(dynamic path) => new io.File(common.getPath(path)); + +/// Creates a new [io.Link] with the specified [path]. +io.Link newLink(dynamic path) => new io.Link(common.getPath(path)); + +/// Wraps [io.Directory.systemTemp]. io.Directory systemTemp() => io.Directory.systemTemp; + +/// Wraps [io.Directory.current]. io.Directory get currentDirectory => io.Directory.current; + +/// Wraps [io.Directory.current=]. set currentDirectory(dynamic path) => io.Directory.current = path; + +/// Wraps [io.FileStat.stat]. Future stat(String path) => io.FileStat.stat(path); + +/// Wraps [io.FileStat.statSync]. io.FileStat statSync(String path) => io.FileStat.statSync(path); + +/// Wraps [io.FileSystemEntity.identical]. Future identical(String path1, String path2) => io.FileSystemEntity.identical(path1, path2); + +/// Wraps [io.FileSystemEntity.identicalSync]. bool identicalSync(String path1, String path2) => io.FileSystemEntity.identicalSync(path1, path2); + +/// Wraps [io.FileSystemEntity.isWatchSupported]. bool get isWatchSupported => io.FileSystemEntity.isWatchSupported; + +/// Wraps [io.FileSystemEntity.type]. Future type(String path, bool followLinks) => io.FileSystemEntity.type(path, followLinks: followLinks); + +/// Wraps [io.FileSystemEntity.typeSync]. io.FileSystemEntityType typeSync(String path, bool followLinks) => io.FileSystemEntity.typeSync(path, followLinks: followLinks); diff --git a/lib/src/io/shim_internal.dart b/lib/src/io/shim_internal.dart index c4b72e81670f3..920c7c760c787 100644 --- a/lib/src/io/shim_internal.dart +++ b/lib/src/io/shim_internal.dart @@ -9,16 +9,41 @@ import 'package:file/src/io.dart' as io; const String _requiresIOMsg = 'This operation requires the use of dart:io'; dynamic _requiresIO() => throw new UnsupportedError(_requiresIOMsg); +/// Throws [UnsupportedError]; browsers cannot use the `local` library. io.Directory newDirectory(_) => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. io.File newFile(_) => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. io.Link newLink(_) => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. io.Directory systemTemp() => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. io.Directory get currentDirectory => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. set currentDirectory(dynamic _) => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. Future stat(String _) => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. io.FileStat statSync(String _) => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. Future identical(String _, String __) => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. bool identicalSync(String _, String __) => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. bool get isWatchSupported => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. Future type(String _, bool __) => _requiresIO(); + +/// Throws [UnsupportedError]; browsers cannot use the `local` library. io.FileSystemEntityType typeSync(String _, bool __) => _requiresIO(); diff --git a/lib/src/testing/core_matchers.dart b/lib/src/testing/core_matchers.dart index d631c2f22bad1..a16977aeb6956 100644 --- a/lib/src/testing/core_matchers.dart +++ b/lib/src/testing/core_matchers.dart @@ -51,6 +51,12 @@ Matcher isFileSystemException([dynamic message]) => Matcher throwsFileSystemException([dynamic message]) => new Throws(isFileSystemException(message)); +/// Expects the specified [callback] to throw a [FileSystemException] with the +/// specified [message]. +void expectFileSystemException(dynamic message, void callback()) { + expect(callback, throwsFileSystemException(message)); +} + class _FileSystemException extends Matcher { final Matcher _matcher; @@ -91,7 +97,11 @@ class _HasPath extends Matcher { @override Description describeMismatch( - item, Description desc, Map matchState, bool verbose) { + dynamic item, + Description desc, + Map matchState, + bool verbose, + ) { desc.add('has path: \'${item.path}\'').add('\n Which: '); Description pathDesc = new StringDescription(); _matcher.describeMismatch(item.path, pathDesc, matchState, verbose); diff --git a/lib/src/testing/record_replay_matchers.dart b/lib/src/testing/record_replay_matchers.dart index 25cc13eea8629..1475ba4ef3dd9 100644 --- a/lib/src/testing/record_replay_matchers.dart +++ b/lib/src/testing/record_replay_matchers.dart @@ -88,14 +88,15 @@ abstract class RecordedInvocation> } /// @nodoc + @override bool matches(dynamic item, Map matchState) { if (!_typeMatcher.matches(item, matchState)) { - addStateInfo(matchState, {'matcher': _typeMatcher}); + addStateInfo(matchState, {'matcher': _typeMatcher}); return false; } for (Matcher matcher in _fieldMatchers) { if (!matcher.matches(item, matchState)) { - addStateInfo(matchState, {'matcher': matcher}); + addStateInfo(matchState, {'matcher': matcher}); return false; } } @@ -103,15 +104,20 @@ abstract class RecordedInvocation> } /// @nodoc - Description describeMismatch(dynamic item, Description mismatchDescription, - Map matchState, bool verbose) { + @override + Description describeMismatch( + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { Matcher matcher = matchState['matcher']; - matcher.describeMismatch( - item, mismatchDescription, matchState['state'], verbose); - return mismatchDescription; + matcher.describeMismatch(item, description, matchState['state'], verbose); + return description; } /// @nodoc + @override Description describe(Description description) { String divider = '\n - '; return _typeMatcher @@ -208,17 +214,22 @@ class _Target extends Matcher { @override Description describeMismatch( - dynamic item, Description desc, Map matchState, bool verbose) { - desc.add('was invoked on: ${item.object}').add('\n Which: '); + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { + description.add('was invoked on: ${item.object}').add('\n Which: '); Description matcherDesc = new StringDescription(); _matcher.describeMismatch(item.object, matcherDesc, matchState, verbose); - desc.add(matcherDesc.toString()); - return desc; + description.add(matcherDesc.toString()); + return description; } - Description describe(Description description) { - description.add('on object: '); - return _matcher.describe(description); + @override + Description describe(Description desc) { + desc.add('on object: '); + return _matcher.describe(desc); } } @@ -232,18 +243,23 @@ class _Result extends Matcher { _matcher.matches(item.result, matchState); @override - Description describeMismatch(dynamic item, Description mismatchDescription, - Map matchState, bool verbose) { - mismatchDescription.add('returned: ${item.result}').add('\n Which: '); + Description describeMismatch( + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { + description.add('returned: ${item.result}').add('\n Which: '); Description matcherDesc = new StringDescription(); _matcher.describeMismatch(item.result, matcherDesc, matchState, verbose); - mismatchDescription.add(matcherDesc.toString()); - return mismatchDescription; + description.add(matcherDesc.toString()); + return description; } - Description describe(Description description) { - description.add('with result: '); - return _matcher.describe(description); + @override + Description describe(Description desc) { + desc.add('with result: '); + return _matcher.describe(desc); } } @@ -257,8 +273,12 @@ class _Type extends Matcher { _kTypeMatchers[type].matches(item, matchState); @override - Description describeMismatch(dynamic item, Description desc, - Map matchState, bool verbose) { + Description describeMismatch( + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { Type type; for (Type matchType in _kTypeMatchers.keys) { Matcher matcher = _kTypeMatchers[matchType]; @@ -268,11 +288,11 @@ class _Type extends Matcher { } } if (type != null) { - desc.add('is ').add(_kTypeDescriptions[type]); + description.add('is ').add(_kTypeDescriptions[type]); } else { - desc.add('is a ${item.runtimeType}'); + description.add('is a ${item.runtimeType}'); } - return desc; + return description; } @override @@ -289,21 +309,24 @@ class _MethodName extends Matcher { _matcher.matches(getSymbolName(item.method), matchState); @override - Description describeMismatch(dynamic item, Description mismatchDescription, - Map matchState, bool verbose) { + Description describeMismatch( + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { String methodName = getSymbolName(item.method); - mismatchDescription - .add('invoked method: \'$methodName\'') - .add('\n Which: '); + description.add('invoked method: \'$methodName\'').add('\n Which: '); Description matcherDesc = new StringDescription(); _matcher.describeMismatch(methodName, matcherDesc, matchState, verbose); - mismatchDescription.add(matcherDesc.toString()); - return mismatchDescription; + description.add(matcherDesc.toString()); + return description; } - Description describe(Description description) { - description.add('method: '); - return _matcher.describe(description); + @override + Description describe(Description desc) { + desc.add('method: '); + return _matcher.describe(desc); } } @@ -317,15 +340,20 @@ class _PositionalArguments extends Matcher { _matcher.matches(item.positionalArguments, matchState); @override - Description describeMismatch(dynamic item, Description desc, - Map matchState, bool verbose) { + Description describeMismatch( + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { return _matcher.describeMismatch( - item.positionalArguments, desc, matchState, verbose); + item.positionalArguments, description, matchState, verbose); } - Description describe(Description description) { - description.add('with positional arguments: '); - return _matcher.describe(description); + @override + Description describe(Description desc) { + desc.add('with positional arguments: '); + return _matcher.describe(desc); } } @@ -343,12 +371,17 @@ class _NamedArgument extends Matcher { _matcher.matches(item.namedArguments, matchState); @override - Description describeMismatch(dynamic item, Description desc, - Map matchState, bool verbose) { + Description describeMismatch( + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { return _matcher.describeMismatch( - item.namedArguments, desc, matchState, verbose); + item.namedArguments, description, matchState, verbose); } + @override Description describe(Description description) => description.add('with named argument "$name" = $value'); } @@ -363,18 +396,21 @@ class _GetPropertyName extends Matcher { _matcher.matches(getSymbolName(item.property), matchState); @override - Description describeMismatch(dynamic item, Description mismatchDescription, - Map matchState, bool verbose) { + Description describeMismatch( + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { String propertyName = getSymbolName(item.property); - mismatchDescription - .add('got property: \'$propertyName\'') - .add('\n Which: '); + description.add('got property: \'$propertyName\'').add('\n Which: '); Description matcherDesc = new StringDescription(); _matcher.describeMismatch(propertyName, matcherDesc, matchState, verbose); - mismatchDescription.add(matcherDesc.toString()); - return mismatchDescription; + description.add(matcherDesc.toString()); + return description; } + @override Description describe(Description description) { description.add('gets property: '); return _matcher.describe(description); @@ -398,18 +434,21 @@ class _SetPropertyName extends Matcher { } @override - Description describeMismatch(dynamic item, Description mismatchDescription, - Map matchState, bool verbose) { + Description describeMismatch( + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { String propertyName = _getPropertyName(item); - mismatchDescription - .add('set property: \'$propertyName\'') - .add('\n Which: '); + description.add('set property: \'$propertyName\'').add('\n Which: '); Description matcherDesc = new StringDescription(); _matcher.describeMismatch(propertyName, matcherDesc, matchState, verbose); - mismatchDescription.add(matcherDesc.toString()); - return mismatchDescription; + description.add(matcherDesc.toString()); + return description; } + @override Description describe(Description description) { description.add('of property: '); return _matcher.describe(description); @@ -426,15 +465,20 @@ class _SetValue extends Matcher { _matcher.matches(item.value, matchState); @override - Description describeMismatch(dynamic item, Description mismatchDescription, - Map matchState, bool verbose) { - mismatchDescription.add('set value: ${item.value}').add('\n Which: '); + Description describeMismatch( + dynamic item, + Description description, + Map matchState, + bool verbose, + ) { + description.add('set value: ${item.value}').add('\n Which: '); Description matcherDesc = new StringDescription(); _matcher.describeMismatch(item.value, matcherDesc, matchState, verbose); - mismatchDescription.add(matcherDesc.toString()); - return mismatchDescription; + description.add(matcherDesc.toString()); + return description; } + @override Description describe(Description description) { description.add('to value: '); return _matcher.describe(description); diff --git a/test/chroot_test.dart b/test/chroot_test.dart index 898a48bbdc724..995d08b5ce552 100644 --- a/test/chroot_test.dart +++ b/test/chroot_test.dart @@ -9,6 +9,7 @@ import 'package:file/chroot.dart'; import 'package:file/file.dart'; import 'package:file/local.dart'; import 'package:file/memory.dart'; +import 'package:file/testing.dart'; import 'package:test/test.dart'; import 'common_tests.dart'; diff --git a/test/common_tests.dart b/test/common_tests.dart index 940b06eca5129..c3c2abf121397 100644 --- a/test/common_tests.dart +++ b/test/common_tests.dart @@ -12,9 +12,9 @@ import 'package:file/testing.dart'; import 'package:test/test.dart'; import 'package:test/test.dart' as testpkg show group, test; -void expectFileSystemException(dynamic msg, void callback()) { - expect(callback, throwsFileSystemException(msg)); -} +/// Callback used in [runCommonTests] to produce the root folder in which all +/// file system entities will be created. +typedef String RootPathGenerator(); /// Runs a suite of tests common to all file system implementations. All file /// system implementations should run *at least* these tests to ensure @@ -31,10 +31,10 @@ void expectFileSystemException(dynamic msg, void callback()) { /// Entries may use regular expression syntax. void runCommonTests( FileSystem createFileSystem(), { - String root(), + RootPathGenerator root, List skip: const [], }) { - var rootfn = root; + RootPathGenerator rootfn = root; group('common', () { FileSystem fs; @@ -42,7 +42,7 @@ void runCommonTests( List stack = []; - void skipIfNecessary(description, callback()) { + void skipIfNecessary(String description, callback()) { stack.add(description); bool matchesCurrentFrame(String input) => new RegExp('^$input\$').hasMatch(stack.join(' > ')); @@ -52,10 +52,10 @@ void runCommonTests( stack.removeLast(); } - void group(description, body()) => + void group(String description, body()) => skipIfNecessary(description, () => testpkg.group(description, body)); - void test(description, body()) => + void test(String description, body()) => skipIfNecessary(description, () => testpkg.test(description, body)); /// Returns [path] prefixed by the [root] namespace. @@ -141,7 +141,7 @@ void runCommonTests( group('systemTempDirectory', () { test('existsAsDirectory', () { - var tmp = fs.systemTempDirectory; + Directory tmp = fs.systemTempDirectory; expect(tmp, isDirectory); expect(tmp.existsSync(), isTrue); }); @@ -270,20 +270,20 @@ void runCommonTests( test('isDirectoryForDirectory', () { fs.directory(ns('/foo')).createSync(); - var stat = fs.statSync(ns('/foo')); + FileStat stat = fs.statSync(ns('/foo')); expect(stat.type, FileSystemEntityType.DIRECTORY); }); test('isFileForFile', () { fs.file(ns('/foo')).createSync(); - var stat = fs.statSync(ns('/foo')); + FileStat stat = fs.statSync(ns('/foo')); expect(stat.type, FileSystemEntityType.FILE); }); test('isFileForLinkToFile', () { fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - var stat = fs.statSync(ns('/bar')); + FileStat stat = fs.statSync(ns('/bar')); expect(stat.type, FileSystemEntityType.FILE); }); @@ -291,7 +291,7 @@ void runCommonTests( fs.link(ns('/foo')).createSync(ns('/bar')); fs.link(ns('/bar')).createSync(ns('/baz')); fs.link(ns('/baz')).createSync(ns('/foo')); - var stat = fs.statSync(ns('/foo')); + FileStat stat = fs.statSync(ns('/foo')); expect(stat.type, FileSystemEntityType.NOT_FOUND); }); }); @@ -337,32 +337,33 @@ void runCommonTests( group('type', () { test('isFileForFile', () { fs.file(ns('/foo')).createSync(); - var type = fs.typeSync(ns('/foo')); + FileSystemEntityType type = fs.typeSync(ns('/foo')); expect(type, FileSystemEntityType.FILE); }); test('isDirectoryForDirectory', () { fs.directory(ns('/foo')).createSync(); - var type = fs.typeSync(ns('/foo')); + FileSystemEntityType type = fs.typeSync(ns('/foo')); expect(type, FileSystemEntityType.DIRECTORY); }); test('isDirectoryForAncestorOfRoot', () { - var type = fs.typeSync('../../../../../../../..'); + FileSystemEntityType type = fs.typeSync('../../../../../../../..'); expect(type, FileSystemEntityType.DIRECTORY); }); test('isFileForLinkToFileAndFollowLinksTrue', () { fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - var type = fs.typeSync(ns('/bar')); + FileSystemEntityType type = fs.typeSync(ns('/bar')); expect(type, FileSystemEntityType.FILE); }); test('isLinkForLinkToFileAndFollowLinksFalse', () { fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - var type = fs.typeSync(ns('/bar'), followLinks: false); + FileSystemEntityType type = + fs.typeSync(ns('/bar'), followLinks: false); expect(type, FileSystemEntityType.LINK); }); @@ -370,17 +371,17 @@ void runCommonTests( fs.link(ns('/foo')).createSync(ns('/bar')); fs.link(ns('/bar')).createSync(ns('/baz')); fs.link(ns('/baz')).createSync(ns('/foo')); - var type = fs.typeSync(ns('/foo')); + FileSystemEntityType type = fs.typeSync(ns('/foo')); expect(type, FileSystemEntityType.NOT_FOUND); }); test('isNotFoundForNoEntityAtTail', () { - var type = fs.typeSync(ns('/foo')); + FileSystemEntityType type = fs.typeSync(ns('/foo')); expect(type, FileSystemEntityType.NOT_FOUND); }); test('isNotFoundForNoDirectoryInTraversal', () { - var type = fs.typeSync(ns('/foo/bar/baz')); + FileSystemEntityType type = fs.typeSync(ns('/foo/bar/baz')); expect(type, FileSystemEntityType.NOT_FOUND); }); }); @@ -519,30 +520,30 @@ void runCommonTests( }); test('succeedsIfDestinationDoesntExist', () { - var src = fs.directory(ns('/foo'))..createSync(); - var dest = src.renameSync(ns('/bar')); + Directory src = fs.directory(ns('/foo'))..createSync(); + Directory dest = src.renameSync(ns('/bar')); expect(dest.path, ns('/bar')); expect(dest.existsSync(), true); }); test('succeedsIfDestinationIsEmptyDirectory', () { fs.directory(ns('/bar')).createSync(); - var src = fs.directory(ns('/foo'))..createSync(); - var dest = src.renameSync(ns('/bar')); + Directory src = fs.directory(ns('/foo'))..createSync(); + Directory dest = src.renameSync(ns('/bar')); expect(src.existsSync(), false); expect(dest.existsSync(), true); }); test('throwsIfDestinationIsFile', () { fs.file(ns('/bar')).createSync(); - var src = fs.directory(ns('/foo'))..createSync(); + Directory src = fs.directory(ns('/foo'))..createSync(); expectFileSystemException('Not a directory', () { src.renameSync(ns('/bar')); }); }); test('throwsIfDestinationParentFolderDoesntExist', () { - var src = fs.directory(ns('/foo'))..createSync(); + Directory src = fs.directory(ns('/foo'))..createSync(); expectFileSystemException('No such file or directory', () { src.renameSync(ns('/bar/baz')); }); @@ -550,7 +551,7 @@ void runCommonTests( test('throwsIfDestinationIsNonEmptyDirectory', () { fs.file(ns('/bar/baz')).createSync(recursive: true); - var src = fs.directory(ns('/foo'))..createSync(); + Directory src = fs.directory(ns('/foo'))..createSync(); // The error will be 'Directory not empty' on OS X, but it will be // 'File exists' on Linux, so we just ignore it here in the test. expectFileSystemException(null, () { @@ -596,7 +597,7 @@ void runCommonTests( }); test('throwsIfDestinationIsLinkToEmptyDirectory', () { - var src = fs.directory(ns('/foo'))..createSync(); + Directory src = fs.directory(ns('/foo'))..createSync(); fs.directory(ns('/bar')).createSync(); fs.link(ns('/baz')).createSync(ns('/bar')); expectFileSystemException('Not a directory', () { @@ -605,7 +606,7 @@ void runCommonTests( }); test('succeedsIfDestinationIsInDifferentDirectory', () { - var src = fs.directory(ns('/foo'))..createSync(); + Directory src = fs.directory(ns('/foo'))..createSync(); fs.directory(ns('/bar')).createSync(); src.renameSync(ns('/bar/baz')); expect(fs.typeSync(ns('/foo')), FileSystemEntityType.NOT_FOUND); @@ -634,19 +635,19 @@ void runCommonTests( }); test('succeedsIfEmptyDirectoryExistsAndRecursiveFalse', () { - var dir = fs.directory(ns('/foo'))..createSync(); + Directory dir = fs.directory(ns('/foo'))..createSync(); dir.deleteSync(); expect(dir.existsSync(), false); }); test('succeedsIfEmptyDirectoryExistsAndRecursiveTrue', () { - var dir = fs.directory(ns('/foo'))..createSync(); + Directory dir = fs.directory(ns('/foo'))..createSync(); dir.deleteSync(recursive: true); expect(dir.existsSync(), false); }); test('throwsIfNonEmptyDirectoryExistsAndRecursiveFalse', () { - var dir = fs.directory(ns('/foo'))..createSync(); + Directory dir = fs.directory(ns('/foo'))..createSync(); fs.file(ns('/foo/bar')).createSync(); expectFileSystemException('Directory not empty', () { dir.deleteSync(); @@ -654,7 +655,7 @@ void runCommonTests( }); test('succeedsIfNonEmptyDirectoryExistsAndRecursiveTrue', () { - var dir = fs.directory(ns('/foo'))..createSync(); + Directory dir = fs.directory(ns('/foo'))..createSync(); fs.file(ns('/foo/bar')).createSync(); dir.deleteSync(recursive: true); expect(fs.directory(ns('/foo')).existsSync(), false); @@ -823,7 +824,7 @@ void runCommonTests( test('handlesParentAndThisFolderReferences', () { fs.directory(ns('/foo/bar/baz')).createSync(recursive: true); fs.link(ns('/foo/bar/baz/qux')).createSync('../..'); - var resolved = fs + String resolved = fs .directory(ns('/foo/./bar/baz/../baz/qux/bar')) .resolveSymbolicLinksSync(); expect(resolved, ns('/foo/bar')); @@ -839,7 +840,7 @@ void runCommonTests( fs.link(ns('/foo/bar/baz')).createSync('../../qux', recursive: true); fs.link(ns('/qux')).createSync('quux'); fs.link(ns('/quux/quuz')).createSync(ns('/foo'), recursive: true); - var resolved = fs + String resolved = fs .directory(ns('/foo//bar/./baz/quuz/bar/..///bar/baz/')) .resolveSymbolicLinksSync(); expect(resolved, ns('/quux')); @@ -887,29 +888,29 @@ void runCommonTests( test('resolvesNameCollisions', () { fs.directory(ns('/foo/bar')).createSync(recursive: true); - var tmp = fs.directory(ns('/foo')).createTempSync('bar'); + Directory tmp = fs.directory(ns('/foo')).createTempSync('bar'); expect(tmp.path, allOf(isNot(ns('/foo/bar')), startsWith(ns('/foo/bar')))); }); test('succeedsWithoutPrefix', () { - var dir = fs.directory(ns('/foo'))..createSync(); + Directory dir = fs.directory(ns('/foo'))..createSync(); expect(dir.createTempSync().path, startsWith(ns('/foo/'))); }); test('succeedsWithPrefix', () { - var dir = fs.directory(ns('/foo'))..createSync(); + Directory dir = fs.directory(ns('/foo'))..createSync(); expect(dir.createTempSync('bar').path, startsWith(ns('/foo/bar'))); }); test('succeedsWithNestedPathPrefixThatExists', () { fs.directory(ns('/foo/bar')).createSync(recursive: true); - var tmp = fs.directory(ns('/foo')).createTempSync('bar/baz'); + Directory tmp = fs.directory(ns('/foo')).createTempSync('bar/baz'); expect(tmp.path, startsWith(ns('/foo/bar/baz'))); }); test('throwsWithNestedPathPrefixThatDoesntExist', () { - var dir = fs.directory(ns('/foo'))..createSync(); + Directory dir = fs.directory(ns('/foo'))..createSync(); expectFileSystemException('No such file or directory', () { dir.createTempSync('bar/baz'); }); @@ -930,7 +931,7 @@ void runCommonTests( }); test('returnsCovariantType', () async { - void expectIsFileSystemEntity(entity) { + void expectIsFileSystemEntity(dynamic entity) { expect(entity, isFileSystemEntity); } @@ -939,7 +940,7 @@ void runCommonTests( }); test('returnsEmptyListForEmptyDirectory', () { - var empty = fs.directory(ns('/bar'))..createSync(); + Directory empty = fs.directory(ns('/bar'))..createSync(); expect(empty.listSync(), isEmpty); }); @@ -950,7 +951,7 @@ void runCommonTests( }); test('returnsLinkObjectsIfFollowLinksFalse', () { - var list = dir.listSync(followLinks: false); + List list = dir.listSync(followLinks: false); expect(list, hasLength(3)); expect(list, contains(allOf(isFile, hasPath(ns('/foo/bar'))))); expect(list, contains(allOf(isDirectory, hasPath(ns('/foo/baz'))))); @@ -958,7 +959,7 @@ void runCommonTests( }); test('followsLinksIfFollowLinksTrue', () { - var list = dir.listSync(); + List list = dir.listSync(); expect(list, hasLength(3)); expect(list, contains(allOf(isFile, hasPath(ns('/foo/bar'))))); expect(list, contains(allOf(isDirectory, hasPath(ns('/foo/baz'))))); @@ -1005,7 +1006,8 @@ void runCommonTests( test('childEntriesNotNormalized', () { dir = fs.directory(ns('/bar/baz'))..createSync(recursive: true); fs.file(ns('/bar/baz/qux')).createSync(); - var list = fs.directory(ns('/bar//../bar/./baz')).listSync(); + List list = + fs.directory(ns('/bar//../bar/./baz')).listSync(); expect(list, hasLength(1)); expect(list[0], allOf(isFile, hasPath(ns('/bar//../bar/./baz/qux')))); }); @@ -1013,8 +1015,9 @@ void runCommonTests( test('symlinksToNotFoundAlwaysReturnedAsLinks', () { dir = fs.directory(ns('/bar'))..createSync(); fs.link(ns('/bar/baz')).createSync('qux'); - for (bool followLinks in [true, false]) { - var list = dir.listSync(followLinks: followLinks); + for (bool followLinks in const [true, false]) { + List list = + dir.listSync(followLinks: followLinks); expect(list, hasLength(1)); expect(list[0], allOf(isLink, hasPath(ns('/bar/baz')))); } @@ -1459,7 +1462,7 @@ void runCommonTests( }); } else { test('createsFileIfDoesntExistAtTail', () { - var raf = fs.file(ns('/bar')).openSync(mode: mode); + RandomAccessFile raf = fs.file(ns('/bar')).openSync(mode: mode); raf.closeSync(); expect(fs.file(ns('/bar')).existsSync(), true); }); @@ -1833,8 +1836,8 @@ void runCommonTests( test('succeedsIfExistsAsFile', () async { File f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world', flush: true); - var stream = f.openRead(); - var data = await stream.toList(); + Stream> stream = f.openRead(); + List> data = await stream.toList(); expect(data, hasLength(1)); expect(UTF8.decode(data[0]), 'Hello world'); }); @@ -1849,8 +1852,8 @@ void runCommonTests( File f = fs.file(ns('/foo'))..createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); f.writeAsStringSync('Hello world', flush: true); - var stream = fs.file(ns('/bar')).openRead(); - var data = await stream.toList(); + Stream> stream = fs.file(ns('/bar')).openRead(); + List> data = await stream.toList(); expect(data, hasLength(1)); expect(UTF8.decode(data[0]), 'Hello world'); }); @@ -1858,8 +1861,8 @@ void runCommonTests( test('respectsStartAndEndParameters', () async { File f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world', flush: true); - var stream = f.openRead(2); - var data = await stream.toList(); + Stream> stream = f.openRead(2); + List> data = await stream.toList(); expect(data, hasLength(1)); expect(UTF8.decode(data[0]), 'llo world'); stream = f.openRead(2, 5); @@ -1870,15 +1873,15 @@ void runCommonTests( test('throwsIfStartParameterIsNegative', () async { File f = fs.file(ns('/foo'))..createSync(); - var stream = f.openRead(-2); + Stream> stream = f.openRead(-2); expect(stream.drain(), throwsRangeError); }); test('stopsAtEndOfFileIfEndParameterIsPastEndOfFile', () async { File f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world', flush: true); - var stream = f.openRead(2, 1024); - var data = await stream.toList(); + Stream> stream = f.openRead(2, 1024); + List> data = await stream.toList(); expect(data, hasLength(1)); expect(UTF8.decode(data[0]), 'llo world'); }); @@ -1886,7 +1889,7 @@ void runCommonTests( test('providesSingleSubscriptionStream', () async { File f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world', flush: true); - var stream = f.openRead(); + Stream> stream = f.openRead(); expect(stream.isBroadcast, isFalse); await stream.drain(); }); @@ -1961,7 +1964,7 @@ void runCommonTests( bool isSinkClosed = false; Future closeSink() { - var future = sink.close(); + Future future = sink.close(); isSinkClosed = true; return future; } @@ -2036,14 +2039,14 @@ void runCommonTests( test('ignoresCloseAfterAlreadyClosed', () async { sink.write('Hello world'); - Future f1 = closeSink(); - Future f2 = closeSink(); - await Future.wait([f1, f2]); + Future f1 = closeSink(); + Future f2 = closeSink(); + await Future.wait(>[f1, f2]); }); test('returnsAccurateDoneFuture', () async { bool done = false; - sink.done.then((_) => done = true); + sink.done.then((_) => done = true); // ignore: unawaited_futures expect(done, isFalse); sink.write('foo'); expect(done, isFalse); @@ -2056,7 +2059,7 @@ void runCommonTests( bool isControllerClosed = false; Future closeController() { - var future = controller.close(); + Future future = controller.close(); isControllerClosed = true; return future; } diff --git a/test/recording_test.dart b/test/recording_test.dart index ec0e52b148d4d..e9c5118965b73 100644 --- a/test/recording_test.dart +++ b/test/recording_test.dart @@ -37,7 +37,7 @@ void main() { test('supportsMultipleActions', () { fs.directory('/foo').createSync(); fs.file('/foo/bar').writeAsStringSync('BAR'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(4)); expect(events[0], invokesMethod('directory')); expect(events[1], invokesMethod('createSync')); @@ -50,51 +50,54 @@ void main() { group('FileSystem', () { test('directory', () { fs.directory('/foo'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( - events[0], - invokesMethod('directory') - .on(fs) - .withPositionalArguments(['/foo']).withResult(isDirectory)); + events[0], + invokesMethod('directory').on(fs).withPositionalArguments( + ['/foo']).withResult(isDirectory), + ); }); test('file', () { fs.file('/foo'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( - events[0], - invokesMethod('file') - .on(fs) - .withPositionalArguments(['/foo']).withResult(isFile)); + events[0], + invokesMethod('file') + .on(fs) + .withPositionalArguments(['/foo']).withResult(isFile), + ); }); test('link', () { fs.link('/foo'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( - events[0], - invokesMethod('link') - .on(fs) - .withPositionalArguments(['/foo']).withResult(isLink)); + events[0], + invokesMethod('link') + .on(fs) + .withPositionalArguments(['/foo']).withResult(isLink), + ); }); test('path', () { fs.path; - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( - events[0], - getsProperty('path') - .on(fs) - .withResult(const isInstanceOf())); + events[0], + getsProperty('path') + .on(fs) + .withResult(const isInstanceOf()), + ); }); test('systemTempDirectory', () { fs.systemTempDirectory; - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( events[0], @@ -106,7 +109,7 @@ void main() { group('currentDirectory', () { test('get', () { fs.currentDirectory; - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( events[0], @@ -118,7 +121,7 @@ void main() { test('setToString', () { delegate.directory('/foo').createSync(); fs.currentDirectory = '/foo'; - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect(events[0], setsProperty('currentDirectory').on(fs).toValue('/foo')); @@ -127,7 +130,7 @@ void main() { test('setToRecordingDirectory', () { delegate.directory('/foo').createSync(); fs.currentDirectory = fs.directory('/foo'); - var events = recording.events; + List> events = recording.events; expect(events.length, greaterThanOrEqualTo(2)); expect(events[0], invokesMethod().withResult(isDirectory)); Directory directory = events[0].result; @@ -142,7 +145,7 @@ void main() { Directory dir = delegate.directory('/foo'); dir.createSync(); fs.currentDirectory = dir; - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect(events[0], setsProperty('currentDirectory').on(fs).toValue(isDirectory)); @@ -152,26 +155,24 @@ void main() { test('stat', () async { delegate.file('/foo').createSync(); await fs.stat('/foo'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( events[0], - invokesMethod('stat') - .on(fs) - .withPositionalArguments(['/foo']).withResult(isFileStat), + invokesMethod('stat').on(fs).withPositionalArguments( + ['/foo']).withResult(isFileStat), ); }); test('statSync', () { delegate.file('/foo').createSync(); fs.statSync('/foo'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( events[0], - invokesMethod('statSync') - .on(fs) - .withPositionalArguments(['/foo']).withResult(isFileStat), + invokesMethod('statSync').on(fs).withPositionalArguments( + ['/foo']).withResult(isFileStat), ); }); @@ -179,29 +180,29 @@ void main() { delegate.file('/foo').createSync(); delegate.file('/bar').createSync(); await fs.identical('/foo', '/bar'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( events[0], invokesMethod('identical').on(fs).withPositionalArguments( - ['/foo', '/bar']).withResult(isFalse)); + ['/foo', '/bar']).withResult(isFalse)); }); test('identicalSync', () { delegate.file('/foo').createSync(); delegate.file('/bar').createSync(); fs.identicalSync('/foo', '/bar'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( events[0], invokesMethod('identicalSync').on(fs).withPositionalArguments( - ['/foo', '/bar']).withResult(isFalse)); + ['/foo', '/bar']).withResult(isFalse)); }); test('isWatchSupported', () { fs.isWatchSupported; - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect(events[0], getsProperty('isWatchSupported').on(fs).withResult(isFalse)); @@ -210,23 +211,23 @@ void main() { test('type', () async { delegate.file('/foo').createSync(); await fs.type('/foo'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( events[0], invokesMethod('type').on(fs).withPositionalArguments( - ['/foo']).withResult(FileSystemEntityType.FILE)); + ['/foo']).withResult(FileSystemEntityType.FILE)); }); test('typeSync', () { delegate.file('/foo').createSync(); fs.typeSync('/foo'); - var events = recording.events; + List> events = recording.events; expect(events, hasLength(1)); expect( events[0], invokesMethod('typeSync').on(fs).withPositionalArguments( - ['/foo']).withResult(FileSystemEntityType.FILE)); + ['/foo']).withResult(FileSystemEntityType.FILE)); }); });