package me.august.lumen;
import me.august.lumen.compile.parser.ast.expr.*;
import me.august.lumen.compile.resolve.type.UnresolvedType;
import org.junit.Assert;
import org.junit.Test;
import org.objectweb.asm.Type;
public class ExpressionTest {
@Test
public void testNumberExpression() {
Expression expr = Util.parseExpression("1");
Assert.assertTrue(
"Expression should be a NumExpr",
expr instanceof NumExpr
);
Assert.assertEquals(
"Number should be 1",
expr, new NumExpr(1)
);
}
@Test
public void testIdentifierExpression() {
Expression expr = Util.parseExpression("foo");
Assert.assertTrue(
"Expression should be an IdentExpr",
expr instanceof IdentExpr
);
Assert.assertEquals(
"Identifier should be 'foo'",
expr, new IdentExpr("foo")
);
}
@Test
public void testUneededParens() {
Expression expr = Util.parseExpression("((((((1))))))");
Assert.assertTrue(
"Expected expression to be a NumExpr",
expr instanceof NumExpr
);
Assert.assertEquals(
"Number should be 1",
expr, new NumExpr(1)
);
}
@Test
public void testTernaryExpression() {
Expression expr = Util.parseExpression("foo ? bar : baz");
Assert.assertTrue(expr instanceof TernaryExpr);
TernaryExpr ternary = (TernaryExpr) expr;
Assert.assertEquals(ternary.getCondition(), new IdentExpr("foo"));
Assert.assertEquals(ternary.getTrueExpr(), new IdentExpr("bar"));
Assert.assertEquals(ternary.getFalseExpr(), new IdentExpr("baz"));
}
@Test
public void testStaticFieldExpression() {
Expression expr = Util.parseExpression("Foo::bar");
Assert.assertTrue(
"Expression should be a StaticField",
expr instanceof StaticField
);
StaticField field = (StaticField) expr;
Assert.assertEquals("Foo", field.getClassName());
Assert.assertEquals("bar", field.getFieldName());
}
@Test
public void testStaticMethodExpression() {
Expression expr = Util.parseExpression("Foo::bar()");
Assert.assertTrue(
"Expression should a StaticMethodCallExpr",
expr instanceof StaticMethodCall
);
StaticMethodCall method = (StaticMethodCall) expr;
Assert.assertEquals("Foo", method.getClassName());
Assert.assertEquals("bar", method.getMethodName());
Assert.assertTrue(
"Method parameters should be empty",
method.getParameters().isEmpty()
);
}
@Test
public void testOwnedExpressions() {
Expression expr;
expr = Util.parseExpression("foo().bar.qux");
Assert.assertTrue(
"Expression should be an IdentExpr",
expr instanceof IdentExpr
);
Assert.assertTrue(
"The identifier's tail should be a MethodCallExpr",
((OwnedExpr) expr).getTail() instanceof MethodCallExpr
);
expr = Util.parseExpression("foo.bar.qux()");
Assert.assertTrue(
"Expression should be a MethodCallExpr",
expr instanceof MethodCallExpr
);
Assert.assertTrue(
"The method call's tail should be an IdentExpr",
((OwnedExpr) expr).getTail() instanceof IdentExpr
);
}
@Test
public void testCastExpression() {
Expression expr = Util.parseExpression("foo as Bar");
Assert.assertTrue(
"Expression should be a CastExpr",
expr instanceof CastExpr
);
CastExpr cast = (CastExpr) expr;
Assert.assertTrue(
"Casting value should be an IdentExpr",
cast.getValue() instanceof IdentExpr
);
Assert.assertEquals(
"Identifier should be 'foo'",
"foo",
((IdentExpr) cast.getValue()).getIdentifier()
);
Assert.assertEquals(
"Cast target type should be 'Bar'",
"Bar",
cast.getUnresolvedType().getBaseName()
);
}
@Test
public void testArrayInitializerExpr() {
Expression expr = Util.parseExpression("int.. [1]");
Assert.assertTrue(
"Expression should be an ArrayInitializerExpr",
expr instanceof ArrayInitializerExpr
);
}
@Test
public void testArrayAccess() {
Expression expr = Util.parseExpression("foo[0]");
Assert.assertTrue(
"Expression should be an ArrayAccessExpr",
expr instanceof ArrayAccessExpr
);
}
@Test
public void testPrecedence() {
Expression expr = Util.parseExpression("1 * 2 + 3 * 4");
Assert.assertTrue(
"Top level expression should be addition",
expr instanceof AddExpr
);
}
@Test
public void testRescue() {
Expression expr;
RescueExpr rescue;
expr = Util.parseExpression("2 / 0 rescue 10");
Assert.assertTrue(
"Expression should be a RescueExpr",
expr instanceof RescueExpr
);
rescue = (RescueExpr) expr;
Assert.assertEquals("Expected `Exception` type", Type.getType(Exception.class), rescue.getResolvedType());
expr = Util.parseExpression("2 / 0 rescue ArithmeticException -> 10");
Assert.assertTrue(
"Expression should be a RescueExpr",
expr instanceof RescueExpr
);
rescue = (RescueExpr) expr;
UnresolvedType expected = new UnresolvedType("ArithmeticException");
Assert.assertEquals(
"Expected `ArithmeticException` type",
expected,
rescue.getUnresolvedType()
);
}
}