package org.mockitousage.junitrunner;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.exceptions.misusing.UnnecessaryStubbingException;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockitousage.IMethods;
import org.mockitoutil.JUnitResultAssert;
import org.mockitoutil.TestBase;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;


public class StrictRunnerTest extends TestBase {

    JUnitCore runner = new JUnitCore();

    @Test public void succeeds_when_all_stubs_were_used() {
        //when
        Result result = runner.run(
                StubbingInConstructorUsed.class,
                StubbingInBeforeUsed.class,
                StubbingInTestUsed.class
        );
        //then
        JUnitResultAssert.assertThat(result).isSuccessful();
    }

    @Test public void fails_when_stubs_were_not_used() {
        Class[] tests = {StubbingInConstructorUnused.class,
                StubbingInBeforeUnused.class,
                StubbingInTestUnused.class};

        //when
        Result result = runner.run(tests);

        //then
        JUnitResultAssert.assertThat(result).fails(3, UnnecessaryStubbingException.class);
    }

    @Test public void does_not_report_unused_stubs_when_different_failure_is_present() {
        //when
        Result result = runner.run(WithUnrelatedAssertionFailure.class);

        //then
        JUnitResultAssert.assertThat(result).fails(1, MyAssertionError.class);
    }

    @Test public void runner_can_coexist_with_rule() {
        //I don't believe that this scenario is useful
        //I only wish that Mockito does not break awkwardly when both: runner & rule is used

        //when
        Result result = runner.run(RunnerAndRule.class);

        //then
        JUnitResultAssert.assertThat(result).fails(1, UnnecessaryStubbingException.class);
    }

    @Test public void runner_in_multi_threaded_tests() {
        //when
        Result result = runner.run(StubUsedFromDifferentThread.class);

        //then
        JUnitResultAssert.assertThat(result).isSuccessful();
    }

    @RunWith(MockitoJUnitRunner.class)
    public static class StubbingInConstructorUsed extends StubbingInConstructorUnused {
        @Test public void test() {
            assertEquals("1", mock.simpleMethod(1));
        }
    }

    @RunWith(MockitoJUnitRunner.Strict.class) //using Strict to make sure it does the right thing
    public static class StubbingInConstructorUnused {
        IMethods mock = when(mock(IMethods.class).simpleMethod(1)).thenReturn("1").getMock();
        @Test public void dummy() {}
    }

    @RunWith(MockitoJUnitRunner.class)
    public static class StubbingInBeforeUsed extends StubbingInBeforeUnused {
        @Test public void test() {
            assertEquals("1", mock.simpleMethod(1));
        }
    }

    @RunWith(MockitoJUnitRunner.class)
    public static class StubbingInBeforeUnused {
        @Mock IMethods mock;
        @Before public void before() {
            when(mock.simpleMethod(1)).thenReturn("1");
        }
        @Test public void dummy() {}
    }

    @RunWith(MockitoJUnitRunner.class)
    public static class StubbingInTestUsed {
        @Test public void test() {
            IMethods mock = mock(IMethods.class);
            when(mock.simpleMethod(1)).thenReturn("1");
            assertEquals("1", mock.simpleMethod(1));
        }
    }

    @RunWith(MockitoJUnitRunner.class)
    public static class StubbingInTestUnused {
        @Test public void test() {
            IMethods mock = mock(IMethods.class);
            when(mock.simpleMethod(1)).thenReturn("1");
            mock.simpleMethod(2); //different arg
        }
    }

    private static class MyAssertionError extends AssertionError {}

    @RunWith(MockitoJUnitRunner.class)
    public static class WithUnrelatedAssertionFailure {

        IMethods mock = mock(IMethods.class);
        IMethods mock2 = mock(IMethods.class);

        @Before public void before() {
            when(mock2.simpleMethod("unused stubbing")).thenReturn("");
        }

        @Test public void passing_test() {
            when(mock.simpleMethod(1)).thenReturn("1");
            assertEquals("1", mock.simpleMethod(1));
        }

        @Test public void failing_test() {
            throw new MyAssertionError();
        }
    }

    @RunWith(MockitoJUnitRunner.class)
    public static class RunnerAndRule {

        public @Rule MockitoRule rule = MockitoJUnit.rule();
        IMethods mock = mock(IMethods.class);

        @Test public void passing_test() {
            when(mock.simpleMethod(1)).thenReturn("1");
            mock.simpleMethod(2);
        }
    }

    @RunWith(MockitoJUnitRunner.class)
    public static class StubUsedFromDifferentThread {

        IMethods mock = mock(IMethods.class);

        @Test public void passing_test() throws Exception {
            //stubbing is done in main thread:
            when(mock.simpleMethod(1)).thenReturn("1");

            //stubbing is used in a different thread
            //stubbing should not be reported as unused by the runner
            Thread t = new Thread() {
                public void run() {
                    mock.simpleMethod(1);
                }
            };
            t.start();
            t.join();
        }
    }
}
