diff --git a/.github/ISSUE_TEMPLATE/timing.md b/.github/ISSUE_TEMPLATE/timing.md new file mode 100644 index 000000000..38a001578 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/timing.md @@ -0,0 +1,5 @@ +--- +name: "package:timing" +about: "Create a bug or file a feature request against package:timing." +labels: "package:timing" +--- \ No newline at end of file diff --git a/.github/labeler.yml b/.github/labeler.yml index 16a5ce833..fd072d2aa 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -112,6 +112,10 @@ - changed-files: - any-glob-to-any-file: 'pkgs/test_reflective_loader/**' +'package:timing': + - changed-files: + - any-glob-to-any-file: 'pkgs/timing/**' + 'package:unified_analytics': - changed-files: - any-glob-to-any-file: 'pkgs/unified_analytics/**' diff --git a/.github/workflows/timing.yaml b/.github/workflows/timing.yaml new file mode 100644 index 000000000..df77b137e --- /dev/null +++ b/.github/workflows/timing.yaml @@ -0,0 +1,67 @@ +name: package:timing + +on: + # Run on PRs and pushes to the default branch. + push: + branches: [ main ] + paths: + - '.github/workflows/timing.yaml' + - 'pkgs/timing/**' + pull_request: + branches: [ main ] + paths: + - '.github/workflows/timing.yaml' + - 'pkgs/timing/**' + schedule: + - cron: "0 0 * * 0" + +env: + PUB_ENVIRONMENT: bot.github + + +defaults: + run: + working-directory: pkgs/timing/ + +jobs: + # Check code formatting and static analysis on a single OS (linux) + # against Dart dev. + analyze: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sdk: [3.4, dev] + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 + with: + sdk: ${{ matrix.sdk }} + - id: install + run: dart pub get + - run: dart format --output=none --set-exit-if-changed . + if: always() && steps.install.outcome == 'success' + - run: dart analyze --fatal-infos + if: always() && steps.install.outcome == 'success' + + # Run tests on a matrix consisting of two dimensions: + # 1. OS: ubuntu-latest, (macos-latest, windows-latest) + # 2. release channel: dev, 2.2.0 + test: + needs: analyze + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Add macos-latest and/or windows-latest if relevant for this package. + os: [ubuntu-latest] + sdk: [3.4, dev] + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 + with: + sdk: ${{ matrix.sdk }} + - id: install + run: dart pub get + - run: dart test --platform vm + if: always() && steps.install.outcome == 'success' diff --git a/README.md b/README.md index 74be5a926..140d6e876 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ don't naturally belong to other topic monorepos (like | [source_span](pkgs/source_span/) | Provides a standard representation for source code locations and spans. | [![package issues](https://img.shields.io/badge/package:source_span-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_span) | [![pub package](https://img.shields.io/pub/v/source_span.svg)](https://pub.dev/packages/source_span) | | [sse](pkgs/sse/) | Provides client and server functionality for setting up bi-directional communication through Server Sent Events (SSE) and corresponding POST requests. | [![package issues](https://img.shields.io/badge/package:sse-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asse) | [![pub package](https://img.shields.io/pub/v/sse.svg)](https://pub.dev/packages/sse) | | [test_reflective_loader](pkgs/test_reflective_loader/) | Support for discovering tests and test suites using reflection. | [![package issues](https://img.shields.io/badge/package:test_reflective_loader-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Atest_reflective_loader) | [![pub package](https://img.shields.io/pub/v/test_reflective_loader.svg)](https://pub.dev/packages/test_reflective_loader) | +| [timing](pkgs/timing/) | A simple package for tracking the performance of synchronous and asynchronous actions. | [![package issues](https://img.shields.io/badge/package:timing-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Atiming) | [![pub package](https://img.shields.io/pub/v/timing.svg)](https://pub.dev/packages/timing) | | [unified_analytics](pkgs/unified_analytics/) | A package for logging analytics for all Dart and Flutter related tooling to Google Analytics. | [![package issues](https://img.shields.io/badge/package:unified_analytics-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics) | [![pub package](https://img.shields.io/pub/v/unified_analytics.svg)](https://pub.dev/packages/unified_analytics) | ## Publishing automation diff --git a/pkgs/file/CHANGELOG.md b/pkgs/file/CHANGELOG.md index 50c96c49d..3a3969cad 100644 --- a/pkgs/file/CHANGELOG.md +++ b/pkgs/file/CHANGELOG.md @@ -1,3 +1,5 @@ +## 7.0.2-wip + ## 7.0.1 * Update the pubspec repository field to reflect the new package repository. diff --git a/pkgs/file/analysis_options.yaml b/pkgs/file/analysis_options.yaml index 8fbd2e443..d978f811c 100644 --- a/pkgs/file/analysis_options.yaml +++ b/pkgs/file/analysis_options.yaml @@ -1,6 +1 @@ -include: package:lints/recommended.yaml - -analyzer: - errors: - # Allow having TODOs in the code - todo: ignore +include: package:dart_flutter_team_lints/analysis_options.yaml diff --git a/pkgs/file/example/main.dart b/pkgs/file/example/main.dart index 7ca0bc73f..b03b363f0 100644 --- a/pkgs/file/example/main.dart +++ b/pkgs/file/example/main.dart @@ -7,8 +7,8 @@ import 'package:file/memory.dart'; Future main() async { final FileSystem fs = MemoryFileSystem(); - final Directory tmp = await fs.systemTempDirectory.createTemp('example_'); - final File outputFile = tmp.childFile('output'); + final tmp = await fs.systemTempDirectory.createTemp('example_'); + final outputFile = tmp.childFile('output'); await outputFile.writeAsString('Hello world!'); print(outputFile.readAsStringSync()); } diff --git a/pkgs/file/lib/chroot.dart b/pkgs/file/lib/chroot.dart index 56d2bd5d7..6992ad0b4 100644 --- a/pkgs/file/lib/chroot.dart +++ b/pkgs/file/lib/chroot.dart @@ -3,4 +3,6 @@ // BSD-style license that can be found in the LICENSE file. /// A file system that provides a view into _another_ `FileSystem` via a path. +library; + export 'src/backends/chroot.dart'; diff --git a/pkgs/file/lib/file.dart b/pkgs/file/lib/file.dart index cdde9fedd..c2e97b2ee 100644 --- a/pkgs/file/lib/file.dart +++ b/pkgs/file/lib/file.dart @@ -4,5 +4,7 @@ /// Core interfaces containing the abstract `FileSystem` interface definition /// and all associated types used by `FileSystem`. +library; + export 'src/forwarding.dart'; export 'src/interface.dart'; diff --git a/pkgs/file/lib/local.dart b/pkgs/file/lib/local.dart index 74f506e36..5b1e3cd9d 100644 --- a/pkgs/file/lib/local.dart +++ b/pkgs/file/lib/local.dart @@ -4,4 +4,6 @@ /// A local file system implementation. This relies on the use of `dart:io` /// and is thus not suitable for use in the browser. +library; + export 'src/backends/local.dart'; diff --git a/pkgs/file/lib/memory.dart b/pkgs/file/lib/memory.dart index c5705eff9..690b65fa5 100644 --- a/pkgs/file/lib/memory.dart +++ b/pkgs/file/lib/memory.dart @@ -4,5 +4,7 @@ /// An implementation of `FileSystem` that exists entirely in memory with an /// internal representation loosely based on the Filesystem Hierarchy Standard. +library; + export 'src/backends/memory.dart'; export 'src/backends/memory/operations.dart'; diff --git a/pkgs/file/lib/src/backends/chroot.dart b/pkgs/file/lib/src/backends/chroot.dart index 6082e808c..402dbec5b 100644 --- a/pkgs/file/lib/src/backends/chroot.dart +++ b/pkgs/file/lib/src/backends/chroot.dart @@ -2,16 +2,16 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library file.src.backends.chroot; - import 'dart:convert'; import 'dart:typed_data'; -import 'package:file/file.dart'; -import 'package:file/src/common.dart' as common; -import 'package:file/src/io.dart' as io; import 'package:path/path.dart' as p; +import '../common.dart' as common; +import '../forwarding.dart'; +import '../interface.dart'; +import '../io.dart' as io; + part 'chroot/chroot_directory.dart'; part 'chroot/chroot_file.dart'; part 'chroot/chroot_file_system.dart'; diff --git a/pkgs/file/lib/src/backends/chroot/chroot_directory.dart b/pkgs/file/lib/src/backends/chroot/chroot_directory.dart index 8fec7b198..e09419384 100644 --- a/pkgs/file/lib/src/backends/chroot/chroot_directory.dart +++ b/pkgs/file/lib/src/backends/chroot/chroot_directory.dart @@ -2,18 +2,18 @@ // 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. -part of file.src.backends.chroot; +part of '../chroot.dart'; class _ChrootDirectory extends _ChrootFileSystemEntity with ForwardingDirectory, common.DirectoryAddOnsMixin { - _ChrootDirectory(ChrootFileSystem fs, String path) : super(fs, path); + _ChrootDirectory(super.fs, super.path); factory _ChrootDirectory.wrapped( ChrootFileSystem fs, Directory delegate, { bool relative = false, }) { - String localPath = fs._local(delegate.path, relative: relative); + var localPath = fs._local(delegate.path, relative: relative); return _ChrootDirectory(fs, localPath); } @@ -32,7 +32,7 @@ class _ChrootDirectory extends _ChrootFileSystemEntity if (await fileSystem.type(path) != expectedType) { throw common.notADirectory(path); } - FileSystemEntityType type = await fileSystem.type(newPath); + var type = await fileSystem.type(newPath); if (type != FileSystemEntityType.notFound) { if (type != expectedType) { throw common.notADirectory(newPath); @@ -44,7 +44,7 @@ class _ChrootDirectory extends _ChrootFileSystemEntity throw common.directoryNotEmpty(newPath); } } - String target = await fileSystem.link(path).target(); + var target = await fileSystem.link(path).target(); await fileSystem.link(path).delete(); await fileSystem.link(newPath).create(target); return fileSystem.directory(newPath); @@ -60,7 +60,7 @@ class _ChrootDirectory extends _ChrootFileSystemEntity if (fileSystem.typeSync(path) != expectedType) { throw common.notADirectory(path); } - FileSystemEntityType type = fileSystem.typeSync(newPath); + var type = fileSystem.typeSync(newPath); if (type != FileSystemEntityType.notFound) { if (type != expectedType) { throw common.notADirectory(newPath); @@ -72,7 +72,7 @@ class _ChrootDirectory extends _ChrootFileSystemEntity throw common.directoryNotEmpty(newPath); } } - String target = fileSystem.link(path).targetSync(); + var target = fileSystem.link(path).targetSync(); fileSystem.link(path).deleteSync(); fileSystem.link(newPath).createSync(target); return fileSystem.directory(newPath); @@ -97,17 +97,15 @@ class _ChrootDirectory extends _ChrootFileSystemEntity @override Future create({bool recursive = false}) async { if (_isLink) { - switch (await fileSystem.type(path)) { - case FileSystemEntityType.notFound: - throw common.noSuchFileOrDirectory(path); - case FileSystemEntityType.file: - throw common.fileExists(path); - case FileSystemEntityType.directory: + return switch (await fileSystem.type(path)) { + FileSystemEntityType.notFound => + throw common.noSuchFileOrDirectory(path), + FileSystemEntityType.file => throw common.fileExists(path), + FileSystemEntityType.directory => // Nothing to do. - return this; - default: - throw AssertionError(); - } + this, + _ => throw AssertionError() + }; } else { return wrap(await delegate.create(recursive: recursive)); } @@ -137,8 +135,8 @@ class _ChrootDirectory extends _ChrootFileSystemEntity bool recursive = false, bool followLinks = true, }) { - Directory delegate = this.delegate as Directory; - String dirname = delegate.path; + var delegate = this.delegate as Directory; + var dirname = delegate.path; return delegate .list(recursive: recursive, followLinks: followLinks) .map((io.FileSystemEntity entity) => _denormalize(entity, dirname)); @@ -149,8 +147,8 @@ class _ChrootDirectory extends _ChrootFileSystemEntity bool recursive = false, bool followLinks = true, }) { - Directory delegate = this.delegate as Directory; - String dirname = delegate.path; + var delegate = this.delegate as Directory; + var dirname = delegate.path; return delegate .listSync(recursive: recursive, followLinks: followLinks) .map((io.FileSystemEntity entity) => _denormalize(entity, dirname)) @@ -158,9 +156,9 @@ class _ChrootDirectory extends _ChrootFileSystemEntity } FileSystemEntity _denormalize(io.FileSystemEntity entity, String dirname) { - p.Context ctx = fileSystem.path; - String relativePart = ctx.relative(entity.path, from: dirname); - String entityPath = ctx.join(path, relativePart); + var ctx = fileSystem.path; + var relativePart = ctx.relative(entity.path, from: dirname); + var entityPath = ctx.join(path, relativePart); if (entity is io.File) { return _ChrootFile(fileSystem, entityPath); } else if (entity is io.Directory) { diff --git a/pkgs/file/lib/src/backends/chroot/chroot_file.dart b/pkgs/file/lib/src/backends/chroot/chroot_file.dart index 4b67bc1f6..d6c29fcff 100644 --- a/pkgs/file/lib/src/backends/chroot/chroot_file.dart +++ b/pkgs/file/lib/src/backends/chroot/chroot_file.dart @@ -2,20 +2,20 @@ // 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. -part of file.src.backends.chroot; +part of '../chroot.dart'; typedef _SetupCallback = dynamic Function(); class _ChrootFile extends _ChrootFileSystemEntity with ForwardingFile { - _ChrootFile(ChrootFileSystem fs, String path) : super(fs, path); + _ChrootFile(super.fs, super.path); factory _ChrootFile.wrapped( ChrootFileSystem fs, io.File delegate, { bool relative = false, }) { - String localPath = fs._local(delegate.path, relative: relative); + var localPath = fs._local(delegate.path, relative: relative); return _ChrootFile(fs, localPath); } @@ -126,7 +126,7 @@ class _ChrootFile extends _ChrootFileSystemEntity @override Future create({bool recursive = false, bool exclusive = false}) async { - String path = fileSystem._resolve( + var path = fileSystem._resolve( this.path, followLinks: false, notFound: recursive ? _NotFoundBehavior.mkdir : _NotFoundBehavior.allow, @@ -158,7 +158,7 @@ class _ChrootFile extends _ChrootFileSystemEntity @override void createSync({bool recursive = false, bool exclusive = false}) { - String path = fileSystem._resolve( + var path = fileSystem._resolve( this.path, followLinks: false, notFound: recursive ? _NotFoundBehavior.mkdir : _NotFoundBehavior.allow, diff --git a/pkgs/file/lib/src/backends/chroot/chroot_file_system.dart b/pkgs/file/lib/src/backends/chroot/chroot_file_system.dart index 6889c987b..503821fb4 100644 --- a/pkgs/file/lib/src/backends/chroot/chroot_file_system.dart +++ b/pkgs/file/lib/src/backends/chroot/chroot_file_system.dart @@ -2,7 +2,7 @@ // 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. -part of file.src.backends.chroot; +part of '../chroot.dart'; const String _thisDir = '.'; const String _parentDir = '..'; @@ -107,7 +107,7 @@ class ChrootFileSystem extends FileSystem { } value = _resolve(value, notFound: _NotFoundBehavior.throwError); - String realPath = _real(value, resolve: false); + var realPath = _real(value, resolve: false); switch (delegate.typeSync(realPath, followLinks: false)) { case FileSystemEntityType.directory: break; @@ -117,7 +117,7 @@ class ChrootFileSystem extends FileSystem { throw common.notADirectory(path as String); } assert(() { - p.Context ctx = delegate.path; + var ctx = delegate.path; return ctx.isAbsolute(value) && value == ctx.canonicalize(value); }()); _cwd = value; @@ -201,7 +201,7 @@ class ChrootFileSystem extends FileSystem { throw _ChrootJailException(); } // TODO(tvolkert): See if _context.relative() works here - String result = realPath.substring(root.length); + var result = realPath.substring(root.length); if (result.isEmpty) { result = _localRoot; } @@ -263,8 +263,8 @@ class ChrootFileSystem extends FileSystem { throw common.noSuchFileOrDirectory(path); } - p.Context ctx = this.path; - String root = _localRoot; + var ctx = this.path; + var root = _localRoot; List parts, ledger; if (ctx.isAbsolute(path)) { parts = ctx.split(path).sublist(1); @@ -277,9 +277,9 @@ class ChrootFileSystem extends FileSystem { } String getCurrentPath() => root + ctx.joinAll(ledger); - Set breadcrumbs = {}; + var breadcrumbs = {}; while (parts.isNotEmpty) { - String segment = parts.removeAt(0); + var segment = parts.removeAt(0); if (segment == _thisDir) { continue; } else if (segment == _parentDir) { @@ -290,8 +290,8 @@ class ChrootFileSystem extends FileSystem { } ledger.add(segment); - String currentPath = getCurrentPath(); - String realPath = _real(currentPath, resolve: false); + var currentPath = getCurrentPath(); + var realPath = _real(currentPath, resolve: false); switch (delegate.typeSync(realPath, followLinks: false)) { case FileSystemEntityType.directory: @@ -333,7 +333,7 @@ class ChrootFileSystem extends FileSystem { if (!breadcrumbs.add(currentPath)) { throw common.tooManyLevelsOfSymbolicLinks(path); } - String target = delegate.link(realPath).targetSync(); + var target = delegate.link(realPath).targetSync(); if (ctx.isAbsolute(target)) { ledger.clear(); parts.insertAll(0, ctx.split(target).sublist(1)); diff --git a/pkgs/file/lib/src/backends/chroot/chroot_file_system_entity.dart b/pkgs/file/lib/src/backends/chroot/chroot_file_system_entity.dart index 8e859ace8..18e37cd02 100644 --- a/pkgs/file/lib/src/backends/chroot/chroot_file_system_entity.dart +++ b/pkgs/file/lib/src/backends/chroot/chroot_file_system_entity.dart @@ -2,7 +2,7 @@ // 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. -part of file.src.backends.chroot; +part of '../chroot.dart'; abstract class _ChrootFileSystemEntity extends ForwardingFileSystemEntity { @@ -103,7 +103,7 @@ abstract class _ChrootFileSystemEntity delete({bool recursive = false}) async { - String path = fileSystem._resolve(this.path, + var path = fileSystem._resolve(this.path, followLinks: false, notFound: _NotFoundBehavior.throwError); String real(String path) => fileSystem._real(path, resolve: false); @@ -114,7 +114,7 @@ abstract class _ChrootFileSystemEntity fileSystem._real(path, resolve: false); @@ -143,7 +143,7 @@ abstract class _ChrootFileSystemEntity with ForwardingLink { - _ChrootLink(ChrootFileSystem fs, String path) : super(fs, path); + _ChrootLink(super.fs, super.path); factory _ChrootLink.wrapped( ChrootFileSystem fs, io.Link delegate, { bool relative = false, }) { - String localPath = fs._local(delegate.path, relative: relative); + var localPath = fs._local(delegate.path, relative: relative); return _ChrootLink(fs, localPath); } diff --git a/pkgs/file/lib/src/backends/chroot/chroot_random_access_file.dart b/pkgs/file/lib/src/backends/chroot/chroot_random_access_file.dart index 4105ac807..10bbd7035 100644 --- a/pkgs/file/lib/src/backends/chroot/chroot_random_access_file.dart +++ b/pkgs/file/lib/src/backends/chroot/chroot_random_access_file.dart @@ -2,7 +2,7 @@ // 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. -part of file.src.backends.chroot; +part of '../chroot.dart'; class _ChrootRandomAccessFile with ForwardingRandomAccessFile { _ChrootRandomAccessFile(this.path, this.delegate); diff --git a/pkgs/file/lib/src/backends/local/local_directory.dart b/pkgs/file/lib/src/backends/local/local_directory.dart index e23e68fe0..3e1db6140 100644 --- a/pkgs/file/lib/src/backends/local/local_directory.dart +++ b/pkgs/file/lib/src/backends/local/local_directory.dart @@ -2,10 +2,10 @@ // 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 'package:file/file.dart'; -import 'package:file/src/common.dart' as common; -import 'package:file/src/io.dart' as io; - +import '../../common.dart' as common; +import '../../forwarding.dart'; +import '../../interface.dart'; +import '../../io.dart' as io; import 'local_file_system_entity.dart'; /// [Directory] implementation that forwards all calls to `dart:io`. @@ -13,7 +13,7 @@ class LocalDirectory extends LocalFileSystemEntity with ForwardingDirectory, common.DirectoryAddOnsMixin { /// Instantiates a new [LocalDirectory] tied to the specified file system /// and delegating to the specified [delegate]. - LocalDirectory(FileSystem fs, io.Directory delegate) : super(fs, delegate); + LocalDirectory(super.fs, super.delegate); @override String toString() => "LocalDirectory: '$path'"; diff --git a/pkgs/file/lib/src/backends/local/local_file.dart b/pkgs/file/lib/src/backends/local/local_file.dart index 36293ba51..a4bc10627 100644 --- a/pkgs/file/lib/src/backends/local/local_file.dart +++ b/pkgs/file/lib/src/backends/local/local_file.dart @@ -2,9 +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 'package:file/file.dart'; -import 'package:file/src/io.dart' as io; - +import '../../forwarding.dart'; +import '../../interface.dart'; +import '../../io.dart' as io; import 'local_file_system_entity.dart'; /// [File] implementation that forwards all calls to `dart:io`. @@ -12,7 +12,7 @@ class LocalFile extends LocalFileSystemEntity with ForwardingFile { /// Instantiates a new [LocalFile] tied to the specified file system /// and delegating to the specified [delegate]. - LocalFile(FileSystem fs, io.File delegate) : super(fs, delegate); + LocalFile(super.fs, super.delegate); @override String toString() => "LocalFile: '$path'"; diff --git a/pkgs/file/lib/src/backends/local/local_file_system.dart b/pkgs/file/lib/src/backends/local/local_file_system.dart index 635998e10..7541c370f 100644 --- a/pkgs/file/lib/src/backends/local/local_file_system.dart +++ b/pkgs/file/lib/src/backends/local/local_file_system.dart @@ -2,10 +2,10 @@ // 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 'package:file/src/io.dart' as io; -import 'package:file/file.dart'; import 'package:path/path.dart' as p; +import '../../interface.dart'; +import '../../io.dart' as io; import 'local_directory.dart'; import 'local_file.dart'; import 'local_link.dart'; diff --git a/pkgs/file/lib/src/backends/local/local_file_system_entity.dart b/pkgs/file/lib/src/backends/local/local_file_system_entity.dart index ca4617b01..d0da55975 100644 --- a/pkgs/file/lib/src/backends/local/local_file_system_entity.dart +++ b/pkgs/file/lib/src/backends/local/local_file_system_entity.dart @@ -2,9 +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 'package:file/file.dart'; -import 'package:file/src/io.dart' as io; - +import '../../forwarding.dart'; +import '../../interface.dart'; +import '../../io.dart' as io; import 'local_directory.dart'; import 'local_file.dart'; import 'local_link.dart'; diff --git a/pkgs/file/lib/src/backends/local/local_link.dart b/pkgs/file/lib/src/backends/local/local_link.dart index fc67d5e88..2ce479165 100644 --- a/pkgs/file/lib/src/backends/local/local_link.dart +++ b/pkgs/file/lib/src/backends/local/local_link.dart @@ -2,9 +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 'package:file/file.dart'; -import 'package:file/src/io.dart' as io; - +import '../../forwarding.dart'; +import '../../interface.dart'; +import '../../io.dart' as io; import 'local_file_system_entity.dart'; /// [Link] implementation that forwards all calls to `dart:io`. @@ -12,7 +12,7 @@ class LocalLink extends LocalFileSystemEntity with ForwardingLink { /// Instantiates a new [LocalLink] tied to the specified file system /// and delegating to the specified [delegate]. - LocalLink(FileSystem fs, io.Link delegate) : super(fs, delegate); + LocalLink(super.fs, super.delegate); @override String toString() => "LocalLink: '$path'"; diff --git a/pkgs/file/lib/src/backends/memory/clock.dart b/pkgs/file/lib/src/backends/memory/clock.dart index 98d5434f9..57c1b72cd 100644 --- a/pkgs/file/lib/src/backends/memory/clock.dart +++ b/pkgs/file/lib/src/backends/memory/clock.dart @@ -2,6 +2,8 @@ // 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. +// ignore_for_file: comment_references + /// Interface describing clocks used by the [MemoryFileSystem]. /// /// The [MemoryFileSystem] uses a clock to determine the modification times of diff --git a/pkgs/file/lib/src/backends/memory/common.dart b/pkgs/file/lib/src/backends/memory/common.dart index 80e3c3851..eb4ca43d7 100644 --- a/pkgs/file/lib/src/backends/memory/common.dart +++ b/pkgs/file/lib/src/backends/memory/common.dart @@ -2,7 +2,7 @@ // 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 'package:file/src/common.dart' as common; +import '../../common.dart' as common; /// Generates a path to use in error messages. typedef PathGenerator = dynamic Function(); diff --git a/pkgs/file/lib/src/backends/memory/memory_directory.dart b/pkgs/file/lib/src/backends/memory/memory_directory.dart index 95fe54247..e73b96706 100644 --- a/pkgs/file/lib/src/backends/memory/memory_directory.dart +++ b/pkgs/file/lib/src/backends/memory/memory_directory.dart @@ -2,11 +2,11 @@ // 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 'package:file/file.dart'; -import 'package:file/src/common.dart' as common; -import 'package:file/src/io.dart' as io; import 'package:meta/meta.dart'; +import '../../common.dart' as common; +import '../../interface.dart'; +import '../../io.dart' as io; import 'common.dart'; import 'memory_file.dart'; import 'memory_file_system_entity.dart'; @@ -25,8 +25,7 @@ class MemoryDirectory extends MemoryFileSystemEntity with common.DirectoryAddOnsMixin implements Directory { /// Instantiates a new [MemoryDirectory]. - MemoryDirectory(NodeBasedFileSystem fileSystem, String path) - : super(fileSystem, path); + MemoryDirectory(super.fileSystem, super.path); @override io.FileSystemEntityType get expectedType => io.FileSystemEntityType.directory; @@ -52,7 +51,7 @@ class MemoryDirectory extends MemoryFileSystemEntity @override void createSync({bool recursive = false}) { fileSystem.opHandle(path, FileSystemOp.create); - Node? node = internalCreateSync( + var node = internalCreateSync( followTailLink: true, visitLinks: true, createChild: (DirectoryNode parent, bool isFinalSegment) { @@ -75,19 +74,19 @@ class MemoryDirectory extends MemoryFileSystemEntity @override Directory createTempSync([String? prefix]) { prefix = '${prefix ?? ''}rand'; - String fullPath = fileSystem.path.join(path, prefix); - String dirname = fileSystem.path.dirname(fullPath); - String basename = fileSystem.path.basename(fullPath); - DirectoryNode? node = fileSystem.findNode(dirname) as DirectoryNode?; + var fullPath = fileSystem.path.join(path, prefix); + var dirname = fileSystem.path.dirname(fullPath); + var basename = fileSystem.path.basename(fullPath); + var node = fileSystem.findNode(dirname) as DirectoryNode?; checkExists(node, () => dirname); utils.checkIsDir(node!, () => dirname); - int tempCounter = _systemTempCounter[fileSystem] ?? 0; + var tempCounter = _systemTempCounter[fileSystem] ?? 0; String name() => '$basename$tempCounter'; while (node.children.containsKey(name())) { tempCounter++; } _systemTempCounter[fileSystem] = tempCounter; - DirectoryNode tempDir = DirectoryNode(node); + var tempDir = DirectoryNode(node); node.children[name()] = tempDir; return MemoryDirectory(fileSystem, fileSystem.path.join(dirname, name())) ..createSync(); @@ -128,9 +127,9 @@ class MemoryDirectory extends MemoryFileSystemEntity bool recursive = false, bool followLinks = true, }) { - DirectoryNode node = backing as DirectoryNode; - List listing = []; - List<_PendingListTask> tasks = <_PendingListTask>[ + var node = backing as DirectoryNode; + var listing = []; + var tasks = <_PendingListTask>[ _PendingListTask( node, path.endsWith(fileSystem.path.separator) @@ -140,14 +139,14 @@ class MemoryDirectory extends MemoryFileSystemEntity ), ]; while (tasks.isNotEmpty) { - _PendingListTask task = tasks.removeLast(); + var task = tasks.removeLast(); task.dir.children.forEach((String name, Node child) { - Set breadcrumbs = Set.from(task.breadcrumbs); - String childPath = fileSystem.path.join(task.path, name); + var breadcrumbs = Set.from(task.breadcrumbs); + var childPath = fileSystem.path.join(task.path, name); while (followLinks && utils.isLink(child) && breadcrumbs.add(child as LinkNode)) { - Node? referent = child.referentOrNull; + var referent = child.referentOrNull; if (referent != null) { child = referent; } diff --git a/pkgs/file/lib/src/backends/memory/memory_file.dart b/pkgs/file/lib/src/backends/memory/memory_file.dart index ba4faab37..1a8f5f972 100644 --- a/pkgs/file/lib/src/backends/memory/memory_file.dart +++ b/pkgs/file/lib/src/backends/memory/memory_file.dart @@ -7,26 +7,25 @@ import 'dart:convert'; import 'dart:math' as math show min; import 'dart:typed_data'; -import 'package:file/file.dart'; -import 'package:file/src/backends/memory/operations.dart'; -import 'package:file/src/common.dart' as common; -import 'package:file/src/io.dart' as io; import 'package:meta/meta.dart'; +import '../../common.dart' as common; +import '../../interface.dart'; +import '../../io.dart' as io; import 'common.dart'; import 'memory_file_system_entity.dart'; import 'memory_random_access_file.dart'; import 'node.dart'; +import 'operations.dart'; import 'utils.dart' as utils; /// Internal implementation of [File]. class MemoryFile extends MemoryFileSystemEntity implements File { /// Instantiates a new [MemoryFile]. - const MemoryFile(NodeBasedFileSystem fileSystem, String path) - : super(fileSystem, path); + const MemoryFile(super.fileSystem, super.path); FileNode get _resolvedBackingOrCreate { - Node? node = backingOrNull; + var node = backingOrNull; if (node == null) { node = _doCreate(); } else { @@ -61,7 +60,7 @@ class MemoryFile extends MemoryFileSystemEntity implements File { } Node? _doCreate({bool recursive = false}) { - Node? node = internalCreateSync( + var node = internalCreateSync( followTailLink: true, createChild: (DirectoryNode parent, bool isFinalSegment) { if (isFinalSegment) { @@ -88,7 +87,7 @@ class MemoryFile extends MemoryFileSystemEntity implements File { newPath, followTailLink: true, checkType: (Node node) { - FileSystemEntityType actualType = node.stat.type; + var actualType = node.stat.type; if (actualType != expectedType) { throw actualType == FileSystemEntityType.notFound ? common.noSuchFileOrDirectory(path) @@ -103,7 +102,7 @@ class MemoryFile extends MemoryFileSystemEntity implements File { @override File copySync(String newPath) { fileSystem.opHandle(path, FileSystemOp.copy); - FileNode sourceNode = resolvedBacking as FileNode; + var sourceNode = resolvedBacking as FileNode; fileSystem.findNode( newPath, segmentVisitor: ( @@ -116,7 +115,7 @@ class MemoryFile extends MemoryFileSystemEntity implements File { if (currentSegment == finalSegment) { if (child != null) { if (utils.isLink(child)) { - List ledger = []; + var ledger = []; child = utils.resolveLinks(child as LinkNode, () => newPath, ledger: ledger); checkExists(child, () => newPath); @@ -127,7 +126,7 @@ class MemoryFile extends MemoryFileSystemEntity implements File { utils.checkType(expectedType, child.type, () => newPath); parent.children.remove(childName); } - FileNode newNode = FileNode(parent); + var newNode = FileNode(parent); newNode.copyFrom(sourceNode); parent.children[childName] = newNode; } @@ -158,7 +157,7 @@ class MemoryFile extends MemoryFileSystemEntity implements File { @override void setLastAccessedSync(DateTime time) { - FileNode node = resolvedBacking as FileNode; + var node = resolvedBacking as FileNode; node.accessed = time.millisecondsSinceEpoch; } @@ -174,7 +173,7 @@ class MemoryFile extends MemoryFileSystemEntity implements File { @override void setLastModifiedSync(DateTime time) { - FileNode node = resolvedBacking as FileNode; + var node = resolvedBacking as FileNode; node.modified = time.millisecondsSinceEpoch; } @@ -199,8 +198,8 @@ class MemoryFile extends MemoryFileSystemEntity implements File { Stream> openRead([int? start, int? end]) { fileSystem.opHandle(path, FileSystemOp.open); try { - FileNode node = resolvedBacking as FileNode; - Uint8List content = node.content; + var node = resolvedBacking as FileNode; + var content = node.content; if (start != null) { content = end == null ? content.sublist(start) @@ -253,13 +252,13 @@ class MemoryFile extends MemoryFileSystemEntity implements File { @override List readAsLinesSync({Encoding encoding = utf8}) { - String str = readAsStringSync(encoding: encoding); + var str = readAsStringSync(encoding: encoding); if (str.isEmpty) { return []; } - final List lines = str.split('\n'); + final lines = str.split('\n'); if (str.endsWith('\n')) { // A final newline should not create an additional line. lines.removeLast(); @@ -287,7 +286,7 @@ class MemoryFile extends MemoryFileSystemEntity implements File { if (!utils.isWriteMode(mode)) { throw common.badFileDescriptor(path); } - FileNode node = _resolvedBackingOrCreate; + var node = _resolvedBackingOrCreate; _truncateIfNecessary(node, mode); fileSystem.opHandle(path, FileSystemOp.write); node.write(bytes); @@ -349,7 +348,7 @@ class _FileSink implements io.IOSink { deferredException = e; } - Future future = Future.microtask(() { + var future = Future.microtask(() { if (deferredException != null) { throw deferredException; } @@ -387,7 +386,7 @@ class _FileSink implements io.IOSink { @override void writeAll(Iterable objects, [String separator = '']) { - bool firstIter = true; + var firstIter = true; for (dynamic obj in objects) { if (!firstIter) { write(separator); @@ -418,7 +417,7 @@ class _FileSink implements io.IOSink { _streamCompleter = Completer(); stream.listen( - (List data) => _addData(data), + _addData, cancelOnError: true, onError: (Object error, StackTrace stackTrace) { _streamCompleter!.completeError(error, stackTrace); @@ -445,8 +444,7 @@ class _FileSink implements io.IOSink { _isClosed = true; _pendingWrites.then( (_) => _completer.complete(), - onError: (Object error, StackTrace stackTrace) => - _completer.completeError(error, stackTrace), + onError: _completer.completeError, ); } return _completer.future; diff --git a/pkgs/file/lib/src/backends/memory/memory_file_stat.dart b/pkgs/file/lib/src/backends/memory/memory_file_stat.dart index 94f86d155..ce6bedac1 100644 --- a/pkgs/file/lib/src/backends/memory/memory_file_stat.dart +++ b/pkgs/file/lib/src/backends/memory/memory_file_stat.dart @@ -2,7 +2,7 @@ // 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 'package:file/src/io.dart' as io; +import '../../io.dart' as io; /// Internal implementation of [io.FileStat]. class MemoryFileStat implements io.FileStat { @@ -47,8 +47,8 @@ class MemoryFileStat implements io.FileStat { @override String modeString() { - int permissions = mode & 0xFFF; - List codes = const [ + var permissions = mode & 0xFFF; + var codes = const [ '---', '--x', '-w-', @@ -58,7 +58,7 @@ class MemoryFileStat implements io.FileStat { 'rw-', 'rwx', ]; - List result = []; + var result = []; result ..add(codes[(permissions >> 6) & 0x7]) ..add(codes[(permissions >> 3) & 0x7]) diff --git a/pkgs/file/lib/src/backends/memory/memory_file_system.dart b/pkgs/file/lib/src/backends/memory/memory_file_system.dart index f3cdaeede..dd359f049 100644 --- a/pkgs/file/lib/src/backends/memory/memory_file_system.dart +++ b/pkgs/file/lib/src/backends/memory/memory_file_system.dart @@ -2,11 +2,10 @@ // 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 'package:file/file.dart'; -import 'package:file/src/backends/memory/operations.dart'; -import 'package:file/src/io.dart' as io; import 'package:path/path.dart' as p; +import '../../interface.dart'; +import '../../io.dart' as io; import 'clock.dart'; import 'common.dart'; import 'memory_directory.dart'; @@ -14,6 +13,7 @@ import 'memory_file.dart'; import 'memory_file_stat.dart'; import 'memory_link.dart'; import 'node.dart'; +import 'operations.dart'; import 'style.dart'; import 'utils.dart' as utils; @@ -91,7 +91,7 @@ class _MemoryFileSystem extends FileSystem p.Context _context; @override - final Function(String context, FileSystemOp operation) opHandle; + final void Function(String context, FileSystemOp operation) opHandle; @override final Clock clock; @@ -141,7 +141,7 @@ class _MemoryFileSystem extends FileSystem } value = directory(value).resolveSymbolicLinksSync(); - Node? node = findNode(value); + var node = findNode(value); checkExists(node, () => value); utils.checkIsDir(node!, () => value); assert(_context.isAbsolute(value)); @@ -166,9 +166,9 @@ class _MemoryFileSystem extends FileSystem @override bool identicalSync(String path1, String path2) { - Node? node1 = findNode(path1); + var node1 = findNode(path1); checkExists(node1, () => path1); - Node? node2 = findNode(path2); + var node2 = findNode(path2); checkExists(node2, () => path2); return node1 != null && node1 == node2; } @@ -220,14 +220,13 @@ class _MemoryFileSystem extends FileSystem reference ??= _current; } - List parts = path.split(style.separator) - ..removeWhere(utils.isEmpty); - DirectoryNode? directory = reference?.directory; + var parts = path.split(style.separator)..removeWhere(utils.isEmpty); + var directory = reference?.directory; Node? child = directory; - int finalSegment = parts.length - 1; - for (int i = 0; i <= finalSegment; i++) { - String basename = parts[i]; + var finalSegment = parts.length - 1; + for (var i = 0; i <= finalSegment; i++) { + var basename = parts[i]; assert(basename.isNotEmpty); switch (basename) { diff --git a/pkgs/file/lib/src/backends/memory/memory_file_system_entity.dart b/pkgs/file/lib/src/backends/memory/memory_file_system_entity.dart index ad987d71a..1990abcd0 100644 --- a/pkgs/file/lib/src/backends/memory/memory_file_system_entity.dart +++ b/pkgs/file/lib/src/backends/memory/memory_file_system_entity.dart @@ -2,11 +2,11 @@ // 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 'package:file/file.dart'; -import 'package:file/src/common.dart' as common; -import 'package:file/src/io.dart' as io; import 'package:meta/meta.dart'; +import '../../common.dart' as common; +import '../../interface.dart'; +import '../../io.dart' as io; import 'common.dart'; import 'memory_directory.dart'; import 'node.dart'; @@ -60,7 +60,7 @@ abstract class MemoryFileSystemEntity implements FileSystemEntity { /// The type of the node is not guaranteed to match [expectedType]. @protected Node get backing { - Node? node = fileSystem.findNode(path); + var node = fileSystem.findNode(path); checkExists(node, () => path); return node!; } @@ -71,7 +71,7 @@ abstract class MemoryFileSystemEntity implements FileSystemEntity { /// doesn't match, this will throw a [io.FileSystemException]. @protected Node get resolvedBacking { - Node node = backing; + var node = backing; node = utils.isLink(node) ? utils.resolveLinks(node as LinkNode, () => path) : node; @@ -107,14 +107,14 @@ abstract class MemoryFileSystemEntity implements FileSystemEntity { if (path.isEmpty) { throw common.noSuchFileOrDirectory(path); } - List ledger = []; + var ledger = []; if (isAbsolute) { ledger.add(fileSystem.style.drive); } - Node? node = fileSystem.findNode(path, + var node = fileSystem.findNode(path, pathWithSymlinks: ledger, followTailLink: true); checkExists(node, () => path); - String resolved = ledger.join(fileSystem.path.separator); + var resolved = ledger.join(fileSystem.path.separator); if (resolved == fileSystem.style.drive) { resolved = fileSystem.style.root; } else if (!fileSystem.path.isAbsolute(resolved)) { @@ -151,7 +151,7 @@ abstract class MemoryFileSystemEntity implements FileSystemEntity { @override FileSystemEntity get absolute { - String absolutePath = path; + var absolutePath = path; if (!fileSystem.path.isAbsolute(absolutePath)) { absolutePath = fileSystem.path.join(fileSystem.cwd, absolutePath); } @@ -242,7 +242,7 @@ abstract class MemoryFileSystemEntity implements FileSystemEntity { bool followTailLink = false, utils.TypeChecker? checkType, }) { - Node node = backing; + var node = backing; (checkType ?? defaultCheckType)(node); fileSystem.findNode( newPath, @@ -256,7 +256,7 @@ abstract class MemoryFileSystemEntity implements FileSystemEntity { if (currentSegment == finalSegment) { if (child != null) { if (followTailLink) { - FileSystemEntityType childType = child.stat.type; + var childType = child.stat.type; if (childType != FileSystemEntityType.notFound) { utils.checkType(expectedType, child.stat.type, () => newPath); } @@ -289,7 +289,7 @@ abstract class MemoryFileSystemEntity implements FileSystemEntity { utils.TypeChecker? checkType, }) { fileSystem.opHandle(path, FileSystemOp.delete); - Node node = backing; + var node = backing; if (!recursive) { if (node is DirectoryNode && node.children.isNotEmpty) { throw common.directoryNotEmpty(path); diff --git a/pkgs/file/lib/src/backends/memory/memory_link.dart b/pkgs/file/lib/src/backends/memory/memory_link.dart index 7d5afb42f..a599fe8f1 100644 --- a/pkgs/file/lib/src/backends/memory/memory_link.dart +++ b/pkgs/file/lib/src/backends/memory/memory_link.dart @@ -2,11 +2,11 @@ // 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 'package:file/file.dart'; -import 'package:file/src/common.dart' as common; -import 'package:file/src/io.dart' as io; import 'package:meta/meta.dart'; +import '../../common.dart' as common; +import '../../interface.dart'; +import '../../io.dart' as io; import 'memory_file_system_entity.dart'; import 'node.dart'; import 'operations.dart'; @@ -15,8 +15,7 @@ import 'utils.dart' as utils; /// Internal implementation of [Link]. class MemoryLink extends MemoryFileSystemEntity implements Link { /// Instantiates a new [MemoryLink]. - const MemoryLink(NodeBasedFileSystem fileSystem, String path) - : super(fileSystem, path); + const MemoryLink(super.fileSystem, super.path); @override io.FileSystemEntityType get expectedType => io.FileSystemEntityType.link; @@ -50,7 +49,7 @@ class MemoryLink extends MemoryFileSystemEntity implements Link { @override void createSync(String target, {bool recursive = false}) { - bool preexisting = true; + var preexisting = true; fileSystem.opHandle(path, FileSystemOp.create); internalCreateSync( createChild: (DirectoryNode parent, bool isFinalSegment) { @@ -76,7 +75,7 @@ class MemoryLink extends MemoryFileSystemEntity implements Link { @override void updateSync(String target) { - Node node = backing; + var node = backing; utils.checkType(expectedType, node.type, () => path); (node as LinkNode).target = target; } @@ -93,7 +92,7 @@ class MemoryLink extends MemoryFileSystemEntity implements Link { @override String targetSync() { - Node node = backing; + var node = backing; if (node.type != expectedType) { // Note: this may change; https://github.com/dart-lang/sdk/issues/28204 throw common.noSuchFileOrDirectory(path); diff --git a/pkgs/file/lib/src/backends/memory/memory_random_access_file.dart b/pkgs/file/lib/src/backends/memory/memory_random_access_file.dart index d4fe73d18..190f0a137 100644 --- a/pkgs/file/lib/src/backends/memory/memory_random_access_file.dart +++ b/pkgs/file/lib/src/backends/memory/memory_random_access_file.dart @@ -6,10 +6,11 @@ import 'dart:convert'; import 'dart:math' as math show min; import 'dart:typed_data'; -import 'package:file/src/common.dart' as common; -import 'package:file/src/io.dart' as io; - +import '../../common.dart' as common; +import '../../io.dart' as io; +import '../memory.dart' show MemoryFileSystem; import 'memory_file.dart'; +import 'memory_file_system.dart' show MemoryFileSystem; import 'node.dart'; import 'utils.dart' as utils; @@ -106,8 +107,8 @@ class MemoryRandomAccessFile implements io.RandomAccessFile { /// Wraps a synchronous function to make it appear asynchronous. /// /// [_asyncOperationPending], [_checkAsync], and [_asyncWrapper] are used to - /// mimic [RandomAccessFile]'s enforcement that only one asynchronous - /// operation is pending for a [RandomAccessFile] instance. Since + /// mimic [io.RandomAccessFile]'s enforcement that only one asynchronous + /// operation is pending for a [io.RandomAccessFile] instance. Since /// [MemoryFileSystem]-based classes are likely to be used in tests, fidelity /// is important to catch errors that might occur in production. /// @@ -211,7 +212,7 @@ class MemoryRandomAccessFile implements io.RandomAccessFile { _checkReadable('read'); // TODO(jamesderlin): Check for integer overflow. final int end = math.min(_position + bytes, lengthSync()); - final Uint8List copy = _node.content.sublist(_position, end); + final copy = _node.content.sublist(_position, end); _position = end; return copy; } @@ -243,7 +244,7 @@ class MemoryRandomAccessFile implements io.RandomAccessFile { end = RangeError.checkValidRange(start, end, buffer.length); - final int length = lengthSync(); + final length = lengthSync(); int i; for (i = start; i < end && _position < length; i += 1, _position += 1) { buffer[i] = _node.content[_position]; @@ -288,7 +289,7 @@ class MemoryRandomAccessFile implements io.RandomAccessFile { 'truncate failed', path, common.invalidArgument(path).osError); } - final int oldLength = lengthSync(); + final oldLength = lengthSync(); if (length < oldLength) { _node.truncate(length); @@ -329,7 +330,7 @@ class MemoryRandomAccessFile implements io.RandomAccessFile { // [Uint8List] will truncate values to 8-bits automatically, so we don't // need to check [value]. - int length = lengthSync(); + var length = lengthSync(); if (_position >= length) { // If [_position] is out of bounds, [RandomAccessFile] zero-fills the // file. @@ -363,8 +364,8 @@ class MemoryRandomAccessFile implements io.RandomAccessFile { end = RangeError.checkValidRange(start, end, buffer.length); - final int writeByteCount = end - start; - final int endPosition = _position + writeByteCount; + final writeByteCount = end - start; + final endPosition = _position + writeByteCount; if (endPosition > lengthSync()) { truncateSync(endPosition); diff --git a/pkgs/file/lib/src/backends/memory/node.dart b/pkgs/file/lib/src/backends/memory/node.dart index ae4d3f75d..eea72b58c 100644 --- a/pkgs/file/lib/src/backends/memory/node.dart +++ b/pkgs/file/lib/src/backends/memory/node.dart @@ -4,13 +4,12 @@ import 'dart:typed_data'; -import 'package:file/file.dart'; -import 'package:file/src/backends/memory/operations.dart'; -import 'package:file/src/io.dart' as io; - +import '../../interface.dart'; +import '../../io.dart' as io; import 'clock.dart'; import 'common.dart'; import 'memory_file_stat.dart'; +import 'operations.dart'; import 'style.dart'; /// Visitor callback for use with [NodeBasedFileSystem.findNode]. @@ -115,7 +114,7 @@ abstract class Node { /// Reparents this node to live in the specified directory. set parent(DirectoryNode parent) { - DirectoryNode ancestor = parent; + var ancestor = parent; while (!ancestor.isRoot) { if (ancestor == this) { throw const io.FileSystemException( @@ -149,8 +148,8 @@ abstract class Node { /// you call [stat] on them). abstract class RealNode extends Node { /// Constructs a new [RealNode] as a child of the specified [parent]. - RealNode(DirectoryNode? parent) : super(parent) { - int now = clock.now.millisecondsSinceEpoch; + RealNode(super.parent) { + var now = clock.now.millisecondsSinceEpoch; changed = now; modified = now; accessed = now; @@ -195,7 +194,7 @@ abstract class RealNode extends Node { /// Class that represents the backing for an in-memory directory. class DirectoryNode extends RealNode { /// Constructs a new [DirectoryNode] as a child of the specified [parent]. - DirectoryNode(DirectoryNode? parent) : super(parent); + DirectoryNode(super.parent); /// Child nodes, indexed by their basename. final Map children = {}; @@ -237,7 +236,7 @@ class RootNode extends DirectoryNode { /// Class that represents the backing for an in-memory regular file. class FileNode extends RealNode { /// Constructs a new [FileNode] as a child of the specified [parent]. - FileNode(DirectoryNode parent) : super(parent); + FileNode(DirectoryNode super.parent); /// File contents in bytes. Uint8List get content => _content; @@ -251,7 +250,7 @@ class FileNode extends RealNode { /// Appends the specified bytes to the end of this node's [content]. void write(List bytes) { - Uint8List existing = _content; + var existing = _content; _content = Uint8List(existing.length + bytes.length); _content.setRange(0, existing.length, existing); _content.setRange(existing.length, _content.length, bytes); @@ -286,9 +285,7 @@ class FileNode extends RealNode { class LinkNode extends Node { /// Constructs a new [LinkNode] as a child of the specified [parent] and /// linking to the specified [target] path. - LinkNode(DirectoryNode parent, this.target) - : assert(target.isNotEmpty), - super(parent); + LinkNode(DirectoryNode super.parent, this.target) : assert(target.isNotEmpty); /// The path to which this link points. String target; @@ -309,7 +306,7 @@ class LinkNode extends Node { Node? Function(DirectoryNode parent, String childName, Node? child)? tailVisitor, }) { - Node? referent = fs.findNode( + var referent = fs.findNode( target, reference: this, segmentVisitor: ( @@ -349,7 +346,7 @@ class LinkNode extends Node { } _reentrant = true; try { - Node? node = referentOrNull; + var node = referentOrNull; return node == null ? MemoryFileStat.notFound : node.stat; } finally { _reentrant = false; diff --git a/pkgs/file/lib/src/backends/memory/operations.dart b/pkgs/file/lib/src/backends/memory/operations.dart index 9fc7462fc..57d118b11 100644 --- a/pkgs/file/lib/src/backends/memory/operations.dart +++ b/pkgs/file/lib/src/backends/memory/operations.dart @@ -2,6 +2,8 @@ // 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. +// ignore_for_file: comment_references + /// A file system operation used by the [MemoryFileSytem] to allow /// tests to insert errors for certain operations. /// @@ -64,23 +66,15 @@ class FileSystemOp { @override String toString() { - switch (_value) { - case 0: - return 'FileSystemOp.read'; - case 1: - return 'FileSystemOp.write'; - case 2: - return 'FileSystemOp.delete'; - case 3: - return 'FileSystemOp.create'; - case 4: - return 'FileSystemOp.open'; - case 5: - return 'FileSystemOp.copy'; - case 6: - return 'FileSystemOp.exists'; - default: - throw StateError('Invalid FileSytemOp type: $this'); - } + return switch (_value) { + 0 => 'FileSystemOp.read', + 1 => 'FileSystemOp.write', + 2 => 'FileSystemOp.delete', + 3 => 'FileSystemOp.create', + 4 => 'FileSystemOp.open', + 5 => 'FileSystemOp.copy', + 6 => 'FileSystemOp.exists', + _ => throw StateError('Invalid FileSytemOp type: $this') + }; } } diff --git a/pkgs/file/lib/src/backends/memory/style.dart b/pkgs/file/lib/src/backends/memory/style.dart index 701c9d05e..f4bd33fb7 100644 --- a/pkgs/file/lib/src/backends/memory/style.dart +++ b/pkgs/file/lib/src/backends/memory/style.dart @@ -2,9 +2,10 @@ // 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 'package:file/file.dart'; import 'package:path/path.dart' as p; +import '../../interface.dart'; + /// Class that represents the path style that a memory file system should /// adopt. /// diff --git a/pkgs/file/lib/src/backends/memory/utils.dart b/pkgs/file/lib/src/backends/memory/utils.dart index eec998038..aa24cfb57 100644 --- a/pkgs/file/lib/src/backends/memory/utils.dart +++ b/pkgs/file/lib/src/backends/memory/utils.dart @@ -2,20 +2,19 @@ // 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 'package:file/file.dart'; -import 'package:file/src/common.dart' as common; -import 'package:file/src/io.dart' as io; - +import '../../common.dart' as common; +import '../../interface.dart'; +import '../../io.dart' as io; import 'common.dart'; import 'node.dart'; -/// Checks if `node.type` returns [io.FileSystemEntityType.FILE]. +/// Checks if `node.type` returns [io.FileSystemEntityType.file]. bool isFile(Node? node) => node?.type == io.FileSystemEntityType.file; -/// Checks if `node.type` returns [io.FileSystemEntityType.DIRECTORY]. +/// Checks if `node.type` returns [io.FileSystemEntityType.directory]. bool isDirectory(Node? node) => node?.type == io.FileSystemEntityType.directory; -/// Checks if `node.type` returns [io.FileSystemEntityType.LINK]. +/// Checks if `node.type` returns [io.FileSystemEntityType.link]. bool isLink(Node? node) => node?.type == io.FileSystemEntityType.link; /// Validator function that is expected to throw a [FileSystemException] if @@ -86,7 +85,7 @@ Node resolveLinks( tailVisitor, }) { // Record a breadcrumb trail to guard against symlink loops. - Set breadcrumbs = {}; + var breadcrumbs = {}; Node node = link; while (isLink(node)) { diff --git a/pkgs/file/lib/src/forwarding/forwarding_directory.dart b/pkgs/file/lib/src/forwarding/forwarding_directory.dart index dba0c8ed6..ad1c548c1 100644 --- a/pkgs/file/lib/src/forwarding/forwarding_directory.dart +++ b/pkgs/file/lib/src/forwarding/forwarding_directory.dart @@ -2,8 +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 'package:file/src/io.dart' as io; -import 'package:file/file.dart'; +import '../forwarding.dart'; +import '../interface.dart'; +import '../io.dart' as io; /// A directory that forwards all methods and properties to a delegate. mixin ForwardingDirectory diff --git a/pkgs/file/lib/src/forwarding/forwarding_file.dart b/pkgs/file/lib/src/forwarding/forwarding_file.dart index 49c211db7..d6cfe3bb7 100644 --- a/pkgs/file/lib/src/forwarding/forwarding_file.dart +++ b/pkgs/file/lib/src/forwarding/forwarding_file.dart @@ -5,8 +5,9 @@ import 'dart:convert'; import 'dart:typed_data'; -import 'package:file/src/io.dart' as io; -import 'package:file/file.dart'; +import '../forwarding.dart'; +import '../interface.dart'; +import '../io.dart' as io; /// A file that forwards all methods and properties to a delegate. mixin ForwardingFile diff --git a/pkgs/file/lib/src/forwarding/forwarding_file_system.dart b/pkgs/file/lib/src/forwarding/forwarding_file_system.dart index d864db94c..885fdb618 100644 --- a/pkgs/file/lib/src/forwarding/forwarding_file_system.dart +++ b/pkgs/file/lib/src/forwarding/forwarding_file_system.dart @@ -2,11 +2,12 @@ // 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 'package:file/src/io.dart' as io; -import 'package:file/file.dart'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; +import '../interface.dart'; +import '../io.dart' as io; + /// A file system that forwards all methods and properties to a delegate. abstract class ForwardingFileSystem extends FileSystem { /// Creates a new [ForwardingFileSystem] that forwards all methods and diff --git a/pkgs/file/lib/src/forwarding/forwarding_file_system_entity.dart b/pkgs/file/lib/src/forwarding/forwarding_file_system_entity.dart index 3c41b39b4..1c0628ee4 100644 --- a/pkgs/file/lib/src/forwarding/forwarding_file_system_entity.dart +++ b/pkgs/file/lib/src/forwarding/forwarding_file_system_entity.dart @@ -2,10 +2,11 @@ // 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 'package:file/src/io.dart' as io; -import 'package:file/file.dart'; import 'package:meta/meta.dart'; +import '../interface.dart'; +import '../io.dart' as io; + /// A file system entity that forwards all methods and properties to a delegate. abstract class ForwardingFileSystemEntity implements FileSystemEntity { diff --git a/pkgs/file/lib/src/forwarding/forwarding_link.dart b/pkgs/file/lib/src/forwarding/forwarding_link.dart index 7a60ecbfe..915e710cf 100644 --- a/pkgs/file/lib/src/forwarding/forwarding_link.dart +++ b/pkgs/file/lib/src/forwarding/forwarding_link.dart @@ -2,8 +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 'package:file/src/io.dart' as io; -import 'package:file/file.dart'; +import '../forwarding.dart'; +import '../interface.dart'; +import '../io.dart' as io; /// A link that forwards all methods and properties to a delegate. mixin ForwardingLink diff --git a/pkgs/file/lib/src/forwarding/forwarding_random_access_file.dart b/pkgs/file/lib/src/forwarding/forwarding_random_access_file.dart index 9dd407930..3847b91f4 100644 --- a/pkgs/file/lib/src/forwarding/forwarding_random_access_file.dart +++ b/pkgs/file/lib/src/forwarding/forwarding_random_access_file.dart @@ -5,11 +5,12 @@ import 'dart:convert'; import 'dart:typed_data'; -import 'package:file/src/io.dart' as io; import 'package:meta/meta.dart'; -/// A [RandomAccessFile] implementation that forwards all methods and properties -/// to a delegate. +import '../io.dart' as io; + +/// A [io.RandomAccessFile] implementation that forwards all methods and +/// properties to a delegate. mixin ForwardingRandomAccessFile implements io.RandomAccessFile { /// The entity to which this entity will forward all methods and properties. @protected diff --git a/pkgs/file/lib/src/interface.dart b/pkgs/file/lib/src/interface.dart index 4662e3515..d9b7ed592 100644 --- a/pkgs/file/lib/src/interface.dart +++ b/pkgs/file/lib/src/interface.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library file.src.interface; - export 'interface/directory.dart'; export 'interface/error_codes.dart'; export 'interface/file.dart'; diff --git a/pkgs/file/lib/src/interface/error_codes.dart b/pkgs/file/lib/src/interface/error_codes.dart index 8943538cb..4836b5658 100644 --- a/pkgs/file/lib/src/interface/error_codes.dart +++ b/pkgs/file/lib/src/interface/error_codes.dart @@ -168,7 +168,7 @@ class ErrorCodes { static int get EXDEV => _platform((_Codes codes) => codes.exdev); static int _platform(int Function(_Codes codes) getCode) { - _Codes codes = (_platforms[operatingSystem] ?? _platforms['linux'])!; + var codes = (_platforms[operatingSystem] ?? _platforms['linux'])!; return getCode(codes); } } diff --git a/pkgs/file/lib/src/interface/file_system.dart b/pkgs/file/lib/src/interface/file_system.dart index ecc01a801..2d4e4aa3b 100644 --- a/pkgs/file/lib/src/interface/file_system.dart +++ b/pkgs/file/lib/src/interface/file_system.dart @@ -6,7 +6,6 @@ import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; import '../io.dart' as io; - import 'directory.dart'; import 'file.dart'; import 'file_system_entity.dart'; @@ -99,9 +98,9 @@ abstract class FileSystem { bool get isWatchSupported; /// Finds the type of file system object that a [path] points to. Returns - /// a Future that completes with the result. + /// a `Future` that completes with the result. /// - /// [io.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 @@ -111,37 +110,38 @@ abstract class FileSystem { /// Syncronously finds the type of file system object that a [path] points /// to. Returns a [io.FileSystemEntityType]. /// - /// [io.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 [io.FileSystemEntityType.notFound] is returned. io.FileSystemEntityType typeSync(String path, {bool followLinks = true}); - /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.FILE]. + /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.file]. Future isFile(String path) async => await type(path) == io.FileSystemEntityType.file; /// Synchronously checks if [`type(path)`](type) returns - /// [io.FileSystemEntityType.FILE]. + /// [io.FileSystemEntityType.file]. bool isFileSync(String path) => typeSync(path) == io.FileSystemEntityType.file; - /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.DIRECTORY]. + /// Checks if [`type(path)`](type) returns + /// [io.FileSystemEntityType.directory]. Future isDirectory(String path) async => await type(path) == io.FileSystemEntityType.directory; /// Synchronously checks if [`type(path)`](type) returns - /// [io.FileSystemEntityType.DIRECTORY]. + /// [io.FileSystemEntityType.directory]. bool isDirectorySync(String path) => typeSync(path) == io.FileSystemEntityType.directory; - /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.LINK]. + /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.link]. Future isLink(String path) async => await type(path, followLinks: false) == io.FileSystemEntityType.link; /// Synchronously checks if [`type(path)`](type) returns - /// [io.FileSystemEntityType.LINK]. + /// [io.FileSystemEntityType.link]. bool isLinkSync(String path) => typeSync(path, followLinks: false) == io.FileSystemEntityType.link; diff --git a/pkgs/file/lib/src/io.dart b/pkgs/file/lib/src/io.dart index 9d57e7869..28c1d6dfa 100644 --- a/pkgs/file/lib/src/io.dart +++ b/pkgs/file/lib/src/io.dart @@ -8,6 +8,8 @@ /// the `file` package. The `file` package re-exports these interfaces (or in /// some cases, implementations of these interfaces by the same name), so this /// file need not be exposes publicly and exists for internal use only. +library; + export 'dart:io' show Directory, diff --git a/pkgs/file/pubspec.yaml b/pkgs/file/pubspec.yaml index 5de5d37c1..0ad65b0d6 100644 --- a/pkgs/file/pubspec.yaml +++ b/pkgs/file/pubspec.yaml @@ -1,5 +1,5 @@ name: file -version: 7.0.1 +version: 7.0.2-wip description: A pluggable, mockable file system abstraction for Dart. repository: https://github.com/dart-lang/tools/tree/main/pkgs/file issue_tracker: https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Afile @@ -12,6 +12,10 @@ dependencies: path: ^1.8.3 dev_dependencies: + dart_flutter_team_lints: ^3.0.0 file_testing: ^3.0.0 - lints: ^2.0.1 test: ^1.23.1 + +dependency_overrides: + file_testing: + path: ../file_testing diff --git a/pkgs/file/test/chroot_test.dart b/pkgs/file/test/chroot_test.dart index 6c34ff200..cf23f4755 100644 --- a/pkgs/file/test/chroot_test.dart +++ b/pkgs/file/test/chroot_test.dart @@ -3,6 +3,8 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('vm') +library; + import 'dart:io' as io; import 'package:file/chroot.dart'; @@ -17,14 +19,15 @@ import 'common_tests.dart'; void main() { group('ChrootFileSystem', () { ChrootFileSystem createMemoryBackedChrootFileSystem() { - MemoryFileSystem fs = MemoryFileSystem(); + var fs = MemoryFileSystem(); fs.directory('/tmp').createSync(); return ChrootFileSystem(fs, '/tmp'); } // TODO(jamesderlin): Make ChrootFile.openSync return a delegating // RandomAccessFile that uses the chroot'd path. - List skipCommon = [ + var skipCommon = [ + // ignore: lines_longer_than_80_chars 'File > open > .* > RandomAccessFile > read > openReadHandleDoesNotChange', 'File > open > .* > RandomAccessFile > openWriteHandleDoesNotChange', ]; @@ -137,6 +140,7 @@ void main() { test('referencesRootEntityForJailbreakPath', () { mem.file('/foo').createSync(); dynamic f = fs.file('../foo'); + // ignore: avoid_dynamic_calls expect(f.delegate.path, '/tmp/foo'); }); }); @@ -151,7 +155,7 @@ void main() { group('copy', () { test('copiesToRootDirectoryIfDestinationIsJailbreakPath', () { - File f = fs.file('/foo')..createSync(); + var f = fs.file('/foo')..createSync(); f.copySync('../bar'); expect(mem.file('/bar'), isNot(exists)); expect(mem.file('/tmp/bar'), exists); diff --git a/pkgs/file/test/common_tests.dart b/pkgs/file/test/common_tests.dart index 6028c7715..491d4f985 100644 --- a/pkgs/file/test/common_tests.dart +++ b/pkgs/file/test/common_tests.dart @@ -3,6 +3,8 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('vm') +library; + import 'dart:async'; import 'dart:convert'; import 'dart:io' as io; @@ -10,8 +12,8 @@ import 'dart:io' as io; import 'package:file/file.dart'; import 'package:file_testing/file_testing.dart'; import 'package:path/path.dart' as p; -import 'package:test/test.dart'; import 'package:test/test.dart' as testpkg show group, setUp, tearDown, test; +import 'package:test/test.dart'; import 'utils.dart'; @@ -54,7 +56,7 @@ void runCommonTests( List skip = const [], FileSystemGenerator? replay, }) { - RootPathGenerator? rootfn = root; + var rootfn = root; group('common', () { late FileSystemGenerator createFs; @@ -62,7 +64,7 @@ void runCommonTests( late List tearDowns; late FileSystem fs; late String root; - List stack = []; + var stack = []; void skipIfNecessary(String description, void Function() callback) { stack.add(description); @@ -105,7 +107,7 @@ void runCommonTests( testpkg.setUp(() async { await Future.forEach(setUps, (SetUpTearDown setUp) => setUp()); await body(); - for (SetUpTearDown tearDown in tearDowns) { + for (var tearDown in tearDowns) { await tearDown(); } createFs = replay; @@ -115,7 +117,7 @@ void runCommonTests( testpkg.test(description, body, skip: skip); testpkg.tearDown(() async { - for (SetUpTearDown tearDown in tearDowns) { + for (var tearDown in tearDowns) { await tearDown(); } }); @@ -126,13 +128,13 @@ void runCommonTests( /// Returns [path] prefixed by the [root] namespace. /// This is only intended for absolute paths. String ns(String path) { - p.Context posix = p.Context(style: p.Style.posix); - List parts = posix.split(path); + var posix = p.Context(style: p.Style.posix); + var parts = posix.split(path); parts[0] = root; path = fs.path.joinAll(parts); - String rootPrefix = fs.path.rootPrefix(path); + var rootPrefix = fs.path.rootPrefix(path); assert(rootPrefix.isNotEmpty); - String result = root == rootPrefix + var result = root == rootPrefix ? path : (path == rootPrefix ? root @@ -160,7 +162,7 @@ void runCommonTests( test('succeedsWithUriArgument', () { fs.directory(ns('/foo')).createSync(); - Uri uri = fs.path.toUri(ns('/foo')); + var uri = fs.path.toUri(ns('/foo')); expect(fs.directory(uri), exists); }); @@ -173,11 +175,11 @@ void runCommonTests( }); // Fails due to - // https://github.com/google/file.dart/issues/112 + // https://github.com/dart-lang/tools/issues/632 test('considersBothSlashesEquivalent', () { fs.directory(r'foo\bar_dir').createSync(recursive: true); expect(fs.directory(r'foo/bar_dir'), exists); - }, skip: 'Fails due to https://github.com/google/file.dart/issues/112'); + }, skip: 'Fails due to https://github.com/dart-lang/tools/issues/632'); }); group('file', () { @@ -191,7 +193,7 @@ void runCommonTests( test('succeedsWithUriArgument', () { fs.file(ns('/foo')).createSync(); - Uri uri = fs.path.toUri(ns('/foo')); + var uri = fs.path.toUri(ns('/foo')); expect(fs.file(uri), exists); }); @@ -204,11 +206,11 @@ void runCommonTests( }); // Fails due to - // https://github.com/google/file.dart/issues/112 + // https://github.com/dart-lang/tools/issues/632 test('considersBothSlashesEquivalent', () { fs.file(r'foo\bar_file').createSync(recursive: true); expect(fs.file(r'foo/bar_file'), exists); - }, skip: 'Fails due to https://github.com/google/file.dart/issues/112'); + }, skip: 'Fails due to https://github.com/dart-lang/tools/issues/632'); }); group('link', () { @@ -223,7 +225,7 @@ void runCommonTests( test('succeedsWithUriArgument', () { fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - Uri uri = fs.path.toUri(ns('/bar')); + var uri = fs.path.toUri(ns('/bar')); expect(fs.link(uri), exists); }); @@ -248,7 +250,7 @@ void runCommonTests( group('systemTempDirectory', () { test('existsAsDirectory', () { - Directory tmp = fs.systemTempDirectory; + var tmp = fs.systemTempDirectory; expect(tmp, isDirectory); expect(tmp, exists); }); @@ -318,7 +320,7 @@ void runCommonTests( test('staysAtRootIfSetToParentOfRoot', () { fs.currentDirectory = List.filled(20, '..').join(fs.path.separator); - String cwd = fs.currentDirectory.path; + var cwd = fs.currentDirectory.path; expect(cwd, fs.path.rootPrefix(cwd)); }); @@ -371,36 +373,36 @@ void runCommonTests( group('stat', () { test('isNotFoundForEmptyPath', () { - FileStat stat = fs.statSync(''); + var stat = fs.statSync(''); expect(stat.type, FileSystemEntityType.notFound); }); test('isNotFoundForPathToNonExistentEntityAtTail', () { - FileStat stat = fs.statSync(ns('/foo')); + var stat = fs.statSync(ns('/foo')); expect(stat.type, FileSystemEntityType.notFound); }); test('isNotFoundForPathToNonExistentEntityInTraversal', () { - FileStat stat = fs.statSync(ns('/foo/bar')); + var stat = fs.statSync(ns('/foo/bar')); expect(stat.type, FileSystemEntityType.notFound); }); test('isDirectoryForDirectory', () { fs.directory(ns('/foo')).createSync(); - FileStat stat = fs.statSync(ns('/foo')); + var stat = fs.statSync(ns('/foo')); expect(stat.type, FileSystemEntityType.directory); }); test('isFileForFile', () { fs.file(ns('/foo')).createSync(); - FileStat stat = fs.statSync(ns('/foo')); + var stat = fs.statSync(ns('/foo')); expect(stat.type, FileSystemEntityType.file); }); test('isFileForLinkToFile', () { fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - FileStat stat = fs.statSync(ns('/bar')); + var stat = fs.statSync(ns('/bar')); expect(stat.type, FileSystemEntityType.file); }); @@ -408,7 +410,7 @@ void runCommonTests( fs.link(ns('/foo')).createSync(ns('/bar')); fs.link(ns('/bar')).createSync(ns('/baz')); fs.link(ns('/baz')).createSync(ns('/foo')); - FileStat stat = fs.statSync(ns('/foo')); + var stat = fs.statSync(ns('/foo')); expect(stat.type, FileSystemEntityType.notFound); }); }); @@ -454,18 +456,18 @@ void runCommonTests( group('type', () { test('isFileForFile', () { fs.file(ns('/foo')).createSync(); - FileSystemEntityType type = fs.typeSync(ns('/foo')); + var type = fs.typeSync(ns('/foo')); expect(type, FileSystemEntityType.file); }); test('isDirectoryForDirectory', () { fs.directory(ns('/foo')).createSync(); - FileSystemEntityType type = fs.typeSync(ns('/foo')); + var type = fs.typeSync(ns('/foo')); expect(type, FileSystemEntityType.directory); }); test('isDirectoryForAncestorOfRoot', () { - FileSystemEntityType type = fs + var type = fs .typeSync(List.filled(20, '..').join(fs.path.separator)); expect(type, FileSystemEntityType.directory); }); @@ -473,15 +475,14 @@ void runCommonTests( test('isFileForLinkToFileAndFollowLinksTrue', () { fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - FileSystemEntityType type = fs.typeSync(ns('/bar')); + var type = fs.typeSync(ns('/bar')); expect(type, FileSystemEntityType.file); }); test('isLinkForLinkToFileAndFollowLinksFalse', () { fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - FileSystemEntityType type = - fs.typeSync(ns('/bar'), followLinks: false); + var type = fs.typeSync(ns('/bar'), followLinks: false); expect(type, FileSystemEntityType.link); }); @@ -489,17 +490,17 @@ void runCommonTests( fs.link(ns('/foo')).createSync(ns('/bar')); fs.link(ns('/bar')).createSync(ns('/baz')); fs.link(ns('/baz')).createSync(ns('/foo')); - FileSystemEntityType type = fs.typeSync(ns('/foo')); + var type = fs.typeSync(ns('/foo')); expect(type, FileSystemEntityType.notFound); }); test('isNotFoundForNoEntityAtTail', () { - FileSystemEntityType type = fs.typeSync(ns('/foo')); + var type = fs.typeSync(ns('/foo')); expect(type, FileSystemEntityType.notFound); }); test('isNotFoundForNoDirectoryInTraversal', () { - FileSystemEntityType type = fs.typeSync(ns('/foo/bar/baz')); + var type = fs.typeSync(ns('/foo/bar/baz')); expect(type, FileSystemEntityType.notFound); }); }); @@ -676,8 +677,8 @@ void runCommonTests( }); test('succeedsIfDestinationDoesntExist', () { - Directory src = fs.directory(ns('/foo'))..createSync(); - Directory dest = src.renameSync(ns('/bar')); + var src = fs.directory(ns('/foo'))..createSync(); + var dest = src.renameSync(ns('/bar')); expect(dest.path, ns('/bar')); expect(dest, exists); }); @@ -686,8 +687,8 @@ void runCommonTests( 'succeedsIfDestinationIsEmptyDirectory', () { fs.directory(ns('/bar')).createSync(); - Directory src = fs.directory(ns('/foo'))..createSync(); - Directory dest = src.renameSync(ns('/bar')); + var src = fs.directory(ns('/foo'))..createSync(); + var dest = src.renameSync(ns('/bar')); expect(src, isNot(exists)); expect(dest, exists); }, @@ -697,14 +698,14 @@ void runCommonTests( test('throwsIfDestinationIsFile', () { fs.file(ns('/bar')).createSync(); - Directory src = fs.directory(ns('/foo'))..createSync(); + var src = fs.directory(ns('/foo'))..createSync(); expectFileSystemException(ErrorCodes.ENOTDIR, () { src.renameSync(ns('/bar')); }); }); test('throwsIfDestinationParentFolderDoesntExist', () { - Directory src = fs.directory(ns('/foo'))..createSync(); + var src = fs.directory(ns('/foo'))..createSync(); expectFileSystemException(ErrorCodes.ENOENT, () { src.renameSync(ns('/bar/baz')); }); @@ -712,7 +713,7 @@ void runCommonTests( test('throwsIfDestinationIsNonEmptyDirectory', () { fs.file(ns('/bar/baz')).createSync(recursive: true); - Directory src = fs.directory(ns('/foo'))..createSync(); + var src = fs.directory(ns('/foo'))..createSync(); // The error will be 'Directory not empty' on OS X, but it will be // 'File exists' on Linux. expectFileSystemException( @@ -749,7 +750,7 @@ void runCommonTests( }); test('throwsIfDestinationIsLinkToNotFound', () { - Directory src = fs.directory(ns('/foo'))..createSync(); + var src = fs.directory(ns('/foo'))..createSync(); fs.link(ns('/bar')).createSync(ns('/baz')); expectFileSystemException(ErrorCodes.ENOTDIR, () { src.renameSync(ns('/bar')); @@ -757,7 +758,7 @@ void runCommonTests( }); test('throwsIfDestinationIsLinkToEmptyDirectory', () { - Directory src = fs.directory(ns('/foo'))..createSync(); + var src = fs.directory(ns('/foo'))..createSync(); fs.directory(ns('/bar')).createSync(); fs.link(ns('/baz')).createSync(ns('/bar')); expectFileSystemException(ErrorCodes.ENOTDIR, () { @@ -766,7 +767,7 @@ void runCommonTests( }); test('succeedsIfDestinationIsInDifferentDirectory', () { - Directory src = fs.directory(ns('/foo'))..createSync(); + var src = fs.directory(ns('/foo'))..createSync(); fs.directory(ns('/bar')).createSync(); src.renameSync(ns('/bar/baz')); expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound); @@ -790,24 +791,24 @@ void runCommonTests( group('delete', () { test('returnsCovariantType', () async { - Directory dir = fs.directory(ns('/foo'))..createSync(); + var dir = fs.directory(ns('/foo'))..createSync(); expect(await dir.delete(), isDirectory); }); test('succeedsIfEmptyDirectoryExistsAndRecursiveFalse', () { - Directory dir = fs.directory(ns('/foo'))..createSync(); + var dir = fs.directory(ns('/foo'))..createSync(); dir.deleteSync(); expect(dir, isNot(exists)); }); test('succeedsIfEmptyDirectoryExistsAndRecursiveTrue', () { - Directory dir = fs.directory(ns('/foo'))..createSync(); + var dir = fs.directory(ns('/foo'))..createSync(); dir.deleteSync(recursive: true); expect(dir, isNot(exists)); }); test('throwsIfNonEmptyDirectoryExistsAndRecursiveFalse', () { - Directory dir = fs.directory(ns('/foo'))..createSync(); + var dir = fs.directory(ns('/foo'))..createSync(); fs.file(ns('/foo/bar')).createSync(); expectFileSystemException(ErrorCodes.ENOTEMPTY, () { dir.deleteSync(); @@ -815,7 +816,7 @@ void runCommonTests( }); test('succeedsIfNonEmptyDirectoryExistsAndRecursiveTrue', () { - Directory dir = fs.directory(ns('/foo'))..createSync(); + var dir = fs.directory(ns('/foo'))..createSync(); fs.file(ns('/foo/bar')).createSync(); dir.deleteSync(recursive: true); expect(fs.directory(ns('/foo')), isNot(exists)); @@ -997,7 +998,7 @@ void runCommonTests( test('handlesParentAndThisFolderReferences', () { fs.directory(ns('/foo/bar/baz')).createSync(recursive: true); fs.link(ns('/foo/bar/baz/qux')).createSync(fs.path.join('..', '..')); - String resolved = fs + var resolved = fs .directory(ns('/foo/./bar/baz/../baz/qux/bar')) .resolveSymbolicLinksSync(); expect(resolved, ns('/foo/bar')); @@ -1015,7 +1016,7 @@ void runCommonTests( .createSync(fs.path.join('..', '..', 'qux'), recursive: true); fs.link(ns('/qux')).createSync('quux'); fs.link(ns('/quux/quuz')).createSync(ns('/foo'), recursive: true); - String resolved = fs + var resolved = fs .directory(ns('/foo//bar/./baz/quuz/bar/..///bar/baz/')) .resolveSymbolicLinksSync(); expect(resolved, ns('/quux')); @@ -1069,29 +1070,29 @@ void runCommonTests( test('resolvesNameCollisions', () { fs.directory(ns('/foo/bar')).createSync(recursive: true); - Directory tmp = fs.directory(ns('/foo')).createTempSync('bar'); + var tmp = fs.directory(ns('/foo')).createTempSync('bar'); expect(tmp.path, allOf(isNot(ns('/foo/bar')), startsWith(ns('/foo/bar')))); }); test('succeedsWithoutPrefix', () { - Directory dir = fs.directory(ns('/foo'))..createSync(); + var dir = fs.directory(ns('/foo'))..createSync(); expect(dir.createTempSync().path, startsWith(ns('/foo/'))); }); test('succeedsWithPrefix', () { - Directory dir = fs.directory(ns('/foo'))..createSync(); + var 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); - Directory tmp = fs.directory(ns('/foo')).createTempSync('bar/baz'); + var tmp = fs.directory(ns('/foo')).createTempSync('bar/baz'); expect(tmp.path, startsWith(ns('/foo/bar/baz'))); }); test('throwsWithNestedPathPrefixThatDoesntExist', () { - Directory dir = fs.directory(ns('/foo'))..createSync(); + var dir = fs.directory(ns('/foo'))..createSync(); expectFileSystemException(ErrorCodes.ENOENT, () { dir.createTempSync('bar/baz'); }); @@ -1123,7 +1124,7 @@ void runCommonTests( }); test('returnsEmptyListForEmptyDirectory', () { - Directory empty = fs.directory(ns('/bar'))..createSync(); + var empty = fs.directory(ns('/bar'))..createSync(); expect(empty.listSync(), isEmpty); }); @@ -1134,7 +1135,7 @@ void runCommonTests( }); test('returnsLinkObjectsIfFollowLinksFalse', () { - List list = dir.listSync(followLinks: false); + var 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'))))); @@ -1142,7 +1143,7 @@ void runCommonTests( }); test('followsLinksIfFollowLinksTrue', () { - List list = dir.listSync(); + var 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'))))); @@ -1189,8 +1190,7 @@ void runCommonTests( test('childEntriesNotNormalized', () { dir = fs.directory(ns('/bar/baz'))..createSync(recursive: true); fs.file(ns('/bar/baz/qux')).createSync(); - List list = - fs.directory(ns('/bar//../bar/./baz')).listSync(); + var list = fs.directory(ns('/bar//../bar/./baz')).listSync(); expect(list, hasLength(1)); expect(list[0], allOf(isFile, hasPath(ns('/bar//../bar/./baz/qux')))); }); @@ -1198,9 +1198,8 @@ void runCommonTests( test('symlinksToNotFoundAlwaysReturnedAsLinks', () { dir = fs.directory(ns('/bar'))..createSync(); fs.link(ns('/bar/baz')).createSync('qux'); - for (bool followLinks in const [true, false]) { - List list = - dir.listSync(followLinks: followLinks); + for (var followLinks in const [true, false]) { + var list = dir.listSync(followLinks: followLinks); expect(list, hasLength(1)); expect(list[0], allOf(isLink, hasPath(ns('/bar/baz')))); } @@ -1208,7 +1207,7 @@ void runCommonTests( }); test('childEntities', () { - Directory dir = fs.directory(ns('/foo'))..createSync(); + var dir = fs.directory(ns('/foo'))..createSync(); dir.childDirectory('bar').createSync(); dir.childFile('baz').createSync(); dir.childLink('qux').createSync('bar'); @@ -1321,22 +1320,22 @@ void runCommonTests( }); test('succeedsIfDestinationDoesntExistAtTail', () { - File src = fs.file(ns('/foo'))..createSync(); - File dest = src.renameSync(ns('/bar')); + var src = fs.file(ns('/foo'))..createSync(); + var dest = src.renameSync(ns('/bar')); expect(fs.file(ns('/foo')), isNot(exists)); expect(fs.file(ns('/bar')), exists); expect(dest.path, ns('/bar')); }); test('throwsIfDestinationDoesntExistViaTraversal', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); expectFileSystemException(ErrorCodes.ENOENT, () { f.renameSync(ns('/bar/baz')); }); }); test('succeedsIfDestinationExistsAsFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.file(ns('/bar')).createSync(); f.renameSync(ns('/bar')); expect(fs.file(ns('/foo')), isNot(exists)); @@ -1344,7 +1343,7 @@ void runCommonTests( }); test('throwsIfDestinationExistsAsDirectory', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.directory(ns('/bar')).createSync(); expectFileSystemException(ErrorCodes.EISDIR, () { f.renameSync(ns('/bar')); @@ -1352,7 +1351,7 @@ void runCommonTests( }); test('succeedsIfDestinationExistsAsLinkToFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.file(ns('/bar')).createSync(); fs.link(ns('/baz')).createSync(ns('/bar')); f.renameSync(ns('/baz')); @@ -1364,7 +1363,7 @@ void runCommonTests( }); test('throwsIfDestinationExistsAsLinkToDirectory', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.directory(ns('/bar')).createSync(); fs.link(ns('/baz')).createSync(ns('/bar')); expectFileSystemException(ErrorCodes.EISDIR, () { @@ -1373,7 +1372,7 @@ void runCommonTests( }); test('succeedsIfDestinationExistsAsLinkToNotFound', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.link(ns('/bar')).createSync(ns('/baz')); f.renameSync(ns('/bar')); expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound); @@ -1429,7 +1428,7 @@ void runCommonTests( }); test('succeedsIfDestinationDoesntExistAtTail', () { - File f = fs.file(ns('/foo')) + var f = fs.file(ns('/foo')) ..createSync() ..writeAsStringSync('foo'); f.copySync(ns('/bar')); @@ -1439,14 +1438,14 @@ void runCommonTests( }); test('throwsIfDestinationDoesntExistViaTraversal', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); expectFileSystemException(ErrorCodes.ENOENT, () { f.copySync(ns('/bar/baz')); }); }); test('succeedsIfDestinationExistsAsFile', () { - File f = fs.file(ns('/foo')) + var f = fs.file(ns('/foo')) ..createSync() ..writeAsStringSync('foo'); fs.file(ns('/bar')) @@ -1460,7 +1459,7 @@ void runCommonTests( }); test('throwsIfDestinationExistsAsDirectory', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.directory(ns('/bar')).createSync(); expectFileSystemException(ErrorCodes.EISDIR, () { f.copySync(ns('/bar')); @@ -1468,7 +1467,7 @@ void runCommonTests( }); test('succeedsIfDestinationExistsAsLinkToFile', () { - File f = fs.file(ns('/foo')) + var f = fs.file(ns('/foo')) ..createSync() ..writeAsStringSync('foo'); fs.file(ns('/bar')) @@ -1487,7 +1486,7 @@ void runCommonTests( }, skip: io.Platform.isWindows /* No links on Windows */); test('throwsIfDestinationExistsAsLinkToDirectory', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.directory(ns('/bar')).createSync(); fs.link(ns('/baz')).createSync(ns('/bar')); expectFileSystemException(ErrorCodes.EISDIR, () { @@ -1525,7 +1524,7 @@ void runCommonTests( }); test('succeedsIfDestinationIsInDifferentDirectoryThanSource', () { - File f = fs.file(ns('/foo/bar')) + var f = fs.file(ns('/foo/bar')) ..createSync(recursive: true) ..writeAsStringSync('foo'); fs.directory(ns('/baz')).createSync(); @@ -1587,12 +1586,12 @@ void runCommonTests( }); test('returnsZeroForNewlyCreatedFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); expect(f.lengthSync(), 0); }); test('writeNBytesReturnsLengthN', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsBytesSync([1, 2, 3, 4], flush: true); expect(f.lengthSync(), 4); }); @@ -1616,10 +1615,10 @@ void runCommonTests( group('lastAccessed', () { test('isNowForNewlyCreatedFile', () { - DateTime before = downstairs(); - File f = fs.file(ns('/foo'))..createSync(); - DateTime after = ceil(); - DateTime accessed = f.lastAccessedSync(); + var before = downstairs(); + var f = fs.file(ns('/foo'))..createSync(); + var after = ceil(); + var accessed = f.lastAccessedSync(); expect(accessed, isSameOrAfter(before)); expect(accessed, isSameOrBefore(after)); }); @@ -1638,18 +1637,18 @@ void runCommonTests( }); test('succeedsIfExistsAsLinkToFile', () { - DateTime before = downstairs(); + var before = downstairs(); fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - DateTime after = ceil(); - DateTime accessed = fs.file(ns('/bar')).lastAccessedSync(); + var after = ceil(); + var accessed = fs.file(ns('/bar')).lastAccessedSync(); expect(accessed, isSameOrAfter(before)); expect(accessed, isSameOrBefore(after)); }); }); group('setLastAccessed', () { - final DateTime time = DateTime(1999); + final time = DateTime(1999); test('throwsIfDoesntExist', () { expectFileSystemException(ErrorCodes.ENOENT, () { @@ -1665,13 +1664,13 @@ void runCommonTests( }); test('succeedsIfExistsAsFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.setLastAccessedSync(time); expect(fs.file(ns('/foo')).lastAccessedSync(), time); }); test('succeedsIfExistsAsLinkToFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); f.setLastAccessedSync(time); expect(fs.file(ns('/bar')).lastAccessedSync(), time); @@ -1680,10 +1679,10 @@ void runCommonTests( group('lastModified', () { test('isNowForNewlyCreatedFile', () { - DateTime before = downstairs(); - File f = fs.file(ns('/foo'))..createSync(); - DateTime after = ceil(); - DateTime modified = f.lastModifiedSync(); + var before = downstairs(); + var f = fs.file(ns('/foo'))..createSync(); + var after = ceil(); + var modified = f.lastModifiedSync(); expect(modified, isSameOrAfter(before)); expect(modified, isSameOrBefore(after)); }); @@ -1702,18 +1701,18 @@ void runCommonTests( }); test('succeedsIfExistsAsLinkToFile', () { - DateTime before = downstairs(); + var before = downstairs(); fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - DateTime after = ceil(); - DateTime modified = fs.file(ns('/bar')).lastModifiedSync(); + var after = ceil(); + var modified = fs.file(ns('/bar')).lastModifiedSync(); expect(modified, isSameOrAfter(before)); expect(modified, isSameOrBefore(after)); }); }); group('setLastModified', () { - final DateTime time = DateTime(1999); + final time = DateTime(1999); test('throwsIfDoesntExist', () { expectFileSystemException(ErrorCodes.ENOENT, () { @@ -1729,13 +1728,13 @@ void runCommonTests( }); test('succeedsIfExistsAsFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.setLastModifiedSync(time); expect(fs.file(ns('/foo')).lastModifiedSync(), time); }); test('succeedsIfExistsAsLinkToFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); f.setLastModifiedSync(time); expect(fs.file(ns('/bar')).lastModifiedSync(), time); @@ -1752,7 +1751,7 @@ void runCommonTests( }); } else { test('createsFileIfDoesntExistAtTail', () { - RandomAccessFile raf = fs.file(ns('/bar')).openSync(mode: mode); + var raf = fs.file(ns('/bar')).openSync(mode: mode); raf.closeSync(); expect(fs.file(ns('/bar')), exists); }); @@ -1877,39 +1876,39 @@ void runCommonTests( }); test('readIntoWithBufferLargerThanContent', () { - List buffer = List.filled(1024, 0); - int numRead = raf.readIntoSync(buffer); + var buffer = List.filled(1024, 0); + var numRead = raf.readIntoSync(buffer); expect(numRead, 21); expect(utf8.decode(buffer.sublist(0, 21)), 'pre-existing content\n'); }); test('readIntoWithBufferSmallerThanContent', () { - List buffer = List.filled(10, 0); - int numRead = raf.readIntoSync(buffer); + var buffer = List.filled(10, 0); + var numRead = raf.readIntoSync(buffer); expect(numRead, 10); expect(utf8.decode(buffer), 'pre-existi'); }); test('readIntoWithStart', () { - List buffer = List.filled(10, 0); - int numRead = raf.readIntoSync(buffer, 2); + var buffer = List.filled(10, 0); + var numRead = raf.readIntoSync(buffer, 2); expect(numRead, 8); expect(utf8.decode(buffer.sublist(2)), 'pre-exis'); }); test('readIntoWithStartAndEnd', () { - List buffer = List.filled(10, 0); - int numRead = raf.readIntoSync(buffer, 2, 5); + var buffer = List.filled(10, 0); + var numRead = raf.readIntoSync(buffer, 2, 5); expect(numRead, 3); expect(utf8.decode(buffer.sublist(2, 5)), 'pre'); }); test('openReadHandleDoesNotChange', () { - final String initial = utf8.decode(raf.readSync(4)); + final initial = utf8.decode(raf.readSync(4)); expect(initial, 'pre-'); - final File newFile = f.renameSync(ns('/bar')); - String rest = utf8.decode(raf.readSync(1024)); + final newFile = f.renameSync(ns('/bar')); + var rest = utf8.decode(raf.readSync(1024)); expect(rest, 'existing content\n'); assert(newFile.path != f.path); @@ -1942,13 +1941,13 @@ void runCommonTests( }); } else { test('lengthGrowsAsDataIsWritten', () { - int lengthBefore = f.lengthSync(); + var lengthBefore = f.lengthSync(); raf.writeByteSync(0xFACE); expect(raf.lengthSync(), lengthBefore + 1); }); test('flush', () { - int lengthBefore = f.lengthSync(); + var lengthBefore = f.lengthSync(); raf.writeByteSync(0xFACE); raf.flushSync(); expect(f.lengthSync(), lengthBefore + 1); @@ -2009,10 +2008,10 @@ void runCommonTests( test('openWriteHandleDoesNotChange', () { raf.writeStringSync('Hello '); - final File newFile = f.renameSync(ns('/bar')); + final newFile = f.renameSync(ns('/bar')); raf.writeStringSync('world'); - final String contents = newFile.readAsStringSync(); + final contents = newFile.readAsStringSync(); if (mode == FileMode.write || mode == FileMode.writeOnly) { expect(contents, 'Hello world'); } else { @@ -2067,7 +2066,7 @@ void runCommonTests( }); } else { test('growsAfterWrite', () { - int positionBefore = raf.positionSync(); + var positionBefore = raf.positionSync(); raf.writeStringSync('Hello world'); expect(raf.positionSync(), positionBefore + 11); }); @@ -2165,42 +2164,42 @@ void runCommonTests( group('openRead', () { test('throwsIfDoesntExist', () { - Stream> stream = fs.file(ns('/foo')).openRead(); + var stream = fs.file(ns('/foo')).openRead(); expect(stream.drain(), throwsFileSystemException(ErrorCodes.ENOENT)); }); test('succeedsIfExistsAsFile', () async { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world', flush: true); - Stream> stream = f.openRead(); - List> data = await stream.toList(); + var stream = f.openRead(); + var data = await stream.toList(); expect(data, hasLength(1)); expect(utf8.decode(data[0]), 'Hello world'); }); test('throwsIfExistsAsDirectory', () { fs.directory(ns('/foo')).createSync(); - Stream> stream = fs.file(ns('/foo')).openRead(); + var stream = fs.file(ns('/foo')).openRead(); expect(stream.drain(), throwsFileSystemException(ErrorCodes.EISDIR)); }); test('succeedsIfExistsAsLinkToFile', () async { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); f.writeAsStringSync('Hello world', flush: true); - Stream> stream = fs.file(ns('/bar')).openRead(); - List> data = await stream.toList(); + var stream = fs.file(ns('/bar')).openRead(); + var data = await stream.toList(); expect(data, hasLength(1)); expect(utf8.decode(data[0]), 'Hello world'); }); test('respectsStartAndEndParameters', () async { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world', flush: true); - Stream> stream = f.openRead(2); - List> data = await stream.toList(); + var stream = f.openRead(2); + var data = await stream.toList(); expect(data, hasLength(1)); expect(utf8.decode(data[0]), 'llo world'); stream = f.openRead(2, 5); @@ -2210,24 +2209,24 @@ void runCommonTests( }); test('throwsIfStartParameterIsNegative', () async { - File f = fs.file(ns('/foo'))..createSync(); - Stream> stream = f.openRead(-2); + var f = fs.file(ns('/foo'))..createSync(); + var stream = f.openRead(-2); expect(stream.drain(), throwsRangeError); }); test('stopsAtEndOfFileIfEndParameterIsPastEndOfFile', () async { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world', flush: true); - Stream> stream = f.openRead(2, 1024); - List> data = await stream.toList(); + var stream = f.openRead(2, 1024); + var data = await stream.toList(); expect(data, hasLength(1)); expect(utf8.decode(data[0]), 'llo world'); }); test('providesSingleSubscriptionStream', () async { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world', flush: true); - Stream> stream = f.openRead(); + var stream = f.openRead(); expect(stream.isBroadcast, isFalse); await stream.drain(); }); @@ -2237,20 +2236,20 @@ void runCommonTests( // split across multiple chunks in the [Stream]. However, there // doesn't seem to be a good way to determine the chunk size used by // [io.File]. - final List data = List.generate( + final data = List.generate( 1024 * 256, (int index) => index & 0xFF, growable: false, ); - final File f = fs.file(ns('/foo'))..createSync(); + final f = fs.file(ns('/foo'))..createSync(); f.writeAsBytesSync(data, flush: true); - final Stream> stream = f.openRead(); + final stream = f.openRead(); File? newFile; List? initialChunk; - final List remainingChunks = []; + final remainingChunks = []; await for (List chunk in stream) { if (initialChunk == null) { @@ -2276,7 +2275,7 @@ void runCommonTests( test('openReadCompatibleWithUtf8Decoder', () async { const content = 'Hello world!'; - File file = fs.file(ns('/foo')) + var file = fs.file(ns('/foo')) ..createSync() ..writeAsStringSync(content); expect( @@ -2315,8 +2314,8 @@ void runCommonTests( }); test('succeedsIfExistsAsEmptyFile', () async { - File f = fs.file(ns('/foo'))..createSync(); - IOSink sink = f.openWrite(); + var f = fs.file(ns('/foo'))..createSync(); + var sink = f.openWrite(); sink.write('Hello world'); await sink.flush(); await sink.close(); @@ -2326,7 +2325,7 @@ void runCommonTests( test('succeedsIfExistsAsLinkToFile', () async { fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - IOSink sink = fs.file(ns('/bar')).openWrite(); + var sink = fs.file(ns('/bar')).openWrite(); sink.write('Hello world'); await sink.flush(); await sink.close(); @@ -2334,9 +2333,9 @@ void runCommonTests( }); test('overwritesContentInWriteMode', () async { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello'); - IOSink sink = f.openWrite(); + var sink = f.openWrite(); sink.write('Goodbye'); await sink.flush(); await sink.close(); @@ -2344,9 +2343,9 @@ void runCommonTests( }); test('appendsContentInAppendMode', () async { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello'); - IOSink sink = f.openWrite(mode: FileMode.append); + var sink = f.openWrite(mode: FileMode.append); sink.write('Goodbye'); await sink.flush(); await sink.close(); @@ -2354,12 +2353,12 @@ void runCommonTests( }); test('openWriteHandleDoesNotChange', () async { - File f = fs.file(ns('/foo'))..createSync(); - IOSink sink = f.openWrite(); + var f = fs.file(ns('/foo'))..createSync(); + var sink = f.openWrite(); sink.write('Hello'); await sink.flush(); - final File newFile = f.renameSync(ns('/bar')); + final newFile = f.renameSync(ns('/bar')); sink.write('Goodbye'); await sink.flush(); await sink.close(); @@ -2377,7 +2376,7 @@ void runCommonTests( late bool isSinkClosed; Future closeSink() { - Future future = sink.close(); + var future = sink.close(); isSinkClosed = true; return future; } @@ -2448,13 +2447,13 @@ void runCommonTests( test('ignoresCloseAfterAlreadyClosed', () async { sink.write('Hello world'); - Future f1 = closeSink(); - Future f2 = closeSink(); + var f1 = closeSink(); + var f2 = closeSink(); await Future.wait(>[f1, f2]); }); test('returnsAccurateDoneFuture', () async { - bool done = false; + var done = false; // ignore: unawaited_futures sink.done.then((dynamic _) => done = true); expect(done, isFalse); @@ -2469,7 +2468,7 @@ void runCommonTests( late bool isControllerClosed; Future closeController() { - Future future = controller.close(); + var future = controller.close(); isControllerClosed = true; return future; } @@ -2543,7 +2542,7 @@ void runCommonTests( }); test('succeedsIfExistsAsFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsBytesSync([1, 2, 3, 4]); expect(f.readAsBytesSync(), [1, 2, 3, 4]); }); @@ -2556,12 +2555,12 @@ void runCommonTests( }); test('returnsEmptyListForZeroByteFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); expect(f.readAsBytesSync(), isEmpty); }); test('returns a copy, not a view, of the file content', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsBytesSync([1, 2, 3, 4]); List result = f.readAsBytesSync(); expect(result, [1, 2, 3, 4]); @@ -2593,7 +2592,7 @@ void runCommonTests( }); test('succeedsIfExistsAsFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world'); expect(f.readAsStringSync(), 'Hello world'); }); @@ -2606,14 +2605,14 @@ void runCommonTests( }); test('returnsEmptyStringForZeroByteFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); expect(f.readAsStringSync(), isEmpty); }); }); group('readAsLines', () { - const String testString = 'Hello world\nHow are you?\nI am fine'; - final List expectedLines = [ + const testString = 'Hello world\nHow are you?\nI am fine'; + final expectedLines = [ 'Hello world', 'How are you?', 'I am fine', @@ -2641,25 +2640,25 @@ void runCommonTests( }); test('succeedsIfExistsAsFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync(testString); expect(f.readAsLinesSync(), expectedLines); }); test('succeedsIfExistsAsLinkToFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); f.writeAsStringSync(testString); expect(f.readAsLinesSync(), expectedLines); }); test('returnsEmptyListForZeroByteFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); expect(f.readAsLinesSync(), isEmpty); }); test('isTrailingNewlineAgnostic', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('$testString\n'); expect(f.readAsLinesSync(), expectedLines); @@ -2677,7 +2676,7 @@ void runCommonTests( }); test('createsFileIfDoesntExist', () { - File f = fs.file(ns('/foo')); + var f = fs.file(ns('/foo')); expect(f, isNot(exists)); f.writeAsBytesSync([1, 2, 3, 4]); expect(f, exists); @@ -2699,21 +2698,21 @@ void runCommonTests( }); test('succeedsIfExistsAsLinkToFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); fs.file(ns('/bar')).writeAsBytesSync([1, 2, 3, 4]); expect(f.readAsBytesSync(), [1, 2, 3, 4]); }); test('throwsIfFileModeRead', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); expectFileSystemException(ErrorCodes.EBADF, () { f.writeAsBytesSync([1], mode: FileMode.read); }); }); test('overwritesContentIfFileModeWrite', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsBytesSync([1, 2]); expect(f.readAsBytesSync(), [1, 2]); f.writeAsBytesSync([3, 4]); @@ -2721,7 +2720,7 @@ void runCommonTests( }); test('appendsContentIfFileModeAppend', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsBytesSync([1, 2], mode: FileMode.append); expect(f.readAsBytesSync(), [1, 2]); f.writeAsBytesSync([3, 4], mode: FileMode.append); @@ -2729,17 +2728,17 @@ void runCommonTests( }); test('acceptsEmptyBytesList', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsBytesSync([]); expect(f.readAsBytesSync(), []); }); test('updatesLastModifiedTime', () async { - File f = fs.file(ns('/foo'))..createSync(); - DateTime before = f.statSync().modified; + var f = fs.file(ns('/foo'))..createSync(); + var before = f.statSync().modified; await Future.delayed(const Duration(seconds: 2)); f.writeAsBytesSync([1, 2, 3]); - DateTime after = f.statSync().modified; + var after = f.statSync().modified; expect(after, isAfter(before)); }); }); @@ -2750,7 +2749,7 @@ void runCommonTests( }); test('createsFileIfDoesntExist', () { - File f = fs.file(ns('/foo')); + var f = fs.file(ns('/foo')); expect(f, isNot(exists)); f.writeAsStringSync('Hello world'); expect(f, exists); @@ -2772,21 +2771,21 @@ void runCommonTests( }); test('succeedsIfExistsAsLinkToFile', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); fs.file(ns('/bar')).writeAsStringSync('Hello world'); expect(f.readAsStringSync(), 'Hello world'); }); test('throwsIfFileModeRead', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); expectFileSystemException(ErrorCodes.EBADF, () { f.writeAsStringSync('Hello world', mode: FileMode.read); }); }); test('overwritesContentIfFileModeWrite', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello world'); expect(f.readAsStringSync(), 'Hello world'); f.writeAsStringSync('Goodbye cruel world'); @@ -2794,7 +2793,7 @@ void runCommonTests( }); test('appendsContentIfFileModeAppend', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync('Hello', mode: FileMode.append); expect(f.readAsStringSync(), 'Hello'); f.writeAsStringSync('Goodbye', mode: FileMode.append); @@ -2802,7 +2801,7 @@ void runCommonTests( }); test('acceptsEmptyString', () { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); f.writeAsStringSync(''); expect(f.readAsStringSync(), isEmpty); }); @@ -2847,38 +2846,38 @@ void runCommonTests( group('stat', () { test('isNotFoundIfDoesntExistAtTail', () { - FileStat stat = fs.file(ns('/foo')).statSync(); + var stat = fs.file(ns('/foo')).statSync(); expect(stat.type, FileSystemEntityType.notFound); }); test('isNotFoundIfDoesntExistViaTraversal', () { - FileStat stat = fs.file(ns('/foo/bar')).statSync(); + var stat = fs.file(ns('/foo/bar')).statSync(); expect(stat.type, FileSystemEntityType.notFound); }); test('isDirectoryIfExistsAsDirectory', () { fs.directory(ns('/foo')).createSync(); - FileStat stat = fs.file(ns('/foo')).statSync(); + var stat = fs.file(ns('/foo')).statSync(); expect(stat.type, FileSystemEntityType.directory); }); test('isFileIfExistsAsFile', () { fs.file(ns('/foo')).createSync(); - FileStat stat = fs.file(ns('/foo')).statSync(); + var stat = fs.file(ns('/foo')).statSync(); expect(stat.type, FileSystemEntityType.file); }); test('isFileIfExistsAsLinkToFile', () { fs.file(ns('/foo')).createSync(); fs.link(ns('/bar')).createSync(ns('/foo')); - FileStat stat = fs.file(ns('/bar')).statSync(); + var stat = fs.file(ns('/bar')).statSync(); expect(stat.type, FileSystemEntityType.file); }); }); group('delete', () { test('returnsCovariantType', () async { - File f = fs.file(ns('/foo'))..createSync(); + var f = fs.file(ns('/foo'))..createSync(); expect(await f.delete(), isFile); }); @@ -2953,14 +2952,14 @@ void runCommonTests( group('uri', () { test('whenTargetIsDirectory', () { fs.directory(ns('/foo')).createSync(); - Link l = fs.link(ns('/bar'))..createSync(ns('/foo')); + var l = fs.link(ns('/bar'))..createSync(ns('/foo')); expect(l.uri, fs.path.toUri(ns('/bar'))); expect(fs.link('bar').uri.toString(), 'bar'); }); test('whenTargetIsFile', () { fs.file(ns('/foo')).createSync(); - Link l = fs.link(ns('/bar'))..createSync(ns('/foo')); + var l = fs.link(ns('/bar'))..createSync(ns('/foo')); expect(l.uri, fs.path.toUri(ns('/bar'))); expect(fs.link('bar').uri.toString(), 'bar'); }); @@ -2991,24 +2990,24 @@ void runCommonTests( }); test('isTrueIfTargetIsNotFound', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); expect(l, exists); }); test('isTrueIfTargetIsFile', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.file(ns('/bar')).createSync(); expect(l, exists); }); test('isTrueIfTargetIsDirectory', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.directory(ns('/bar')).createSync(); expect(l, exists); }); test('isTrueIfTargetIsLinkLoop', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.link(ns('/bar')).createSync(ns('/foo')); expect(l, exists); }); @@ -3038,29 +3037,29 @@ void runCommonTests( }); test('isNotFoundIfTargetNotFoundAtTail', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); expect(l.statSync().type, FileSystemEntityType.notFound); }); test('isNotFoundIfTargetNotFoundViaTraversal', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar/baz')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar/baz')); expect(l.statSync().type, FileSystemEntityType.notFound); }); test('isNotFoundIfTargetIsLinkLoop', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.link(ns('/bar')).createSync(ns('/foo')); expect(l.statSync().type, FileSystemEntityType.notFound); }); test('isFileIfTargetIsFile', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.file(ns('/bar')).createSync(); expect(l.statSync().type, FileSystemEntityType.file); }); test('isDirectoryIfTargetIsDirectory', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.directory(ns('/bar')).createSync(); expect(l.statSync().type, FileSystemEntityType.directory); }); @@ -3068,7 +3067,7 @@ void runCommonTests( group('delete', () { test('returnsCovariantType', () async { - Link link = fs.link(ns('/foo'))..createSync(ns('/bar')); + var link = fs.link(ns('/foo'))..createSync(ns('/bar')); expect(await link.delete(), isLink); }); @@ -3118,7 +3117,7 @@ void runCommonTests( }); test('unlinksIfTargetIsFileAndRecursiveFalse', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.file(ns('/bar')).createSync(); l.deleteSync(); expect(fs.typeSync(ns('/foo'), followLinks: false), @@ -3128,7 +3127,7 @@ void runCommonTests( }); test('unlinksIfTargetIsFileAndRecursiveTrue', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.file(ns('/bar')).createSync(); l.deleteSync(recursive: true); expect(fs.typeSync(ns('/foo'), followLinks: false), @@ -3138,7 +3137,7 @@ void runCommonTests( }); test('unlinksIfTargetIsDirectoryAndRecursiveFalse', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.directory(ns('/bar')).createSync(); l.deleteSync(); expect(fs.typeSync(ns('/foo'), followLinks: false), @@ -3148,7 +3147,7 @@ void runCommonTests( }); test('unlinksIfTargetIsDirectoryAndRecursiveTrue', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.directory(ns('/bar')).createSync(); l.deleteSync(recursive: true); expect(fs.typeSync(ns('/foo'), followLinks: false), @@ -3158,7 +3157,7 @@ void runCommonTests( }); test('unlinksIfTargetIsLinkLoop', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.link(ns('/bar')).createSync(ns('/foo')); l.deleteSync(); expect(fs.typeSync(ns('/foo'), followLinks: false), @@ -3178,7 +3177,7 @@ void runCommonTests( }); test('ignoresLinkTarget', () { - Link l = fs.link(ns('/foo/bar')) + var l = fs.link(ns('/foo/bar')) ..createSync(ns('/baz/qux'), recursive: true); expect(l.parent.path, ns('/foo')); }); @@ -3190,7 +3189,7 @@ void runCommonTests( }); test('succeedsIfLinkDoesntExistAtTail', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); expect(fs.typeSync(ns('/foo'), followLinks: false), FileSystemEntityType.link); expect(l.targetSync(), ns('/bar')); @@ -3203,7 +3202,7 @@ void runCommonTests( }); test('succeedsIfLinkDoesntExistViaTraversalAndRecursiveTrue', () { - Link l = fs.link(ns('/foo/bar'))..createSync('baz', recursive: true); + var l = fs.link(ns('/foo/bar'))..createSync('baz', recursive: true); expect(fs.typeSync(ns('/foo'), followLinks: false), FileSystemEntityType.directory); expect(fs.typeSync(ns('/foo/bar'), followLinks: false), @@ -3242,7 +3241,7 @@ void runCommonTests( group('update', () { test('returnsCovariantType', () async { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); expect(await l.update(ns('/baz')), isLink); }); @@ -3336,24 +3335,24 @@ void runCommonTests( }); test('succeedsIfTargetIsNotFound', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); expect(l.targetSync(), ns('/bar')); }); test('succeedsIfTargetIsFile', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.file(ns('/bar')).createSync(); expect(l.targetSync(), ns('/bar')); }); test('succeedsIfTargetIsDirectory', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.directory(ns('/bar')).createSync(); expect(l.targetSync(), ns('/bar')); }); test('succeedsIfTargetIsLinkLoop', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.link(ns('/bar')).createSync(ns('/foo')); expect(l.targetSync(), ns('/bar')); }); @@ -3393,9 +3392,9 @@ void runCommonTests( }); test('succeedsIfSourceIsLinkToFile', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.file(ns('/bar')).createSync(); - Link renamed = l.renameSync(ns('/baz')); + var renamed = l.renameSync(ns('/baz')); expect(renamed.path, ns('/baz')); expect(fs.typeSync(ns('/foo'), followLinks: false), FileSystemEntityType.notFound); @@ -3407,8 +3406,8 @@ void runCommonTests( }); test('succeedsIfSourceIsLinkToNotFound', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); - Link renamed = l.renameSync(ns('/baz')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var renamed = l.renameSync(ns('/baz')); expect(renamed.path, ns('/baz')); expect(fs.typeSync(ns('/foo'), followLinks: false), FileSystemEntityType.notFound); @@ -3418,9 +3417,9 @@ void runCommonTests( }); test('succeedsIfSourceIsLinkToDirectory', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.directory(ns('/bar')).createSync(); - Link renamed = l.renameSync(ns('/baz')); + var renamed = l.renameSync(ns('/baz')); expect(renamed.path, ns('/baz')); expect(fs.typeSync(ns('/foo'), followLinks: false), FileSystemEntityType.notFound); @@ -3432,9 +3431,9 @@ void runCommonTests( }); test('succeedsIfSourceIsLinkLoop', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.link(ns('/bar')).createSync(ns('/foo')); - Link renamed = l.renameSync(ns('/baz')); + var renamed = l.renameSync(ns('/baz')); expect(renamed.path, ns('/baz')); expect(fs.typeSync(ns('/foo'), followLinks: false), FileSystemEntityType.notFound); @@ -3446,22 +3445,22 @@ void runCommonTests( }); test('succeedsIfDestinationDoesntExistAtTail', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); - Link renamed = l.renameSync(ns('/baz')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var renamed = l.renameSync(ns('/baz')); expect(renamed.path, ns('/baz')); expect(fs.link(ns('/foo')), isNot(exists)); expect(fs.link(ns('/baz')), exists); }); test('throwsIfDestinationDoesntExistViaTraversal', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); expectFileSystemException(ErrorCodes.ENOENT, () { l.renameSync(ns('/baz/qux')); }); }); test('throwsIfDestinationExistsAsFile', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.file(ns('/baz')).createSync(); expectFileSystemException(ErrorCodes.EINVAL, () { l.renameSync(ns('/baz')); @@ -3469,7 +3468,7 @@ void runCommonTests( }); test('throwsIfDestinationExistsAsDirectory', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.directory(ns('/baz')).createSync(); expectFileSystemException(ErrorCodes.EINVAL, () { l.renameSync(ns('/baz')); @@ -3477,7 +3476,7 @@ void runCommonTests( }); test('succeedsIfDestinationExistsAsLinkToFile', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.file(ns('/baz')).createSync(); fs.link(ns('/qux')).createSync(ns('/baz')); l.renameSync(ns('/qux')); @@ -3490,7 +3489,7 @@ void runCommonTests( }); test('throwsIfDestinationExistsAsLinkToDirectory', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.directory(ns('/baz')).createSync(); fs.link(ns('/qux')).createSync(ns('/baz')); l.renameSync(ns('/qux')); @@ -3503,7 +3502,7 @@ void runCommonTests( }); test('succeedsIfDestinationExistsAsLinkToNotFound', () { - Link l = fs.link(ns('/foo'))..createSync(ns('/bar')); + var l = fs.link(ns('/foo'))..createSync(ns('/bar')); fs.link(ns('/baz')).createSync(ns('/qux')); l.renameSync(ns('/baz')); expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound); diff --git a/pkgs/file/test/local_test.dart b/pkgs/file/test/local_test.dart index e1618d230..b794ccd7b 100644 --- a/pkgs/file/test/local_test.dart +++ b/pkgs/file/test/local_test.dart @@ -2,7 +2,11 @@ // 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. +// ignore_for_file: lines_longer_than_80_chars + @TestOn('vm') +library; + import 'dart:io' as io; import 'package:file/local.dart'; @@ -33,7 +37,7 @@ void main() { setUpAll(() { if (io.Platform.isWindows) { // TODO(tvolkert): Remove once all more serious test failures are fixed - // https://github.com/google/file.dart/issues/56 + // https://github.com/dart-lang/tools/issues/618 ignoreOsErrorCodes = true; } }); @@ -42,7 +46,7 @@ void main() { ignoreOsErrorCodes = false; }); - Map> skipOnPlatform = >{ + var skipOnPlatform = >{ 'windows': [ 'FileSystem > currentDirectory > throwsIfHasNonExistentPathInComplexChain', 'FileSystem > currentDirectory > resolvesLinksIfEncountered', diff --git a/pkgs/file/test/memory_operations_test.dart b/pkgs/file/test/memory_operations_test.dart index 5e27843b5..916707c62 100644 --- a/pkgs/file/test/memory_operations_test.dart +++ b/pkgs/file/test/memory_operations_test.dart @@ -2,22 +2,21 @@ // 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 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:test/test.dart'; void main() { test('Read operations invoke opHandle', () async { - List contexts = []; - List operations = []; - MemoryFileSystem fs = MemoryFileSystem.test( + var contexts = []; + var operations = []; + var fs = MemoryFileSystem.test( opHandle: (String context, FileSystemOp operation) { if (operation == FileSystemOp.read) { contexts.add(context); operations.add(operation); } }); - final File file = fs.file('test')..createSync(); + final file = fs.file('test')..createSync(); await file.readAsBytes(); file.readAsBytesSync(); @@ -34,16 +33,16 @@ void main() { }); test('Write operations invoke opHandle', () async { - List contexts = []; - List operations = []; - MemoryFileSystem fs = MemoryFileSystem.test( + var contexts = []; + var operations = []; + var fs = MemoryFileSystem.test( opHandle: (String context, FileSystemOp operation) { if (operation == FileSystemOp.write) { contexts.add(context); operations.add(operation); } }); - final File file = fs.file('test')..createSync(); + final file = fs.file('test')..createSync(); await file.writeAsBytes([]); file.writeAsBytesSync([]); @@ -60,18 +59,18 @@ void main() { }); test('Delete operations invoke opHandle', () async { - List contexts = []; - List operations = []; - MemoryFileSystem fs = MemoryFileSystem.test( + var contexts = []; + var operations = []; + var fs = MemoryFileSystem.test( opHandle: (String context, FileSystemOp operation) { if (operation == FileSystemOp.delete) { contexts.add(context); operations.add(operation); } }); - final File file = fs.file('test')..createSync(); - final Directory directory = fs.directory('testDir')..createSync(); - final Link link = fs.link('testLink')..createSync('foo'); + final file = fs.file('test')..createSync(); + final directory = fs.directory('testDir')..createSync(); + final link = fs.link('testLink')..createSync('foo'); await file.delete(); file.createSync(); @@ -98,9 +97,9 @@ void main() { }); test('Create operations invoke opHandle', () async { - List contexts = []; - List operations = []; - MemoryFileSystem fs = MemoryFileSystem.test( + var contexts = []; + var operations = []; + var fs = MemoryFileSystem.test( opHandle: (String context, FileSystemOp operation) { if (operation == FileSystemOp.create) { contexts.add(context); @@ -139,16 +138,16 @@ void main() { }); test('Open operations invoke opHandle', () async { - List contexts = []; - List operations = []; - MemoryFileSystem fs = MemoryFileSystem.test( + var contexts = []; + var operations = []; + var fs = MemoryFileSystem.test( opHandle: (String context, FileSystemOp operation) { if (operation == FileSystemOp.open) { contexts.add(context); operations.add(operation); } }); - final File file = fs.file('test')..createSync(); + final file = fs.file('test')..createSync(); await file.open(); file.openSync(); @@ -165,16 +164,16 @@ void main() { }); test('Copy operations invoke opHandle', () async { - List contexts = []; - List operations = []; - MemoryFileSystem fs = MemoryFileSystem.test( + var contexts = []; + var operations = []; + var fs = MemoryFileSystem.test( opHandle: (String context, FileSystemOp operation) { if (operation == FileSystemOp.copy) { contexts.add(context); operations.add(operation); } }); - final File file = fs.file('test')..createSync(); + final file = fs.file('test')..createSync(); await file.copy('A'); file.copySync('B'); @@ -187,9 +186,9 @@ void main() { }); test('Exists operations invoke opHandle', () async { - List contexts = []; - List operations = []; - MemoryFileSystem fs = MemoryFileSystem.test( + var contexts = []; + var operations = []; + var fs = MemoryFileSystem.test( opHandle: (String context, FileSystemOp operation) { if (operation == FileSystemOp.exists) { contexts.add(context); diff --git a/pkgs/file/test/memory_test.dart b/pkgs/file/test/memory_test.dart index f3b324e6c..ce8675f2e 100644 --- a/pkgs/file/test/memory_test.dart +++ b/pkgs/file/test/memory_test.dart @@ -66,8 +66,7 @@ void main() { }); test('MemoryFileSystem.test', () { - final MemoryFileSystem fs = - MemoryFileSystem.test(); // creates root directory + final fs = MemoryFileSystem.test(); // creates root directory fs.file('/test1.txt').createSync(); // creates file fs.file('/test2.txt').createSync(); // creates file expect(fs.directory('/').statSync().modified, DateTime(2000, 1, 1, 0, 1)); @@ -95,10 +94,10 @@ void main() { }); test('MemoryFile.openSync returns a MemoryRandomAccessFile', () async { - final MemoryFileSystem fs = MemoryFileSystem.test(); + final fs = MemoryFileSystem.test(); final io.File file = fs.file('/test1')..createSync(); - io.RandomAccessFile raf = file.openSync(); + var raf = file.openSync(); try { expect(raf, isA()); } finally { @@ -114,7 +113,7 @@ void main() { }); test('MemoryFileSystem.systemTempDirectory test', () { - final MemoryFileSystem fs = MemoryFileSystem.test(); + final fs = MemoryFileSystem.test(); final io.Directory fooA = fs.systemTempDirectory.createTempSync('foo'); final io.Directory fooB = fs.systemTempDirectory.createTempSync('foo'); @@ -122,7 +121,7 @@ void main() { expect(fooA.path, '/.tmp_rand0/foorand0'); expect(fooB.path, '/.tmp_rand0/foorand1'); - final MemoryFileSystem secondFs = MemoryFileSystem.test(); + final secondFs = MemoryFileSystem.test(); final io.Directory fooAA = secondFs.systemTempDirectory.createTempSync('foo'); @@ -136,16 +135,16 @@ void main() { test('Failed UTF8 decoding in MemoryFileSystem throws a FileSystemException', () { - final MemoryFileSystem fileSystem = MemoryFileSystem.test(); - final File file = fileSystem.file('foo') + final fileSystem = MemoryFileSystem.test(); + final file = fileSystem.file('foo') ..writeAsBytesSync([0xFFFE]); // Invalid UTF8 expect(file.readAsStringSync, throwsA(isA())); }); test('Creating a temporary directory actually creates the directory', () { - final MemoryFileSystem fileSystem = MemoryFileSystem.test(); - final Directory tempDir = fileSystem.currentDirectory.createTempSync('foo'); + final fileSystem = MemoryFileSystem.test(); + final tempDir = fileSystem.currentDirectory.createTempSync('foo'); expect(tempDir.existsSync(), true); }); diff --git a/pkgs/file/test/utils.dart b/pkgs/file/test/utils.dart index 231312fbe..797ec9de5 100644 --- a/pkgs/file/test/utils.dart +++ b/pkgs/file/test/utils.dart @@ -25,7 +25,7 @@ DateTime floor([DateTime? time]) { /// If [time] is not specified, it will default to the current time. DateTime ceil([DateTime? time]) { time ??= DateTime.now(); - int microseconds = (1000 * time.millisecond) + time.microsecond; + var microseconds = (1000 * time.millisecond) + time.microsecond; return (microseconds == 0) ? time // Add just enough milliseconds and microseconds to reach the next second. @@ -78,7 +78,7 @@ abstract class _CompareDateTime extends Matcher { bool verbose, ) { if (item is DateTime) { - Duration diff = item.difference(_time).abs(); + var diff = item.difference(_time).abs(); return description.add('is $mismatchAdjective $_time by $diff'); } else { return description.add('is not a DateTime'); diff --git a/pkgs/file/test/utils_test.dart b/pkgs/file/test/utils_test.dart index 75293bf3c..23788e983 100644 --- a/pkgs/file/test/utils_test.dart +++ b/pkgs/file/test/utils_test.dart @@ -8,9 +8,9 @@ import 'utils.dart'; void main() { test('floorAndCeilProduceExactSecondDateTime', () { - DateTime time = DateTime.fromMicrosecondsSinceEpoch(1001); - DateTime lower = floor(time); - DateTime upper = ceil(time); + var time = DateTime.fromMicrosecondsSinceEpoch(1001); + var lower = floor(time); + var upper = ceil(time); expect(lower.millisecond, 0); expect(upper.millisecond, 0); expect(lower.microsecond, 0); @@ -18,26 +18,26 @@ void main() { }); test('floorAndCeilWorkWithNow', () { - DateTime time = DateTime.now(); - int lower = time.difference(floor(time)).inMicroseconds; - int upper = ceil(time).difference(time).inMicroseconds; + var time = DateTime.now(); + var lower = time.difference(floor(time)).inMicroseconds; + var upper = ceil(time).difference(time).inMicroseconds; expect(lower, lessThan(1000000)); expect(upper, lessThanOrEqualTo(1000000)); }); test('floorAndCeilWorkWithExactSecondDateTime', () { - DateTime time = DateTime.parse('1999-12-31 23:59:59'); - DateTime lower = floor(time); - DateTime upper = ceil(time); + var time = DateTime.parse('1999-12-31 23:59:59'); + var lower = floor(time); + var upper = ceil(time); expect(lower, time); expect(upper, time); }); test('floorAndCeilWorkWithInexactSecondDateTime', () { - DateTime time = DateTime.parse('1999-12-31 23:59:59.500'); - DateTime lower = floor(time); - DateTime upper = ceil(time); - Duration difference = upper.difference(lower); + var time = DateTime.parse('1999-12-31 23:59:59.500'); + var lower = floor(time); + var upper = ceil(time); + var difference = upper.difference(lower); expect(difference.inMicroseconds, 1000000); }); } diff --git a/pkgs/file_testing/CHANGELOG.md b/pkgs/file_testing/CHANGELOG.md index 0af779d87..17039ee16 100644 --- a/pkgs/file_testing/CHANGELOG.md +++ b/pkgs/file_testing/CHANGELOG.md @@ -1,3 +1,8 @@ +## 3.1.0-wip + +* Changed the type of several matchers to `TypeMatcher` which allows cascading + their usage with `.having` and similar. + ## 3.0.2 * Require Dart 3.1. diff --git a/pkgs/file_testing/analysis_options.yaml b/pkgs/file_testing/analysis_options.yaml index 8fbd2e443..d978f811c 100644 --- a/pkgs/file_testing/analysis_options.yaml +++ b/pkgs/file_testing/analysis_options.yaml @@ -1,6 +1 @@ -include: package:lints/recommended.yaml - -analyzer: - errors: - # Allow having TODOs in the code - todo: ignore +include: package:dart_flutter_team_lints/analysis_options.yaml diff --git a/pkgs/file_testing/lib/src/testing/core_matchers.dart b/pkgs/file_testing/lib/src/testing/core_matchers.dart index f58539f19..801209e89 100644 --- a/pkgs/file_testing/lib/src/testing/core_matchers.dart +++ b/pkgs/file_testing/lib/src/testing/core_matchers.dart @@ -2,6 +2,8 @@ // 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. +// ignore_for_file: comment_references + import 'dart:io'; import 'package:test/test.dart'; @@ -9,26 +11,27 @@ import 'package:test/test.dart'; import 'internal.dart'; /// Matcher that successfully matches against any instance of [Directory]. -const Matcher isDirectory = TypeMatcher(); +const isDirectory = TypeMatcher(); /// Matcher that successfully matches against any instance of [File]. -const Matcher isFile = TypeMatcher(); +const isFile = TypeMatcher(); /// Matcher that successfully matches against any instance of [Link]. -const Matcher isLink = TypeMatcher(); +const isLink = TypeMatcher(); /// Matcher that successfully matches against any instance of /// [FileSystemEntity]. -const Matcher isFileSystemEntity = TypeMatcher(); +const isFileSystemEntity = TypeMatcher(); /// Matcher that successfully matches against any instance of [FileStat]. -const Matcher isFileStat = TypeMatcher(); +const isFileStat = TypeMatcher(); /// Returns a [Matcher] that matches [path] against an entity's path. /// /// [path] may be a String, a predicate function, or a [Matcher]. If it is /// a String, it will be wrapped in an equality matcher. -Matcher hasPath(dynamic path) => _HasPath(path); +TypeMatcher hasPath(dynamic path) => + isFileSystemEntity.having((e) => e.path, 'path', path); /// Returns a [Matcher] that successfully matches against an instance of /// [FileSystemException]. @@ -39,7 +42,8 @@ Matcher hasPath(dynamic path) => _HasPath(path); /// [osErrorCode] may be an `int`, a predicate function, or a [Matcher]. If it /// is an `int`, it will be wrapped in an equality matcher. Matcher isFileSystemException([dynamic osErrorCode]) => - _FileSystemException(osErrorCode); + const TypeMatcher().having((e) => e.osError?.errorCode, + 'osError.errorCode', _fileExceptionWrapMatcher(osErrorCode)); /// Returns a matcher that successfully matches against a future or function /// that throws a [FileSystemException]. @@ -67,89 +71,10 @@ void expectFileSystemException(dynamic osErrorCode, void Function() callback) { /// Matcher that successfully matches against a [FileSystemEntity] that /// exists ([FileSystemEntity.existsSync] returns true). -const Matcher exists = _Exists(); - -class _FileSystemException extends Matcher { - _FileSystemException(dynamic osErrorCode) - : _matcher = _wrapMatcher(osErrorCode); - - final Matcher? _matcher; - - static Matcher? _wrapMatcher(dynamic osErrorCode) { - if (osErrorCode == null) { - return null; - } - return ignoreOsErrorCodes ? anything : wrapMatcher(osErrorCode); - } - - @override - bool matches(dynamic item, Map matchState) { - if (item is FileSystemException) { - return _matcher == null || - _matcher!.matches(item.osError?.errorCode, matchState); - } - return false; - } - - @override - Description describe(Description desc) { - if (_matcher == null) { - return desc.add('FileSystemException'); - } else { - desc.add('FileSystemException with osError.errorCode: '); - return _matcher!.describe(desc); - } - } -} - -class _HasPath extends Matcher { - _HasPath(dynamic path) : _matcher = wrapMatcher(path); - - final Matcher _matcher; +final TypeMatcher exists = + isFileSystemEntity.having((e) => e.existsSync(), 'existsSync', true); - @override - bool matches(dynamic item, Map matchState) => - _matcher.matches(item.path, matchState); - - @override - Description describe(Description desc) { - desc.add('has path: '); - return _matcher.describe(desc); - } - - @override - Description describeMismatch( - dynamic item, - Description desc, - Map matchState, - bool verbose, - ) { - desc.add('has path: \'${item.path}\'').add('\n Which: '); - final Description pathDesc = StringDescription(); - _matcher.describeMismatch(item.path, pathDesc, matchState, verbose); - desc.add(pathDesc.toString()); - return desc; - } -} - -class _Exists extends Matcher { - const _Exists(); - - @override - bool matches(dynamic item, Map matchState) => - item is FileSystemEntity && item.existsSync(); - - @override - Description describe(Description description) => - description.add('a file system entity that exists'); - - @override - Description describeMismatch( - dynamic item, - Description description, - Map matchState, - bool verbose, - ) { - return description.add('does not exist'); - } -} +Matcher? _fileExceptionWrapMatcher(dynamic osErrorCode) => + (osErrorCode == null || ignoreOsErrorCodes) + ? anything + : wrapMatcher(osErrorCode); diff --git a/pkgs/file_testing/pubspec.yaml b/pkgs/file_testing/pubspec.yaml index 691efa0e6..895826a39 100644 --- a/pkgs/file_testing/pubspec.yaml +++ b/pkgs/file_testing/pubspec.yaml @@ -1,5 +1,5 @@ name: file_testing -version: 3.0.2 +version: 3.1.0-wip description: Testing utilities for package:file. repository: https://github.com/dart-lang/tools/tree/main/pkgs/file_testing issue_tracker: https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Afile_testing @@ -10,5 +10,5 @@ environment: dependencies: test: ^1.23.1 -dev_dependencies: - lints: ^5.0.0 +dev_dependencies: + dart_flutter_team_lints: ^3.0.0 diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index ae7711e57..b06ac72ea 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.10.14-wip + ## 0.10.13 * Require Dart 3.3 diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index 54ba7433f..9043c6326 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. /// Contains a builder object useful for creating source maps programatically. -library source_maps.builder; +library; // TODO(sigmund): add a builder for multi-section mappings. diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index b699ac728..590dfc682 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. /// Contains the top-level function to parse source maps version 3. -library source_maps.parser; +library; import 'dart:convert'; diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index 17733cdd3..32523d62f 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. /// Contains a code printer that generates code by recording the source maps. -library source_maps.printer; +library; import 'package:source_span/source_span.dart'; diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index 98e0c9345..a518a0ce4 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -6,7 +6,7 @@ /// /// [TextEditTransaction] supports making a series of changes to a text buffer. /// [guessIndent] helps to guess the appropriate indentiation for the new code. -library source_maps.refactor; +library; import 'package:source_span/source_span.dart'; diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart index 58f805a3a..244dee7a9 100644 --- a/pkgs/source_maps/lib/source_maps.dart +++ b/pkgs/source_maps/lib/source_maps.dart @@ -24,7 +24,7 @@ /// var mapping = parse(json); /// mapping.spanFor(outputSpan1.line, outputSpan1.column) /// ``` -library source_maps; +library; import 'package:source_span/source_span.dart'; diff --git a/pkgs/source_maps/lib/src/utils.dart b/pkgs/source_maps/lib/src/utils.dart index f70531e95..ba04fbb0f 100644 --- a/pkgs/source_maps/lib/src/utils.dart +++ b/pkgs/source_maps/lib/src/utils.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. /// Utilities that shouldn't be in this package. -library source_maps.utils; +library; /// Find the first entry in a sorted [list] that matches a monotonic predicate. /// Given a result `n`, that all items before `n` will not match, `n` matches, diff --git a/pkgs/source_maps/lib/src/vlq.dart b/pkgs/source_maps/lib/src/vlq.dart index 61b476839..3b0562d82 100644 --- a/pkgs/source_maps/lib/src/vlq.dart +++ b/pkgs/source_maps/lib/src/vlq.dart @@ -10,7 +10,7 @@ /// represented by using the least significant bit of the value as the sign bit. /// /// For more details see the source map [version 3 documentation](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?usp=sharing). -library source_maps.src.vlq; +library; import 'dart:math'; diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 8518fa756..32cbf4fb7 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.13 +version: 0.10.14-wip description: A library to programmatically manipulate source map files. repository: https://github.com/dart-lang/tools/tree/main/pkgs/source_maps @@ -10,6 +10,6 @@ dependencies: source_span: ^1.8.0 dev_dependencies: - dart_flutter_team_lints: ^2.0.0 + dart_flutter_team_lints: ^3.0.0 term_glyph: ^1.2.0 test: ^1.16.0 diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index f6139de47..e225ff5a4 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. /// Common input/output used by builder, parser and end2end tests -library test.common; +library; import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; diff --git a/pkgs/source_maps/test/utils_test.dart b/pkgs/source_maps/test/utils_test.dart index 4abdce298..2516d1e47 100644 --- a/pkgs/source_maps/test/utils_test.dart +++ b/pkgs/source_maps/test/utils_test.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. /// Tests for the binary search utility algorithm. -library test.utils_test; +library; import 'package:source_maps/src/utils.dart'; import 'package:test/test.dart'; diff --git a/pkgs/timing/.gitignore b/pkgs/timing/.gitignore new file mode 100644 index 000000000..1ddf798b7 --- /dev/null +++ b/pkgs/timing/.gitignore @@ -0,0 +1,7 @@ +.packages +/build/ +pubspec.lock + +# Files generated by dart tools +.dart_tool +doc/ diff --git a/pkgs/timing/CHANGELOG.md b/pkgs/timing/CHANGELOG.md new file mode 100644 index 000000000..8cdb8eadc --- /dev/null +++ b/pkgs/timing/CHANGELOG.md @@ -0,0 +1,34 @@ +## 1.0.2 + +- Require Dart `3.4`. +- Move to `dart-lang/tools` monorepo. + +## 1.0.1 + +- Require Dart `2.14`. + +## 1.0.0 + +- Enable null safety. +- Require Dart `2.12`. + +## 0.1.1+3 + +- Allow `package:json_annotation` `'>=1.0.0 <5.0.0'`. + +## 0.1.1+2 + +- Support the latest version of `package:json_annotation`. +- Require Dart 2.2 or later. + +## 0.1.1+1 + +- Support the latest version of `package:json_annotation`. + +## 0.1.1 + +- Add JSON serialization + +## 0.1.0 + +- Initial release diff --git a/pkgs/timing/LICENSE b/pkgs/timing/LICENSE new file mode 100644 index 000000000..9972f6e70 --- /dev/null +++ b/pkgs/timing/LICENSE @@ -0,0 +1,27 @@ +Copyright 2018, the Dart project authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkgs/timing/README.md b/pkgs/timing/README.md new file mode 100644 index 000000000..9dab7cc51 --- /dev/null +++ b/pkgs/timing/README.md @@ -0,0 +1,30 @@ +[![Build Status](https://github.com/dart-lang/tools/actions/workflows/timing.yaml/badge.svg)](https://github.com/dart-lang/tools/actions/workflows/timing.yaml) +[![pub package](https://img.shields.io/pub/v/timing.svg)](https://pub.dev/packages/timing) +[![package publisher](https://img.shields.io/pub/publisher/timing.svg)](https://pub.dev/packages/timing/publisher) + +Timing is a simple package for tracking performance of both async and sync actions + +## Usage + +```dart +var tracker = AsyncTimeTracker(); +await tracker.track(() async { + // some async code here +}); + +// Use results +print('${tracker.duration} ${tracker.innerDuration} ${tracker.slices}'); +``` + +## Building + +Use the following command to re-generate `lib/src/timing.g.dart` file: + +```bash +dart pub run build_runner build +``` + +## Publishing automation + +For information about our publishing automation and release process, see +https://github.com/dart-lang/ecosystem/wiki/Publishing-automation. diff --git a/pkgs/timing/analysis_options.yaml b/pkgs/timing/analysis_options.yaml new file mode 100644 index 000000000..396236d68 --- /dev/null +++ b/pkgs/timing/analysis_options.yaml @@ -0,0 +1,2 @@ +# https://dart.dev/tools/analysis#the-analysis-options-file +include: package:dart_flutter_team_lints/analysis_options.yaml diff --git a/pkgs/timing/lib/src/clock.dart b/pkgs/timing/lib/src/clock.dart new file mode 100644 index 000000000..6a9d29509 --- /dev/null +++ b/pkgs/timing/lib/src/clock.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; + +/// A function that returns the current [DateTime]. +typedef _Clock = DateTime Function(); +DateTime _defaultClock() => DateTime.now(); + +const _zoneKey = #timing_Clock; + +/// Returns the current [DateTime]. +/// +/// May be overridden for tests using [scopeClock]. +DateTime now() => (Zone.current[_zoneKey] as _Clock? ?? _defaultClock)(); + +/// Runs [f], with [clock] scoped whenever [now] is called. +T scopeClock(DateTime Function() clock, T Function() f) => + runZoned(f, zoneValues: {_zoneKey: clock}); diff --git a/pkgs/timing/lib/src/timing.dart b/pkgs/timing/lib/src/timing.dart new file mode 100644 index 000000000..049ba8189 --- /dev/null +++ b/pkgs/timing/lib/src/timing.dart @@ -0,0 +1,338 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; + +import 'package:json_annotation/json_annotation.dart'; + +import 'clock.dart'; + +part 'timing.g.dart'; + +/// The timings of an operation, including its [startTime], [stopTime], and +/// [duration]. +@JsonSerializable() +class TimeSlice { + /// The total duration of this operation, equivalent to taking the difference + /// between [stopTime] and [startTime]. + Duration get duration => stopTime.difference(startTime); + + final DateTime startTime; + + final DateTime stopTime; + + TimeSlice(this.startTime, this.stopTime); + + factory TimeSlice.fromJson(Map json) => + _$TimeSliceFromJson(json); + + Map toJson() => _$TimeSliceToJson(this); + + @override + String toString() => '($startTime + $duration)'; +} + +/// The timings of an async operation, consist of several sync [slices] and +/// includes total [startTime], [stopTime], and [duration]. +@JsonSerializable() +class TimeSliceGroup implements TimeSlice { + final List slices; + + @override + DateTime get startTime => slices.first.startTime; + + @override + DateTime get stopTime => slices.last.stopTime; + + /// The total duration of this operation, equivalent to taking the difference + /// between [stopTime] and [startTime]. + @override + Duration get duration => stopTime.difference(startTime); + + /// Sum of [duration]s of all [slices]. + /// + /// If some of slices implements [TimeSliceGroup] [innerDuration] will be used + /// to compute sum. + Duration get innerDuration => slices.fold( + Duration.zero, + (duration, slice) => + duration + + (slice is TimeSliceGroup ? slice.innerDuration : slice.duration)); + + TimeSliceGroup(this.slices); + + /// Constructs TimeSliceGroup from JSON representation + factory TimeSliceGroup.fromJson(Map json) => + _$TimeSliceGroupFromJson(json); + + @override + Map toJson() => _$TimeSliceGroupToJson(this); + + @override + String toString() => slices.toString(); +} + +abstract class TimeTracker implements TimeSlice { + /// Whether tracking is active. + /// + /// Tracking is only active after `isStarted` and before `isFinished`. + bool get isTracking; + + /// Whether tracking is finished. + /// + /// Tracker can't be used as [TimeSlice] before it is finished + bool get isFinished; + + /// Whether tracking was started. + /// + /// Equivalent of `isTracking || isFinished` + bool get isStarted; + + T track(T Function() action); +} + +/// Tracks only sync actions +class SyncTimeTracker implements TimeTracker { + /// When this operation started, call [_start] to set this. + @override + DateTime get startTime => _startTime!; + DateTime? _startTime; + + /// When this operation stopped, call [_stop] to set this. + @override + DateTime get stopTime => _stopTime!; + DateTime? _stopTime; + + /// Start tracking this operation, must only be called once, before [_stop]. + void _start() { + assert(_startTime == null && _stopTime == null); + _startTime = now(); + } + + /// Stop tracking this operation, must only be called once, after [_start]. + void _stop() { + assert(_startTime != null && _stopTime == null); + _stopTime = now(); + } + + /// Splits tracker into two slices. + /// + /// Returns new [TimeSlice] started on [startTime] and ended now. Modifies + /// [startTime] of tracker to current time point + /// + /// Don't change state of tracker. Can be called only while [isTracking], and + /// tracker will sill be tracking after call. + TimeSlice _split() { + if (!isTracking) { + throw StateError('Can be only called while tracking'); + } + final splitPoint = now(); + final prevSlice = TimeSlice(_startTime!, splitPoint); + _startTime = splitPoint; + return prevSlice; + } + + @override + T track(T Function() action) { + if (isStarted) { + throw StateError('Can not be tracked twice'); + } + _start(); + try { + return action(); + } finally { + _stop(); + } + } + + @override + bool get isStarted => _startTime != null; + + @override + bool get isTracking => _startTime != null && _stopTime == null; + + @override + bool get isFinished => _startTime != null && _stopTime != null; + + @override + Duration get duration => _stopTime!.difference(_startTime!); + + /// Converts to JSON representation + /// + /// Can't be used before [isFinished] + @override + Map toJson() => _$TimeSliceToJson(this); +} + +/// Async actions returning [Future] will be tracked as single sync time span +/// from the beginning of execution till completion of future +class SimpleAsyncTimeTracker extends SyncTimeTracker { + @override + T track(T Function() action) { + if (isStarted) { + throw StateError('Can not be tracked twice'); + } + T result; + _start(); + try { + result = action(); + } catch (_) { + _stop(); + rethrow; + } + if (result is Future) { + return result.whenComplete(_stop) as T; + } else { + _stop(); + return result; + } + } +} + +/// No-op implementation of [SyncTimeTracker] that does nothing. +class NoOpTimeTracker implements TimeTracker { + static final sharedInstance = NoOpTimeTracker(); + + @override + Duration get duration => + throw UnsupportedError('Unsupported in no-op implementation'); + + @override + DateTime get startTime => + throw UnsupportedError('Unsupported in no-op implementation'); + + @override + DateTime get stopTime => + throw UnsupportedError('Unsupported in no-op implementation'); + + @override + bool get isStarted => + throw UnsupportedError('Unsupported in no-op implementation'); + + @override + bool get isTracking => + throw UnsupportedError('Unsupported in no-op implementation'); + + @override + bool get isFinished => + throw UnsupportedError('Unsupported in no-op implementation'); + + @override + T track(T Function() action) => action(); + + @override + Map toJson() => + throw UnsupportedError('Unsupported in no-op implementation'); +} + +/// Track all async execution as disjoint time [slices] in ascending order. +/// +/// Can [track] both async and sync actions. +/// Can exclude time of tested trackers. +/// +/// If tracked action spawns some dangled async executions behavior is't +/// defined. Tracked might or might not track time of such executions +class AsyncTimeTracker extends TimeSliceGroup implements TimeTracker { + final bool trackNested; + + static const _zoneKey = #timing_AsyncTimeTracker; + + AsyncTimeTracker({this.trackNested = true}) : super([]); + + T _trackSyncSlice(ZoneDelegate parent, Zone zone, T Function() action) { + // Ignore dangling runs after tracker completes + if (isFinished) { + return action(); + } + + final isNestedRun = slices.isNotEmpty && + slices.last is SyncTimeTracker && + (slices.last as SyncTimeTracker).isTracking; + final isExcludedNestedTrack = !trackNested && zone[_zoneKey] != this; + + // Exclude nested sync tracks + if (isNestedRun && isExcludedNestedTrack) { + final timer = slices.last as SyncTimeTracker; + // Split already tracked time into new slice. + // Replace tracker in slices.last with splitted slice, to indicate for + // recursive calls that we not tracking. + slices.last = parent.run(zone, timer._split); + try { + return action(); + } finally { + // Split tracker again and discard slice from nested tracker + parent.run(zone, timer._split); + // Add tracker back to list of slices and continue tracking + slices.add(timer); + } + } + + // Exclude nested async tracks + if (isExcludedNestedTrack) { + return action(); + } + + // Split time slices in nested sync runs + if (isNestedRun) { + return action(); + } + + final timer = SyncTimeTracker(); + slices.add(timer); + + // Pass to parent zone, in case of overwritten clock + return parent.runUnary(zone, timer.track, action); + } + + static final asyncTimeTrackerZoneSpecification = ZoneSpecification( + run: (Zone self, ZoneDelegate parent, Zone zone, R Function() f) { + final tracker = self[_zoneKey] as AsyncTimeTracker; + return tracker._trackSyncSlice(parent, zone, () => parent.run(zone, f)); + }, + runUnary: (Zone self, ZoneDelegate parent, Zone zone, R Function(T) f, + T arg) { + final tracker = self[_zoneKey] as AsyncTimeTracker; + return tracker._trackSyncSlice( + parent, zone, () => parent.runUnary(zone, f, arg)); + }, + runBinary: (Zone self, ZoneDelegate parent, Zone zone, + R Function(T1, T2) f, T1 arg1, T2 arg2) { + final tracker = self[_zoneKey] as AsyncTimeTracker; + return tracker._trackSyncSlice( + parent, zone, () => parent.runBinary(zone, f, arg1, arg2)); + }, + ); + + @override + T track(T Function() action) { + if (isStarted) { + throw StateError('Can not be tracked twice'); + } + _tracking = true; + final result = runZoned(action, + zoneSpecification: asyncTimeTrackerZoneSpecification, + zoneValues: {_zoneKey: this}); + if (result is Future) { + return result + // Break possible sync processing of future completion, so slice + // trackers can be finished + .whenComplete(Future.value) + .whenComplete(() => _tracking = false) as T; + } else { + _tracking = false; + return result; + } + } + + bool? _tracking; + + @override + bool get isStarted => _tracking != null; + + @override + bool get isFinished => _tracking == false; + + @override + bool get isTracking => _tracking == true; +} diff --git a/pkgs/timing/lib/src/timing.g.dart b/pkgs/timing/lib/src/timing.g.dart new file mode 100644 index 000000000..679c082ff --- /dev/null +++ b/pkgs/timing/lib/src/timing.g.dart @@ -0,0 +1,29 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'timing.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +TimeSlice _$TimeSliceFromJson(Map json) => TimeSlice( + DateTime.parse(json['startTime'] as String), + DateTime.parse(json['stopTime'] as String), + ); + +Map _$TimeSliceToJson(TimeSlice instance) => { + 'startTime': instance.startTime.toIso8601String(), + 'stopTime': instance.stopTime.toIso8601String(), + }; + +TimeSliceGroup _$TimeSliceGroupFromJson(Map json) => + TimeSliceGroup( + (json['slices'] as List) + .map((e) => TimeSlice.fromJson(e as Map)) + .toList(), + ); + +Map _$TimeSliceGroupToJson(TimeSliceGroup instance) => + { + 'slices': instance.slices, + }; diff --git a/pkgs/timing/lib/timing.dart b/pkgs/timing/lib/timing.dart new file mode 100644 index 000000000..5cb16d423 --- /dev/null +++ b/pkgs/timing/lib/timing.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +export 'src/timing.dart' + show + AsyncTimeTracker, + NoOpTimeTracker, + SimpleAsyncTimeTracker, + SyncTimeTracker, + TimeSlice, + TimeSliceGroup, + TimeTracker; diff --git a/pkgs/timing/pubspec.yaml b/pkgs/timing/pubspec.yaml new file mode 100644 index 000000000..891a8af3d --- /dev/null +++ b/pkgs/timing/pubspec.yaml @@ -0,0 +1,18 @@ +name: timing +version: 1.0.2 +description: >- + A simple package for tracking the performance of synchronous and asynchronous + actions. +repository: https://github.com/dart-lang/tools/tree/main/pkgs/timing + +environment: + sdk: ^3.4.0 + +dependencies: + json_annotation: ^4.9.0 + +dev_dependencies: + build_runner: ^2.0.6 + dart_flutter_team_lints: ^3.0.0 + json_serializable: ^6.0.0 + test: ^1.17.10 diff --git a/pkgs/timing/test/timing_test.dart b/pkgs/timing/test/timing_test.dart new file mode 100644 index 000000000..b5836d9d2 --- /dev/null +++ b/pkgs/timing/test/timing_test.dart @@ -0,0 +1,416 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// ignore_for_file: only_throw_errors, inference_failure_on_instance_creation + +import 'dart:async'; + +import 'package:test/test.dart'; +import 'package:timing/src/clock.dart'; +import 'package:timing/src/timing.dart'; + +void _noop() {} + +void main() { + late DateTime time; + final startTime = DateTime(2017); + DateTime fakeClock() => time; + + late TimeTracker tracker; + late TimeTracker nestedTracker; + + T scopedTrack(T Function() f) => + scopeClock(fakeClock, () => tracker.track(f)); + + setUp(() { + time = startTime; + }); + + void canHandleSync([void Function() additionalExpects = _noop]) { + test('Can track sync code', () { + expect(tracker.isStarted, false); + expect(tracker.isTracking, false); + expect(tracker.isFinished, false); + scopedTrack(() { + expect(tracker.isStarted, true); + expect(tracker.isTracking, true); + expect(tracker.isFinished, false); + time = time.add(const Duration(seconds: 5)); + }); + expect(tracker.isStarted, true); + expect(tracker.isTracking, false); + expect(tracker.isFinished, true); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, time); + expect(tracker.duration, const Duration(seconds: 5)); + additionalExpects(); + }); + + test('Can track handled sync exceptions', () async { + scopedTrack(() { + try { + time = time.add(const Duration(seconds: 4)); + throw 'error'; + } on String { + time = time.add(const Duration(seconds: 1)); + } + }); + expect(tracker.isFinished, true); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, time); + expect(tracker.duration, const Duration(seconds: 5)); + additionalExpects(); + }); + + test('Can track in case of unhandled sync exceptions', () async { + expect( + () => scopedTrack(() { + time = time.add(const Duration(seconds: 5)); + throw 'error'; + }), + throwsA(const TypeMatcher())); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, time); + expect(tracker.duration, const Duration(seconds: 5)); + additionalExpects(); + }); + + test('Can be nested sync', () { + scopedTrack(() { + time = time.add(const Duration(seconds: 1)); + nestedTracker.track(() { + time = time.add(const Duration(seconds: 2)); + }); + time = time.add(const Duration(seconds: 4)); + }); + expect(tracker.isFinished, true); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, time); + expect(tracker.duration, const Duration(seconds: 7)); + expect(nestedTracker.startTime.isAfter(startTime), true); + expect(nestedTracker.stopTime.isBefore(time), true); + expect(nestedTracker.duration, const Duration(seconds: 2)); + additionalExpects(); + }); + } + + void canHandleAsync([void Function() additionalExpects = _noop]) { + test('Can track async code', () async { + expect(tracker.isStarted, false); + expect(tracker.isTracking, false); + expect(tracker.isFinished, false); + await scopedTrack(() => Future(() { + expect(tracker.isStarted, true); + expect(tracker.isTracking, true); + expect(tracker.isFinished, false); + time = time.add(const Duration(seconds: 5)); + })); + expect(tracker.isStarted, true); + expect(tracker.isTracking, false); + expect(tracker.isFinished, true); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, time); + expect(tracker.duration, const Duration(seconds: 5)); + additionalExpects(); + }); + + test('Can track handled async exceptions', () async { + await scopedTrack(() { + time = time.add(const Duration(seconds: 1)); + return Future(() { + time = time.add(const Duration(seconds: 2)); + throw 'error'; + }).then((_) { + time = time.add(const Duration(seconds: 4)); + }).catchError((error, stack) { + time = time.add(const Duration(seconds: 8)); + }); + }); + expect(tracker.isFinished, true); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, time); + expect(tracker.duration, const Duration(seconds: 11)); + additionalExpects(); + }); + + test('Can track in case of unhandled async exceptions', () async { + final future = scopedTrack(() { + time = time.add(const Duration(seconds: 1)); + return Future(() { + time = time.add(const Duration(seconds: 2)); + throw 'error'; + }).then((_) { + time = time.add(const Duration(seconds: 4)); + }); + }); + await expectLater(future, throwsA(const TypeMatcher())); + expect(tracker.isFinished, true); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, time); + expect(tracker.duration, const Duration(seconds: 3)); + additionalExpects(); + }); + + test('Can be nested async', () async { + await scopedTrack(() async { + time = time.add(const Duration(milliseconds: 1)); + await Future.value(); + time = time.add(const Duration(milliseconds: 2)); + await nestedTracker.track(() async { + time = time.add(const Duration(milliseconds: 4)); + await Future.value(); + time = time.add(const Duration(milliseconds: 8)); + await Future.value(); + time = time.add(const Duration(milliseconds: 16)); + }); + time = time.add(const Duration(milliseconds: 32)); + await Future.value(); + time = time.add(const Duration(milliseconds: 64)); + }); + expect(tracker.isFinished, true); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, time); + expect(tracker.duration, const Duration(milliseconds: 127)); + expect(nestedTracker.startTime.isAfter(startTime), true); + expect(nestedTracker.stopTime.isBefore(time), true); + expect(nestedTracker.duration, const Duration(milliseconds: 28)); + additionalExpects(); + }); + } + + group('SyncTimeTracker', () { + setUp(() { + tracker = SyncTimeTracker(); + nestedTracker = SyncTimeTracker(); + }); + + canHandleSync(); + + test('Can not track async code', () async { + await scopedTrack(() => Future(() { + time = time.add(const Duration(seconds: 5)); + })); + expect(tracker.isFinished, true); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, startTime); + expect(tracker.duration, const Duration(seconds: 0)); + }); + }); + + group('AsyncTimeTracker.simple', () { + setUp(() { + tracker = SimpleAsyncTimeTracker(); + nestedTracker = SimpleAsyncTimeTracker(); + }); + + canHandleSync(); + + canHandleAsync(); + + test('Can not distinguish own async code', () async { + final future = scopedTrack(() => Future(() { + time = time.add(const Duration(seconds: 5)); + })); + time = time.add(const Duration(seconds: 10)); + await future; + expect(tracker.isFinished, true); + expect(tracker.startTime, startTime); + expect(tracker.stopTime, time); + expect(tracker.duration, const Duration(seconds: 15)); + }); + }); + + group('AsyncTimeTracker', () { + late AsyncTimeTracker asyncTracker; + late AsyncTimeTracker nestedAsyncTracker; + setUp(() { + tracker = asyncTracker = AsyncTimeTracker(); + nestedTracker = nestedAsyncTracker = AsyncTimeTracker(); + }); + + canHandleSync(() { + expect(asyncTracker.innerDuration, asyncTracker.duration); + expect(asyncTracker.slices.length, 1); + }); + + canHandleAsync(() { + expect(asyncTracker.innerDuration, asyncTracker.duration); + expect(asyncTracker.slices.length, greaterThan(1)); + }); + + test('Can track complex async innerDuration', () async { + final completer = Completer(); + final future = scopedTrack(() async { + time = time.add(const Duration(seconds: 1)); // Tracked sync + await Future.value(); + time = time.add(const Duration(seconds: 2)); // Tracked async + await completer.future; + time = time.add(const Duration(seconds: 4)); // Tracked async, delayed + }).then((_) { + time = time.add(const Duration(seconds: 8)); // Async, after tracking + }); + time = time.add(const Duration(seconds: 16)); // Sync, between slices + + await Future(() { + // Async, between slices + time = time.add(const Duration(seconds: 32)); + completer.complete(); + }); + await future; + expect(asyncTracker.isFinished, true); + expect(asyncTracker.startTime, startTime); + expect(asyncTracker.stopTime.isBefore(time), true); + expect(asyncTracker.duration, const Duration(seconds: 55)); + expect(asyncTracker.innerDuration, const Duration(seconds: 7)); + expect(asyncTracker.slices.length, greaterThan(1)); + }); + + test('Can exclude nested sync', () { + tracker = asyncTracker = AsyncTimeTracker(trackNested: false); + scopedTrack(() { + time = time.add(const Duration(seconds: 1)); + nestedAsyncTracker.track(() { + time = time.add(const Duration(seconds: 2)); + }); + time = time.add(const Duration(seconds: 4)); + }); + expect(asyncTracker.isFinished, true); + expect(asyncTracker.startTime, startTime); + expect(asyncTracker.stopTime, time); + expect(asyncTracker.duration, const Duration(seconds: 7)); + expect(asyncTracker.innerDuration, const Duration(seconds: 5)); + expect(asyncTracker.slices.length, greaterThan(1)); + expect(nestedAsyncTracker.startTime.isAfter(startTime), true); + expect(nestedAsyncTracker.stopTime.isBefore(time), true); + expect(nestedAsyncTracker.duration, const Duration(seconds: 2)); + expect(nestedAsyncTracker.innerDuration, const Duration(seconds: 2)); + expect(nestedAsyncTracker.slices.length, 1); + }); + + test('Can exclude complex nested sync', () { + tracker = asyncTracker = AsyncTimeTracker(trackNested: false); + nestedAsyncTracker = AsyncTimeTracker(trackNested: false); + final nestedAsyncTracker2 = AsyncTimeTracker(trackNested: false); + scopedTrack(() { + time = time.add(const Duration(seconds: 1)); + nestedAsyncTracker.track(() { + time = time.add(const Duration(seconds: 2)); + nestedAsyncTracker2.track(() { + time = time.add(const Duration(seconds: 4)); + }); + time = time.add(const Duration(seconds: 8)); + }); + time = time.add(const Duration(seconds: 16)); + }); + expect(asyncTracker.isFinished, true); + expect(asyncTracker.startTime, startTime); + expect(asyncTracker.stopTime, time); + expect(asyncTracker.duration, const Duration(seconds: 31)); + expect(asyncTracker.innerDuration, const Duration(seconds: 17)); + expect(asyncTracker.slices.length, greaterThan(1)); + expect(nestedAsyncTracker.startTime.isAfter(startTime), true); + expect(nestedAsyncTracker.stopTime.isBefore(time), true); + expect(nestedAsyncTracker.duration, const Duration(seconds: 14)); + expect(nestedAsyncTracker.innerDuration, const Duration(seconds: 10)); + expect(nestedAsyncTracker.slices.length, greaterThan(1)); + expect(nestedAsyncTracker2.startTime.isAfter(startTime), true); + expect(nestedAsyncTracker2.stopTime.isBefore(time), true); + expect(nestedAsyncTracker2.duration, const Duration(seconds: 4)); + expect(nestedAsyncTracker2.innerDuration, const Duration(seconds: 4)); + expect(nestedAsyncTracker2.slices.length, 1); + }); + + test( + 'Can track all on grand-parent level and ' + 'exclude grand-childrens from parent', () { + tracker = asyncTracker = AsyncTimeTracker(trackNested: true); + nestedAsyncTracker = AsyncTimeTracker(trackNested: false); + final nestedAsyncTracker2 = AsyncTimeTracker(); + scopedTrack(() { + time = time.add(const Duration(seconds: 1)); + nestedAsyncTracker.track(() { + time = time.add(const Duration(seconds: 2)); + nestedAsyncTracker2.track(() { + time = time.add(const Duration(seconds: 4)); + }); + time = time.add(const Duration(seconds: 8)); + }); + time = time.add(const Duration(seconds: 16)); + }); + expect(asyncTracker.isFinished, true); + expect(asyncTracker.startTime, startTime); + expect(asyncTracker.stopTime, time); + expect(asyncTracker.duration, const Duration(seconds: 31)); + expect(asyncTracker.innerDuration, const Duration(seconds: 31)); + expect(asyncTracker.slices.length, 1); + expect(nestedAsyncTracker.startTime.isAfter(startTime), true); + expect(nestedAsyncTracker.stopTime.isBefore(time), true); + expect(nestedAsyncTracker.duration, const Duration(seconds: 14)); + expect(nestedAsyncTracker.innerDuration, const Duration(seconds: 10)); + expect(nestedAsyncTracker.slices.length, greaterThan(1)); + expect(nestedAsyncTracker2.startTime.isAfter(startTime), true); + expect(nestedAsyncTracker2.stopTime.isBefore(time), true); + expect(nestedAsyncTracker2.duration, const Duration(seconds: 4)); + expect(nestedAsyncTracker2.innerDuration, const Duration(seconds: 4)); + expect(nestedAsyncTracker2.slices.length, 1); + }); + + test('Can exclude nested async', () async { + tracker = asyncTracker = AsyncTimeTracker(trackNested: false); + await scopedTrack(() async { + time = time.add(const Duration(seconds: 1)); + await nestedAsyncTracker.track(() async { + time = time.add(const Duration(seconds: 2)); + await Future.value(); + time = time.add(const Duration(seconds: 4)); + await Future.value(); + time = time.add(const Duration(seconds: 8)); + }); + time = time.add(const Duration(seconds: 16)); + }); + expect(asyncTracker.isFinished, true); + expect(asyncTracker.startTime, startTime); + expect(asyncTracker.stopTime, time); + expect(asyncTracker.duration, const Duration(seconds: 31)); + expect(asyncTracker.innerDuration, const Duration(seconds: 17)); + expect(asyncTracker.slices.length, greaterThan(1)); + expect(nestedAsyncTracker.startTime.isAfter(startTime), true); + expect(nestedAsyncTracker.stopTime.isBefore(time), true); + expect(nestedAsyncTracker.duration, const Duration(seconds: 14)); + expect(nestedAsyncTracker.innerDuration, const Duration(seconds: 14)); + expect(nestedAsyncTracker.slices.length, greaterThan(1)); + }); + + test('Can handle callbacks in excluded nested async', () async { + tracker = asyncTracker = AsyncTimeTracker(trackNested: false); + await scopedTrack(() async { + time = time.add(const Duration(seconds: 1)); + final completer = Completer(); + final future = completer.future.then((_) { + time = time.add(const Duration(seconds: 2)); + }); + await nestedAsyncTracker.track(() async { + time = time.add(const Duration(seconds: 4)); + await Future.value(); + time = time.add(const Duration(seconds: 8)); + completer.complete(); + await future; + time = time.add(const Duration(seconds: 16)); + }); + time = time.add(const Duration(seconds: 32)); + }); + expect(asyncTracker.isFinished, true); + expect(asyncTracker.startTime, startTime); + expect(asyncTracker.stopTime, time); + expect(asyncTracker.duration, const Duration(seconds: 63)); + expect(asyncTracker.innerDuration, const Duration(seconds: 35)); + expect(asyncTracker.slices.length, greaterThan(1)); + expect(nestedAsyncTracker.startTime.isAfter(startTime), true); + expect(nestedAsyncTracker.stopTime.isBefore(time), true); + expect(nestedAsyncTracker.duration, const Duration(seconds: 30)); + expect(nestedAsyncTracker.innerDuration, const Duration(seconds: 28)); + expect(nestedAsyncTracker.slices.length, greaterThan(1)); + }); + }); +}