Skip to content

Commit

Permalink
Introduce notEmpty(Object[], String) in Preconditions
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sbrannen committed Oct 5, 2016
1 parent d3bb779 commit f16e3f6
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 29 deletions.
Expand Up @@ -1034,7 +1034,7 @@ public static void assertAll(Stream<Executable> executables) throws MultipleFail
*/ */
@API(Experimental) @API(Experimental)
public static void assertAll(String heading, Executable... executables) throws MultipleFailuresError { 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"); Preconditions.containsNoNullElements(executables, "individual executables must not be null");
assertAll(heading, Arrays.stream(executables)); assertAll(heading, Arrays.stream(executables));
} }
Expand Down
Expand Up @@ -314,7 +314,7 @@ class Namespace {
* <p>Internally the {@code parts} are compared using {@link Object#equals(Object)}. * <p>Internally the {@code parts} are compared using {@link Object#equals(Object)}.
*/ */
public static Namespace create(Object... parts) { 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"); Preconditions.containsNoNullElements(parts, "individual parts must not be null");
return new Namespace(parts); return new Namespace(parts);
} }
Expand Down
Expand Up @@ -3342,7 +3342,7 @@ void assertAllWithNullInExecutableArray() {
// @formatter:on // @formatter:on
} }
catch (PreconditionViolationException ex) { catch (PreconditionViolationException ex) {
assertMessageEquals(ex, "executables array must not be null"); assertMessageEquals(ex, "individual executables must not be null");
} }
} }


Expand All @@ -3352,7 +3352,7 @@ void assertAllWithNullExecutableArray() {
assertAll((Executable[]) null); assertAll((Executable[]) null);
} }
catch (PreconditionViolationException ex) { catch (PreconditionViolationException ex) {
assertMessageEquals(ex, "executables array must not be null"); assertMessageEquals(ex, "executables array must not be null or empty");
} }
} }


Expand Down
Expand Up @@ -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 <em>empty</em>.
*
* <p><strong>WARNING</strong>: 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 <em>empty</em>
* @see #containsNoNullElements(Object[], String)
* @see #condition(boolean, String)
*/
public static <T> 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.
*
* <p><strong>WARNING</strong>: this method does NOT check if the supplied
* collection contains any {@code null} elements.
* *
* @param collection the collection to check * @param collection the collection to check
* @param message precondition violation message * @param message precondition violation message
* @return the supplied collection as a convenience * @return the supplied collection as a convenience
* @throws PreconditionViolationException if the supplied collection is {@code null} or empty * @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 extends Collection<?>> T notEmpty(T collection, String message) public static <T extends Collection<?>> T notEmpty(T collection, String message)
throws PreconditionViolationException { throws PreconditionViolationException {
condition(collection != null && !collection.isEmpty(), () -> message); condition(collection != null && !collection.isEmpty(), message);
collection.forEach(object -> notNull(object, () -> message));
return collection; return collection;
} }


Expand All @@ -113,11 +135,11 @@ public static <T extends Collection<?>> T notEmpty(T collection, String message)
* @return the supplied array as a convenience * @return the supplied array as a convenience
* @throws PreconditionViolationException if the supplied array contains * @throws PreconditionViolationException if the supplied array contains
* any {@code null} elements * any {@code null} elements
* @see #notNull(Object, Supplier) * @see #notNull(Object, String)
*/ */
public static <T> T[] containsNoNullElements(T[] array, String message) throws PreconditionViolationException { public static <T> T[] containsNoNullElements(T[] array, String message) throws PreconditionViolationException {
if (array != null) { if (array != null) {
Arrays.stream(array).forEach(object -> notNull(object, () -> message)); Arrays.stream(array).forEach(object -> notNull(object, message));
} }
return array; return array;
} }
Expand All @@ -133,12 +155,12 @@ public static <T> T[] containsNoNullElements(T[] array, String message) throws P
* @return the supplied collection as a convenience * @return the supplied collection as a convenience
* @throws PreconditionViolationException if the supplied collection contains * @throws PreconditionViolationException if the supplied collection contains
* any {@code null} elements * any {@code null} elements
* @see #notNull(Object, Supplier) * @see #notNull(Object, String)
*/ */
public static <T extends Collection<?>> T containsNoNullElements(T collection, String message) public static <T extends Collection<?>> T containsNoNullElements(T collection, String message)
throws PreconditionViolationException { throws PreconditionViolationException {
if (collection != null) { if (collection != null) {
collection.forEach(object -> notNull(object, () -> message)); collection.forEach(object -> notNull(object, message));
} }
return collection; return collection;
} }
Expand Down
Expand Up @@ -49,6 +49,7 @@ public class CompositeTestSource implements TestSource {
*/ */
public CompositeTestSource(Collection<? extends TestSource> sources) { public CompositeTestSource(Collection<? extends TestSource> sources) {
Preconditions.notEmpty(sources, "TestSource collection must not be null or empty"); 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)); this.sources = Collections.unmodifiableList(new ArrayList<>(sources));
} }


