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