1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
#include "harness.h"
#define CHECK_PARSE(var, expr) \
do { \
var = Expr::From(expr, false); \
CHECK_TRUE(var != NULL); \
} while(0)
#define CHECK_PARSE_ERR(expr, msg) \
do { \
std::string err; \
Expr *e = Expr::Parse(expr, &err); \
CHECK_TRUE(e == NULL); \
CHECK_TRUE(err.find(msg) != std::string::npos); \
} while(0)
TEST_CASE(constant) {
Expr *e;
CHECK_PARSE(e, "pi");
CHECK_EQ_EPS(e->Eval(), 3.1415926);
}
TEST_CASE(literal) {
Expr *e;
CHECK_PARSE(e, "42");
CHECK_TRUE(e->Eval() == 42);
CHECK_PARSE(e, "42.5");
CHECK_TRUE(e->Eval() == 42.5);
CHECK_PARSE(e, "1_000_000");
CHECK_TRUE(e->Eval() == 1000000);
}
TEST_CASE(unary_ops) {
Expr *e;
CHECK_PARSE(e, "-10");
CHECK_TRUE(e->Eval() == -10);
}
TEST_CASE(binary_ops) {
Expr *e;
CHECK_PARSE(e, "1 + 2");
CHECK_TRUE(e->Eval() == 3);
CHECK_PARSE(e, "1 - 2");
CHECK_TRUE(e->Eval() == -1);
CHECK_PARSE(e, "3 * 4");
CHECK_TRUE(e->Eval() == 12);
CHECK_PARSE(e, "3 / 4");
CHECK_TRUE(e->Eval() == 0.75);
}
TEST_CASE(parentheses) {
Expr *e;
CHECK_PARSE(e, "(1 + 2) * 3");
CHECK_TRUE(e->Eval() == 9);
CHECK_PARSE(e, "1 + (2 * 3)");
CHECK_TRUE(e->Eval() == 7);
}
TEST_CASE(functions) {
Expr *e;
CHECK_PARSE(e, "sqrt(2)");
CHECK_EQ_EPS(e->Eval(), 1.414213);
CHECK_PARSE(e, "square(3)");
CHECK_EQ_EPS(e->Eval(), 9);
CHECK_PARSE(e, "sin(180)");
CHECK_EQ_EPS(e->Eval(), 0);
CHECK_PARSE(e, "sin(90)");
CHECK_EQ_EPS(e->Eval(), 1);
CHECK_PARSE(e, "cos(180)");
CHECK_EQ_EPS(e->Eval(), -1);
CHECK_PARSE(e, "asin(1)");
CHECK_EQ_EPS(e->Eval(), 90);
CHECK_PARSE(e, "acos(0)");
CHECK_EQ_EPS(e->Eval(), 90);
}
TEST_CASE(variable) {
Expr *e;
CHECK_PARSE(e, "Var");
CHECK_TRUE(e->op == Expr::Op::VARIABLE);
}
TEST_CASE(precedence) {
Expr *e;
CHECK_PARSE(e, "2 + 3 * 4");
CHECK_TRUE(e->Eval() == 14);
CHECK_PARSE(e, "2 - 3 / 4");
CHECK_TRUE(e->Eval() == 1.25);
CHECK_PARSE(e, "-3 + 2");
CHECK_TRUE(e->Eval() == -1);
CHECK_PARSE(e, "2 + 3 - 4");
CHECK_TRUE(e->Eval() == 1);
}
TEST_CASE(errors) {
CHECK_PARSE_ERR("\x01",
"Unexpected character");
CHECK_PARSE_ERR("notavar",
"'notavar' is not a valid variable, function or constant");
CHECK_PARSE_ERR("1e2e3",
"'1e2e3' is not a valid number");
CHECK_PARSE_ERR("_",
"'_' is not a valid operator");
CHECK_PARSE_ERR("2 2",
"Expected an operator");
CHECK_PARSE_ERR("2 + +",
"Expected an operand");
CHECK_PARSE_ERR("( 2 + 2",
"Expected ')'");
CHECK_PARSE_ERR("(",
"Expected ')'");
}
|