OpenDiablo2/d2common/d2calculation/d2parser/parser_test.go

296 lines
5.4 KiB
Go

package d2parser
import (
"math"
"math/rand"
"testing"
)
func TestEmptyInput(t *testing.T) {
parser := New()
table := []struct {
expr string
result int
}{
{"", 0},
{" ", 0},
{"\t\t \t\t \t", 0},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if res != row.result {
t.Errorf("Expression %v gave wrong result, got %d, want %d", row.expr, res, row.result)
}
}
}
func TestConstantExpression(t *testing.T) {
parser := New()
table := []struct {
expr string
result int
}{
{"0", 0},
{"5", 5},
{"455", 455},
{"789", 789},
{"3242", 3242},
{"45454", 45454},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if res != row.result {
t.Errorf("Expression %v gave wrong result, got %d, want %d", row.expr, res, row.result)
}
}
}
func TestUnaryOperations(t *testing.T) {
parser := New()
table := []struct {
expr string
result int
}{
{"+0", 0},
{"-0", 0},
{"+455", 455},
{"++455", 455},
{"+++455", 455},
{"-455", -455},
{"--455", 455},
{"---455", -455},
{"+-+789", -789},
{"-++3242", -3242},
{"++--+-+45454", -45454},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if res != row.result {
t.Errorf("Expression %v gave wrong result, got %d, want %d", row.expr, res, row.result)
}
}
}
func TestArithmeticBinaryOperations(t *testing.T) {
parser := New()
table := []struct {
expr string
result int
}{
{"1 + 2", 3},
{"54+56", 54 + 56},
{"9212-2121", 9212 - 2121},
{"1+2-5", -2},
{"5-3-1", 1},
{"4*5", 20},
{"512/2", 256},
{"10/9", 1},
{"1/3*5", 0},
{"2^3^2", int(math.Pow(2., 9.))},
{"4^2*2+1", 33},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if res != row.result {
t.Errorf("Expression %v gave wrong result, got %d, want %d", row.expr, res, row.result)
}
}
}
func TestParentheses(t *testing.T) {
parser := New()
table := []struct {
expr string
result int
}{
{"(1+2)*5", 15},
{"(99-98)/2", 0},
{"((3+2)*6)/3", 10},
{"(3+2)*(6/3)", 10},
{"(20+10)/6/5", 1},
{"(20+10)/(6/5)", 30},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if res != row.result {
t.Errorf("Expression %v gave wrong result, got %d, want %d", row.expr, res, row.result)
}
}
}
func TestLackFinalParethesis(t *testing.T) {
parser := New()
table := []struct {
expr string
result int
}{
{"(3+2)*(6/3", 10},
{"(20+10)/(6/5", 30},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if res != row.result {
t.Errorf("Expression %v gave wrong result, got %d, want %d", row.expr, res, row.result)
}
}
}
func TestLogicalBinaryOperations(t *testing.T) {
parser := New()
table := []struct {
expr string
result bool
}{
{"1 < 2", true},
{"1 < -5", false},
{"1 <= 5", true},
{"1 <= 10", true},
{"5 <= 1", false},
{"1 <= 1", true},
{"5 > 10", false},
{"54 >= 100", false},
{"45 >= 45", true},
{"10 == 10", true},
{"10 == 1", false},
{"10 != 1", true},
{"10 != 10", false},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if (res == 0 && row.result) || (res != 0 && !row.result) {
t.Errorf("Expression %v gave wrong result, got %d, want %v", row.expr, res, row.result)
}
}
}
func TestLogicalAndArithmetic(t *testing.T) {
parser := New()
table := []struct {
expr string
result bool
}{
{"(1 < 2)*(5 < 10)", true},
{"(1 < -5)+(1 == 5)", false},
{"(5 > 10)*(10 == 10)", false},
{"(45 >= 45)+(1 > 500000)", true},
{"(10 == 10)*(30 > 50)+(5 >= 5)", true},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if (res == 0 && row.result) || (res != 0 && !row.result) {
t.Errorf("Expression %v gave wrong result, got %d, want %v", row.expr, res, row.result)
}
}
}
func TestTernaryOperator(t *testing.T) {
parser := New()
table := []struct {
expr string
result int
}{
{"5 > 1 ? 3 : 5", 3},
{"5 <= 1 ? 3 : 5", 5},
{"(1 < 10)*(5 < 3) ? 43 : 5 == 5 ? 1 : 2", 1},
{"(1 < 10)*(5 < 3) ? 43 : 5 != 5 ? 1 : 2", 2},
{"(1 < 10)*(5 > 3) ? 43 : 5 == 5 ? 1 : 2", 43},
{"(1 < 10)*(5 > 3) ? 43 != 0 ? 65 : 32 : 5 == 5 ? 1 : 2", 65},
{"(1 < 10)*(5 > 3) ? 43 == 0 ? 65 : 32 : 5 == 5 ? 1 : 2", 32},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if res != row.result {
t.Errorf("Expression %v gave wrong result, got %d, want %d", row.expr, res, row.result)
}
}
}
func TestBuiltinFunctions(t *testing.T) {
parser := New()
table := []struct {
expr string
result int
}{
{"min(5, 2)", 2},
{"min(4^6, 5+10)", 15},
{"max(10, 4*3)", 12},
{"max(50-2, 50-3)", 48},
}
for _, row := range table {
c := parser.Parse(row.expr)
res := c.Eval()
if res != row.result {
t.Errorf("Expression %v gave wrong result, got %d, want %d", row.expr, res, row.result)
}
}
}
func TestRandFunction(t *testing.T) {
parser := New()
c := parser.Parse("rand(1,5)")
rand.Seed(1)
res1 := []int{c.Eval(), c.Eval(), c.Eval(), c.Eval(), c.Eval()}
rand.Seed(1)
res2 := []int{c.Eval(), c.Eval(), c.Eval(), c.Eval(), c.Eval()}
for i := 0; i < len(res1); i++ {
t.Logf("%d, %d", res1[i], res2[i])
if res1[i] != res2[i] {
t.Error("Results not equal.")
}
}
}
func BenchmarkSimpleExpression(b *testing.B) {
parser := New()
expr := "(1 < 10)*(5 > 3) ? 43 == 0 ? 65 : 32 : 5 == 5 ? 1 : 2"
for n := 0; n < b.N; n++ {
parser.Parse(expr)
}
}