Skip to content

Commit

Permalink
Migrate many custom matchers to TypeMatcher (#1668)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevmoo authored Dec 12, 2024
1 parent ea2419f commit 42effa6
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?.errorCode,
'osError.errorCode', _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<FileSystemEntity> 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 42effa6

Please sign in to comment.