forgot to add the array module. Separated tests on array and list from operators

This commit is contained in:
2026-07-14 06:49:50 +02:00
parent 6b561fea45
commit bf2c7df0f0
3 changed files with 242 additions and 99 deletions
+17 -56
View File
@@ -11,62 +11,6 @@ import (
"git.portale-stac.it/go-pkg/expr/types/list"
)
func TestArray(t *testing.T) {
section := "Array"
inputs := []inputType{
/* 1 */ {`[]`, array.NewArrayA(), nil},
/* 2 */ {`[1,2,3]`, array.NewArrayA(int64(1), int64(2), int64(3)), nil},
/* 3 */ {`[1,2,"hello"]`, array.NewArrayA(int64(1), int64(2), "hello"), nil},
/* 4 */ {`[1+2, not true, "hello"]`, array.NewArrayA(int64(3), false, "hello"), nil},
/* 5 */ {`[1,2]+[3]`, array.NewArrayA(int64(1), int64(2), int64(3)), nil},
/* 6 */ {`[1,4,3,2]-[3]`, array.NewArrayA(int64(1), int64(4), int64(2)), nil},
/* 7 */ {`builtin "math.arith"; add([1,4,3,2])`, int64(10), nil},
/* 8 */ {`builtin "math.arith"; add([1,[2,2],3,2])`, int64(10), nil},
/* 9 */ {`builtin "math.arith"; mul([1,4,3.0,2])`, float64(24.0), nil},
/* 10 */ {`builtin "math.arith"; add([1,"hello"])`, nil, `add(): param nr 2 (2 in 1) has wrong type string, number expected`},
/* 11 */ {`[a=1,b=2,c=3] but a+b+c`, int64(6), nil},
/* 12 */ {`[1,2,3] <+ 2+2`, array.NewArrayA(int64(1), int64(2), int64(3), int64(4)), nil},
/* 13 */ {`2-1 +> [2,3]`, array.NewArrayA(int64(1), int64(2), int64(3)), nil},
/* 14 */ {`[1,2,3][1]`, int64(2), nil},
/* 15 */ {`ls=[1,2,3] but ls[1]`, int64(2), nil},
/* 16 */ {`ls=[1,2,3] but ls[-1]`, int64(3), nil},
/* 17 */ {`list=["one","two","three"]; list[10]`, nil, `[1:34] index 10 out of bounds`},
/* 18 */ {`["a", "b", "c"]`, array.NewArrayA("a", "b", "c"), nil},
/* 19 */ {`["a", "b", "c"]`, array.NewArray([]any{"a", "b", "c"}), nil},
/* 20 */ {`#["a", "b", "c"]`, int64(3), nil},
/* 21 */ {`"b" in ["a", "b", "c"]`, true, nil},
/* 22 */ {`a=[1,2]; (a)<+3`, array.NewArrayA(int64(1), int64(2), int64(3)), nil},
/* 23 */ {`a=[1,2]; (a)<+3; a`, array.NewArrayA(int64(1), int64(2)), nil},
/* 24 */ {`["a","b","c","d"][1]`, "b", nil},
/* 25 */ {`["a","b","c","d"][1,1]`, nil, `[1:19] one index only is allowed`},
/* 26 */ {`[0,1,2,3,4][:]`, array.NewArrayA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil},
/* 27 */ {`["a", "b", "c"] <+ ;`, nil, `[1:18] infix operator "<+" requires two non-nil operands, got 1`},
/* 28 */ {`2 << 3;`, int64(16), nil},
/* 29 */ {`but +> ["a", "b", "c"]`, nil, `[1:6] infix operator "+>" requires two non-nil operands, got 0`},
/* 30 */ {`2 >> 3;`, int64(0), nil},
/* 31 */ {`a=[1,2]; a<+3`, array.NewArrayA(int64(1), int64(2), int64(3)), nil},
/* 32 */ {`a=[1,2]; 5+>a`, array.NewArrayA(int64(5), int64(1), int64(2)), nil},
/* 33 */ {`L=[1,2]; L[0]=9; L`, array.NewArrayA(int64(9), int64(2)), nil},
/* 34 */ {`L=[1,2]; L[5]=9; L`, nil, `index 5 out of bounds (0, 1)`},
/* 35 */ {`L=[1,2]; L[]=9; L`, nil, `[1:12] index/key specification expected, got [] [array]`},
/* 36 */ {`L=[1,2]; L[nil]=9;`, nil, `[1:12] index/key is nil`},
/* 37 */ {`[0,1,2,3,4][2:3]`, array.NewArrayA(int64(2)), nil},
/* 38 */ {`[0,1,2,3,4][3:-1]`, array.NewArrayA(int64(3)), nil},
/* 30 */ {`[0,1,2,3,4][-3:-1]`, array.NewArrayA(int64(2), int64(3)), nil},
/* 40 */ {`[0,1,2,3,4][0:]`, array.NewArrayA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil},
/* 41 */ {`[0] << $([1,2,3,4])`, array.NewArrayA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil},
/* 42 */ {`L=[]; [1] >> L; L`, array.NewArrayA(), nil},
/* 43 */ {`L=[]; L << [1]; L`, array.NewArrayA(), nil},
// /* 44 */ {`[0,1,2,3,4][2:3]`, kern.NewListA(int64(20)), nil},
}
// t.Setenv("EXPR_PATH", ".")
// runTestSuiteSpec(t, section, inputs, 44)
RunTestSuite(t, section, inputs)
}
func TestLinkedListParser(t *testing.T) {
section := "Linked-List"
@@ -89,3 +33,20 @@ func TestLinkedListParser(t *testing.T) {
// runTestSuiteSpec(t, section, inputs, 4)
RunTestSuite(t, section, inputs)
}
func TestLinkedInsert(t *testing.T) {
section := "LinkedList-Insert"
inputs := []inputType{
/* 1 */ {`[<>] << 1`, list.NewLinkedListA(1), nil},
/* 2 */ {`[<>] << [1,2]`, list.NewLinkedListA(array.NewArrayA(int64(1), int64(2))), nil},
/* 3 */ {`[<>] << [<1,2>]`, list.NewLinkedListA(list.NewLinkedListA(1, 2)), nil},
/* 4 */ {`1 >> [<>]`, list.NewLinkedListA(1), nil},
/* 5 */ {`[1,2] >> [<>]`, list.NewLinkedListA(array.NewArrayA(int64(1), int64(2))), nil},
/* 6 */ {`[<1,2>] >> [<>]`, list.NewLinkedListA(list.NewLinkedListA(1, 2)), nil},
/* 7 */ {`$([1,2]) >> [<>]`, list.NewLinkedListA(1, 2), nil},
/* 8 */ {`$([<1,2>]) >> [<>]`, list.NewLinkedListA(1, 2), nil},
}
// runTestSuiteSpec(t, section, inputs, 9)
RunTestSuite(t, section, inputs)
}
-43
View File
@@ -9,7 +9,6 @@ import (
"git.portale-stac.it/go-pkg/expr/types/array"
"git.portale-stac.it/go-pkg/expr/types/dict"
"git.portale-stac.it/go-pkg/expr/types/list"
)
func TestOperator(t *testing.T) {
@@ -51,48 +50,6 @@ func TestOperator(t *testing.T) {
RunTestSuite(t, section, inputs)
}
func TestOperatorInsert(t *testing.T) {
section := "Operator-Insert"
inputs := []inputType{
/* 1 */ {`["a", "b"] << nil`, array.NewArrayA("a", "b"), nil},
/* 2 */ {`["a", "b"] << []`, array.NewArrayA("a", "b", array.NewArrayA()), nil},
/* 3 */ {`["a", "b"] << $([])`, array.NewArrayA("a", "b"), nil},
/* 4 */ {`["a", "b"] << 3`, array.NewArrayA("a", "b", int64(3)), nil},
/* 5 */ {`3 << ["a", "b"]`, nil, `[1:5] left operand '3' [integer] and right operand '["a", "b"]' [array] are not compatible with operator "<<"`},
/* 6 */ {`nil >> ["a", "b"]`, array.NewArrayA("a", "b"), nil},
/* 7 */ {`[] >> ["a", "b"]`, array.NewArrayA(array.NewArrayA(), "a", "b"), nil},
/* 8 */ {`$([]) >> ["a", "b"]`, array.NewArrayA("a", "b"), nil},
/* 9 */ {`["a", "b"] << $([1,2,3])`, array.NewArrayA("a", "b", int64(1), int64(2), int64(3)), nil},
/* 10 */ {`L=["a", "b"]; L << $([1,2,3])`, array.NewArrayA("a", "b", int64(1), int64(2), int64(3)), nil},
/* 11 */ {`L=["a", "b"]; L << $([1,2,3]); L`, array.NewArrayA("a", "b"), nil},
/* 12 */ {`L << $([1,2,3])`, nil, `undefined variable or function "L"`},
/* 13 */ {`[<>] << 1`, list.NewLinkedListA(1), nil},
/* 14 */ {`[<>] << [1,2]`, list.NewLinkedListA(array.NewArrayA(int64(1), int64(2))), nil},
/* 15 */ {`[<>] << [<1,2>]`, list.NewLinkedListA(list.NewLinkedListA(1, 2)), nil},
/* 16 */ {`1 >> [<>]`, list.NewLinkedListA(1), nil},
/* 17 */ {`[1,2] >> [<>]`, list.NewLinkedListA(array.NewArrayA(int64(1), int64(2))), nil},
/* 18 */ {`[<1,2>] >> [<>]`, list.NewLinkedListA(list.NewLinkedListA(1, 2)), nil},
/* 19 */ {`$([1,2]) >> [<>]`, list.NewLinkedListA(1, 2), nil},
/* 20 */ {`$([<1,2>]) >> [<>]`, list.NewLinkedListA(1, 2), nil},
}
// runTestSuiteSpec(t, section, inputs, 9)
RunTestSuite(t, section, inputs)
}
func TestOperatorDeepAssign(t *testing.T) {
section := "Operator-DeepAssign"
inputs := []inputType{
/* 1 */ {`DD={"uno": 1, "due": 2}; D=DD; D["uno"]=11; DD`, dict.NewDict(map[any]any{"uno": int64(11), "due": int64(2)}), nil},
/* 2 */ {`DD={"uno": 1, "due": 2}; D:=DD; D["uno"]=11; DD`, dict.NewDict(map[any]any{"uno": int64(1), "due": int64(2)}), nil},
/* 3 */ {`LL=["a", "b"]; L=LL; L[0]="x"; LL`, array.NewArrayA("x", "b"), nil},
/* 4 */ {`LL=["a", "b"]; L:=LL; L[0]="x"; LL`, array.NewArrayA("a", "b"), nil},
}
// runTestSuiteSpec(t, section, inputs, 4)
RunTestSuite(t, section, inputs)
}
func TestOperatorDigest(t *testing.T) {
section := "Operator-Digest"
inputs := []inputType{
+225
View File
@@ -0,0 +1,225 @@
// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// array-type.go
package array
import (
"fmt"
"strings"
"git.portale-stac.it/go-pkg/expr/kern"
)
type ArrayType []any
func IsArray(v any) (ok bool) {
_, ok = v.(*ArrayType)
return ok
}
func NewArrayA(listAny ...any) (list *ArrayType) {
if listAny == nil {
listAny = []any{}
}
return NewArray(listAny)
}
func NewArray(arrayAny []any) (aRef *ArrayType) {
if arrayAny != nil {
a := make(ArrayType, len(arrayAny))
copy(a, arrayAny)
aRef = &a
}
return
}
func MakeArray(length, capacity int) (list *ArrayType) {
if capacity < length {
capacity = length
}
ls := make(ArrayType, length, capacity)
list = &ls
return
}
func ArrayFromStrings(stringSlice []string) (aRef *ArrayType) {
aRef = MakeArray(len(stringSlice), 0)
for i, s := range stringSlice {
(*aRef)[i] = s
}
return
}
func (aRef *ArrayType) ToString(opt kern.FmtOpt) (s string) {
indent := kern.GetFormatIndent(opt)
flags := kern.GetFormatFlags(opt)
var sb strings.Builder
sb.WriteByte('[')
if len(*aRef) > 0 {
innerOpt := kern.MakeFormatOptions(flags, indent+1)
nest := strings.Repeat(" ", indent+1)
if flags&kern.MultiLine != 0 {
sb.WriteByte('\n')
sb.WriteString(nest)
}
for i, item := range []any(*aRef) {
if i > 0 {
if flags&kern.MultiLine != 0 {
sb.WriteString(",\n")
sb.WriteString(nest)
} else {
sb.WriteString(", ")
}
}
kern.Format(&sb, item, innerOpt)
}
if flags&kern.MultiLine != 0 {
sb.WriteByte('\n')
sb.WriteString(strings.Repeat(" ", indent))
}
}
sb.WriteByte(']')
s = sb.String()
if flags&kern.Truncate != 0 && len(s) > kern.TruncateSize {
s = kern.TruncateString(s)
}
return
}
func (aRef *ArrayType) String() string {
return aRef.ToString(0)
}
func (aRef *ArrayType) TypeName() string {
return kern.TypeArray
}
func (aRef *ArrayType) Contains(t *ArrayType) (answer bool) {
if len(*aRef) >= len(*t) {
answer = true
for _, item := range *t {
if answer = aRef.IndexDeepSameCmp(item) >= 0; !answer {
break
}
}
}
return
}
func (aRef *ArrayType) EqualTo(other kern.Equaler) (equal bool) {
if otherList, ok := other.(*ArrayType); ok {
equal = aRef.Equals(*otherList)
}
return
}
func (aRef *ArrayType) Equals(ls2 ArrayType) (answer bool) {
if ls2 != nil && len(*aRef) == len(ls2) {
answer = true
for index, i1 := range *aRef {
// if !reflect.DeepEqual(i1, ls2[index]) {
// answer = false
// break
// }
if !kern.Equal(i1, ls2[index]) {
answer = false
break
}
}
}
return
}
func (aRef *ArrayType) Clone() kern.Cloner {
ls := make(ArrayType, len(*aRef))
for i, item := range *aRef {
ls[i] = kern.Clone(item)
}
return &ls
}
func (aRef *ArrayType) IndexDeepSameCmp(target any) (index int64) {
index = -1
for i, item := range *aRef {
if kern.Equal(item, target) {
index = int64(i)
break
}
}
return
}
// func (ls *ListType) IndexDeepSameCmp(target any) (index int) {
// var eq bool
// var err error
// index = -1
// for i, item := range *ls {
// if eq, err = deepSame(item, target, SameContent); err != nil {
// break
// } else if eq {
// index = i
// break
// }
// }
// return
// }
func SameContent(a, b any) (same bool, err error) {
aRef, aValid := a.(*ArrayType)
bRef, bValid := b.(*ArrayType)
if !aValid || !bValid {
err = fmt.Errorf("invalid type for comparison")
return
}
if len(*aRef) == len(*bRef) {
same = true
for _, item := range *aRef {
if pos := bRef.IndexDeepSameCmp(item); pos < 0 {
same = false
break
}
}
}
return
}
// func deepSame(a, b any, deepCmp kern.DeepFuncTemplate) (eq bool, err error) {
// if IsNumOrFract(a) && IsNumOrFract(b) {
// if IsNumber(a) && IsNumber(b) {
// if IsInteger(a) && IsInteger(b) {
// li, _ := a.(int64)
// ri, _ := b.(int64)
// eq = li == ri
// } else {
// eq = NumAsFloat(a) == NumAsFloat(b)
// }
// } else {
// var cmp int
// if cmp, err = fract.CmpAnyFract(a, b); err == nil {
// eq = cmp == 0
// }
// }
// } else if deepCmp != nil && IsList(a) && IsList(b) {
// eq, err = deepCmp(a, b)
// } else {
// eq = reflect.DeepEqual(a, b)
// }
// return
// }
func (aRef *ArrayType) SetItem(index int64, value any) (err error) {
if index >= 0 && index < int64(len(*aRef)) {
(*aRef)[index] = value
} else {
err = fmt.Errorf("index %d out of bounds (0, %d)", index, len(*aRef)-1)
}
return
}
func (aRef *ArrayType) AppendItem(value any) {
*aRef = append(*aRef, value)
}