199 lines
4.4 KiB
Go
199 lines
4.4 KiB
Go
package expr
|
|
|
|
import "testing"
|
|
|
|
func TestIntArithmetic(t *testing.T) {
|
|
cases := []struct {
|
|
expr string
|
|
expected int64
|
|
}{
|
|
{"+10", 10},
|
|
{"-10", -10},
|
|
{"3 + 4 + 5 + 6 * 7 + 8", 62},
|
|
{"3 + 4 + (5 + 6) * 7 + 8", 92},
|
|
{"3 + 4 + (5 + 6) * 7 / 11 + 8", 22},
|
|
{"3 + 4 + -5 * 6 / 7 % 8", 3},
|
|
{"10 - 5", 5},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
expr, e := Compile(c.expr)
|
|
if e != nil {
|
|
t.Errorf("failed to compile expression '%s': %s", c.expr, e.Error())
|
|
}
|
|
if res := expr.Eval(nil); res.(int64) != c.expected {
|
|
t.Errorf("result for expression '%s' is %v, but expected is %v", c.expr, res, c.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFloatArithmetic(t *testing.T) {
|
|
cases := []struct {
|
|
expr string
|
|
expected float64
|
|
}{
|
|
{"+10.5", 10.5},
|
|
{"-10.5", -10.5},
|
|
{"3.1 + 4.2 + 5 + 6 * 7 + 8", 62.3},
|
|
{"3.1 + 4.2 + (5 + 6) * 7 + 8.3", 92.6},
|
|
{"3.1 + 4.2 + (5.1 + 5.9) * 7 / 11 + 8", 22.3},
|
|
{"3.3 + 4.2 - 4.0 * 7.5 / 3", -2.5},
|
|
{"3.3 + 4.2 - 4 * 7.0 / 2", -6.5},
|
|
{"3.5/2.0", 1.75},
|
|
{"3.5/2", 1.75},
|
|
{"7 / 3.5", 2},
|
|
{"3.5 % 2.0", 1.5},
|
|
{"3.5 % 2", 1.5},
|
|
{"7 % 2.5", 2},
|
|
{"7.3 - 2", 5.3},
|
|
{"7 - 2.3", 4.7},
|
|
{"1 + 1.5", 2.5},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
expr, e := Compile(c.expr)
|
|
if e != nil {
|
|
t.Errorf("failed to compile expression '%s': %s", c.expr, e.Error())
|
|
}
|
|
if res := expr.Eval(nil); res.(float64) != c.expected {
|
|
t.Errorf("result for expression '%s' is %v, but expected is %v", c.expr, res, c.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVariable(t *testing.T) {
|
|
variables := map[string]interface{}{
|
|
"a": int64(6),
|
|
"b": int64(7),
|
|
}
|
|
env := func(key string) interface{} {
|
|
return variables[key]
|
|
}
|
|
|
|
cases := []struct {
|
|
expr string
|
|
expected int64
|
|
}{
|
|
{"3 + 4 + (+5) + a * b + 8", 62},
|
|
{"3 + 4 + (5 + a) * b + 8", 92},
|
|
{"3 + 4 + (5 + a) * b / 11 + 8", 22},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
expr, e := Compile(c.expr)
|
|
if e != nil {
|
|
t.Errorf("failed to compile expression '%s': %s", c.expr, e.Error())
|
|
}
|
|
if res := expr.Eval(env); res.(int64) != c.expected {
|
|
t.Errorf("result for expression '%s' is %v, but expected is %v", c.expr, res, c.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFunction(t *testing.T) {
|
|
variables := map[string]interface{}{
|
|
"a": int64(6),
|
|
"b": 7.0,
|
|
}
|
|
|
|
env := func(key string) interface{} {
|
|
return variables[key]
|
|
}
|
|
|
|
cases := []struct {
|
|
expr string
|
|
expected float64
|
|
}{
|
|
{"sum(3, 4, 5, a * b, 8)", 62},
|
|
{"sum(3, 4, (5 + a) * b, 8)", 92},
|
|
{"sum(3, 4, (5 + a) * b / 11, 8)", 22},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
expr, e := Compile(c.expr)
|
|
if e != nil {
|
|
t.Errorf("failed to compile expression '%s': %s", c.expr, e.Error())
|
|
}
|
|
if res := expr.Eval(env); res.(float64) != c.expected {
|
|
t.Errorf("result for expression '%s' is %v, but expected is %v", c.expr, res, c.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLogical(t *testing.T) {
|
|
cases := []struct {
|
|
expr string
|
|
expected bool
|
|
}{
|
|
{"true", true},
|
|
{"false", false},
|
|
{"true == true", true},
|
|
{"true == false", false},
|
|
{"true != true", false},
|
|
{"true != false", true},
|
|
{"5 > 3", true},
|
|
{"5 < 3", false},
|
|
{"5.2 > 3", true},
|
|
{"5.2 < 3", false},
|
|
{"5 > 3.1", true},
|
|
{"5 < 3.1", false},
|
|
{"5.1 > 3.3", true},
|
|
{"5.1 < 3.3", false},
|
|
{"5 >= 3", true},
|
|
{"5 <= 3", false},
|
|
{"5.2 >= 3", true},
|
|
{"5.2 <= 3", false},
|
|
{"5 >= 3.1", true},
|
|
{"5 <= 3.1", false},
|
|
{"5.1 >= 3.3", true},
|
|
{"5.1 <= 3.3", false},
|
|
{"5 != 3", true},
|
|
{"5.2 != 3.2", true},
|
|
{"5.2 != 3", true},
|
|
{"5 != 3.2", true},
|
|
{"5 == 3", false},
|
|
{"5.2 == 3.2", false},
|
|
{"5.2 == 3", false},
|
|
{"5 == 3.2", false},
|
|
{"!(5 > 3)", false},
|
|
{"5>3 && 3>1", true},
|
|
{"5<3 || 3<1", false},
|
|
{"4<=4 || 3<1", true},
|
|
{"4<4 || 3>=1", true},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
expr, e := Compile(c.expr)
|
|
if e != nil {
|
|
t.Errorf("failed to compile expression '%s': %s", c.expr, e.Error())
|
|
}
|
|
if res := expr.Eval(nil); res.(bool) != c.expected {
|
|
t.Errorf("result for expression '%s' is %v, but expected is %v", c.expr, res, c.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBitwise(t *testing.T) {
|
|
cases := []struct {
|
|
expr string
|
|
expected int64
|
|
}{
|
|
{"0x0C & 0x04", 0x04},
|
|
{"0x08 | 0x04", 0x0C},
|
|
{"0x0C ^ 0x04", 0x08},
|
|
{"0x01 << 2", 0x04},
|
|
{"0x04 >> 2", 0x01},
|
|
{"~0x04", ^0x04},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
expr, e := Compile(c.expr)
|
|
if e != nil {
|
|
t.Errorf("failed to compile expression '%s': %s", c.expr, e.Error())
|
|
}
|
|
if res := expr.Eval(nil); res.(int64) != c.expected {
|
|
t.Errorf("result for expression '%s' is 0x%X, but expected is 0x%X", c.expr, res, c.expected)
|
|
}
|
|
}
|
|
}
|