From f16e3f6a838726ff9744edf3735a501085203483 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 5 Oct 2016 15:41:56 +0200 Subject: [PATCH] Introduce notEmpty(Object[], String) in Preconditions Prior to this commit, precondition checks for "not empty" were supported by the notEmpty(Collection, String) method. However, there was no equivalent support for arrays. This commit introduces a notEmpty(Object[], String) precondition check for arrays. In addition, this commit removes the "no null elements" check from notEmpty(Collection, String) since this behavior is now covered by the recently added containsNoNullElements() variant. Issue: #496 --- .../org/junit/jupiter/api/Assertions.java | 2 +- .../api/extension/ExtensionContext.java | 2 +- .../junit/jupiter/api/AssertionsTests.java | 4 +- .../platform/commons/util/Preconditions.java | 38 +++++++++--- .../descriptor/CompositeTestSource.java | 1 + .../org/junit/platform/launcher/Launcher.java | 2 +- .../launcher/core/DefaultLauncher.java | 2 +- .../commons/util/PreconditionsTests.java | 58 ++++++++++++++----- .../launcher/core/DefaultLauncherTests.java | 31 ++++++++++ 9 files changed, 111 insertions(+), 29 deletions(-) diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java index 3dd98d7bea5..a758a48dd04 100644 --- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java +++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java @@ -1034,7 +1034,7 @@ public static void assertAll(Stream executables) throws MultipleFail */ @API(Experimental) public static void assertAll(String heading, Executable... executables) throws MultipleFailuresError { - Preconditions.notNull(executables, "executables array must not be null"); + Preconditions.notEmpty(executables, "executables array must not be null or empty"); Preconditions.containsNoNullElements(executables, "individual executables must not be null"); assertAll(heading, Arrays.stream(executables)); } diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/ExtensionContext.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/ExtensionContext.java index 4da5cacf28f..0fb195d9dd3 100644 --- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/ExtensionContext.java +++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/extension/ExtensionContext.java @@ -314,7 +314,7 @@ class Namespace { *

