Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4fe78ee
Change: Updated version and dependencies.
klisiewicz Aug 31, 2022
af60f3a
Added: shouldContain and shouldNotContain matchers.
klisiewicz Aug 31, 2022
c5a2d0a
#0.5.0: updated dependencies
klisiewicz Dec 28, 2024
cef35ed
#0.5.0: restructured code
klisiewicz Dec 28, 2024
9c50e4a
#0.5.0 Iterable assertions: shouldContainIgnoringCase
klisiewicz Dec 28, 2024
e9e9778
#0.5.0 fixed lint warning
klisiewicz Dec 28, 2024
11b4989
#0.5.0 updated Dart version
klisiewicz Dec 28, 2024
9e8a584
#0.5.0 should contain any and some
klisiewicz Dec 28, 2024
6a909fd
0.5.0 added more tests
klisiewicz Dec 29, 2024
c16fbd4
0.5.0 added shouldContainAnyIgnoringCase and shouldContainNoneIgnorin…
klisiewicz Dec 29, 2024
719b71b
0.5.0 added shouldContainAll
klisiewicz Dec 29, 2024
f12599f
0.5.0 renamed test data
klisiewicz Dec 29, 2024
003f2d9
0.5.0 updated README.md
klisiewicz Dec 29, 2024
df3d483
0.5.0 added shouldContainAllInOrder
klisiewicz Dec 29, 2024
b407da4
0.5.0 fixed formatting command
klisiewicz Dec 29, 2024
90ff770
0.5.0 fixed formatting
klisiewicz Dec 29, 2024
ce039b6
0.5.0 removed containsAny Matcher
klisiewicz Dec 29, 2024
00a8c92
0.5.0 removed containsIgnoringCase Matcher
klisiewicz Dec 29, 2024
be8d168
0.5.0 added shouldContainAllIgnoringCase and shouldContainAllInOrderI…
klisiewicz Dec 29, 2024
211adad
0.5.0 added shouldContainAnyThat
klisiewicz Dec 29, 2024
6a91979
0.5.0 updated description
klisiewicz Dec 29, 2024
4fb743e
0.5.0 added size matchers
klisiewicz Dec 29, 2024
4fb2332
0.5.0 added contain none matcher
klisiewicz Dec 29, 2024
de60525
0.5.0 fixed import
klisiewicz Dec 29, 2024
44e2b3c
0.5.0 updated comments
klisiewicz Dec 29, 2024
d6ad4ca
0.5.0 added shouldAllBeInstanceOf, shouldAnyBeInstanceOf, shouldNoneB…
klisiewicz Dec 31, 2024
a537b97
0.5.0 updated dependencies
klisiewicz Dec 31, 2024
82a4f10
0.5.0 fixed formatting
klisiewicz Dec 31, 2024
e7b025b
0.5.0 renamed base_assertions.dart to basic_assertions.dart
klisiewicz Jan 1, 2025
9130e75
0.5.0 updated README.md
klisiewicz Jan 1, 2025
c3274c1
0.5.0 updated reason
klisiewicz Jan 1, 2025
c28c752
0.5.0 fixed formatting
klisiewicz Jan 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
run: flutter pub get

- name: Check formatting
run: flutter format --set-exit-if-changed --dry-run .
run: dart format --set-exit-if-changed .

- name: Run analyzer
run: flutter analyze
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.5.0

* Iterable assertions.

## 0.4.0

