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.emptyMap;
import static java.util.Collections.singletonMap;
import static java.util.stream.Collectors.toSet;
import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP;
import static org.apache.maven.surefire.api.booter.ProviderParameterNames.TESTNG_GROUPS_PROP;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.surefire.api.provider.ProviderParameters;
import org.apache.maven.surefire.api.report.ConsoleOutputReceiver;
import org.apache.maven.surefire.api.report.ReportEntry;
import org.apache.maven.surefire.api.report.ReporterFactory;
import org.apache.maven.surefire.api.report.RunListener;
import org.apache.maven.surefire.api.report.SimpleReportEntry;
import org.apache.maven.surefire.api.report.TestSetReportEntry;
import org.apache.maven.surefire.api.testset.TestListResolver;
import org.apache.maven.surefire.api.testset.TestRequest;
import org.apache.maven.surefire.api.testset.TestSetFailedException;
import org.apache.maven.surefire.api.util.RunOrderCalculator;
import org.apache.maven.surefire.api.util.ScanResult;
import org.apache.maven.surefire.api.util.TestsToRun;
import org.fest.assertions.Assertions;
import org.junit.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
import org.junit.platform.launcher.listeners.TestExecutionSummary;
import org.junit.platform.launcher.listeners.TestExecutionSummary.Failure;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;

/**
 * Unit tests for {@link JUnitPlatformProvider}.
 *
 * @since 2.22.0
 */
