| // Copyright (c) 2022, 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 'dart:async'; | |
| import 'package:checks/checks.dart'; | |
| import 'package:checks/context.dart'; | |
| extension RejectionChecks<T> on Subject<T> { | |
| void isRejectedBy( | |
| Condition<T> condition, { | |
| Iterable<String>? actual, | |
| Iterable<String>? which, | |
| }) { | |
| late T actualValue; | |
| var didRunCallback = false; | |
| final rejection = context.nest<Rejection>( | |
| () => ['does not meet a condition with a Rejection'], | |
| (value) { | |
| actualValue = value; | |
| didRunCallback = true; | |
| final failure = softCheck(value, condition); | |
| if (failure == null) { | |
| return Extracted.rejection( | |
| which: [ | |
| 'was accepted by the condition checking:', | |
| ...describe(condition), | |
| ], | |
| ); | |
| } | |
| return Extracted.value(failure.rejection); | |
| }, | |
| ); | |
| if (didRunCallback) { | |
| rejection | |
| .has((r) => r.actual, 'actual') | |
| .deepEquals(actual ?? literal(actualValue)); | |
| } else { | |
| rejection | |
| .has((r) => r.actual, 'actual') | |
| .context | |
| .expect(() => ['is left default'], (_) => null); | |
| } | |
| if (which == null) { | |
| rejection.has((r) => r.which, 'which').isNull(); | |
| } else { | |
| rejection.has((r) => r.which, 'which').isNotNull().deepEquals(which); | |
| } | |
| } | |
| Future<void> isRejectedByAsync( | |
| Condition<T> condition, { | |
| Iterable<String>? actual, | |
| Iterable<String>? which, | |
| }) { | |
| late T actualValue; | |
| var didRunCallback = false; | |
| return context.nestAsync<Rejection>( | |
| () => ['does not meet an async condition with a Rejection'], | |
| (value) async { | |
| actualValue = value; | |
| didRunCallback = true; | |
| final failure = await softCheckAsync(value, condition); | |
| if (failure == null) { | |
| return Extracted.rejection( | |
| which: [ | |
| 'was accepted by the condition checking:', | |
| ...await describeAsync(condition), | |
| ], | |
| ); | |
| } | |
| return Extracted.value(failure.rejection); | |
| }, | |
| (rejection) { | |
| if (didRunCallback) { | |
| rejection | |
| .has((r) => r.actual, 'actual') | |
| .deepEquals(actual ?? literal(actualValue)); | |
| } else { | |
| rejection | |
| .has((r) => r.actual, 'actual') | |
| .context | |
| .expect(() => ['is left default'], (_) => null); | |
| } | |
| if (which == null) { | |
| rejection.has((r) => r.which, 'which').isNull(); | |
| } else { | |
| rejection.has((r) => r.which, 'which').isNotNull().deepEquals(which); | |
| } | |
| }, | |
| ); | |
| } | |
| } | |
| extension ConditionChecks<T> on Subject<Condition<T>> { | |
| Subject<Iterable<String>> get description => | |
| has((c) => describe<T>(c), 'description'); | |
| Future<void> hasAsyncDescriptionWhich( | |
| Condition<Iterable<String>> descriptionCondition, | |
| ) => context.nestAsync( | |
| () => ['has description'], | |
| (condition) async => Extracted.value(await describeAsync<T>(condition)), | |
| descriptionCondition, | |
| ); | |
| } |