Compare commits
3 Commits
91fdc1926e
...
c39970fa7e
Author | SHA1 | Date | |
---|---|---|---|
c39970fa7e | |||
14bb9e942b | |||
9451958218 |
@ -27,6 +27,7 @@ func TestDictParser(t *testing.T) {
|
|||||||
/* 4 */ {`{1:"one",2:"two",3:"three"}.2`, "three", nil},
|
/* 4 */ {`{1:"one",2:"two",3:"three"}.2`, "three", nil},
|
||||||
/* 5 */ {`#{1:"one",2:"two",3:"three"}`, int64(3), nil},
|
/* 5 */ {`#{1:"one",2:"two",3:"three"}`, int64(3), nil},
|
||||||
/* 6 */ {`{1:"one"} + {2:"two"}`, map[any]any{1: "one", 2: "two"}, nil},
|
/* 6 */ {`{1:"one"} + {2:"two"}`, map[any]any{1: "one", 2: "two"}, nil},
|
||||||
|
/* 7 */ {`2 in {1:"one", 2:"two"}`, true, nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
succeeded := 0
|
succeeded := 0
|
||||||
|
@ -40,6 +40,7 @@ func TestListParser(t *testing.T) {
|
|||||||
/* 18 */ {`["a", "b", "c"]`, newListA("a", "b", "c"), nil},
|
/* 18 */ {`["a", "b", "c"]`, newListA("a", "b", "c"), nil},
|
||||||
/* 19 */ {`["a", "b", "c"]`, newList([]any{"a", "b", "c"}), nil},
|
/* 19 */ {`["a", "b", "c"]`, newList([]any{"a", "b", "c"}), nil},
|
||||||
/* 20 */ {`#["a", "b", "c"]`, int64(3), nil},
|
/* 20 */ {`#["a", "b", "c"]`, int64(3), nil},
|
||||||
|
/* 21 */ {`"b" in ["a", "b", "c"]`, true, nil},
|
||||||
|
|
||||||
// /* 8 */ {`[int(x)|x=csv("test.csv",1,all(),1)]`, []any{int64(10), int64(40), int64(20)}, nil},
|
// /* 8 */ {`[int(x)|x=csv("test.csv",1,all(),1)]`, []any{int64(10), int64(40), int64(20)}, nil},
|
||||||
// /* 9 */ {`sum(@[int(x)|x=csv("test.csv",1,all(),1)])`, []any{int64(10), int64(40), int64(20)}, nil},
|
// /* 9 */ {`sum(@[int(x)|x=csv("test.csv",1,all(),1)])`, []any{int64(10), int64(40), int64(20)}, nil},
|
||||||
@ -58,8 +59,8 @@ func TestListParser(t *testing.T) {
|
|||||||
var gotErr error
|
var gotErr error
|
||||||
|
|
||||||
ctx := NewSimpleFuncStore()
|
ctx := NewSimpleFuncStore()
|
||||||
ctx.SetVar("var1", int64(123))
|
// ctx.SetVar("var1", int64(123))
|
||||||
ctx.SetVar("var2", "abc")
|
// ctx.SetVar("var2", "abc")
|
||||||
ImportMathFuncs(ctx)
|
ImportMathFuncs(ctx)
|
||||||
parser := NewParser(ctx)
|
parser := NewParser(ctx)
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ package expr
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -61,6 +62,16 @@ func newList(listAny []any) (list *ListType) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (list *ListType) indexDeepCmp(target any) (index int) {
|
||||||
|
index = -1
|
||||||
|
for i, item := range *list {
|
||||||
|
if reflect.DeepEqual(item, target) {
|
||||||
|
index = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// -------- list term
|
// -------- list term
|
||||||
func newListTermA(args ...*term) *term {
|
func newListTermA(args ...*term) *term {
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
// operand-fraction.go
|
// operand-fraction.go
|
||||||
package expr
|
package expr
|
||||||
|
|
||||||
|
//https://www.youmath.it/lezioni/algebra-elementare/lezioni-di-algebra-e-aritmetica-per-scuole-medie/553-dalle-frazioni-a-numeri-decimali.html
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
46
operator-in.go
Normal file
46
operator-in.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// operator-in.go
|
||||||
|
package expr
|
||||||
|
|
||||||
|
//-------- in term
|
||||||
|
|
||||||
|
func newInTerm(tk *Token) (inst *term) {
|
||||||
|
return &term{
|
||||||
|
tk: *tk,
|
||||||
|
children: make([]*term, 0, 2),
|
||||||
|
position: posInfix,
|
||||||
|
priority: priRelational,
|
||||||
|
evalFunc: evalIn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasKey(d map[any]any, target any) (ok bool) {
|
||||||
|
_, ok = d[target]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func evalIn(ctx ExprContext, self *term) (v any, err error) {
|
||||||
|
var leftValue, rightValue any
|
||||||
|
|
||||||
|
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsList(rightValue) {
|
||||||
|
list, _ := rightValue.(*ListType)
|
||||||
|
v = list.indexDeepCmp(leftValue) >= 0
|
||||||
|
} else if IsDict(rightValue) {
|
||||||
|
d, _ := rightValue.(map[any]any)
|
||||||
|
v = hasKey(d, leftValue)
|
||||||
|
} else {
|
||||||
|
err = self.errIncompatibleTypes(leftValue, rightValue)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// init
|
||||||
|
func init() {
|
||||||
|
registerTermConstructor(SymKwIn, newInTerm)
|
||||||
|
}
|
@ -99,6 +99,7 @@ const (
|
|||||||
SymKwBut
|
SymKwBut
|
||||||
SymKwFunc
|
SymKwFunc
|
||||||
SymKwBuiltin
|
SymKwBuiltin
|
||||||
|
SymKwIn
|
||||||
SymKwInclude
|
SymKwInclude
|
||||||
SymKwNil
|
SymKwNil
|
||||||
)
|
)
|
||||||
@ -112,6 +113,7 @@ func init() {
|
|||||||
"BUILTIN": SymKwBuiltin,
|
"BUILTIN": SymKwBuiltin,
|
||||||
"BUT": SymKwBut,
|
"BUT": SymKwBut,
|
||||||
"FUNC": SymKwFunc,
|
"FUNC": SymKwFunc,
|
||||||
|
"IN": SymKwIn,
|
||||||
"INCLUDE": SymKwInclude,
|
"INCLUDE": SymKwInclude,
|
||||||
"NOT": SymKwNot,
|
"NOT": SymKwNot,
|
||||||
"OR": SymKwOr,
|
"OR": SymKwOr,
|
||||||
|
@ -31,6 +31,7 @@ func TestGetRoom(t *testing.T) {
|
|||||||
t.Errorf("err: got <%v>, want <nil>", gotErr)
|
t.Errorf("err: got <%v>, want <nil>", gotErr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetChildrenCount(t *testing.T) {
|
func TestGetChildrenCount(t *testing.T) {
|
||||||
tk1 := NewValueToken(0, 0, SymInteger, "100", 100)
|
tk1 := NewValueToken(0, 0, SymInteger, "100", 100)
|
||||||
|
|
||||||
|
139
utils_test.go
Normal file
139
utils_test.go
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// utils_test.go
|
||||||
|
package expr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIsString(t *testing.T) {
|
||||||
|
count := 0
|
||||||
|
succeeded := 0
|
||||||
|
failed := 0
|
||||||
|
|
||||||
|
count++
|
||||||
|
if !IsBool(true) {
|
||||||
|
t.Errorf("%d: IsBool(true) -> result = false, want true", count)
|
||||||
|
failed++
|
||||||
|
} else {
|
||||||
|
succeeded++
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
if !IsString("abc") {
|
||||||
|
t.Errorf("%d: IsString(\"abc\") -> result = false, want true", count)
|
||||||
|
failed++
|
||||||
|
} else {
|
||||||
|
succeeded++
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
if !IsInteger(int64(123)) {
|
||||||
|
t.Errorf("%d: IsInteger(123) -> result = false, want true", count)
|
||||||
|
failed++
|
||||||
|
} else {
|
||||||
|
succeeded++
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
if !IsFloat(1.23) {
|
||||||
|
t.Errorf("%d: IsFloat(1.23) -> result = false, want true", count)
|
||||||
|
failed++
|
||||||
|
} else {
|
||||||
|
succeeded++
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
if !IsFloat(numAsFloat(123)) {
|
||||||
|
t.Errorf("%d: IsFloat(numAsFloat(123)) -> result = false, want true", count)
|
||||||
|
failed++
|
||||||
|
} else {
|
||||||
|
succeeded++
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
b, ok := toBool(true)
|
||||||
|
if !(ok && b) {
|
||||||
|
t.Errorf("%d: toBool(true) b=%v, ok=%v -> result = false, want true", count, b, ok)
|
||||||
|
failed++
|
||||||
|
} else {
|
||||||
|
succeeded++
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
b, ok = toBool("abc")
|
||||||
|
if !(ok && b) {
|
||||||
|
t.Errorf("%d: toBool(\"abc\") b=%v, ok=%v -> result = false, want true", count, b, ok)
|
||||||
|
failed++
|
||||||
|
} else {
|
||||||
|
succeeded++
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("test count: %d, succeeded count: %d, failed count: %d", count, succeeded, failed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestToIntOk(t *testing.T) {
|
||||||
|
source := int64(64)
|
||||||
|
wantValue := int(64)
|
||||||
|
wantErr := error(nil)
|
||||||
|
|
||||||
|
gotValue, gotErr := toInt(source, "test")
|
||||||
|
|
||||||
|
if gotErr != nil || gotValue != wantValue {
|
||||||
|
t.Errorf("toInt(%v, \"test\") gotValue=%v, gotErr=%v -> wantValue=%v, wantErr=%v",
|
||||||
|
source, gotValue, gotErr, wantValue, wantErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestToIntErr(t *testing.T) {
|
||||||
|
source := uint64(64)
|
||||||
|
wantValue := 0
|
||||||
|
wantErr := errors.New(`test expected integer, got uint64 (64)`)
|
||||||
|
|
||||||
|
gotValue, gotErr := toInt(source, "test")
|
||||||
|
|
||||||
|
if gotErr.Error() != wantErr.Error() || gotValue != wantValue {
|
||||||
|
t.Errorf("toInt(%v, \"test\") gotValue=%v, gotErr=%v -> wantValue=%v, wantErr=%v",
|
||||||
|
source, gotValue, gotErr, wantValue, wantErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyInteger(t *testing.T) {
|
||||||
|
type inputType struct {
|
||||||
|
source any
|
||||||
|
wantValue int64
|
||||||
|
wantOk bool
|
||||||
|
}
|
||||||
|
section := "utils.anyInteger"
|
||||||
|
|
||||||
|
inputs := []inputType{
|
||||||
|
/* 1 */ {int8(-8), int64(-8), true},
|
||||||
|
/* 2 */ {int16(-16), int64(-16), true},
|
||||||
|
/* 3 */ {int32(-32), int64(-32), true},
|
||||||
|
/* 4 */ {int64(-64), int64(-64), true},
|
||||||
|
/* 5 */ {uint8(8), int64(8), true},
|
||||||
|
/* 6 */ {uint16(16), int64(16), true},
|
||||||
|
/* 7 */ {uint32(32), int64(32), true},
|
||||||
|
/* 8 */ {uint64(64), int64(64), true},
|
||||||
|
/* 9 */ {int(-1), int64(-1), true},
|
||||||
|
/* 10 */ {true, 0, false},
|
||||||
|
}
|
||||||
|
|
||||||
|
succeeded := 0
|
||||||
|
failed := 0
|
||||||
|
|
||||||
|
for i, input := range inputs {
|
||||||
|
gotValue, gotOk := anyInteger(input.source)
|
||||||
|
if gotOk != input.wantOk || gotValue != input.wantValue {
|
||||||
|
t.Errorf("%d: anyInteger(%v) -> gotOk = %t, wantOk = %t; gotValue = %v, wantValue = %v",
|
||||||
|
i+1, input.source, gotOk, input.wantOk, gotValue, input.wantValue)
|
||||||
|
failed++
|
||||||
|
} else {
|
||||||
|
succeeded++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Logf("%s -- test count: %d, succeeded: %d, failed: %d", section, len(inputs), succeeded, failed)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user