func testFloat64(body jquery.JQuery) { logInfo("begin testFloat64") cases := []struct { name string f float64 min, max, step float64 valid htmlctrl.Validator }{ {"f1", 0.5, -10, 10, 1.5, nil}, {"f2", 2.1, -100, 100, 1, htmlctrl.ValidateFloat64(func(f float64) bool { if f == 5.5 { log("f can't be 5.5") } return f != 5.5 })}, {"f3", 0, math.NaN(), math.NaN(), math.NaN(), nil}, } float64s := jq("<div>").AddClass("float64s") for _, c := range cases { logInfo(fmt.Sprintf("test case: %#v", c)) j, e := htmlctrl.Float64(&c.f, c.name, "float64-id", "float64-class", c.min, c.max, c.step, c.valid) if e != nil { logError(fmt.Sprintf("%s: unexpected error: %s", c.name, e)) } if title := j.Attr("title"); title != c.name { logError(fmt.Sprintf("%s: title is %s, expected %s", c.name, title, c.name)) } float64s.Append(j) c := &c float64s.Append(jq("<button>").SetText("verify "+c.name).Call(jquery.CLICK, func() { log(c.name, c.f) })) } body.Append(float64s) logInfo("end testFloat64") }
func testStruct(body jquery.JQuery) { logInfo("begin testStruct") Bptr := true Iptr := 11 Fptr := 1.1 Sptr := "abc" type St2 struct { B []int `desc:"inner int" id:"St2-B" class:"struct-int-slice" min:"-1" max:"11"` } type St1 struct { A []St2 `desc:"slice of St2 struct" id:"St1-A" class:"struct-struct-slice"` } struct1 := struct { b bool B bool `desc:"a bool"` Bptr *bool `desc:"bool ptr" id:"s1-Bptr" class:"struct-bool-ptr"` Bt bool `desc:"Always true" valid:"BoolTrue"` I int `desc:"an int" id:"s1-I" class:"struct-int"` Iptr *int `desc:"int ptr"` Ilim int `desc:"limited int" min:"1" max:"10" step:"2" valid:"IntNot5"` F float64 `desc:"an float64" id:"s1-F" class:"struct-float64"` Fptr *float64 `desc:"float64 ptr"` Flim float64 `desc:"limited float64" min:"1.2" max:"10.5" step:"1.2" valid:"Float64Not5"` S string `desc:"a string" id:"s1-S" class:"struct-string"` Sptr *string `desc:"string ptr"` Slim string `desc:"limited string" valid:"StringNotHello"` C string `desc:"a choice" choice:"def,abc,invalid,hi" id:"s1-C" class:"struct-choice"` Cptr *string `desc:"choice ptr" choice:"def,abc,invalid,hi"` Clim string `desc:"limited choice" choice:"def,abc,invalid,hi" valid:"ChoiceNotInvalid"` St St1 `desc:"inner struct" id:"s1-St" class:"struct-struct"` }{ false, false, &Bptr, true, 2, &Iptr, 1, 2.5, &Fptr, 1.2, "a", &Sptr, "def", "", &Sptr, "hi", St1{A: []St2{}}, } htmlctrl.RegisterValidator("BoolTrue", htmlctrl.ValidateBool(func(b bool) bool { log("bool is locked at true") return b })) htmlctrl.RegisterValidator("IntNot5", htmlctrl.ValidateInt(func(i int) bool { not5 := i != 5 if !not5 { log("int can't be 5") } return not5 })) htmlctrl.RegisterValidator("Float64Not5", htmlctrl.ValidateFloat64(func(f float64) bool { not5 := f != 5 if !not5 { log("float can't be 5") } return not5 })) htmlctrl.RegisterValidator("StringNotHello", htmlctrl.ValidateString(func(s string) bool { notHello := s != "hello" if !notHello { log("string can't be 'hello'") } return notHello })) htmlctrl.RegisterValidator("ChoiceNotInvalid", htmlctrl.ValidateString(func(c string) bool { if c == "invalid" { log("choice can't be 'invalid'") } return c != "invalid" })) _, e := htmlctrl.Struct(struct1, "error", "struct-id", "struct-class") if e == nil { logError("expected error when passing non-ptr") } _, e = htmlctrl.Struct(&e, "error", "struct-id", "struct-class") if e == nil { logError("expected error when passing ptr to non-slice") } j, e := htmlctrl.Struct(&struct1, "struct1", "struct-id", "struct-class") if e != nil { logError(fmt.Sprintf("%s: unexpected error: %s", "struct1", e)) } if title := j.Attr("title"); title != "struct1" { logError(fmt.Sprintf("%s: title is %s, expected %s", "struct1", title, "struct1")) } body.Append(j) body.Append(jq("<button>").SetText("verify struct1").Call(jquery.CLICK, func() { log("struct1", struct1) })) logInfo("end testStruct") }
func testSlices(body jquery.JQuery) { logInfo("begin testSlices") logInfo("begin testSlice bool") cases := []sliceCase{ &sliceBoolCase{"bool1", []bool{}}, &sliceBoolCase{"bool2", []bool{true, false}}, } _, e := htmlctrl.Slice(cases[0], "error", "slice-id", "slice-class", 0, 0, 0, nil) if e == nil { logError("expected error when passing non-ptr to slice") } _, e = htmlctrl.Slice(&e, "error", "slice-id", "slice-class", 0, 0, 0, nil) if e == nil { logError("expected error when passing ptr to non-slice") } testSlice(body, cases) logInfo("begin testSlice *bool") b1, b2 := true, false cases = []sliceCase{ &sliceBoolPtrCase{"[]*bool1", []*bool{&b1, &b2}, htmlctrl.ValidateBool(func(b bool) bool { log("bool is locked at true") return b })}, &sliceBoolPtrCase{"[]*bool2", []*bool{}, nil}, } testSlice(body, cases) logInfo("begin testSlice int") cases = []sliceCase{ &sliceIntCase{"[]int1", []int{2, 4}, 0, 50, 2, htmlctrl.ValidateInt(func(i int) bool { allowed := i != 3 && i != 5 && i != 7 if !allowed { log("int may not be 3, 5, or 7") } return allowed })}, &sliceIntCase{"[]int2", []int{}, 0, 0, 1, nil}, } testSlice(body, cases) logInfo("begin testSlice *int") i1, i2 := 1, 22 cases = []sliceCase{ &sliceIntPtrCase{"[]*int1", []*int{&i1, &i2}, 0, 50, 2, htmlctrl.ValidateInt(func(i int) bool { allowed := i != 3 && i != 5 && i != 7 if !allowed { log("int may not be 3, 5, or 7") } return allowed })}, &sliceIntPtrCase{"[]*int2", []*int{}, 0, 0, 1, nil}, } testSlice(body, cases) logInfo("begin testSlice float64") cases = []sliceCase{ &sliceFloat64Case{"[]float64 1", []float64{2.1, 4.2}, 0, 50, 2.1, htmlctrl.ValidateFloat64(func(f float64) bool { allowed := f != 3 && f != 5 && f != 7 if !allowed { log("float64 may not be 3, 5, or 7") } return allowed })}, &sliceFloat64Case{"[]float64 2", []float64{}, 0, 0, 1, nil}, } testSlice(body, cases) logInfo("begin testSlice *float64") f1, f2 := 1.1, 22.2 cases = []sliceCase{ &sliceFloat64PtrCase{"[]*float64 1", []*float64{&f1, &f2}, 0, 50, 2, htmlctrl.ValidateFloat64(func(f float64) bool { allowed := f != 3 && f != 5 && f != 7 if !allowed { log("float64 may not be 3, 5, or 7") } return allowed })}, &sliceFloat64PtrCase{"[]*float64 2", []*float64{}, 0, 0, 1, nil}, } testSlice(body, cases) logInfo("begin testSlice string") cases = []sliceCase{ &sliceStringCase{"[]string1", []string{"a", "b"}, htmlctrl.ValidateString(func(s string) bool { allowed := s != "c" && s != "d" if !allowed { log("string may not be c, d") } return allowed })}, &sliceStringCase{"[]string2", []string{}, nil}, } testSlice(body, cases) logInfo("begin testSlice *string") s1, s2 := "ab", "cd" cases = []sliceCase{ &sliceStringPtrCase{"[]*string1", []*string{&s1, &s2}, htmlctrl.ValidateString(func(s string) bool { allowed := s != "c" && s != "d" if !allowed { log("string may not be c, d") } return allowed })}, &sliceStringPtrCase{"[]*string2", []*string{}, nil}, } testSlice(body, cases) logInfo("begin testSlice []int") cases = []sliceCase{ &sliceIntSliceCase{"[][]int1", [][]int{{2, 4}, {8, 16}}, 0, 50, 2, htmlctrl.ValidateInt(func(i int) bool { allowed := i != 3 && i != 5 && i != 7 if !allowed { log("int may not be 3, 5, or 7") } return allowed })}, &sliceIntSliceCase{"[][]int2", [][]int{}, 0, 0, 1, nil}, } testSlice(body, cases) logInfo("begin testSlice *[]*int") is1, is2 := []*int{&i1, &i2}, []*int{} cases = []sliceCase{ &sliceIntPtrSliceCase{"[]*[]*int1", []*[]*int{&is1, &is2}, 0, 50, 2, htmlctrl.ValidateInt(func(i int) bool { allowed := i != 3 && i != 5 && i != 7 if !allowed { log("int may not be 3, 5, or 7") } return allowed })}, &sliceIntPtrSliceCase{"[]*[]*int2", []*[]*int{}, 0, 0, 1, nil}, } testSlice(body, cases) logInfo("end testSlices") }