Add alternative matcher
diff --git a/lib/matcher.dart b/lib/matcher.dart
index 72918aa..20ed254 100644
--- a/lib/matcher.dart
+++ b/lib/matcher.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
/// Support for specifying test expectations, such as for unit tests.
+export 'src/alternatives_matcher.dart';
export 'src/core_matchers.dart';
export 'src/custom_matcher.dart';
export 'src/description.dart';
diff --git a/lib/src/alternatives_matcher.dart b/lib/src/alternatives_matcher.dart
new file mode 100644
index 0000000..2b2045b
--- /dev/null
+++ b/lib/src/alternatives_matcher.dart
@@ -0,0 +1,19 @@
+import 'equals_matcher.dart';
+import 'interfaces.dart';
+import 'operator_matchers.dart';
+
+/// Matches expected or any of the given alternatives.
+///
+/// Example:
+/// ```dart
+/// expect(2, alternatives(1, {2})) // returns true
+/// ```
+///
+/// Especially helpful in enabling the setup of alternative expected values
+/// before breaking changes, to avoid test failures in migrations.
+Matcher alternatives(
+ Object expected, [
+ Set<Object>? alternatives,
+ Matcher Function(Object) matcher = equals,
+]) =>
+ anyOf([expected, ...?alternatives].map(matcher).toList());
diff --git a/test/alternatives_matcher_test.dart b/test/alternatives_matcher_test.dart
new file mode 100644
index 0000000..2563165
--- /dev/null
+++ b/test/alternatives_matcher_test.dart
@@ -0,0 +1,35 @@
+import 'package:test/test.dart';
+
+void main() {
+ final alternativeMatcher = alternatives(
+ 'oldCase',
+ {'alternative', 'alternative2'},
+ );
+
+ test('Equals', () {
+ expect('oldCase', alternativeMatcher);
+ });
+
+ test('Equals alternative', () {
+ expect('alternative', alternativeMatcher);
+ expect('alternative2', alternativeMatcher);
+ });
+
+ test('Equals fails', () {
+ expect(
+ () => expect('newCaseNotInAlternatives', alternativeMatcher),
+ throwsA(isA<TestFailure>()),
+ );
+ });
+
+ test('Pass matcher as argument', () {
+ expect([1, 2, 3, 3], alternatives(3, {2}, containsOnce));
+ });
+
+ test('Pass matcher as argument and fail', () {
+ expect(
+ () => expect([1, 2, 3, 3], alternatives(4, {}, containsOnce)),
+ throwsA(isA<TestFailure>()),
+ );
+ });
+}