package aspectjhw.lambda;
import junit.framework.TestCase;
import java.util.*;

/** Tests for the Boundvars aspect */
public class BoundVarsTest extends TestCase {
    
    /** Construct this test. */
    public BoundVarsTest(String name) { 
        super(name); 
    }

    /** Run this test */
    public static void main(String[] args) {
        junit.textui.TestRunner.run(BoundVarsTest.class);
    }
    
    /** Test boundVars for variables */
    public void testBoundVarsOfVariable() {
        Term t = new Variable("z");
        Set s = new HashSet();
        assertEquals(s, t.boundVars());
    }
    
    /** Test boundVars for applications */
    public void testBoundVarsOfApplication() {
        assertEquals(
            new HashSet(),
            new Application(new Variable("x"), new Variable("y")).boundVars());
        Term t =
            new Application(
                new Lambda("x", new Variable("x")),
                new Lambda("y", new Variable("y")));
        Set s = new HashSet();
        s.add("x");
        s.add("y");
        assertEquals(s, t.boundVars());
    }
    
    /** Test boundVars for lambda abstractions */
    public void testBoundVarsOfLambda() {
        assertEquals(
            new HashSet(),
            new Lambda("x", new Variable("y")).boundVars());
        Term t = new Lambda("x", new Variable("x"));
        Set s = new HashSet();
        s.add("x");
        assertEquals(s, t.boundVars());
    }
    
    /** Test boundVars for lambda abstractions */
    public void testBoundVarsOfLambda2() {
        Term t = new Lambda("x", new Lambda("x", new Variable("x")));
        Set s = new HashSet();
        s.add("x");
        assertEquals(s, t.boundVars());
    }

    /** Test boundVars for lambda abstractions */
    public void testBoundVarsOfLambda3() {
        Term t = new Lambda("f",
                     new Application(
                        new Application(new Variable("f"),
                                        new Lambda("y", new Variable("y"))),
                        new Application(new Lambda("z", new Variable("z")),
                                        new Variable("f"))));
        Set s = new HashSet();
        s.add("y");
        s.add("z");
        s.add("f");
        assertEquals(s, t.boundVars());
    }

    /** General tests for boundVars */
    public void testBoundVarsGeneral() {
        Term t =
            new Application(
                new Lambda(
                    "x",
                    new Application(new Variable("x"), new Variable("y"))),
                new Application(
                    new Lambda("z", new Variable("q")),
                    new Lambda(
                        "r",
                        new Application(
                            new Variable("r"),
                            new Variable("r")))));
        Set s = new HashSet();
        s.add("x");
        s.add("r");
        assertEquals(s, t.boundVars());
    }
}
