package com.github.havarunner.rules;

import com.github.havarunner.HavaRunner;
import com.google.common.collect.Lists;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import java.util.Collection;
import java.util.List;

import static com.github.havarunner.TestHelper.run;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class RuleTest {
    static Collection<Description> firstRuleApplications= Lists.newArrayList();
    static Collection<Description> secondRuleApplications = Lists.newArrayList();
    static boolean firstTestRun;
    static boolean secondTestRun;

    @Test
    public void HavaRunner_supports_JUnit_rules() {
        run(new HavaRunner(TestWithTwoRules.class));
        verify(firstRuleApplications);
        verify(secondRuleApplications);
        assertTrue(firstTestRun);
        assertTrue(secondTestRun);
    }

    private void verify(Collection<Description> ruleApplications) {
        assertEquals(2, ruleApplications.size());
        HavaRunner_applies_each_rule_on_each_test_method(ruleApplications);
    }

    private void HavaRunner_applies_each_rule_on_each_test_method(Collection<Description> ruleApplications) {
        List<String> calledTestMethods = Lists.newArrayList();
        for (Description ruleApplication : ruleApplications) {
            calledTestMethods.add(ruleApplication.getMethodName());
        }
        assertTrue(calledTestMethods.contains("hello"));
        assertTrue(calledTestMethods.contains("helloAgain"));
    }

    static class TestWithTwoRules {
        @Rule
        TestRule first = new TestRule() {
            @Override
            public Statement apply(Statement base, Description description) {
                firstRuleApplications.add(description);
                return base;
            }
        };

        @Rule
        TestRule second = new TestRule() {
            @Override
            public Statement apply(Statement base, Description description) {
                secondRuleApplications.add(description);
                return base;
            }
        };

        @Test
        void hello() {
            firstTestRun = true;
        }

        @Test
        void helloAgain() {
            secondTestRun = true;
        }
    }
}

@@ -296,24 +296,54 @@
 Collection;%0A
+import java.util.Collections;%0A
 import java.
@@ -577,22 +577,64 @@
 ations= 
-Lists.
+Collections.synchronizedList(Lists.%3CDescription%3E
 newArray
@@ -631,32 +631,33 @@
 n%3EnewArrayList()
+)
 ;%0A    static Col
@@ -698,30 +698,72 @@
 lications = 
-Lists.
+Collections.synchronizedList(Lists.%3CDescription%3E
 newArrayList
@@ -760,24 +760,25 @@
 wArrayList()
+)
 ;%0A    static

Synchronise test lists