blob: fb8a0b2d2e1de632371822046a97d56ebd1f4a7b [file] [log] [blame]
// 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 'custom_matcher.dart';
import 'interfaces.dart';
import 'type_matcher.dart';
import 'util.dart';
/// A package-private [TypeMatcher] implementation that handles is returned
/// by calls to [TypeMatcher.having].
class HavingMatcher<T> implements TypeMatcher<T> {
final TypeMatcher<T> _parent;
final List<_FunctionMatcher<T>> _functionMatchers;
HavingMatcher(TypeMatcher<T> parent, String description,
Object? Function(T) feature, dynamic matcher,
[Iterable<_FunctionMatcher<T>>? existing])
: _parent = parent,
_functionMatchers = [
_FunctionMatcher<T>(description, feature, matcher)
TypeMatcher<T> having(
Object? Function(T) feature, String description, dynamic matcher) =>
HavingMatcher(_parent, description, feature, matcher, _functionMatchers);
bool matches(item, Map matchState) {
for (var matcher in <Matcher>[_parent].followedBy(_functionMatchers)) {
if (!matcher.matches(item, matchState)) {
addStateInfo(matchState, {'matcher': matcher});
return false;
return true;
Description describeMismatch(
item, Description mismatchDescription, Map matchState, bool verbose) {
var matcher = matchState['matcher'] as Matcher;
item, mismatchDescription, matchState['state'] as Map, verbose);
return mismatchDescription;
Description describe(Description description) => description
.add(' with ')
.addAll('', ' and ', '', _functionMatchers);
class _FunctionMatcher<T> extends CustomMatcher {
final dynamic Function(T value) _feature;
_FunctionMatcher(String name, this._feature, matcher)
: super('`$name`:', '`$name`', matcher);
Object? featureValueOf(covariant T actual) => _feature(actual);