Skip to content

Commit

Permalink
Introduce class-level support for @RegisterExtension in Jupiter
Browse files Browse the repository at this point in the history
Issue: #497
  • Loading branch information
sbrannen committed Jan 20, 2018
1 parent f253ffb commit 179fd55
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toList;
import static org.apiguardian.api.API.Status.INTERNAL;
import static org.junit.platform.commons.util.AnnotationUtils.findAnnotatedFields;
import static org.junit.platform.commons.util.AnnotationUtils.findAnnotation;
import static org.junit.platform.commons.util.AnnotationUtils.findRepeatableAnnotations;
import static org.junit.platform.commons.util.ReflectionUtils.isStatic;
import static org.junit.platform.commons.util.ReflectionUtils.readFieldValue;

import java.lang.reflect.AnnotatedElement;
import java.util.Arrays;
Expand All @@ -32,6 +35,7 @@
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.api.function.Executable;
import org.junit.jupiter.engine.execution.ConditionEvaluator;
import org.junit.jupiter.engine.execution.JupiterEngineExecutionContext;
Expand Down Expand Up @@ -142,7 +146,22 @@ protected ExtensionRegistry populateNewExtensionRegistryFromExtendWith(Annotated
.flatMap(Arrays::stream)
.collect(toList());
// @formatter:on
return ExtensionRegistry.createRegistryFrom(existingExtensionRegistry, extensionTypes);
ExtensionRegistry newRegistry = ExtensionRegistry.createRegistryFrom(existingExtensionRegistry, extensionTypes);

if (annotatedElement instanceof Class) {
Class<?> clazz = (Class<?>) annotatedElement;
// @formatter:off
findAnnotatedFields(clazz, RegisterExtension.class, field -> isStatic(field)).stream()
.map(field -> readFieldValue(clazz, field.getName(), null))
.filter(Optional::isPresent)
.map(Optional::get)
.filter(Extension.class::isInstance)
.map(Extension.class::cast)
.forEach(ext -> newRegistry.registerExtension(ext, clazz));
// @formatter:on
}

return newRegistry;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,21 @@ void instanceLevel() {
assertOneTestSucceeded(InstanceLevelExtensionRegistrationTestCase.class);
}

@Disabled("Disabled until feature is completed")
@Test
void classLevel() {
assertOneTestSucceeded(ClassLevelExtensionRegistrationTestCase.class);
}

@Test
void classLevelFromSuperclass() {
assertOneTestSucceeded(SubClassLevelExtensionRegistrationTestCase.class);
}

@Test
void classLevelFromInterface() {
assertOneTestSucceeded(ExtensionRegistrationFromInterfaceTestCase.class);
}

private void assertOneTestSucceeded(Class<?> testClass) {
ExecutionEventRecorder eventRecorder = executeTestsForClass(testClass);
assertAll(//
Expand Down Expand Up @@ -120,6 +129,52 @@ static void afterAll(String wisdom) {

}

static class SubClassLevelExtensionRegistrationTestCase extends ClassLevelExtensionRegistrationTestCase {

@Test
@Override
void test(String wisdom) {
assertWisdom(crystalBall, wisdom, "Overridden @Test");
}

}

interface ClassLevelExtensionRegistrationInterface {

@RegisterExtension
static final CrystalBall crystalBall = new CrystalBall("Outlook good");

@BeforeAll
static void beforeAll(String wisdom) {
assertWisdom(crystalBall, wisdom, "@BeforeAll");
}

@BeforeEach
default void beforeEach(String wisdom) {
assertWisdom(crystalBall, wisdom, "@BeforeEach");
}

@AfterEach
default void afterEach(String wisdom) {
assertWisdom(crystalBall, wisdom, "@AfterEach");
}

@AfterAll
static void afterAll(String wisdom) {
assertWisdom(crystalBall, wisdom, "@AfterAll");
}

}

static class ExtensionRegistrationFromInterfaceTestCase implements ClassLevelExtensionRegistrationInterface {

@Test
void test(String wisdom) {
assertWisdom(crystalBall, wisdom, "@Test");
}

}

private static class CrystalBall implements ParameterResolver {

private final String wisdom;
Expand Down

0 comments on commit 179fd55

Please sign in to comment.