Skip to content

Commit a8f12fe

Browse files
authored
Release 0.5.0 (#5)
1 parent 838e44f commit a8f12fe

18 files changed

+1121
-26
lines changed

.github/workflows/run_tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
run: flutter pub get
2121

2222
- name: Check formatting
23-
run: flutter format --set-exit-if-changed --dry-run .
23+
run: dart format --set-exit-if-changed .
2424

2525
- name: Run analyzer
2626
run: flutter analyze

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.5.0
4+
5+
* Iterable assertions.
6+
37
## 0.4.0
48

59
* Added assertions for strings.

README.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,43 @@ hasChildren.shouldNotBeTrue();
173173
'name'.shouldNotBeNullOrBlank()
174174
```
175175

176-
#### Collection Assertions
176+
#### Iterable Assertions
177+
178+
```dart
179+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContain('Flutter');
180+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainIgnoringCase('flutter');
181+
```
182+
183+
```dart
184+
['Flutter', 'React Native', 'Jetpack Compose'].shouldNotContain('Vue');
185+
['Flutter', 'React Native', 'Jetpack Compose'].shouldNotContainIgnoringCase('vue');
186+
```
187+
188+
```dart
189+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAny(['Flutter', 'Vue']);
190+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAnyIgnoringCase(['react native']);
191+
```
192+
193+
```dart
194+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainNone(['Angular', 'Vue'])
195+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainNoneIgnoringCase(['angular', 'vue']);
196+
```
197+
198+
```dart
199+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAll(['Jetpack Compose', 'React Native']);
200+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAllIgnoringCase(['jetpack compose', 'react native']);
201+
```
202+
203+
```dart
204+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAllInOrder(['Flutter', 'React Native']);
205+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAllInOrderIgnoringCase(['flutter', 'react native']);
206+
```
207+
208+
```dart
209+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAllThat((framework) => framework.startsWith(RegExp('[A-Z]')));
210+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainAnyThat((framework) => framework.contains('React'));
211+
['Flutter', 'React Native', 'Jetpack Compose'].shouldContainNoneThat((framework) => framework.isEmpty);
212+
```
177213

178214
## Features and bugs
179215

lib/fluent_assertions.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
/// It uses Dart's Extension Functions to provide a fluent wrapper around test assertions.
44
library fluent_assertions;
55

6-
export 'src/basic_assertions.dart';
7-
export 'src/numerical_assertions.dart';
8-
export 'src/string_assertions.dart';
6+
export 'src/basic/basic_assertions.dart';
7+
export 'src/iterable/iterable_assertions.dart';
8+
export 'src/numerical/numerical_assertions.dart';
9+
export 'src/string/string_assertions.dart';
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'package:test/test.dart';
22

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

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

16-
// Asserts that the value is null.
16+
/// Asserts that the value is null.
1717
void shouldBeNull() => expect(this, isNull);
1818

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

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

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

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

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

38-
// Asserts that the value is false.
38+
/// Asserts that the value is false.
3939
void shouldBeFalse() => expect(this, isFalse);
4040

41-
// Asserts that the value is false.
41+
/// Asserts that the value is false.
4242
void shouldNotBeTrue() => expect(this, isNot(isTrue));
4343
}
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
import 'package:fluent_assertions/src/iterable/iterable_matchers.dart';
2+
import 'package:test/test.dart';
3+
4+
extension IterableObjectAssertions on Iterable<Object> {
5+
/// Asserts that every value in [Iterable] is of type [E].
6+
/// [E] - Expected type.
7+
void shouldAllBeInstanceOf<E>() {
8+
expect(
9+
this,
10+
everyElement((e) => e is E),
11+
reason: 'Expected all elements to be instances of $E, but some were not.',
12+
);
13+
}
14+
15+
/// Asserts that any value in [Iterable] is of type [E].
16+
/// [E] - Expected type.
17+
void shouldAnyBeInstanceOf<E>() {
18+
expect(
19+
this,
20+
anyElement((e) => e is E),
21+
reason:
22+
'Expected at least one element to be an instance of $E, but none were.',
23+
);
24+
}
25+
26+
/// Asserts that every value in [Iterable] is not of type [E].
27+
/// [E] - Expected type.
28+
void shouldNoneBeInstanceOf<E>() {
29+
expect(
30+
this,
31+
everyElement((e) => e is! E),
32+
reason: 'Expected no elements to be instances of $E, but some were.',
33+
);
34+
}
35+
}
36+
37+
extension IterableAssertions<T> on Iterable<T> {
38+
/// Asserts that [Iterable] has [expectedSize] elements
39+
void shouldHaveSize(int expectedSize) {
40+
expect(
41+
this,
42+
hasLength(expectedSize),
43+
reason:
44+
'Expected iterable to have $expectedSize elements, but found $length.',
45+
);
46+
}
47+
48+
/// Asserts that [Iterable] is empty.
49+
void shouldBeEmpty() {
50+
expect(
51+
this,
52+
isEmpty,
53+
reason: 'Expected iterable to be empty, but it was not.',
54+
);
55+
}
56+
57+
/// Asserts that [Iterable] is not empty.
58+
void shouldNotBeEmpty() {
59+
expect(
60+
this,
61+
isNot(isEmpty),
62+
reason: 'Expected iterable to not be empty, but it was.',
63+
);
64+
}
65+
66+
/// Asserts that [Iterable] has 1 element.
67+
void shouldHaveSingleItem() {
68+
expect(
69+
this,
70+
hasLength(1),
71+
reason: 'Expected iterable to have exactly one item, but has $length.',
72+
);
73+
}
74+
75+
/// Asserts that [Iterable] contains [expected].
76+
void shouldContain(T? expected) {
77+
expect(
78+
this,
79+
contains(expected),
80+
reason: 'Expected iterable to contain $expected, but it did not.',
81+
);
82+
}
83+
84+
/// Asserts that [Iterable] does not contain [expected].
85+
void shouldNotContain(T? expected) {
86+
expect(
87+
this,
88+
isNot(contains(expected)),
89+
reason: 'Expected iterable to not contain $expected, but it did.',
90+
);
91+
}
92+
93+
/// Asserts that [Iterable] contains any of [expected].
94+
void shouldContainAny(Iterable<T> expected) {
95+
expect(
96+
this,
97+
containsAny(expected.map(equals).toList()),
98+
reason:
99+
'Expected at least one element from $expected to be present in $this.',
100+
);
101+
}
102+
103+
/// Asserts that [Iterable] contains none of [expected].
104+
void shouldContainNone(Iterable<T> expected) {
105+
expect(
106+
this,
107+
isNot(containsAny(expected.map(equals).toList())),
108+
reason:
109+
'Expected iterable to contain none of $expected, but some were found.',
110+
);
111+
}
112+
113+
/// Asserts that [Iterable] contains an element matching every value in
114+
/// [expected] in any order, and may contain additional values.
115+
void shouldContainAll(Iterable<T> expected) {
116+
expect(
117+
this,
118+
containsAll(expected),
119+
reason:
120+
'Expected iterable to contain all of $expected, but some were missing.',
121+
);
122+
}
123+
124+
/// Asserts that [Iterable] contains an element matching every value in
125+
/// [expected] in the same order, but may contain additional values
126+
/// interleaved throughout.
127+
void shouldContainAllInOrder(Iterable<T> expected) {
128+
expect(
129+
this,
130+
containsAllInOrder(expected),
131+
reason:
132+
'Expected iterable to contain all of $expected in order, but it did not.',
133+
);
134+
}
135+
136+
/// Asserts that [Iterable] contains an element matching the given [predicate].
137+
void shouldContainAnyThat(bool Function(T argument) predicate) {
138+
expect(
139+
this,
140+
anyElement(predicate),
141+
reason:
142+
'Expected iterable to contain at least one element matching the predicate, but none did.',
143+
);
144+
}
145+
146+
/// Asserts that all [Iterable] elements match [predicate].
147+
void shouldContainAllThat(bool Function(T argument) predicate) {
148+
expect(
149+
this,
150+
everyElement(predicate),
151+
reason:
152+
'Expected every element in iterable to match the predicate, but some did not.',
153+
);
154+
}
155+
156+
/// Asserts that none [Iterable] elements match [predicate].
157+
void shouldContainNoneThat(bool Function(T argument) predicate) {
158+
expect(
159+
this,
160+
everyElement(isNot(predicate)),
161+
reason:
162+
'Expected no elements in iterable to match the predicate, but some did.',
163+
);
164+
}
165+
}
166+
167+
extension IterableStringAssertions on Iterable<String> {
168+
/// Asserts that [Iterable] contains [expected] case-insensitively.
169+
void shouldContainIgnoringCase(String expected) {
170+
expect(
171+
this,
172+
containsAll([equalsIgnoringCase(expected)]),
173+
reason:
174+
'Expected iterable to contain "$expected" ignoring case, but it did not.',
175+
);
176+
}
177+
178+
/// Asserts that [Iterable] contains [expected] case-insensitively.
179+
void shouldNotContainIgnoringCase(String expected) {
180+
expect(
181+
this,
182+
isNot(containsAll([equalsIgnoringCase(expected)])),
183+
reason:
184+
'Expected iterable to not contain "$expected" ignoring case, but it did.',
185+
);
186+
}
187+
188+
/// Asserts that [Iterable] contains any of [expected] case-insensitively.
189+
void shouldContainAnyIgnoringCase(Iterable<String> expected) {
190+
expect(
191+
this,
192+
containsAny(expected.map((e) => equalsIgnoringCase(e)).toList()),
193+
reason:
194+
'Expected iterable to contain any of $expected ignoring case, but none were found.',
195+
);
196+
}
197+
198+
/// Asserts that [Iterable] contains none of [expected] case-insensitively.
199+
void shouldContainNoneIgnoringCase(Iterable<String> expected) {
200+
expect(
201+
this,
202+
isNot(containsAny(expected.map((e) => equalsIgnoringCase(e)).toList())),
203+
reason:
204+
'Expected iterable to contain none of $expected ignoring case, but some were found.',
205+
);
206+
}
207+
208+
/// Asserts that [Iterable] contains an element matching every value in
209+
/// [expected] in any order, case-insensitively, and may contain additional
210+
/// values.
211+
void shouldContainAllIgnoringCase(Iterable<String> expected) {
212+
expect(
213+
this,
214+
containsAll(expected.map((e) => equalsIgnoringCase(e))),
215+
reason:
216+
'Expected iterable to contain all of $expected ignoring case, but some were missing.',
217+
);
218+
}
219+
220+
/// Asserts that [Iterable] contains an element matching every value in
221+
/// [expected] in the same order and case-insensitively but may contain
222+
/// additional values interleaved throughout.
223+
void shouldContainAllInOrderIgnoringCase(Iterable<String> expected) {
224+
expect(
225+
this,
226+
containsAllInOrder(expected.map((e) => equalsIgnoringCase(e))),
227+
reason:
228+
'Expected iterable to contain all of $expected in order ignoring case, but it did not.',
229+
);
230+
}
231+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import 'package:test/test.dart';
2+
3+
Matcher containsAny(Iterable<Object> matchers) {
4+
return contains(anyOf(matchers));
5+
}

lib/src/string_assertions.dart renamed to lib/src/string/string_assertions.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ extension StringAssertions on String {
166166

167167
/// Asserts that the value matches the regular expression given by [regExp].
168168
/// [regExp] can be a [RegExp] instance or a [String].
169-
void shouldMatch(dynamic regExp) {
169+
void shouldMatch(Pattern regExp) {
170170
expect(
171171
this,
172172
matches(regExp),
@@ -177,7 +177,7 @@ extension StringAssertions on String {
177177
/// Asserts that the value does not match the regular expression \
178178
/// given by [regExp].
179179
/// [regExp] can be a [RegExp] instance or a [String].
180-
void shouldNotMatch(dynamic regExp) {
180+
void shouldNotMatch(Pattern regExp) {
181181
expect(
182182
this,
183183
isNot(matches(regExp)),

pubspec.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
name: fluent_assertions
2-
description: Fluent Assertions library written in Dart.
3-
version: 0.4.0
2+
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.
3+
version: 0.5.0
44
homepage: https://github.com/klisiewicz/fluent-assertions
55

66
environment:
7-
sdk: '>=2.12.0 <3.0.0'
7+
sdk: '>=2.12.0 <4.0.0'
88

99
dependencies:
10-
test: 1.16.5
10+
test: ^1.25.14
1111

1212
dev_dependencies:
13-
lint: ^1.5.3
13+
lint: ^2.3.0

0 commit comments

Comments
 (0)