/* $Id$ */

package aspectjhw.lambda;

import junit.framework.TestCase;
import java.util.*;

/** Tests for lambda abstractions.
 * @author Gary T. Leavens
 */
public class LambdaTest extends TestCase {

    /**Constructor for LambdaTest.
     * @param name
     */
    public LambdaTest(String name) {
        super(name);
    }

    /** Run this test. */
    public static void main(String[] args) {
        junit.textui.TestRunner.run(LambdaTest.class);
    }

    /** Test the equals method for lambda terms */
    public void testEquals() {
        assertEquals(
            new Lambda("x", new Variable("x")),
            new Lambda("x", new Variable("x")));
        assertFalse(
            new Lambda("x", new Variable("x")).equals(
                new Lambda("y", new Variable("x"))));
        assertFalse(
            new Lambda("x", new Variable("x")).equals(
                new Lambda("x", new Variable("y"))));
    }

    /** Test the hashCode method */
    public void testHashCode() {
        assertEquals(
            new Lambda("x", new Variable("x")).hashCode(),
            new Lambda("x", new Variable("x")).hashCode());
    }

    /** Test the evaluate method */
    public void testEvaluate() {
        Term t =
            new Application(
                new Lambda("x", new Variable("x")),
                new Variable("y"));
        assertEquals(new Variable("y"), t.reduce1Step());
    }

    /** Test the freeVars method */
    public void testFreeVars() {
        assertEquals(
            new HashSet(),
            new Lambda("x", new Variable("x")).freeVars());
        Term t = new Lambda("x", new Variable("y"));
        Set s = new HashSet();
        s.add("y");
        assertEquals(s, t.freeVars());
    }

    /** Test the substituteFor method */
    public void testSubstituteFor() {
        Term t = new Lambda("x", new Variable("x"));
        assertEquals(t, t.substituteFor("z", new Variable("q")));
        assertEquals(t, t.substituteFor("x", new Variable("q")));
        assertEquals(
            new Lambda("x", new Variable("z")),
            new Lambda("x", new Variable("y")).substituteFor(
                "y",
                new Variable("z")));
    }

    /** Test the toString method */
    public void testToString() {
        assertEquals(
            "(\\ x -> x)",
            new Lambda("x", new Variable("x")).toString());
    }

}
