/*
 * Created on 04-Apr-2003
 */
package test.mockobjects.dynamic;

import junit.framework.TestCase;

import com.mockobjects.dynamic.*;


public class CallMatchTest extends TestCase {
    private static final Object[] IGNORED_ARGS = new Object[0];
    final String METHOD_NAME = "methodName";
    Mock mock = new Mock(DummyInterface.class, "mock");
    MockCallable mockCallable = new MockCallable();
    MockConstraintMatcher mockConstraintMatcher = new MockConstraintMatcher();
    CallSignature callSignature = new CallSignature(METHOD_NAME, mockConstraintMatcher, mockCallable);

    public CallMatchTest(String name) {
        super(name);
    }

    public void testCallArgumentsArePropagatedToDecorated()
        throws Throwable {
        final Object[] arguments = IGNORED_ARGS;
        final String result = "result";

        mockCallable.setExpectedCall(mock, METHOD_NAME, arguments);
        mockCallable.setupCallReturn(result);

        callSignature.call(mock, METHOD_NAME, arguments);

        mockCallable.verifyExpectations();
    }

    public void testUncalledCallVerifies() {
        mockCallable.setExpectedVerifyCalls(1);

        callSignature.verify();

        mockCallable.verifyExpectations();
    }

    public void testCallSuccessVerifies() throws Throwable {
        mockCallable.setExpectedVerifyCalls(1);
        mockCallable.setupCallReturn("result");

        callSignature.call(mock, "methodName", IGNORED_ARGS);
        callSignature.verify();

        mockCallable.verifyExpectations();
    }

    public void testMultipleCallsSucceed() throws Throwable {
        mockCallable.setupCallReturn("result");

        callSignature.call(mock, METHOD_NAME, IGNORED_ARGS);
        callSignature.call(mock, METHOD_NAME, IGNORED_ARGS);

        mockCallable.verifyExpectations();
    }

    public void testCallFailure() throws Throwable {
    	// na
    }

    public void testCallDoesNotMatchWhenWrongName() throws Throwable {
        assertFalse("call does not match", callSignature.matches("anotherName", IGNORED_ARGS));
        mockCallable.verifyExpectations();
    }

    public void testMatchesAfterCalls() throws Throwable {
        mockCallable.setupCallReturn("result");
        mockCallable.setupMatchesReturn(true);

        mockConstraintMatcher.setupMatches(true);

        callSignature.call(mock, METHOD_NAME, IGNORED_ARGS);
        assertTrue("matches after first call", callSignature.matches(METHOD_NAME, IGNORED_ARGS));
        callSignature.call(mock, METHOD_NAME, IGNORED_ARGS);
        assertTrue("matches after further calls", callSignature.matches(METHOD_NAME, IGNORED_ARGS));

        mockCallable.verifyExpectations();
    }

    public void testMatchesDelegatesToContraintMatcher()
        throws Throwable {
        final String[] args = new String[] { "a1", "a2" };

        mockConstraintMatcher.addExpectedMatches(args);
        mockConstraintMatcher.setupMatches(true);

        assertTrue("matches delegated to constraint matcher", callSignature.matches(METHOD_NAME, args));
        mockConstraintMatcher.verify();
    }

    public void testMatchesFailure() throws Throwable {
        mockConstraintMatcher.setupMatches(false);

        assertFalse("Should not match if constraint matcher doesn't", callSignature.matches(METHOD_NAME, IGNORED_ARGS));
    }
}
