Core Matchers
ribs_test provides custom matchers for the fundamental ribs_core types — Option, Either, and Validated — so your test assertions read naturally alongside the types they check.
import 'package:ribs_test/ribs_core_test.dart';Option
isSome([matcher])
Matches a Some value. If a nested matcher is supplied, the contained value must also satisfy it. Without an argument, any Some matches.
isNone()
Matches None.
void optionTests() {
// isSome asserts the value is Some; the optional argument checks the contained value.
test('Some with value', () {
expect(const Some(42), isSome(42));
expect(const Some('hi'), isSome());
expect(none<int>(), isNot(isSome()));
});
// isNone asserts the value is None.
test('None', () {
expect(none<int>(), isNone());
expect(const Some(1), isNot(isNone()));
});
}Either
isLeft([matcher])
Matches a Left value. If a nested matcher is supplied, the value inside Left must also satisfy it.
isRight([matcher])
Matches a Right value. The inner value is validated against matcher when provided.
void eitherTests() {
// isLeft asserts the Either is a Left; optionally checks the contained value.
test('Left', () {
expect('error'.asLeft<int>(), isLeft('error'));
expect('error'.asLeft<int>(), isLeft());
expect(42.asRight<String>(), isNot(isLeft()));
});
// isRight asserts the Either is a Right; accepts any nested matcher.
test('Right', () {
expect(42.asRight<String>(), isRight(42));
expect(42.asRight<String>(), isRight(greaterThan(40)));
expect('err'.asLeft<int>(), isNot(isRight()));
});
}Validated
Validated is ribs_core's accumulating error type. Its matchers mirror the Either pair but work with Valid/Invalid directly.
isValid([matcher])
Matches a Valid value, optionally checking the contained value.
isValidNel([matcher])
Alias for isValid. Use this variant when you're working with ValidatedNel to make intent clear at the call site.
isInvalid([matcher])
Matches an Invalid value. Pass a matcher to inspect the error.
void validatedTests() {
// isValid asserts a Valid value, optionally checking the contained value.
test('Valid', () {
expect(Validated.valid<String, int>(42), isValid(42));
expect(Validated.valid<String, String>('ok'), isValid());
expect(Validated.invalid<String, int>('e'), isNot(isValid()));
});
// isValidNel is an alias for isValid; use it with ValidatedNel to clarify intent.
test('ValidNel', () {
expect(Validated.validNel<String, int>(42), isValidNel(42));
});
// isInvalid asserts an Invalid value, optionally inspecting the error.
test('Invalid', () {
expect(Validated.invalid<String, int>('oops'), isInvalid('oops'));
expect(Validated.invalidNel<String, int>('a'), isInvalid());
expect(Validated.valid<String, int>(1), isNot(isInvalid()));
});
}Composing with standard matchers
All ribs matchers accept any package:test Matcher as their optional argument, so you can combine them with the full matcher vocabulary:
void composingTests() {
// All ribs matchers accept any package:test Matcher as their optional argument.
test('composing with standard matchers', () {
expect(Some(ilist([1, 2, 3])), isSome(isA<IList<int>>()));
expect('not_email'.asLeft<String>(), isLeft(isNot(contains('@'))));
expect(
Validated.invalidNel<String, int>('too short'),
isInvalid(isA<NonEmptyIList<String>>()),
);
});
}