Add dummy values for `RegExp` and `MapEntry`.
Avoids generating mocks for `RegExp` and `MapEntry`.
Both are value types and shouldn't be mocked.
`RegExp` will eventually become non-mockable, `MapEntry` already is.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 51bfd2a..4bb43c3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 5.6.0
+
+* Add dummy values for `RegExp` and `MapEntry`.
+
## 5.5.1
* Require `analyzer: ^8.1.0`.
diff --git a/lib/src/builder.dart b/lib/src/builder.dart
index 039e0a6..42b295f 100644
--- a/lib/src/builder.dart
+++ b/lib/src/builder.dart
@@ -1758,7 +1758,7 @@
} else if (type.isDartTypedDataSealed) {
// These types (XXXList + ByteData) from dart:typed_data are
// sealed, e.g. "non-subtypeable", but they
- // have predicatble constructors; each has an unnamed constructor which
+ // have predictable constructors; each has an unnamed constructor which
// takes a single int argument.
return referImported(
type.element.name!,
@@ -1766,6 +1766,26 @@
).call([literalNum(0)]);
// TODO(srawlins): Do other types from typed_data have a "non-subtypeable"
// restriction as well?
+ } else if (type.element.library.isDartCore) {
+ if (type.element.name == 'RegExp') {
+ return referImported('RegExp', 'dart:core').call([literalString('')]);
+ }
+ if (type.element.name == 'MapEntry') {
+ assert(typeArguments.length == 2);
+ final keyType = typeArguments[0];
+ final valueType = typeArguments[1];
+ return TypeReference((b) {
+ b
+ ..symbol = 'MapEntry'
+ ..url = 'dart:core';
+ b.types
+ ..add(_typeReference(keyType))
+ ..add(_typeReference(valueType));
+ }).call([
+ _dummyValue(keyType, invocation),
+ _dummyValue(valueType, invocation),
+ ]);
+ }
}
// This class is unknown; we must likely generate a fake class, and return
diff --git a/lib/src/dummies.dart b/lib/src/dummies.dart
index b9cfa83..40f9807 100644
--- a/lib/src/dummies.dart
+++ b/lib/src/dummies.dart
@@ -123,6 +123,7 @@
Float32List: (_, _) => Float32List(0),
Float64List: (_, _) => Float64List(0),
ByteData: (_, _) => ByteData(0),
+ RegExp: (_, _) => RegExp(''),
...platformDummies,
};
diff --git a/pubspec.yaml b/pubspec.yaml
index 1dc1711..3e9c62d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: mockito
-version: 5.5.1
+version: 5.6.0
description: >-
A mock framework inspired by Mockito with APIs for Fakes, Mocks,
behavior verification, and stubbing.
diff --git a/test/builder/auto_mocks_test.dart b/test/builder/auto_mocks_test.dart
index cca678a..4824180 100644
--- a/test/builder/auto_mocks_test.dart
+++ b/test/builder/auto_mocks_test.dart
@@ -2690,14 +2690,27 @@
},
);
- test('creates dummy non-null Stream return value', () async {
+ test('creates dummy non-null RegExp return value', () async {
await expectSingleNonNullableOutput(
dedent(r'''
abstract class Foo {
- Stream<int> m();
+ RegExp m();
}
'''),
- _containsAllOf('returnValue: _i3.Stream<int>.empty()'),
+ _containsAllOf("returnValue: RegExp('')"),
+ );
+ });
+
+ test('creates dummy non-null MapEntry<int, String> return value', () async {
+ await expectSingleNonNullableOutput(
+ dedent(r'''
+ abstract class Foo {
+ MapEntry<int, String> m();
+ }
+ '''),
+ _containsAllOf(
+ 'returnValue: MapEntry<int, String>(0, _i3.dummyValue<String>(',
+ ),
);
});
@@ -4340,23 +4353,20 @@
/// Dedent [input], so that each line is shifted to the left, so that the first
/// line is at the 0 column.
String dedent(String input) {
- final indentMatch = RegExp(r'^(\s*)').firstMatch(input)!;
- final indent = ''.padRight(indentMatch.group(1)!.length);
- return input.splitMapJoin(
- '\n',
- onNonMatch: (s) => s.replaceFirst(RegExp('^$indent'), ''),
- );
+ final indentMatch = RegExp(r'^\s*').firstMatch(input)!;
+ if (indentMatch.end == 0) return input;
+ final indent = indentMatch[0]!;
+ return input.replaceAll(RegExp('^$indent', multiLine: true), '');
}
/// Dedent [input], so that each line is shifted to the left, so that the first
/// line is at column 2 (starting position for a class member).
String dedent2(String input) {
- final indentMatch = RegExp(r'^ (\s*)').firstMatch(input)!;
- final indent = ''.padRight(indentMatch.group(1)!.length);
- return input
- .replaceFirst(RegExp(r'\s*$'), '')
- .splitMapJoin(
- '\n',
- onNonMatch: (s) => s.replaceFirst(RegExp('^$indent'), ''),
- );
+ final indentMatch = RegExp(r'^\s{2,}').firstMatch(input)!;
+ if (indentMatch.end == 0) return input;
+ final indent = indentMatch[0];
+ return input.trimRight().replaceAll(
+ RegExp('^$indent', multiLine: true),
+ ' ',
+ );
}
diff --git a/test/builder/contains_ignoring_formatting.dart b/test/builder/contains_ignoring_formatting.dart
index d2c46d0..4b6baf6 100644
--- a/test/builder/contains_ignoring_formatting.dart
+++ b/test/builder/contains_ignoring_formatting.dart
@@ -23,11 +23,12 @@
/// Matches a string that contains a given string, ignoring differences related
/// to formatting: whitespace and trailing commas.
class _ContainsIgnoringFormattingMatcher extends Matcher {
- /// Matches one or more whitespace characters.
- static final _whitespacePattern = RegExp(r'\s+');
-
- /// Matches a trailing comma preceding a closing bracket character.
- static final _trailingCommaPattern = RegExp(r',\s*([)}\]])');
+ /// Matches one or more whitespace characters, or a trailing comma.
+ ///
+ /// A trailing comma is one followed by a closing bracket of some kind.
+ static final _whitespaceOrTrailingCommaPattern = RegExp(
+ r'\s+|,\s*(?=[)}\]])',
+ );
/// The string that the actual value must contain in order for the match to
/// succeed.
@@ -49,13 +50,10 @@
/// Removes whitespace and trailing commas.
///
/// Note that the result is not valid code because it means adjacent
- ///.identifiers and operators may be joined in ways that break the semantics.
+ /// identifiers and operators may be joined in ways that break the semantics.
/// The goal is not to produce an but valid version of the code, just to
/// produce a string that will reliably match the actual string when it has
/// also been stripped the same way.
String _stripFormatting(String code) =>
- code
- .replaceAll(_whitespacePattern, '')
- .replaceAllMapped(_trailingCommaPattern, (match) => match[1]!)
- .trim();
+ code.replaceAll(_whitespaceOrTrailingCommaPattern, '');
}
diff --git a/test/builder/custom_mocks_test.dart b/test/builder/custom_mocks_test.dart
index 57f40e2..59ae669 100644
--- a/test/builder/custom_mocks_test.dart
+++ b/test/builder/custom_mocks_test.dart
@@ -1846,10 +1846,8 @@
/// Dedent [input], so that each line is shifted to the left, so that the first
/// line is at the 0 column.
String dedent(String input) {
- final indentMatch = RegExp(r'^(\s*)').firstMatch(input)!;
- final indent = ''.padRight(indentMatch.group(1)!.length);
- return input.splitMapJoin(
- '\n',
- onNonMatch: (s) => s.replaceFirst(RegExp('^$indent'), ''),
- );
+ final indentMatch = RegExp(r'^\s*').firstMatch(input)!;
+ if (indentMatch.end == 0) return input;
+ final indent = indentMatch[0]!;
+ return input.replaceAll(RegExp('^$indent', multiLine: true), '');
}
diff --git a/test/invocation_matcher_test.dart b/test/invocation_matcher_test.dart
index 4db3de7..259c2b6 100644
--- a/test/invocation_matcher_test.dart
+++ b/test/invocation_matcher_test.dart
@@ -175,7 +175,7 @@
final matcher =
expected is String
? equalsIgnoringWhitespace(expected)
- : expected is RegExp
+ : expected is Pattern
? contains(expected)
: expected;
expect(collapseWhitespace(e.message!), matcher, reason: reason);
diff --git a/test/verify_test.dart b/test/verify_test.dart
index ca3b4c6..75501ef 100644
--- a/test/verify_test.dart
+++ b/test/verify_test.dart
@@ -180,12 +180,12 @@
test('should mock setter', () {
mock.setter = 'A';
- final expectedMessage = RegExp.escape(
- 'No matching calls. '
- 'All calls: _MockedClass.setter==\'A\'\n$noMatchingCallsFooter',
- );
+ final expectedMessagePattern =
+ 'No matching calls. '
+ "All calls: _MockedClass\\.setter=?='A'\n"
+ '${RegExp.escape(noMatchingCallsFooter)}';
// RegExp needed because of https://github.com/dart-lang/sdk/issues/33565
- final expectedPattern = RegExp(expectedMessage.replaceFirst('==', '=?='));
+ final expectedPattern = RegExp(expectedMessagePattern);
expectFail(expectedPattern, () => verify(mock.setter = 'B'));
verify(mock.setter = 'A');