Skip to content

Commit 588d24b

Browse files
patrickuhlmannIvoHDalexandra-junghansfmbenhassine
authored
Propagate common basetype for the extracting method (#3673)
Co-authored-by: IvoHD <[email protected]> Co-authored-by: Alexandra Junghans <[email protected]> Co-authored-by: Mahmoud Ben Hassine <[email protected]>
1 parent 60503e1 commit 588d24b

2 files changed

Lines changed: 51 additions & 16 deletions

File tree

assertj-core/src/main/java/org/assertj/core/api/AbstractObjectAssert.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -912,18 +912,18 @@ public AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> extracting(S
912912
*/
913913
@CheckReturnValue
914914
@SafeVarargs
915-
public final AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> extracting(Function<? super ACTUAL, ?>... extractors) {
915+
public final <T> AbstractListAssert<?, List<? extends T>, T, ObjectAssert<T>> extracting(Function<? super ACTUAL, ? extends T>... extractors) {
916916
return extractingForProxy(extractors);
917917
}
918918

919919
// This method is protected in order to be proxied for SoftAssertions / Assumptions.
920920
// The public method for it (the one not ending with "ForProxy") is marked as final and annotated with @SafeVarargs
921921
// in order to avoid compiler warning in user code
922-
protected AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> extractingForProxy(Function<? super ACTUAL, ?>[] extractors) {
922+
protected <T> AbstractListAssert<?, List<? extends T>, T, ObjectAssert<T>> extractingForProxy(Function<? super ACTUAL, ? extends T>[] extractors) {
923923
requireNonNull(extractors, shouldNotBeNull("extractors")::create);
924-
List<Object> values = Stream.of(extractors)
925-
.map(extractor -> extractor.apply(actual))
926-
.collect(toList());
924+
List<T> values = Stream.of(extractors)
925+
.map(extractor -> extractor.apply(actual))
926+
.collect(toList());
927927
return newListAssertInstance(values).withAssertionState(myself);
928928
}
929929

assertj-core/src/test/java/org/assertj/core/api/object/ObjectAssert_extracting_with_Function_Array_Test.java renamed to assertj-tests/assertj-integration-tests/assertj-core-tests/src/test/java/org/assertj/tests/core/api/object/ObjectAssert_extracting_with_Function_Array_Test.java

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,26 @@
1010
*
1111
* Copyright 2012-2024 the original author or authors.
1212
*/
13-
package org.assertj.core.api.object;
13+
package org.assertj.tests.core.api.object;
1414

1515
import static org.assertj.core.api.Assertions.assertThat;
1616
import static org.assertj.core.api.Assertions.catchThrowable;
1717
import static org.assertj.core.api.BDDAssertions.then;
1818
import static org.assertj.core.error.ShouldNotBeNull.shouldNotBeNull;
1919
import static org.assertj.core.presentation.UnicodeRepresentation.UNICODE_REPRESENTATION;
20-
import static org.assertj.core.testkit.AlwaysEqualComparator.ALWAYS_EQUALS;
21-
import static org.assertj.core.testkit.AlwaysEqualComparator.ALWAYS_EQUALS_STRING;
2220

2321
import java.util.List;
2422
import java.util.function.Function;
2523

2624
import org.assertj.core.api.AbstractAssert;
2725
import org.assertj.core.api.AbstractListAssert;
28-
import org.assertj.core.api.NavigationMethodBaseTest;
2926
import org.assertj.core.api.ObjectAssert;
3027
import org.assertj.core.internal.Objects;
31-
import org.assertj.core.testkit.Employee;
32-
import org.assertj.core.testkit.Name;
3328
import org.assertj.core.util.introspection.PropertyOrFieldSupport;
29+
import org.assertj.tests.core.testkit.AlwaysEqualComparator;
30+
import org.assertj.tests.core.testkit.Employee;
31+
import org.assertj.tests.core.testkit.Name;
32+
import org.assertj.tests.core.testkit.NavigationMethodBaseTest;
3433
import org.junit.jupiter.api.BeforeEach;
3534
import org.junit.jupiter.api.Test;
3635

@@ -50,7 +49,41 @@ void should_allow_extracting_values_using_multiple_lambda_extractors() {
5049
// GIVEN
5150
Function<Employee, Object> lastName = employee -> employee.getName().getLast();
5251
// WHEN
53-
AbstractListAssert<?, ?, Object, ?> result = assertThat(luke).extracting(firstName, lastName);
52+
AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> result = assertThat(luke).extracting(firstName, lastName);
53+
// THEN
54+
result.hasSize(2)
55+
.containsExactly("Luke", "Skywalker");
56+
}
57+
58+
static class Manager extends Employee {
59+
public Manager(int age) {
60+
this.setAge(age);
61+
}
62+
}
63+
record Company(Manager manager, Employee employee) {
64+
}
65+
66+
@Test
67+
void should_allow_extracting_values_using_multiple_lambda_extractors_with_common_ancestor() {
68+
// GIVEN
69+
var company = new Company(new Manager(40), new Employee(1, new Name("John"), 40));
70+
Function<Company, Manager> manager = containerName -> company.manager();
71+
Function<Company, Employee> employee = containerParentName -> company.employee();
72+
// WHEN
73+
AbstractListAssert<?, List<? extends Employee>, Employee, ObjectAssert<Employee>> result = assertThat(company).extracting(manager,
74+
employee);
75+
// THEN
76+
result.hasSize(2)
77+
.allSatisfy(e -> assertThat(e.getAge()).isGreaterThan(30));
78+
}
79+
80+
@Test
81+
void should_allow_extracting_values_using_multiple_lambda_extractors_with_type() {
82+
// GIVEN
83+
Function<Employee, String> lastName = employee -> employee.getName().getLast();
84+
// WHEN
85+
AbstractListAssert<?, List<? extends String>, String, ObjectAssert<String>> result = assertThat(luke).extracting(firstName,
86+
lastName);
5487
// THEN
5588
result.hasSize(2)
5689
.containsExactly("Luke", "Skywalker");
@@ -96,16 +129,18 @@ void extracting_should_keep_assertion_state() {
96129
ObjectAssert<Employee> assertion = assertThat(luke).as("test description")
97130
.withFailMessage("error message")
98131
.withRepresentation(UNICODE_REPRESENTATION)
99-
.usingComparator(ALWAYS_EQUALS)
100-
.usingComparatorForFields(ALWAYS_EQUALS_STRING, "foo")
101-
.usingComparatorForType(ALWAYS_EQUALS_STRING, String.class);
132+
.usingComparator(AlwaysEqualComparator.ALWAYS_EQUALS)
133+
.usingComparatorForFields(AlwaysEqualComparator.ALWAYS_EQUALS_STRING,
134+
"foo")
135+
.usingComparatorForType(AlwaysEqualComparator.ALWAYS_EQUALS_STRING,
136+
String.class);
102137
// WHEN
103138
AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> result = assertion.extracting(firstName, Employee::getName);
104139
// THEN
105140
then(result.descriptionText()).isEqualTo("test description");
106141
then(result.info.overridingErrorMessage()).isEqualTo("error message");
107142
then(result.info.representation()).isEqualTo(UNICODE_REPRESENTATION);
108-
then(comparatorOf(result).getComparator()).isSameAs(ALWAYS_EQUALS);
143+
then(comparatorOf(result).getComparator()).isSameAs(AlwaysEqualComparator.ALWAYS_EQUALS);
109144
}
110145

111146
private static Objects comparatorOf(AbstractListAssert<?, ?, ?, ?> assertion) {

0 commit comments

Comments
 (0)