Skip to content

Commit 027add4

Browse files
committed
Add methods to check for size and empty collections
1 parent 799223d commit 027add4

2 files changed

Lines changed: 200 additions & 18 deletions

File tree

src/main/java/edu/hm/hafner/util/Ensure.java

Lines changed: 179 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* </p>
2323
*
2424
* <p>
25-
* Available checks:
25+
* Available checks:
2626
* </p>
2727
* <ul>
2828
* <li>Boolean assertions, e.g., {@code Ensure.that(condition).isTrue(); } </li>
@@ -33,7 +33,8 @@
3333
* </ul>
3434
*
3535
* @author Ullrich Hafner
36-
* @see <a href="http://se.ethz.ch/~meyer/publications/computer/contract.pdf"> Design by Contract (Meyer, Bertrand)</a>
36+
* @see <a href="http://se.ethz.ch/~meyer/publications/computer/contract.pdf"> Design by Contract (Meyer,
37+
* Bertrand)</a>
3738
*/
3839
public final class Ensure {
3940
/**
@@ -212,12 +213,78 @@ public IterableCondition(@CheckForNull final Iterable<?> value) {
212213
* that each element of the iterable is not {@code null}.
213214
*
214215
* @throws AssertionError
215-
* if the iterable is empty (or {@code null}), or at least one iterable element is {@code null}.
216+
* if the iterable is empty (or {@code null}), or at least one iterable element is {@code null}
216217
*/
217218
public void isNotEmpty() {
218219
isNotEmpty("Iterable is empty or NULL");
219220
}
220221

222+
/**
223+
* Ensures that the given iterable is not {@code null} but empty.
224+
*
225+
* @throws AssertionError
226+
* if the iterable is not empty (or {@code null})
227+
*/
228+
public void isEmpty() {
229+
isEmpty("Iterable is not empty or NULL");
230+
}
231+
232+
/**
233+
* Ensures that the given iterable is not {@code null} and contains the specified number of elements.
234+
* Additionally, ensures that each element of the iterable is not {@code null}.
235+
*
236+
* @param expectedSize
237+
* the expected number of elements in the iterable
238+
*
239+
* @throws AssertionError
240+
* if the iterable does not contain the expected number of elements (or is {@code null}), or at least
241+
* one iterable element is {@code null}
242+
*/
243+
@FormatMethod
244+
public void hasSize(final int expectedSize) {
245+
hasSize(expectedSize,
246+
"Iterable does not contain the expected number of elements. Actual: %s. Expected: %d",
247+
getValue(), expectedSize);
248+
}
249+
250+
/**
251+
* Ensures that the given iterable is not {@code null} and contains the specified number of elements.
252+
* Additionally, ensures that each element of the iterable is not {@code null}.
253+
*
254+
* @param expectedSize
255+
* the expected number of elements in the iterable
256+
* @param explanation
257+
* a {@link Formatter formatted message} explaining the assertion
258+
* @param args
259+
* Arguments referenced by the format specifiers in the formatted explanation. If there are more
260+
* arguments than format specifiers, the extra arguments are ignored. The number of arguments is
261+
* variable and may be zero.
262+
*
263+
* @throws AssertionError
264+
* if the iterable does not contain the expected number of elements (or is {@code null}), or at least
265+
* one iterable element is {@code null}
266+
*/
267+
@FormatMethod
268+
public void hasSize(final int expectedSize, final String explanation, final Object... args) {
269+
isNotNull(explanation, args);
270+
271+
var size = computeSize(explanation, args);
272+
if (size != expectedSize) {
273+
throwException(explanation, args);
274+
}
275+
}
276+
277+
private int computeSize(final String explanation, final Object... args) {
278+
int size = 0;
279+
for (Object object : getValue()) {
280+
if (object == null) {
281+
throwException(explanation, args);
282+
}
283+
size++;
284+
}
285+
return size;
286+
}
287+
221288
/**
222289
* Ensures that the given iterable is not {@code null} and contains at least one element. Additionally, ensures
223290
* that each element of the iterable is not {@code null}.
@@ -230,20 +297,35 @@ public void isNotEmpty() {
230297
* variable and may be zero.
231298
*
232299
* @throws AssertionError
233-
* if the iterable is empty (or {@code null}), or at least one iterable element is {@code null}.
300+
* if the iterable is empty (or {@code null}), or at least one iterable element is {@code null}
234301
*/
235302
@FormatMethod
236303
public void isNotEmpty(final String explanation, final Object... args) {
237304
isNotNull(explanation, args);
238305

239-
if (getValue().iterator().hasNext()) {
240-
for (Object object : getValue()) {
241-
if (object == null) {
242-
throwException(explanation, args);
243-
}
244-
}
306+
if (computeSize(explanation, args) == 0) {
307+
throwException(explanation, args);
245308
}
246-
else {
309+
}
310+
311+
/**
312+
* Ensures that the given iterable is not {@code null} but has no elements.
313+
*
314+
* @param explanation
315+
* a {@link Formatter formatted message} explaining the assertion
316+
* @param args
317+
* Arguments referenced by the format specifiers in the formatted explanation. If there are more
318+
* arguments than format specifiers, the extra arguments are ignored. The number of arguments is
319+
* variable and may be zero.
320+
*
321+
* @throws AssertionError
322+
* if the iterable is not empty (or {@code null})
323+
*/
324+
@FormatMethod
325+
public void isEmpty(final String explanation, final Object... args) {
326+
isNotNull(explanation, args);
327+
328+
if (computeSize(explanation, args) != 0) {
247329
throwException(explanation, args);
248330
}
249331
}
@@ -363,12 +445,61 @@ public ArrayCondition(@CheckForNull final Object[] values) {
363445
* that each element of the array is not {@code null}.
364446
*
365447
* @throws AssertionError
366-
* if the array is empty (or {@code null}), or at least one array element is {@code null}.
448+
* if the array is empty (or {@code null}), or at least one array element is {@code null}
367449
*/
368450
public void isNotEmpty() {
369451
isNotEmpty("Array is empty or NULL");
370452
}
371453

454+
/**
455+
* Ensures that the given array is not {@code null} but empty.
456+
*
457+
* @throws AssertionError
458+
* if the array is not empty (or {@code null})
459+
*/
460+
public void isEmpty() {
461+
isEmpty("Array is not empty or NULL");
462+
}
463+
464+
/**
465+
* Ensures that the given array is not {@code null} and has the specified number of elements. Additionally,
466+
* ensures that each element of the array is not {@code null}.
467+
*
468+
* @param expectedSize
469+
* the expected number of elements in the array
470+
*
471+
* @throws AssertionError
472+
* if the array does not contain the expected number of elements (or is {@code null}), or at least one
473+
* array element is {@code null}
474+
*/
475+
public void hasSize(final int expectedSize) {
476+
hasSize(expectedSize,
477+
"Array does not contain the expected number of elements. Actual: %s. Expected: %d",
478+
getValue().length, expectedSize);
479+
}
480+
481+
/**
482+
* Ensures that the given array is not {@code null} but empty.
483+
*
484+
* @param explanation
485+
* a {@link Formatter formatted message} explaining the assertion
486+
* @param args
487+
* Arguments referenced by the format specifiers in the formatted explanation. If there are more
488+
* arguments than format specifiers, the extra arguments are ignored. The number of arguments is
489+
* variable and may be zero.
490+
*
491+
* @throws AssertionError
492+
* if the array is empty (or {@code null}), or at least one array element is {@code null}.
493+
*/
494+
@FormatMethod
495+
public void isEmpty(final String explanation, final Object... args) {
496+
isNotNull(explanation, args);
497+
498+
if (getValue().length != 0) {
499+
throwException(explanation, args);
500+
}
501+
}
502+
372503
/**
373504
* Ensures that the given array is not {@code null} and contains at least one element. Additionally, ensures
374505
* that each element of the array is not {@code null}.
@@ -391,15 +522,45 @@ public void isNotEmpty(final String explanation, final Object... args) {
391522
throwException(explanation, args);
392523
}
393524
else {
394-
for (Object object : getValue()) {
395-
if (object == null) {
396-
throwException(explanation, args);
397-
}
398-
}
525+
doesNotContainNull(explanation, args);
526+
}
527+
}
528+
529+
/**
530+
* Ensures that the given array is not {@code null} and contains the specified number of elements. Additionally,
531+
* ensures that each element of the array is not {@code null}.
532+
*
533+
* @param expectedSize
534+
* the expected number of elements in the array
535+
* @param explanation
536+
* a {@link Formatter formatted message} explaining the assertion
537+
* @param args
538+
* Arguments referenced by the format specifiers in the formatted explanation. If there are more
539+
* arguments than format specifiers, the extra arguments are ignored. The number of arguments is
540+
* variable and may be zero.
541+
*
542+
* @throws AssertionError
543+
* if the array is empty (or {@code null}), or at least one array element is {@code null}.
544+
*/
545+
@FormatMethod
546+
public void hasSize(final int expectedSize, final String explanation, final Object... args) {
547+
isNotNull(explanation, args);
548+
549+
if (getValue().length == expectedSize) {
550+
doesNotContainNull(explanation, args);
551+
}
552+
else {
553+
throwException(explanation, args);
399554
}
400555
}
401556

402-
// FIXME: add isEmpty() methods
557+
private void doesNotContainNull(final String explanation, final Object[] args) {
558+
for (Object object : getValue()) {
559+
if (object == null) {
560+
throwException(explanation, args);
561+
}
562+
}
563+
}
403564
}
404565

405566
/**

src/test/java/edu/hm/hafner/util/EnsureTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ void shouldNotThrowExceptionIfContractIsValid() {
3030
Ensure.that("", "").isNotNull();
3131
Ensure.that(null, (Object) null).isNull();
3232
Ensure.that(new String[]{""}).isNotEmpty();
33+
Ensure.that(new String[]{""}).hasSize(1);
34+
Ensure.that(new String[0]).isEmpty();
35+
Ensure.that(new String[0]).hasSize(0);
3336
Ensure.that(SOME_STRING).isNotEmpty();
3437
Ensure.that(SOME_STRING).isNotBlank();
3538
Ensure.that("").isInstanceOf(String.class);
39+
Ensure.that(Set.of()).isEmpty();
3640
Ensure.that(Set.of("")).isNotEmpty();
41+
Ensure.that(Set.of("")).hasSize(1);
3742
Ensure.that(Set.of("")).contains("");
3843
Ensure.that(Set.of("")).doesNotContain(SOME_STRING);
3944
}).doesNotThrowAnyException();
@@ -71,6 +76,20 @@ void shouldThrowExceptionIfContractIsViolated() {
7176
.isInstanceOf(AssertionError.class);
7277
assertThatThrownBy(() -> Ensure.that(Set.of("")).doesNotContain(""))
7378
.isInstanceOf(AssertionError.class);
79+
assertThatThrownBy(() -> Ensure.that(Set.of("")).isEmpty())
80+
.isInstanceOf(AssertionError.class);
81+
assertThatThrownBy(() -> Ensure.that(Set.of()).isNotEmpty())
82+
.isInstanceOf(AssertionError.class);
83+
assertThatThrownBy(() -> Ensure.that(Set.of("")).hasSize(0))
84+
.isInstanceOf(AssertionError.class);
85+
assertThatThrownBy(() -> Ensure.that(Set.of("")).hasSize(2))
86+
.isInstanceOf(AssertionError.class);
87+
assertThatThrownBy(() -> Ensure.that(new String[]{"not-empty"}).isEmpty())
88+
.isInstanceOf(AssertionError.class);
89+
assertThatThrownBy(() -> Ensure.that(new String[]{"not-empty"}).hasSize(0))
90+
.isInstanceOf(AssertionError.class);
91+
assertThatThrownBy(() -> Ensure.that(new String[]{"not-empty"}).hasSize(2))
92+
.isInstanceOf(AssertionError.class);
7493
}
7594

7695
/**
@@ -121,6 +140,8 @@ void shouldThrowExceptionIfEmpty() {
121140
Ensure.that("").isNotEmpty(ERROR_MESSAGE)).isInstanceOf(AssertionError.class);
122141
assertThatThrownBy(() ->
123142
Ensure.that(" ").isNotBlank(ERROR_MESSAGE)).isInstanceOf(AssertionError.class);
143+
assertThatThrownBy(() ->
144+
Ensure.that("").isNotBlank(ERROR_MESSAGE)).isInstanceOf(AssertionError.class);
124145
assertThatThrownBy(() ->
125146
Ensure.that("").isInstanceOf(Integer.class, ERROR_MESSAGE)).isInstanceOf(AssertionError.class);
126147
assertThatThrownBy(() ->

0 commit comments

Comments
 (0)