package com.dhemery.polling;

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.Sequence;
import org.jmock.auto.Auto;
import org.jmock.auto.Mock;
import org.jmock.integration.junit4.JMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JMock.class)
public class AnEvaluatingPoller {
    Mockery context  = new Mockery();
    @Mock Ticker ticker;
    @Mock PollEvaluator evaluator;
    @Mock Condition condition;
    @Auto Sequence polling;
    Poller poller;

    @Before
    public void setup() {
        poller = new EvaluatingPoller(evaluator);
    }

    @Test
    public void returnsIfTheEvaluatorIsImmediatelySatisfied() {
        context.checking(new Expectations() {{
            allowing(ticker).start();
            allowing(ticker).isExpired(); will(returnValue(false));

            oneOf(evaluator).evaluate(with(condition), with(any(Long.class)));
                will(returnValue(true));
        }});

        poller.poll(ticker, condition);
    }

    @Test
    public void returnsIfTheEvaluatorIsEventuallySatisfied() {
        context.checking(new Expectations() {{
            allowing(ticker).start();
            allowing(ticker).tick();
            allowing(ticker).isExpired(); will(returnValue(false));
            oneOf(evaluator).evaluate(with(condition), with(any(Long.class)));
                will(returnValue(false));
                inSequence(polling);
            oneOf(evaluator).evaluate(with(condition), with(any(Long.class)));
                will(returnValue(true));
                inSequence(polling);
        }});

        poller.poll(ticker, condition);
    }

    @Test(expected=PollTimeoutException.class)
    public void throwsIfTheTimerImmediatelyExpires() {
        context.checking(new Expectations() {{
            allowing(ticker).start();
            oneOf(ticker).isExpired(); will(returnValue(true));
        }});

        poller.poll(ticker, condition);
    }

    @Test(expected=PollTimeoutException.class)
    public void throwsIfTheTimerEventuallyExpires() {
        context.checking(new Expectations() {{
            allowing(ticker).start();
            allowing(ticker).tick();
            allowing(evaluator).evaluate(with(condition), with(any(Long.class)));
                will(returnValue(false));
            oneOf(ticker).isExpired();
                inSequence(polling);
                will(returnValue(false));
            oneOf(ticker).isExpired();
                inSequence(polling);
                will(returnValue(true));
        }});

        poller.poll(ticker, condition);
    }

    @Test
    public void reportsFailureCountWithEachEvaluation() {
        context.checking(new Expectations() {{
            allowing(ticker).start();
            allowing(ticker).tick();
            allowing(ticker).isExpired(); will(returnValue(false));
            oneOf(evaluator).evaluate(condition, 0); inSequence(polling); will(returnValue(false));
            oneOf(evaluator).evaluate(condition, 1); inSequence(polling); will(returnValue(false));
            oneOf(evaluator).evaluate(condition, 2); inSequence(polling); will(returnValue(false));
            oneOf(evaluator).evaluate(condition, 3); inSequence(polling); will(returnValue(false));
            oneOf(evaluator).evaluate(condition, 4); inSequence(polling); will(returnValue(false));
            oneOf(evaluator).evaluate(condition, 5); inSequence(polling); will(returnValue(true));
        }});

        poller.poll(ticker, condition);
    }
}

@@ -848,37 +848,40 @@
 );%0A%0A            
-oneOf
+allowing
 (evaluator).eval
@@ -1295,37 +1295,40 @@
 ));%0A            
-oneOf
+allowing
 (evaluator).eval
@@ -1398,220 +1398,65 @@
 ill(
-returnValue(false));%0A                inSequence(polling);%0A            oneOf(evaluator).evaluate(with(condition), with(any(Long.class)));%0A                will(returnValue(true));%0A                inSequence(polling
+onConsecutiveCalls(returnValue(false), returnValue(true))
 );%0A 
@@ -1706,37 +1706,40 @@
 ();%0A            
-oneOf
+allowing
 (ticker).isExpir
@@ -2134,32 +2134,16 @@
 lass)));
-%0A               
  will(re
@@ -2165,37 +2165,40 @@
 ));%0A            
-oneOf
+allowing
 (ticker).isExpir
@@ -2206,66 +2206,32 @@
 d();
-%0A                inSequence(polling);%0A                wi
+ will(onConsecutiveCa
 ll
+s
 (ret
@@ -2249,108 +2249,10 @@
 lse)
-);%0A            oneOf(ticker).isExpired();%0A                inSequence(polling);%0A                will(
+, 
 retu
@@ -2257,32 +2257,33 @@
 turnValue(true))
+)
 ;%0A        %7D%7D);%0A%0A

Tidy up the evaluating poller tests.