package test.mockobjects.dynamic;

import com.mockobjects.dynamic.*;
import com.mockobjects.dynamic.ConstraintMatcher;

import junit.framework.TestCase;

public class ConstraintMatcherTest extends TestCase {

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

    public void testNoMatchWhenTooManyArguments() throws Throwable {
        String[] args = { "arg1", "arg2" };
        MockConstraint[] constraints = { new MockConstraint("constraint1", args[0], true) };

        ConstraintMatcher constraintMatcher = new FullConstraintMatcher(constraints);

        assertFalse("Should not match if too many arguments", constraintMatcher.matches(args));
    }

    public void testNoMatchWhenTooFewArguments() throws Throwable {
        String[] args = { "arg1" };
        MockConstraint[] constraints = { new MockConstraint("constraint1", args[0], true), new MockConstraint("constraint2", args[0], true) };

        ConstraintMatcher constraintMatcher = new FullConstraintMatcher(constraints);

        assertFalse("Should not match if too few arguments", constraintMatcher.matches(args));
    }

    public void testNoMatchWhenConstraintIsViolated() throws Throwable {
        String[] args = { "argA", "argB", "argC" };
        MockConstraint[] constraints = {
            new MockConstraint("constraintA", args[0], true), new MockConstraint("constraintB", args[1], false),
            new MockConstraint("constraintC", args[2], true)
        };

        ConstraintMatcher constraintMatcher = new FullConstraintMatcher(constraints);

        assertFalse("Should not match", constraintMatcher.matches(args));
    }

    public void testNoMatchWithNoArgumentsAndCalleeHasArguments()
        throws Throwable {
        String[] args = new String[] { "arg1", "arg2" };
        MockConstraint[] constraints = new MockConstraint[0];

        ConstraintMatcher constraintMatcher = new FullConstraintMatcher(constraints);

        assertFalse("Should not match", constraintMatcher.matches(args));
    }

    public void testMatchWithNoArguments() throws Throwable {
        String[] args = new String[0];
        MockConstraint[] constraints = new MockConstraint[0];

        ConstraintMatcher constraintMatcher = new FullConstraintMatcher(constraints);

        assertTrue("Should match", constraintMatcher.matches(args));
    }

    public void testMatchAndArgumentsCheckedAgainstConstraints()
        throws Throwable {
        String[] args = { "argA", "argB", "argC" };
        MockConstraint constraintA = new MockConstraint("constraintA", args[0], true);
        MockConstraint constraintB = new MockConstraint("constraintB", args[1], true);
        MockConstraint constraintC = new MockConstraint("constraintC", args[2], true);
        MockConstraint[] constraints = { constraintA, constraintB, constraintC };

        ConstraintMatcher constraintMatcher = new FullConstraintMatcher(constraints);

        assertTrue("Should match", constraintMatcher.matches(args));
        constraintA.verify();
        constraintB.verify();
        constraintC.verify();
    }

    public void testMatchWithArgument() throws Throwable {
        String[] args = { "argA" };

        MockConstraint constraintA = new MockConstraint("constraintA", args[0], true);
        ConstraintMatcher constraintMatcher = new FullConstraintMatcher(new MockConstraint[] { constraintA });

        assertTrue("Should match", constraintMatcher.matches(args));
    }
}
