package sandbox import ( "testing" "go.starlark.net/starlark" ) func TestGoToStarlark_Primitives(t *testing.T) { tests := []struct { name string in any want string // starlark.Value.String() }{ {"nil", nil, "None"}, {"bool true", true, "True"}, {"bool false", false, "False"}, {"int", 42, "42"}, {"int64", int64(99), "99"}, {"float64 integer", float64(5), "5"}, {"float64 fractional", 3.14, "3.14"}, {"string", "hello", `"hello"`}, {"unknown type", struct{}{}, `"{}"`}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := GoToStarlark(tt.in) if got.String() != tt.want { t.Errorf("GoToStarlark(%v) = %s, want %s", tt.in, got.String(), tt.want) } }) } } func TestGoToStarlark_Containers(t *testing.T) { // map[string]any m := map[string]any{"a": 1.0, "b": "two"} d := GoToStarlark(m) if _, ok := d.(*starlark.Dict); !ok { t.Fatalf("expected *starlark.Dict, got %T", d) } // []any s := []any{1.0, "x", true} l := GoToStarlark(s) if list, ok := l.(*starlark.List); !ok || list.Len() != 3 { t.Fatalf("expected *starlark.List len 3, got %T", l) } } func TestStarlarkToGo_Primitives(t *testing.T) { tests := []struct { name string in starlark.Value want any }{ {"None", starlark.None, nil}, {"True", starlark.True, true}, {"Int", starlark.MakeInt(7), int64(7)}, {"Float", starlark.Float(2.5), 2.5}, {"String", starlark.String("hi"), "hi"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := StarlarkToGo(tt.in) if got != tt.want { t.Errorf("StarlarkToGo(%s) = %v (%T), want %v (%T)", tt.in, got, got, tt.want, tt.want) } }) } } func TestStarlarkToGo_Tuple(t *testing.T) { tup := starlark.Tuple{starlark.MakeInt(1), starlark.String("a")} got := StarlarkToGo(tup) arr, ok := got.([]any) if !ok || len(arr) != 2 { t.Fatalf("expected []any len 2, got %T", got) } if arr[0] != int64(1) { t.Errorf("arr[0] = %v, want 1", arr[0]) } } func TestRoundTrip(t *testing.T) { original := map[string]any{ "name": "test", "count": float64(42), "active": true, "tags": []any{"a", "b"}, "nested": map[string]any{ "x": float64(1), }, } sv := GoToStarlark(original) back := StarlarkToGo(sv) m, ok := back.(map[string]any) if !ok { t.Fatalf("round-trip produced %T, want map[string]any", back) } if m["name"] != "test" { t.Errorf("name = %v", m["name"]) } if m["count"] != int64(42) { t.Errorf("count = %v (%T)", m["count"], m["count"]) } if m["active"] != true { t.Errorf("active = %v", m["active"]) } tags, ok := m["tags"].([]any) if !ok || len(tags) != 2 { t.Fatalf("tags = %v (%T)", m["tags"], m["tags"]) } nested, ok := m["nested"].(map[string]any) if !ok { t.Fatalf("nested = %T", m["nested"]) } if nested["x"] != int64(1) { t.Errorf("nested.x = %v", nested["x"]) } } func TestDictToMap(t *testing.T) { d := starlark.NewDict(2) _ = d.SetKey(starlark.String("k"), starlark.String("v")) _ = d.SetKey(starlark.MakeInt(1), starlark.String("skip")) // non-string key m := DictToMap(d) if len(m) != 1 { t.Errorf("expected 1 entry (non-string key skipped), got %d", len(m)) } if m["k"] != "v" { t.Errorf("m[k] = %v", m["k"]) } } func TestMapToDict(t *testing.T) { m := map[string]any{"a": "b", "n": float64(3)} d := MapToDict(m) if d.Len() != 2 { t.Errorf("expected 2 entries, got %d", d.Len()) } v, found, _ := d.Get(starlark.String("a")) if !found || v.(starlark.String) != "b" { t.Errorf("dict[a] = %v", v) } }