package hatmill_test import ( "bytes" "fmt" "html" "io" "os" "reflect" "strings" "testing" "github.com/leanovate/gopter" "github.com/leanovate/gopter/gen" "github.com/leanovate/gopter/prop" "gitlab.codemonkeysoftware.net/b/hatmill" ha "gitlab.codemonkeysoftware.net/b/hatmill/attribute" he "gitlab.codemonkeysoftware.net/b/hatmill/element" ) type NopWriter struct{} func (NopWriter) Write(p []byte) (n int, err error) { return len(p), nil } func writeToString(wt io.WriterTo) string { var buf bytes.Buffer _, err := wt.WriteTo(&buf) if err != nil { panic(err) } return buf.String() } func checkWrite(wt io.WriterTo, expected string) bool { var buf bytes.Buffer n, err := wt.WriteTo(&buf) return err == nil && n == int64(buf.Len()) && buf.String() == expected } func TestText(t *testing.T) { properties := gopter.NewProperties(nil) properties.Property("WriteTo is correct", prop.ForAll( func(s string) bool { return checkWrite(hatmill.Text(s), s) }, gen.AnyString(), )) properties.TestingRun(t) } var nonEmptyAlphaString = gen.AlphaString().SuchThat(func(v interface{}) bool { return v.(string) != "" }) var attribGen = gen.Struct(reflect.TypeOf(hatmill.Attrib{}), map[string]gopter.Gen{ "Key": nonEmptyAlphaString, "Value": gen.AlphaString(), }) func TestAttrib(t *testing.T) { properties := gopter.NewProperties(nil) properties.Property("WriteTo only writes key when value is empty", prop.ForAll( func(key string) bool { attrib := hatmill.Attrib{ Key: key, } return checkWrite(attrib, key) }, nonEmptyAlphaString, )) properties.Property("writes key=value when value is not empty", prop.ForAll( func(attrib hatmill.Attrib) bool { expected := fmt.Sprintf("%s='%s'", attrib.Key, attrib.Value) return checkWrite(attrib, expected) }, attribGen.SuchThat(func(attrib interface{}) bool { return attrib.(hatmill.Attrib).Value != "" }), )) properties.TestingRun(t) } func TestEmptyElement(t *testing.T) { properties := gopter.NewProperties(nil) properties.Property("WriteTo writes element correctly with no attributes", prop.ForAll( func(tagName string) bool { elem := &hatmill.VoidElement{ TagName: tagName, } expected := "<" + tagName + ">" return checkWrite(elem, expected) }, gen.AnyString(), )) properties.Property("WriteTo writes element correctly with attributes", prop.ForAll( func(tagName string, attribs []hatmill.Attrib) bool { elem := hatmill.VoidElement{ TagName: tagName, Attribs: attribs, } var attribStrings []string for _, attrib := range attribs { attribStrings = append(attribStrings, writeToString(attrib)) } if len(attribStrings) > 0 { attribStrings[0] = " " + attribStrings[0] } expected := "<" + tagName + strings.Join(attribStrings, " ") + ">" return checkWrite(elem, expected) }, gen.AnyString(), gen.SliceOf(attribGen), )) properties.TestingRun(t) } var htmlTextGen = gen.AnyString().Map(func(s string) hatmill.Term { return hatmill.Text(s) }) func TestParentElement(t *testing.T) { properties := gopter.NewProperties(nil) properties.Property("WriteTo writes element correctly without children", prop.ForAll( func(tagName string, attribs []hatmill.Attrib) bool { elem := &hatmill.ParentElement{ VoidElement: hatmill.VoidElement{ TagName: tagName, Attribs: attribs, }, } openTag := writeToString(elem.VoidElement) expected := openTag + "" return checkWrite(elem, expected) }, gen.AnyString(), gen.SliceOf(attribGen), )) properties.Property("WriteTo writes element correctly with children", prop.ForAll( func(tagName string, attribs []hatmill.Attrib, children []hatmill.Term) bool { elem := &hatmill.ParentElement{ VoidElement: hatmill.VoidElement{ TagName: tagName, Attribs: attribs, }, Children: children, } openTag := writeToString(elem.VoidElement) var childStrings []string for _, child := range children { childStrings = append(childStrings, writeToString(child)) } expected := openTag + strings.Join(childStrings, "") + "" return checkWrite(elem, expected) }, gen.AnyString(), gen.SliceOf(attribGen), gen.SliceOf(htmlTextGen), )) properties.TestingRun(t) } func Example() { userInput := "" document := he.Html()( he.Body()( he.Img(ha.Src("./photo.jpg")), hatmill.Text(html.EscapeString(userInput)), he.Div(ha.Disabled(), ha.CustomData("coolness", "awesome"))(), he.Textarea(ha.Rows(25))(), he.Meter(ha.Min(-1.3), ha.Max(5.5E12))(), ), ) hatmill.WriteDocument(os.Stdout, document) // Output: <script>launchMissiles();</script>
}