package com.atlassian.bitbucket.test.rules;

import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import static org.junit.Assert.assertEquals;

public class RetryRuleTest {

    @Test
    public void testRetries() {
        assertEquals(1, evaluate(1, false));
        assertEquals(2, evaluate(2, false));
        assertEquals(3, evaluate(3, false));
        assertEquals(3, evaluate(4, true));
        // Run out the rest of the testFailures (it's static unfortunately)
        for (int i = 0; i < 19; i++) {
            assertEquals(3, evaluate(4, true));
        }
        // And now we only ever run the tests once
        assertEquals(1, evaluate(4, true));
    }

    private static int evaluate(final int runsLessThan, boolean hasError) {
        final int[] evaluations = new int[1];
        boolean error = false;
        try {
            new RetryRule(3).apply(new Statement() {
                @Override
                public void evaluate() throws Throwable {
                    evaluations[0]++;
                    if (evaluations[0] < runsLessThan) {
                        throw new RuntimeException();
                    }
                }
            }, Description.createTestDescription(RetryRuleTest.class, "foo")).evaluate();
        } catch (Throwable t) {
            error = true;
        }
        assertEquals(hasError, error);
        return evaluations[0];
    }
}
