package org.apache.maven.surefire.junitplatform;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import static java.util.Collections.emptyList;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static org.fest.assertions.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.platform.engine.TestDescriptor.Type.CONTAINER;
import static org.junit.platform.engine.TestDescriptor.Type.TEST;
import static org.junit.platform.engine.TestExecutionResult.aborted;
import static org.junit.platform.engine.TestExecutionResult.failed;
import static org.junit.platform.engine.TestExecutionResult.successful;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.powermock.reflect.Whitebox.getInternalState;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Optional;

import org.apache.maven.surefire.report.PojoStackTraceWriter;
import org.apache.maven.surefire.report.ReportEntry;
import org.apache.maven.surefire.report.RunListener;
import org.apache.maven.surefire.report.SimpleReportEntry;
import org.apache.maven.surefire.report.StackTraceWriter;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.engine.descriptor.ClassTestDescriptor;
import org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor;
import org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor;
import org.junit.platform.engine.ConfigurationParameters;
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.TestSource;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.engine.support.descriptor.AbstractTestDescriptor;
import org.junit.platform.engine.support.descriptor.ClassSource;
import org.junit.platform.engine.support.descriptor.EngineDescriptor;
import org.junit.platform.engine.support.descriptor.MethodSource;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.opentest4j.TestSkippedException;

/**
 * Unit tests for {@link RunListenerAdapter}.
 *
 * @since 2.22.0
 */
public class RunListenerAdapterTest
{
    private static final ConfigurationParameters CONFIG_PARAMS = mock( ConfigurationParameters.class );

    private RunListener listener;

    private RunListenerAdapter adapter;

    @Before
    public void setUp()
    {
        listener = mock( RunListener.class );
        adapter = new RunListenerAdapter( listener );
        adapter.testPlanExecutionStarted( TestPlan.from( emptyList() ) );
    }

    @Test
    public void notifiedWithCorrectNamesWhenMethodExecutionStarted()
                    throws Exception
    {
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );

        TestPlan testPlan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Luke's Plan" ) ) );
        adapter.testPlanExecutionStarted( testPlan );

        TestIdentifier methodIdentifier =
                identifiersAsParentOnTestPlan( testPlan, newClassDescriptor(), newMethodDescriptor() );

        adapter.executionStarted( methodIdentifier );
        verify( listener ).testStarting( entryCaptor.capture() );

