Skip to content

Commit

Permalink
Migrate many custom matchers to TypeMatcher
Browse files Browse the repository at this point in the history
And change the public signature to allow better reuse
  • Loading branch information
kevmoo committed Dec 11, 2024
1 parent 5590447 commit fe8a384
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 101 deletions.
4 changes: 4 additions & 0 deletions pkgs/file/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ dev_dependencies:
file_testing: ^3.0.0
lints: ^2.0.1
test: ^1.23.1

dependency_overrides:
file_testing:
path: ../file_testing
5 changes: 5 additions & 0 deletions pkgs/file_testing/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
7 changes: 1 addition & 6 deletions pkgs/file_testing/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -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
109 changes: 17 additions & 92 deletions pkgs/file_testing/lib/src/testing/core_matchers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,36 @@
// 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';

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].
Expand All @@ -39,7 +42,8 @@ Matcher hasPath(dynamic path) => _HasPath(path);
/// [osErrorCode] may be an `int`, a predicate function, or a [Matcher]. If it
/// is an `int`, it will be wrapped in an equality matcher.
Matcher isFileSystemException([dynamic osErrorCode]) =>
_FileSystemException(osErrorCode);
const TypeMatcher<FileSystemException>().having(
(e) => e.osError, 'orError', _fileExceptionWrapMatcher(osErrorCode));

/// Returns a matcher that successfully matches against a future or function
/// that throws a [FileSystemException].
Expand Down Expand Up @@ -67,89 +71,10 @@ void expectFileSystemException(dynamic osErrorCode, void Function() callback) {

/// Matcher that successfully matches against a [FileSystemEntity] that
/// exists ([FileSystemEntity.existsSync] returns true).
const Matcher exists = _Exists();

class _FileSystemException extends Matcher {
_FileSystemException(dynamic osErrorCode)
: _matcher = _wrapMatcher(osErrorCode);

final Matcher? _matcher;

static Matcher? _wrapMatcher(dynamic osErrorCode) {
if (osErrorCode == null) {
return null;
}
return ignoreOsErrorCodes ? anything : wrapMatcher(osErrorCode);
}

@override
bool matches(dynamic item, Map<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;
final TypeMatcher exists =
isFileSystemEntity.having((e) => e.existsSync(), 'existsSync', true);

@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);
6 changes: 3 additions & 3 deletions pkgs/file_testing/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -10,5 +10,5 @@ environment:
dependencies:
test: ^1.23.1

dev_dependencies:
lints: ^5.0.0
dev_dependencies:
dart_flutter_team_lints: ^3.0.0

0 comments on commit fe8a384

Please sign in to comment.