// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // t_dict_test.go package expr import ( "errors" "testing" "git.portale-stac.it/go-pkg/expr/kern" "git.portale-stac.it/go-pkg/expr/scan" ) func TestDictParser(t *testing.T) { section := "Dict" inputs := []inputType{ /* 1 */ {`{}`, kern.NewDict(nil), nil}, /* 2 */ {`{123}`, nil, errors.New("[1:6] expected `:`, got `}`")}, /* 3 */ {`{1:"one",2:"two",3:"three"}`, kern.NewDict(map[any]any{int64(1): "one", int64(2): "two", int64(3): "three"}), nil}, /* 4 */ {`{1:"one",2:"two",3:"three"}[3]`, "three", nil}, /* 5 */ {`#{1:"one",2:"two",3:"three"}`, int64(3), nil}, /* 6 */ {`{1:"one"} + {2:"two"}`, kern.NewDict(map[any]any{int64(1): "one", int64(2): "two"}), nil}, /* 7 */ {`2 in {1:"one", 2:"two"}`, true, nil}, /* 8 */ {`D={"a":1, "b":2}; D["a"]=9; D`, kern.NewDict(map[any]any{"a": int64(9), "b": int64(2)}), nil}, /* 9 */ {`D={"a":1, "b":2}; D["z"]=9; D`, kern.NewDict(map[any]any{"z": int64(9), "a": int64(1), "b": int64(2)}), nil}, /* 10 */ {`D={"a":1, "b":2}; D[nil]=9`, nil, errors.New(`[1:21] index/key is nil`)}, /* 11 */ {`D={"a":1, "b":2}; D["a"]`, int64(1), nil}, /* 12 */ {`m={ "a":1, //"b":2, "c":3 }`, kern.NewDict(map[any]any{"a": int64(1), "c": int64(3)}), nil}, /* 13 */ {`D={"a":1, "b":2}; D."a"`, int64(1), nil}, /* 14 */ {`D={"a":1, "b":2}; D.a`, int64(1), nil}, /* 15 */ {`D={1:"a", 2:"b", 3:"c"}; D.(1+2)`, "c", nil}, /* 16 */ {`D={1:"a"}; D.2`, nil, `[1:15] key 2 not found`}, /* 17 */ {`D={1:"a"}; D."2"`, nil, `[1:17] key "2" not found`}, /* 18 */ {`D={"a":1, "b":2}; D.a = 10; D.a`, int64(10), nil}, /* 19 */ {`k="a"; D={k: 10}`, kern.NewDict(map[any]any{"a": int64(10)}), nil}, /* 20 */ {`k=[<1,2>]; D={k: 10}`, nil, `[1:16] dict key can be integer or string, got lisked-list`}, /* 21 */ {`f=func(n){"x"+n}; d{f(5):10}`, nil, `[0:0] two adjacent operators: "d" and "{}"`}, /* 22 */ {`f=func(n){"x"+n}; d={f(5):10}`, kern.NewDict(map[any]any{"x5": int64(10)}), nil}, /* 23 */ {`f=func(n){"x"+n}; d={f(5); "z":10}`, nil, "[1:27] expected one of `:`, `}`, got `;`"}, /* 24 */ {`f=func(n){"x"+n}; d={f(5) but "z":10}`, kern.NewDict(map[any]any{"z": int64(10)}), nil}, } // runTestSuiteSpec(t, section, inputs, 23, 24) runTestSuite(t, section, inputs) } func TestAccessSubFields(t *testing.T) { section := "Dict-Assign-Item" ctx := NewSimpleStore() ctx.UnsafeSetVar( "D", kern.NewDict(map[any]any{ "a": kern.NewDict(map[any]any{"uno": int64(10)}), "b": kern.NewListA(1, 2, 3), }), ) // D={"a": {"uno":1}} inputs := []inputType{ /* 1 */ {`D.a.uno`, int64(10), nil}, /* 2 */ {`D.a.uno = 111; D.a."uno"`, int64(111), nil}, /* 3 */ {`D.a.uno = 111; D["a"]["uno"]`, int64(111), nil}, /* 4 */ {`D.b[1] = 22; D["b"][1]`, int64(22), nil}, } // runCtxTestSuiteSpec(t, ctx, section, inputs, 4) runCtxTestSuite(t, ctx, section, inputs) } func TestDictToStringMultiLine(t *testing.T) { var good bool section := "dict-ToString-ML" want := `{ "first": 1 }` args := map[any]any{ "first": newLiteralTerm(scan.NewValueToken(0, 0, scan.SymInteger, "1", 1)), } dict := kern.NewDict(args) got := dict.ToString(kern.MultiLine) // fmt.Printf("got=%q\n", got) if good = got == want; !good { t.Errorf("ToString(MultiLine): got = %q, want %q", got, want) } if good { t.Logf("%s -- succeeded", section) } else { t.Logf("%s -- failed", section) } } func TestDictToString(t *testing.T) { var good bool section := "dict-ToString-SL" want := `{"first": 1}` args := map[any]any{ "first": newLiteralTerm(scan.NewValueToken(0, 0, scan.SymInteger, "1", 1)), } dict := kern.NewDict(args) got := dict.ToString(0) // fmt.Printf("got=%q\n", got) if good = got == want; !good { t.Errorf("ToString(0): got = %q, want %q", got, want) } if good { t.Logf("%s -- succeeded", section) } else { t.Logf("%s -- failed", section) } }