package vdom import ( "context" "encoding/json" "fmt" "log" "reflect" "testing" "github.com/wavetermdev/waveterm/pkg/util/utilfn" ) type renderContextKeyType struct{} var renderContextKey = renderContextKeyType{} type TestContext struct { ButtonId string } func Page(ctx context.Context, props map[string]any) any { clicked, setClicked := UseState(ctx, false) var clickedDiv *VDomElem if clicked { clickedDiv = Bind(`
clicked
`, nil) } clickFn := func() { log.Printf("run clickFn\n") setClicked(true) } return Bind( `

hello world

`, map[string]any{"clickFn": clickFn, "clickedDiv": clickedDiv}, ) } func Button(ctx context.Context, props map[string]any) any { ref := UseVDomRef(ctx) clName, setClName := UseState(ctx, "button") UseEffect(ctx, func() func() { fmt.Printf("Button useEffect\n") setClName("button mounted") return nil }, nil) compId := UseId(ctx) testContext := getTestContext(ctx) if testContext != nil { testContext.ButtonId = compId } return Bind(`
`, map[string]any{"clName": clName, "ref": ref, "onClick": props["onClick"], "children": props["children"]}) } func printVDom(root *RootElem) { vd := root.MakeVDom() jsonBytes, _ := json.MarshalIndent(vd, "", " ") fmt.Printf("%s\n", string(jsonBytes)) } func getTestContext(ctx context.Context) *TestContext { val := ctx.Value(renderContextKey) if val == nil { return nil } return val.(*TestContext) } func Test1(t *testing.T) { log.Printf("hello!\n") testContext := &TestContext{ButtonId: ""} ctx := context.WithValue(context.Background(), renderContextKey, testContext) root := MakeRoot() root.SetOuterCtx(ctx) root.RegisterComponent("Page", Page) root.RegisterComponent("Button", Button) root.Render(E("Page")) if root.Root == nil { t.Fatalf("root.Root is nil") } printVDom(root) root.RunWork() printVDom(root) root.Event(testContext.ButtonId, "onClick", VDomEvent{EventType: "onClick"}) root.RunWork() printVDom(root) } func TestBind(t *testing.T) { elem := Bind(`
clicked
`, nil) jsonBytes, _ := json.MarshalIndent(elem, "", " ") log.Printf("%s\n", string(jsonBytes)) elem = Bind(`
clicked
`, nil) jsonBytes, _ = json.MarshalIndent(elem, "", " ") log.Printf("%s\n", string(jsonBytes)) elem = Bind(``, nil) jsonBytes, _ = json.MarshalIndent(elem, "", " ") log.Printf("%s\n", string(jsonBytes)) elem = Bind(`

hello world

`, nil) jsonBytes, _ = json.MarshalIndent(elem, "", " ") log.Printf("%s\n", string(jsonBytes)) } func TestJsonBind(t *testing.T) { elem := Bind(`
`, nil) if elem == nil { t.Fatalf("elem is nil") } if elem.Tag != "div" { t.Fatalf("elem.Tag: %s (expected 'div')\n", elem.Tag) } if elem.Props == nil || len(elem.Props) != 3 { t.Fatalf("elem.Props: %v\n", elem.Props) } data1Val, ok := elem.Props["data1"] if !ok { t.Fatalf("data1 not found\n") } _, ok = data1Val.(float64) if !ok { t.Fatalf("data1: %T\n", data1Val) } data1Int, ok := utilfn.ToInt(data1Val) if !ok || data1Int != 5 { t.Fatalf("data1: %v\n", data1Val) } data2Val, ok := elem.Props["data2"] if !ok { t.Fatalf("data2 not found\n") } d2type := reflect.TypeOf(data2Val) if d2type.Kind() != reflect.Slice { t.Fatalf("data2: %T\n", data2Val) } data2Arr := data2Val.([]any) if len(data2Arr) != 3 { t.Fatalf("data2: %v\n", data2Val) } d2v2, ok := data2Arr[1].(float64) if !ok || d2v2 != 2 { t.Fatalf("data2: %v\n", data2Val) } data3Val, ok := elem.Props["data3"] if !ok || data3Val == nil { t.Fatalf("data3 not found\n") } d3type := reflect.TypeOf(data3Val) if d3type.Kind() != reflect.Map { t.Fatalf("data3: %T\n", data3Val) } data3Map := data3Val.(map[string]any) if len(data3Map) != 1 { t.Fatalf("data3: %v\n", data3Val) } d3v1, ok := data3Map["a"] if !ok { t.Fatalf("data3: %v\n", data3Val) } mval, ok := utilfn.ToInt(d3v1) if !ok || mval != 1 { t.Fatalf("data3: %v\n", data3Val) } log.Printf("elem: %v\n", elem) }