package org.apache.maven.surefire.junitcore;

/*
 * 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 java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import junit.framework.TestCase;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.Computer;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.RunListener;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;

/**
 * @author Kristian Rosenvold
 */
public class JUnitCoreRunListenerTest extends TestCase
{
    public void testTestRunStarted()
    {
        RunListener jUnit4TestSetReporter = new JUnitCoreRunListener( new MockReporter(),
                new HashMap<String, TestSet>() );
        JUnitCore core = new JUnitCore();
        core.addListener( jUnit4TestSetReporter );
        Result result = core.run( new Computer(), STest1.class, STest2.class );
        core.removeListener( jUnit4TestSetReporter );
        assertEquals( 2, result.getRunCount() );
    }

    public void testFailedAssumption()
    {
        RunListener jUnit4TestSetReporter = new JUnitCoreRunListener( new MockReporter(),
                new HashMap<String, TestSet>() );
        JUnitCore core = new JUnitCore();
        core.addListener( jUnit4TestSetReporter );
        Result result = core.run( new Computer(), TestWithAssumptionFailure.class );
        core.removeListener( jUnit4TestSetReporter );
        assertEquals( 1, result.getRunCount() );
    }

    public void testStateForClassesWithNoChildren() throws Exception
    {
        Description testDescription = Description.createSuiteDescription(
                "testMethod(cannot.be.loaded.by.junit.Test)" );
        Description st1 = Description.createSuiteDescription( STest1.class );
        //        st1.addChild( Description.createSuiteDescription( STest1.class ) );
        testDescription.addChild( st1 );
        Description st2 = Description.createSuiteDescription( STest2.class );
        //      st2.addChild( Description.createSuiteDescription( STest2.class ) );
        testDescription.addChild( st2 );

        Map<String, TestSet> classMethodCounts = new HashMap<>();
        JUnitCoreRunListener listener = new JUnitCoreRunListener( new MockReporter(), classMethodCounts );
        listener.testRunStarted( testDescription );
        assertEquals( 2, classMethodCounts.size() );
        Iterator<TestSet> iterator = classMethodCounts.values().iterator();
        assertFalse( iterator.next().equals( iterator.next() ) );
    }

    public void testTestClassNotLoadableFromJUnitClassLoader() throws Exception
    {
        // can't use Description.createTestDescription() methods as these require a loaded Class
        Description testDescription = Description.createSuiteDescription(
                "testMethod(cannot.be.loaded.by.junit.Test)" );
        assertEquals( "testMethod", testDescription.getMethodName() );
        assertEquals( "cannot.be.loaded.by.junit.Test", testDescription.getClassName() );
        // assert that the test class is not visible by the JUnit classloader
        assertNull( testDescription.getTestClass() );
        Description suiteDescription = Description.createSuiteDescription( "testSuite" );
        suiteDescription.addChild( testDescription );
        Map<String, TestSet> classMethodCounts = new HashMap<>();
        JUnitCoreRunListener listener = new JUnitCoreRunListener( new MockReporter(), classMethodCounts );
        listener.testRunStarted( suiteDescription );
        assertEquals( 1, classMethodCounts.size() );
        TestSet testSet = classMethodCounts.get( "cannot.be.loaded.by.junit.Test" );
        assertNotNull( testSet );
    }

    public void testNonEmptyTestRunStarted() throws Exception
    {
        Description aggregator = Description.createSuiteDescription( "null" );
        Description suite = Description.createSuiteDescription( "some.junit.Test" );
        suite.addChild( Description.createSuiteDescription( "testMethodA(some.junit.Test)" ) );
        suite.addChild( Description.createSuiteDescription( "testMethodB(some.junit.Test)" ) );
        suite.addChild( Description.createSuiteDescription( "testMethod(another.junit.Test)" ) );
        aggregator.addChild( suite );
        Map<String, TestSet> classMethodCounts = new HashMap<>();
        JUnitCoreRunListener listener = new JUnitCoreRunListener( new MockReporter(), classMethodCounts );
        listener.testRunStarted( aggregator );
        assertThat( classMethodCounts.keySet(), hasSize( 2 ) );
        assertThat( classMethodCounts.keySet(), containsInAnyOrder( "some.junit.Test", "another.junit.Test" ) );
        TestSet testSet = classMethodCounts.get( "some.junit.Test" );
        MockReporter reporter = new MockReporter();
        testSet.replay( reporter );
        assertTrue( reporter.containsNotification( MockReporter.SET_STARTED ) );
        assertTrue( reporter.containsNotification( MockReporter.SET_COMPLETED ) );
        listener.testRunFinished( null );
        assertThat( classMethodCounts.keySet(), empty() );
    }

    public void testEmptySuiteTestRunStarted() throws Exception
    {
        Description aggregator = Description.createSuiteDescription( "null" );
        Description suite = Description.createSuiteDescription( "some.junit.TestSuite" );
        aggregator.addChild( suite );
        Map<String, TestSet> classMethodCounts = new HashMap<>();
        JUnitCoreRunListener listener = new JUnitCoreRunListener( new MockReporter(), classMethodCounts );
        listener.testRunStarted( aggregator );
        assertThat( classMethodCounts.keySet(), hasSize( 1 ) );
        assertThat( classMethodCounts.keySet(), contains( "some.junit.TestSuite" ) );
        listener.testRunFinished( null );
        assertThat( classMethodCounts.keySet(), empty() );
    }

    /**
     *
     */
    public static class STest1
    {
        @Test
        public void testSomething()
        {
        }
    }

    /**
     *
     */
    public static class STest2
    {
        @Test
        public void testSomething2()
        {
        }
    }

    /**
     *
     */
    public static class TestWithAssumptionFailure
    {
        @Test
        public void testSomething2()
        {
            Assume.assumeTrue( false );
        }
    }

}
