Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -912,18 +912,18 @@ public AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> extracting(S
*/
@CheckReturnValue
@SafeVarargs
public final AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> extracting(Function<? super ACTUAL, ?>... extractors) {
public final <T> AbstractListAssert<?, List<? extends T>, T, ObjectAssert<T>> extracting(Function<? super ACTUAL, ? extends T>... extractors) {
return extractingForProxy(extractors);
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,26 @@
*
* Copyright 2012-2024 the original author or authors.
*/
package org.assertj.core.api.object;
package org.assertj.tests.core.api.object;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.assertj.core.api.BDDAssertions.then;
import static org.assertj.core.error.ShouldNotBeNull.shouldNotBeNull;
import static org.assertj.core.presentation.UnicodeRepresentation.UNICODE_REPRESENTATION;
import static org.assertj.core.testkit.AlwaysEqualComparator.ALWAYS_EQUALS;
import static org.assertj.core.testkit.AlwaysEqualComparator.ALWAYS_EQUALS_STRING;

import java.util.List;
import java.util.function.Function;

import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractListAssert;
import org.assertj.core.api.NavigationMethodBaseTest;
import org.assertj.core.api.ObjectAssert;
import org.assertj.core.internal.Objects;
import org.assertj.core.testkit.Employee;
import org.assertj.core.testkit.Name;
import org.assertj.core.util.introspection.PropertyOrFieldSupport;
import org.assertj.tests.core.testkit.AlwaysEqualComparator;
import org.assertj.tests.core.testkit.Employee;
import org.assertj.tests.core.testkit.Name;
import org.assertj.tests.core.testkit.NavigationMethodBaseTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand All @@ -50,7 +49,41 @@ void should_allow_extracting_values_using_multiple_lambda_extractors() {
// GIVEN
Function<Employee, Object> lastName = employee -> employee.getName().getLast();
// WHEN
AbstractListAssert<?, ?, Object, ?> result = assertThat(luke).extracting(firstName, lastName);
AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> result = assertThat(luke).extracting(firstName, lastName);
// THEN
result.hasSize(2)
.containsExactly("Luke", "Skywalker");
}

static class Manager extends Employee {
public Manager(int age) {
this.setAge(age);
}
}
record Company(Manager manager, Employee employee) {
}

@Test
void should_allow_extracting_values_using_multiple_lambda_extractors_with_common_ancestor() {
// GIVEN
var company = new Company(new Manager(40), new Employee(1, new Name("John"), 40));
Function<Company, Manager> manager = containerName -> company.manager();
Function<Company, Employee> employee = containerParentName -> company.employee();
// WHEN
AbstractListAssert<?, List<? extends Employee>, Employee, ObjectAssert<Employee>> result = assertThat(company).extracting(manager,
employee);
// THEN
result.hasSize(2)
.allSatisfy(e -> assertThat(e.getAge()).isGreaterThan(30));
}

@Test
void should_allow_extracting_values_using_multiple_lambda_extractors_with_type() {
// GIVEN
Function<Employee, String> lastName = employee -> employee.getName().getLast();
// WHEN
AbstractListAssert<?, List<? extends String>, String, ObjectAssert<String>> result = assertThat(luke).extracting(firstName,
lastName);
// THEN
result.hasSize(2)
.containsExactly("Luke", "Skywalker");
Expand Down Expand Up @@ -96,16 +129,18 @@ void extracting_should_keep_assertion_state() {
ObjectAssert<Employee> assertion = assertThat(luke).as("test description")
.withFailMessage("error message")
.withRepresentation(UNICODE_REPRESENTATION)
.usingComparator(ALWAYS_EQUALS)
.usingComparatorForFields(ALWAYS_EQUALS_STRING, "foo")
.usingComparatorForType(ALWAYS_EQUALS_STRING, String.class);
.usingComparator(AlwaysEqualComparator.ALWAYS_EQUALS)
.usingComparatorForFields(AlwaysEqualComparator.ALWAYS_EQUALS_STRING,
"foo")
.usingComparatorForType(AlwaysEqualComparator.ALWAYS_EQUALS_STRING,
String.class);
// WHEN
AbstractListAssert<?, List<?>, Object, ObjectAssert<Object>> result = assertion.extracting(firstName, Employee::getName);
// THEN
then(result.descriptionText()).isEqualTo("test description");
then(result.info.overridingErrorMessage()).isEqualTo("error message");
then(result.info.representation()).isEqualTo(UNICODE_REPRESENTATION);
then(comparatorOf(result).getComparator()).isSameAs(ALWAYS_EQUALS);
then(comparatorOf(result).getComparator()).isSameAs(AlwaysEqualComparator.ALWAYS_EQUALS);
}

private static Objects comparatorOf(AbstractListAssert<?, ?, ?, ?> assertion) {
Expand Down
Loading