package org.reasm.expressions;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertThat;

import org.junit.Test;
import org.reasm.StaticSymbol;
import org.reasm.UnsignedIntValue;
import org.reasm.Value;
import org.reasm.ValueVisitor;
import org.reasm.testhelpers.DummySymbolLookup;
import org.reasm.testhelpers.SingleSymbolLookup;

/**
 * Test class for {@link IdentifierExpression}.
 *
 * @author Francis Gagné
 */
public class IdentifierExpressionTest {

    static final IdentifierExpression IDENTIFIER_EXPRESSION = new IdentifierExpression("foo", DummySymbolLookup.DEFAULT);

    /**
     * Asserts that {@link IdentifierExpression#evaluate(EvaluationContext)} evaluates to the value of the symbol identified by the
     * identifier.
     */
    @Test
    public void evaluate() {
        final Value value = new UnsignedIntValue(1);
        final SymbolLookup symbolLookup = new SingleSymbolLookup("foo", new StaticSymbol(value));
        assertThat(new IdentifierExpression("foo", symbolLookup).evaluate(EvaluationContext.DUMMY), is(value));
    }

    /**
     * Asserts that {@link IdentifierExpression#evaluate(EvaluationContext)} returns <code>null</code> when the {@link SymbolLookup}
     * is <code>null</code>.
     */
    @Test
    public void evaluateNullSymbolLookup() {
        assertThat(new IdentifierExpression("foo", null).evaluate(EvaluationContext.DUMMY), is(nullValue()));
    }

    /**
     * Asserts that {@link IdentifierExpression#IdentifierExpression(String, SymbolLookup)} correctly initializes an
     * {@link IdentifierExpression}.
     */
    @Test
    public void identifierExpression() {
        assertThat(IDENTIFIER_EXPRESSION.getIdentifier(), is("foo"));
        assertThat(IDENTIFIER_EXPRESSION.getSymbolLookup(), is((SymbolLookup) DummySymbolLookup.DEFAULT));
    }

    /**
     * Asserts that {@link IdentifierExpression#IdentifierExpression(String, SymbolLookup)} throws a {@link NullPointerException}
     * when the <code>identifier</code> argument is <code>null</code>.
     */
    @Test(expected = NullPointerException.class)
    public void identifierExpressionNullIdentifier() {
        new IdentifierExpression(null, DummySymbolLookup.DEFAULT);
    }

    /**
     * Asserts that {@link IdentifierExpression#toString()} returns a string representation of the expression.
     */
    @Test
    public void testToString() {
        assertThat(IDENTIFIER_EXPRESSION.toString(), is("IdentifierExpression [identifier=foo, symbolLookup="
                + DummySymbolLookup.DEFAULT.toString() + "]"));
    }

    /**
     * Asserts that {@link IdentifierExpression#toIdentifier(EvaluationContext, ValueVisitor)} returns the
     * {@link IdentifierExpression} itself.
     */
    @Test
    public void toIdentifier() {
        assertThat(IDENTIFIER_EXPRESSION.toIdentifier(EvaluationContext.DUMMY, new ValueToStringVisitor(EvaluationContext.DUMMY,
                "???")), is(sameInstance(IDENTIFIER_EXPRESSION)));
    }

}

@@ -260,16 +260,70 @@
 Symbol;%0A
+import org.reasm.Symbol;%0Aimport org.reasm.SymbolType;%0A
 import o
@@ -1218,32 +1218,1332 @@
 value));%0A    %7D%0A%0A
+    /**%0A     * Asserts that %7B@link IdentifierExpression#evaluate(EvaluationContext)%7D returns %3Ccode%3Enull%3C/code%3E when the identifier%0A     * identifies a symbol whose value is not a %7B@link Value%7D.%0A     */%0A    @Test%0A    public void evaluateNotAValue() %7B%0A        final SymbolLookup symbolLookup = new SymbolLookup() %7B%0A            @Override%0A            public Symbol getSymbol(final String name) %7B%0A                return new Symbol(name, SymbolType.CONSTANT) %7B%0A                    @Override%0A                    public Object getValue() %7B%0A                        return name;%0A                    %7D%0A                %7D;%0A            %7D%0A        %7D;%0A%0A        assertThat(new IdentifierExpression(%22foo%22, symbolLookup).evaluate(EvaluationContext.DUMMY), is(nullValue()));%0A    %7D%0A%0A    /**%0A     * Asserts that %7B@link IdentifierExpression#evaluate(EvaluationContext)%7D returns %3Ccode%3Enull%3C/code%3E when the identifier%0A     * identifies no known symbol.%0A     */%0A    @Test%0A    public void evaluateNullSymbol() %7B%0A        final SymbolLookup symbolLookup = new SymbolLookup() %7B%0A            @Override%0A            public Symbol getSymbol(String name) %7B%0A                return null;%0A            %7D%0A        %7D;%0A%0A        assertThat(new IdentifierExpression(%22foo%22, symbolLookup).evaluate(EvaluationContext.DUMMY), is(nullValue()));%0A    %7D%0A%0A
     /**%0A     * A

Add tests for IdentifierExpression.evaluate()