diff --git a/src/main/java/org/assertj/core/api/AbstractIterableAssert.java b/src/main/java/org/assertj/core/api/AbstractIterableAssert.java index f56aed463b..dc5eb14f82 100644 --- a/src/main/java/org/assertj/core/api/AbstractIterableAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractIterableAssert.java @@ -139,7 +139,6 @@ protected static Iterable toLazyIterable(Iterator actual) { * @return a new {@link AbstractListAssert}. */ protected AbstractListAssert, E, ObjectAssert> newListAssertInstance(List newActual) { - // this might not be the best implementation (SoftAssertion needs to override this). return new ListAssert<>(newActual); } @@ -1355,7 +1354,7 @@ public AbstractListAssert, Object, ObjectAssert result = actualStream.flatMap(element -> Stream.of(extractors) .map(extractor -> extractor.extract(element))) .collect(Collectors.toList()); - return new ListAssert<>(result); + return newListAssertInstance(result); } /** @@ -1399,7 +1398,7 @@ public AbstractListAssert result = actualStream.flatMap(element -> Stream.of(extractors) .map(extractor -> extractor.extract(element))) .collect(Collectors.toList()); - return new ListAssert<>(result); + return newListAssertInstance(result); } /** @@ -2077,9 +2076,11 @@ public AbstractListAssert, ELEMENT, ObjectAssert, ELEMENT, ObjectAssert> filteredOnNull(String propertyOrFieldName) { - // need to cast nulll to Object otherwise it calls : - // filteredOn(String propertyOrFieldName, FilterOperation filterOperation) - return filteredOn(propertyOrFieldName, (Object) null); + // can't call filteredOn(String propertyOrFieldName, null) as it does not work with soft assertions proxying + // mechanism, it would lead to double proxying which is not handle properly (improvements needed in our proxy mechanism) + Filters filter = filter((Iterable) actual); + Iterable filteredIterable = filter.with(propertyOrFieldName, null).get(); + return newListAssertInstance(newArrayList(filteredIterable)); } /** @@ -2234,6 +2235,8 @@ public AbstractListAssert, ELEMENT, ObjectAssert + *

+ * Warning: this method does not work with soft assertions or assumptions. * * @return the assertion on the first element * @throws AssertionError if the actual {@link Iterable} is empty. @@ -2281,6 +2284,8 @@ public ELEMENT_ASSERT first() { * // assertion fails * assertThat(hobbits, StringAssert.class).last() * .startsWith("fro"); + *

+ * Warning: this method does not work with soft assertions or assumptions. * * @return the assertion on the first element * @throws AssertionError if the actual {@link Iterable} is empty. @@ -2341,6 +2346,8 @@ private ELEMENT lastElement() { * // assertion fails * assertThat(hobbits, StringAssert.class).element(1) * .startsWith("fro"); + *

+ * Warning: this method does not work with soft assertions or assumptions. * * @param index the element's index * @return the assertion on the given element @@ -2401,7 +2408,7 @@ private static String removeAssert(String text) { */ public AbstractListAssert, ELEMENT, ObjectAssert> filteredOn(Predicate predicate) { checkArgument(predicate != null, "The filter predicate should not be null"); - return new ListAssert<>(stream(actual.spliterator(), false).filter(predicate).collect(toList())); + return newListAssertInstance(stream(actual.spliterator(), false).filter(predicate).collect(toList())); } /** @@ -2680,6 +2687,8 @@ public SELF withThreadDumpOnError() { * * // assertion will fail: * assertThat(elvesRings).size().isGreaterThan(3); + *

+ * Warning: this method does not work with soft assertions or assumptions. * * @return AbstractIterableSizeAssert built with the {@code Iterable}'s size. * @throws NullPointerException if the given {@code Iterable} is {@code null}. diff --git a/src/main/java/org/assertj/core/api/AbstractMapAssert.java b/src/main/java/org/assertj/core/api/AbstractMapAssert.java index 26c8c49590..fa8cfa1ed8 100644 --- a/src/main/java/org/assertj/core/api/AbstractMapAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractMapAssert.java @@ -13,7 +13,9 @@ package org.assertj.core.api; import static org.assertj.core.data.MapEntry.entry; +import static org.assertj.core.description.Description.mostRelevantDescription; import static org.assertj.core.extractor.Extractors.byName; +import static org.assertj.core.extractor.Extractors.extractedDescriptionOf; import static org.assertj.core.util.Arrays.array; import static org.assertj.core.util.Arrays.isArray; import static org.assertj.core.util.IterableUtil.toCollection; @@ -1191,6 +1193,8 @@ public SELF withThreadDumpOnError() { * * // assertion will fail: * assertThat(ringBearers).size().isGreaterThan(5); + *

+ * Warning: this method does not work with soft assertions or assumptions. * * @return a {@link AbstractMapSizeAssert} to allow assertions on the the number of key-value mappings in this map * @throws NullPointerException if the given map is {@code null}. @@ -1229,7 +1233,7 @@ public AbstractMapSizeAssert size() { */ @CheckReturnValue @Override - public AbstractObjectArrayAssert extracting(String... keys) { + public AbstractListAssert, Object, ObjectAssert> extracting(String... keys) { return super.extracting(keys); } @@ -1255,7 +1259,7 @@ public AbstractObjectArrayAssert extracting(String... keys) { * assertThat(map).flatExtracting("name","job","city", "rank") * .containsExactly("Dave", "Jeff", * "Plumber", "Builder", - * "Dover", "Boston", "Paris" + * "Dover", "Boston", "Paris", * 1, 2, 3); * * // the order of values in the resulting array is the order of map keys then key values: @@ -1279,10 +1283,12 @@ public AbstractObjectArrayAssert extracting(String... keys) { * @return a new assertion object whose object under test is the array containing the extracted flattened map values */ @CheckReturnValue - public AbstractObjectArrayAssert flatExtracting(String... keys) { + public AbstractListAssert, Object, ObjectAssert> flatExtracting(String... keys) { Tuple values = byName(keys).extract(actual); List valuesFlattened = flatten(values.toList()); - return extracting(valuesFlattened, keys); + String extractedPropertiesOrFieldsDescription = extractedDescriptionOf(keys); + String description = mostRelevantDescription(info.description(), extractedPropertiesOrFieldsDescription); + return newListAssertInstance(valuesFlattened).as(description); } private static List flatten(Iterable collectionToFlatten) { diff --git a/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java index a37b8f542a..d41388c093 100644 --- a/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java @@ -13,6 +13,7 @@ package org.assertj.core.api; import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toList; import static org.assertj.core.api.filter.Filters.filter; import static org.assertj.core.description.Description.mostRelevantDescription; import static org.assertj.core.extractor.Extractors.byName; @@ -65,7 +66,6 @@ import org.assertj.core.internal.TypeComparators; import org.assertj.core.presentation.PredicateDescription; import org.assertj.core.util.CheckReturnValue; -import org.assertj.core.util.IterableUtil; import org.assertj.core.util.VisibleForTesting; import org.assertj.core.util.introspection.IntrospectionError; @@ -1821,8 +1821,8 @@ public SELF usingElementComparatorIgnoringFields(String... fields) { } /** - * Extract the values of given field or property from the array's elements under test into a new array, this new array - * becoming the array under test. + * Extract the values of given field or property from the array's elements under test into a new list, this new list + * becoming the object under test. *

* It allows you to test a field/property of the array's elements instead of testing the elements themselves, which can * be much less work ! @@ -1859,20 +1859,20 @@ public SELF usingElementComparatorIgnoringFields(String... fields) { * Note that the order of extracted field/property values is consistent with the array order. * * @param fieldOrProperty the field/property to extract from the array under test - * @return a new assertion object whose object under test is the array of extracted field/property values. + * @return a new assertion object whose object under test is the list of extracted field/property values. * @throws IntrospectionError if no field or property exists with the given name */ @CheckReturnValue - public ObjectArrayAssert extracting(String fieldOrProperty) { + public AbstractListAssert, Object, ObjectAssert> extracting(String fieldOrProperty) { Object[] values = FieldsOrPropertiesExtractor.extract(actual, byName(fieldOrProperty)); String extractedDescription = extractedDescriptionOf(fieldOrProperty); String description = mostRelevantDescription(info.description(), extractedDescription); - return new ObjectArrayAssert<>(values).as(description); + return newListAssertInstance(newArrayList(values)).as(description); } /** - * Extract the values of given field or property from the array's elements under test into a new array, this new array - * becoming the array under test with type. + * Extract the values of given field or property from the array's elements under test into a new list, this new list of the provided type + * becoming the object under test. *

* It allows you to test a field/property of the array's elements instead of testing the elements themselves, which can * be much less work ! @@ -1911,21 +1911,22 @@ public ObjectArrayAssert extracting(String fieldOrProperty) { * @param

the type of elements to extract. * @param fieldOrProperty the field/property to extract from the array under test * @param extractingType type to return - * @return a new assertion object whose object under test is the array of extracted field/property values. + * @return a new assertion object whose object under test is the list of extracted field/property values. * @throws IntrospectionError if no field or property exists with the given name */ @CheckReturnValue - public

ObjectArrayAssert

extracting(String fieldOrProperty, Class

extractingType) { + public

AbstractListAssert, P, ObjectAssert

> extracting(String fieldOrProperty, + Class

extractingType) { @SuppressWarnings("unchecked") - P[] values = (P[]) FieldsOrPropertiesExtractor.extract(actual, byName(fieldOrProperty)); + List

values = (List

) FieldsOrPropertiesExtractor.extract(Arrays.asList(actual), byName(fieldOrProperty)); String extractedDescription = extractedDescriptionOf(fieldOrProperty); String description = mostRelevantDescription(info.description(), extractedDescription); - return new ObjectArrayAssert<>(values).as(description); + return newListAssertInstance(values).as(description); } /** - * Extract the values of given fields/properties from the array's elements under test into a new array composed of - * Tuple (a simple data structure), this new array becoming the array under test. + * Extract the values of given fields/properties from the array's elements under test into a list composed of + * Tuple (a simple data structure), this new list becoming the object under test. *

* It allows you to test fields/properties of the the array's elements instead of testing the elements themselves, it * can be sometimes much less work ! @@ -1970,26 +1971,22 @@ public

ObjectArrayAssert

extracting(String fieldOrProperty, Class

extr * test. * * @param propertiesOrFields the properties/fields to extract from the initial array under test - * @return a new assertion object whose object under test is the list of Tuple with extracted properties/fields values - * as data. - * @throws IntrospectionError if one of the given name does not match a field or property in one of the initial - * Iterable's element. + * @return a new assertion object whose object under test is the list of Tuple with extracted properties/fields values as data. + * @throws IntrospectionError if one of the given name does not match a field or property in one of the initial Iterable's element. */ @CheckReturnValue - public ObjectArrayAssert extracting(String... propertiesOrFields) { - Object[] values = FieldsOrPropertiesExtractor.extract(actual, byName(propertiesOrFields)); - Tuple[] result = Arrays.copyOf(values, values.length, Tuple[].class); - String extractedPropertiesOrFieldsDescription = extractedDescriptionOf(propertiesOrFields); - String description = mostRelevantDescription(info.description(), extractedPropertiesOrFieldsDescription); - return new ObjectArrayAssert<>(result).as(description); + public AbstractListAssert, Tuple, ObjectAssert> extracting(String... propertiesOrFields) { + List values = FieldsOrPropertiesExtractor.extract(Arrays.asList(actual), byName(propertiesOrFields)); + String extractedDescription = extractedDescriptionOf(propertiesOrFields); + String description = mostRelevantDescription(info.description(), extractedDescription); + return newListAssertInstance(values).as(description); } /** - * Extract the values from the array's elements by applying an extracting function on them. The returned - * array becomes a new object under test. + * Extract the values from the array's elements by applying an extracting function on them, the resulting list becomes + * the new object under test. *

- * It allows to test values from the elements in safer way than by using {@link #extracting(String)}, as it - * doesn't utilize introspection. + * This method is similar to {@link #extracting(String)} but more refactoring friendly as it does not use introspection. *

* Let's take a look an example: *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
@@ -2014,23 +2011,22 @@ public ObjectArrayAssert extracting(String... propertiesOrFields) {
    *
    * @param  the type of elements to extract.
    * @param extractor the object transforming input object to desired one
-   * @return a new assertion object whose object under test is the list of values extracted
+   * @return a new assertion object whose object under test is the list of extracted values. 
    */
   @CheckReturnValue
-  public  ObjectArrayAssert extracting(Extractor extractor) {
-    U[] extracted = FieldsOrPropertiesExtractor.extract(actual, extractor);
-
-    return new ObjectArrayAssert<>(extracted);
+  public  AbstractListAssert, U, ObjectAssert> extracting(Extractor extractor) {
+    List values = FieldsOrPropertiesExtractor.extract(Arrays.asList(actual), extractor);
+    return newListAssertInstance(values);
   }
 
   /**
    * Extract the values from the array's elements by applying an extracting function (which might throw an exception)
-   * on them. The returned array becomes a new object under test.
+   * on them, the resulting list of extracted values becomes a new object under test.
    * 

* Any checked exception raised in the extractor is rethrown wrapped in a {@link RuntimeException}. *

* It allows to test values from the elements in safer way than by using {@link #extracting(String)}, as it - * doesn't utilize introspection. + * doesn't use introspection. *

* Let's take a look an example: *

 // Build a list of TolkienCharacter, a TolkienCharacter has a name, and age and a Race (a specific class)
@@ -2052,26 +2048,24 @@ public  ObjectArrayAssert extracting(Extractor extract
    *   }
    *   return input.getName();
    * }).contains("Frodo");
+ *

+ * Note that the order of extracted property/field values is consistent with the iteration order of the array under test. * - * Note that the order of extracted property/field values is consistent with the iteration order of the Iterable under - * test, for example if it's a {@link HashSet}, you won't be able to make any assumptions on the extracted values - * order. - * - * @param the type of elements to extract. + * @param the type of elements to extract. * @param the exception type of {@link ThrowingExtractor} * @param extractor the object transforming input object to desired one - * @return a new assertion object whose object under test is the list of values extracted + * @return a new assertion object whose object under test is the list of extracted values * @since 3.7.0 */ - public ObjectArrayAssert extracting(ThrowingExtractor extractor) { - U[] extracted = FieldsOrPropertiesExtractor.extract(actual, extractor); - - return new ObjectArrayAssert<>(extracted); + @CheckReturnValue + public AbstractListAssert, V, ObjectAssert> extracting(ThrowingExtractor extractor) { + List values = FieldsOrPropertiesExtractor.extract(newArrayList(actual), extractor); + return newListAssertInstance(values); } /** - * Use the given {@link Function}s to extract the values from the array's elements into a new array - * composed of {@link Tuple}s (a simple data structure containing the extracted values), this new array becoming the + * Use the given {@link Function}s to extract the values from the array's elements into a new list + * composed of {@link Tuple}s (a simple data structure containing the extracted values), this new list becoming the * object under test. *

* It allows you to test values from the array's elements instead of testing the elements themselves, which sometimes can be @@ -2079,8 +2073,7 @@ public ObjectArrayAssert extracting(Throwing *

* The {@link Tuple} data corresponds to the extracted values from the arrays's elements, for instance if you pass functions * extracting "id", "name" and "email" values then each {@link Tuple}'s data will be composed of an id, a name and an email - * extracted from the element of the initial array (the Tuple's data order is the same as the given functions - * order). + * extracted from the element of the initial array (the Tuple's data order is the same as the given functions order). *

* Let's take a look at an example to make things clearer : *

 // Build an array of TolkienCharacter, a TolkienCharacter has a name (String) and a Race (a class)
@@ -2116,16 +2109,16 @@ public  ObjectArrayAssert extracting(Throwing
    * for example if it's a {@link HashSet}, you won't be able to make any assumptions on the extracted tuples order.
    *
    * @param extractors the extractor functions to extract a value from an element of the array under test.
-   * @return a new assertion object whose object under test is the array of Tuples containing the extracted values.
+   * @return a new assertion object whose object under test is the list of Tuples containing the extracted values.
    */
   @CheckReturnValue
-  public ObjectArrayAssert extracting(@SuppressWarnings("unchecked") Function... extractors) {
+  public AbstractListAssert, Tuple, ObjectAssert> extracting(@SuppressWarnings("unchecked") Function... extractors) {
 
     Function tupleExtractor = objectToExtractValueFrom -> new Tuple(Stream.of(extractors)
                                                                                           .map(extractor -> extractor.apply(objectToExtractValueFrom))
                                                                                           .toArray());
-    Tuple[] tuples = stream(actual).map(tupleExtractor).toArray(size -> new Tuple[size]);
-    return new ObjectArrayAssert<>(tuples);
+    List tuples = stream(actual).map(tupleExtractor).collect(toList());
+    return newListAssertInstance(tuples).as(info.description());
   }
 
   /**
@@ -2159,7 +2152,7 @@ public ObjectArrayAssert extracting(@SuppressWarnings("unchecked") Functi
    * @return a new assertion object whose object under test is the list of values extracted
    */
   @CheckReturnValue
-  public > ObjectArrayAssert flatExtracting(Extractor extractor) {
+  public > AbstractListAssert, V, ObjectAssert> flatExtracting(Extractor extractor) {
     return doFlatExtracting(extractor);
   }
 
@@ -2193,7 +2186,7 @@ public > ObjectArrayAssert flatExtracting(Extracto
    * The order of extracted values is consisted with both the order of the collection itself, as well as the extracted
    * collections.
    *
-   * @param  the type of elements to extract.
+   * @param  the type of elements to extract.
    * @param  the type of collection to flat/extract.
    * @param  the exception type of {@link ThrowingExtractor}
    * @param extractor the object transforming input object to an Iterable of desired ones
@@ -2201,19 +2194,19 @@ public > ObjectArrayAssert flatExtracting(Extracto
    * @since 3.7.0
    */
   @CheckReturnValue
-  public , EXCEPTION extends Exception> ObjectArrayAssert flatExtracting(ThrowingExtractor extractor) {
+  public , EXCEPTION extends Exception> AbstractListAssert, V, ObjectAssert> flatExtracting(ThrowingExtractor extractor) {
     return doFlatExtracting(extractor);
   }
 
-  private > ObjectArrayAssert doFlatExtracting(Extractor extractor) {
+  private > AbstractListAssert, V, ObjectAssert> doFlatExtracting(Extractor extractor) {
     final List extractedValues = FieldsOrPropertiesExtractor.extract(Arrays.asList(actual), extractor);
 
-    final List result = newArrayList();
+    final List result = newArrayList();
     for (C e : extractedValues) {
       result.addAll(e);
     }
 
-    return new ObjectArrayAssert<>(IterableUtil.toArray(result));
+    return newListAssertInstance(result);
   }
 
   /**
@@ -2246,7 +2239,7 @@ private > ObjectArrayAssert doFlatExtracting(Extra
    * @throws IllegalArgumentException if one of the extracted property value was not an array or an iterable.
    */
   @CheckReturnValue
-  public ObjectArrayAssert flatExtracting(String propertyName) {
+  public AbstractListAssert, Object, ObjectAssert> flatExtracting(String propertyName) {
     List extractedValues = newArrayList();
     List extractedGroups = FieldsOrPropertiesExtractor.extract(Arrays.asList(actual), byName(propertyName));
     for (Object group : extractedGroups) {
@@ -2265,12 +2258,12 @@ public ObjectArrayAssert flatExtracting(String propertyName) {
         CommonErrors.wrongElementTypeForFlatExtracting(group);
       }
     }
-    return new ObjectArrayAssert<>(extractedValues.toArray());
+    return newListAssertInstance(extractedValues);
   }
 
   /**
-   * Extract the result of given method invocation from the array's elements under test into a new array, this new array
-   * becoming the array under test.
+   * Extract the result of given method invocation from the array's elements under test into a list, this list becoming 
+   * the object under test.
    * 

* It allows you to test a method results of the array's elements instead of testing the elements themselves, which can be * much less work! @@ -2301,21 +2294,21 @@ public ObjectArrayAssert flatExtracting(String propertyName) { * Note that the order of extracted values is consistent with the order of the array under test. * * @param method the name of the method which result is to be extracted from the array under test - * @return a new assertion object whose object under test is the array of extracted values. + * @return a new assertion object whose object under test is the list of extracted values. * @throws IllegalArgumentException if no method exists with the given name, or method is not public, or method does * return void, or method accepts arguments. */ @CheckReturnValue - public ObjectArrayAssert extractingResultOf(String method) { + public AbstractListAssert, Object, ObjectAssert> extractingResultOf(String method) { Object[] values = FieldsOrPropertiesExtractor.extract(actual, resultOf(method)); String extractedDescription = extractedDescriptionOfMethod(method); String description = mostRelevantDescription(info.description(), extractedDescription); - return new ObjectArrayAssert<>(values).as(description); + return newListAssertInstance(newArrayList(values)).as(description); } /** - * Extract the result of given method invocation from the array's elements under test into a new array, this new array - * becoming the array under test. + * Extract the result of given method invocation from the array's elements under test into a list, this list becoming + * the object under test. *

* It allows you to test a method results of the array's elements instead of testing the elements themselves, which can be * much less work! @@ -2348,17 +2341,18 @@ public ObjectArrayAssert extractingResultOf(String method) { * @param

the type of elements extracted. * @param method the name of the method which result is to be extracted from the array under test * @param extractingType type to return - * @return a new assertion object whose object under test is the array of extracted values. + * @return a new assertion object whose object under test is the list of extracted values. * @throws IllegalArgumentException if no method exists with the given name, or method is not public, or method does * return void, or method accepts arguments. */ @CheckReturnValue - public

ObjectArrayAssert

extractingResultOf(String method, Class

extractingType) { + public

AbstractListAssert, P, ObjectAssert

> extractingResultOf(String method, + Class

extractingType) { @SuppressWarnings("unchecked") P[] values = (P[]) FieldsOrPropertiesExtractor.extract(actual, resultOf(method)); String extractedDescription = extractedDescriptionOfMethod(method); String description = mostRelevantDescription(info.description(), extractedDescription); - return new ObjectArrayAssert<>(values).as(description); + return newListAssertInstance(newArrayList(values)).as(description); } /** @@ -2401,8 +2395,8 @@ public SELF inBinary() { } /** - * Filter the array under test keeping only elements having a property or field equal to {@code expectedValue}, the - * property/field is specified by {@code propertyOrFieldName} parameter. + * Filter the array under test into a list composed of the elements elements having a property or field equal to + * {@code expectedValue}, the property/field is specified by {@code propertyOrFieldName} parameter. *

* The filter first tries to get the value from a property (named {@code propertyOrFieldName}), if no such property * exists it tries to read the value from a field. Reading private fields is supported by default, this can be @@ -2447,26 +2441,28 @@ public SELF inBinary() { * assertThat(fellowshipOfTheRing).filteredOn("race.name", "Man") * .filteredOn("name", not("Boromir")) * .containsOnly(aragorn); - * If you need more complex filter, use {@link #filteredOn(Condition)} and provide a {@link Condition} to specify the - * filter to apply. + *

+ * If you need more complex filter, use {@link #filteredOn(Condition)} or {@link #filteredOn(Predicate)} and + * provide a {@link Condition} or {@link Predicate} to specify the filter to apply. * * @param propertyOrFieldName the name of the property or field to read * @param expectedValue the value to compare element's property or field with - * @return a new assertion object with the filtered array under test + * @return a new assertion object with the filtered list under test * @throws IllegalArgumentException if the given propertyOrFieldName is {@code null} or empty. * @throws IntrospectionError if the given propertyOrFieldName can't be found in one of the array elements. */ - @SuppressWarnings("unchecked") @CheckReturnValue - public SELF filteredOn(String propertyOrFieldName, Object expectedValue) { + public AbstractListAssert, ELEMENT, ObjectAssert> filteredOn(String propertyOrFieldName, + Object expectedValue) { Iterable filteredIterable = filter(actual).with(propertyOrFieldName, expectedValue).get(); - return (SELF) new ObjectArrayAssert<>(toArray(filteredIterable)); + return newListAssertInstance(newArrayList(filteredIterable)); } /** - * Filter the array under test keeping only elements whose property or field specified by {@code propertyOrFieldName} - * is null. + * Filter the array under test into a list composed of the elements whose property or field specified + * by {@code propertyOrFieldName} are null. *

+ * The filter first tries to get the value from a property (named {@code propertyOrFieldName}), if no such property * exists it tries to read the value from a field. Reading private fields is supported by default, this can be * globally disabled by calling {@link Assertions#setAllowExtractingPrivateFields(boolean) * Assertions.setAllowExtractingPrivateFields(false)}. @@ -2493,23 +2489,21 @@ public SELF filteredOn(String propertyOrFieldName, Object expectedValue) { * * An {@link IntrospectionError} is thrown if the given propertyOrFieldName can't be found in one of the array * elements. - *

- * If you need more complex filter, use {@link #filteredOn(Condition)} and provide a {@link Condition} to specify the - * filter to apply. * * @param propertyOrFieldName the name of the property or field to read - * @return a new assertion object with the filtered array under test + * @return a new assertion object with the filtered list under test * @throws IntrospectionError if the given propertyOrFieldName can't be found in one of the array elements. */ @CheckReturnValue - public SELF filteredOnNull(String propertyOrFieldName) { - // need to cast nulll to Object otherwise it calls : - // filteredOn(String propertyOrFieldName, FilterOperation filterOperation) - return filteredOn(propertyOrFieldName, (Object) null); + public AbstractListAssert, ELEMENT, ObjectAssert> filteredOnNull(String propertyOrFieldName) { + // can't call filteredOn(String propertyOrFieldName, null) as it does not work with soft assertions proxying + // mechanism, it would lead to double proxying which is not handle properly (improvements needed in our proxy mechanism) + Iterable filteredIterable = filter(actual).with(propertyOrFieldName, null).get(); + return newListAssertInstance(newArrayList(filteredIterable)); } /** - * Filter the array under test keeping only elements having a property or field matching the filter expressed with + * Filter the array under test into a list composed of elements having a property or field matching the filter expressed with * the {@link FilterOperator}, the property/field is specified by {@code propertyOrFieldName} parameter. *

* The existing filters are : @@ -2527,7 +2521,6 @@ public SELF filteredOnNull(String propertyOrFieldName) { * When reading nested property/field, if an intermediate value is null the whole nested property/field is * considered to be null, thus reading "address.street.name" value will return null if "street" value is null. *

- * * As an example, let's check stuff on some special employees : *

 Employee yoda   = new Employee(1L, new Name("Yoda"), 800);
    * Employee obiwan = new Employee(2L, new Name("Obiwan"), 800);
@@ -2564,26 +2557,27 @@ public SELF filteredOnNull(String propertyOrFieldName) {
    * assertThat(fellowshipOfTheRing).filteredOn("race.name", "Man")
    *                                .filteredOn("name", not("Boromir"))
    *                                .containsOnly(aragorn);
- * - * If you need more complex filter, use {@link #filteredOn(Condition)} and provide a {@link Condition} to specify the - * filter to apply. + *

+ * If you need more complex filter, use {@link #filteredOn(Condition)} or {@link #filteredOn(Predicate)} and + * provide a {@link Condition} or {@link Predicate} to specify the filter to apply. * * @param propertyOrFieldName the name of the property or field to read * @param filterOperator the filter operator to apply - * @return a new assertion object with the filtered array under test + * @return a new assertion object with the filtered list under test * @throws IllegalArgumentException if the given propertyOrFieldName is {@code null} or empty. */ - @SuppressWarnings("unchecked") @CheckReturnValue - public SELF filteredOn(String propertyOrFieldName, FilterOperator filterOperator) { + public AbstractListAssert, ELEMENT, ObjectAssert> filteredOn(String propertyOrFieldName, + FilterOperator filterOperator) { checkNotNull(filterOperator); Filters filter = filter(actual).with(propertyOrFieldName); filterOperator.applyOn(filter); - return (SELF) new ObjectArrayAssert<>(toArray(filter.get())); + return newListAssertInstance(newArrayList(filter.get())); } /** - * Filter the array under test keeping only elements matching the given {@link Condition}. + * Filter the array under test into a list composed of the elements matching the given {@link Condition}, + * allowing to perform assertions on the filtered list. *

* Let's check old employees whose age > 100: *

 Employee yoda   = new Employee(1L, new Name("Yoda"), 800);
@@ -2611,18 +2605,18 @@ public SELF filteredOn(String propertyOrFieldName, FilterOperator filterOpera
    *                      .contains(luke, noname);
* * @param condition the filter condition / predicate - * @return a new assertion object with the filtered array under test + * @return a new assertion object with the filtered list under test * @throws IllegalArgumentException if the given condition is {@code null}. */ - @SuppressWarnings("unchecked") @CheckReturnValue - public SELF filteredOn(Condition condition) { + public AbstractListAssert, ELEMENT, ObjectAssert> filteredOn(Condition condition) { Iterable filteredIterable = filter(actual).being(condition).get(); - return (SELF) new ObjectArrayAssert<>(toArray(filteredIterable)); + return newListAssertInstance(newArrayList(filteredIterable)); } /** - * Filter the iterable under test keeping only elements matching the given {@link Predicate}. + * Filter the array under test into a list composed of the elements matching the given {@link Predicate}, + * allowing to perform assertions on the filtered list. *

* Example : check old employees whose age > 100: * @@ -2636,13 +2630,13 @@ public SELF filteredOn(Condition condition) { * .containsOnly(yoda, obiwan); * * @param predicate the filter predicate - * @return a new assertion object with the filtered array under test + * @return a new assertion object with the filtered list under test * @throws IllegalArgumentException if the given predicate is {@code null}. */ - @SuppressWarnings("unchecked") - public SELF filteredOn(Predicate predicate) { + public AbstractListAssert, ELEMENT, ObjectAssert> filteredOn(Predicate predicate) { checkArgument(predicate != null, "The filter predicate should not be null"); - return (SELF) new ObjectArrayAssert<>(stream(actual).filter(predicate).toArray()); + List filtered = stream(actual).filter(predicate).collect(toList()); + return newListAssertInstance(filtered); } /** @@ -2848,4 +2842,21 @@ public SELF noneMatch(Predicate predicate) { iterables.assertNoneMatch(info, newArrayList(actual), predicate, PredicateDescription.GIVEN); return myself; } + + /** + * Create a friendly soft or "hard" assertion. + *

+ * Implementations need to redefine it so that some methods, such as {@link #extracting(Extractor)}, are able + * to build the appropriate list assert (eg: {@link ListAssert} versus {@link ProxyableListAssert}). + *

+ * The default implementation will assume that this concrete implementation is NOT a soft assertion. + * + * @param the type of elements. + * @param newActual new value + * @return a new {@link AbstractListAssert}. + */ + protected AbstractListAssert, E, ObjectAssert> newListAssertInstance(List newActual) { + return new ListAssert<>(newActual); + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractObjectAssert.java b/src/main/java/org/assertj/core/api/AbstractObjectAssert.java index 01dc1a4ff0..f8d504c759 100644 --- a/src/main/java/org/assertj/core/api/AbstractObjectAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractObjectAssert.java @@ -23,8 +23,10 @@ import java.util.Map; import java.util.TreeMap; import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.Stream; +import org.assertj.core.api.iterable.Extractor; import org.assertj.core.description.Description; import org.assertj.core.groups.Tuple; import org.assertj.core.internal.TypeComparators; @@ -506,11 +508,11 @@ public SELF hasFieldOrPropertyWithValue(String name, Object value) { } /** - * Extract the values of given fields/properties from the object under test into an array, this new array becoming + * Extract the values of given fields/properties from the object under test into a list, this new list becoming * the object under test. *

- * If you extract "id", "name" and "email" fields/properties then the array will contain the id, name and email values - * of the object under test, you can then perform array assertions on the extracted values. + * If you extract "id", "name" and "email" fields/properties then the list will contain the id, name and email values + * of the object under test, you can then perform list assertions on the extracted values. *

* Nested fields/properties are supported, specifying "adress.street.number" is equivalent to get the value * corresponding to actual.getAdress().getStreet().getNumber() @@ -528,33 +530,28 @@ public SELF hasFieldOrPropertyWithValue(String name, Object value) { * .containsExactly("Frodo", 33, "Hobbit"); * * A property with the given name is looked for first, if it doesn't exist then a field with the given name is looked - * for, if the field is not accessible (i.e. does not exist) an IntrospectionError is thrown. + * for, if the field is not accessible (i.e. does not exist) an {@link IntrospectionError} is thrown. *

- * Note that the order of extracted property/field values is consistent with the iteration order of the array under - * test. + * Note that the order of extracted values is consistent with the order of the given property/field. * * @param propertiesOrFields the properties/fields to extract from the initial object under test - * @return a new assertion object whose object under test is the array containing the extracted properties/fields values + * @return a new assertion object whose object under test is the list containing the extracted properties/fields values * @throws IntrospectionError if one of the given name does not match a field or property */ @CheckReturnValue - public AbstractObjectArrayAssert extracting(String... propertiesOrFields) { + public AbstractListAssert, Object, ObjectAssert> extracting(String... propertiesOrFields) { Tuple values = byName(propertiesOrFields).extract(actual); - return extracting(values.toList(), propertiesOrFields); - } - - AbstractObjectArrayAssert extracting(List values, String... propertiesOrFields) { String extractedPropertiesOrFieldsDescription = extractedDescriptionOf(propertiesOrFields); String description = mostRelevantDescription(info.description(), extractedPropertiesOrFieldsDescription); - return new ObjectArrayAssert<>(values.toArray()).as(description); + return newListAssertInstance(values.toList()).as(description); } /** - * Use the given {@link Function}s to extract the values from the object under test into an array, this new array becoming + * Use the given {@link Function}s to extract the values from the object under test into a list, this new list becoming * the object under test. *

- * If the given {@link Function}s extract the id, name and email values then the array will contain the id, name and email values - * of the object under test, you can then perform array assertions on the extracted values. + * If the given {@link Function}s extract the id, name and email values then the list will contain the id, name and email values + * of the object under test, you can then perform list assertions on the extracted values. *

* Example: *

 // Create frodo, setting its name, age and Race (Race having a name property)
@@ -566,17 +563,17 @@ AbstractObjectArrayAssert extracting(List values, String... p
    *                              character -> character.getRace().getName())
    *                  .containsExactly("Frodo", 33, "Hobbit");
    * 

- * Note that the order of extracted values is consistent with the iteration order of the array under test. + * Note that the order of extracted values is consistent with the order of given extractor functions. * * @param extractors the extractor functions to extract a value from an element of the Iterable under test. - * @return a new assertion object whose object under test is the array containing the extracted values + * @return a new assertion object whose object under test is the list containing the extracted values */ @CheckReturnValue - public AbstractObjectArrayAssert extracting(@SuppressWarnings("unchecked") Function... extractors) { - Object[] values = Stream.of(extractors) - .map(extractor -> extractor.apply(actual)) - .toArray(); - return new ObjectArrayAssert<>(values); + public AbstractListAssert, Object, ObjectAssert> extracting(@SuppressWarnings("unchecked") Function... extractors) { + List values = Stream.of(extractors) + .map(extractor -> extractor.apply(actual)) + .collect(Collectors.toList()); + return newListAssertInstance(values).as(info.description()); } /** @@ -677,4 +674,21 @@ public SELF returns(T expected, Function from) { objects.assertEqual(info, from.apply(actual), expected); return myself; } + + /** + * Create a friendly soft or "hard" assertion. + *

+ * Implementations need to redefine it so that some methods, such as {@link #extracting(Extractor)}, are able + * to build the appropriate list assert (eg: {@link ListAssert} versus {@link ProxyableListAssert}). + *

+ * The default implementation will assume that this concrete implementation is NOT a soft assertion. + * + * @param the type of elements. + * @param newActual new value + * @return a new {@link AbstractListAssert}. + */ + protected AbstractListAssert, E, ObjectAssert> newListAssertInstance(List newActual) { + return new ListAssert<>(newActual); + } + } diff --git a/src/main/java/org/assertj/core/api/Assert.java b/src/main/java/org/assertj/core/api/Assert.java index f066a9409e..24fca628fe 100644 --- a/src/main/java/org/assertj/core/api/Assert.java +++ b/src/main/java/org/assertj/core/api/Assert.java @@ -537,6 +537,8 @@ public interface Assert, ACTUAL> extends Descr * * // assertion will fail * assertThat(unsortedListAsObject).asList().isSorted(); + *

+ * Warning: this method does not work with soft assertions or assumptions. * * @return a list assertion object */ @@ -555,6 +557,8 @@ public interface Assert, ACTUAL> extends Descr * * // assertion will fail * assertThat(stringAsObject).asString().contains("holla"); + *

+ * Warning: this method does not work with soft assertions or assumptions. * * @return a string assertion object */ diff --git a/src/main/java/org/assertj/core/api/Assertions.java b/src/main/java/org/assertj/core/api/Assertions.java index 3c086d1c50..5b9d2b2c52 100644 --- a/src/main/java/org/assertj/core/api/Assertions.java +++ b/src/main/java/org/assertj/core/api/Assertions.java @@ -415,7 +415,7 @@ public static AbstractCharacterAssert assertThat(Character actual) { * @return the created assertion object. */ @CheckReturnValue - public static AbstractClassAssert assertThat(Class actual) { + public static ClassAssert assertThat(Class actual) { return AssertionsForClassTypes.assertThat(actual); } diff --git a/src/main/java/org/assertj/core/api/AssertionsForClassTypes.java b/src/main/java/org/assertj/core/api/AssertionsForClassTypes.java index 7e0c19859b..72dfe838a1 100644 --- a/src/main/java/org/assertj/core/api/AssertionsForClassTypes.java +++ b/src/main/java/org/assertj/core/api/AssertionsForClassTypes.java @@ -272,7 +272,7 @@ public static AbstractCharacterAssert assertThat(Character actual) { * @return the created assertion object. */ @CheckReturnValue - public static AbstractClassAssert assertThat(Class actual) { + public static ClassAssert assertThat(Class actual) { return new ClassAssert(actual); } diff --git a/src/main/java/org/assertj/core/api/Assumptions.java b/src/main/java/org/assertj/core/api/Assumptions.java index 8e9c6f194a..6bc8326911 100644 --- a/src/main/java/org/assertj/core/api/Assumptions.java +++ b/src/main/java/org/assertj/core/api/Assumptions.java @@ -12,7 +12,6 @@ */ package org.assertj.core.api; -import static net.bytebuddy.matcher.ElementMatchers.any; import static org.assertj.core.api.Assertions.catchThrowable; import static org.assertj.core.util.Arrays.array; @@ -76,6 +75,7 @@ import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.SuperCall; import net.bytebuddy.implementation.bind.annotation.This; +import net.bytebuddy.matcher.ElementMatchers; /** * Entry point for assumption methods for different types, which allow to skip test execution on failed assumptions. @@ -1150,8 +1150,9 @@ private static ASSERTION asAssumption(final Class asserti } private static Class createAssumption(Class assertionType) { + // TODO ignore special methods like extracting ? return new ByteBuddy().subclass(assertionType) - .method(any()) + .method(ElementMatchers.any()) .intercept(MethodDelegation.to(new AssumptionMethodInterceptor())) .make() .load(Assumptions.class.getClassLoader()) @@ -1191,8 +1192,9 @@ private static Object asAssumption(AbstractAssert assertion) { if (assertion instanceof FactoryBasedNavigableListAssert) { return asAssumption(ProxyableListAssert.class, List.class, actual); } - if (assertion instanceof ObjectArrayAssert) return asAssumption(ObjectArrayAssert.class, Object[].class, actual); - if (assertion instanceof IterableSizeAssert) { + if (assertion instanceof AbstractObjectArrayAssert) + return asAssumption(ProxyableObjectArrayAssert.class, Object[].class, actual); + if (assertion instanceof IterableSizeAssert) { // TODO should likely return a proxyable class @SuppressWarnings("rawtypes") IterableSizeAssert iterableSizeAssert = (IterableSizeAssert) assertion; Class[] constructorTypes = array(AbstractIterableAssert.class, Integer.class); diff --git a/src/main/java/org/assertj/core/api/BDDAssertions.java b/src/main/java/org/assertj/core/api/BDDAssertions.java index 550d3eb591..c558153faf 100644 --- a/src/main/java/org/assertj/core/api/BDDAssertions.java +++ b/src/main/java/org/assertj/core/api/BDDAssertions.java @@ -326,7 +326,7 @@ public static AbstractCharacterAssert then(Character actual) { * @return the created assertion object. */ @CheckReturnValue - public static AbstractClassAssert then(Class actual) { + public static ClassAssert then(Class actual) { return assertThat(actual); } diff --git a/src/main/java/org/assertj/core/api/MapAssert.java b/src/main/java/org/assertj/core/api/MapAssert.java index 431b76ac84..268d8e56ba 100644 --- a/src/main/java/org/assertj/core/api/MapAssert.java +++ b/src/main/java/org/assertj/core/api/MapAssert.java @@ -89,4 +89,5 @@ public final MapAssert doesNotContainKeys(KEY... keys) { public final MapAssert doesNotContain(Map.Entry... entries) { return super.doesNotContain(entries); } + } diff --git a/src/main/java/org/assertj/core/api/ObjectArrayAssert.java b/src/main/java/org/assertj/core/api/ObjectArrayAssert.java index 33652ff9e7..adbc11f16c 100644 --- a/src/main/java/org/assertj/core/api/ObjectArrayAssert.java +++ b/src/main/java/org/assertj/core/api/ObjectArrayAssert.java @@ -14,6 +14,7 @@ import static org.assertj.core.util.Arrays.array; +import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.function.Function; @@ -45,8 +46,86 @@ public ObjectArrayAssert(AtomicReferenceArray actual) { @Override @SafeVarargs - public final ObjectArrayAssert extracting(Function... extractors) { + public final AbstractListAssert, Tuple, ObjectAssert> extracting(Function... extractors) { return super.extracting(extractors); } + @Override + @SafeVarargs + public final ObjectArrayAssert contains(ELEMENT... values) { + return super.contains(values); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert containsOnly(ELEMENT... values) { + return super.containsOnly(values); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert containsOnlyOnce(ELEMENT... values) { + return super.containsOnlyOnce(values); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert containsExactly(ELEMENT... values) { + return super.containsExactly(values); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert containsExactlyInAnyOrder(ELEMENT... values) { + return super.containsExactlyInAnyOrder(values); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert containsAnyOf(ELEMENT... values) { + return super.containsAnyOf(values); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert isSubsetOf(ELEMENT... values) { + return super.isSubsetOf(values); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert containsSequence(ELEMENT... sequence) { + return super.containsSequence(sequence); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert doesNotContainSequence(ELEMENT... sequence) { + return super.doesNotContainSequence(sequence); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert containsSubsequence(ELEMENT... sequence) { + return super.containsSubsequence(sequence); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert doesNotContainSubsequence(ELEMENT... sequence) { + return super.doesNotContainSubsequence(sequence); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert doesNotContain(ELEMENT... values) { + return super.doesNotContain(values); + } + + @Override + @SafeVarargs + public final ObjectArrayAssert endsWith(ELEMENT first, ELEMENT... rest) { + return super.endsWith(first, rest); + } + } diff --git a/src/main/java/org/assertj/core/api/ObjectAssert.java b/src/main/java/org/assertj/core/api/ObjectAssert.java index ad07d14997..95a3d094fe 100644 --- a/src/main/java/org/assertj/core/api/ObjectAssert.java +++ b/src/main/java/org/assertj/core/api/ObjectAssert.java @@ -12,6 +12,7 @@ */ package org.assertj.core.api; +import java.util.List; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; @@ -42,7 +43,7 @@ public ObjectAssert(AtomicReference actual) { @Override @CheckReturnValue @SafeVarargs - public final AbstractObjectArrayAssert extracting(Function... extractors) { + public final AbstractListAssert, Object, ObjectAssert> extracting(Function... extractors) { return super.extracting(extractors); } diff --git a/src/main/java/org/assertj/core/api/ProxyableMapAssert.java b/src/main/java/org/assertj/core/api/ProxyableMapAssert.java index 8efe8cdbf4..93a7d9d704 100644 --- a/src/main/java/org/assertj/core/api/ProxyableMapAssert.java +++ b/src/main/java/org/assertj/core/api/ProxyableMapAssert.java @@ -12,6 +12,7 @@ */ package org.assertj.core.api; +import java.util.List; import java.util.Map; /** @@ -23,4 +24,9 @@ public ProxyableMapAssert(Map actual) { super(actual, ProxyableMapAssert.class); } + @Override + protected AbstractListAssert, ELEMENT, ObjectAssert> newListAssertInstance(List newActual) { + return new ProxyableListAssert<>(newActual); + } + } diff --git a/src/main/java/org/assertj/core/api/ProxyableObjectArrayAssert.java b/src/main/java/org/assertj/core/api/ProxyableObjectArrayAssert.java index 088e3414d5..51b0f4b203 100644 --- a/src/main/java/org/assertj/core/api/ProxyableObjectArrayAssert.java +++ b/src/main/java/org/assertj/core/api/ProxyableObjectArrayAssert.java @@ -14,6 +14,7 @@ import static org.assertj.core.util.Arrays.array; +import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; /** @@ -29,4 +30,9 @@ public ProxyableObjectArrayAssert(AtomicReferenceArray actual) { this(array(actual)); } + @Override + protected AbstractListAssert, E, ObjectAssert> newListAssertInstance(List newActual) { + return new ProxyableListAssert<>(newActual); + } + } diff --git a/src/main/java/org/assertj/core/api/ProxyableObjectAssert.java b/src/main/java/org/assertj/core/api/ProxyableObjectAssert.java index b0991d7e6f..8cba1760a9 100644 --- a/src/main/java/org/assertj/core/api/ProxyableObjectAssert.java +++ b/src/main/java/org/assertj/core/api/ProxyableObjectAssert.java @@ -12,6 +12,7 @@ */ package org.assertj.core.api; +import java.util.List; import java.util.concurrent.atomic.AtomicReference; /** @@ -27,4 +28,9 @@ public ProxyableObjectAssert(AtomicReference actual) { this(actual == null ? null: actual.get()); } + @Override + protected AbstractListAssert, ELEMENT, ObjectAssert> newListAssertInstance(List newActual) { + return new ProxyableListAssert<>(newActual); + } + } diff --git a/src/main/java/org/assertj/core/api/SoftProxies.java b/src/main/java/org/assertj/core/api/SoftProxies.java index f2eabee25b..5e36aac1bf 100644 --- a/src/main/java/org/assertj/core/api/SoftProxies.java +++ b/src/main/java/org/assertj/core/api/SoftProxies.java @@ -44,9 +44,9 @@ List errorsCollected() { V create(final Class assertClass, Class actualClass, T actual) { try { - Class proxyClass = (Class) cache - .findOrInsert(getClass().getClassLoader(), new SimpleKey(assertClass), - () -> createProxy(assertClass, collector)); + ClassLoader classLoader = getClass().getClassLoader(); + SimpleKey key = new SimpleKey(assertClass); + Class proxyClass = (Class) cache.findOrInsert(classLoader, key, () -> createProxy(assertClass, collector)); Constructor constructor = proxyClass.getConstructor(actualClass); return constructor.newInstance(actual); diff --git a/src/main/java/org/assertj/core/api/WithAssertions.java b/src/main/java/org/assertj/core/api/WithAssertions.java index 429108ba0c..a8d3660528 100644 --- a/src/main/java/org/assertj/core/api/WithAssertions.java +++ b/src/main/java/org/assertj/core/api/WithAssertions.java @@ -593,7 +593,7 @@ default AbstractShortAssert assertThat(final Short actual) { * @return the created assertion object. */ @CheckReturnValue - default AbstractClassAssert assertThat(final Class actual) { + default ClassAssert assertThat(final Class actual) { return Assertions.assertThat(actual); } diff --git a/src/test/java/org/assertj/core/api/BDDSoftAssertionsTest.java b/src/test/java/org/assertj/core/api/BDDSoftAssertionsTest.java index ff74df2899..5544171577 100644 --- a/src/test/java/org/assertj/core/api/BDDSoftAssertionsTest.java +++ b/src/test/java/org/assertj/core/api/BDDSoftAssertionsTest.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.in; import static org.assertj.core.api.Assertions.tuple; import static org.assertj.core.api.SoftAssertions.assertSoftly; import static org.assertj.core.test.Maps.mapOf; @@ -35,7 +36,9 @@ import java.time.LocalTime; import java.time.OffsetTime; import java.time.ZoneOffset; +import java.util.Collection; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -54,6 +57,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.function.DoublePredicate; +import java.util.function.Function; import java.util.function.IntPredicate; import java.util.function.LongPredicate; import java.util.function.Predicate; @@ -66,6 +70,8 @@ import org.assertj.core.api.ClassAssertBaseTest.AnotherAnnotation; import org.assertj.core.api.ClassAssertBaseTest.MyAnnotation; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.assertj.core.api.iterable.Extractor; +import org.assertj.core.api.iterable.ThrowingExtractor; import org.assertj.core.api.test.ComparableExample; import org.assertj.core.data.MapEntry; import org.assertj.core.test.CartoonCharacter; @@ -85,6 +91,17 @@ public class BDDSoftAssertionsTest extends BaseAssertionsTest { private CartoonCharacter maggie; private CartoonCharacter bart; + private Map iterableMap; + + private ThrowingExtractor throwingFirstNameExtractor; + private ThrowingExtractor throwingLastNameExtractor; + private Extractor firstNameExtractor; + private Extractor lastNameExtractor; + private Function firstNameFunction; + private Function lastNameFunction; + + private Extractor> childrenExtractor; + @Before public void setup() { softly = new BDDSoftAssertions(); @@ -101,6 +118,26 @@ public void setup() { CartoonCharacter pebbles = new CartoonCharacter("Pebbles Flintstone"); fred = new CartoonCharacter("Fred Flintstone"); fred.getChildren().add(pebbles); + + List names = asList("Dave", "Jeff"); + LinkedHashSet jobs = newLinkedHashSet("Plumber", "Builder"); + Iterable cities = asList("Dover", "Boston", "Paris"); + int[] ranks = { 1, 2, 3 }; + + iterableMap = new LinkedHashMap<>(); + iterableMap.put("name", names); + iterableMap.put("job", jobs); + iterableMap.put("city", cities); + iterableMap.put("rank", ranks); + + throwingFirstNameExtractor = Name::getFirst; + throwingLastNameExtractor = Name::getLast; + firstNameFunction = Name::getFirst; + lastNameFunction = Name::getLast; + firstNameExtractor = Name::getFirst; + lastNameExtractor = Name::getLast; + + childrenExtractor = CartoonCharacter::getChildren; } @Test @@ -922,23 +959,22 @@ public void should_fix_bug_1146() { } } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_iterable_assertion_final_methods_should_work_with_soft_assertions() { + public void iterable_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN Iterable names = asList(name("John", "Doe"), name("Jane", "Doe")); Iterable characters = asList(homer, fred); - // WHEN softly.then(names) - .extracting(Name::getFirst) + .extracting(throwingFirstNameExtractor) .contains("gandalf") .contains("frodo"); softly.then(names) .extracting("last") .containsExactly("foo", "bar"); softly.then(characters) - .flatExtracting(CartoonCharacter::getChildren) + .flatExtracting(childrenExtractor) .as("using flatExtracting on Iterable") .hasSize(1) .containsAnyOf(homer, fred); @@ -967,12 +1003,75 @@ public void all_iterable_assertion_final_methods_should_work_with_soft_assertion softly.then(characters) .endsWith(bart); softly.then(names) - .extracting(Name::getFirst, Name::getLast) + .extracting(firstNameFunction, lastNameFunction) .contains(tuple("John", "Doe")) .contains(tuple("Frodo", "Baggins")); + softly.then(names) + .extracting("first", "last") + .contains(tuple("John", "Doe")) + .contains(tuple("Bilbo", "Baggins")); + softly.then(names) + .extracting(firstNameExtractor) + .contains("John") + .contains("sam"); + softly.then(names) + .extracting("first", String.class) + .contains("John") + .contains("Aragorn"); + softly.then(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .hasSize(123); + softly.then(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .extracting(firstNameExtractor) + .contains("Sauron"); + softly.then(names) + .flatExtracting(firstNameExtractor, lastNameExtractor) + .as("flatExtracting with multiple Extractors") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.then(names) + .flatExtracting(throwingFirstNameExtractor, throwingLastNameExtractor) + .as("flatExtracting with multiple ThrowingExtractors") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.then(names) + .extractingResultOf("getFirst") + .contains("John", "Jane") + .contains("Sam", "Aragorn"); + softly.then(names) + .extractingResultOf("getFirst", String.class) + .contains("John", "Jane") + .contains("Messi", "Ronaldo"); + softly.then(names) + .filteredOn(new Condition<>(name -> name.first.startsWith("Jo"), "startsWith Jo")) + .as("filteredOn with condition") + .hasSize(5); + softly.then(names) + .filteredOn("first", in("John", "Frodo")) + .as("filteredOn firstName in {John, Frodo}") + .isEmpty(); + softly.then(names) + .filteredOn("first", "John") + .as("filteredOn firstName = John") + .isEmpty(); + softly.then(names) + .filteredOnNull("first") + .as("filteredOn firstName = null") + .isNotEmpty(); + softly.then(names) + .flatExtracting("first", "last") + .as("using flatExtracting(String... fieldOrPropertyNames)") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.then(characters) + .flatExtracting("children") + .as("using flatExtracting(String fieldOrPropertyName)") + .contains(bart, maggie) + .contains("Sauron"); // THEN List errorsCollected = softly.errorsCollected(); - assertThat(errorsCollected).hasSize(17); + assertThat(errorsCollected).hasSize(32); assertThat(errorsCollected.get(0)).hasMessageContaining("gandalf"); assertThat(errorsCollected.get(1)).hasMessageContaining("frodo"); assertThat(errorsCollected.get(2)).hasMessageContaining("foo") @@ -991,12 +1090,27 @@ public void all_iterable_assertion_final_methods_should_work_with_soft_assertion assertThat(errorsCollected.get(14)).hasMessageContaining(fred.toString()); assertThat(errorsCollected.get(15)).hasMessageContaining(bart.toString()); assertThat(errorsCollected.get(16)).hasMessageContaining("Baggins"); + assertThat(errorsCollected.get(17)).hasMessageContaining("Bilbo"); + assertThat(errorsCollected.get(18)).hasMessageContaining("sam"); + assertThat(errorsCollected.get(19)).hasMessageContaining("Aragorn"); + assertThat(errorsCollected.get(20)).hasMessageContaining("123"); + assertThat(errorsCollected.get(21)).hasMessageContaining("Sauron"); + assertThat(errorsCollected.get(22)).hasMessageContaining("flatExtracting with multiple Extractors"); + assertThat(errorsCollected.get(23)).hasMessageContaining("flatExtracting with multiple ThrowingExtractors"); + assertThat(errorsCollected.get(24)).hasMessageContaining("Sam"); + assertThat(errorsCollected.get(25)).hasMessageContaining("Ronaldo"); + assertThat(errorsCollected.get(26)).hasMessageContaining("filteredOn with condition"); + assertThat(errorsCollected.get(27)).hasMessageContaining("filteredOn firstName in {John, Frodo}"); + assertThat(errorsCollected.get(28)).hasMessageContaining("filteredOn firstName = John"); + assertThat(errorsCollected.get(29)).hasMessageContaining("filteredOn firstName = null"); + assertThat(errorsCollected.get(30)).hasMessageContaining("using flatExtracting(String... fieldOrPropertyNames)"); + assertThat(errorsCollected.get(31)).hasMessageContaining("using flatExtracting(String fieldOrPropertyName)"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_list_assertion_final_methods_should_work_with_soft_assertions() { + public void list_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN List names = asList(name("John", "Doe"), name("Jane", "Doe")); List characters = asList(homer, fred); @@ -1041,9 +1155,72 @@ public void all_list_assertion_final_methods_should_work_with_soft_assertions() .extracting(Name::getFirst, Name::getLast) .contains(tuple("John", "Doe")) .contains(tuple("Frodo", "Baggins")); + softly.then(names) + .extracting("first", "last") + .contains(tuple("John", "Doe")) + .contains(tuple("Bilbo", "Baggins")); + softly.then(names) + .extracting(firstNameExtractor) + .contains("John") + .contains("sam"); + softly.then(names) + .extracting("first", String.class) + .contains("John") + .contains("Aragorn"); + softly.then(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .hasSize(123); + softly.then(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .extracting(firstNameExtractor) + .contains("Sauron"); + softly.then(names) + .flatExtracting(firstNameExtractor, lastNameExtractor) + .as("flatExtracting with multiple Extractors") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.then(names) + .flatExtracting(throwingFirstNameExtractor, throwingLastNameExtractor) + .as("flatExtracting with multiple ThrowingExtractors") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.then(names) + .extractingResultOf("getFirst") + .contains("John", "Jane") + .contains("Sam", "Aragorn"); + softly.then(names) + .extractingResultOf("getFirst", String.class) + .contains("John", "Jane") + .contains("Messi", "Ronaldo"); + softly.then(names) + .filteredOn(new Condition<>(name -> name.first.startsWith("Jo"), "startsWith Jo")) + .as("filteredOn with condition") + .hasSize(5); + softly.then(names) + .filteredOn("first", in("John", "Frodo")) + .as("filteredOn firstName in {John, Frodo}") + .isEmpty(); + softly.then(names) + .filteredOn("first", "John") + .as("filteredOn firstName = John") + .isEmpty(); + softly.then(names) + .filteredOnNull("first") + .as("filteredOn firstName = null") + .isNotEmpty(); + softly.then(names) + .flatExtracting("first", "last") + .as("using flatExtracting(String... fieldOrPropertyNames)") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.then(characters) + .flatExtracting("children") + .as("using flatExtracting(String fieldOrPropertyName)") + .contains(bart, maggie) + .contains("Sauron"); // THEN List errorsCollected = softly.errorsCollected(); - assertThat(errorsCollected).hasSize(17); + assertThat(errorsCollected).hasSize(32); assertThat(errorsCollected.get(0)).hasMessageContaining("gandalf"); assertThat(errorsCollected.get(1)).hasMessageContaining("frodo"); assertThat(errorsCollected.get(2)).hasMessageContaining("foo") @@ -1062,12 +1239,27 @@ public void all_list_assertion_final_methods_should_work_with_soft_assertions() assertThat(errorsCollected.get(14)).hasMessageContaining(fred.toString()); assertThat(errorsCollected.get(15)).hasMessageContaining(bart.toString()); assertThat(errorsCollected.get(16)).hasMessageContaining("Baggins"); + assertThat(errorsCollected.get(17)).hasMessageContaining("Bilbo"); + assertThat(errorsCollected.get(18)).hasMessageContaining("sam"); + assertThat(errorsCollected.get(19)).hasMessageContaining("Aragorn"); + assertThat(errorsCollected.get(20)).hasMessageContaining("123"); + assertThat(errorsCollected.get(21)).hasMessageContaining("Sauron"); + assertThat(errorsCollected.get(22)).hasMessageContaining("flatExtracting with multiple Extractors"); + assertThat(errorsCollected.get(23)).hasMessageContaining("flatExtracting with multiple ThrowingExtractors"); + assertThat(errorsCollected.get(24)).hasMessageContaining("Sam"); + assertThat(errorsCollected.get(25)).hasMessageContaining("Ronaldo"); + assertThat(errorsCollected.get(26)).hasMessageContaining("filteredOn with condition"); + assertThat(errorsCollected.get(27)).hasMessageContaining("filteredOn firstName in {John, Frodo}"); + assertThat(errorsCollected.get(28)).hasMessageContaining("filteredOn firstName = John"); + assertThat(errorsCollected.get(29)).hasMessageContaining("filteredOn firstName = null"); + assertThat(errorsCollected.get(30)).hasMessageContaining("using flatExtracting(String... fieldOrPropertyNames)"); + assertThat(errorsCollected.get(31)).hasMessageContaining("using flatExtracting(String fieldOrPropertyName)"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_object_array_assertion_final_methods_should_work_with_soft_assertions() { + public void object_array_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN Name[] names = array(name("John", "Doe"), name("Jane", "Doe")); CartoonCharacter[] characters = array(homer, fred); @@ -1112,9 +1304,57 @@ public void all_object_array_assertion_final_methods_should_work_with_soft_asser .extracting(Name::getFirst, Name::getLast) .contains(tuple("John", "Doe")) .contains(tuple("Frodo", "Baggins")); + softly.then(names) + .extracting("first", "last") + .contains(tuple("John", "Doe")) + .contains(tuple("Bilbo", "Baggins")); + softly.then(names) + .extracting(firstNameExtractor) + .contains("John") + .contains("sam"); + softly.then(names) + .extracting("first", String.class) + .contains("John") + .contains("Aragorn"); + softly.then(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .hasSize(123); + softly.then(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .extracting(firstNameExtractor) + .contains("Sauron"); + softly.then(names) + .extractingResultOf("getFirst") + .contains("John", "Jane") + .contains("Sam", "Aragorn"); + softly.then(names) + .extractingResultOf("getFirst", String.class) + .contains("John", "Jane") + .contains("Messi", "Ronaldo"); + softly.then(names) + .filteredOn(new Condition<>(name -> name.first.startsWith("Jo"), "startsWith Jo")) + .as("filteredOn with condition") + .hasSize(5); + softly.then(names) + .filteredOn("first", in("John", "Frodo")) + .as("filteredOn firstName in {John, Frodo}") + .isEmpty(); + softly.then(names) + .filteredOn("first", "John") + .as("filteredOn firstName = John") + .isEmpty(); + softly.then(names) + .filteredOnNull("first") + .as("filteredOn firstName = null") + .isNotEmpty(); + softly.then(characters) + .flatExtracting("children") + .as("using flatExtracting(String fieldOrPropertyName)") + .contains(bart, maggie) + .contains("Sauron"); // THEN List errorsCollected = softly.errorsCollected(); - assertThat(errorsCollected).hasSize(17); + assertThat(errorsCollected).hasSize(29); assertThat(errorsCollected.get(0)).hasMessageContaining("gandalf"); assertThat(errorsCollected.get(1)).hasMessageContaining("frodo"); assertThat(errorsCollected.get(2)).hasMessageContaining("foo") @@ -1133,12 +1373,24 @@ public void all_object_array_assertion_final_methods_should_work_with_soft_asser assertThat(errorsCollected.get(14)).hasMessageContaining(fred.toString()); assertThat(errorsCollected.get(15)).hasMessageContaining(bart.toString()); assertThat(errorsCollected.get(16)).hasMessageContaining("Baggins"); + assertThat(errorsCollected.get(17)).hasMessageContaining("Bilbo"); + assertThat(errorsCollected.get(18)).hasMessageContaining("sam"); + assertThat(errorsCollected.get(19)).hasMessageContaining("Aragorn"); + assertThat(errorsCollected.get(20)).hasMessageContaining("123"); + assertThat(errorsCollected.get(21)).hasMessageContaining("Sauron"); + assertThat(errorsCollected.get(22)).hasMessageContaining("Sam"); + assertThat(errorsCollected.get(23)).hasMessageContaining("Ronaldo"); + assertThat(errorsCollected.get(24)).hasMessageContaining("filteredOn with condition"); + assertThat(errorsCollected.get(25)).hasMessageContaining("filteredOn firstName in {John, Frodo}"); + assertThat(errorsCollected.get(26)).hasMessageContaining("filteredOn firstName = John"); + assertThat(errorsCollected.get(27)).hasMessageContaining("filteredOn firstName = null"); + assertThat(errorsCollected.get(28)).hasMessageContaining("using flatExtracting(String fieldOrPropertyName)"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_class_assertion_final_methods_should_work_with_soft_assertions() { + public void class_soft_assertions_should_report_errors_on_final_methods() { // GIVEN Class actual = AnnotatedClass.class; // WHEN @@ -1152,27 +1404,32 @@ public void all_class_assertion_final_methods_should_work_with_soft_assertions() .hasMessageContaining("VisibleForTesting"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_object_assertion_final_methods_should_work_with_soft_assertions() { + public void object_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN Name name = name("John", "Doe"); // WHEN + softly.then(name) + .extracting("first", "last") + .contains("John") + .contains("gandalf"); softly.then(name) .extracting(Name::getFirst, Name::getLast) .contains("John") .contains("frodo"); // THEN List errorsCollected = softly.errorsCollected(); - assertThat(errorsCollected).hasSize(1); - assertThat(errorsCollected.get(0)).hasMessageContaining("frodo"); + assertThat(errorsCollected).hasSize(2); + assertThat(errorsCollected.get(0)).hasMessageContaining("gandalf"); + assertThat(errorsCollected.get(1)).hasMessageContaining("frodo"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_map_assertion_final_methods_should_work_with_soft_assertions() { + public void map_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN Map map = mapOf(entry("a", "1"), entry("b", "2"), entry("c", "3")); // WHEN @@ -1185,9 +1442,14 @@ public void all_map_assertion_final_methods_should_work_with_soft_assertions() { softly.then(map).containsValues("V1", "V2"); softly.then(map).doesNotContain(entry("a", "1"), entry("abc", "ABC")); softly.then(map).doesNotContainKeys("a", "b"); + softly.then(map).extracting("a", "b").contains("456"); + softly.then(iterableMap) + .flatExtracting("name", "job", "city", "rank") + .contains("Unexpected", "Builder", "Dover", "Boston", "Paris", 1, 2, 3); + // softly.then(map).size().isGreaterThan(1000); not yet supported // THEN List errors = softly.errorsCollected(); - assertThat(errors).hasSize(10); + assertThat(errors).hasSize(12); assertThat(errors.get(0)).hasMessageContaining("MapEntry[key=\"abc\", value=\"ABC\"]"); assertThat(errors.get(1)).hasMessageContaining("empty"); assertThat(errors.get(2)).hasMessageContaining("gh") @@ -1199,11 +1461,13 @@ public void all_map_assertion_final_methods_should_work_with_soft_assertions() { assertThat(errors.get(7)).hasMessageContaining("V2"); assertThat(errors.get(8)).hasMessageContaining("ABC"); assertThat(errors.get(9)).hasMessageContaining("b"); + assertThat(errors.get(10)).hasMessageContaining("456"); + assertThat(errors.get(11)).hasMessageContaining("Unexpected"); } @SuppressWarnings("unchecked") @Test - public void all_predicate_assertion_final_methods_should_work_with_soft_assertions() { + public void predicate_soft_assertions_should_report_errors_on_final_methods() { // GIVEN Predicate> ballSportPredicate = sport -> sport.value.contains("ball"); // WHEN diff --git a/src/test/java/org/assertj/core/api/MapAssertBaseTest.java b/src/test/java/org/assertj/core/api/MapAssertBaseTest.java index 3877c57fa4..eb0565ca31 100644 --- a/src/test/java/org/assertj/core/api/MapAssertBaseTest.java +++ b/src/test/java/org/assertj/core/api/MapAssertBaseTest.java @@ -44,7 +44,7 @@ protected void inject_internal_objects() { } protected Map.Entry javaMapEntry(K key, V value) { - return new SimpleImmutableEntry(key, value); + return new SimpleImmutableEntry<>(key, value); } protected Map map(K key, V value) { @@ -52,7 +52,7 @@ protected Map map(K key, V value) { } protected Map map(K k1, V v1, K k2, V v2) { - Map map = new LinkedHashMap(); + Map map = new LinkedHashMap<>(); map.put(k1, v1); map.put(k2, v2); return map; diff --git a/src/test/java/org/assertj/core/api/SoftAssertionsTest.java b/src/test/java/org/assertj/core/api/SoftAssertionsTest.java index 261cb8cfbd..fef0f8f1f5 100644 --- a/src/test/java/org/assertj/core/api/SoftAssertionsTest.java +++ b/src/test/java/org/assertj/core/api/SoftAssertionsTest.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.in; import static org.assertj.core.api.Assertions.tuple; import static org.assertj.core.api.SoftAssertions.assertSoftly; import static org.assertj.core.test.Maps.mapOf; @@ -35,7 +36,9 @@ import java.time.LocalTime; import java.time.OffsetTime; import java.time.ZoneOffset; +import java.util.Collection; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -54,6 +57,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.function.DoublePredicate; +import java.util.function.Function; import java.util.function.IntPredicate; import java.util.function.LongPredicate; import java.util.function.Predicate; @@ -66,6 +70,8 @@ import org.assertj.core.api.ClassAssertBaseTest.AnotherAnnotation; import org.assertj.core.api.ClassAssertBaseTest.MyAnnotation; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; +import org.assertj.core.api.iterable.Extractor; +import org.assertj.core.api.iterable.ThrowingExtractor; import org.assertj.core.api.test.ComparableExample; import org.assertj.core.data.MapEntry; import org.assertj.core.test.CartoonCharacter; @@ -90,6 +96,17 @@ public class SoftAssertionsTest extends BaseAssertionsTest { private CartoonCharacter maggie; private CartoonCharacter bart; + private Map iterableMap; + + private ThrowingExtractor throwingFirstNameExtractor; + private ThrowingExtractor throwingLastNameExtractor; + private Extractor firstNameExtractor; + private Extractor lastNameExtractor; + private Function firstNameFunction; + private Function lastNameFunction; + + private Extractor> childrenExtractor; + @Before public void setup() { softly = new SoftAssertions(); @@ -106,6 +123,26 @@ public void setup() { CartoonCharacter pebbles = new CartoonCharacter("Pebbles Flintstone"); fred = new CartoonCharacter("Fred Flintstone"); fred.getChildren().add(pebbles); + + List names = asList("Dave", "Jeff"); + LinkedHashSet jobs = newLinkedHashSet("Plumber", "Builder"); + Iterable cities = asList("Dover", "Boston", "Paris"); + int[] ranks = { 1, 2, 3 }; + + iterableMap = new LinkedHashMap<>(); + iterableMap.put("name", names); + iterableMap.put("job", jobs); + iterableMap.put("city", cities); + iterableMap.put("rank", ranks); + + throwingFirstNameExtractor = Name::getFirst; + throwingLastNameExtractor = Name::getLast; + firstNameFunction = Name::getFirst; + lastNameFunction = Name::getLast; + firstNameExtractor = Name::getFirst; + lastNameExtractor = Name::getLast; + + childrenExtractor = CartoonCharacter::getChildren; } @Test @@ -926,23 +963,22 @@ public void should_fix_bug_1146() { } } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_iterable_assertion_final_methods_should_work_with_soft_assertions() { + public void iterable_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN Iterable names = asList(name("John", "Doe"), name("Jane", "Doe")); Iterable characters = asList(homer, fred); - // WHEN softly.assertThat(names) - .extracting(Name::getFirst) + .extracting(throwingFirstNameExtractor) .contains("gandalf") .contains("frodo"); softly.assertThat(names) .extracting("last") .containsExactly("foo", "bar"); softly.assertThat(characters) - .flatExtracting(CartoonCharacter::getChildren) + .flatExtracting(childrenExtractor) .as("using flatExtracting on Iterable") .hasSize(1) .containsAnyOf(homer, fred); @@ -971,12 +1007,75 @@ public void all_iterable_assertion_final_methods_should_work_with_soft_assertion softly.assertThat(characters) .endsWith(bart); softly.assertThat(names) - .extracting(Name::getFirst, Name::getLast) + .extracting(firstNameFunction, lastNameFunction) .contains(tuple("John", "Doe")) .contains(tuple("Frodo", "Baggins")); + softly.assertThat(names) + .extracting("first", "last") + .contains(tuple("John", "Doe")) + .contains(tuple("Bilbo", "Baggins")); + softly.assertThat(names) + .extracting(firstNameExtractor) + .contains("John") + .contains("sam"); + softly.assertThat(names) + .extracting("first", String.class) + .contains("John") + .contains("Aragorn"); + softly.assertThat(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .hasSize(123); + softly.assertThat(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .extracting(firstNameExtractor) + .contains("Sauron"); + softly.assertThat(names) + .flatExtracting(firstNameExtractor, lastNameExtractor) + .as("flatExtracting with multiple Extractors") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.assertThat(names) + .flatExtracting(throwingFirstNameExtractor, throwingLastNameExtractor) + .as("flatExtracting with multiple ThrowingExtractors") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.assertThat(names) + .extractingResultOf("getFirst") + .contains("John", "Jane") + .contains("Sam", "Aragorn"); + softly.assertThat(names) + .extractingResultOf("getFirst", String.class) + .contains("John", "Jane") + .contains("Messi", "Ronaldo"); + softly.assertThat(names) + .filteredOn(new Condition<>(name -> name.first.startsWith("Jo"), "startsWith Jo")) + .as("filteredOn with condition") + .hasSize(5); + softly.assertThat(names) + .filteredOn("first", in("John", "Frodo")) + .as("filteredOn firstName in {John, Frodo}") + .isEmpty(); + softly.assertThat(names) + .filteredOn("first", "John") + .as("filteredOn firstName = John") + .isEmpty(); + softly.assertThat(names) + .filteredOnNull("first") + .as("filteredOn firstName = null") + .isNotEmpty(); + softly.assertThat(names) + .flatExtracting("first", "last") + .as("using flatExtracting(String... fieldOrPropertyNames)") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.assertThat(characters) + .flatExtracting("children") + .as("using flatExtracting(String fieldOrPropertyName)") + .contains(bart, maggie) + .contains("Sauron"); // THEN List errorsCollected = softly.errorsCollected(); - assertThat(errorsCollected).hasSize(17); + assertThat(errorsCollected).hasSize(32); assertThat(errorsCollected.get(0)).hasMessageContaining("gandalf"); assertThat(errorsCollected.get(1)).hasMessageContaining("frodo"); assertThat(errorsCollected.get(2)).hasMessageContaining("foo") @@ -995,12 +1094,27 @@ public void all_iterable_assertion_final_methods_should_work_with_soft_assertion assertThat(errorsCollected.get(14)).hasMessageContaining(fred.toString()); assertThat(errorsCollected.get(15)).hasMessageContaining(bart.toString()); assertThat(errorsCollected.get(16)).hasMessageContaining("Baggins"); + assertThat(errorsCollected.get(17)).hasMessageContaining("Bilbo"); + assertThat(errorsCollected.get(18)).hasMessageContaining("sam"); + assertThat(errorsCollected.get(19)).hasMessageContaining("Aragorn"); + assertThat(errorsCollected.get(20)).hasMessageContaining("123"); + assertThat(errorsCollected.get(21)).hasMessageContaining("Sauron"); + assertThat(errorsCollected.get(22)).hasMessageContaining("flatExtracting with multiple Extractors"); + assertThat(errorsCollected.get(23)).hasMessageContaining("flatExtracting with multiple ThrowingExtractors"); + assertThat(errorsCollected.get(24)).hasMessageContaining("Sam"); + assertThat(errorsCollected.get(25)).hasMessageContaining("Ronaldo"); + assertThat(errorsCollected.get(26)).hasMessageContaining("filteredOn with condition"); + assertThat(errorsCollected.get(27)).hasMessageContaining("filteredOn firstName in {John, Frodo}"); + assertThat(errorsCollected.get(28)).hasMessageContaining("filteredOn firstName = John"); + assertThat(errorsCollected.get(29)).hasMessageContaining("filteredOn firstName = null"); + assertThat(errorsCollected.get(30)).hasMessageContaining("using flatExtracting(String... fieldOrPropertyNames)"); + assertThat(errorsCollected.get(31)).hasMessageContaining("using flatExtracting(String fieldOrPropertyName)"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_list_assertion_final_methods_should_work_with_soft_assertions() { + public void list_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN List names = asList(name("John", "Doe"), name("Jane", "Doe")); List characters = asList(homer, fred); @@ -1045,9 +1159,72 @@ public void all_list_assertion_final_methods_should_work_with_soft_assertions() .extracting(Name::getFirst, Name::getLast) .contains(tuple("John", "Doe")) .contains(tuple("Frodo", "Baggins")); + softly.assertThat(names) + .extracting("first", "last") + .contains(tuple("John", "Doe")) + .contains(tuple("Bilbo", "Baggins")); + softly.assertThat(names) + .extracting(firstNameExtractor) + .contains("John") + .contains("sam"); + softly.assertThat(names) + .extracting("first", String.class) + .contains("John") + .contains("Aragorn"); + softly.assertThat(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .hasSize(123); + softly.assertThat(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .extracting(firstNameExtractor) + .contains("Sauron"); + softly.assertThat(names) + .flatExtracting(firstNameExtractor, lastNameExtractor) + .as("flatExtracting with multiple Extractors") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.assertThat(names) + .flatExtracting(throwingFirstNameExtractor, throwingLastNameExtractor) + .as("flatExtracting with multiple ThrowingExtractors") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.assertThat(names) + .extractingResultOf("getFirst") + .contains("John", "Jane") + .contains("Sam", "Aragorn"); + softly.assertThat(names) + .extractingResultOf("getFirst", String.class) + .contains("John", "Jane") + .contains("Messi", "Ronaldo"); + softly.assertThat(names) + .filteredOn(new Condition<>(name -> name.first.startsWith("Jo"), "startsWith Jo")) + .as("filteredOn with condition") + .hasSize(5); + softly.assertThat(names) + .filteredOn("first", in("John", "Frodo")) + .as("filteredOn firstName in {John, Frodo}") + .isEmpty(); + softly.assertThat(names) + .filteredOn("first", "John") + .as("filteredOn firstName = John") + .isEmpty(); + softly.assertThat(names) + .filteredOnNull("first") + .as("filteredOn firstName = null") + .isNotEmpty(); + softly.assertThat(names) + .flatExtracting("first", "last") + .as("using flatExtracting(String... fieldOrPropertyNames)") + .contains("John", "Jane", "Doe") + .contains("Sauron"); + softly.assertThat(characters) + .flatExtracting("children") + .as("using flatExtracting(String fieldOrPropertyName)") + .contains(bart, maggie) + .contains("Sauron"); // THEN List errorsCollected = softly.errorsCollected(); - assertThat(errorsCollected).hasSize(17); + assertThat(errorsCollected).hasSize(32); assertThat(errorsCollected.get(0)).hasMessageContaining("gandalf"); assertThat(errorsCollected.get(1)).hasMessageContaining("frodo"); assertThat(errorsCollected.get(2)).hasMessageContaining("foo") @@ -1066,12 +1243,27 @@ public void all_list_assertion_final_methods_should_work_with_soft_assertions() assertThat(errorsCollected.get(14)).hasMessageContaining(fred.toString()); assertThat(errorsCollected.get(15)).hasMessageContaining(bart.toString()); assertThat(errorsCollected.get(16)).hasMessageContaining("Baggins"); + assertThat(errorsCollected.get(17)).hasMessageContaining("Bilbo"); + assertThat(errorsCollected.get(18)).hasMessageContaining("sam"); + assertThat(errorsCollected.get(19)).hasMessageContaining("Aragorn"); + assertThat(errorsCollected.get(20)).hasMessageContaining("123"); + assertThat(errorsCollected.get(21)).hasMessageContaining("Sauron"); + assertThat(errorsCollected.get(22)).hasMessageContaining("flatExtracting with multiple Extractors"); + assertThat(errorsCollected.get(23)).hasMessageContaining("flatExtracting with multiple ThrowingExtractors"); + assertThat(errorsCollected.get(24)).hasMessageContaining("Sam"); + assertThat(errorsCollected.get(25)).hasMessageContaining("Ronaldo"); + assertThat(errorsCollected.get(26)).hasMessageContaining("filteredOn with condition"); + assertThat(errorsCollected.get(27)).hasMessageContaining("filteredOn firstName in {John, Frodo}"); + assertThat(errorsCollected.get(28)).hasMessageContaining("filteredOn firstName = John"); + assertThat(errorsCollected.get(29)).hasMessageContaining("filteredOn firstName = null"); + assertThat(errorsCollected.get(30)).hasMessageContaining("using flatExtracting(String... fieldOrPropertyNames)"); + assertThat(errorsCollected.get(31)).hasMessageContaining("using flatExtracting(String fieldOrPropertyName)"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_object_array_assertion_final_methods_should_work_with_soft_assertions() { + public void object_array_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN Name[] names = array(name("John", "Doe"), name("Jane", "Doe")); CartoonCharacter[] characters = array(homer, fred); @@ -1116,9 +1308,57 @@ public void all_object_array_assertion_final_methods_should_work_with_soft_asser .extracting(Name::getFirst, Name::getLast) .contains(tuple("John", "Doe")) .contains(tuple("Frodo", "Baggins")); + softly.assertThat(names) + .extracting("first", "last") + .contains(tuple("John", "Doe")) + .contains(tuple("Bilbo", "Baggins")); + softly.assertThat(names) + .extracting(firstNameExtractor) + .contains("John") + .contains("sam"); + softly.assertThat(names) + .extracting("first", String.class) + .contains("John") + .contains("Aragorn"); + softly.assertThat(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .hasSize(123); + softly.assertThat(names) + .filteredOn(name -> name.first.startsWith("Jo")) + .extracting(firstNameExtractor) + .contains("Sauron"); + softly.assertThat(names) + .extractingResultOf("getFirst") + .contains("John", "Jane") + .contains("Sam", "Aragorn"); + softly.assertThat(names) + .extractingResultOf("getFirst", String.class) + .contains("John", "Jane") + .contains("Messi", "Ronaldo"); + softly.assertThat(names) + .filteredOn(new Condition<>(name -> name.first.startsWith("Jo"), "startsWith Jo")) + .as("filteredOn with condition") + .hasSize(5); + softly.assertThat(names) + .filteredOn("first", in("John", "Frodo")) + .as("filteredOn firstName in {John, Frodo}") + .isEmpty(); + softly.assertThat(names) + .filteredOn("first", "John") + .as("filteredOn firstName = John") + .isEmpty(); + softly.assertThat(names) + .filteredOnNull("first") + .as("filteredOn firstName = null") + .isNotEmpty(); + softly.assertThat(characters) + .flatExtracting("children") + .as("using flatExtracting(String fieldOrPropertyName)") + .contains(bart, maggie) + .contains("Sauron"); // THEN List errorsCollected = softly.errorsCollected(); - assertThat(errorsCollected).hasSize(17); + assertThat(errorsCollected).hasSize(29); assertThat(errorsCollected.get(0)).hasMessageContaining("gandalf"); assertThat(errorsCollected.get(1)).hasMessageContaining("frodo"); assertThat(errorsCollected.get(2)).hasMessageContaining("foo") @@ -1137,12 +1377,24 @@ public void all_object_array_assertion_final_methods_should_work_with_soft_asser assertThat(errorsCollected.get(14)).hasMessageContaining(fred.toString()); assertThat(errorsCollected.get(15)).hasMessageContaining(bart.toString()); assertThat(errorsCollected.get(16)).hasMessageContaining("Baggins"); + assertThat(errorsCollected.get(17)).hasMessageContaining("Bilbo"); + assertThat(errorsCollected.get(18)).hasMessageContaining("sam"); + assertThat(errorsCollected.get(19)).hasMessageContaining("Aragorn"); + assertThat(errorsCollected.get(20)).hasMessageContaining("123"); + assertThat(errorsCollected.get(21)).hasMessageContaining("Sauron"); + assertThat(errorsCollected.get(22)).hasMessageContaining("Sam"); + assertThat(errorsCollected.get(23)).hasMessageContaining("Ronaldo"); + assertThat(errorsCollected.get(24)).hasMessageContaining("filteredOn with condition"); + assertThat(errorsCollected.get(25)).hasMessageContaining("filteredOn firstName in {John, Frodo}"); + assertThat(errorsCollected.get(26)).hasMessageContaining("filteredOn firstName = John"); + assertThat(errorsCollected.get(27)).hasMessageContaining("filteredOn firstName = null"); + assertThat(errorsCollected.get(28)).hasMessageContaining("using flatExtracting(String fieldOrPropertyName)"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_class_assertion_final_methods_should_work_with_soft_assertions() { + public void class_soft_assertions_should_report_errors_on_final_methods() { // GIVEN Class actual = AnnotatedClass.class; // WHEN @@ -1156,27 +1408,32 @@ public void all_class_assertion_final_methods_should_work_with_soft_assertions() .hasMessageContaining("VisibleForTesting"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_object_assertion_final_methods_should_work_with_soft_assertions() { + public void object_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN Name name = name("John", "Doe"); // WHEN + softly.assertThat(name) + .extracting("first", "last") + .contains("John") + .contains("gandalf"); softly.assertThat(name) .extracting(Name::getFirst, Name::getLast) .contains("John") .contains("frodo"); // THEN List errorsCollected = softly.errorsCollected(); - assertThat(errorsCollected).hasSize(1); - assertThat(errorsCollected.get(0)).hasMessageContaining("frodo"); + assertThat(errorsCollected).hasSize(2); + assertThat(errorsCollected.get(0)).hasMessageContaining("gandalf"); + assertThat(errorsCollected.get(1)).hasMessageContaining("frodo"); } - // the test would if any method was not proxyable as the assertion error would not be softly caught + // the test would fail if any method was not proxyable as the assertion error would not be softly caught @SuppressWarnings("unchecked") @Test - public void all_map_assertion_final_methods_should_work_with_soft_assertions() { + public void map_soft_assertions_should_report_errors_on_final_methods_and_methods_that_change_the_object_under_test() { // GIVEN Map map = mapOf(entry("a", "1"), entry("b", "2"), entry("c", "3")); // WHEN @@ -1189,9 +1446,14 @@ public void all_map_assertion_final_methods_should_work_with_soft_assertions() { softly.assertThat(map).containsValues("V1", "V2"); softly.assertThat(map).doesNotContain(entry("a", "1"), entry("abc", "ABC")); softly.assertThat(map).doesNotContainKeys("a", "b"); + softly.assertThat(map).extracting("a", "b").contains("456"); + softly.assertThat(iterableMap) + .flatExtracting("name", "job", "city", "rank") + .contains("Unexpected", "Builder", "Dover", "Boston", "Paris", 1, 2, 3); + // softly.assertThat(map).size().isGreaterThan(1000); not yet supported // THEN List errors = softly.errorsCollected(); - assertThat(errors).hasSize(10); + assertThat(errors).hasSize(12); assertThat(errors.get(0)).hasMessageContaining("MapEntry[key=\"abc\", value=\"ABC\"]"); assertThat(errors.get(1)).hasMessageContaining("empty"); assertThat(errors.get(2)).hasMessageContaining("gh") @@ -1203,11 +1465,13 @@ public void all_map_assertion_final_methods_should_work_with_soft_assertions() { assertThat(errors.get(7)).hasMessageContaining("V2"); assertThat(errors.get(8)).hasMessageContaining("ABC"); assertThat(errors.get(9)).hasMessageContaining("b"); + assertThat(errors.get(10)).hasMessageContaining("456"); + assertThat(errors.get(11)).hasMessageContaining("Unexpected"); } @SuppressWarnings("unchecked") @Test - public void all_predicate_assertion_final_methods_should_work_with_soft_assertions() { + public void predicate_soft_assertions_should_report_errors_on_final_methods() { // GIVEN Predicate> ballSportPredicate = sport -> sport.value.contains("ball"); // WHEN diff --git a/src/test/java/org/assertj/core/api/assumptions/BaseAssumptionsRunnerTest.java b/src/test/java/org/assertj/core/api/assumptions/BaseAssumptionsRunnerTest.java index 7e3d880a05..bc30476f20 100644 --- a/src/test/java/org/assertj/core/api/assumptions/BaseAssumptionsRunnerTest.java +++ b/src/test/java/org/assertj/core/api/assumptions/BaseAssumptionsRunnerTest.java @@ -14,10 +14,14 @@ import static org.assertj.core.api.Assertions.fail; +import java.util.Collection; +import java.util.function.Function; + import org.assertj.core.api.Assertions; import org.assertj.core.api.iterable.Extractor; import org.assertj.core.api.iterable.ThrowingExtractor; import org.assertj.core.data.TolkienCharacter; +import org.assertj.core.data.TolkienCharacter.Race; import org.assertj.core.test.CartoonCharacter; import org.junit.Test; @@ -27,15 +31,21 @@ public abstract class BaseAssumptionsRunnerTest { Assertions.setRemoveAssertJRelatedElementsFromStackTrace(false); } + protected static TolkienCharacter frodo; + protected static TolkienCharacter sam; protected static CartoonCharacter homer; protected static CartoonCharacter fred; protected static CartoonCharacter lisa; protected static CartoonCharacter maggie; protected static CartoonCharacter bart; - protected static ThrowingExtractor throwingNameExtractor; - protected static ThrowingExtractor throwingAgeExtractor; - protected static Extractor nameExtractor; - protected static Extractor ageExtractor; + protected static ThrowingExtractor throwingNameExtractor; + protected static ThrowingExtractor throwingAgeExtractor; + protected static Extractor nameExtractor; + protected static Extractor ageExtractor; + protected static Function nameExtractorFunction; + protected static Function ageExtractorFunction; + protected static Extractor> childrenExtractor; + protected AssumptionRunner assumptionRunner; public BaseAssumptionsRunnerTest(AssumptionRunner assumptionRunner) { @@ -60,6 +70,12 @@ public static void setupData() { throwingAgeExtractor = TolkienCharacter::getAge; nameExtractor = TolkienCharacter::getName; ageExtractor = TolkienCharacter::getAge; + nameExtractorFunction = TolkienCharacter::getName; + ageExtractorFunction = TolkienCharacter::getAge; + + frodo = TolkienCharacter.of("Frodo", 33, Race.HOBBIT); + sam = TolkienCharacter.of("Sam", 35, Race.HOBBIT); + childrenExtractor = CartoonCharacter::getChildren; } @Test diff --git a/src/test/java/org/assertj/core/api/assumptions/Iterable_final_method_assertions_in_assumptions_Test.java b/src/test/java/org/assertj/core/api/assumptions/Iterable_final_method_assertions_in_assumptions_Test.java deleted file mode 100644 index f7385a8948..0000000000 --- a/src/test/java/org/assertj/core/api/assumptions/Iterable_final_method_assertions_in_assumptions_Test.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2012-2018 the original author or authors. - */ -package org.assertj.core.api.assumptions; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.assertj.core.api.Assumptions.assumeThat; -import static org.assertj.core.api.assumptions.BaseAssumptionRunner.run; -import static org.assertj.core.util.IterableUtil.iterable; - -import org.assertj.core.api.IterableAssert; -import org.assertj.core.api.ProxyableIterableAssert; -import org.assertj.core.data.TolkienCharacter; -import org.assertj.core.data.TolkienCharacter.Race; -import org.assertj.core.test.CartoonCharacter; -import org.junit.AfterClass; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -/** - * verify that assertions final methods in {@link IterableAssert} work with assumptions (i.e. that they are proxied correctly in {@link ProxyableIterableAssert}). - */ -@RunWith(Parameterized.class) -public class Iterable_final_method_assertions_in_assumptions_Test extends BaseAssumptionsRunnerTest { - - protected static int ranTests = 0; - - public Iterable_final_method_assertions_in_assumptions_Test(AssumptionRunner assumptionRunner) { - super(assumptionRunner); - } - - @Override - protected void incrementRunTests() { - ranTests++; - } - - @SuppressWarnings("unchecked") - @Parameters - public static Object[][] provideAssumptionsRunners() { - setupData(); - return new AssumptionRunner[][] { - run(iterable(TolkienCharacter.of("Frodo", 33, Race.HOBBIT), TolkienCharacter.of("Sam", 35, Race.HOBBIT)), - value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) - .contains(tuple("Frodo", 33)), - value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) - .contains(tuple("Gandalf", 1000))), - run(iterable(homer, fred), - value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) - .containsAnyOf(bart, lisa), - value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) - .containsAnyOf(homer, fred)), - run(iterable(TolkienCharacter.of("Frodo", 33, Race.HOBBIT), TolkienCharacter.of("Sam", 35, Race.HOBBIT)), - value -> assumeThat(value).flatExtracting(throwingNameExtractor, throwingAgeExtractor) - .contains("Frodo", 33), - value -> assumeThat(value).flatExtracting(throwingNameExtractor, throwingAgeExtractor) - .contains("Gandalf", 1000)), - run(iterable(TolkienCharacter.of("Frodo", 33, Race.HOBBIT), TolkienCharacter.of("Sam", 35, Race.HOBBIT)), - value -> assumeThat(value).flatExtracting(nameExtractor, ageExtractor) - .contains("Frodo", 33), - value -> assumeThat(value).flatExtracting(nameExtractor, ageExtractor) - .contains("Gandalf", 1000)), - run(iterable(1, 2, 3), - value -> assumeThat(value).contains(1, 2), - value -> assumeThat(value).contains(4)), - run(iterable(1, 2, 3), - value -> assumeThat(value).containsAnyOf(1, 10, 20), - value -> assumeThat(value).containsAnyOf(0, 5, 10)), - run(iterable(1, 2, 3), - value -> assumeThat(value).containsExactly(1, 2, 3), - value -> assumeThat(value).containsExactly(4)), - run(iterable(1, 2, 3), - value -> assumeThat(value).containsExactlyInAnyOrder(2, 1, 3), - value -> assumeThat(value).containsExactlyInAnyOrder(1, 2)), - run(iterable(1, 2, 3), - value -> assumeThat(value).containsOnly(2, 1, 3, 2), - value -> assumeThat(value).containsOnly(1, 2, 4)), - run(iterable(2, 4, 2), - value -> assumeThat(value).containsOnlyOnce(4), - value -> assumeThat(value).containsOnlyOnce(2)), - run(iterable(1, 2, 3), - value -> assumeThat(value).containsSequence(1, 2), - value -> assumeThat(value).containsSequence(1, 3)), - run(iterable(1, 2, 3), - value -> assumeThat(value).containsSubsequence(1, 3), - value -> assumeThat(value).containsSubsequence(2, 1)), - run(iterable(1, 2, 3), - value -> assumeThat(value).doesNotContain(4, 5), - value -> assumeThat(value).doesNotContain(2, 1)), - run(iterable(1, 2, 3), - value -> assumeThat(value).doesNotContainSequence(1, 3), - value -> assumeThat(value).doesNotContainSequence(1, 2)), - run(iterable(1, 2, 3), - value -> assumeThat(value).doesNotContainSubsequence(2, 1), - value -> assumeThat(value).doesNotContainSubsequence(1, 3)), - run(iterable(1, 2, 3), - value -> assumeThat(value).isSubsetOf(1, 2, 3, 4), - value -> assumeThat(value).isSubsetOf(2, 4, 6)), - run(iterable(1, 2, 3), - value -> assumeThat(value).startsWith(1, 2), - value -> assumeThat(value).startsWith(2, 3)), - run(iterable(1, 2, 3), - value -> assumeThat(value).endsWith(2, 3), - value -> assumeThat(value).endsWith(2, 4)) - }; - } - - @AfterClass - public static void afterClass() { - assertThat(ranTests).as("number of tests run").isEqualTo(provideAssumptionsRunners().length); - } - -} diff --git a/src/test/java/org/assertj/core/api/assumptions/Iterable_special_assertion_methods_in_assumptions_Test.java b/src/test/java/org/assertj/core/api/assumptions/Iterable_special_assertion_methods_in_assumptions_Test.java new file mode 100644 index 0000000000..e3f31deb01 --- /dev/null +++ b/src/test/java/org/assertj/core/api/assumptions/Iterable_special_assertion_methods_in_assumptions_Test.java @@ -0,0 +1,218 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2012-2018 the original author or authors. + */ +package org.assertj.core.api.assumptions; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.in; +import static org.assertj.core.api.Assertions.tuple; +import static org.assertj.core.api.Assumptions.assumeThat; +import static org.assertj.core.api.assumptions.BaseAssumptionRunner.run; +import static org.assertj.core.util.IterableUtil.iterable; + +import org.assertj.core.api.Condition; +import org.assertj.core.api.IterableAssert; +import org.assertj.core.api.ProxyableIterableAssert; +import org.assertj.core.data.TolkienCharacter; +import org.assertj.core.test.CartoonCharacter; +import org.junit.AfterClass; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * verify that assertions final methods or methods changing the object under test in {@link IterableAssert} work with assumptions + * (i.e. that they are proxied correctly in {@link ProxyableIterableAssert}). + */ +@RunWith(Parameterized.class) +public class Iterable_special_assertion_methods_in_assumptions_Test extends BaseAssumptionsRunnerTest { + + protected static int ranTests = 0; + + public Iterable_special_assertion_methods_in_assumptions_Test(AssumptionRunner assumptionRunner) { + super(assumptionRunner); + } + + @Override + protected void incrementRunTests() { + ranTests++; + } + + @SuppressWarnings("unchecked") + @Parameters + public static Object[][] provideAssumptionsRunners() { + setupData(); + + return new AssumptionRunner[][] { + // extracting methods + run(iterable(frodo, sam), + value -> assumeThat(value).extracting(throwingNameExtractor) + .contains("Frodo"), + value -> assumeThat(value).extracting(throwingNameExtractor) + .contains("Gandalf")), + run(iterable(frodo, sam), + value -> assumeThat(value).extracting(nameExtractor) + .contains("Frodo", "Sam"), + value -> assumeThat(value).extracting(nameExtractor) + .contains("Gandalf", "Sam")), + run(iterable(frodo, sam), + value -> assumeThat(value).extracting("name") + .contains("Frodo", "Sam"), + value -> assumeThat(value).extracting("name") + .contains("Gandalf", "Sam")), + run(iterable(frodo, sam), + value -> assumeThat(value).extracting("name", String.class) + .contains("Frodo", "Sam"), + value -> assumeThat(value).extracting("name", String.class) + .contains("Gandalf", "Sam")), + run(iterable(frodo, sam), + value -> assumeThat(value).extracting("name", "age") + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).extracting("name", "age") + .contains(tuple("Gandalf", 1000))), + run(iterable(frodo, sam), + value -> assumeThat(value).extracting(nameExtractorFunction, ageExtractorFunction) + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).extracting(nameExtractorFunction, ageExtractorFunction) + .contains(tuple("Gandalf", 1000))), + run(iterable(frodo, sam), + value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) + .contains(tuple("Gandalf", 1000))), + // extractingResultOf methods + run(iterable(frodo, sam), + value -> assumeThat(value).extractingResultOf("getName") + .contains("Frodo", "Sam"), + value -> assumeThat(value).extractingResultOf("getName") + .contains("Gandalf", "Sam")), + run(iterable(frodo, sam), + value -> assumeThat(value).extractingResultOf("getName", String.class) + .contains("Frodo", "Sam"), + value -> assumeThat(value).extractingResultOf("getName", String.class) + .contains("Gandalf", "Sam")), + // flatExtracting methods + run(iterable(homer, fred), + value -> assumeThat(value).flatExtracting("children") + .containsAnyOf(bart, lisa), + value -> assumeThat(value).flatExtracting("children") + .containsAnyOf(homer, fred)), + run(iterable(homer, fred), + value -> assumeThat(value).flatExtracting(childrenExtractor) + .containsAnyOf(bart, lisa), + value -> assumeThat(value).flatExtracting(childrenExtractor) + .containsAnyOf(homer, fred)), + run(iterable(homer, fred), + value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) + .containsAnyOf(bart, lisa), + value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) + .containsAnyOf(homer, fred)), + run(iterable(frodo, sam), + value -> assumeThat(value).flatExtracting(throwingNameExtractor, throwingAgeExtractor) + .contains("Frodo", 33), + value -> assumeThat(value).flatExtracting(throwingNameExtractor, throwingAgeExtractor) + .contains("Gandalf", 1000)), + run(iterable(frodo, sam), + value -> assumeThat(value).flatExtracting(nameExtractor, ageExtractor) + .contains("Frodo", 33), + value -> assumeThat(value).flatExtracting(nameExtractor, ageExtractor) + .contains("Gandalf", 1000)), + run(iterable(frodo, sam), + value -> assumeThat(value).flatExtracting("name", "age") + .contains("Frodo", 33), + value -> assumeThat(value).flatExtracting("name", "age") + .contains("Gandalf", 1000)), + // filteredOn methods + run(iterable(frodo, sam), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .contains(frodo), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .contains(sam)), + run(iterable(frodo, sam), + value -> assumeThat(value).filteredOn(new Condition<>(hero -> hero.getName().startsWith("Fro"), "startsWith Fro")) + .contains(frodo), + value -> assumeThat(value).filteredOn(new Condition<>(hero -> hero.getName().startsWith("Fro"), "startsWith Fro")) + .contains(sam)), + run(iterable(frodo, sam), + value -> assumeThat(value).filteredOn("name", "Frodo") + .contains(frodo), + value -> assumeThat(value).filteredOn("name", "Frodo") + .contains(sam)), + run(iterable(frodo, sam), + value -> assumeThat(value).filteredOnNull("name") + .isEmpty(), + value -> assumeThat(value).filteredOnNull("name") + .contains(sam)), + run(iterable(frodo, sam), + value -> assumeThat(value).filteredOn("name", in("John", "Frodo")) + .contains(frodo), + value -> assumeThat(value).filteredOn("name", in("John", "Frodo")) + .contains(sam)), + run(iterable(frodo, sam), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .extracting("name", "age") + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .extracting("name", "age") + .contains(tuple("Sam", 35))), + // final methods + run(iterable(1, 2, 3), + value -> assumeThat(value).contains(1, 2), + value -> assumeThat(value).contains(4)), + run(iterable(1, 2, 3), + value -> assumeThat(value).containsAnyOf(1, 10, 20), + value -> assumeThat(value).containsAnyOf(0, 5, 10)), + run(iterable(1, 2, 3), + value -> assumeThat(value).containsExactly(1, 2, 3), + value -> assumeThat(value).containsExactly(4)), + run(iterable(1, 2, 3), + value -> assumeThat(value).containsExactlyInAnyOrder(2, 1, 3), + value -> assumeThat(value).containsExactlyInAnyOrder(1, 2)), + run(iterable(1, 2, 3), + value -> assumeThat(value).containsOnly(2, 1, 3, 2), + value -> assumeThat(value).containsOnly(1, 2, 4)), + run(iterable(2, 4, 2), + value -> assumeThat(value).containsOnlyOnce(4), + value -> assumeThat(value).containsOnlyOnce(2)), + run(iterable(1, 2, 3), + value -> assumeThat(value).containsSequence(1, 2), + value -> assumeThat(value).containsSequence(1, 3)), + run(iterable(1, 2, 3), + value -> assumeThat(value).containsSubsequence(1, 3), + value -> assumeThat(value).containsSubsequence(2, 1)), + run(iterable(1, 2, 3), + value -> assumeThat(value).doesNotContain(4, 5), + value -> assumeThat(value).doesNotContain(2, 1)), + run(iterable(1, 2, 3), + value -> assumeThat(value).doesNotContainSequence(1, 3), + value -> assumeThat(value).doesNotContainSequence(1, 2)), + run(iterable(1, 2, 3), + value -> assumeThat(value).doesNotContainSubsequence(2, 1), + value -> assumeThat(value).doesNotContainSubsequence(1, 3)), + run(iterable(1, 2, 3), + value -> assumeThat(value).isSubsetOf(1, 2, 3, 4), + value -> assumeThat(value).isSubsetOf(2, 4, 6)), + run(iterable(1, 2, 3), + value -> assumeThat(value).startsWith(1, 2), + value -> assumeThat(value).startsWith(2, 3)), + run(iterable(1, 2, 3), + value -> assumeThat(value).endsWith(2, 3), + value -> assumeThat(value).endsWith(2, 4)) + }; + } + + @AfterClass + public static void afterClass() { + assertThat(ranTests).as("number of tests run").isEqualTo(provideAssumptionsRunners().length); + } + +} diff --git a/src/test/java/org/assertj/core/api/assumptions/List_final_method_assertions_in_assumptions_Test.java b/src/test/java/org/assertj/core/api/assumptions/List_final_method_assertions_in_assumptions_Test.java deleted file mode 100644 index 7ae3b32827..0000000000 --- a/src/test/java/org/assertj/core/api/assumptions/List_final_method_assertions_in_assumptions_Test.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2012-2018 the original author or authors. - */ -package org.assertj.core.api.assumptions; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.assertj.core.api.Assumptions.assumeThat; -import static org.assertj.core.api.assumptions.BaseAssumptionRunner.run; - -import org.assertj.core.api.ListAssert; -import org.assertj.core.api.ProxyableListAssert; -import org.assertj.core.data.TolkienCharacter; -import org.assertj.core.data.TolkienCharacter.Race; -import org.assertj.core.test.CartoonCharacter; -import org.junit.AfterClass; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -/** - * verify that assertions final methods in {@link ListAssert} work with assumptions (i.e. that they are proxied correctly in {@link ProxyableListAssert}). - */ -@RunWith(Parameterized.class) -public class List_final_method_assertions_in_assumptions_Test extends BaseAssumptionsRunnerTest { - - private static int ranTests = 0; - - public List_final_method_assertions_in_assumptions_Test(AssumptionRunner assumptionRunner) { - super(assumptionRunner); - } - - @Override - protected void incrementRunTests() { - ranTests++; - } - - @SuppressWarnings("unchecked") - @Parameters - public static Object[][] provideAssumptionsRunners() { - setupData(); - return new AssumptionRunner[][] { - run(asList(TolkienCharacter.of("Frodo", 33, Race.HOBBIT), TolkienCharacter.of("Sam", 35, Race.HOBBIT)), - value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) - .contains(tuple("Frodo", 33)), - value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) - .contains(tuple("Gandalf", 1000))), - run(asList(homer, fred), - value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) - .containsAnyOf(bart, lisa), - value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) - .containsAnyOf(homer, fred)), - run(asList(TolkienCharacter.of("Frodo", 33, Race.HOBBIT), TolkienCharacter.of("Sam", 35, Race.HOBBIT)), - value -> assumeThat(value).flatExtracting(throwingNameExtractor, throwingAgeExtractor) - .contains("Frodo", 33), - value -> assumeThat(value).flatExtracting(throwingNameExtractor, throwingAgeExtractor) - .contains("Gandalf", 1000)), - run(asList(TolkienCharacter.of("Frodo", 33, Race.HOBBIT), TolkienCharacter.of("Sam", 35, Race.HOBBIT)), - value -> assumeThat(value).flatExtracting(nameExtractor, ageExtractor) - .contains("Frodo", 33), - value -> assumeThat(value).flatExtracting(nameExtractor, ageExtractor) - .contains("Gandalf", 1000)), - run(asList(1, 2, 3), - value -> assumeThat(value).contains(1, 2), - value -> assumeThat(value).contains(4)), - run(asList(1, 2, 3), - value -> assumeThat(value).containsAnyOf(1, 10, 20), - value -> assumeThat(value).containsAnyOf(0, 5, 10)), - run(asList(1, 2, 3), - value -> assumeThat(value).containsExactly(1, 2, 3), - value -> assumeThat(value).containsExactly(4)), - run(asList(1, 2, 3), - value -> assumeThat(value).containsExactlyInAnyOrder(2, 1, 3), - value -> assumeThat(value).containsExactlyInAnyOrder(1, 2)), - run(asList(1, 2, 3), - value -> assumeThat(value).containsOnly(2, 1, 3, 2), - value -> assumeThat(value).containsOnly(1, 2, 4)), - run(asList(2, 4, 2), - value -> assumeThat(value).containsOnlyOnce(4), - value -> assumeThat(value).containsOnlyOnce(2)), - run(asList(1, 2, 3), - value -> assumeThat(value).containsSequence(1, 2), - value -> assumeThat(value).containsSequence(1, 3)), - run(asList(1, 2, 3), - value -> assumeThat(value).containsSubsequence(1, 3), - value -> assumeThat(value).containsSubsequence(2, 1)), - run(asList(1, 2, 3), - value -> assumeThat(value).doesNotContain(4, 5), - value -> assumeThat(value).doesNotContain(2, 1)), - run(asList(1, 2, 3), - value -> assumeThat(value).doesNotContainSequence(1, 3), - value -> assumeThat(value).doesNotContainSequence(1, 2)), - run(asList(1, 2, 3), - value -> assumeThat(value).doesNotContainSubsequence(2, 1), - value -> assumeThat(value).doesNotContainSubsequence(1, 3)), - run(asList(1, 2, 3), - value -> assumeThat(value).isSubsetOf(1, 2, 3, 4), - value -> assumeThat(value).isSubsetOf(2, 4, 6)), - run(asList(1, 2, 3), - value -> assumeThat(value).startsWith(1, 2), - value -> assumeThat(value).startsWith(2, 3)), - run(asList(1, 2, 3), - value -> assumeThat(value).endsWith(2, 3), - value -> assumeThat(value).endsWith(2, 4)) - }; - }; - - @AfterClass - public static void afterClass() { - assertThat(ranTests).as("number of tests run").isEqualTo(provideAssumptionsRunners().length); - } - -} diff --git a/src/test/java/org/assertj/core/api/assumptions/List_special_assertion_methods_in_assumptions_Test.java b/src/test/java/org/assertj/core/api/assumptions/List_special_assertion_methods_in_assumptions_Test.java new file mode 100644 index 0000000000..190aea1dcb --- /dev/null +++ b/src/test/java/org/assertj/core/api/assumptions/List_special_assertion_methods_in_assumptions_Test.java @@ -0,0 +1,216 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2012-2018 the original author or authors. + */ +package org.assertj.core.api.assumptions; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.in; +import static org.assertj.core.api.Assertions.tuple; +import static org.assertj.core.api.Assumptions.assumeThat; +import static org.assertj.core.api.assumptions.BaseAssumptionRunner.run; + +import org.assertj.core.api.Condition; +import org.assertj.core.api.ListAssert; +import org.assertj.core.api.ProxyableListAssert; +import org.assertj.core.data.TolkienCharacter; +import org.assertj.core.test.CartoonCharacter; +import org.junit.AfterClass; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * verify that assertions final methods or methods changing the object under test in {@link ListAssert} work with assumptions + * (i.e. that they are proxied correctly in {@link ProxyableListAssert}). + */ +@RunWith(Parameterized.class) +public class List_special_assertion_methods_in_assumptions_Test extends BaseAssumptionsRunnerTest { + + private static int ranTests = 0; + + public List_special_assertion_methods_in_assumptions_Test(AssumptionRunner assumptionRunner) { + super(assumptionRunner); + } + + @Override + protected void incrementRunTests() { + ranTests++; + } + + @SuppressWarnings("unchecked") + @Parameters + public static Object[][] provideAssumptionsRunners() { + setupData(); + return new AssumptionRunner[][] { + // extracting methods + run(asList(frodo, sam), + value -> assumeThat(value).extracting(throwingNameExtractor) + .contains("Frodo"), + value -> assumeThat(value).extracting(throwingNameExtractor) + .contains("Gandalf")), + run(asList(frodo, sam), + value -> assumeThat(value).extracting(nameExtractor) + .contains("Frodo", "Sam"), + value -> assumeThat(value).extracting(nameExtractor) + .contains("Gandalf", "Sam")), + run(asList(frodo, sam), + value -> assumeThat(value).extracting("name") + .contains("Frodo", "Sam"), + value -> assumeThat(value).extracting("name") + .contains("Gandalf", "Sam")), + run(asList(frodo, sam), + value -> assumeThat(value).extracting("name", String.class) + .contains("Frodo", "Sam"), + value -> assumeThat(value).extracting("name", String.class) + .contains("Gandalf", "Sam")), + run(asList(frodo, sam), + value -> assumeThat(value).extracting("name", "age") + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).extracting("name", "age") + .contains(tuple("Gandalf", 1000))), + run(asList(frodo, sam), + value -> assumeThat(value).extracting(nameExtractorFunction, ageExtractorFunction) + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).extracting(nameExtractorFunction, ageExtractorFunction) + .contains(tuple("Gandalf", 1000))), + run(asList(frodo, sam), + value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) + .contains(tuple("Gandalf", 1000))), + // extractingResultOf methods + run(asList(frodo, sam), + value -> assumeThat(value).extractingResultOf("getName") + .contains("Frodo", "Sam"), + value -> assumeThat(value).extractingResultOf("getName") + .contains("Gandalf", "Sam")), + run(asList(frodo, sam), + value -> assumeThat(value).extractingResultOf("getName", String.class) + .contains("Frodo", "Sam"), + value -> assumeThat(value).extractingResultOf("getName", String.class) + .contains("Gandalf", "Sam")), + // flatExtracting methods + run(asList(homer, fred), + value -> assumeThat(value).flatExtracting("children") + .containsAnyOf(bart, lisa), + value -> assumeThat(value).flatExtracting("children") + .containsAnyOf(homer, fred)), + run(asList(homer, fred), + value -> assumeThat(value).flatExtracting(childrenExtractor) + .containsAnyOf(bart, lisa), + value -> assumeThat(value).flatExtracting(childrenExtractor) + .containsAnyOf(homer, fred)), + run(asList(homer, fred), + value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) + .containsAnyOf(bart, lisa), + value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) + .containsAnyOf(homer, fred)), + run(asList(frodo, sam), + value -> assumeThat(value).flatExtracting(throwingNameExtractor, throwingAgeExtractor) + .contains("Frodo", 33), + value -> assumeThat(value).flatExtracting(throwingNameExtractor, throwingAgeExtractor) + .contains("Gandalf", 1000)), + run(asList(frodo, sam), + value -> assumeThat(value).flatExtracting(nameExtractor, ageExtractor) + .contains("Frodo", 33), + value -> assumeThat(value).flatExtracting(nameExtractor, ageExtractor) + .contains("Gandalf", 1000)), + run(asList(frodo, sam), + value -> assumeThat(value).flatExtracting("name", "age") + .contains("Frodo", 33), + value -> assumeThat(value).flatExtracting("name", "age") + .contains("Gandalf", 1000)), + // filteredOn methods + run(asList(frodo, sam), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .contains(frodo), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .contains(sam)), + run(asList(frodo, sam), + value -> assumeThat(value).filteredOn(new Condition<>(hero -> hero.getName().startsWith("Fro"), "startsWith Fro")) + .contains(frodo), + value -> assumeThat(value).filteredOn(new Condition<>(hero -> hero.getName().startsWith("Fro"), "startsWith Fro")) + .contains(sam)), + run(asList(frodo, sam), + value -> assumeThat(value).filteredOn("name", "Frodo") + .contains(frodo), + value -> assumeThat(value).filteredOn("name", "Frodo") + .contains(sam)), + run(asList(frodo, sam), + value -> assumeThat(value).filteredOnNull("name") + .isEmpty(), + value -> assumeThat(value).filteredOnNull("name") + .contains(sam)), + run(asList(frodo, sam), + value -> assumeThat(value).filteredOn("name", in("John", "Frodo")) + .contains(frodo), + value -> assumeThat(value).filteredOn("name", in("John", "Frodo")) + .contains(sam)), + run(asList(frodo, sam), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .extracting("name", "age") + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .extracting("name", "age") + .contains(tuple("Sam", 35))), + run(asList(1, 2, 3), + value -> assumeThat(value).contains(1, 2), + value -> assumeThat(value).contains(4)), + run(asList(1, 2, 3), + value -> assumeThat(value).containsAnyOf(1, 10, 20), + value -> assumeThat(value).containsAnyOf(0, 5, 10)), + run(asList(1, 2, 3), + value -> assumeThat(value).containsExactly(1, 2, 3), + value -> assumeThat(value).containsExactly(4)), + run(asList(1, 2, 3), + value -> assumeThat(value).containsExactlyInAnyOrder(2, 1, 3), + value -> assumeThat(value).containsExactlyInAnyOrder(1, 2)), + run(asList(1, 2, 3), + value -> assumeThat(value).containsOnly(2, 1, 3, 2), + value -> assumeThat(value).containsOnly(1, 2, 4)), + run(asList(2, 4, 2), + value -> assumeThat(value).containsOnlyOnce(4), + value -> assumeThat(value).containsOnlyOnce(2)), + run(asList(1, 2, 3), + value -> assumeThat(value).containsSequence(1, 2), + value -> assumeThat(value).containsSequence(1, 3)), + run(asList(1, 2, 3), + value -> assumeThat(value).containsSubsequence(1, 3), + value -> assumeThat(value).containsSubsequence(2, 1)), + run(asList(1, 2, 3), + value -> assumeThat(value).doesNotContain(4, 5), + value -> assumeThat(value).doesNotContain(2, 1)), + run(asList(1, 2, 3), + value -> assumeThat(value).doesNotContainSequence(1, 3), + value -> assumeThat(value).doesNotContainSequence(1, 2)), + run(asList(1, 2, 3), + value -> assumeThat(value).doesNotContainSubsequence(2, 1), + value -> assumeThat(value).doesNotContainSubsequence(1, 3)), + run(asList(1, 2, 3), + value -> assumeThat(value).isSubsetOf(1, 2, 3, 4), + value -> assumeThat(value).isSubsetOf(2, 4, 6)), + run(asList(1, 2, 3), + value -> assumeThat(value).startsWith(1, 2), + value -> assumeThat(value).startsWith(2, 3)), + run(asList(1, 2, 3), + value -> assumeThat(value).endsWith(2, 3), + value -> assumeThat(value).endsWith(2, 4)) + }; + }; + + @AfterClass + public static void afterClass() { + assertThat(ranTests).as("number of tests run").isEqualTo(provideAssumptionsRunners().length); + } + +} diff --git a/src/test/java/org/assertj/core/api/assumptions/Map_final_method_assertions_in_assumptions_Test.java b/src/test/java/org/assertj/core/api/assumptions/Map_special_assertion_methods_in_assumptions_Test.java similarity index 66% rename from src/test/java/org/assertj/core/api/assumptions/Map_final_method_assertions_in_assumptions_Test.java rename to src/test/java/org/assertj/core/api/assumptions/Map_special_assertion_methods_in_assumptions_Test.java index d4a3f4e7c5..aafb2ce022 100644 --- a/src/test/java/org/assertj/core/api/assumptions/Map_final_method_assertions_in_assumptions_Test.java +++ b/src/test/java/org/assertj/core/api/assumptions/Map_special_assertion_methods_in_assumptions_Test.java @@ -12,30 +12,36 @@ */ package org.assertj.core.api.assumptions; +import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.api.Assumptions.assumeThat; import static org.assertj.core.api.assumptions.BaseAssumptionRunner.run; import static org.assertj.core.test.Maps.mapOf; +import static org.assertj.core.util.Sets.newLinkedHashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; -import org.assertj.core.api.ClassAssert; -import org.assertj.core.api.ProxyableClassAssert; +import org.assertj.core.api.MapAssert; +import org.assertj.core.api.ProxyableMapAssert; import org.junit.AfterClass; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; /** - * verify that assertions final methods in {@link ClassAssert} work with assumptions (i.e. that they are proxied correctly in {@link ProxyableClassAssert}). + * verify that assertions final methods or methods changing the object under test in {@link MapAssert} work with assumptions + * (i.e. that they are proxied correctly in {@link ProxyableMapAssert}). */ @RunWith(Parameterized.class) -public class Map_final_method_assertions_in_assumptions_Test extends BaseAssumptionsRunnerTest { +public class Map_special_assertion_methods_in_assumptions_Test extends BaseAssumptionsRunnerTest { private static int ranTests = 0; - public Map_final_method_assertions_in_assumptions_Test(AssumptionRunner assumptionRunner) { + public Map_special_assertion_methods_in_assumptions_Test(AssumptionRunner assumptionRunner) { super(assumptionRunner); } @@ -47,7 +53,19 @@ protected void incrementRunTests() { @SuppressWarnings("unchecked") @Parameters public static Object[][] provideAssumptionsRunners() { + + List names = asList("Dave", "Jeff"); + LinkedHashSet jobs = newLinkedHashSet("Plumber", "Builder"); + Iterable cities = asList("Dover", "Boston", "Paris"); + int[] ranks = { 1, 2, 3 }; + Map iterableMap = new LinkedHashMap<>(); + iterableMap.put("name", names); + iterableMap.put("job", jobs); + iterableMap.put("city", cities); + iterableMap.put("rank", ranks); + Map map = mapOf(entry("a", "1"), entry("b", "2"), entry("c", "3")); + return new AssumptionRunner[][] { run(map, value -> assumeThat(value).contains(entry("a", "1"), entry("c", "3")), @@ -76,6 +94,14 @@ public static Object[][] provideAssumptionsRunners() { run(map, value -> assumeThat(value).doesNotContainKeys("d", "e", "f"), value -> assumeThat(value).doesNotContainKeys("a", "e", "f")), + run(map, + value -> assumeThat(value).extracting("a", "b").contains("1", "2"), + value -> assumeThat(value).extracting("a", "b").contains("456")), + run(iterableMap, + value -> assumeThat(value).flatExtracting("name", "job", "city", "rank") + .contains("Jeff", "Builder", "Dover", "Boston", "Paris", 1, 2, 3), + value -> assumeThat(value).flatExtracting("name", "job", "city", "rank") + .contains("Unexpected", "Builder", "Dover", "Boston", "Paris", 1, 2, 3)), }; }; diff --git a/src/test/java/org/assertj/core/api/assumptions/ObjectArray_assumptions_Test.java b/src/test/java/org/assertj/core/api/assumptions/ObjectArray_assumptions_Test.java deleted file mode 100644 index a5f5655a62..0000000000 --- a/src/test/java/org/assertj/core/api/assumptions/ObjectArray_assumptions_Test.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * Copyright 2012-2018 the original author or authors. - */ -package org.assertj.core.api.assumptions; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.assertj.core.api.Assumptions.assumeThat; -import static org.assertj.core.api.assumptions.BaseAssumptionRunner.run; -import static org.assertj.core.util.Arrays.array; - -import org.assertj.core.data.TolkienCharacter; -import org.assertj.core.data.TolkienCharacter.Race; -import org.junit.AfterClass; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -/** - * verify that assertions including final methods in work with assumptions. - */ -@RunWith(Parameterized.class) -public class ObjectArray_assumptions_Test extends BaseAssumptionsRunnerTest { - - private static int ranTests = 0; - - public ObjectArray_assumptions_Test(AssumptionRunner assumptionRunner) { - super(assumptionRunner); - } - - @Override - protected void incrementRunTests() { - ranTests++; - } - - @SuppressWarnings("unchecked") - @Parameters - public static Object[][] provideAssumptionsRunners() { - return new AssumptionRunner[][] { - run(array(TolkienCharacter.of("Frodo", 33, Race.HOBBIT), TolkienCharacter.of("Sam", 35, Race.HOBBIT)), - value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) - .contains(tuple("Frodo", 33)), - value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) - .contains(tuple("Gandalf", 1000))), - run(array(1, 2, 3), - value -> assumeThat(value).contains(1, 2), - value -> assumeThat(value).contains(4)), - run(array(1, 2, 3), - value -> assumeThat(value).containsAnyOf(1, 10, 20), - value -> assumeThat(value).containsAnyOf(0, 5, 10)), - run(array(1, 2, 3), - value -> assumeThat(value).containsExactly(1, 2, 3), - value -> assumeThat(value).containsExactly(4)), - run(array(1, 2, 3), - value -> assumeThat(value).containsExactlyInAnyOrder(2, 1, 3), - value -> assumeThat(value).containsExactlyInAnyOrder(1, 2)), - run(array(1, 2, 3), - value -> assumeThat(value).containsOnly(2, 1, 3, 2), - value -> assumeThat(value).containsOnly(1, 2, 4)), - run(array(2, 4, 2), - value -> assumeThat(value).containsOnlyOnce(4), - value -> assumeThat(value).containsOnlyOnce(2)), - run(array(1, 2, 3), - value -> assumeThat(value).containsSequence(1, 2), - value -> assumeThat(value).containsSequence(1, 3)), - run(array(1, 2, 3), - value -> assumeThat(value).containsSubsequence(1, 3), - value -> assumeThat(value).containsSubsequence(2, 1)), - run(array(1, 2, 3), - value -> assumeThat(value).doesNotContain(4, 5), - value -> assumeThat(value).doesNotContain(2, 1)), - run(array(1, 2, 3), - value -> assumeThat(value).doesNotContainSequence(1, 3), - value -> assumeThat(value).doesNotContainSequence(1, 2)), - run(array(1, 2, 3), - value -> assumeThat(value).doesNotContainSubsequence(2, 1), - value -> assumeThat(value).doesNotContainSubsequence(1, 3)), - run(array(1, 2, 3), - value -> assumeThat(value).isSubsetOf(1, 2, 3, 4), - value -> assumeThat(value).isSubsetOf(2, 4, 6)), - run(array(1, 2, 3), - value -> assumeThat(value).startsWith(1, 2), - value -> assumeThat(value).startsWith(2, 3)), - run(array(1, 2, 3), - value -> assumeThat(value).endsWith(2, 3), - value -> assumeThat(value).endsWith(2, 4)) - }; - }; - - @AfterClass - public static void afterClass() { - assertThat(ranTests).as("number of tests run").isEqualTo(provideAssumptionsRunners().length); - } - -} diff --git a/src/test/java/org/assertj/core/api/assumptions/ObjectArray_special_assertion_methods_in_assumptions_Test.java b/src/test/java/org/assertj/core/api/assumptions/ObjectArray_special_assertion_methods_in_assumptions_Test.java new file mode 100644 index 0000000000..3260413141 --- /dev/null +++ b/src/test/java/org/assertj/core/api/assumptions/ObjectArray_special_assertion_methods_in_assumptions_Test.java @@ -0,0 +1,201 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * Copyright 2012-2018 the original author or authors. + */ +package org.assertj.core.api.assumptions; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.in; +import static org.assertj.core.api.Assertions.tuple; +import static org.assertj.core.api.Assumptions.assumeThat; +import static org.assertj.core.api.assumptions.BaseAssumptionRunner.run; +import static org.assertj.core.util.Arrays.array; + +import org.assertj.core.api.Condition; +import org.assertj.core.api.ObjectArrayAssert; +import org.assertj.core.api.ProxyableObjectArrayAssert; +import org.assertj.core.data.TolkienCharacter; +import org.assertj.core.test.CartoonCharacter; +import org.junit.AfterClass; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * verify that assertions final methods or methods changing the object under test in {@link ObjectArrayAssert} work with assumptions + * (i.e. that they are proxied correctly in {@link ProxyableObjectArrayAssert}). + */ +@RunWith(Parameterized.class) +public class ObjectArray_special_assertion_methods_in_assumptions_Test extends BaseAssumptionsRunnerTest { + + private static int ranTests = 0; + + public ObjectArray_special_assertion_methods_in_assumptions_Test(AssumptionRunner assumptionRunner) { + super(assumptionRunner); + } + + @Override + protected void incrementRunTests() { + ranTests++; + } + + @SuppressWarnings("unchecked") + @Parameters + public static Object[][] provideAssumptionsRunners() { + setupData(); + return new AssumptionRunner[][] { + // extracting methods + run(array(frodo, sam), + value -> assumeThat(value).extracting(throwingNameExtractor) + .contains("Frodo"), + value -> assumeThat(value).extracting(throwingNameExtractor) + .contains("Gandalf")), + run(array(frodo, sam), + value -> assumeThat(value).extracting(nameExtractor) + .contains("Frodo", "Sam"), + value -> assumeThat(value).extracting(nameExtractor) + .contains("Gandalf", "Sam")), + run(array(frodo, sam), + value -> assumeThat(value).extracting("name") + .contains("Frodo", "Sam"), + value -> assumeThat(value).extracting("name") + .contains("Gandalf", "Sam")), + run(array(frodo, sam), + value -> assumeThat(value).extracting("name", String.class) + .contains("Frodo", "Sam"), + value -> assumeThat(value).extracting("name", String.class) + .contains("Gandalf", "Sam")), + run(array(frodo, sam), + value -> assumeThat(value).extracting("name", "age") + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).extracting("name", "age") + .contains(tuple("Gandalf", 1000))), + run(array(frodo, sam), + value -> assumeThat(value).extracting(nameExtractorFunction, ageExtractorFunction) + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).extracting(nameExtractorFunction, ageExtractorFunction) + .contains(tuple("Gandalf", 1000))), + run(array(frodo, sam), + value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) + .contains(tuple("Gandalf", 1000))), + // extractingResultOf methods + run(array(frodo, sam), + value -> assumeThat(value).extractingResultOf("getName") + .contains("Frodo", "Sam"), + value -> assumeThat(value).extractingResultOf("getName") + .contains("Gandalf", "Sam")), + run(array(frodo, sam), + value -> assumeThat(value).extractingResultOf("getName", String.class) + .contains("Frodo", "Sam"), + value -> assumeThat(value).extractingResultOf("getName", String.class) + .contains("Gandalf", "Sam")), + // flatExtracting methods + run(array(homer, fred), + value -> assumeThat(value).flatExtracting("children") + .containsAnyOf(bart, lisa), + value -> assumeThat(value).flatExtracting("children") + .containsAnyOf(homer, fred)), + run(array(homer, fred), + value -> assumeThat(value).flatExtracting(childrenExtractor) + .containsAnyOf(bart, lisa), + value -> assumeThat(value).flatExtracting(childrenExtractor) + .containsAnyOf(homer, fred)), + run(array(homer, fred), + value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) + .containsAnyOf(bart, lisa), + value -> assumeThat(value).flatExtracting(CartoonCharacter::getChildren) + .containsAnyOf(homer, fred)), + // filteredOn methods + run(array(frodo, sam), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .contains(frodo), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .contains(sam)), + run(array(frodo, sam), + value -> assumeThat(value).filteredOn(new Condition<>(hero -> hero.getName().startsWith("Fro"), "startsWith Fro")) + .contains(frodo), + value -> assumeThat(value).filteredOn(new Condition<>(hero -> hero.getName().startsWith("Fro"), "startsWith Fro")) + .contains(sam)), + run(array(frodo, sam), + value -> assumeThat(value).filteredOn("name", "Frodo") + .contains(frodo), + value -> assumeThat(value).filteredOn("name", "Frodo") + .contains(sam)), + run(array(frodo, sam), + value -> assumeThat(value).filteredOnNull("name") + .isEmpty(), + value -> assumeThat(value).filteredOnNull("name") + .contains(sam)), + run(array(frodo, sam), + value -> assumeThat(value).filteredOn("name", in("John", "Frodo")) + .contains(frodo), + value -> assumeThat(value).filteredOn("name", in("John", "Frodo")) + .contains(sam)), + run(array(frodo, sam), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .extracting("name", "age") + .contains(tuple("Frodo", 33)), + value -> assumeThat(value).filteredOn(hero -> hero.getName().startsWith("Fro")) + .extracting("name", "age") + .contains(tuple("Sam", 35))), + run(array(1, 2, 3), + value -> assumeThat(value).contains(1, 2), + value -> assumeThat(value).contains(4)), + run(array(1, 2, 3), + value -> assumeThat(value).containsAnyOf(1, 10, 20), + value -> assumeThat(value).containsAnyOf(0, 5, 10)), + run(array(1, 2, 3), + value -> assumeThat(value).containsExactly(1, 2, 3), + value -> assumeThat(value).containsExactly(4)), + run(array(1, 2, 3), + value -> assumeThat(value).containsExactlyInAnyOrder(2, 1, 3), + value -> assumeThat(value).containsExactlyInAnyOrder(1, 2)), + run(array(1, 2, 3), + value -> assumeThat(value).containsOnly(2, 1, 3, 2), + value -> assumeThat(value).containsOnly(1, 2, 4)), + run(array(2, 4, 2), + value -> assumeThat(value).containsOnlyOnce(4), + value -> assumeThat(value).containsOnlyOnce(2)), + run(array(1, 2, 3), + value -> assumeThat(value).containsSequence(1, 2), + value -> assumeThat(value).containsSequence(1, 3)), + run(array(1, 2, 3), + value -> assumeThat(value).containsSubsequence(1, 3), + value -> assumeThat(value).containsSubsequence(2, 1)), + run(array(1, 2, 3), + value -> assumeThat(value).doesNotContain(4, 5), + value -> assumeThat(value).doesNotContain(2, 1)), + run(array(1, 2, 3), + value -> assumeThat(value).doesNotContainSequence(1, 3), + value -> assumeThat(value).doesNotContainSequence(1, 2)), + run(array(1, 2, 3), + value -> assumeThat(value).doesNotContainSubsequence(2, 1), + value -> assumeThat(value).doesNotContainSubsequence(1, 3)), + run(array(1, 2, 3), + value -> assumeThat(value).isSubsetOf(1, 2, 3, 4), + value -> assumeThat(value).isSubsetOf(2, 4, 6)), + run(array(1, 2, 3), + value -> assumeThat(value).startsWith(1, 2), + value -> assumeThat(value).startsWith(2, 3)), + run(array(1, 2, 3), + value -> assumeThat(value).endsWith(2, 3), + value -> assumeThat(value).endsWith(2, 4)) + }; + }; + + @AfterClass + public static void afterClass() { + assertThat(ranTests).as("number of tests run").isEqualTo(provideAssumptionsRunners().length); + } + +} diff --git a/src/test/java/org/assertj/core/api/assumptions/Object_final_method_assertions_in_assumptions_Test.java b/src/test/java/org/assertj/core/api/assumptions/Object_special_assertion_methods_in_assumptions_Test.java similarity index 70% rename from src/test/java/org/assertj/core/api/assumptions/Object_final_method_assertions_in_assumptions_Test.java rename to src/test/java/org/assertj/core/api/assumptions/Object_special_assertion_methods_in_assumptions_Test.java index b2b3546439..b9785a0782 100644 --- a/src/test/java/org/assertj/core/api/assumptions/Object_final_method_assertions_in_assumptions_Test.java +++ b/src/test/java/org/assertj/core/api/assumptions/Object_special_assertion_methods_in_assumptions_Test.java @@ -16,8 +16,8 @@ import static org.assertj.core.api.Assumptions.assumeThat; import static org.assertj.core.api.assumptions.BaseAssumptionRunner.run; -import org.assertj.core.api.ClassAssert; -import org.assertj.core.api.ProxyableClassAssert; +import org.assertj.core.api.ObjectAssert; +import org.assertj.core.api.ProxyableObjectAssert; import org.assertj.core.data.TolkienCharacter; import org.assertj.core.data.TolkienCharacter.Race; import org.junit.AfterClass; @@ -26,14 +26,15 @@ import org.junit.runners.Parameterized.Parameters; /** - * verify that assertions final methods in {@link ClassAssert} work with assumptions (i.e. that they are proxied correctly in {@link ProxyableClassAssert}). + * verify that assertions final methods or methods changing the object under test in {@link ObjectAssert} work with assumptions + * (i.e. that they are proxied correctly in {@link ProxyableObjectAssert}). */ @RunWith(Parameterized.class) -public class Object_final_method_assertions_in_assumptions_Test extends BaseAssumptionsRunnerTest { +public class Object_special_assertion_methods_in_assumptions_Test extends BaseAssumptionsRunnerTest {; private static int ranTests = 0; - public Object_final_method_assertions_in_assumptions_Test(AssumptionRunner assumptionRunner) { + public Object_special_assertion_methods_in_assumptions_Test(AssumptionRunner assumptionRunner) { super(assumptionRunner); } @@ -50,6 +51,11 @@ public static Object[][] provideAssumptionsRunners() { value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) .contains("Frodo", 33), value -> assumeThat(value).extracting(TolkienCharacter::getName, TolkienCharacter::getAge) + .contains("Gandalf", 1000)), + run(TolkienCharacter.of("Frodo", 33, Race.HOBBIT), + value -> assumeThat(value).extracting("name", "age") + .contains("Frodo", 33), + value -> assumeThat(value).extracting("name", "age") .contains("Gandalf", 1000)) }; };