* Added assertions for strings.
Expand Down
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,43 @@ hasChildren.shouldNotBeTrue();
'name'.shouldNotBeNullOrBlank()
```

#### Collection Assertions
#### Iterable Assertions

```dart
['Flutter', 'React Native', 'Jetpack Compose'].shouldContain('Flutter');
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainIgnoringCase('flutter');
```

```dart
['Flutter', 'React Native', 'Jetpack Compose'].shouldNotContain('Vue');
['Flutter', 'React Native', 'Jetpack Compose'].shouldNotContainIgnoringCase('vue');
```

```dart
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAny(['Flutter', 'Vue']);
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAnyIgnoringCase(['react native']);
```

```dart
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainNone(['Angular', 'Vue'])
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainNoneIgnoringCase(['angular', 'vue']);
```

```dart
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAll(['Jetpack Compose', 'React Native']);
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAllIgnoringCase(['jetpack compose', 'react native']);
```

```dart
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAllInOrder(['Flutter', 'React Native']);
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAllInOrderIgnoringCase(['flutter', 'react native']);
```

```dart
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAllThat((framework) => framework.startsWith(RegExp('[A-Z]')));
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAnyThat((framework) => framework.contains('React'));
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainNoneThat((framework) => framework.isEmpty);
```

## Features and bugs

Expand Down
7 changes: 4 additions & 3 deletions lib/fluent_assertions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/// It uses Dart's Extension Functions to provide a fluent wrapper around test assertions.
library fluent_assertions;

export 'src/basic_assertions.dart';
export 'src/numerical_assertions.dart';
export 'src/string_assertions.dart';
export 'src/basic/basic_assertions.dart';
export 'src/iterable/iterable_assertions.dart';
export 'src/numerical/numerical_assertions.dart';
export 'src/string/string_assertions.dart';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:test/test.dart';

extension BasicAssertions<T> on T? {
extension BaseAssertions<T> on T? {
/// Asserts that the value is structurally equal to [expected].
void shouldBeEqualTo(T expected) => expect(this, equals(expected));

Expand All @@ -13,31 +13,31 @@ extension BasicAssertions<T> on T? {
/// Asserts that the value is not the same instance as [expected], using [identical].
void shouldNotBe(T expected) => expect(this, isNot(same(expected)));

// Asserts that the value is null.
/// Asserts that the value is null.
void shouldBeNull() => expect(this, isNull);

// Asserts that the value is non-null.
/// Asserts that the value is non-null.
void shouldNotBeNull() => expect(this, isNotNull);

// Asserts that the value is of type [E].
/// Asserts that the value is of type [E].
/// [E] - Expected type.
void shouldBeInstanceOf<E>() => expect(this, isA<E>());

// Asserts that the value is not of type [E].
/// Asserts that the value is not of type [E].
/// [E] - Expected type.
void shouldNotBeInstanceOf<E>() => expect(this, isNot(isA<E>()));
}

extension BoolAssertions on bool {
// Asserts that the value is true.
/// Asserts that the value is true.
void shouldBeTrue() => expect(this, isTrue);

// Asserts that the value is true.
/// Asserts that the value is true.
void shouldNotBeFalse() => expect(this, isNot(isFalse));

// Asserts that the value is false.
/// Asserts that the value is false.
void shouldBeFalse() => expect(this, isFalse);

// Asserts that the value is false.
/// Asserts that the value is false.
void shouldNotBeTrue() => expect(this, isNot(isTrue));
}
231 changes: 231 additions & 0 deletions lib/src/iterable/iterable_assertions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
import 'package:fluent_assertions/src/iterable/iterable_matchers.dart';
import 'package:test/test.dart';

extension IterableObjectAssertions on Iterable<Object> {
/// Asserts that every value in [Iterable] is of type [E].
/// [E] - Expected type.
void shouldAllBeInstanceOf<E>() {
expect(
this,
everyElement((e) => e is E),
reason: 'Expected all elements to be instances of $E, but some were not.',
);
}

/// Asserts that any value in [Iterable] is of type [E].
/// [E] - Expected type.
void shouldAnyBeInstanceOf<E>() {
expect(
this,
anyElement((e) => e is E),
reason:
'Expected at least one element to be an instance of $E, but none were.',
);
}

/// Asserts that every value in [Iterable] is not of type [E].
/// [E] - Expected type.
void shouldNoneBeInstanceOf<E>() {
expect(
this,
everyElement((e) => e is! E),
reason: 'Expected no elements to be instances of $E, but some were.',
);
}
}

extension IterableAssertions<T> on Iterable<T> {
/// Asserts that [Iterable] has [expectedSize] elements
void shouldHaveSize(int expectedSize) {
expect(
this,
hasLength(expectedSize),
reason:
'Expected iterable to have $expectedSize elements, but found $length.',
);
}

/// Asserts that [Iterable] is empty.
void shouldBeEmpty() {
expect(
this,
isEmpty,
reason: 'Expected iterable to be empty, but it was not.',
);
}

/// Asserts that [Iterable] is not empty.
void shouldNotBeEmpty() {
expect(
this,
isNot(isEmpty),
reason: 'Expected iterable to not be empty, but it was.',
);
}

/// Asserts that [Iterable] has 1 element.
void shouldHaveSingleItem() {
expect(
this,
hasLength(1),
reason: 'Expected iterable to have exactly one item, but has $length.',
);
}

/// Asserts that [Iterable] contains [expected].
void shouldContain(T? expected) {
expect(
this,
contains(expected),
reason: 'Expected iterable to contain $expected, but it did not.',
);
}

/// Asserts that [Iterable] does not contain [expected].
void shouldNotContain(T? expected) {
expect(
this,
isNot(contains(expected)),
reason: 'Expected iterable to not contain $expected, but it did.',
);
}

/// Asserts that [Iterable] contains any of [expected].
void shouldContainAny(Iterable<T> expected) {
expect(
this,
containsAny(expected.map(equals).toList()),
reason:
'Expected at least one element from $expected to be present in $this.',
);
}

/// Asserts that [Iterable] contains none of [expected].
void shouldContainNone(Iterable<T> expected) {
expect(
this,
isNot(containsAny(expected.map(equals).toList())),
reason:
'Expected iterable to contain none of $expected, but some were found.',
);
}

/// Asserts that [Iterable] contains an element matching every value in
/// [expected] in any order, and may contain additional values.
void shouldContainAll(Iterable<T> expected) {
expect(
this,
containsAll(expected),
reason:
'Expected iterable to contain all of $expected, but some were missing.',
);
}

/// Asserts that [Iterable] contains an element matching every value in
/// [expected] in the same order, but may contain additional values
/// interleaved throughout.
void shouldContainAllInOrder(Iterable<T> expected) {
expect(
this,
containsAllInOrder(expected),
reason:
'Expected iterable to contain all of $expected in order, but it did not.',
);
}

/// Asserts that [Iterable] contains an element matching the given [predicate].
void shouldContainAnyThat(bool Function(T argument) predicate) {
expect(
this,
anyElement(predicate),
reason:
'Expected iterable to contain at least one element matching the predicate, but none did.',
);
}

/// Asserts that all [Iterable] elements match [predicate].
void shouldContainAllThat(bool Function(T argument) predicate) {
expect(
this,
everyElement(predicate),
reason:
'Expected every element in iterable to match the predicate, but some did not.',
);
}

/// Asserts that none [Iterable] elements match [predicate].
void shouldContainNoneThat(bool Function(T argument) predicate) {
expect(
this,
everyElement(isNot(predicate)),
reason:
'Expected no elements in iterable to match the predicate, but some did.',
);
}
}

extension IterableStringAssertions on Iterable<String> {
/// Asserts that [Iterable] contains [expected] case-insensitively.
void shouldContainIgnoringCase(String expected) {
expect(
this,
containsAll([equalsIgnoringCase(expected)]),
reason:
'Expected iterable to contain "$expected" ignoring case, but it did not.',
);
}

/// Asserts that [Iterable] contains [expected] case-insensitively.
void shouldNotContainIgnoringCase(String expected) {
expect(
this,
isNot(containsAll([equalsIgnoringCase(expected)])),
reason:
'Expected iterable to not contain "$expected" ignoring case, but it did.',
);
}

/// Asserts that [Iterable] contains any of [expected] case-insensitively.
void shouldContainAnyIgnoringCase(Iterable<String> expected) {
expect(
this,
containsAny(expected.map((e) => equalsIgnoringCase(e)).toList()),
reason:
'Expected iterable to contain any of $expected ignoring case, but none were found.',
);
}

/// Asserts that [Iterable] contains none of [expected] case-insensitively.
void shouldContainNoneIgnoringCase(Iterable<String> expected) {
expect(
this,
isNot(containsAny(expected.map((e) => equalsIgnoringCase(e)).toList())),
reason:
'Expected iterable to contain none of $expected ignoring case, but some were found.',
);
}

/// Asserts that [Iterable] contains an element matching every value in
/// [expected] in any order, case-insensitively, and may contain additional
/// values.
void shouldContainAllIgnoringCase(Iterable<String> expected) {
expect(
this,
containsAll(expected.map((e) => equalsIgnoringCase(e))),
reason:
'Expected iterable to contain all of $expected ignoring case, but some were missing.',
);
}

/// Asserts that [Iterable] contains an element matching every value in
/// [expected] in the same order and case-insensitively but may contain
/// additional values interleaved throughout.
void shouldContainAllInOrderIgnoringCase(Iterable<String> expected) {
expect(
this,
containsAllInOrder(expected.map((e) => equalsIgnoringCase(e))),
reason:
'Expected iterable to contain all of $expected in order ignoring case, but it did not.',
);
}
}
5 changes: 5 additions & 0 deletions lib/src/iterable/iterable_matchers.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import 'package:test/test.dart';

Matcher containsAny(Iterable<Object> matchers) {
return contains(anyOf(matchers));
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ extension StringAssertions on String {

/// Asserts that the value matches the regular expression given by [regExp].
/// [regExp] can be a [RegExp] instance or a [String].
void shouldMatch(dynamic regExp) {
void shouldMatch(Pattern regExp) {
expect(
this,
matches(regExp),
Expand All @@ -177,7 +177,7 @@ extension StringAssertions on String {
/// Asserts that the value does not match the regular expression \
/// given by [regExp].
/// [regExp] can be a [RegExp] instance or a [String].
void shouldNotMatch(dynamic regExp) {
void shouldNotMatch(Pattern regExp) {
expect(
this,
isNot(matches(regExp)),
Expand Down
10 changes: 5 additions & 5 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
name: fluent_assertions
description: Fluent Assertions library written in Dart.
version: 0.4.0
description: A very extensive set of extension methods that allow you to more naturally specify the expected outcome of a TDD or BDD-style unit tests.
version: 0.5.0
homepage: https://github.com/klisiewicz/fluent-assertions

environment:
sdk: '>=2.12.0 <3.0.0'
sdk: '>=2.12.0 <4.0.0'

dependencies:
test: 1.16.5
test: ^1.25.14

dev_dependencies:
lint: ^1.5.3
lint: ^2.3.0
Loading
Loading