Skip to content

Commit

Permalink
Use dynamic methods for map matchers (#2415)
Browse files Browse the repository at this point in the history
Allow using `containsKey` and `containsValue` on non-map types like
built collection maps which do not implement the core `Map` but has the
required methods and operators.
  • Loading branch information
natebosch authored Nov 1, 2024
1 parent 40e1f91 commit 8a07bee
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions pkgs/matcher/lib/src/map_matchers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +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 'feature_matcher.dart';
import 'interfaces.dart';
import 'util.dart';

/// Returns a matcher which matches maps containing the given [value].
Matcher containsValue(Object? value) => _ContainsValue(value);

class _ContainsValue extends FeatureMatcher<Map> {
class _ContainsValue extends Matcher {
final Object? _value;

const _ContainsValue(this._value);

@override
bool typedMatches(Map item, Map matchState) => item.containsValue(_value);
bool matches(Object? item, Map matchState) =>
// ignore: avoid_dynamic_calls
(item as dynamic).containsValue(_value);
@override
Description describe(Description description) =>
description.add('contains value ').addDescriptionOf(_value);
Expand All @@ -26,15 +27,17 @@ class _ContainsValue extends FeatureMatcher<Map> {
Matcher containsPair(Object? key, Object? valueOrMatcher) =>
_ContainsMapping(key, wrapMatcher(valueOrMatcher));

class _ContainsMapping extends FeatureMatcher<Map> {
class _ContainsMapping extends Matcher {
final Object? _key;
final Matcher _valueMatcher;

const _ContainsMapping(this._key, this._valueMatcher);

@override
bool typedMatches(Map item, Map matchState) =>
item.containsKey(_key) && _valueMatcher.matches(item[_key], matchState);
bool matches(Object? item, Map matchState) =>
// ignore: avoid_dynamic_calls
(item as dynamic).containsKey(_key) &&
_valueMatcher.matches((item as dynamic)[_key], matchState);

@override
Description describe(Description description) {
Expand All @@ -46,9 +49,10 @@ class _ContainsMapping extends FeatureMatcher<Map> {
}

@override
Description describeTypedMismatch(
Map item, Description mismatchDescription, Map matchState, bool verbose) {
if (!item.containsKey(_key)) {
Description describeMismatch(Object? item, Description mismatchDescription,
Map matchState, bool verbose) {
// ignore: avoid_dynamic_calls
if (!((item as dynamic).containsKey(_key) as bool)) {
return mismatchDescription
.add(" doesn't contain key ")
.addDescriptionOf(_key);
Expand All @@ -58,7 +62,7 @@ class _ContainsMapping extends FeatureMatcher<Map> {
.addDescriptionOf(_key)
.add(' but with value ');
_valueMatcher.describeMismatch(
item[_key], mismatchDescription, matchState, verbose);
(item as dynamic)[_key], mismatchDescription, matchState, verbose);
return mismatchDescription;
}
}
Expand Down

0 comments on commit 8a07bee

Please sign in to comment.