Skip to content
This repository was archived by the owner on Oct 22, 2024. It is now read-only.

Commit 4ff649f

Browse files
committed
feature: Add a type argument to TypeMatcher and make it non-abstract
Eliminates 13 implementations Deprecate the existing `name` parameter - tell folks to use the type arg Deprecate isInstanceOf class. Tell folks to use TypeMatcher<T> instead Removed isInstanceOf tests from core_matchers_test centralizing tests in type_matcher_test
1 parent 37acc6f commit 4ff649f

7 files changed

+62
-128
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## 0.12.3
2+
3+
- Added a type parameter to `TypeMatcher` and make it non-abstract.
4+
- Can now be used directly as `const TypeMatcher<MyType>()`.
5+
- Deprecated the `name` constructor argument. It's redundant to the type
6+
parameter.
7+
8+
- Deprecated the `isInstanceOf` class. Use `TypeMatcher` instead.
9+
110
## 0.12.2+1
211

312
- Updated SDK version to 2.0.0-dev.17.0

lib/matcher.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ export 'src/numeric_matchers.dart';
1515
export 'src/operator_matchers.dart';
1616
export 'src/order_matchers.dart';
1717
export 'src/string_matchers.dart';
18+
export 'src/type_matcher.dart';
1819
export 'src/util.dart';

lib/src/core_matchers.dart

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'interfaces.dart';
6+
import 'type_matcher.dart';
67
import 'util.dart';
78

89
/// Returns a matcher that matches the isEmpty property.
@@ -113,14 +114,10 @@ class _IsAnything extends Matcher {
113114
/// 'Foo', we would write:
114115
///
115116
/// expect(bar, new isInstanceOf<Foo>());
117+
@Deprecated('Use `const TypeMatcher<MyType>()` instead.')
116118
// ignore: camel_case_types
117-
class isInstanceOf<T> extends Matcher {
119+
class isInstanceOf<T> extends TypeMatcher<T> {
118120
const isInstanceOf();
119-
120-
bool matches(item, Map matchState) => item is T;
121-
122-
Description describe(Description description) =>
123-
description.add('an instance of $T');
124121
}
125122

126123
/// A matcher that matches a function call against no exception.
@@ -157,48 +154,11 @@ class _ReturnsNormally extends Matcher {
157154
}
158155
}
159156

160-
/*
161-
* Matchers for different exception types. Ideally we should just be able to
162-
* use something like:
163-
*
164-
* final Matcher throwsException =
165-
* const _Throws(const isInstanceOf<Exception>());
166-
*
167-
* Unfortunately instanceOf is not working with dart2js.
168-
*
169-
* Alternatively, if static functions could be used in const expressions,
170-
* we could use:
171-
*
172-
* bool _isException(x) => x is Exception;
173-
* final Matcher isException = const _Predicate(_isException, "Exception");
174-
* final Matcher throwsException = const _Throws(isException);
175-
*
176-
* But currently using static functions in const expressions is not supported.
177-
* For now the only solution for all platforms seems to be separate classes
178-
* for each exception type.
179-
*/
180-
181-
abstract class TypeMatcher extends Matcher {
182-
final String _name;
183-
const TypeMatcher(this._name);
184-
Description describe(Description description) => description.add(_name);
185-
}
186-
187157
/// A matcher for Map types.
188-
const Matcher isMap = const _IsMap();
189-
190-
class _IsMap extends TypeMatcher {
191-
const _IsMap() : super("Map");
192-
bool matches(item, Map matchState) => item is Map;
193-
}
158+
const Matcher isMap = const TypeMatcher<Map>();
194159

195160
/// A matcher for List types.
196-
const Matcher isList = const _IsList();
197-
198-
class _IsList extends TypeMatcher {
199-
const _IsList() : super('List');
200-
bool matches(item, Map matchState) => item is List;
201-
}
161+
const Matcher isList = const TypeMatcher<List>();
202162

203163
/// Returns a matcher that matches if an object has a length property
204164
/// that matches [matcher].

lib/src/error_matchers.dart

Lines changed: 13 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,94 +2,40 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'core_matchers.dart';
65
import 'interfaces.dart';
6+
import 'type_matcher.dart';
77

88
/// A matcher for ArgumentErrors.
9-
const Matcher isArgumentError = const _ArgumentError();
10-
11-
class _ArgumentError extends TypeMatcher {
12-
const _ArgumentError() : super("ArgumentError");
13-
bool matches(item, Map matchState) => item is ArgumentError;
14-
}
9+
const Matcher isArgumentError = const TypeMatcher<ArgumentError>();
1510

1611
/// A matcher for ConcurrentModificationError.
1712
const Matcher isConcurrentModificationError =
18-
const _ConcurrentModificationError();
19-
20-
class _ConcurrentModificationError extends TypeMatcher {
21-
const _ConcurrentModificationError() : super("ConcurrentModificationError");
22-
bool matches(item, Map matchState) => item is ConcurrentModificationError;
23-
}
13+
const TypeMatcher<ConcurrentModificationError>();
2414

2515
/// A matcher for CyclicInitializationError.
26-
const Matcher isCyclicInitializationError = const _CyclicInitializationError();
27-
28-
class _CyclicInitializationError extends TypeMatcher {
29-
const _CyclicInitializationError() : super("CyclicInitializationError");
30-
bool matches(item, Map matchState) => item is CyclicInitializationError;
31-
}
16+
const Matcher isCyclicInitializationError =
17+
const TypeMatcher<CyclicInitializationError>();
3218

3319
/// A matcher for Exceptions.
34-
const Matcher isException = const _Exception();
35-
36-
class _Exception extends TypeMatcher {
37-
const _Exception() : super("Exception");
38-
bool matches(item, Map matchState) => item is Exception;
39-
}
20+
const Matcher isException = const TypeMatcher<Exception>();
4021

4122
/// A matcher for FormatExceptions.
42-
const Matcher isFormatException = const _FormatException();
43-
44-
class _FormatException extends TypeMatcher {
45-
const _FormatException() : super("FormatException");
46-
bool matches(item, Map matchState) => item is FormatException;
47-
}
23+
const Matcher isFormatException = const TypeMatcher<FormatException>();
4824

4925
/// A matcher for NoSuchMethodErrors.
50-
const Matcher isNoSuchMethodError = const _NoSuchMethodError();
51-
52-
class _NoSuchMethodError extends TypeMatcher {
53-
const _NoSuchMethodError() : super("NoSuchMethodError");
54-
bool matches(item, Map matchState) => item is NoSuchMethodError;
55-
}
26+
const Matcher isNoSuchMethodError = const TypeMatcher<NoSuchMethodError>();
5627

5728
/// A matcher for NullThrownError.
58-
const Matcher isNullThrownError = const _NullThrownError();
59-
60-
class _NullThrownError extends TypeMatcher {
61-
const _NullThrownError() : super("NullThrownError");
62-
bool matches(item, Map matchState) => item is NullThrownError;
63-
}
29+
const Matcher isNullThrownError = const TypeMatcher<NullThrownError>();
6430

6531
/// A matcher for RangeErrors.
66-
const Matcher isRangeError = const _RangeError();
67-
68-
class _RangeError extends TypeMatcher {
69-
const _RangeError() : super("RangeError");
70-
bool matches(item, Map matchState) => item is RangeError;
71-
}
32+
const Matcher isRangeError = const TypeMatcher<RangeError>();
7233

7334
/// A matcher for StateErrors.
74-
const Matcher isStateError = const _StateError();
75-
76-
class _StateError extends TypeMatcher {
77-
const _StateError() : super("StateError");
78-
bool matches(item, Map matchState) => item is StateError;
79-
}
35+
const Matcher isStateError = const TypeMatcher<StateError>();
8036

8137
/// A matcher for UnimplementedErrors.
82-
const Matcher isUnimplementedError = const _UnimplementedError();
83-
84-
class _UnimplementedError extends TypeMatcher {
85-
const _UnimplementedError() : super("UnimplementedError");
86-
bool matches(item, Map matchState) => item is UnimplementedError;
87-
}
38+
const Matcher isUnimplementedError = const TypeMatcher<UnimplementedError>();
8839

8940
/// A matcher for UnsupportedError.
90-
const Matcher isUnsupportedError = const _UnsupportedError();
91-
92-
class _UnsupportedError extends TypeMatcher {
93-
const _UnsupportedError() : super("UnsupportedError");
94-
bool matches(item, Map matchState) => item is UnsupportedError;
95-
}
41+
const Matcher isUnsupportedError = const TypeMatcher<UnsupportedError>();

lib/src/type_matcher.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'interfaces.dart';
6+
7+
class TypeMatcher<T> extends Matcher {
8+
final String _name;
9+
const TypeMatcher(
10+
[@Deprecated('Provide a type argument to TypeMatcher and omit the name. '
11+
'This argument will be removed in the next release.')
12+
String name])
13+
: this._name =
14+
// ignore: deprecated_member_use
15+
name;
16+
17+
Description describe(Description description) {
18+
if (_name == null) {
19+
return description.addDescriptionOf(T);
20+
} else {
21+
return description.add('instance of `$_name`');
22+
}
23+
}
24+
25+
bool matches(item, Map matchState) => item is T;
26+
}

test/core_matchers_test.dart

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,6 @@ void main() {
228228
shouldFail(actual3, equals(expected3), reason3);
229229
});
230230