public class JUnitPlatformProviderTest
{
    @Test
    public void shouldFailClassOnBeforeAll()
            throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParametersMock(), launcher );
        RunListener listener = mock( RunListener.class );

        ArgumentCaptor<ReportEntry> testCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        ArgumentCaptor<TestSetReportEntry> testSetCaptor = ArgumentCaptor.forClass( TestSetReportEntry.class );

        RunListenerAdapter adapter = new RunListenerAdapter( listener );
        launcher.registerTestExecutionListeners( adapter );

        TestsToRun testsToRun = newTestsToRun( FailingBeforeAllJupiterTest.class );
        invokeProvider( provider, testsToRun );
        InOrder inOrder = inOrder( listener );
        inOrder.verify( listener, times( 1 ) ).testSetStarting( testSetCaptor.capture() );
        inOrder.verify( listener, never() ).testStarting( any( ReportEntry.class ) );
        inOrder.verify( listener, times( 1 ) ).testFailed( testCaptor.capture() );
        inOrder.verify( listener, times( 1 ) ).testSetCompleted( testSetCaptor.capture() );

        assertThat( testSetCaptor.getAllValues() )
                .hasSize( 2 );

        assertThat( testSetCaptor.getAllValues().get( 0 ).getSourceName() )
                .isEqualTo( FailingBeforeAllJupiterTest.class.getName() );

        assertThat( testSetCaptor.getAllValues().get( 0 ).getName() )
                .isNull();

        assertThat( testCaptor.getAllValues() )
                .hasSize( 1 );

        assertThat( testCaptor.getValue().getSourceName() )
                .isEqualTo( FailingBeforeAllJupiterTest.class.getName() );

        assertThat( testCaptor.getValue().getName() )
                .isNull();

        assertThat( testSetCaptor.getAllValues().get( 1 ).getSourceName() )
                .isEqualTo( FailingBeforeAllJupiterTest.class.getName() );

        assertThat( testSetCaptor.getAllValues().get( 1 ).getName() )
                .isNull();
    }

    @Test
    public void shouldErrorClassOnBeforeAll()
            throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParametersMock(), launcher );
        RunListener listener = mock( RunListener.class );

        ArgumentCaptor<ReportEntry> testCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        ArgumentCaptor<TestSetReportEntry> testSetCaptor = ArgumentCaptor.forClass( TestSetReportEntry.class );

        RunListenerAdapter adapter = new RunListenerAdapter( listener );
        launcher.registerTestExecutionListeners( adapter );

        TestsToRun testsToRun = newTestsToRun( FailingWithErrorBeforeAllJupiterTest.class );
        invokeProvider( provider, testsToRun );
        InOrder inOrder = inOrder( listener );
        inOrder.verify( listener, times( 1 ) ).testSetStarting( testSetCaptor.capture() );
        inOrder.verify( listener, never() ).testStarting( any( ReportEntry.class ) );
        inOrder.verify( listener, times( 1 ) ).testError( testCaptor.capture() );
        inOrder.verify( listener, times( 1 ) ).testSetCompleted( testSetCaptor.capture() );

        assertThat( testSetCaptor.getAllValues() )
                .hasSize( 2 );

        assertThat( testSetCaptor.getAllValues().get( 0 ).getSourceName() )
                .isEqualTo( FailingWithErrorBeforeAllJupiterTest.class.getName() );

        assertThat( testSetCaptor.getAllValues().get( 0 ).getName() )
                .isNull();

        assertThat( testCaptor.getAllValues() )
                .hasSize( 1 );

        assertThat( testCaptor.getValue().getSourceName() )
                .isEqualTo( FailingWithErrorBeforeAllJupiterTest.class.getName() );

        assertThat( testCaptor.getValue().getName() )
                .isNull();

        assertThat( testSetCaptor.getAllValues().get( 1 ).getSourceName() )
                .isEqualTo( FailingWithErrorBeforeAllJupiterTest.class.getName() );

        assertThat( testSetCaptor.getAllValues().get( 1 ).getName() )
                .isNull();
    }

    @Test
    public void getSuitesReturnsScannedClasses()
    {
        ProviderParameters providerParameters = providerParametersMock( TestClass1.class, TestClass2.class );
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );
        assertThat( provider.getSuites() )
                .containsOnly( TestClass1.class, TestClass2.class );
    }

    @Test
    public void invokeThrowsForWrongForkTestSet()
    {
        ProviderParameters providerParameters = providerParametersMock( Integer.class );
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );

        assertThrows( IllegalArgumentException.class, () -> invokeProvider( provider, "wrong forkTestSet" ) );
    }

    @Test
    public void allGivenTestsToRunAreInvoked()
                    throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParametersMock(), launcher );

        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();
        launcher.registerTestExecutionListeners( executionListener );

        TestsToRun testsToRun = newTestsToRun( TestClass1.class, TestClass2.class );
        invokeProvider( provider, testsToRun );

        assertThat( executionListener.summaries ).hasSize( 1 );
        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( TestClass1.TESTS_FOUND + TestClass2.TESTS_FOUND, summary.getTestsFoundCount() );
        assertEquals(
                        TestClass1.TESTS_STARTED + TestClass2.TESTS_STARTED, summary.getTestsStartedCount() );
        assertEquals(
                        TestClass1.TESTS_SKIPPED + TestClass2.TESTS_SKIPPED, summary.getTestsSkippedCount() );
        assertEquals(
                        TestClass1.TESTS_SUCCEEDED + TestClass2.TESTS_SUCCEEDED, summary.getTestsSucceededCount() );
        assertEquals(
                        TestClass1.TESTS_ABORTED + TestClass2.TESTS_ABORTED, summary.getTestsAbortedCount() );
        assertEquals( TestClass1.TESTS_FAILED + TestClass2.TESTS_FAILED, summary.getTestsFailedCount() );
    }

    @Test
    public void singleTestClassIsInvoked()
                    throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParametersMock(), launcher );

        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();
        launcher.registerTestExecutionListeners( executionListener );

        invokeProvider( provider, TestClass1.class );

        assertThat( executionListener.summaries ).hasSize( 1 );
        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( TestClass1.TESTS_FOUND, summary.getTestsFoundCount() );
        assertEquals( TestClass1.TESTS_STARTED, summary.getTestsStartedCount() );
        assertEquals( TestClass1.TESTS_SKIPPED, summary.getTestsSkippedCount() );
        assertEquals( TestClass1.TESTS_SUCCEEDED, summary.getTestsSucceededCount() );
        assertEquals( TestClass1.TESTS_ABORTED, summary.getTestsAbortedCount() );
        assertEquals( TestClass1.TESTS_FAILED, summary.getTestsFailedCount() );
    }

    @Test
    public void singleTestClassIsInvokedLazily()
        throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParametersMock(), launcher );

        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();
        launcher.registerTestExecutionListeners( executionListener );

        invokeProvider( provider, newTestsToRunLazily( TestClass1.class ) );

        assertThat( executionListener.summaries ).hasSize( 1 );
        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( TestClass1.TESTS_FOUND, summary.getTestsFoundCount() );
        assertEquals( TestClass1.TESTS_STARTED, summary.getTestsStartedCount() );
        assertEquals( TestClass1.TESTS_SKIPPED, summary.getTestsSkippedCount() );
        assertEquals( TestClass1.TESTS_SUCCEEDED, summary.getTestsSucceededCount() );
        assertEquals( TestClass1.TESTS_ABORTED, summary.getTestsAbortedCount() );
        assertEquals( TestClass1.TESTS_FAILED, summary.getTestsFailedCount() );
    }

    @Test
    public void failingTestCaseAfterRerun()
            throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        ProviderParameters parameters = providerParametersMock();
        // Mock the rerun variable
        when( parameters.getTestRequest().getRerunFailingTestsCount() ).thenReturn( 1 );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( parameters, launcher );

        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();
        launcher.registerTestExecutionListeners( executionListener );

        invokeProvider( provider, TestClass2.class );

        assertThat( executionListener.summaries ).hasSize( 2 );
        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( TestClass2.TESTS_FOUND, summary.getTestsFoundCount() );
        assertEquals( TestClass2.TESTS_STARTED, summary.getTestsStartedCount() );
        assertEquals( TestClass2.TESTS_SKIPPED, summary.getTestsSkippedCount() );
        assertEquals( TestClass2.TESTS_SUCCEEDED, summary.getTestsSucceededCount() );
        assertEquals( TestClass2.TESTS_ABORTED, summary.getTestsAbortedCount() );
        assertEquals( TestClass2.TESTS_FAILED, summary.getTestsFailedCount() );

        // Should only be re-running one unit test
        // - And it should only fail
        summary = executionListener.summaries.get( 1 );
        assertEquals( 1, summary.getTestsFoundCount() );
        assertEquals( 1, summary.getTestsStartedCount() );
        assertEquals( 0, summary.getTestsSkippedCount() );
        assertEquals( 0, summary.getTestsSucceededCount() );
        assertEquals( 0, summary.getTestsAbortedCount() );
        assertEquals( 1, summary.getTestsFailedCount() );
    }

    @Test
    public void rerunStillFailing()
                    throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        ProviderParameters parameters = providerParametersMock();
        // Mock the rerun variable
        when( parameters.getTestRequest().getRerunFailingTestsCount() ).thenReturn( 2 );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( parameters, launcher );
        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();
        launcher.registerTestExecutionListeners( executionListener );

        // 3 unit tests:
        // - fail always
        // - fail twice (pass on 2nd rerun)
        // - pass always
        invokeProvider( provider, TestClass4.class );

        assertThat( executionListener.summaries ).hasSize( 3 );
        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( 6, summary.getTestsFoundCount() );
        assertEquals( 5, summary.getTestsStartedCount() );
        assertEquals( 1, summary.getTestsSkippedCount() );
        assertEquals( 1, summary.getTestsSucceededCount() );
        assertEquals( 1, summary.getTestsAbortedCount() );
        assertEquals( 3, summary.getTestsFailedCount() );
        Set<String> failDisplays = new HashSet<>();
        for ( TestExecutionSummary.Failure failure : summary.getFailures() )
        {
            failDisplays.add( failure.getTestIdentifier().getDisplayName() );
        }
        assertEquals( 3, failDisplays.size() );
        assertTrue( failDisplays.contains( "Fails twice" ) );
        assertTrue( failDisplays.contains( "testAlwaysFail()" ) );
        assertTrue( failDisplays.contains( "testAlwaysError()" ) );

        // Should rerun both of the failures
        summary = executionListener.summaries.get( 1 );
        assertEquals( 3, summary.getTestsFoundCount() );
        assertEquals( 3, summary.getTestsStartedCount() );
        assertEquals( 0, summary.getTestsSkippedCount() );
        assertEquals( 0, summary.getTestsSucceededCount() );
        assertEquals( 0, summary.getTestsAbortedCount() );
        assertEquals( 3, summary.getTestsFailedCount() );
        failDisplays.clear();
        for ( TestExecutionSummary.Failure failure : summary.getFailures() )
        {
            failDisplays.add( failure.getTestIdentifier().getDisplayName() );
        }
        assertEquals( 3, failDisplays.size() );
        assertTrue( failDisplays.contains( "Fails twice" ) );
        assertTrue( failDisplays.contains( "testAlwaysFail()" ) );
        assertTrue( failDisplays.contains( "testAlwaysError()" ) );

        // now only one failure should remain
        summary = executionListener.summaries.get( 2 );
        assertEquals( 3, summary.getTestsFoundCount() );
        assertEquals( 3, summary.getTestsStartedCount() );
        assertEquals( 0, summary.getTestsSkippedCount() );
        assertEquals( 1, summary.getTestsSucceededCount() );
        assertEquals( 0, summary.getTestsAbortedCount() );
        assertEquals( 2, summary.getTestsFailedCount() );
        failDisplays.clear();
        for ( TestExecutionSummary.Failure failure : summary.getFailures() )
        {
            failDisplays.add( failure.getTestIdentifier().getDisplayName() );
        }
        assertEquals( 2, failDisplays.size() );
        assertTrue( failDisplays.contains( "testAlwaysFail()" ) );
        assertTrue( failDisplays.contains( "testAlwaysError()" ) );
    }

    @Test
    public void rerunWithSuccess()
            throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        ProviderParameters parameters = providerParametersMock();
        // Mock the rerun variable
        when( parameters.getTestRequest().getRerunFailingTestsCount() ).thenReturn( 2 );
        when( parameters.getProviderProperties() )
                .thenReturn( singletonMap( JUnitPlatformProvider.CONFIGURATION_PARAMETERS,
                        "forkCount = 1\nreuseForks = true" ) );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( parameters, launcher );
        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();
        launcher.registerTestExecutionListeners( executionListener );

        invokeProvider( provider, TestClass5.class );

        assertThat( executionListener.summaries ).hasSize( 3 );
        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( 1, summary.getTestsFoundCount() );
        assertEquals( 1, summary.getTestsStartedCount() );
        assertEquals( 0, summary.getTestsSucceededCount() );
        assertEquals( 1, summary.getTestsFailedCount() );

        summary = executionListener.summaries.get( 1 );
        assertEquals( 1, summary.getTestsFoundCount() );
        assertEquals( 1, summary.getTestsStartedCount() );
        assertEquals( 0, summary.getTestsSucceededCount() );
        assertEquals( 1, summary.getTestsFailedCount() );

        summary = executionListener.summaries.get( 2 );
        assertEquals( 1, summary.getTestsFoundCount() );
        assertEquals( 1, summary.getTestsStartedCount() );
        assertEquals( 1, summary.getTestsSucceededCount() );
        assertEquals( 0, summary.getTestsFailedCount() );
    }

    @Test
    public void runDisplayNameTest() throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        ProviderParameters parameters = providerParametersMock();
        JUnitPlatformProvider provider = new JUnitPlatformProvider( parameters, launcher );

        RunListener listener = mock( RunListener.class );
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        RunListenerAdapter adapter = new RunListenerAdapter( listener );

        launcher.registerTestExecutionListeners( adapter );

        invokeProvider( provider, DisplayNameTest.class );

        verify( listener, times( 1 ) ).testStarting( entryCaptor.capture() );
        List<ReportEntry> reportEntries = entryCaptor.getAllValues();

        assertEquals( 1, reportEntries.size() );

        assertEquals( DisplayNameTest.class.getName(), reportEntries.get( 0 ).getSourceName() );
        assertEquals( "<< ✨ >>", reportEntries.get( 0 ).getSourceText() );
        assertEquals( "test1", reportEntries.get( 0 ).getName() );
        assertEquals( "73$71 ✔", reportEntries.get( 0 ).getNameText() );
    }

    @Test
    public void detectErroredParameterized()
        throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        ProviderParameters parameters = providerParametersMock();

        JUnitPlatformProvider provider = new JUnitPlatformProvider( parameters, launcher );

        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();

        RunListener listener = mock( RunListener.class );
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        RunListenerAdapter adapter = new RunListenerAdapter( listener );

        launcher.registerTestExecutionListeners( executionListener, adapter );

        invokeProvider( provider, TestClass8.class );

        assertThat( executionListener.summaries ).hasSize( 1 );

        verify( listener, times( 1 ) ).testSetCompleted( any() );
        verify( listener, times( 1 ) ).testError( entryCaptor.capture() );
        List<ReportEntry> reportEntries = entryCaptor.getAllValues();

        assertEquals( TestClass8.class.getName(), reportEntries.get( 0 ).getSourceName() );
        assertNull( reportEntries.get( 0 ).getSourceText() );
        assertEquals( "testParameterizedTestCases", reportEntries.get( 0 ).getName() );
        assertNull( reportEntries.get( 0 ).getNameText() );

        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( 0, summary.getTestsFoundCount() );
        assertEquals( 1, summary.getContainersFailedCount() );
        assertEquals( 0, summary.getTestsStartedCount() );
        assertEquals( 0, summary.getTestsSucceededCount() );
        assertEquals( 0, summary.getTestsFailedCount() );
    }

    @Test
    public void detectFailedParameterized()
            throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        ProviderParameters parameters = providerParametersMock();

        JUnitPlatformProvider provider = new JUnitPlatformProvider( parameters, launcher );

        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();

        RunListener listener = mock( RunListener.class );
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        RunListenerAdapter adapter = new RunListenerAdapter( listener );

        launcher.registerTestExecutionListeners( executionListener, adapter );

        invokeProvider( provider, TestClass9.class );

        assertThat( executionListener.summaries ).hasSize( 1 );

        verify( listener, times( 1 ) ).testSetCompleted( any() );
        verify( listener, times( 1 ) ).testFailed( entryCaptor.capture() );
        List<ReportEntry> reportEntries = entryCaptor.getAllValues();

        assertEquals( TestClass9.class.getName(), reportEntries.get( 0 ).getSourceName() );
        assertNull( reportEntries.get( 0 ).getSourceText() );
        assertEquals( "testParameterizedTestCases", reportEntries.get( 0 ).getName() );
        assertNull( reportEntries.get( 0 ).getNameText() );

        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( 0, summary.getTestsFoundCount() );
        assertEquals( 1, summary.getContainersFailedCount() );
        assertEquals( 0, summary.getTestsStartedCount() );
        assertEquals( 0, summary.getTestsSucceededCount() );
        assertEquals( 0, summary.getTestsFailedCount() );
    }

    @Test
    public void rerunParameterized()
            throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        ProviderParameters parameters = providerParametersMock();
        // Mock the rerun variable
        when( parameters.getTestRequest().getRerunFailingTestsCount() ).thenReturn( 2 );
        when( parameters.getProviderProperties() )
                .thenReturn( singletonMap( JUnitPlatformProvider.CONFIGURATION_PARAMETERS,
                        "forkCount = 1\nreuseForks = true" ) );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( parameters, launcher );

        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();

        RunListener listener = mock( RunListener.class );
        ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class );
        RunListenerAdapter adapter = new RunListenerAdapter( listener );

        launcher.registerTestExecutionListeners( executionListener, adapter );

        invokeProvider( provider, TestClass7.class );

        assertThat( executionListener.summaries ).hasSize( 3 );

        verify( listener, times( 4 ) ).testStarting( entryCaptor.capture() );
        List<ReportEntry> reportEntries = entryCaptor.getAllValues();

        assertEquals( TestClass7.class.getName(), reportEntries.get( 0 ).getSourceName() );
        assertNull( reportEntries.get( 0 ).getSourceText() );
        assertEquals( "testParameterizedTestCases(String, boolean)[1]", reportEntries.get( 0 ).getName() );
        assertEquals( "[1] Always pass, true", reportEntries.get( 0 ).getNameText() );

        assertEquals( TestClass7.class.getName(), reportEntries.get( 1 ).getSourceName() );
        assertNull( reportEntries.get( 1 ).getSourceText() );
        assertEquals( "testParameterizedTestCases(String, boolean)[2]", reportEntries.get( 1 ).getName() );
        assertEquals( "[2] Always fail, false", reportEntries.get( 1 ).getNameText() );

        assertEquals( TestClass7.class.getName(), reportEntries.get( 2 ).getSourceName() );
        assertNull( reportEntries.get( 2 ).getSourceText() );
        assertEquals( "testParameterizedTestCases(String, boolean)[2]", reportEntries.get( 2 ).getName() );
        assertEquals( "[2] Always fail, false", reportEntries.get( 2 ).getNameText() );

        assertEquals( TestClass7.class.getName(), reportEntries.get( 3 ).getSourceName() );
        assertNull( reportEntries.get( 3 ).getSourceText() );
        assertEquals( "testParameterizedTestCases(String, boolean)[2]", reportEntries.get( 3 ).getName() );
        assertEquals( "[2] Always fail, false", reportEntries.get( 3 ).getNameText() );

        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( 2, summary.getTestsFoundCount() );
        assertEquals( 2, summary.getTestsStartedCount() );
        assertEquals( 1, summary.getTestsSucceededCount() );
        assertEquals( 1, summary.getTestsFailedCount() );

        summary = executionListener.summaries.get( 1 );
        assertEquals( 1, summary.getTestsFoundCount() );
        assertEquals( 1, summary.getTestsStartedCount() );
        assertEquals( 0, summary.getTestsSucceededCount() );
        assertEquals( 1, summary.getTestsFailedCount() );

        summary = executionListener.summaries.get( 2 );
        assertEquals( 1, summary.getTestsFoundCount() );
        assertEquals( 1, summary.getTestsStartedCount() );
        assertEquals( 0, summary.getTestsSucceededCount() );
        assertEquals( 1, summary.getTestsFailedCount() );
    }

    @Test
    public void allDiscoveredTestsAreInvokedForNullArgument()
                    throws Exception
    {
        RunListener runListener = runListenerMock();
        ProviderParameters providerParameters =
                        providerParametersMock( runListener, TestClass1.class, TestClass2.class );
        Launcher launcher = LauncherFactory.create();
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters, launcher );

        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();
        launcher.registerTestExecutionListeners( executionListener );

        invokeProvider( provider, null );

        InOrder inOrder = inOrder( runListener );

        ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        inOrder.verify( runListener )
                .testSetStarting( report.capture() );
        Assertions.assertThat( report.getValue().getSourceName() )
                .isEqualTo( TestClass1.class.getName() );
        Assertions.assertThat( report.getValue().getName() )
                .isNull();

        report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        inOrder.verify( runListener )
                .testSetCompleted( report.capture() );
        Assertions.assertThat( report.getValue().getSourceName() )
                .isEqualTo( TestClass1.class.getName() );
        Assertions.assertThat( report.getValue().getName() )
                .isNull();

        report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        inOrder.verify( runListener )
                .testSetStarting( report.capture() );
        Assertions.assertThat( report.getValue().getSourceName() )
                .isEqualTo( TestClass2.class.getName() );
        Assertions.assertThat( report.getValue().getName() )
                .isNull();

        report = ArgumentCaptor.forClass( SimpleReportEntry.class );
        inOrder.verify( runListener )
                .testSetCompleted( report.capture() );
        Assertions.assertThat( report.getValue().getSourceName() )
                .isEqualTo( TestClass2.class.getName() );
        Assertions.assertThat( report.getValue().getName() )
                .isNull();

        assertThat( executionListener.summaries ).hasSize( 1 );
        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        assertEquals( TestClass1.TESTS_FOUND + TestClass2.TESTS_FOUND, summary.getTestsFoundCount() );
        assertEquals(
                        TestClass1.TESTS_STARTED + TestClass2.TESTS_STARTED, summary.getTestsStartedCount() );
        assertEquals(
                        TestClass1.TESTS_SKIPPED + TestClass2.TESTS_SKIPPED, summary.getTestsSkippedCount() );
        assertEquals(
                        TestClass1.TESTS_SUCCEEDED + TestClass2.TESTS_SUCCEEDED, summary.getTestsSucceededCount() );
        assertEquals(
                        TestClass1.TESTS_ABORTED + TestClass2.TESTS_ABORTED, summary.getTestsAbortedCount() );
        assertEquals( TestClass1.TESTS_FAILED + TestClass2.TESTS_FAILED, summary.getTestsFailedCount() );
    }

    @Test
    public void outputIsCaptured()
                    throws Exception
    {
        Launcher launcher = LauncherFactory.create();
        RunListener runListener = runListenerMock();
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParametersMock( runListener ), launcher );

        invokeProvider( provider, VerboseTestClass.class );

        ArgumentCaptor<String> captor = ArgumentCaptor.forClass( String.class );
        verify( (ConsoleOutputReceiver) runListener )
                        .writeTestOutput( captor.capture(), eq( true ), eq( true ) );
        verify( (ConsoleOutputReceiver) runListener )
                        .writeTestOutput( captor.capture(), eq( true ), eq( false ) );
        assertThat( captor.getAllValues() )
                .hasSize( 2 )
                .containsExactly( "stdout", "stderr" );
    }

    @Test
    public void onlyGroupsIsDeclared()
    {
        Map<String, String> properties = singletonMap( TESTNG_GROUPS_PROP, "groupOne, groupTwo" );

        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );
        when( providerParameters.getProviderProperties() ).thenReturn( properties );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );

        assertEquals( 1, provider.getFilters().length );
    }

    @Test
    public void onlyExcludeTagsIsDeclared()
    {
        Map<String, String> properties = singletonMap( TESTNG_EXCLUDEDGROUPS_PROP, "tagOne, tagTwo" );

        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );
        when( providerParameters.getProviderProperties() ).thenReturn( properties );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );

        assertEquals( 1, provider.getFilters().length );
    }

    @Test
    public void noFiltersAreCreatedIfTagsAreEmpty()
    {
        Map<String, String> properties = singletonMap( TESTNG_GROUPS_PROP, "" );

        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );
        when( providerParameters.getProviderProperties() ).thenReturn( properties );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );
        assertEquals( 0, provider.getFilters().length );
    }

    @Test
    public void filtersWithEmptyTagsAreNotRegistered()
    {
        // Here only tagOne is registered as a valid tag and other tags are ignored as they are empty
        Map<String, String> properties = singletonMap( TESTNG_EXCLUDEDGROUPS_PROP, "tagOne," );

        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );
        when( providerParameters.getProviderProperties() ).thenReturn( properties );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );
        assertEquals( 1, provider.getFilters().length );
    }

    @Test
    public void bothIncludeAndExcludeAreAllowed()
    {
        Map<String, String> properties = new HashMap<>();
        properties.put( TESTNG_GROUPS_PROP, "tagOne, tagTwo" );
        properties.put( TESTNG_EXCLUDEDGROUPS_PROP, "tagThree, tagFour" );

        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );
        when( providerParameters.getProviderProperties() ).thenReturn( properties );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );

        assertEquals( 2, provider.getFilters().length );
    }

    @Test
    public void tagExpressionsAreSupportedForIncludeTagsContainingVerticalBar()
    {
        Map<String, String> properties = new HashMap<>();
        properties.put( TESTNG_GROUPS_PROP, "tagOne | tagTwo" );
        properties.put( TESTNG_EXCLUDEDGROUPS_PROP, "tagThree | tagFour" );

        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );
        when( providerParameters.getProviderProperties() ).thenReturn( properties );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );

        assertEquals( 2, provider.getFilters().length );
    }

    @Test
    public void tagExpressionsAreSupportedForIncludeTagsContainingAmpersand()
    {
        Map<String, String> properties = new HashMap<>();
        properties.put( TESTNG_GROUPS_PROP, "tagOne & !tagTwo" );
        properties.put( TESTNG_EXCLUDEDGROUPS_PROP, "tagThree & !tagFour" );

        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );
        when( providerParameters.getProviderProperties() ).thenReturn( properties );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );

        assertEquals( 2, provider.getFilters().length );
    }

    @Test
    public void noFiltersAreCreatedIfNoPropertiesAreDeclared()
    {
        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );

        assertEquals( 0, provider.getFilters().length );
    }

    @Test
    public void defaultConfigurationParametersAreEmpty()
    {
        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );
        when( providerParameters.getProviderProperties() ).thenReturn( emptyMap() );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );

        assertTrue( provider.getConfigurationParameters().isEmpty() );
    }

    @Test
    public void parsesConfigurationParameters()
    {
        ProviderParameters providerParameters = providerParametersMock( TestClass1.class );
        when( providerParameters.getProviderProperties() )
                        .thenReturn( singletonMap( JUnitPlatformProvider.CONFIGURATION_PARAMETERS,
                                                     "foo = true\nbar 42\rbaz: *\r\nqux: EOF" ) );

        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters );

        assertEquals( 4, provider.getConfigurationParameters().size() );
        assertEquals( "true", provider.getConfigurationParameters().get( "foo" ) );
        assertEquals( "42", provider.getConfigurationParameters().get( "bar" ) );
        assertEquals( "*", provider.getConfigurationParameters().get( "baz" ) );
        assertEquals( "EOF", provider.getConfigurationParameters().get( "qux" ) );
    }

    @Test
    public void executesSingleTestIncludedByName()
                    throws Exception
    {
        // following is equivalent of adding '-Dtest=TestClass3#prefix1Suffix1'
        // '*' needed because it's a nested class and thus has name prefixed with '$'
        String pattern = "*TestClass3#prefix1Suffix1";

        testExecutionOfMatchingTestMethods( TestClass3.class, pattern, "prefix1Suffix1()" );
    }

    @Test
    public void executesMultipleTestsIncludedByName()
                    throws Exception
    {
        // following is equivalent of adding '-Dtest=TestClass3#prefix1Suffix1+prefix2Suffix1'
        // '*' needed because it's a nested class and thus has name prefixed with '$'
        String pattern = "*TestClass3#prefix1Suffix1+prefix2Suffix1";

        testExecutionOfMatchingTestMethods(
                        TestClass3.class, pattern, "prefix1Suffix1()", "prefix2Suffix1()" );
    }

    @Test
    public void executesMultipleTestsIncludedByNamePattern()
                    throws Exception
    {
        // following is equivalent of adding '-Dtest=TestClass3#prefix1*'
        // '*' needed because it's a nested class and thus has name prefixed with '$'
        String pattern = "*TestClass3#prefix1*";

        testExecutionOfMatchingTestMethods(
                        TestClass3.class, pattern, "prefix1Suffix1()", "prefix1Suffix2()" );
    }

    @Test
    public void executesMultipleTestsIncludedByNamePatternWithQuestionMark()
                    throws Exception
    {
        // following is equivalent of adding '-Dtest=TestClass3#prefix?Suffix2'
        // '*' needed because it's a nested class and thus has name prefixed with '$'
        String pattern = "*TestClass3#prefix?Suffix2";

        testExecutionOfMatchingTestMethods(
                        TestClass3.class, pattern, "prefix1Suffix2()", "prefix2Suffix2()" );
    }

    @Test
    public void doesNotExecuteTestsExcludedByName()
                    throws Exception
    {
        // following is equivalent of adding '-Dtest=!TestClass3#prefix1Suffix2'
        // '*' needed because it's a nested class and thus has name prefixed with '$'
        String pattern = "!*TestClass3#prefix1Suffix2";

        testExecutionOfMatchingTestMethods(
                        TestClass3.class, pattern, "prefix1Suffix1()", "prefix2Suffix1()", "prefix2Suffix2()" );
    }

    @Test
    public void doesNotExecuteTestsExcludedByNamePattern()
                    throws Exception
    {
        // following is equivalent of adding '-Dtest=!TestClass3#prefix2*'
        // '*' needed because it's a nested class and thus has name prefixed with '$'
        String pattern = "!*TestClass3#prefix2*";

        testExecutionOfMatchingTestMethods(
                        TestClass3.class, pattern, "prefix1Suffix1()", "prefix1Suffix2()" );
    }

    private static void testExecutionOfMatchingTestMethods( Class<?> testClass, String pattern,
                                                            String... expectedTestNames )
                    throws Exception
    {
        TestListResolver testListResolver = new TestListResolver( pattern );
        ProviderParameters providerParameters = providerParametersMock( testListResolver, testClass );
        Launcher launcher = LauncherFactory.create();
        JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters, launcher );

        TestPlanSummaryListener executionListener = new TestPlanSummaryListener();
        launcher.registerTestExecutionListeners( executionListener );

        invokeProvider( provider, null );

        assertEquals( 1, executionListener.summaries.size() );
        TestExecutionSummary summary = executionListener.summaries.get( 0 );
        int expectedCount = expectedTestNames.length;
        assertEquals( expectedCount, summary.getTestsFoundCount() );
        assertEquals( expectedCount, summary.getTestsFailedCount() );
        assertEquals( expectedCount, summary.getFailures().size() );

        assertThat( failedTestDisplayNames( summary ) ).contains( expectedTestNames );
    }

    private static ProviderParameters providerParametersMock( Class<?>... testClasses )
    {
        return providerParametersMock( runListenerMock(), testClasses );
    }

    private static ProviderParameters providerParametersMock(
                    RunListener runListener, Class<?>... testClasses )
    {
        TestListResolver testListResolver = new TestListResolver( "" );
        return providerParametersMock( runListener, testListResolver, testClasses );
    }

    private static ProviderParameters providerParametersMock(
                    TestListResolver testListResolver, Class<?>... testClasses )
    {
        return providerParametersMock( runListenerMock(), testListResolver, testClasses );
    }

    private static ProviderParameters providerParametersMock(
                    RunListener runListener, TestListResolver testListResolver, Class<?>... testClasses )
    {
        TestsToRun testsToRun = newTestsToRun( testClasses );

        ScanResult scanResult = mock( ScanResult.class );
        when( scanResult.applyFilter( any(), any() ) ).thenReturn( testsToRun );

        RunOrderCalculator runOrderCalculator = mock( RunOrderCalculator.class );
        when( runOrderCalculator.orderTestClasses( any() ) ).thenReturn( testsToRun );

        ReporterFactory reporterFactory = mock( ReporterFactory.class );
        when( reporterFactory.createReporter() ).thenReturn( runListener );

        TestRequest testRequest = mock( TestRequest.class );
        when( testRequest.getTestListResolver() ).thenReturn( testListResolver );

        ProviderParameters providerParameters = mock( ProviderParameters.class );
        when( providerParameters.getScanResult() ).thenReturn( scanResult );
        when( providerParameters.getRunOrderCalculator() ).thenReturn( runOrderCalculator );
        when( providerParameters.getReporterFactory() ).thenReturn( reporterFactory );
        when( providerParameters.getTestRequest() ).thenReturn( testRequest );

        return providerParameters;
    }

    private static RunListener runListenerMock()
    {
        return mock( RunListener.class, withSettings().extraInterfaces( ConsoleOutputReceiver.class ) );
    }

    private static Set<String> failedTestDisplayNames( TestExecutionSummary summary )
    {
        // @formatter:off
        return summary.getFailures()
                .stream()
                .map( Failure::getTestIdentifier )
                .map( TestIdentifier::getDisplayName )
                .collect( toSet() );
        // @formatter:on
    }

    private static TestsToRun newTestsToRun( Class<?>... testClasses )
    {
        List<Class<?>> classesList = Arrays.asList( testClasses );
        return new TestsToRun( new LinkedHashSet<>( classesList ) );
    }

    private static TestsToRun newTestsToRunLazily( Class<?>... testClasses )
    {
        class LazyTestsToRunFake extends TestsToRun
        {
            LazyTestsToRunFake( Set<Class<?>> locatedClasses )
            {
                super( locatedClasses );
            }

            @Override
            public boolean allowEagerReading()
            {
                return false;
            }
        }
        List<Class<?>> classesList = Arrays.asList( testClasses );
        return new LazyTestsToRunFake( new LinkedHashSet<>( classesList ) );
    }

    private static class TestPlanSummaryListener
                    extends SummaryGeneratingListener
    {
        private final List<TestExecutionSummary> summaries = new ArrayList<>();

        @Override
        public void testPlanExecutionFinished( TestPlan testPlan )
        {
            super.testPlanExecutionFinished( testPlan );
            summaries.add( getSummary() );
        }
    }

    /**
     * Invokes the provider, then restores system out and system error.
     *
     * @see <a href="https://github.com/junit-team/junit5/issues/986">#986</a>
     */
    private static void invokeProvider( JUnitPlatformProvider provider, Object forkTestSet )
                    throws TestSetFailedException
    {
        PrintStream systemOut = System.out;
        PrintStream systemErr = System.err;
        try
        {
            provider.invoke( forkTestSet );
        }
        finally
        {
            System.setOut( systemOut );
            System.setErr( systemErr );
        }
    }

    static class TestClass1
    {

        static final int TESTS_FOUND = 4;

        static final int TESTS_STARTED = 3;

        static final int TESTS_SKIPPED = 1;

        static final int TESTS_SUCCEEDED = 2;

        static final int TESTS_ABORTED = 0;

        static final int TESTS_FAILED = 1;

        @org.junit.jupiter.api.Test
        void test1()
        {
        }

        @org.junit.jupiter.api.Test
        void test2()
        {
        }

        @Disabled
        @org.junit.jupiter.api.Test
        void test3()
        {
        }

        @org.junit.jupiter.api.Test
        void test4()
        {
            throw new RuntimeException();
        }
    }

    static class TestClass2
    {

        static final int TESTS_FOUND = 3;

        static final int TESTS_STARTED = 3;

        static final int TESTS_SKIPPED = 0;

        static final int TESTS_SUCCEEDED = 1;

        static final int TESTS_ABORTED = 1;

        static final int TESTS_FAILED = 1;

        @org.junit.jupiter.api.Test
        void test1()
        {
        }

        @org.junit.jupiter.api.Test
        void test2()
        {
            throw new RuntimeException();
        }

        @org.junit.jupiter.api.Test
        void test3()
        {
            assumeTrue( false );
        }
    }

    static class VerboseTestClass
    {
        @org.junit.jupiter.api.Test
        void test()
        {
            System.out.println( "stdout" );
            System.err.println( "stderr" );
        }
    }

    @Test
    public void usesClassNamesForXmlReport()
                    throws TestSetFailedException
    {
        String[] classNames = { Sub1Tests.class.getName(), Sub2Tests.class.getName() };
        ProviderParameters providerParameters =
                        providerParametersMock( Sub1Tests.class, Sub2Tests.class );

        JUnitPlatformProvider jUnitPlatformProvider = new JUnitPlatformProvider( providerParameters );
        TestsToRun testsToRun = newTestsToRun( Sub1Tests.class, Sub2Tests.class );

        invokeProvider( jUnitPlatformProvider, testsToRun );
        RunListener reporter = providerParameters.getReporterFactory().createReporter();

        ArgumentCaptor<ReportEntry> reportEntryArgumentCaptor =
                        ArgumentCaptor.forClass( ReportEntry.class );
        verify( reporter, times( 2 ) ).testSucceeded( reportEntryArgumentCaptor.capture() );

        List<ReportEntry> allValues = reportEntryArgumentCaptor.getAllValues();
        assertThat( allValues ).extracting( ReportEntry::getSourceName ).containsExactly( classNames );
    }

    static class AbstractTestClass
    {
        @org.junit.jupiter.api.Test
        void test()
        {
        }
    }

    static class Sub1Tests
                    extends AbstractTestClass
    {
    }

    static class Sub2Tests
                    extends AbstractTestClass
    {
    }

    static class TestClass3
    {
        @org.junit.jupiter.api.Test
        void prefix1Suffix1()
        {
            throw new RuntimeException();
        }

        @org.junit.jupiter.api.Test
        void prefix2Suffix1()
        {
            throw new RuntimeException();
        }

        @org.junit.jupiter.api.Test
        void prefix1Suffix2()
        {
            throw new RuntimeException();
        }

        @org.junit.jupiter.api.Test
        void prefix2Suffix2()
        {
            throw new RuntimeException();
        }
    }

    static class TestClass4
    {
        static int count;

        @org.junit.jupiter.api.DisplayName( "Always passes" )
        @org.junit.jupiter.api.Test
        void testPass()
        {
        }

        @org.junit.jupiter.api.Test
        void testAborted()
        {
            assumeFalse( true );
            throw new IllegalStateException( "this exception should never happen" );
        }

        @org.junit.jupiter.api.Test
        void testAlwaysError()
        {
            throw new Error( "some error" );
        }

        @org.junit.jupiter.api.Test
        void testAlwaysFail()
        {
            assertTrue( false );
        }

        @org.junit.jupiter.api.Test
        @org.junit.jupiter.api.Disabled
        void testAlwaysSkipped()
        {
            throw new IllegalStateException( "this test should be never called" );
        }

        @org.junit.jupiter.api.DisplayName( "Fails twice" )
        @org.junit.jupiter.api.Test
        void testFailTwice()
        {
            count += 1;
            assertTrue( count >= 3 );
        }
    }

    static class TestClass5
    {
        static int count;

        @org.junit.jupiter.api.Test
        void testFailTwice1()
        {
            count += 1;
            assertTrue( count >= 3 );
        }
    }

    static class TestClass7
    {
        static List<Object[]> params()
        {
            return Arrays.asList(  new Object[] { "Always pass", true },
                    new Object[] { "Always fail", false }  );
        }

        @org.junit.jupiter.params.ParameterizedTest
        @org.junit.jupiter.params.provider.MethodSource( "params" )
        void testParameterizedTestCases( String testName, boolean value )
        {
            assertTrue( value );
        }
    }

    static class TestClass8
    {
        static List<Object[]> params()
        {
            throw new RuntimeException();
        }

        @org.junit.jupiter.params.ParameterizedTest
        @org.junit.jupiter.params.provider.MethodSource( "params" )
        void testParameterizedTestCases()
        {
        }
    }

    static class TestClass9
    {
        static List<Object[]> params()
        {
            assertTrue( false );
            return new ArrayList<>();
        }

        @org.junit.jupiter.params.ParameterizedTest
        @org.junit.jupiter.params.provider.MethodSource( "params" )
        void testParameterizedTestCases()
        {
        }
    }

    @DisplayName( "<< ✨ >>" )
    static class DisplayNameTest
    {
        @org.junit.jupiter.api.Test
        @DisplayName( "73$71 ✔" )
        void test1()
        {
        }
    }

    static class FailingBeforeAllJupiterTest
    {

        @BeforeAll
        static void oneTimeSetUp()
        {
            fail( "oneTimeSetUp() failed" );
        }

        @org.junit.jupiter.api.Test
        void test()
        {
        }

    }

    static class FailingWithErrorBeforeAllJupiterTest
    {

        @BeforeAll
        static void oneTimeSetUp()
        {
            throw new RuntimeException( "oneTimeSetUp() threw an exception" );
        }

        @org.junit.jupiter.api.Test
        void test()
        {
        }

    }
}