Expand Down
Expand Up @@ -56,7 +56,7 @@ public interface Launcher {
* Register one or more listeners for test execution. * Register one or more listeners for test execution.
* *
* @param listeners the listeners to be notified of test execution events; * @param listeners the listeners to be notified of test execution events;
* never {@code null} * never {@code null} or empty
*/ */
void registerTestExecutionListeners(TestExecutionListener... listeners); void registerTestExecutionListeners(TestExecutionListener... listeners);


Expand Down
Expand Up @@ -68,7 +68,7 @@ private static Iterable<TestEngine> validateUniqueIds(Iterable<TestEngine> testE


@Override @Override
public void registerTestExecutionListeners(TestExecutionListener... listeners) { 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"); Preconditions.containsNoNullElements(listeners, "individual listeners must not be null");
this.listenerRegistry.registerListeners(listeners); this.listenerRegistry.registerListeners(listeners);
} }
Expand Down
Expand Up @@ -10,6 +10,8 @@


package org.junit.platform.commons.util; 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.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
Expand All @@ -21,7 +23,6 @@


import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;


import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
Expand All @@ -46,7 +47,7 @@ void notNullThrowsForNullObject() {
@Test @Test
void notNullPassesForNonNullObject() { void notNullPassesForNonNullObject() {
Object object = new Object(); Object object = new Object();
Object nonNullObject = notNull(object, ""); Object nonNullObject = notNull(object, "message");
assertSame(object, nonNullObject); assertSame(object, nonNullObject);
} }


Expand Down Expand Up @@ -80,14 +81,14 @@ void notNullForNullObjectArrayWithCustomMessage() {
@Test @Test
void notNullPassesForEmptyObjectArray() { void notNullPassesForEmptyObjectArray() {
Object[] objects = new Object[0]; Object[] objects = new Object[0];
Object nonNullObjects = notNull(objects, ""); Object nonNullObjects = notNull(objects, "message");
assertSame(objects, nonNullObjects); assertSame(objects, nonNullObjects);
} }


@Test @Test
void notNullPassesForObjectArrayContainingObjects() { void notNullPassesForObjectArrayContainingObjects() {
Object[] objects = { new Object(), new Object(), new Object() }; Object[] objects = { new Object(), new Object(), new Object() };
Object nonNullObjects = notNull(objects, ""); Object nonNullObjects = notNull(objects, "message");
assertSame(objects, nonNullObjects); assertSame(objects, nonNullObjects);
} }


Expand All @@ -102,39 +103,66 @@ void notNullThrowsForObjectArrayContainingNulls() {
assertEquals(message, exception.getMessage()); assertEquals(message, exception.getMessage());
} }


@Test
void notEmptyPassesForNonEmptyArray() {
String[] array = new String[] { "a", "b", "c" };
String[] nonEmptyArray = notEmpty(array, "message");
assertSame(array, nonEmptyArray);
}

@Test @Test
void notEmptyPassesForNonEmptyCollection() { void notEmptyPassesForNonEmptyCollection() {
Collection<String> collection = Arrays.asList("a", "b", "c"); Collection<String> collection = Arrays.asList("a", "b", "c");
Collection<String> nonEmptyCollection = notEmpty(collection, ""); Collection<String> nonEmptyCollection = notEmpty(collection, "message");
assertSame(collection, nonEmptyCollection); 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 @Test
void notEmptyThrowsForNullCollection() { void notEmptyThrowsForNullCollection() {
String message = "collection is empty"; String message = "collection is empty";


PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, PreconditionViolationException exception = assertThrows(PreconditionViolationException.class,
() -> notEmpty(null, message)); () -> notEmpty((Collection<?>) null, message));


assertEquals(message, exception.getMessage()); assertEquals(message, exception.getMessage());
} }


@Test @Test
void notEmptyThrowsForEmptyCollection() { void notEmptyThrowsForEmptyArray() {
String message = "collection is empty"; String message = "array is empty";


PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, PreconditionViolationException exception = assertThrows(PreconditionViolationException.class,
() -> notEmpty(Collections.emptyList(), message)); () -> notEmpty(new Object[0], message));


assertEquals(message, exception.getMessage()); assertEquals(message, exception.getMessage());
} }


@Test @Test
void notEmptyThrowsForCollectionWithNullElements() { void notEmptyThrowsForEmptyCollection() {
String message = "collection contains null elements"; String message = "collection is empty";


PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, PreconditionViolationException exception = assertThrows(PreconditionViolationException.class,
() -> notEmpty(Collections.singletonList(null), message)); () -> notEmpty(emptyList(), message));


assertEquals(message, exception.getMessage()); assertEquals(message, exception.getMessage());
} }
Expand All @@ -148,7 +176,7 @@ void containsNoNullElementsPassesForArrayThatIsNullOrEmpty() {
@Test @Test
void containsNoNullElementsPassesForCollectionThatIsNullOrEmpty() { void containsNoNullElementsPassesForCollectionThatIsNullOrEmpty() {
containsNoNullElements((List<?>) null, "collection is null"); containsNoNullElements((List<?>) null, "collection is null");
containsNoNullElements(Collections.emptyList(), "collection is empty"); containsNoNullElements(emptyList(), "collection is empty");
} }


@Test @Test
Expand Down Expand Up @@ -181,15 +209,15 @@ void containsNoNullElementsThrowsForCollectionContainingNullElements() {
String message = "collection contains null elements"; String message = "collection contains null elements";


PreconditionViolationException exception = assertThrows(PreconditionViolationException.class, PreconditionViolationException exception = assertThrows(PreconditionViolationException.class,
() -> containsNoNullElements(Collections.singletonList(null), message)); () -> containsNoNullElements(singletonList(null), message));


assertEquals(message, exception.getMessage()); assertEquals(message, exception.getMessage());
} }


@Test @Test
void notBlankPassesForNonBlankString() { void notBlankPassesForNonBlankString() {
String string = "abc"; String string = "abc";
String nonBlankString = notBlank(string, ""); String nonBlankString = notBlank(string, "message");
assertSame(string, nonBlankString); assertSame(string, nonBlankString);
} }


Expand Down
Expand Up @@ -37,6 +37,7 @@
import org.junit.platform.engine.test.TestEngineStub; import org.junit.platform.engine.test.TestEngineStub;
import org.junit.platform.launcher.PostDiscoveryFilter; import org.junit.platform.launcher.PostDiscoveryFilter;
import org.junit.platform.launcher.PostDiscoveryFilterStub; import org.junit.platform.launcher.PostDiscoveryFilterStub;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier; import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan; import org.junit.platform.launcher.TestPlan;


Expand Down Expand Up @@ -67,6 +68,36 @@ void constructLauncherWithMultipleTestEnginesWithDuplicateIds() {
assertThat(exception).hasMessageContaining("multiple engines with the same ID"); 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 @Test
void discoverEmptyTestPlanWithEngineWithoutAnyTests() { void discoverEmptyTestPlanWithEngineWithoutAnyTests() {
DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine()); DefaultLauncher launcher = createLauncher(new DemoHierarchicalTestEngine());
Expand Down

0 comments on commit f16e3f6

Please sign in to comment.