        ReportEntry entry = entryCaptor.getValue();
        assertEquals( MY_TEST_METHOD_NAME, entry.getName() );
        assertEquals( MyTestClass.class.getName(), entry.getSourceName() );
        assertNull( entry.getStackTraceWriter() );
    }

    @Test
    public void notifiedWithCompatibleNameForMethodWithArguments()
                    throws Exception
    {
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );

        TestPlan testPlan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Luke's Plan" ) ) );
        adapter.testPlanExecutionStarted( testPlan );

        TestIdentifier methodIdentifier = identifiersAsParentOnTestPlan( testPlan, newClassDescriptor(),
                newMethodDescriptor( String.class ) );

        adapter.executionStarted( methodIdentifier );
        verify( listener ).testStarting( entryCaptor.capture() );

        ReportEntry entry = entryCaptor.getValue();
        assertEquals( MY_TEST_METHOD_NAME + "(String)", entry.getName() );
        assertNull( entry.getNameText() );
        assertEquals( MyTestClass.class.getName(), entry.getSourceName() );
        assertNull( entry.getSourceText() );
        assertNull( entry.getStackTraceWriter() );
    }

    @Test
    public void notifiedEagerlyForTestSetWhenClassExecutionStarted()
                    throws Exception
    {
        EngineDescriptor engine = newEngineDescriptor();
        TestDescriptor parent = newClassDescriptor();
        engine.addChild( parent );
        TestDescriptor child = newMethodDescriptor();
        parent.addChild( child );
        TestPlan plan = TestPlan.from( singletonList( engine ) );

        String className = MyTestClass.class.getName();

        adapter.testPlanExecutionStarted( plan );
        adapter.executionStarted( TestIdentifier.from( engine ) );
        adapter.executionStarted( TestIdentifier.from( parent ) );
        verify( listener )
                .testSetStarting( new SimpleReportEntry( className, null, null, null ) );
        verifyNoMoreInteractions( listener );

        adapter.executionStarted( TestIdentifier.from( child ) );
        verify( listener )
                .testStarting( new SimpleReportEntry( className, null, MY_TEST_METHOD_NAME, null ) );
        verifyNoMoreInteractions( listener );

        adapter.executionFinished( TestIdentifier.from( child ), successful() );
        ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        verify( listener ).testSucceeded( report.capture() );
        assertThat( report.getValue().getSourceName() )
                .isEqualTo( className );
        assertThat( report.getValue().getSourceText() )
                .isNull();
        assertThat( report.getValue().getName() )
                .isEqualTo( MY_TEST_METHOD_NAME );
        assertThat( report.getValue().getNameText() )
                .isNull();
        assertThat( report.getValue().getElapsed() )
                .isNotNull();
        assertThat( report.getValue().getSystemProperties() )
                .isEmpty();
        verifyNoMoreInteractions( listener );

        adapter.executionFinished( TestIdentifier.from( parent ), successful() );
        report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        verify( listener ).testSetCompleted( report.capture() );
        assertThat( report.getValue().getSourceName() )
                .isEqualTo( className );
        assertThat( report.getValue().getName() )
                .isNull();
        assertThat( report.getValue().getElapsed() )
                .isNotNull();
        assertThat( report.getValue().getSystemProperties() )
                .isNotEmpty();
        verifyNoMoreInteractions( listener );

        adapter.executionFinished( TestIdentifier.from( engine ), successful() );
        verifyNoMoreInteractions( listener );
    }

    @Test
    public void displayNamesInClassAndMethods()
            throws Exception
    {
        EngineDescriptor engine = newEngineDescriptor();
        TestDescriptor parent = newClassDescriptor( "parent" );
        engine.addChild( parent );

        UniqueId id1 = parent.getUniqueId().append( MyTestClass.class.getName(), MY_NAMED_TEST_METHOD_NAME );
        Method m1 = MyTestClass.class.getDeclaredMethod( MY_NAMED_TEST_METHOD_NAME );
        TestDescriptor child1 = new TestMethodTestDescriptorWithDisplayName( id1, MyTestClass.class, m1, "dn1" );
        parent.addChild( child1 );

        UniqueId id2 = parent.getUniqueId().append( MyTestClass.class.getName(), MY_TEST_METHOD_NAME );
        Method m2 = MyTestClass.class.getDeclaredMethod( MY_TEST_METHOD_NAME, String.class );
        TestDescriptor child2 = new TestMethodTestDescriptor( id2, MyTestClass.class, m2 );
        parent.addChild( child2 );

        TestPlan plan = TestPlan.from( singletonList( engine ) );

        InOrder inOrder = inOrder( listener );

        adapter.testPlanExecutionStarted( plan );

        adapter.executionStarted( TestIdentifier.from( engine ) );
        adapter.executionStarted( TestIdentifier.from( parent ) );
        ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        inOrder.verify( listener ).testSetStarting( report.capture() );
        assertThat( report.getValue().getSourceName() )
                .isEqualTo( MyTestClass.class.getName() );
        assertThat( report.getValue().getSourceText() )
                .isEqualTo( "parent" );
        assertThat( report.getValue().getName() )
                .isNull();
        assertThat( report.getValue().getSystemProperties() )
                .isEmpty();
        verifyZeroInteractions( listener );

        adapter.executionStarted( TestIdentifier.from( child1 ) );
        inOrder.verify( listener )
                .testStarting( new SimpleReportEntry( MyTestClass.class.getName(), "parent",
                        MY_NAMED_TEST_METHOD_NAME, "dn1" ) );
        inOrder.verifyNoMoreInteractions();

        adapter.executionFinished( TestIdentifier.from( child1 ), successful() );
        report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        inOrder.verify( listener ).testSucceeded( report.capture() );
        assertThat( report.getValue().getSourceName() )
                .isEqualTo( MyTestClass.class.getName() );
        assertThat( report.getValue().getSourceText() )
                .isEqualTo( "parent" );
        assertThat( report.getValue().getName() )
                .isEqualTo( MY_NAMED_TEST_METHOD_NAME );
        assertThat( report.getValue().getNameText() )
                .isEqualTo( "dn1" );
        assertThat( report.getValue().getElapsed() )
                .isNotNull();
        assertThat( report.getValue().getSystemProperties() )
                .isEmpty();
        inOrder.verifyNoMoreInteractions();

        adapter.executionStarted( TestIdentifier.from( child2 ) );
        inOrder.verify( listener )
                .testStarting( new SimpleReportEntry( MyTestClass.class.getName(), "parent",
                        MY_TEST_METHOD_NAME + "(String)", null ) );
        inOrder.verifyNoMoreInteractions();

        Exception assumptionFailure = new Exception();
        adapter.executionFinished( TestIdentifier.from( child2 ), aborted( assumptionFailure ) );
        report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        inOrder.verify( listener ).testAssumptionFailure( report.capture() );
        assertThat( report.getValue().getSourceName() )
                .isEqualTo( MyTestClass.class.getName() );
        assertThat( report.getValue().getSourceText() )
                .isEqualTo( "parent" );
        assertThat( report.getValue().getName() )
                .isEqualTo( MY_TEST_METHOD_NAME + "(String)" );
        assertThat( report.getValue().getNameText() )
                .isNull();
        assertThat( report.getValue().getElapsed() )
                .isNotNull();
        assertThat( report.getValue().getSystemProperties() )
                .isEmpty();
        assertThat( report.getValue().getStackTraceWriter() )
                .isNotNull();
        assertThat( report.getValue().getStackTraceWriter().getThrowable().getTarget() )
                .isSameAs( assumptionFailure );
        inOrder.verifyNoMoreInteractions();

        adapter.executionFinished( TestIdentifier.from( parent ), successful() );
        inOrder.verify( listener ).testSetCompleted( report.capture() );
        assertThat( report.getValue().getSourceName() )
                .isEqualTo( MyTestClass.class.getName() );
        assertThat( report.getValue().getSourceText() )
                .isEqualTo( "parent" );
        assertThat( report.getValue().getName() )
                .isNull();
        assertThat( report.getValue().getNameText() )
                .isNull();
        assertThat( report.getValue().getElapsed() )
                .isNotNull();
        assertThat( report.getValue().getSystemProperties() )
                .isNotEmpty();
        assertThat( report.getValue().getStackTraceWriter() )
                .isNull();
        inOrder.verifyNoMoreInteractions();

        adapter.executionFinished( TestIdentifier.from( engine ), successful() );
        inOrder.verifyNoMoreInteractions();
    }

    @Test
    public void notifiedForUnclassifiedTestIdentifier()
    {
        EngineDescriptor engine = new EngineDescriptor( UniqueId.forEngine( "engine" ), "engine" )
        {
            @Override
            public Type getType()
            {
                return TEST;
            }
        };
        TestPlan plan = TestPlan.from( singletonList( engine ) );

        adapter.testPlanExecutionStarted( plan );
        assertThat( (TestPlan) getInternalState( adapter, "testPlan" ) )
                .isSameAs( plan );
        assertThat( (Map) getInternalState( adapter, "testStartTime" ) )
                .isEmpty();


        adapter.executionStarted( TestIdentifier.from( engine ) );
        verify( listener )
                .testStarting( new SimpleReportEntry( "engine", null, "engine", null ) );
        verifyNoMoreInteractions( listener );

        adapter.executionFinished( TestIdentifier.from( engine ), successful() );
        ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        verify( listener ).testSucceeded( report.capture() );
        assertThat( report.getValue().getSourceName() )
                .isEqualTo( "engine" );
        assertThat( report.getValue().getSourceText() )
                .isNull();
        assertThat( report.getValue().getName() )
                .isEqualTo( "engine" );
        assertThat( report.getValue().getNameText() )
                .isNull();
        assertThat( report.getValue().getElapsed() )
                .isNotNull();
        assertThat( report.getValue().getStackTraceWriter() )
                .isNull();
        assertThat( report.getValue().getSystemProperties() )
                .isEmpty();

        adapter.testPlanExecutionFinished( plan );
        assertThat( (TestPlan) getInternalState( adapter, "testPlan" ) )
                .isNull();
        assertThat( (Map) getInternalState( adapter, "testStartTime" ) )
                .isEmpty();

        verifyNoMoreInteractions( listener );
    }

    @Test
    public void notNotifiedWhenEngineExecutionStarted()
    {
        adapter.executionStarted( newEngineIdentifier() );
        verify( listener, never() ).testStarting( any() );
    }

    @Test
    public void notifiedWhenMethodExecutionSkipped()
                    throws Exception
    {
        adapter.executionSkipped( newMethodIdentifier(), "test" );
        verify( listener ).testSkipped( any() );
    }

    @Test
    public void notifiedWithCorrectNamesWhenClassExecutionSkipped()
    {
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        TestPlan testPlan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Luke's Plan" ) ) );
        adapter.testPlanExecutionStarted( testPlan );

        TestIdentifier classIdentifier =
                        identifiersAsParentOnTestPlan( testPlan, newEngineDescriptor(), newClassDescriptor() );

        adapter.executionSkipped( classIdentifier, "test" );
        verify( listener ).testSkipped( entryCaptor.capture() );

        ReportEntry entry = entryCaptor.getValue();
        assertNull( entry.getName() );
        assertEquals( MyTestClass.class.getTypeName(), entry.getSourceName() );
    }

    @Test
    public void notifiedWhenEngineExecutionSkipped()
    {
        adapter.executionSkipped( newEngineIdentifier(), "test" );
        verify( listener ).testSkipped( any() );
    }

    @Test
    public void notifiedWhenMethodExecutionAborted()
                    throws Exception
    {
        adapter.executionFinished( newMethodIdentifier(), aborted( null ) );
        verify( listener ).testAssumptionFailure( any() );
    }

    @Test
    public void notifiedWhenClassExecutionAborted()
    {
        TestSkippedException t = new TestSkippedException( "skipped" );
        adapter.executionFinished( newClassIdentifier(), aborted( t ) );
        String source = MyTestClass.class.getName();
        StackTraceWriter stw = new PojoStackTraceWriter( source, null, t );
        ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        verify( listener ).testSetCompleted( report.capture() );
        assertThat( report.getValue().getSourceName() )
                .isEqualTo( source );
        assertThat( report.getValue().getStackTraceWriter() )
                .isEqualTo( stw );
    }

    @Test
    public void notifiedOfContainerFailureWhenErrored()
                    throws Exception
    {
        adapter.executionFinished( newContainerIdentifier(), failed( new RuntimeException() ) );
        verify( listener ).testError( any() );
    }

    @Test
    public void notifiedOfContainerFailureWhenFailed()
                    throws Exception
    {
        adapter.executionFinished( newContainerIdentifier(), failed( new AssertionError() ) );
        verify( listener ).testFailed( any() );
    }

    @Test
    public void notifiedWhenMethodExecutionFailed()
                    throws Exception
    {
        adapter.executionFinished( newMethodIdentifier(), failed( new AssertionError() ) );
        verify( listener ).testFailed( any() );
    }

    @Test
    public void notifiedWhenMethodExecutionFailedWithError()
                    throws Exception
    {
        adapter.executionFinished( newMethodIdentifier(), failed( new RuntimeException() ) );
        verify( listener ).testError( any() );
    }

    @Test
    public void notifiedWithCorrectNamesWhenClassExecutionFailed()
    {
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        TestPlan testPlan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Luke's Plan" ) ) );
        adapter.testPlanExecutionStarted( testPlan );

        adapter.executionFinished( identifiersAsParentOnTestPlan( testPlan, newClassDescriptor() ),
                failed( new AssertionError() ) );
        verify( listener ).testFailed( entryCaptor.capture() );

        ReportEntry entry = entryCaptor.getValue();
        assertEquals( MyTestClass.class.getTypeName(), entry.getSourceName() );
        assertNull( entry.getName() );
        assertNotNull( entry.getStackTraceWriter() );
        assertNotNull( entry.getStackTraceWriter().getThrowable() );
        assertThat( entry.getStackTraceWriter().getThrowable().getTarget() )
                .isInstanceOf( AssertionError.class );
    }

    @Test
    public void notifiedWithCorrectNamesWhenClassExecutionErrored()
    {
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        TestPlan testPlan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Luke's Plan" ) ) );
        adapter.testPlanExecutionStarted( testPlan );

        adapter.executionFinished( identifiersAsParentOnTestPlan( testPlan, newClassDescriptor() ),
                failed( new RuntimeException() ) );
        verify( listener ).testError( entryCaptor.capture() );

        ReportEntry entry = entryCaptor.getValue();
        assertEquals( MyTestClass.class.getTypeName(), entry.getSourceName() );
        assertNull( entry.getName() );
        assertNotNull( entry.getStackTraceWriter() );
        assertNotNull( entry.getStackTraceWriter().getThrowable() );
        assertThat( entry.getStackTraceWriter().getThrowable().getTarget() )
                .isInstanceOf( RuntimeException.class );
    }

    @Test
    public void notifiedWithCorrectNamesWhenContainerFailed()
                    throws Exception
    {
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        TestPlan testPlan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Luke's Plan" ) ) );
        adapter.testPlanExecutionStarted( testPlan );

        adapter.executionFinished( newContainerIdentifier(), failed( new RuntimeException() ) );
        verify( listener ).testError( entryCaptor.capture() );

        ReportEntry entry = entryCaptor.getValue();
        assertEquals( MyTestClass.class.getTypeName(), entry.getSourceName() );
        assertEquals( MY_TEST_METHOD_NAME, entry.getName() );
        assertNotNull( entry.getStackTraceWriter() );
        assertNotNull( entry.getStackTraceWriter().getThrowable() );
        assertThat( entry.getStackTraceWriter().getThrowable().getTarget() )
                .isInstanceOf( RuntimeException.class );
    }

    @Test
    public void notifiedWhenMethodExecutionSucceeded()
                    throws Exception
    {
        adapter.executionFinished( newMethodIdentifier(), successful() );
        verify( listener ).testSucceeded( any() );
    }

    @Test
    public void notifiedForTestSetWhenClassExecutionSucceeded()
    {
        EngineDescriptor engineDescriptor = newEngineDescriptor();
        TestDescriptor classDescriptor = newClassDescriptor();
        engineDescriptor.addChild( classDescriptor );
        adapter.testPlanExecutionStarted( TestPlan.from( singleton( engineDescriptor ) ) );
        adapter.executionStarted( TestIdentifier.from( classDescriptor ) );

        adapter.executionFinished( TestIdentifier.from( classDescriptor ), successful() );

        String className = MyTestClass.class.getName();

        verify( listener )
                .testSetStarting( new SimpleReportEntry( className, null, null, null ) );

        ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        verify( listener )
                .testSetCompleted( report.capture() );

        assertThat( report.getValue().getSourceName() )
                .isEqualTo( className );
        assertThat( report.getValue().getSourceText() )
                .isNull();
        assertThat( report.getValue().getName() )
                .isNull();
        assertThat( report.getValue().getNameText() )
                .isNull();
        assertThat( report.getValue().getStackTraceWriter() )
                .isNull();
        assertThat( report.getValue().getElapsed() )
                .isNotNull();
        assertThat( report.getValue().getSystemProperties() )
                .isNotEmpty();

        verify( listener, never() )
                .testSucceeded( any() );

        verifyNoMoreInteractions( listener );
    }

    @Test
    public void notifiedWithParentDisplayNameWhenTestClassUnknown()
    {
        // Set up a test plan
        TestPlan plan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Luke's Plan" ) ) );
        adapter.testPlanExecutionStarted( plan );

        // Use the test plan to set up child with parent.
        final String parentDisplay = "I am your father";
        TestIdentifier child = newSourcelessChildIdentifierWithParent( plan, parentDisplay, null );
        adapter.executionStarted( child );

        // Check that the adapter has informed Surefire that the test has been invoked,
        // with the parent name as source (since the test case itself had no source).
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        verify( listener ).testStarting( entryCaptor.capture() );
        assertEquals( parentDisplay, entryCaptor.getValue().getSourceName() );
        assertNull( entryCaptor.getValue().getSourceText() );
        assertNull( entryCaptor.getValue().getName() );
        assertNull( entryCaptor.getValue().getNameText() );
    }

    @Test
    public void stackTraceWriterPresentWhenParentHasSource()
    {
        TestPlan plan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Some Plan" ) ) );
        adapter.testPlanExecutionStarted( plan );

        TestIdentifier child =
                newSourcelessChildIdentifierWithParent( plan, "Parent", ClassSource.from( MyTestClass.class ) );
        adapter.executionFinished( child, failed( new RuntimeException() ) );
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        verify( listener ).testError( entryCaptor.capture() );
        assertNotNull( entryCaptor.getValue().getStackTraceWriter() );
    }

    @Test
    public void stackTraceWriterDefaultsToTestClass()
    {
        TestPlan plan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Some Plan" ) ) );
        adapter.testPlanExecutionStarted( plan );

        TestIdentifier child = newSourcelessChildIdentifierWithParent( plan, "Parent", null );
        adapter.executionFinished( child, failed( new RuntimeException( "message" ) ) );
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        verify( listener ).testError( entryCaptor.capture() );
        assertNotNull( entryCaptor.getValue().getStackTraceWriter() );
        assertNotNull( entryCaptor.getValue().getStackTraceWriter().smartTrimmedStackTrace() );
        assertNotNull( entryCaptor.getValue().getStackTraceWriter().writeTraceToString() );
        assertNotNull( entryCaptor.getValue().getStackTraceWriter().writeTrimmedTraceToString() );
    }

    @Test
    public void stackTraceWriterPresentEvenWithoutException()
                    throws Exception
    {
        adapter.executionFinished( newMethodIdentifier(), failed( null ) );
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        verify( listener ).testError( entryCaptor.capture() );
        assertNotNull( entryCaptor.getValue().getStackTraceWriter() );
    }

    @Test
    public void displayNamesIgnoredInReport()
                    throws NoSuchMethodException
    {
        TestMethodTestDescriptorWithDisplayName descriptor = new TestMethodTestDescriptorWithDisplayName( newId(),
                MyTestClass.class, MyTestClass.class.getDeclaredMethod( "myNamedTestMethod" ), "some display name" );

        TestIdentifier factoryIdentifier = TestIdentifier.from( descriptor );
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );

        adapter.executionSkipped( factoryIdentifier, "" );
        verify( listener ).testSkipped( entryCaptor.capture() );

        ReportEntry value = entryCaptor.getValue();

        assertEquals( MyTestClass.class.getName(), value.getSourceName() );
        assertNull( value.getSourceText() );
        assertEquals( "myNamedTestMethod", value.getName() );
        assertEquals( "some display name", value.getNameText() );
    }

    private static TestIdentifier newMethodIdentifier()
                    throws Exception
    {
        return TestIdentifier.from( newMethodDescriptor() );
    }

    private static TestDescriptor newMethodDescriptor( Class<?>... parameterTypes )
                    throws Exception
    {
        return new TestMethodTestDescriptor(
                        UniqueId.forEngine( "method" ),
                        MyTestClass.class,
                        MyTestClass.class.getDeclaredMethod( MY_TEST_METHOD_NAME, parameterTypes ) );
    }

    private static TestIdentifier newClassIdentifier()
    {
        return TestIdentifier.from( newClassDescriptor() );
    }

    private static TestDescriptor newClassDescriptor( String displayName )
    {
        return new ClassTestDescriptor( UniqueId.root( "class", MyTestClass.class.getName() ),
                c -> displayName, MyTestClass.class, CONFIG_PARAMS )
                  { };
    }

    private static TestDescriptor newClassDescriptor()
    {
        return new ClassTestDescriptor( UniqueId.root( "class", MyTestClass.class.getName() ),
                MyTestClass.class, CONFIG_PARAMS );
    }

    private static TestIdentifier newSourcelessChildIdentifierWithParent(
                    TestPlan testPlan, String parentDisplay, TestSource parentTestSource )
    {
        // A parent test identifier with a name.
        TestDescriptor parent = mock( TestDescriptor.class );
        when( parent.getUniqueId() ).thenReturn( newId() );
        when( parent.getDisplayName() ).thenReturn( parentDisplay );
        when( parent.getLegacyReportingName() ).thenReturn( parentDisplay );
        when( parent.getSource() ).thenReturn( Optional.ofNullable( parentTestSource ) );
        when( parent.getType() ).thenReturn( CONTAINER );
        TestIdentifier parentId = TestIdentifier.from( parent );

        // The (child) test case that is to be executed as part of a test plan.
        TestDescriptor child = mock( TestDescriptor.class );
        when( child.getUniqueId() ).thenReturn( newId() );
        when( child.getType() ).thenReturn( TEST );
        when( child.getLegacyReportingName() ).thenReturn( "child" );

        // Ensure the child source is null yet that there is a parent -- the special case to be tested.
        when( child.getSource() ).thenReturn( Optional.empty() );
        when( child.getParent() ).thenReturn( Optional.of( parent ) );
        TestIdentifier childId = TestIdentifier.from( child );

        testPlan.add( childId );
        testPlan.add( parentId );

        return childId;
    }

    private static TestIdentifier newContainerIdentifier()
        throws Exception
    {
        return TestIdentifier.from(
                new TestTemplateTestDescriptor( UniqueId.forEngine( "method" ),
                    MyTestClass.class,
                    MyTestClass.class.getDeclaredMethod( MY_TEST_METHOD_NAME ) ) );
    }

    private static TestIdentifier newEngineIdentifier()
    {
        TestDescriptor testDescriptor = newEngineDescriptor();
        return TestIdentifier.from( testDescriptor );
    }

    private static EngineDescriptor newEngineDescriptor()
    {
        return new EngineDescriptor( UniqueId.forEngine( "engine" ), "engine" );
    }

    private static TestIdentifier identifiersAsParentOnTestPlan(
                    TestPlan plan, TestDescriptor parent, TestDescriptor child )
    {
        child.setParent( parent );

        TestIdentifier parentIdentifier = TestIdentifier.from( parent );
        TestIdentifier childIdentifier = TestIdentifier.from( child );

        plan.add( parentIdentifier );
        plan.add( childIdentifier );

        return childIdentifier;
    }

    private static TestIdentifier identifiersAsParentOnTestPlan( TestPlan plan, TestDescriptor root )
    {
        TestIdentifier rootIdentifier = TestIdentifier.from( root );
        plan.add( rootIdentifier );
        return rootIdentifier;
    }

    private static UniqueId newId()
    {
        return UniqueId.forEngine( "engine" );
    }

    private static final String MY_TEST_METHOD_NAME = "myTestMethod";
    private static final String MY_NAMED_TEST_METHOD_NAME = "myNamedTestMethod";

    private static class MyTestClass
    {
        @org.junit.jupiter.api.Test
        void myTestMethod()
        {
        }

        @org.junit.jupiter.api.Test
        void myTestMethod( String foo )
        {
        }

        @DisplayName( "name" )
        @org.junit.jupiter.api.Test
        void myNamedTestMethod()
        {
        }
    }

    static class TestMethodTestDescriptorWithDisplayName extends AbstractTestDescriptor
    {
        private TestMethodTestDescriptorWithDisplayName( UniqueId uniqueId,
                                                         Class<?> testClass, Method testMethod, String displayName )
        {
            super( uniqueId, displayName, MethodSource.from( testClass, testMethod ) );
        }

        @Override
        public Type getType()
        {
            return Type.TEST;
        }
    }
}
