Merge branch 'main' into merge-term_glyph-package
diff --git a/.github/ISSUE_TEMPLATE/test_reflective_loader.md b/.github/ISSUE_TEMPLATE/test_reflective_loader.md
new file mode 100644
index 0000000..bde03fe
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/test_reflective_loader.md
@@ -0,0 +1,5 @@
+---
+name: "package:test_reflective_loader"
+about: "Create a bug or file a feature request against package:test_reflective_loader."
+labels: "package:test_reflective_loader"
+---
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/timing.md b/.github/ISSUE_TEMPLATE/timing.md
new file mode 100644
index 0000000..38a0015
--- /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 4c93a39..87232f5 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -112,6 +112,14 @@
- changed-files:
- any-glob-to-any-file: 'pkgs/term_glyph/**'
+'package:test_reflective_loader':
+ - 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/bazel_worker.yaml b/.github/workflows/bazel_worker.yaml
index 0eb06da..b448219 100644
--- a/.github/workflows/bazel_worker.yaml
+++ b/.github/workflows/bazel_worker.yaml
@@ -36,6 +36,8 @@
- uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94
with:
sdk: ${{ matrix.sdk }}
+ - run: dart pub get
- run: "dart format --output=none --set-exit-if-changed ."
+ if: ${{ matrix.sdk == 'dev' }}
- name: Test
run: ./tool/travis.sh
diff --git a/.github/workflows/test_reflective_loader.yaml b/.github/workflows/test_reflective_loader.yaml
new file mode 100644
index 0000000..975c970
--- /dev/null
+++ b/.github/workflows/test_reflective_loader.yaml
@@ -0,0 +1,43 @@
+name: package:test_reflective_loader
+
+on:
+ # Run on PRs and pushes to the default branch.
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/test_reflective_loader.yaml'
+ - 'pkgs/test_reflective_loader/**'
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/test_reflective_loader.yaml'
+ - 'pkgs/test_reflective_loader/**'
+ schedule:
+ - cron: "0 0 * * 0"
+
+env:
+ PUB_ENVIRONMENT: bot.github
+
+defaults:
+ run:
+ working-directory: pkgs/test_reflective_loader/
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ sdk: [dev, 3.1]
+
+ steps:
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94
+ with:
+ sdk: ${{ matrix.sdk }}
+
+ - run: dart pub get
+ - name: dart format
+ run: dart format --output=none --set-exit-if-changed .
+ - run: dart analyze --fatal-infos
+ - run: dart test
diff --git a/.github/workflows/timing.yaml b/.github/workflows/timing.yaml
new file mode 100644
index 0000000..df77b13
--- /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 fc9fa4b..ddf2b52 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,8 @@
| [source_span](pkgs/source_span/) | Provides a standard representation for source code locations and spans. | [](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_span) | [](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. | [](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asse) | [](https://pub.dev/packages/sse) |
| [term_glyph](pkgs/term_glyph/) | Useful Unicode glyphs and ASCII substitutes. | [](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aterm_glyph) | [](https://pub.dev/packages/term_glyph) |
+| [test_reflective_loader](pkgs/test_reflective_loader/) | Support for discovering tests and test suites using reflection. | [](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Atest_reflective_loader) | [](https://pub.dev/packages/test_reflective_loader) |
+| [timing](pkgs/timing/) | A simple package for tracking the performance of synchronous and asynchronous actions. | [](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Atiming) | [](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. | [](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics) | [](https://pub.dev/packages/unified_analytics) |
## Publishing automation
diff --git a/pkgs/bazel_worker/benchmark/benchmark.dart b/pkgs/bazel_worker/benchmark/benchmark.dart
index 035e2b8..0a03122 100644
--- a/pkgs/bazel_worker/benchmark/benchmark.dart
+++ b/pkgs/bazel_worker/benchmark/benchmark.dart
@@ -12,10 +12,7 @@
var path = 'blaze-bin/some/path/to/a/file/that/is/an/input/$i';
workRequest
..arguments.add('--input=$path')
- ..inputs.add(Input(
- path: '',
- digest: List.filled(70, 0x11),
- ));
+ ..inputs.add(Input(path: '', digest: List.filled(70, 0x11)));
}
// Serialize it.
@@ -24,14 +21,20 @@
print('Request has $length requestBytes.');
// Add the length in front base 128 encoded as in the worker protocol.
- requestBytes =
- Uint8List.fromList(requestBytes.toList()..insertAll(0, _varInt(length)));
+ requestBytes = Uint8List.fromList(
+ requestBytes.toList()..insertAll(0, _varInt(length)),
+ );
// Split into 10000 byte chunks.
var lists = <Uint8List>[];
for (var i = 0; i < requestBytes.length; i += 10000) {
- lists.add(Uint8List.sublistView(
- requestBytes, i, min(i + 10000, requestBytes.length)));
+ lists.add(
+ Uint8List.sublistView(
+ requestBytes,
+ i,
+ min(i + 10000, requestBytes.length),
+ ),
+ );
}
// Time `AsyncMessageGrouper` and deserialization.
diff --git a/pkgs/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart b/pkgs/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart
index a94875d..285b03d 100644
--- a/pkgs/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart
+++ b/pkgs/bazel_worker/e2e_test/bin/async_worker_in_isolate.dart
@@ -17,7 +17,10 @@
Future main(List<String> args, [SendPort? message]) async {
var receivePort = ReceivePort();
await Isolate.spawnUri(
- Uri.file('async_worker.dart'), [], receivePort.sendPort);
+ Uri.file('async_worker.dart'),
+ [],
+ receivePort.sendPort,
+ );
var worker = await ForwardsToIsolateAsyncWorker.create(receivePort);
await worker.run();
diff --git a/pkgs/bazel_worker/e2e_test/lib/async_worker.dart b/pkgs/bazel_worker/e2e_test/lib/async_worker.dart
index d48d87c..55f5171 100644
--- a/pkgs/bazel_worker/e2e_test/lib/async_worker.dart
+++ b/pkgs/bazel_worker/e2e_test/lib/async_worker.dart
@@ -16,9 +16,6 @@
@override
Future<WorkResponse> performRequest(WorkRequest request) async {
- return WorkResponse(
- exitCode: 0,
- output: request.arguments.join('\n'),
- );
+ return WorkResponse(exitCode: 0, output: request.arguments.join('\n'));
}
}
diff --git a/pkgs/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart b/pkgs/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart
index bb937b2..a4845cf 100644
--- a/pkgs/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart
+++ b/pkgs/bazel_worker/e2e_test/lib/forwards_to_isolate_async_worker.dart
@@ -13,9 +13,11 @@
final IsolateDriverConnection _isolateDriverConnection;
static Future<ForwardsToIsolateAsyncWorker> create(
- ReceivePort receivePort) async {
+ ReceivePort receivePort,
+ ) async {
return ForwardsToIsolateAsyncWorker(
- await IsolateDriverConnection.create(receivePort));
+ await IsolateDriverConnection.create(receivePort),
+ );
}
ForwardsToIsolateAsyncWorker(this._isolateDriverConnection);
diff --git a/pkgs/bazel_worker/e2e_test/pubspec.yaml b/pkgs/bazel_worker/e2e_test/pubspec.yaml
index 56f00cd..7eaa89a 100644
--- a/pkgs/bazel_worker/e2e_test/pubspec.yaml
+++ b/pkgs/bazel_worker/e2e_test/pubspec.yaml
@@ -10,6 +10,6 @@
dev_dependencies:
cli_util: ^0.4.2
- dart_flutter_team_lints: ^1.0.0
+ dart_flutter_team_lints: ^3.0.0
path: ^1.8.0
test: ^1.16.0
diff --git a/pkgs/bazel_worker/e2e_test/test/e2e_test.dart b/pkgs/bazel_worker/e2e_test/test/e2e_test.dart
index caa813a..6b79b5e 100644
--- a/pkgs/bazel_worker/e2e_test/test/e2e_test.dart
+++ b/pkgs/bazel_worker/e2e_test/test/e2e_test.dart
@@ -12,14 +12,18 @@
void main() {
var dart = p.join(sdkPath, 'bin', 'dart');
- runE2eTestForWorker('sync worker',
- () => Process.start(dart, [p.join('bin', 'sync_worker.dart')]));
- runE2eTestForWorker('async worker',
- () => Process.start(dart, [p.join('bin', 'async_worker.dart')]));
runE2eTestForWorker(
- 'async worker in isolate',
- () =>
- Process.start(dart, [p.join('bin', 'async_worker_in_isolate.dart')]));
+ 'sync worker',
+ () => Process.start(dart, [p.join('bin', 'sync_worker.dart')]),
+ );
+ runE2eTestForWorker(
+ 'async worker',
+ () => Process.start(dart, [p.join('bin', 'async_worker.dart')]),
+ );
+ runE2eTestForWorker(
+ 'async worker in isolate',
+ () => Process.start(dart, [p.join('bin', 'async_worker_in_isolate.dart')]),
+ );
}
void runE2eTestForWorker(String groupName, SpawnWorker spawnWorker) {
diff --git a/pkgs/bazel_worker/example/client.dart b/pkgs/bazel_worker/example/client.dart
index 7147fcb..326bb18 100644
--- a/pkgs/bazel_worker/example/client.dart
+++ b/pkgs/bazel_worker/example/client.dart
@@ -5,10 +5,14 @@
void main() async {
var scratchSpace = await Directory.systemTemp.createTemp();
var driver = BazelWorkerDriver(
- () => Process.start(Platform.resolvedExecutable,
- [Platform.script.resolve('worker.dart').toFilePath()],
- workingDirectory: scratchSpace.path),
- maxWorkers: 4);
+ () => Process.start(
+ Platform.resolvedExecutable,
+ [
+ Platform.script.resolve('worker.dart').toFilePath(),
+ ],
+ workingDirectory: scratchSpace.path),
+ maxWorkers: 4,
+ );
var response = await driver.doWork(WorkRequest(arguments: ['foo']));
if (response.exitCode != EXIT_CODE_OK) {
print('Worker request failed');
diff --git a/pkgs/bazel_worker/lib/src/async_message_grouper.dart b/pkgs/bazel_worker/lib/src/async_message_grouper.dart
index e1f0dea..8fc4778 100644
--- a/pkgs/bazel_worker/lib/src/async_message_grouper.dart
+++ b/pkgs/bazel_worker/lib/src/async_message_grouper.dart
@@ -86,13 +86,18 @@
// Copy as much as possible from the input buffer. Limit is the
// smaller of the remaining length to fill in the message and the
// remaining length in the buffer.
- var lengthToCopy = min(_message.length - _messagePos,
- _inputBuffer.length - _inputBufferPos);
+ var lengthToCopy = min(
+ _message.length - _messagePos,
+ _inputBuffer.length - _inputBufferPos,
+ );
_message.setRange(
- _messagePos,
- _messagePos + lengthToCopy,
- _inputBuffer.sublist(
- _inputBufferPos, _inputBufferPos + lengthToCopy));
+ _messagePos,
+ _messagePos + lengthToCopy,
+ _inputBuffer.sublist(
+ _inputBufferPos,
+ _inputBufferPos + lengthToCopy,
+ ),
+ );
_messagePos += lengthToCopy;
_inputBufferPos += lengthToCopy;
diff --git a/pkgs/bazel_worker/lib/src/driver/driver.dart b/pkgs/bazel_worker/lib/src/driver/driver.dart
index 4a78020..06cf0fe 100644
--- a/pkgs/bazel_worker/lib/src/driver/driver.dart
+++ b/pkgs/bazel_worker/lib/src/driver/driver.dart
@@ -44,9 +44,12 @@
/// Factory method that spawns a worker process.
final SpawnWorker _spawnWorker;
- BazelWorkerDriver(this._spawnWorker,
- {int? maxIdleWorkers, int? maxWorkers, int? maxRetries})
- : _maxIdleWorkers = maxIdleWorkers ?? 4,
+ BazelWorkerDriver(
+ this._spawnWorker, {
+ int? maxIdleWorkers,
+ int? maxWorkers,
+ int? maxRetries,
+ }) : _maxIdleWorkers = maxIdleWorkers ?? 4,
_maxWorkers = maxWorkers ?? 4,
_maxRetries = maxRetries ?? 4;
@@ -56,8 +59,10 @@
/// [request] has been actually sent to the worker. This allows the caller
/// to determine when actual work is being done versus just waiting for an
/// available worker.
- Future<WorkResponse> doWork(WorkRequest request,
- {void Function(Future<WorkResponse?>)? trackWork}) {
+ Future<WorkResponse> doWork(
+ WorkRequest request, {
+ void Function(Future<WorkResponse?>)? trackWork,
+ }) {
var attempt = _WorkAttempt(request, trackWork: trackWork);
_workQueue.add(attempt);
_runWorkQueue();
@@ -69,9 +74,11 @@
for (var worker in _readyWorkers.toList()) {
_killWorker(worker);
}
- await Future.wait(_spawningWorkers.map((worker) async {
- _killWorker(await worker);
- }));
+ await Future.wait(
+ _spawningWorkers.map((worker) async {
+ _killWorker(await worker);
+ }),
+ );
}
/// Runs as many items in [_workQueue] as possible given the number of
@@ -88,8 +95,10 @@
if (_workQueue.isEmpty) return;
if (_numWorkers == _maxWorkers && _idleWorkers.isEmpty) return;
if (_numWorkers > _maxWorkers) {
- throw StateError('Internal error, created to many workers. Please '
- 'file a bug at https://github.com/dart-lang/bazel_worker/issues/new');
+ throw StateError(
+ 'Internal error, created to many workers. Please '
+ 'file a bug at https://github.com/dart-lang/bazel_worker/issues/new',
+ );
}
// At this point we definitely want to run a task, we just need to decide
@@ -137,48 +146,51 @@
void _runWorker(Process worker, _WorkAttempt attempt) {
var rescheduled = false;
- runZonedGuarded(() async {
- var connection = _workerConnections[worker]!;
+ runZonedGuarded(
+ () async {
+ var connection = _workerConnections[worker]!;
- connection.writeRequest(attempt.request);
- var responseFuture = connection.readResponse();
- if (attempt.trackWork != null) {
- attempt.trackWork!(responseFuture);
- }
- var response = await responseFuture;
+ connection.writeRequest(attempt.request);
+ var responseFuture = connection.readResponse();
+ if (attempt.trackWork != null) {
+ attempt.trackWork!(responseFuture);
+ }
+ var response = await responseFuture;
- // It is possible for us to complete with an error response due to an
- // unhandled async error before we get here.
- if (!attempt.responseCompleter.isCompleted) {
- if (response.exitCode == EXIT_CODE_BROKEN_PIPE) {
+ // It is possible for us to complete with an error response due to an
+ // unhandled async error before we get here.
+ if (!attempt.responseCompleter.isCompleted) {
+ if (response.exitCode == EXIT_CODE_BROKEN_PIPE) {
+ rescheduled = _tryReschedule(attempt);
+ if (rescheduled) return;
+ stderr.writeln('Failed to run request ${attempt.request}');
+ response = WorkResponse(
+ exitCode: EXIT_CODE_ERROR,
+ output:
+ 'Invalid response from worker, this probably means it wrote '
+ 'invalid output or died.',
+ );
+ }
+ attempt.responseCompleter.complete(response);
+ _cleanUp(worker);
+ }
+ },
+ (e, s) {
+ // Note that we don't need to do additional cleanup here on failures. If
+ // the worker dies that is already handled in a generic fashion, we just
+ // need to make sure we complete with a valid response.
+ if (!attempt.responseCompleter.isCompleted) {
rescheduled = _tryReschedule(attempt);
if (rescheduled) return;
- stderr.writeln('Failed to run request ${attempt.request}');
- response = WorkResponse(
+ var response = WorkResponse(
exitCode: EXIT_CODE_ERROR,
- output:
- 'Invalid response from worker, this probably means it wrote '
- 'invalid output or died.',
+ output: 'Error running worker:\n$e\n$s',
);
+ attempt.responseCompleter.complete(response);
+ _cleanUp(worker);
}
- attempt.responseCompleter.complete(response);
- _cleanUp(worker);
- }
- }, (e, s) {
- // Note that we don't need to do additional cleanup here on failures. If
- // the worker dies that is already handled in a generic fashion, we just
- // need to make sure we complete with a valid response.
- if (!attempt.responseCompleter.isCompleted) {
- rescheduled = _tryReschedule(attempt);
- if (rescheduled) return;
- var response = WorkResponse(
- exitCode: EXIT_CODE_ERROR,
- output: 'Error running worker:\n$e\n$s',
- );
- attempt.responseCompleter.complete(response);
- _cleanUp(worker);
- }
- });
+ },
+ );
}
/// Performs post-work cleanup for [worker].
diff --git a/pkgs/bazel_worker/lib/src/driver/driver_connection.dart b/pkgs/bazel_worker/lib/src/driver/driver_connection.dart
index b419deb..80d5c98 100644
--- a/pkgs/bazel_worker/lib/src/driver/driver_connection.dart
+++ b/pkgs/bazel_worker/lib/src/driver/driver_connection.dart
@@ -34,13 +34,16 @@
Future<void> get done => _messageGrouper.done;
- StdDriverConnection(
- {Stream<List<int>>? inputStream, StreamSink<List<int>>? outputStream})
- : _messageGrouper = AsyncMessageGrouper(inputStream ?? stdin),
+ StdDriverConnection({
+ Stream<List<int>>? inputStream,
+ StreamSink<List<int>>? outputStream,
+ }) : _messageGrouper = AsyncMessageGrouper(inputStream ?? stdin),
_outputStream = outputStream ?? stdout;
factory StdDriverConnection.forWorker(Process worker) => StdDriverConnection(
- inputStream: worker.stdout, outputStream: worker.stdin);
+ inputStream: worker.stdout,
+ outputStream: worker.stdin,
+ );
/// Note: This will attempts to recover from invalid proto messages by parsing
/// them as strings. This is a common error case for workers (they print a
diff --git a/pkgs/bazel_worker/lib/src/utils.dart b/pkgs/bazel_worker/lib/src/utils.dart
index 609b435..f67bbac 100644
--- a/pkgs/bazel_worker/lib/src/utils.dart
+++ b/pkgs/bazel_worker/lib/src/utils.dart
@@ -13,8 +13,9 @@
var delimiterBuffer = CodedBufferWriter();
delimiterBuffer.writeInt32NoTag(messageBuffer.lengthInBytes);
- var result =
- Uint8List(messageBuffer.lengthInBytes + delimiterBuffer.lengthInBytes);
+ var result = Uint8List(
+ messageBuffer.lengthInBytes + delimiterBuffer.lengthInBytes,
+ );
delimiterBuffer.writeTo(result);
messageBuffer.writeTo(result, delimiterBuffer.lengthInBytes);
diff --git a/pkgs/bazel_worker/lib/src/worker/async_worker_loop.dart b/pkgs/bazel_worker/lib/src/worker/async_worker_loop.dart
index 5182b55..a95d09a 100644
--- a/pkgs/bazel_worker/lib/src/worker/async_worker_loop.dart
+++ b/pkgs/bazel_worker/lib/src/worker/async_worker_loop.dart
@@ -32,20 +32,20 @@
var request = await connection.readRequest();
if (request == null) break;
var printMessages = StringBuffer();
- response = await runZoned(() => performRequest(request),
- zoneSpecification:
- ZoneSpecification(print: (self, parent, zone, message) {
- printMessages.writeln();
- printMessages.write(message);
- }));
+ response = await runZoned(
+ () => performRequest(request),
+ zoneSpecification: ZoneSpecification(
+ print: (self, parent, zone, message) {
+ printMessages.writeln();
+ printMessages.write(message);
+ },
+ ),
+ );
if (printMessages.isNotEmpty) {
response.output = '${response.output}$printMessages';
}
} catch (e, s) {
- response = WorkResponse(
- exitCode: EXIT_CODE_ERROR,
- output: '$e\n$s',
- );
+ response = WorkResponse(exitCode: EXIT_CODE_ERROR, output: '$e\n$s');
}
connection.writeResponse(response);
diff --git a/pkgs/bazel_worker/lib/src/worker/sync_worker_loop.dart b/pkgs/bazel_worker/lib/src/worker/sync_worker_loop.dart
index a857105..51da684 100644
--- a/pkgs/bazel_worker/lib/src/worker/sync_worker_loop.dart
+++ b/pkgs/bazel_worker/lib/src/worker/sync_worker_loop.dart
@@ -30,19 +30,20 @@
var request = connection.readRequest();
if (request == null) break;
var printMessages = StringBuffer();
- response = runZoned(() => performRequest(request), zoneSpecification:
- ZoneSpecification(print: (self, parent, zone, message) {
- printMessages.writeln();
- printMessages.write(message);
- }));
+ response = runZoned(
+ () => performRequest(request),
+ zoneSpecification: ZoneSpecification(
+ print: (self, parent, zone, message) {
+ printMessages.writeln();
+ printMessages.write(message);
+ },
+ ),
+ );
if (printMessages.isNotEmpty) {
response.output = '${response.output}$printMessages';
}
} catch (e, s) {
- response = WorkResponse(
- exitCode: EXIT_CODE_ERROR,
- output: '$e\n$s',
- );
+ response = WorkResponse(exitCode: EXIT_CODE_ERROR, output: '$e\n$s');
}
connection.writeResponse(response);
diff --git a/pkgs/bazel_worker/lib/src/worker/worker_connection.dart b/pkgs/bazel_worker/lib/src/worker/worker_connection.dart
index b395316..fd5508e 100644
--- a/pkgs/bazel_worker/lib/src/worker/worker_connection.dart
+++ b/pkgs/bazel_worker/lib/src/worker/worker_connection.dart
@@ -29,13 +29,16 @@
/// Creates a [StdAsyncWorkerConnection] with the specified [inputStream]
/// and [outputStream], unless [sendPort] is specified, in which case
/// creates a [SendPortAsyncWorkerConnection].
- factory AsyncWorkerConnection(
- {Stream<List<int>>? inputStream,
- StreamSink<List<int>>? outputStream,
- SendPort? sendPort}) =>
+ factory AsyncWorkerConnection({
+ Stream<List<int>>? inputStream,
+ StreamSink<List<int>>? outputStream,
+ SendPort? sendPort,
+ }) =>
sendPort == null
? StdAsyncWorkerConnection(
- inputStream: inputStream, outputStream: outputStream)
+ inputStream: inputStream,
+ outputStream: outputStream,
+ )
: SendPortAsyncWorkerConnection(sendPort);
@override
@@ -53,9 +56,10 @@
final AsyncMessageGrouper _messageGrouper;
final StreamSink<List<int>> _outputStream;
- StdAsyncWorkerConnection(
- {Stream<List<int>>? inputStream, StreamSink<List<int>>? outputStream})
- : _messageGrouper = AsyncMessageGrouper(inputStream ?? stdin),
+ StdAsyncWorkerConnection({
+ Stream<List<int>>? inputStream,
+ StreamSink<List<int>>? outputStream,
+ }) : _messageGrouper = AsyncMessageGrouper(inputStream ?? stdin),
_outputStream = outputStream ?? stdout;
@override
diff --git a/pkgs/bazel_worker/lib/testing.dart b/pkgs/bazel_worker/lib/testing.dart
index 3ae4c1f..7aefabb 100644
--- a/pkgs/bazel_worker/lib/testing.dart
+++ b/pkgs/bazel_worker/lib/testing.dart
@@ -72,10 +72,18 @@
}
@override
- StreamSubscription<Uint8List> listen(void Function(Uint8List bytes)? onData,
- {Function? onError, void Function()? onDone, bool? cancelOnError}) {
- return _controller.stream.listen(onData,
- onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+ StreamSubscription<Uint8List> listen(
+ void Function(Uint8List bytes)? onData, {
+ Function? onError,
+ void Function()? onDone,
+ bool? cancelOnError,
+ }) {
+ return _controller.stream.listen(
+ onData,
+ onError: onError,
+ onDone: onDone,
+ cancelOnError: cancelOnError,
+ );
}
@override
@@ -165,8 +173,9 @@
final List<WorkResponse> responses = <WorkResponse>[];
TestAsyncWorkerConnection(
- Stream<List<int>> inputStream, StreamSink<List<int>> outputStream)
- : super(inputStream: inputStream, outputStream: outputStream);
+ Stream<List<int>> inputStream,
+ StreamSink<List<int>> outputStream,
+ ) : super(inputStream: inputStream, outputStream: outputStream);
@override
void writeResponse(WorkResponse response) {
diff --git a/pkgs/bazel_worker/test/driver_test.dart b/pkgs/bazel_worker/test/driver_test.dart
index c397830..c3db55c 100644
--- a/pkgs/bazel_worker/test/driver_test.dart
+++ b/pkgs/bazel_worker/test/driver_test.dart
@@ -23,27 +23,37 @@
await _doRequests(count: 1);
});
- test('can run multiple batches of requests through multiple workers',
- () async {
- var maxWorkers = 4;
- var maxIdleWorkers = 2;
- driver = BazelWorkerDriver(MockWorker.spawn,
- maxWorkers: maxWorkers, maxIdleWorkers: maxIdleWorkers);
- for (var i = 0; i < 10; i++) {
- await _doRequests(driver: driver);
- expect(MockWorker.liveWorkers.length, maxIdleWorkers);
- // No workers should be killed while there is ongoing work, but they
- // should be cleaned up once there isn't any more work to do.
- expect(MockWorker.deadWorkers.length,
- (maxWorkers - maxIdleWorkers) * (i + 1));
- }
- });
+ test(
+ 'can run multiple batches of requests through multiple workers',
+ () async {
+ var maxWorkers = 4;
+ var maxIdleWorkers = 2;
+ driver = BazelWorkerDriver(
+ MockWorker.spawn,
+ maxWorkers: maxWorkers,
+ maxIdleWorkers: maxIdleWorkers,
+ );
+ for (var i = 0; i < 10; i++) {
+ await _doRequests(driver: driver);
+ expect(MockWorker.liveWorkers.length, maxIdleWorkers);
+ // No workers should be killed while there is ongoing work, but they
+ // should be cleaned up once there isn't any more work to do.
+ expect(
+ MockWorker.deadWorkers.length,
+ (maxWorkers - maxIdleWorkers) * (i + 1),
+ );
+ }
+ },
+ );
test('can run multiple requests through one worker', () async {
var maxWorkers = 1;
var maxIdleWorkers = 1;
- driver = BazelWorkerDriver(MockWorker.spawn,
- maxWorkers: maxWorkers, maxIdleWorkers: maxIdleWorkers);
+ driver = BazelWorkerDriver(
+ MockWorker.spawn,
+ maxWorkers: maxWorkers,
+ maxIdleWorkers: maxIdleWorkers,
+ );
for (var i = 0; i < 10; i++) {
await _doRequests(driver: driver);
expect(MockWorker.liveWorkers.length, 1);
@@ -52,8 +62,11 @@
});
test('can run one request through multiple workers', () async {
- driver =
- BazelWorkerDriver(MockWorker.spawn, maxWorkers: 4, maxIdleWorkers: 4);
+ driver = BazelWorkerDriver(
+ MockWorker.spawn,
+ maxWorkers: 4,
+ maxIdleWorkers: 4,
+ );
for (var i = 0; i < 10; i++) {
await _doRequests(driver: driver, count: 1);
expect(MockWorker.liveWorkers.length, 1);
@@ -63,8 +76,11 @@
test('can run with maxIdleWorkers == 0', () async {
var maxWorkers = 4;
- driver = BazelWorkerDriver(MockWorker.spawn,
- maxWorkers: maxWorkers, maxIdleWorkers: 0);
+ driver = BazelWorkerDriver(
+ MockWorker.spawn,
+ maxWorkers: maxWorkers,
+ maxIdleWorkers: 0,
+ );
for (var i = 0; i < 10; i++) {
await _doRequests(driver: driver);
expect(MockWorker.liveWorkers.length, 0);
@@ -77,14 +93,15 @@
driver = BazelWorkerDriver(MockWorker.spawn, maxWorkers: maxWorkers);
var tracking = <Future>[];
await _doRequests(
- driver: driver,
- count: 10,
- trackWork: (Future response) {
- // We should never be tracking more than `maxWorkers` jobs at a time.
- expect(tracking.length, lessThan(maxWorkers));
- tracking.add(response);
- response.then((_) => tracking.remove(response));
- });
+ driver: driver,
+ count: 10,
+ trackWork: (Future response) {
+ // We should never be tracking more than `maxWorkers` jobs at a time.
+ expect(tracking.length, lessThan(maxWorkers));
+ tracking.add(response);
+ response.then((_) => tracking.remove(response));
+ },
+ );
});
group('failing workers', () {
@@ -93,27 +110,39 @@
void createDriver({int maxRetries = 2, int numBadWorkers = 2}) {
var numSpawned = 0;
driver = BazelWorkerDriver(
- () async => MockWorker(workerLoopFactory: (MockWorker worker) {
- var connection = StdAsyncWorkerConnection(
- inputStream: worker._stdinController.stream,
- outputStream: worker._stdoutController.sink);
- if (numSpawned < numBadWorkers) {
- numSpawned++;
- return ThrowingMockWorkerLoop(
- worker, MockWorker.responseQueue, connection);
- } else {
- return MockWorkerLoop(MockWorker.responseQueue,
- connection: connection);
- }
- }),
- maxRetries: maxRetries);
+ () async => MockWorker(
+ workerLoopFactory: (MockWorker worker) {
+ var connection = StdAsyncWorkerConnection(
+ inputStream: worker._stdinController.stream,
+ outputStream: worker._stdoutController.sink,
+ );
+ if (numSpawned < numBadWorkers) {
+ numSpawned++;
+ return ThrowingMockWorkerLoop(
+ worker,
+ MockWorker.responseQueue,
+ connection,
+ );
+ } else {
+ return MockWorkerLoop(
+ MockWorker.responseQueue,
+ connection: connection,
+ );
+ }
+ },
+ ),
+ maxRetries: maxRetries,
+ );
}
test('should retry up to maxRetries times', () async {
createDriver();
var expectedResponse = WorkResponse();
- MockWorker.responseQueue.addAll(
- [disconnectedResponse, disconnectedResponse, expectedResponse]);
+ MockWorker.responseQueue.addAll([
+ disconnectedResponse,
+ disconnectedResponse,
+ expectedResponse,
+ ]);
var actualResponse = await driver!.doWork(WorkRequest());
// The first 2 null responses are thrown away, and we should get the
// third one.
@@ -125,23 +154,29 @@
test('should fail if it exceeds maxRetries failures', () async {
createDriver(maxRetries: 2, numBadWorkers: 3);
- MockWorker.responseQueue.addAll(
- [disconnectedResponse, disconnectedResponse, WorkResponse()]);
+ MockWorker.responseQueue.addAll([
+ disconnectedResponse,
+ disconnectedResponse,
+ WorkResponse(),
+ ]);
var actualResponse = await driver!.doWork(WorkRequest());
// Should actually get a bad response.
expect(actualResponse.exitCode, 15);
expect(
- actualResponse.output,
- 'Invalid response from worker, this probably means it wrote '
- 'invalid output or died.');
+ actualResponse.output,
+ 'Invalid response from worker, this probably means it wrote '
+ 'invalid output or died.',
+ );
expect(MockWorker.deadWorkers.length, 3);
});
});
test('handles spawnWorker failures', () async {
- driver = BazelWorkerDriver(() async => throw StateError('oh no!'),
- maxRetries: 0);
+ driver = BazelWorkerDriver(
+ () async => throw StateError('oh no!'),
+ maxRetries: 0,
+ );
expect(driver!.doWork(WorkRequest()), throwsA(isA<StateError>()));
});
@@ -156,10 +191,11 @@
/// Runs [count] of fake work requests through [driver], and asserts that they
/// all completed.
-Future _doRequests(
- {BazelWorkerDriver? driver,
- int count = 100,
- void Function(Future<WorkResponse?>)? trackWork}) async {
+Future _doRequests({
+ BazelWorkerDriver? driver,
+ int count = 100,
+ void Function(Future<WorkResponse?>)? trackWork,
+}) async {
// If we create a driver, we need to make sure and terminate it.
var terminateDriver = driver == null;
driver ??= BazelWorkerDriver(MockWorker.spawn);
@@ -167,7 +203,8 @@
var responses = List.generate(count, (_) => WorkResponse());
MockWorker.responseQueue.addAll(responses);
var actualResponses = await Future.wait(
- requests.map((request) => driver!.doWork(request, trackWork: trackWork)));
+ requests.map((request) => driver!.doWork(request, trackWork: trackWork)),
+ );
expect(actualResponses, unorderedEquals(responses));
if (terminateDriver) await driver.terminateWorkers();
}
@@ -191,9 +228,11 @@
class ThrowingMockWorkerLoop extends MockWorkerLoop {
final MockWorker _mockWorker;
- ThrowingMockWorkerLoop(this._mockWorker, Queue<WorkResponse> responseQueue,
- AsyncWorkerConnection connection)
- : super(responseQueue, connection: connection);
+ ThrowingMockWorkerLoop(
+ this._mockWorker,
+ Queue<WorkResponse> responseQueue,
+ AsyncWorkerConnection connection,
+ ) : super(responseQueue, connection: connection);
/// Run the worker loop. The returned [Future] doesn't complete until
/// [connection#readRequest] returns `null`.
@@ -234,10 +273,13 @@
liveWorkers.add(this);
var workerLoop = workerLoopFactory != null
? workerLoopFactory(this)
- : MockWorkerLoop(responseQueue,
+ : MockWorkerLoop(
+ responseQueue,
connection: StdAsyncWorkerConnection(
- inputStream: _stdinController.stream,
- outputStream: _stdoutController.sink));
+ inputStream: _stdinController.stream,
+ outputStream: _stdoutController.sink,
+ ),
+ );
workerLoop.run();
}
@@ -260,8 +302,10 @@
int get pid => throw UnsupportedError('Not needed.');
@override
- bool kill(
- [ProcessSignal processSignal = ProcessSignal.sigterm, int exitCode = 0]) {
+ bool kill([
+ ProcessSignal processSignal = ProcessSignal.sigterm,
+ int exitCode = 0,
+ ]) {
if (_killed) return false;
() async {
await _stdoutController.close();
diff --git a/pkgs/bazel_worker/test/message_grouper_test.dart b/pkgs/bazel_worker/test/message_grouper_test.dart
index 475190e..fd99911 100644
--- a/pkgs/bazel_worker/test/message_grouper_test.dart
+++ b/pkgs/bazel_worker/test/message_grouper_test.dart
@@ -18,8 +18,10 @@
});
}
-void runTests(TestStdin Function() stdinFactory,
- MessageGrouper Function(Stdin) messageGrouperFactory) {
+void runTests(
+ TestStdin Function() stdinFactory,
+ MessageGrouper Function(Stdin) messageGrouperFactory,
+) {
late MessageGrouper messageGrouper;
late TestStdin stdinStream;
@@ -52,16 +54,12 @@
});
test('Short message', () async {
- await check([
- 5,
- 10,
- 20,
- 30,
- 40,
- 50
- ], [
- [10, 20, 30, 40, 50]
- ]);
+ await check(
+ [5, 10, 20, 30, 40, 50],
+ [
+ [10, 20, 30, 40, 50],
+ ],
+ );
});
test('Message with 2-byte length', () async {
@@ -79,57 +77,44 @@
});
test('Multiple messages', () async {
- await check([
- 2,
- 10,
- 20,
- 2,
- 30,
- 40
- ], [
- [10, 20],
- [30, 40]
- ]);
+ await check(
+ [2, 10, 20, 2, 30, 40],
+ [
+ [10, 20],
+ [30, 40],
+ ],
+ );
});
test('Empty message at start', () async {
- await check([
- 0,
- 2,
- 10,
- 20
- ], [
- [],
- [10, 20]
- ]);
+ await check(
+ [0, 2, 10, 20],
+ [
+ [],
+ [10, 20],
+ ],
+ );
});
test('Empty message at end', () async {
- await check([
- 2,
- 10,
- 20,
- 0
- ], [
- [10, 20],
- []
- ]);
+ await check(
+ [2, 10, 20, 0],
+ [
+ [10, 20],
+ [],
+ ],
+ );
});
test('Empty message in the middle', () async {
- await check([
- 2,
- 10,
- 20,
- 0,
- 2,
- 30,
- 40
- ], [
- [10, 20],
- [],
- [30, 40]
- ]);
+ await check(
+ [2, 10, 20, 0, 2, 30, 40],
+ [
+ [10, 20],
+ [],
+ [30, 40],
+ ],
+ );
});
test('Handles the case when stdin gives an error instead of EOF', () async {
diff --git a/pkgs/bazel_worker/test/worker_loop_test.dart b/pkgs/bazel_worker/test/worker_loop_test.dart
index 50d2151..24068b1 100644
--- a/pkgs/bazel_worker/test/worker_loop_test.dart
+++ b/pkgs/bazel_worker/test/worker_loop_test.dart
@@ -11,36 +11,45 @@
void main() {
group('SyncWorkerLoop', () {
- runTests(TestStdinSync.new, TestSyncWorkerConnection.new,
- TestSyncWorkerLoop.new);
+ runTests(
+ TestStdinSync.new,
+ TestSyncWorkerConnection.new,
+ TestSyncWorkerLoop.new,
+ );
});
group('AsyncWorkerLoop', () {
- runTests(TestStdinAsync.new, TestAsyncWorkerConnection.new,
- TestAsyncWorkerLoop.new);
+ runTests(
+ TestStdinAsync.new,
+ TestAsyncWorkerConnection.new,
+ TestAsyncWorkerLoop.new,
+ );
});
group('SyncWorkerLoopWithPrint', () {
runTests(
- TestStdinSync.new,
- TestSyncWorkerConnection.new,
- (TestSyncWorkerConnection connection) =>
- TestSyncWorkerLoop(connection, printMessage: 'Goodbye!'));
+ TestStdinSync.new,
+ TestSyncWorkerConnection.new,
+ (TestSyncWorkerConnection connection) =>
+ TestSyncWorkerLoop(connection, printMessage: 'Goodbye!'),
+ );
});
group('AsyncWorkerLoopWithPrint', () {
runTests(
- TestStdinAsync.new,
- TestAsyncWorkerConnection.new,
- (TestAsyncWorkerConnection connection) =>
- TestAsyncWorkerLoop(connection, printMessage: 'Goodbye!'));
+ TestStdinAsync.new,
+ TestAsyncWorkerConnection.new,
+ (TestAsyncWorkerConnection connection) =>
+ TestAsyncWorkerLoop(connection, printMessage: 'Goodbye!'),
+ );
});
}
void runTests<T extends TestWorkerConnection>(
- TestStdin Function() stdinFactory,
- T Function(Stdin, Stdout) workerConnectionFactory,
- TestWorkerLoop Function(T) workerLoopFactory) {
+ TestStdin Function() stdinFactory,
+ T Function(Stdin, Stdout) workerConnectionFactory,
+ TestWorkerLoop Function(T) workerLoopFactory,
+) {
late TestStdin stdinStream;
late TestStdoutStream stdoutStream;
late T connection;
@@ -63,19 +72,29 @@
// Make sure `print` never gets called in the parent zone.
var printMessages = <String>[];
- await runZoned(() => workerLoop.run(), zoneSpecification:
- ZoneSpecification(print: (self, parent, zone, message) {
- printMessages.add(message);
- }));
- expect(printMessages, isEmpty,
- reason: 'The worker loop should hide all print calls from the parent '
- 'zone.');
+ await runZoned(
+ () => workerLoop.run(),
+ zoneSpecification: ZoneSpecification(
+ print: (self, parent, zone, message) {
+ printMessages.add(message);
+ },
+ ),
+ );
+ expect(
+ printMessages,
+ isEmpty,
+ reason: 'The worker loop should hide all print calls from the parent '
+ 'zone.',
+ );
expect(connection.responses, hasLength(1));
expect(connection.responses[0], response);
if (workerLoop.printMessage != null) {
- expect(response.output, endsWith(workerLoop.printMessage!),
- reason: 'Print messages should get appended to the response output.');
+ expect(
+ response.output,
+ endsWith(workerLoop.printMessage!),
+ reason: 'Print messages should get appended to the response output.',
+ );
}
// Check that a serialized version was written to std out.
diff --git a/pkgs/clock/analysis_options.yaml b/pkgs/clock/analysis_options.yaml
index 9ee7c2b..db6072d 100644
--- a/pkgs/clock/analysis_options.yaml
+++ b/pkgs/clock/analysis_options.yaml
@@ -11,4 +11,3 @@
rules:
- avoid_private_typedef_functions
- avoid_redundant_argument_values
- - use_super_parameters
diff --git a/pkgs/coverage/analysis_options.yaml b/pkgs/coverage/analysis_options.yaml
index 82ce5e0..bb1afe0 100644
--- a/pkgs/coverage/analysis_options.yaml
+++ b/pkgs/coverage/analysis_options.yaml
@@ -9,14 +9,9 @@
linter:
rules:
- - always_declare_return_types
- avoid_slow_async_io
- cancel_subscriptions
- - comment_references
- literal_only_boolean_expressions
- prefer_final_locals
- sort_constructors_first
- sort_unnamed_constructors_first
- - test_types_in_equals
- - throw_in_finally
- - type_annotate_public_apis
diff --git a/pkgs/file/CHANGELOG.md b/pkgs/file/CHANGELOG.md
index 50c96c4..3a3969c 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 8fbd2e4..d978f81 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 7ca0bc7..b03b363 100644
--- a/pkgs/file/example/main.dart
+++ b/pkgs/file/example/main.dart
@@ -7,8 +7,8 @@
Future<void> 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 56d2bd5..6992ad0 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 cdde9fe..c2e97b2 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 74f506e..5b1e3cd 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 c5705ef..690b65f 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 6082e80..402dbec 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 8fec7b1..e094193 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<Directory, io.Directory>
with ForwardingDirectory<Directory>, 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 @@
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 @@
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 @@
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 @@
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 @@
@override
Future<Directory> 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 @@
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 @@
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 @@
}
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 4b67bc1..d6c29fc 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<File, io.File>
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 @@
@override
Future<File> 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 @@
@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 6889c98..503821f 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 @@
}
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 @@
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 @@
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 @@
throw common.noSuchFileOrDirectory(path);
}
- p.Context ctx = this.path;
- String root = _localRoot;
+ var ctx = this.path;
+ var root = _localRoot;
List<String> parts, ledger;
if (ctx.isAbsolute(path)) {
parts = ctx.split(path).sublist(1);
@@ -277,9 +277,9 @@
}
String getCurrentPath() => root + ctx.joinAll(ledger);
- Set<String> breadcrumbs = <String>{};
+ var breadcrumbs = <String>{};
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 @@
}
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 @@
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 8e859ac..18e37cd 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<T extends FileSystemEntity,
D extends io.FileSystemEntity> extends ForwardingFileSystemEntity<T, D> {
@@ -103,7 +103,7 @@
@override
Future<T> 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 @@
if (expectedType == FileSystemEntityType.link) {
await fileSystem.delegate.link(real(path)).delete();
} else {
- String resolvedPath = fileSystem._resolve(p.basename(path),
+ var resolvedPath = fileSystem._resolve(p.basename(path),
from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail);
if (!recursive && await type(resolvedPath) != expectedType) {
throw expectedType == FileSystemEntityType.file
@@ -132,7 +132,7 @@
@override
void deleteSync({bool recursive = false}) {
- 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);
@@ -143,7 +143,7 @@
if (expectedType == FileSystemEntityType.link) {
fileSystem.delegate.link(real(path)).deleteSync();
} else {
- String resolvedPath = fileSystem._resolve(p.basename(path),
+ var resolvedPath = fileSystem._resolve(p.basename(path),
from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail);
if (!recursive && type(resolvedPath) != expectedType) {
throw expectedType == FileSystemEntityType.file
diff --git a/pkgs/file/lib/src/backends/chroot/chroot_link.dart b/pkgs/file/lib/src/backends/chroot/chroot_link.dart
index acbeda6..1620df9 100644
--- a/pkgs/file/lib/src/backends/chroot/chroot_link.dart
+++ b/pkgs/file/lib/src/backends/chroot/chroot_link.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 _ChrootLink extends _ChrootFileSystemEntity<Link, io.Link>
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 4105ac8..10bbd70 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 e23e68f..3e1db61 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 @@
with ForwardingDirectory<LocalDirectory>, 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 36293ba..a4bc106 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 @@
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 635998e..7541c37 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 ca4617b..d0da559 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 fc67d5e..2ce4791 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 @@
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 98d5434..57c1b72 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 80e3c38..eb4ca43 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 95fe542..e73b967 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 @@
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 @@
@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 @@
@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 @@
bool recursive = false,
bool followLinks = true,
}) {
- DirectoryNode node = backing as DirectoryNode;
- List<FileSystemEntity> listing = <FileSystemEntity>[];
- List<_PendingListTask> tasks = <_PendingListTask>[
+ var node = backing as DirectoryNode;
+ var listing = <FileSystemEntity>[];
+ var tasks = <_PendingListTask>[
_PendingListTask(
node,
path.endsWith(fileSystem.path.separator)
@@ -140,14 +139,14 @@
),
];
while (tasks.isNotEmpty) {
- _PendingListTask task = tasks.removeLast();
+ var task = tasks.removeLast();
task.dir.children.forEach((String name, Node child) {
- Set<LinkNode> breadcrumbs = Set<LinkNode>.from(task.breadcrumbs);
- String childPath = fileSystem.path.join(task.path, name);
+ var breadcrumbs = Set<LinkNode>.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 ba4faab..1a8f5f9 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: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 @@
}
Node? _doCreate({bool recursive = false}) {
- Node? node = internalCreateSync(
+ var node = internalCreateSync(
followTailLink: true,
createChild: (DirectoryNode parent, bool isFinalSegment) {
if (isFinalSegment) {
@@ -88,7 +87,7 @@
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 @@
@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 @@
if (currentSegment == finalSegment) {
if (child != null) {
if (utils.isLink(child)) {
- List<String> ledger = <String>[];
+ var ledger = <String>[];
child = utils.resolveLinks(child as LinkNode, () => newPath,
ledger: ledger);
checkExists(child, () => newPath);
@@ -127,7 +126,7 @@
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 @@
@override
void setLastAccessedSync(DateTime time) {
- FileNode node = resolvedBacking as FileNode;
+ var node = resolvedBacking as FileNode;
node.accessed = time.millisecondsSinceEpoch;
}
@@ -174,7 +173,7 @@
@override
void setLastModifiedSync(DateTime time) {
- FileNode node = resolvedBacking as FileNode;
+ var node = resolvedBacking as FileNode;
node.modified = time.millisecondsSinceEpoch;
}
@@ -199,8 +198,8 @@
Stream<List<int>> 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 @@
@override
List<String> readAsLinesSync({Encoding encoding = utf8}) {
- String str = readAsStringSync(encoding: encoding);
+ var str = readAsStringSync(encoding: encoding);
if (str.isEmpty) {
return <String>[];
}
- final List<String> 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 @@
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 @@
deferredException = e;
}
- Future<FileNode> future = Future<FileNode>.microtask(() {
+ var future = Future<FileNode>.microtask(() {
if (deferredException != null) {
throw deferredException;
}
@@ -387,7 +386,7 @@
@override
void writeAll(Iterable<dynamic> objects, [String separator = '']) {
- bool firstIter = true;
+ var firstIter = true;
for (dynamic obj in objects) {
if (!firstIter) {
write(separator);
@@ -418,7 +417,7 @@
_streamCompleter = Completer<void>();
stream.listen(
- (List<int> data) => _addData(data),
+ _addData,
cancelOnError: true,
onError: (Object error, StackTrace stackTrace) {
_streamCompleter!.completeError(error, stackTrace);
@@ -445,8 +444,7 @@
_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 94f86d1..ce6beda 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 @@
@override
String modeString() {
- int permissions = mode & 0xFFF;
- List<String> codes = const <String>[
+ var permissions = mode & 0xFFF;
+ var codes = const <String>[
'---',
'--x',
'-w-',
@@ -58,7 +58,7 @@
'rw-',
'rwx',
];
- List<String> result = <String>[];
+ var result = <String>[];
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 f3cdaee..dd359f0 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_stat.dart';
import 'memory_link.dart';
import 'node.dart';
+import 'operations.dart';
import 'style.dart';
import 'utils.dart' as utils;
@@ -91,7 +91,7 @@
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 @@
}
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 @@
@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 @@
reference ??= _current;
}
- List<String> 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 ad987d7..1990abc 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 @@
/// 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 @@
/// 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 @@
if (path.isEmpty) {
throw common.noSuchFileOrDirectory(path);
}
- List<String> ledger = <String>[];
+ var ledger = <String>[];
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 @@
@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 @@
bool followTailLink = false,
utils.TypeChecker? checkType,
}) {
- Node node = backing;
+ var node = backing;
(checkType ?? defaultCheckType)(node);
fileSystem.findNode(
newPath,
@@ -256,7 +256,7 @@
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 @@
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 7d5afb4..a599fe8 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 @@
/// 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 @@
@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 @@
@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 @@
@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 d4fe73d..190f0a1 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: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 @@
/// 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 @@
_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 @@
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 @@
'truncate failed', path, common.invalidArgument(path).osError);
}
- final int oldLength = lengthSync();
+ final oldLength = lengthSync();
if (length < oldLength) {
_node.truncate(length);
@@ -329,7 +330,7 @@
// [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 @@
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 ae4d3f7..eea72b5 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 @@
/// 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 @@
/// 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 @@
/// 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<String, Node> children = <String, Node>{};
@@ -237,7 +236,7 @@
/// 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 @@
/// Appends the specified bytes to the end of this node's [content].
void write(List<int> 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 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 @@
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 @@
}
_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 9fc7462..57d118b 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 @@
@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 701c9d0..f4bd33f 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 eec9980..aa24cfb 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 @@
tailVisitor,
}) {
// Record a breadcrumb trail to guard against symlink loops.
- Set<LinkNode> breadcrumbs = <LinkNode>{};
+ var breadcrumbs = <LinkNode>{};
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 dba0c8e..ad1c548 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<T extends Directory>
diff --git a/pkgs/file/lib/src/forwarding/forwarding_file.dart b/pkgs/file/lib/src/forwarding/forwarding_file.dart
index 49c211d..d6cfe3b 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 d864db9..885fdb6 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 3c41b39..1c0628e 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<T extends FileSystemEntity,
D extends io.FileSystemEntity> implements FileSystemEntity {
diff --git a/pkgs/file/lib/src/forwarding/forwarding_link.dart b/pkgs/file/lib/src/forwarding/forwarding_link.dart
index 7a60ecb..915e710 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 9dd4079..3847b91 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 4662e35..d9b7ed5 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 8943538..4836b56 100644
--- a/pkgs/file/lib/src/interface/error_codes.dart
+++ b/pkgs/file/lib/src/interface/error_codes.dart
@@ -168,7 +168,7 @@
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 ecc01a8..2d4e4aa 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: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 @@
bool get isWatchSupported;
/// Finds the type of file system object that a [path] points to. Returns
- /// a Future<FileSystemEntityType> that completes with the result.
+ /// a `Future<FileSystemEntityType>` 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 @@
/// 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<bool> 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<bool> 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<bool> 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 9d57e78..28c1d6d 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 5de5d37..0ad65b0 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 @@
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 6c34ff2..cf23f47 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 @@
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<String> skipCommon = <String>[
+ var skipCommon = <String>[
+ // ignore: lines_longer_than_80_chars
'File > open > .* > RandomAccessFile > read > openReadHandleDoesNotChange',
'File > open > .* > RandomAccessFile > openWriteHandleDoesNotChange',
];
@@ -137,6 +140,7 @@
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 @@
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 6028c77..491d4f9 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 '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 @@
List<String> skip = const <String>[],
FileSystemGenerator? replay,
}) {
- RootPathGenerator? rootfn = root;
+ var rootfn = root;
group('common', () {
late FileSystemGenerator createFs;
@@ -62,7 +64,7 @@
late List<SetUpTearDown> tearDowns;
late FileSystem fs;
late String root;
- List<String> stack = <String>[];
+ var stack = <String>[];
void skipIfNecessary(String description, void Function() callback) {
stack.add(description);
@@ -105,7 +107,7 @@
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 @@
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 @@
/// 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<String> 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 @@
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 @@
});
// 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 @@
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 @@
});
// 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 @@
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 @@
group('systemTempDirectory', () {
test('existsAsDirectory', () {
- Directory tmp = fs.systemTempDirectory;
+ var tmp = fs.systemTempDirectory;
expect(tmp, isDirectory);
expect(tmp, exists);
});
@@ -318,7 +320,7 @@
test('staysAtRootIfSetToParentOfRoot', () {
fs.currentDirectory =
List<String>.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 @@
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 @@
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 @@
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<String>.filled(20, '..').join(fs.path.separator));
expect(type, FileSystemEntityType.directory);
});
@@ -473,15 +475,14 @@
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 @@
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 @@
});
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 @@
'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 @@
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 @@
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 @@
});
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 @@
});
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 @@
});
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 @@
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 @@
});
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 @@
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 @@
.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 @@
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 @@
});
test('returnsEmptyListForEmptyDirectory', () {
- Directory empty = fs.directory(ns('/bar'))..createSync();
+ var empty = fs.directory(ns('/bar'))..createSync();
expect(empty.listSync(), isEmpty);
});
@@ -1134,7 +1135,7 @@
});
test('returnsLinkObjectsIfFollowLinksFalse', () {
- List<FileSystemEntity> 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 @@
});
test('followsLinksIfFollowLinksTrue', () {
- List<FileSystemEntity> 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 @@
test('childEntriesNotNormalized', () {
dir = fs.directory(ns('/bar/baz'))..createSync(recursive: true);
fs.file(ns('/bar/baz/qux')).createSync();
- List<FileSystemEntity> 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 @@
test('symlinksToNotFoundAlwaysReturnedAsLinks', () {
dir = fs.directory(ns('/bar'))..createSync();
fs.link(ns('/bar/baz')).createSync('qux');
- for (bool followLinks in const <bool>[true, false]) {
- List<FileSystemEntity> list =
- dir.listSync(followLinks: followLinks);
+ for (var followLinks in const <bool>[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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
}, 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 @@
});
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 @@
});
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(<int>[1, 2, 3, 4], flush: true);
expect(f.lengthSync(), 4);
});
@@ -1616,10 +1615,10 @@
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 @@
});
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 @@
});
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 @@
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 @@
});
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 @@
});
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 @@
});
} 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 @@
});
test('readIntoWithBufferLargerThanContent', () {
- List<int> buffer = List<int>.filled(1024, 0);
- int numRead = raf.readIntoSync(buffer);
+ var buffer = List<int>.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<int> buffer = List<int>.filled(10, 0);
- int numRead = raf.readIntoSync(buffer);
+ var buffer = List<int>.filled(10, 0);
+ var numRead = raf.readIntoSync(buffer);
expect(numRead, 10);
expect(utf8.decode(buffer), 'pre-existi');
});
test('readIntoWithStart', () {
- List<int> buffer = List<int>.filled(10, 0);
- int numRead = raf.readIntoSync(buffer, 2);
+ var buffer = List<int>.filled(10, 0);
+ var numRead = raf.readIntoSync(buffer, 2);
expect(numRead, 8);
expect(utf8.decode(buffer.sublist(2)), 'pre-exis');
});
test('readIntoWithStartAndEnd', () {
- List<int> buffer = List<int>.filled(10, 0);
- int numRead = raf.readIntoSync(buffer, 2, 5);
+ var buffer = List<int>.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 @@
});
} 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 @@
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 @@
});
} else {
test('growsAfterWrite', () {
- int positionBefore = raf.positionSync();
+ var positionBefore = raf.positionSync();
raf.writeStringSync('Hello world');
expect(raf.positionSync(), positionBefore + 11);
});
@@ -2165,42 +2164,42 @@
group('openRead', () {
test('throwsIfDoesntExist', () {
- Stream<List<int>> stream = fs.file(ns('/foo')).openRead();
+ var stream = fs.file(ns('/foo')).openRead();
expect(stream.drain<void>(),
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<List<int>> stream = f.openRead();
- List<List<int>> 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<List<int>> stream = fs.file(ns('/foo')).openRead();
+ var stream = fs.file(ns('/foo')).openRead();
expect(stream.drain<void>(),
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<List<int>> stream = fs.file(ns('/bar')).openRead();
- List<List<int>> 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<List<int>> stream = f.openRead(2);
- List<List<int>> 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 @@
});
test('throwsIfStartParameterIsNegative', () async {
- File f = fs.file(ns('/foo'))..createSync();
- Stream<List<int>> stream = f.openRead(-2);
+ var f = fs.file(ns('/foo'))..createSync();
+ var stream = f.openRead(-2);
expect(stream.drain<void>(), 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<List<int>> stream = f.openRead(2, 1024);
- List<List<int>> 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<List<int>> stream = f.openRead();
+ var stream = f.openRead();
expect(stream.isBroadcast, isFalse);
await stream.drain<void>();
});
@@ -2237,20 +2236,20 @@
// 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<int> data = List<int>.generate(
+ final data = List<int>.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<List<int>> stream = f.openRead();
+ final stream = f.openRead();
File? newFile;
List<int>? initialChunk;
- final List<int> remainingChunks = <int>[];
+ final remainingChunks = <int>[];
await for (List<int> chunk in stream) {
if (initialChunk == null) {
@@ -2276,7 +2275,7 @@
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 @@
});
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 @@
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 @@
});
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 @@
});
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 @@
});
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 @@
late bool isSinkClosed;
Future<dynamic> closeSink() {
- Future<dynamic> future = sink.close();
+ var future = sink.close();
isSinkClosed = true;
return future;
}
@@ -2448,13 +2447,13 @@
test('ignoresCloseAfterAlreadyClosed', () async {
sink.write('Hello world');
- Future<dynamic> f1 = closeSink();
- Future<dynamic> f2 = closeSink();
+ var f1 = closeSink();
+ var f2 = closeSink();
await Future.wait<dynamic>(<Future<dynamic>>[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 @@
late bool isControllerClosed;
Future<dynamic> closeController() {
- Future<dynamic> future = controller.close();
+ var future = controller.close();
isControllerClosed = true;
return future;
}
@@ -2543,7 +2542,7 @@
});
test('succeedsIfExistsAsFile', () {
- File f = fs.file(ns('/foo'))..createSync();
+ var f = fs.file(ns('/foo'))..createSync();
f.writeAsBytesSync(<int>[1, 2, 3, 4]);
expect(f.readAsBytesSync(), <int>[1, 2, 3, 4]);
});
@@ -2556,12 +2555,12 @@
});
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(<int>[1, 2, 3, 4]);
List<int> result = f.readAsBytesSync();
expect(result, <int>[1, 2, 3, 4]);
@@ -2593,7 +2592,7 @@
});
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 @@
});
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<String> expectedLines = <String>[
+ const testString = 'Hello world\nHow are you?\nI am fine';
+ final expectedLines = <String>[
'Hello world',
'How are you?',
'I am fine',
@@ -2641,25 +2640,25 @@
});
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 @@
});
test('createsFileIfDoesntExist', () {
- File f = fs.file(ns('/foo'));
+ var f = fs.file(ns('/foo'));
expect(f, isNot(exists));
f.writeAsBytesSync(<int>[1, 2, 3, 4]);
expect(f, exists);
@@ -2699,21 +2698,21 @@
});
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(<int>[1, 2, 3, 4]);
expect(f.readAsBytesSync(), <int>[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(<int>[1], mode: FileMode.read);
});
});
test('overwritesContentIfFileModeWrite', () {
- File f = fs.file(ns('/foo'))..createSync();
+ var f = fs.file(ns('/foo'))..createSync();
f.writeAsBytesSync(<int>[1, 2]);
expect(f.readAsBytesSync(), <int>[1, 2]);
f.writeAsBytesSync(<int>[3, 4]);
@@ -2721,7 +2720,7 @@
});
test('appendsContentIfFileModeAppend', () {
- File f = fs.file(ns('/foo'))..createSync();
+ var f = fs.file(ns('/foo'))..createSync();
f.writeAsBytesSync(<int>[1, 2], mode: FileMode.append);
expect(f.readAsBytesSync(), <int>[1, 2]);
f.writeAsBytesSync(<int>[3, 4], mode: FileMode.append);
@@ -2729,17 +2728,17 @@
});
test('acceptsEmptyBytesList', () {
- File f = fs.file(ns('/foo'))..createSync();
+ var f = fs.file(ns('/foo'))..createSync();
f.writeAsBytesSync(<int>[]);
expect(f.readAsBytesSync(), <int>[]);
});
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<void>.delayed(const Duration(seconds: 2));
f.writeAsBytesSync(<int>[1, 2, 3]);
- DateTime after = f.statSync().modified;
+ var after = f.statSync().modified;
expect(after, isAfter(before));
});
});
@@ -2750,7 +2749,7 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
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 @@
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 @@
});
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 @@
});
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 @@
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 e1618d2..b794ccd 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 @@
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 @@
ignoreOsErrorCodes = false;
});
- Map<String, List<String>> skipOnPlatform = <String, List<String>>{
+ var skipOnPlatform = <String, List<String>>{
'windows': <String>[
'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 5e27843..916707c 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<String> contexts = <String>[];
- List<FileSystemOp> operations = <FileSystemOp>[];
- MemoryFileSystem fs = MemoryFileSystem.test(
+ var contexts = <String>[];
+ var operations = <FileSystemOp>[];
+ 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 @@
});
test('Write operations invoke opHandle', () async {
- List<String> contexts = <String>[];
- List<FileSystemOp> operations = <FileSystemOp>[];
- MemoryFileSystem fs = MemoryFileSystem.test(
+ var contexts = <String>[];
+ var operations = <FileSystemOp>[];
+ 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(<int>[]);
file.writeAsBytesSync(<int>[]);
@@ -60,18 +59,18 @@
});
test('Delete operations invoke opHandle', () async {
- List<String> contexts = <String>[];
- List<FileSystemOp> operations = <FileSystemOp>[];
- MemoryFileSystem fs = MemoryFileSystem.test(
+ var contexts = <String>[];
+ var operations = <FileSystemOp>[];
+ 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 @@
});
test('Create operations invoke opHandle', () async {
- List<String> contexts = <String>[];
- List<FileSystemOp> operations = <FileSystemOp>[];
- MemoryFileSystem fs = MemoryFileSystem.test(
+ var contexts = <String>[];
+ var operations = <FileSystemOp>[];
+ var fs = MemoryFileSystem.test(
opHandle: (String context, FileSystemOp operation) {
if (operation == FileSystemOp.create) {
contexts.add(context);
@@ -139,16 +138,16 @@
});
test('Open operations invoke opHandle', () async {
- List<String> contexts = <String>[];
- List<FileSystemOp> operations = <FileSystemOp>[];
- MemoryFileSystem fs = MemoryFileSystem.test(
+ var contexts = <String>[];
+ var operations = <FileSystemOp>[];
+ 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 @@
});
test('Copy operations invoke opHandle', () async {
- List<String> contexts = <String>[];
- List<FileSystemOp> operations = <FileSystemOp>[];
- MemoryFileSystem fs = MemoryFileSystem.test(
+ var contexts = <String>[];
+ var operations = <FileSystemOp>[];
+ 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 @@
});
test('Exists operations invoke opHandle', () async {
- List<String> contexts = <String>[];
- List<FileSystemOp> operations = <FileSystemOp>[];
- MemoryFileSystem fs = MemoryFileSystem.test(
+ var contexts = <String>[];
+ var operations = <FileSystemOp>[];
+ 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 f3b324e..ce8675f 100644
--- a/pkgs/file/test/memory_test.dart
+++ b/pkgs/file/test/memory_test.dart
@@ -66,8 +66,7 @@
});
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 @@
});
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<MemoryRandomAccessFile>());
} finally {
@@ -114,7 +113,7 @@
});
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 @@
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 @@
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(<int>[0xFFFE]); // Invalid UTF8
expect(file.readAsStringSync, throwsA(isA<FileSystemException>()));
});
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 231312f..797ec9d 100644
--- a/pkgs/file/test/utils.dart
+++ b/pkgs/file/test/utils.dart
@@ -25,7 +25,7 @@
/// 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 @@
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 75293bf..23788e9 100644
--- a/pkgs/file/test/utils_test.dart
+++ b/pkgs/file/test/utils_test.dart
@@ -8,9 +8,9 @@
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 @@
});
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 0af779d..17039ee 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 8fbd2e4..d978f81 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 f58539f..801209e 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 'internal.dart';
/// Matcher that successfully matches against any instance of [Directory].
-const Matcher isDirectory = TypeMatcher<Directory>();
+const isDirectory = TypeMatcher<Directory>();
/// Matcher that successfully matches against any instance of [File].
-const Matcher isFile = TypeMatcher<File>();
+const isFile = TypeMatcher<File>();
/// Matcher that successfully matches against any instance of [Link].
-const Matcher isLink = TypeMatcher<Link>();
+const isLink = TypeMatcher<Link>();
/// Matcher that successfully matches against any instance of
/// [FileSystemEntity].
-const Matcher isFileSystemEntity = TypeMatcher<FileSystemEntity>();
+const isFileSystemEntity = TypeMatcher<FileSystemEntity>();
/// Matcher that successfully matches against any instance of [FileStat].
-const Matcher isFileStat = TypeMatcher<FileStat>();
+const isFileStat = TypeMatcher<FileStat>();
/// 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<FileSystemEntity> 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 @@
/// [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<FileSystemException>().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 @@
/// Matcher that successfully matches against a [FileSystemEntity] that
/// exists ([FileSystemEntity.existsSync] returns true).
-const Matcher exists = _Exists();
+final TypeMatcher<FileSystemEntity> exists =
+ isFileSystemEntity.having((e) => e.existsSync(), 'existsSync', true);
-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<dynamic, dynamic> 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;
-
- @override
- bool matches(dynamic item, Map<dynamic, dynamic> 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<dynamic, dynamic> 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<dynamic, dynamic> 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<dynamic, dynamic> 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 691efa0..895826a 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 @@
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 ae7711e..b06ac72 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 54ba743..9043c63 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 b699ac7..590dfc6 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 17733cd..32523d6 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 98e0c93..a518a0c 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 58f805a..244dee7 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 f70531e..ba04fbb 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 61b4768..3b0562d 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 8518fa7..32cbf4f 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 @@
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 f6139de..e225ff5 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 4abdce2..2516d1e 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/test_reflective_loader/.gitignore b/pkgs/test_reflective_loader/.gitignore
new file mode 100644
index 0000000..2a2c261
--- /dev/null
+++ b/pkgs/test_reflective_loader/.gitignore
@@ -0,0 +1,11 @@
+.buildlog
+.DS_Store
+.idea
+.dart_tool/
+.pub/
+.project
+.settings/
+build/
+packages
+.packages
+pubspec.lock
diff --git a/pkgs/test_reflective_loader/AUTHORS b/pkgs/test_reflective_loader/AUTHORS
new file mode 100644
index 0000000..e8063a8
--- /dev/null
+++ b/pkgs/test_reflective_loader/AUTHORS
@@ -0,0 +1,6 @@
+# Below is a list of people and organizations that have contributed
+# to the project. Names should be added to the list like so:
+#
+# Name/Organization <email address>
+
+Google Inc.
diff --git a/pkgs/test_reflective_loader/CHANGELOG.md b/pkgs/test_reflective_loader/CHANGELOG.md
new file mode 100644
index 0000000..803eb0e
--- /dev/null
+++ b/pkgs/test_reflective_loader/CHANGELOG.md
@@ -0,0 +1,72 @@
+## 0.2.3
+
+- Require Dart `^3.1.0`.
+- Move to `dart-lang/tools` monorepo.
+
+## 0.2.2
+
+- Update to package:lints 2.0.0 and move it to a dev dependency.
+
+## 0.2.1
+
+- Use package:lints for analysis.
+- Populate the pubspec `repository` field.
+
+## 0.2.0
+
+- Stable null safety release.
+
+## 0.2.0-nullsafety.0
+
+- Migrate to the null safety language feature.
+
+## 0.1.9
+
+- Add `@SkippedTest` annotation and `skip_test` prefix.
+
+## 0.1.8
+
+- Update `FailingTest` to add named parameters `issue` and `reason`.
+
+## 0.1.7
+
+- Update documentation comments.
+- Remove `@MirrorsUsed` annotation on `dart:mirrors`.
+
+## 0.1.6
+
+- Make `FailingTest` public, with the URI of the issue that causes
+ the test to break.
+
+## 0.1.5
+
+- Set max SDK version to `<3.0.0`, and adjust other dependencies.
+
+## 0.1.3
+
+- Fix `@failingTest` to fail when the test passes.
+
+## 0.1.2
+
+- Update the pubspec `dependencies` section to include `package:test`
+
+## 0.1.1
+
+- For `@failingTest` tests, properly handle when the test fails by throwing an
+ exception in a timer task
+- Analyze this package in strong mode
+
+## 0.1.0
+
+- Switched from 'package:unittest' to 'package:test'.
+- Since 'package:test' does not define 'solo_test', in order to keep this
+ functionality, `defineReflectiveSuite` must be used to wrap all
+ `defineReflectiveTests` invocations.
+
+## 0.0.4
+
+- Added @failingTest, @assertFailingTest and @soloTest annotations.
+
+## 0.0.1
+
+- Initial version
diff --git a/pkgs/test_reflective_loader/LICENSE b/pkgs/test_reflective_loader/LICENSE
new file mode 100644
index 0000000..633672a
--- /dev/null
+++ b/pkgs/test_reflective_loader/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2015, 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/test_reflective_loader/README.md b/pkgs/test_reflective_loader/README.md
new file mode 100644
index 0000000..9b5a83d
--- /dev/null
+++ b/pkgs/test_reflective_loader/README.md
@@ -0,0 +1,28 @@
+[](https://github.com/dart-lang/tools/actions/workflows/test_reflective_loader.yaml)
+[](https://pub.dev/packages/test_reflective_loader)
+[](https://pub.dev/packages/test_reflective_loader/publisher)
+
+Support for discovering tests and test suites using reflection.
+
+This package follows the xUnit style where each class is a test suite, and each
+method with the name prefix `test_` is a single test.
+
+Methods with names starting with `test_` are run using the `test()` function with
+the corresponding name. If the class defines methods `setUp()` or `tearDown()`,
+they are executed before / after each test correspondingly, even if the test fails.
+
+Methods with names starting with `solo_test_` are run using the `solo_test()` function.
+
+Methods with names starting with `fail_` are expected to fail.
+
+Methods with names starting with `solo_fail_` are run using the `solo_test()` function
+and expected to fail.
+
+Method returning `Future` class instances are asynchronous, so `tearDown()` is
+executed after the returned `Future` completes.
+
+## Features and bugs
+
+Please file feature requests and bugs at the [issue tracker][tracker].
+
+[tracker]: https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Atest_reflective_loader
diff --git a/pkgs/test_reflective_loader/analysis_options.yaml b/pkgs/test_reflective_loader/analysis_options.yaml
new file mode 100644
index 0000000..ea61158
--- /dev/null
+++ b/pkgs/test_reflective_loader/analysis_options.yaml
@@ -0,0 +1,5 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+linter:
+ rules:
+ - public_member_api_docs
diff --git a/pkgs/test_reflective_loader/lib/test_reflective_loader.dart b/pkgs/test_reflective_loader/lib/test_reflective_loader.dart
new file mode 100644
index 0000000..cb69bf3
--- /dev/null
+++ b/pkgs/test_reflective_loader/lib/test_reflective_loader.dart
@@ -0,0 +1,354 @@
+// Copyright (c) 2015, 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 'dart:mirrors';
+
+import 'package:test/test.dart' as test_package;
+
+/// A marker annotation used to annotate test methods which are expected to fail
+/// when asserts are enabled.
+const Object assertFailingTest = _AssertFailingTest();
+
+/// A marker annotation used to annotate test methods which are expected to
+/// fail.
+const Object failingTest = FailingTest();
+
+/// A marker annotation used to instruct dart2js to keep reflection information
+/// for the annotated classes.
+const Object reflectiveTest = _ReflectiveTest();
+
+/// A marker annotation used to annotate test methods that should be skipped.
+const Object skippedTest = SkippedTest();
+
+/// A marker annotation used to annotate "solo" groups and tests.
+const Object soloTest = _SoloTest();
+
+final List<_Group> _currentGroups = <_Group>[];
+int _currentSuiteLevel = 0;
+String _currentSuiteName = '';
+
+/// Is `true` the application is running in the checked mode.
+final bool _isCheckedMode = () {
+ try {
+ assert(false);
+ return false;
+ } catch (_) {
+ return true;
+ }
+}();
+
+/// Run the [define] function parameter that calls [defineReflectiveTests] to
+/// add normal and "solo" tests, and also calls [defineReflectiveSuite] to
+/// create embedded suites. If the current suite is the top-level one, perform
+/// check for "solo" groups and tests, and run all or only "solo" items.
+void defineReflectiveSuite(void Function() define, {String name = ''}) {
+ var groupName = _currentSuiteName;
+ _currentSuiteLevel++;
+ try {
+ _currentSuiteName = _combineNames(_currentSuiteName, name);
+ define();
+ } finally {
+ _currentSuiteName = groupName;
+ _currentSuiteLevel--;
+ }
+ _addTestsIfTopLevelSuite();
+}
+
+/// Runs test methods existing in the given [type].
+///
+/// If there is a "solo" test method in the top-level suite, only "solo" methods
+/// are run.
+///
+/// If there is a "solo" test type, only its test methods are run.
+///
+/// Otherwise all tests methods of all test types are run.
+///
+/// Each method is run with a new instance of [type].
+/// So, [type] should have a default constructor.
+///
+/// If [type] declares method `setUp`, it methods will be invoked before any
+/// test method invocation.
+///
+/// If [type] declares method `tearDown`, it will be invoked after any test
+/// method invocation. If method returns [Future] to test some asynchronous
+/// behavior, then `tearDown` will be invoked in `Future.complete`.
+void defineReflectiveTests(Type type) {
+ var classMirror = reflectClass(type);
+ if (!classMirror.metadata.any((InstanceMirror annotation) =>
+ annotation.type.reflectedType == _ReflectiveTest)) {
+ var name = MirrorSystem.getName(classMirror.qualifiedName);
+ throw Exception('Class $name must have annotation "@reflectiveTest" '
+ 'in order to be run by runReflectiveTests.');
+ }
+
+ _Group group;
+ {
+ var isSolo = _hasAnnotationInstance(classMirror, soloTest);
+ var className = MirrorSystem.getName(classMirror.simpleName);
+ group = _Group(isSolo, _combineNames(_currentSuiteName, className));
+ _currentGroups.add(group);
+ }
+
+ classMirror.instanceMembers
+ .forEach((Symbol symbol, MethodMirror memberMirror) {
+ // we need only methods
+ if (!memberMirror.isRegularMethod) {
+ return;
+ }
+ // prepare information about the method
+ var memberName = MirrorSystem.getName(symbol);
+ var isSolo = memberName.startsWith('solo_') ||
+ _hasAnnotationInstance(memberMirror, soloTest);
+ // test_
+ if (memberName.startsWith('test_')) {
+ if (_hasSkippedTestAnnotation(memberMirror)) {
+ group.addSkippedTest(memberName);
+ } else {
+ group.addTest(isSolo, memberName, memberMirror, () {
+ if (_hasFailingTestAnnotation(memberMirror) ||
+ _isCheckedMode && _hasAssertFailingTestAnnotation(memberMirror)) {
+ return _runFailingTest(classMirror, symbol);
+ } else {
+ return _runTest(classMirror, symbol);
+ }
+ });
+ }
+ return;
+ }
+ // solo_test_
+ if (memberName.startsWith('solo_test_')) {
+ group.addTest(true, memberName, memberMirror, () {
+ return _runTest(classMirror, symbol);
+ });
+ }
+ // fail_test_
+ if (memberName.startsWith('fail_')) {
+ group.addTest(isSolo, memberName, memberMirror, () {
+ return _runFailingTest(classMirror, symbol);
+ });
+ }
+ // solo_fail_test_
+ if (memberName.startsWith('solo_fail_')) {
+ group.addTest(true, memberName, memberMirror, () {
+ return _runFailingTest(classMirror, symbol);
+ });
+ }
+ // skip_test_
+ if (memberName.startsWith('skip_test_')) {
+ group.addSkippedTest(memberName);
+ }
+ });
+
+ // Support for the case of missing enclosing [defineReflectiveSuite].
+ _addTestsIfTopLevelSuite();
+}
+
+/// If the current suite is the top-level one, add tests to the `test` package.
+void _addTestsIfTopLevelSuite() {
+ if (_currentSuiteLevel == 0) {
+ void runTests({required bool allGroups, required bool allTests}) {
+ for (var group in _currentGroups) {
+ if (allGroups || group.isSolo) {
+ for (var test in group.tests) {
+ if (allTests || test.isSolo) {
+ test_package.test(test.name, test.function,
+ timeout: test.timeout, skip: test.isSkipped);
+ }
+ }
+ }
+ }
+ }
+
+ if (_currentGroups.any((g) => g.hasSoloTest)) {
+ runTests(allGroups: true, allTests: false);
+ } else if (_currentGroups.any((g) => g.isSolo)) {
+ runTests(allGroups: false, allTests: true);
+ } else {
+ runTests(allGroups: true, allTests: true);
+ }
+ _currentGroups.clear();
+ }
+}
+
+/// Return the combination of the [base] and [addition] names.
+/// If any other two is `null`, then the other one is returned.
+String _combineNames(String base, String addition) {
+ if (base.isEmpty) {
+ return addition;
+ } else if (addition.isEmpty) {
+ return base;
+ } else {
+ return '$base | $addition';
+ }
+}
+
+Object? _getAnnotationInstance(DeclarationMirror declaration, Type type) {
+ for (var annotation in declaration.metadata) {
+ if ((annotation.reflectee as Object).runtimeType == type) {
+ return annotation.reflectee;
+ }
+ }
+ return null;
+}
+
+bool _hasAnnotationInstance(DeclarationMirror declaration, Object instance) =>
+ declaration.metadata.any((InstanceMirror annotation) =>
+ identical(annotation.reflectee, instance));
+
+bool _hasAssertFailingTestAnnotation(MethodMirror method) =>
+ _hasAnnotationInstance(method, assertFailingTest);
+
+bool _hasFailingTestAnnotation(MethodMirror method) =>
+ _hasAnnotationInstance(method, failingTest);
+
+bool _hasSkippedTestAnnotation(MethodMirror method) =>
+ _hasAnnotationInstance(method, skippedTest);
+
+Future<Object?> _invokeSymbolIfExists(
+ InstanceMirror instanceMirror, Symbol symbol) {
+ Object? invocationResult;
+ InstanceMirror? closure;
+ try {
+ closure = instanceMirror.getField(symbol);
+ // ignore: avoid_catching_errors
+ } on NoSuchMethodError {
+ // ignore
+ }
+
+ if (closure is ClosureMirror) {
+ invocationResult = closure.apply([]).reflectee;
+ }
+ return Future.value(invocationResult);
+}
+
+/// Run a test that is expected to fail, and confirm that it fails.
+///
+/// This properly handles the following cases:
+/// - The test fails by throwing an exception
+/// - The test returns a future which completes with an error.
+/// - An exception is thrown to the zone handler from a timer task.
+Future<Object?>? _runFailingTest(ClassMirror classMirror, Symbol symbol) {
+ var passed = false;
+ return runZonedGuarded(() {
+ // ignore: void_checks
+ return Future.sync(() => _runTest(classMirror, symbol)).then<void>((_) {
+ passed = true;
+ test_package.fail('Test passed - expected to fail.');
+ }).catchError((Object e) {
+ // if passed, and we call fail(), rethrow this exception
+ if (passed) {
+ // ignore: only_throw_errors
+ throw e;
+ }
+ // otherwise, an exception is not a failure for _runFailingTest
+ });
+ }, (e, st) {
+ // if passed, and we call fail(), rethrow this exception
+ if (passed) {
+ // ignore: only_throw_errors
+ throw e;
+ }
+ // otherwise, an exception is not a failure for _runFailingTest
+ });
+}
+
+Future<void> _runTest(ClassMirror classMirror, Symbol symbol) async {
+ var instanceMirror = classMirror.newInstance(const Symbol(''), []);
+ try {
+ await _invokeSymbolIfExists(instanceMirror, #setUp);
+ await instanceMirror.invoke(symbol, []).reflectee;
+ } finally {
+ await _invokeSymbolIfExists(instanceMirror, #tearDown);
+ }
+}
+
+typedef _TestFunction = dynamic Function();
+
+/// A marker annotation used to annotate test methods which are expected to
+/// fail.
+class FailingTest {
+ /// Initialize this annotation with the given arguments.
+ ///
+ /// [issue] is a full URI describing the failure and used for tracking.
+ /// [reason] is a free form textual description.
+ const FailingTest({String? issue, String? reason});
+}
+
+/// A marker annotation used to annotate test methods which are skipped.
+class SkippedTest {
+ /// Initialize this annotation with the given arguments.
+ ///
+ /// [issue] is a full URI describing the failure and used for tracking.
+ /// [reason] is a free form textual description.
+ const SkippedTest({String? issue, String? reason});
+}
+
+/// A marker annotation used to annotate test methods with additional timeout
+/// information.
+class TestTimeout {
+ final test_package.Timeout _timeout;
+
+ /// Initialize this annotation with the given timeout.
+ const TestTimeout(test_package.Timeout timeout) : _timeout = timeout;
+}
+
+/// A marker annotation used to annotate test methods which are expected to fail
+/// when asserts are enabled.
+class _AssertFailingTest {
+ const _AssertFailingTest();
+}
+
+/// Information about a type based test group.
+class _Group {
+ final bool isSolo;
+ final String name;
+ final List<_Test> tests = <_Test>[];
+
+ _Group(this.isSolo, this.name);
+
+ bool get hasSoloTest => tests.any((test) => test.isSolo);
+
+ void addSkippedTest(String name) {
+ var fullName = _combineNames(this.name, name);
+ tests.add(_Test.skipped(isSolo, fullName));
+ }
+
+ void addTest(bool isSolo, String name, MethodMirror memberMirror,
+ _TestFunction function) {
+ var fullName = _combineNames(this.name, name);
+ var timeout =
+ _getAnnotationInstance(memberMirror, TestTimeout) as TestTimeout?;
+ tests.add(_Test(isSolo, fullName, function, timeout?._timeout));
+ }
+}
+
+/// A marker annotation used to instruct dart2js to keep reflection information
+/// for the annotated classes.
+class _ReflectiveTest {
+ const _ReflectiveTest();
+}
+
+/// A marker annotation used to annotate "solo" groups and tests.
+class _SoloTest {
+ const _SoloTest();
+}
+
+/// Information about a test.
+class _Test {
+ final bool isSolo;
+ final String name;
+ final _TestFunction function;
+ final test_package.Timeout? timeout;
+
+ final bool isSkipped;
+
+ _Test(this.isSolo, this.name, this.function, this.timeout)
+ : isSkipped = false;
+
+ _Test.skipped(this.isSolo, this.name)
+ : isSkipped = true,
+ function = (() {}),
+ timeout = null;
+}
diff --git a/pkgs/test_reflective_loader/pubspec.yaml b/pkgs/test_reflective_loader/pubspec.yaml
new file mode 100644
index 0000000..569933f
--- /dev/null
+++ b/pkgs/test_reflective_loader/pubspec.yaml
@@ -0,0 +1,13 @@
+name: test_reflective_loader
+version: 0.2.3
+description: Support for discovering tests and test suites using reflection.
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/test_reflective_loader
+
+environment:
+ sdk: ^3.1.0
+
+dependencies:
+ test: ^1.16.0
+
+dev_dependencies:
+ dart_flutter_team_lints: ^3.0.0
diff --git a/pkgs/test_reflective_loader/test/test_reflective_loader_test.dart b/pkgs/test_reflective_loader/test/test_reflective_loader_test.dart
new file mode 100644
index 0000000..fad98a5
--- /dev/null
+++ b/pkgs/test_reflective_loader/test/test_reflective_loader_test.dart
@@ -0,0 +1,48 @@
+// 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.
+
+// ignore_for_file: non_constant_identifier_names
+
+import 'dart:async';
+
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TestReflectiveLoaderTest);
+ });
+}
+
+@reflectiveTest
+class TestReflectiveLoaderTest {
+ void test_passes() {
+ expect(true, true);
+ }
+
+ @failingTest
+ void test_fails() {
+ expect(false, true);
+ }
+
+ @failingTest
+ void test_fails_throws_sync() {
+ throw StateError('foo');
+ }
+
+ @failingTest
+ Future test_fails_throws_async() {
+ return Future.error('foo');
+ }
+
+ @skippedTest
+ void test_fails_but_skipped() {
+ throw StateError('foo');
+ }
+
+ @skippedTest
+ void test_times_out_but_skipped() {
+ while (true) {}
+ }
+}
diff --git a/pkgs/timing/.gitignore b/pkgs/timing/.gitignore
new file mode 100644
index 0000000..1ddf798
--- /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 0000000..8cdb8ea
--- /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 0000000..9972f6e
--- /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 0000000..9dab7cc
--- /dev/null
+++ b/pkgs/timing/README.md
@@ -0,0 +1,30 @@
+[](https://github.com/dart-lang/tools/actions/workflows/timing.yaml)
+[](https://pub.dev/packages/timing)
+[](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 0000000..396236d
--- /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 0000000..6a9d295
--- /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<T>(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 0000000..049ba81
--- /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<String, dynamic> json) =>
+ _$TimeSliceFromJson(json);
+
+ Map<String, dynamic> 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<TimeSlice> 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<String, dynamic> json) =>
+ _$TimeSliceGroupFromJson(json);
+
+ @override
+ Map<String, dynamic> 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>(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>(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<String, dynamic> 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>(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>(T Function() action) => action();
+
+ @override
+ Map<String, dynamic> 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<T>(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: <R>(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: <R, T>(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: <R, T1, T2>(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>(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 0000000..679c082
--- /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<String, dynamic> json) => TimeSlice(
+ DateTime.parse(json['startTime'] as String),
+ DateTime.parse(json['stopTime'] as String),
+ );
+
+Map<String, dynamic> _$TimeSliceToJson(TimeSlice instance) => <String, dynamic>{
+ 'startTime': instance.startTime.toIso8601String(),
+ 'stopTime': instance.stopTime.toIso8601String(),
+ };
+
+TimeSliceGroup _$TimeSliceGroupFromJson(Map<String, dynamic> json) =>
+ TimeSliceGroup(
+ (json['slices'] as List<dynamic>)
+ .map((e) => TimeSlice.fromJson(e as Map<String, dynamic>))
+ .toList(),
+ );
+
+Map<String, dynamic> _$TimeSliceGroupToJson(TimeSliceGroup instance) =>
+ <String, dynamic>{
+ 'slices': instance.slices,
+ };
diff --git a/pkgs/timing/lib/timing.dart b/pkgs/timing/lib/timing.dart
new file mode 100644
index 0000000..5cb16d4
--- /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 0000000..891a8af
--- /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 0000000..b5836d9
--- /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>(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<String>()));
+ 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<String>()));
+ 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));
+ });
+ });
+}