mirror of
https://github.com/romychs/Ocean-240.2-Emulator.git
synced 2026-04-21 11:03:21 +03:00
167 lines
3.9 KiB
Go
167 lines
3.9 KiB
Go
package gval
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func Test_Infix(t *testing.T) {
|
|
type subTest struct {
|
|
name string
|
|
a interface{}
|
|
b interface{}
|
|
wantRet interface{}
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
infix
|
|
subTests []subTest
|
|
}{
|
|
{
|
|
"number operator",
|
|
infix{
|
|
number: func(a, b float64) (interface{}, error) { return a * b, nil },
|
|
},
|
|
[]subTest{
|
|
{"float64 arguments", 7., 3., 21.},
|
|
{"int arguments", 7, 3, 21.},
|
|
{"string arguments", "7", "3.", 21.},
|
|
},
|
|
},
|
|
{
|
|
"number and string operator",
|
|
infix{
|
|
number: func(a, b float64) (interface{}, error) { return a + b, nil },
|
|
text: func(a, b string) (interface{}, error) { return fmt.Sprintf("%v%v", a, b), nil },
|
|
},
|
|
|
|
[]subTest{
|
|
{"float64 arguments", 7., 3., 10.},
|
|
{"int arguments", 7, 3, 10.},
|
|
{"number string arguments", "7", "3.", "73."},
|
|
{"string arguments", "hello ", "world", "hello world"},
|
|
},
|
|
},
|
|
{
|
|
"bool operator",
|
|
infix{
|
|
shortCircuit: func(a interface{}) (interface{}, bool) { return false, a == false },
|
|
boolean: func(a, b bool) (interface{}, error) { return a && b, nil },
|
|
},
|
|
|
|
[]subTest{
|
|
{"bool arguments", false, true, false},
|
|
{"number arguments", 0, true, false},
|
|
{"lower string arguments", "false", "true", false},
|
|
{"upper string arguments", "TRUE", "FALSE", false},
|
|
{"shortCircuit", false, "not a boolean", false},
|
|
},
|
|
},
|
|
{
|
|
"bool, number, text and interface operator",
|
|
infix{
|
|
number: func(a, b float64) (interface{}, error) { return a == b, nil },
|
|
boolean: func(a, b bool) (interface{}, error) { return a == b, nil },
|
|
text: func(a, b string) (interface{}, error) { return a == b, nil },
|
|
arbitrary: func(a, b interface{}) (interface{}, error) { return a == b, nil },
|
|
},
|
|
|
|
[]subTest{
|
|
{"number string and int arguments", "7", 7, true},
|
|
{"bool string and bool arguments", "true", true, true},
|
|
{"string arguments", "hello", "hello", true},
|
|
{"upper string arguments", "TRUE", "FALSE", false},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
tt.infix.initiate("<" + tt.name + ">")
|
|
builder := tt.infix.builder
|
|
for _, tt := range tt.subTests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
eval, err := builder(constant(tt.a), constant(tt.b))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
got, err := eval(context.Background(), nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(got, tt.wantRet) {
|
|
t.Fatalf("binaryOperator() eval() = %v, want %v", got, tt.wantRet)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_stageStack_push(t *testing.T) {
|
|
p := (*Parser)(nil)
|
|
tests := []struct {
|
|
name string
|
|
pres []operatorPrecedence
|
|
expect string
|
|
}{
|
|
{
|
|
"flat",
|
|
[]operatorPrecedence{1, 1, 1, 1},
|
|
"((((AB)C)D)E)",
|
|
},
|
|
{
|
|
"asc",
|
|
[]operatorPrecedence{1, 2, 3, 4},
|
|
"(A(B(C(DE))))",
|
|
},
|
|
{
|
|
"desc",
|
|
[]operatorPrecedence{4, 3, 2, 1},
|
|
"((((AB)C)D)E)",
|
|
},
|
|
{
|
|
"mixed",
|
|
[]operatorPrecedence{1, 2, 1, 1},
|
|
"(((A(BC))D)E)",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
X := int('A')
|
|
|
|
op := func(a, b Evaluable) (Evaluable, error) {
|
|
return func(c context.Context, o interface{}) (interface{}, error) {
|
|
aa, _ := a.EvalString(c, nil)
|
|
bb, _ := b.EvalString(c, nil)
|
|
s := "(" + aa + bb + ")"
|
|
return s, nil
|
|
}, nil
|
|
}
|
|
stack := stageStack{}
|
|
for _, pre := range tt.pres {
|
|
if err := stack.push(stage{p.Const(string(rune(X))), op, pre}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
X++
|
|
}
|
|
|
|
if err := stack.push(stage{p.Const(string(rune(X))), nil, 0}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if len(stack) != 1 {
|
|
t.Fatalf("stack must hold exactly one element")
|
|
}
|
|
|
|
got, _ := stack[0].EvalString(context.Background(), nil)
|
|
if got != tt.expect {
|
|
t.Fatalf("got %s but expected %s", got, tt.expect)
|
|
}
|
|
})
|
|
}
|
|
}
|