231-
test('isInstanceOf', () {
232-
shouldFail(0, const isInstanceOf<String>(),
233-
"Expected: an instance of String Actual: <0>");
234-
shouldPass('cow', const isInstanceOf<String>());
235-
});
236-
237231
group('Predicate Matchers', () {
238232
test('isInstanceOf', () {
239233
shouldFail(0, predicate((x) => x is String, "an instance of String"),

test/type_matcher_test.dart

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ void main() {
2626
_test('NullThrownError', isNullThrownError, new NullThrownError());
2727

2828
group('custom `TypeMatcher`', () {
29+
// ignore: deprecated_member_use
2930
_test('String', const isInstanceOf<String>(), 'hello');
3031
_test('String', const _StringMatcher(), 'hello');
32+
_test('String', const TypeMatcher<String>(), 'hello');
3133
});
3234
}
3335

@@ -41,21 +43,17 @@ void _test(String name, Matcher typeMatcher, Object matchingType) {
4143
}
4244

4345
test('fails', () {
44-
shouldFail(
45-
const _TestType(),
46-
typeMatcher,
47-
anyOf(
48-
// Handles the TypeMatcher case
49-
equalsIgnoringWhitespace('Expected: $name Actual: ?:<TestType>'),
50-
// Handles the `isInstanceOf` case
51-
equalsIgnoringWhitespace(
52-
'Expected: an instance of $name Actual: ?:<TestType>')));
46+
shouldFail(const _TestType(), typeMatcher,
47+
'Expected: instance of `$name` Actual: ?:<TestType>');
5348
});
5449
});
5550
}
5651

52+
// Validate that existing implementations continue to work.
5753
class _StringMatcher extends TypeMatcher {
58-
const _StringMatcher() : super('String');
54+
const _StringMatcher() : super(
55+
// ignore: deprecated_member_use
56+
'String');
5957

6058
bool matches(item, Map matchState) => item is String;
6159
}

0 commit comments

Comments
 (0)