/* * Copyright 2015-2017 the original author or authors. * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html */ package org.junit.jupiter.engine.descriptor; import static org.junit.platform.commons.meta.API.Usage.Internal; import java.lang.reflect.Constructor; import java.util.Optional; import java.util.Set; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.engine.execution.ExecutableInvoker; import org.junit.jupiter.engine.execution.JupiterEngineExecutionContext; import org.junit.jupiter.engine.execution.TestInstanceProvider; import org.junit.jupiter.engine.extension.ExtensionRegistry; import org.junit.platform.commons.meta.API; import org.junit.platform.commons.util.ReflectionUtils; import org.junit.platform.engine.TestDescriptor; import org.junit.platform.engine.TestTag; import org.junit.platform.engine.UniqueId; /** * {@link TestDescriptor} for tests based on nested (but not static) Java classes. * * <h3>Default Display Names</h3> * * <p>The default display name for a non-static nested test class is the simple * name of the class. * * @since 5.0 */ @API(Internal) public class NestedClassTestDescriptor extends ClassTestDescriptor { private static final ExecutableInvoker executableInvoker = new ExecutableInvoker(); public NestedClassTestDescriptor(UniqueId uniqueId, Class<?> testClass) { super(uniqueId, Class::getSimpleName, testClass); } // --- TestDescriptor ------------------------------------------------------ @Override public final Set<TestTag> getTags() { Set<TestTag> localTags = super.getTags(); getParent().ifPresent(parentDescriptor -> localTags.addAll(parentDescriptor.getTags())); return localTags; } // --- Node ---------------------------------------------------------------- @Override protected TestInstanceProvider testInstanceProvider(JupiterEngineExecutionContext parentExecutionContext, ExtensionRegistry registry, ExtensionContext extensionContext) { return childExtensionRegistry -> { // Extensions registered for nested classes and below are not to be used for instancing outer classes Optional<ExtensionRegistry> childExtensionRegistryForOuterInstance = Optional.empty(); Object outerInstance = parentExecutionContext.getTestInstanceProvider().getTestInstance( childExtensionRegistryForOuterInstance); Constructor<?> constructor = ReflectionUtils.getDeclaredConstructor(getTestClass()); Object instance = executableInvoker.invoke(constructor, outerInstance, extensionContext, childExtensionRegistry.orElse(registry)); invokeTestInstancePostProcessors(instance, childExtensionRegistry.orElse(registry), extensionContext); return instance; }; } }