Internally the {@code parts} are compared using {@link Object#equals(Object)}. */ public static Namespace create(Object... parts) { - Preconditions.notNull(parts, "parts array must not be null"); + Preconditions.notEmpty(parts, "parts array must not be null or empty"); Preconditions.containsNoNullElements(parts, "individual parts must not be null"); return new Namespace(parts); } diff --git a/junit-jupiter-engine/src/test/java/org/junit/jupiter/api/AssertionsTests.java b/junit-jupiter-engine/src/test/java/org/junit/jupiter/api/AssertionsTests.java index 3771b971e97..1ac86a55822 100644 --- a/junit-jupiter-engine/src/test/java/org/junit/jupiter/api/AssertionsTests.java +++ b/junit-jupiter-engine/src/test/java/org/junit/jupiter/api/AssertionsTests.java @@ -3342,7 +3342,7 @@ void assertAllWithNullInExecutableArray() { // @formatter:on } catch (PreconditionViolationException ex) { - assertMessageEquals(ex, "executables array must not be null"); + assertMessageEquals(ex, "individual executables must not be null"); } } @@ -3352,7 +3352,7 @@ void assertAllWithNullExecutableArray() { assertAll((Executable[]) null); } catch (PreconditionViolationException ex) { - assertMessageEquals(ex, "executables array must not be null"); + assertMessageEquals(ex, "executables array must not be null or empty"); } } diff --git a/junit-platform-commons/src/main/java/org/junit/platform/commons/util/Preconditions.java b/junit-platform-commons/src/main/java/org/junit/platform/commons/util/Preconditions.java index bc0a36b2c9d..17dfd089b9c 100644 --- a/junit-platform-commons/src/main/java/org/junit/platform/commons/util/Preconditions.java +++ b/junit-platform-commons/src/main/java/org/junit/platform/commons/util/Preconditions.java @@ -87,18 +87,40 @@ public static Object[] notNull(Object[] objects, String message) throws Precondi } /** - * Assert that the supplied {@link Collection} is not {@code null} or empty. + * Assert that the supplied array is neither {@code null} nor empty. + * + *

WARNING: this method does NOT check if the supplied + * array contains any {@code null} elements. + * + * @param array the array to check + * @param message precondition violation message + * @return the supplied array as a convenience + * @throws PreconditionViolationException if the supplied array is + * {@code null} or empty + * @see #containsNoNullElements(Object[], String) + * @see #condition(boolean, String) + */ + public static T[] notEmpty(T[] array, String message) throws PreconditionViolationException { + condition(array != null && array.length > 0, message); + return array; + } + + /** + * Assert that the supplied {@link Collection} is neither {@code null} nor empty. + * + *

WARNING: this method does NOT check if the supplied + * collection contains any {@code null} elements. * * @param collection the collection to check * @param message precondition violation message * @return the supplied collection as a convenience * @throws PreconditionViolationException if the supplied collection is {@code null} or empty - * @see #condition(boolean, Supplier) + * @see #containsNoNullElements(Collection, String) + * @see #condition(boolean, String) */ public static > T notEmpty(T collection, String message) throws PreconditionViolationException { - condition(collection != null && !collection.isEmpty(), () -> message); - collection.forEach(object -> notNull(object, () -> message)); + condition(collection != null && !collection.isEmpty(), message); return collection; } @@ -113,11 +135,11 @@ public static > T notEmpty(T collection, String message) * @return the supplied array as a convenience * @throws PreconditionViolationException if the supplied array contains * any {@code null} elements - * @see #notNull(Object, Supplier) + * @see #notNull(Object, String) */ public static T[] containsNoNullElements(T[] array, String message) throws PreconditionViolationException { if (array != null) { - Arrays.stream(array).forEach(object -> notNull(object, () -> message)); + Arrays.stream(array).forEach(object -> notNull(object, message)); } return array; } @@ -133,12 +155,12 @@ public static T[] containsNoNullElements(T[] array, String message) throws P * @return the supplied collection as a convenience * @throws PreconditionViolationException if the supplied collection contains * any {@code null} elements - * @see #notNull(Object, Supplier) + * @see #notNull(Object, String) */ public static > T containsNoNullElements(T collection, String message) throws PreconditionViolationException { if (collection != null) { - collection.forEach(object -> notNull(object, () -> message)); + collection.forEach(object -> notNull(object, message)); } return collection; } diff --git a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/descriptor/CompositeTestSource.java b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/descriptor/CompositeTestSource.java index 425ae4696cb..4e32d1f0d29 100644 --- a/junit-platform-engine/src/main/java/org/junit/platform/engine/support/descriptor/CompositeTestSource.java +++ b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/descriptor/CompositeTestSource.java @@ -49,6 +49,7 @@ public class CompositeTestSource implements TestSource { */ public CompositeTestSource(Collection sources) { Preconditions.notEmpty(sources, "TestSource collection must not be null or empty"); + Preconditions.containsNoNullElements(sources, "individual TestSources must not be null"); this.sources = Collections.unmodifiableList(new ArrayList<>(sources)); } diff --git a/junit-platform-launcher/src/main/java/org/junit/platform/launcher/Launcher.java b/junit-platform-launcher/src/main/java/org/junit/platform/launcher/Launcher.java index ae6cd5183a5..7b0a2d4f5a0 100644 --- a/junit-platform-launcher/src/main/java/org/junit/platform/launcher/Launcher.java +++ b/junit-platform-launcher/src/main/java/org/junit/platform/launcher/Launcher.java @@ -56,7 +56,7 @@ public interface Launcher { * Register one or more listeners for test execution. * * @param listeners the listeners to be notified of test execution events; - * never {@code null} + * never {@code null} or empty */ void registerTestExecutionListeners(TestExecutionListener... listeners); diff --git a/junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/DefaultLauncher.java b/junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/DefaultLauncher.java index 2abd6f0d3f5..98abaf5f6bd 100644 --- a/junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/DefaultLauncher.java +++ b/junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/DefaultLauncher.java @@ -68,7 +68,7 @@ private static Iterable validateUniqueIds(Iterable testE @Override public void registerTestExecutionListeners(TestExecutionListener... listeners) { - Preconditions.notNull(listeners, "listeners array must not be null"); + Preconditions.notEmpty(listeners, "listeners array must not be null or empty"); Preconditions.containsNoNullElements(listeners, "individual listeners must not be null"); this.listenerRegistry.registerListeners(listeners); } diff --git a/platform-tests/src/test/java/org/junit/platform/commons/util/PreconditionsTests.java b/platform-tests/src/test/java/org/junit/platform/commons/util/PreconditionsTests.java index 70215abf269..55f5ee0628e 100644 --- a/platform-tests/src/test/java/org/junit/platform/commons/util/PreconditionsTests.java +++ b/platform-tests/src/test/java/org/junit/platform/commons/util/PreconditionsTests.java @@ -10,6 +10,8 @@ package org.junit.platform.commons.util; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -21,7 +23,6 @@ import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; @@ -46,7 +47,7 @@ void notNullThrowsForNullObject() { @Test void notNullPassesForNonNullObject() { Object object = new Object(); - Object nonNullObject = notNull(object, ""); + Object nonNullObject = notNull(object, "message"); assertSame(object, nonNullObject); } @@ -80,14 +81,14 @@ void notNullForNullObjectArrayWithCustomMessage() { @Test void notNullPassesForEmptyObjectArray() { Object[] objects = new Object[0]; - Object nonNullObjects = notNull(objects, ""); + Object nonNullObjects = notNull(objects, "message"); assertSame(objects, nonNullObjects); } @Test void notNullPassesForObjectArrayContainingObjects() { Object[] objects = { new Object(), new Object(), new Object() }; - Object nonNullObjects = notNull(objects, ""); + Object nonNullObjects = notNull(objects, "message"); assertSame(objects, nonNullObjects); } @@ -102,39 +103,66 @@ void notNullThrowsForObjectArrayContainingNulls() { assertEquals(message, exception.getMessage()); } + @Test + void notEmptyPassesForNonEmptyArray() { + String[] array = new String[] { "a", "b", "c" }; + String[] nonEmptyArray = notEmpty(array, "message"); + assertSame(array, nonEmptyArray); + } + @Test void notEmptyPassesForNonEmptyCollection() { Collection collection = Arrays.asList("a", "b", "c"); - Collection nonEmptyCollection = notEmpty(collection, ""); + Collection nonEmptyCollection = notEmpty(collection, "message"); assertSame(collection, nonEmptyCollection); } + @Test + void notEmptyPassesForArrayWithNullElements() { + notEmpty(new String[] { null }, "message"); + } + + @Test + void notEmptyPassesForCollectionWithNullElements() { + notEmpty(singletonList(null), "message"); + } + + @Test + void notEmptyThrowsForNullArray() { + String message = "array is empty"; + + PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, + () -> notEmpty((Object[]) null, message)); + + assertEquals(message, exception.getMessage()); + } + @Test void notEmptyThrowsForNullCollection() { String message = "collection is empty"; PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, - () -> notEmpty(null, message)); + () -> notEmpty((Collection) null, message)); assertEquals(message, exception.getMessage()); } @Test - void notEmptyThrowsForEmptyCollection() { - String message = "collection is empty"; + void notEmptyThrowsForEmptyArray() { + String message = "array is empty"; PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, - () -> notEmpty(Collections.emptyList(), message)); + () -> notEmpty(new Object[0], message)); assertEquals(message, exception.getMessage()); } @Test - void notEmptyThrowsForCollectionWithNullElements() { - String message = "collection contains null elements"; + void notEmptyThrowsForEmptyCollection() { + String message = "collection is empty"; PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, - () -> notEmpty(Collections.singletonList(null), message)); + () -> notEmpty(emptyList(), message)); assertEquals(message, exception.getMessage()); } @@ -148,7 +176,7 @@ void containsNoNullElementsPassesForArrayThatIsNullOrEmpty() { @Test void containsNoNullElementsPassesForCollectionThatIsNullOrEmpty() { containsNoNullElements((List) null, "collection is null"); - containsNoNullElements(Collections.emptyList(), "collection is empty"); + containsNoNullElements(emptyList(), "collection is empty"); } @Test @@ -181,7 +209,7 @@ void containsNoNullElementsThrowsForCollectionContainingNullElements() { String message = "collection contains null elements"; PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, - () -> containsNoNullElements(Collections.singletonList(null), message)); + () -> containsNoNullElements(singletonList(null), message)); assertEquals(message, exception.getMessage()); } @@ -189,7 +217,7 @@ void containsNoNullElementsThrowsForCollectionContainingNullElements() { @Test void notBlankPassesForNonBlankString() { String string = "abc"; - String nonBlankString = notBlank(string, ""); + String nonBlankString = notBlank(string, "message"); assertSame(string, nonBlankString); } diff --git a/platform-tests/src/test/java/org/junit/platform/launcher/core/DefaultLauncherTests.java b/platform-tests/src/test/java/org/junit/platform/launcher/core/DefaultLauncherTests.java index 21309d9db80..8093b43dc35 100644 --- a/platform-tests/src/test/java/org/junit/platform/launcher/core/DefaultLauncherTests.java +++ b/platform-tests/src/test/java/org/junit/platform/launcher/core/DefaultLauncherTests.java @@ -37,6 +37,7 @@ import org.junit.platform.engine.test.TestEngineStub; import org.junit.platform.launcher.PostDiscoveryFilter; import org.junit.platform.launcher.PostDiscoveryFilterStub; +import org.junit.platform.launcher.TestExecutionListener; import org.junit.platform.launcher.TestIdentifier; import org.junit.platform.launcher.TestPlan; @@ -67,6 +68,36 @@ void constructLauncherWithMultipleTestEnginesWithDuplicateIds() { assertThat(exception).hasMessageContaining("multiple engines with the same ID"); } + @Test + void registerTestExecutionListenersWithNullArray() { + DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine("dummy id")); + + PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, + () -> launcher.registerTestExecutionListeners((TestExecutionListener[]) null)); + + assertThat(exception).hasMessageContaining("listeners array must not be null or empty"); + } + + @Test + void registerTestExecutionListenersWithEmptyArray() { + DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine("dummy id")); + + PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, + () -> launcher.registerTestExecutionListeners(new TestExecutionListener[0])); + + assertThat(exception).hasMessageContaining("listeners array must not be null or empty"); + } + + @Test + void registerTestExecutionListenersWithArrayContainingNullElements() { + DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine("dummy id")); + + PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, + () -> launcher.registerTestExecutionListeners(new TestExecutionListener[] { null })); + + assertThat(exception).hasMessageContaining("individual listeners must not be null"); + } + @Test void discoverEmptyTestPlanWithEngineWithoutAnyTests() { DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine());