func main() { user := &User{ Name: "Emil Sjölander", Repos: []Repo{ Repo{ Name: "goson", Url: "https://github.com/emilsjolander/goson", Stars: 0, Forks: 0, }, Repo{ Name: "StickyListHeaders", Url: "https://github.com/emilsjolander/StickyListHeaders", Stars: 722, Forks: 197, }, Repo{ Name: "android-FlipView", Url: "https://github.com/emilsjolander/android-FlipView", Stars: 157, Forks: 47, }, }, } result, err := goson.Render("user", goson.Args{"User": user}) if err != nil { panic(err) } fmt.Println(string(result)) }
// Test rendering an int passed to Args. Test all sizes of ints func TestInt(t *testing.T) { result, err := goson.Render("templates/int", goson.Args{"int": int(-1), "int8": int8(2), "int16": int16(3), "int32": int32(-4), "int64": int64(5)}) if err != nil { t.Error(err) } else if string(result) != "{\"int\":-1,\"int8\":2,\"int16\":3,\"int32\":-4,\"int64\":5}" { t.Error("json did not match") } }
// Test rendering an uint passed to Args. Test all sizes of uints func TestUint(t *testing.T) { result, err := goson.Render("templates/uint", goson.Args{"uint": uint(10), "uint8": uint8(20), "uint16": uint16(30), "uint32": uint32(40), "uint64": uint64(50)}) if err != nil { t.Error(err) } else if string(result) != "{\"uint\":10,\"uint8\":20,\"uint16\":30,\"uint32\":40,\"uint64\":50}" { t.Error("json did not match") } }
// Test rendering a float passed to Args. Test all sizes of floats func TestFloat(t *testing.T) { result, err := goson.Render("templates/float", goson.Args{"float32": float32(32.32), "float64": float64(64.64)}) if err != nil { t.Error(err) } else if string(result) != "{\"float32\":32.32,\"float64\":64.64}" { t.Error("json did not match") } }
// Test rendering a json.Marshaler interface passed to Args func TestJSONMarshaler(t *testing.T) { result, err := goson.Render("templates/marshaler", goson.Args{"marshaler": &time.Time{}}) if err != nil { t.Error(err) } else if string(result) != "{\"json\":\"0001-01-01T00:00:00Z\"}" { t.Error("json did not match") } }
// Test rendering of constants in the template. string, int, float, bool and object literals func TestConstants(t *testing.T) { result, err := goson.Render("templates/constants", goson.Args{}) if err != nil { t.Error(err) } else if string(result) != "{\"object\":{\"string\":\"hej\",\"int\":123,\"float\":1.23,\"bool\":true}}" { t.Error("json did not match") } }
// Test rendering a bool passed to Args. func TestBool(t *testing.T) { result, err := goson.Render("templates/bool", goson.Args{"bool": true}) if err != nil { t.Error(err) } else if string(result) != "{\"bool\":true}" { t.Error("json did not match") } }
// Test rendering a string passed to Args. func TestString(t *testing.T) { result, err := goson.Render("templates/string", goson.Args{"string": "a string"}) if err != nil { t.Error(err) } else if string(result) != "{\"string\":\"a string\"}" { t.Error("json did not match") } }
// Test rendering a function passed to Args. func TestFunction(t *testing.T) { result, err := goson.Render("templates/function", goson.Args{"MyFunc": func() int { return 1337 }}) if err != nil { t.Error(err) } else if string(result) != "{\"func_result\":1337}" { t.Error("json did not match") } }
// Test commenting out lines with both single and multiline syntax func TestComments(t *testing.T) { result, err := goson.Render("templates/comments", goson.Args{}) if err != nil { t.Error(err) } else if string(result) != "{\"first\":1,\"third\":3,\"fifth\":5}" { t.Error("json did not match") } }
// Test rendering a method attached to a struct passed to Args. func TestMethod(t *testing.T) { result, err := goson.Render("templates/method", goson.Args{"MyStruct": new(MethodTester)}) if err != nil { t.Error(err) } else if string(result) != "{\"my_struct\":{\"method\":\"method test\"}}" { t.Error("json did not match") } }
// Test rendering a slice of primites where the primitives are looped over and wrapped in json objects. func TestSliceOfPrimitives(t *testing.T) { ints := []int{1, 2, 4, 8} result, err := goson.Render("templates/slice_of_ints", goson.Args{"Ints": ints}) if err != nil { t.Error(err) } else if string(result) != "{\"ints\":[{\"int\":1},{\"int\":2},{\"int\":4},{\"int\":8}]}" { t.Error("json did not match") } }
// Test rendering a pointer to a struct passed to Args. func TestStructPtr(t *testing.T) { myStruct := struct{ MyString string }{MyString: "MyString"} result, err := goson.Render("templates/struct", goson.Args{"MyStruct": &myStruct}) if err != nil { t.Error(err) } else if string(result) != "{\"my_struct\":{\"my_string\":\"MyString\"}}" { t.Error("json did not match") } }
// Test rendering a map passed to Args. func TestMap(t *testing.T) { myMap := map[string]string{"key1": "key 1!", "key2": "key 2!", "key3": "key 3!"} result, err := goson.Render("templates/map", goson.Args{"MyMap": myMap}) if err != nil { t.Error(err) } else if string(result) != "{\"my_map\":{\"key1\":\"key 1!\",\"key2\":\"key 2!\",\"key3\":\"key 3!\"}}" { t.Error("json did not match") } }
// Test rendering methods and properties of a anonymous embedded struct func TestAnonymousEmbeddedStruct(t *testing.T) { v := &Outer{Inner{Property: "property"}} result, err := goson.Render("templates/anonymous_embedded_struct", goson.Args{"Outer": v}) if err != nil { t.Error(err) } else if string(result) != "{\"my_struct\":{\"property\":\"property\",\"method\":\"method\"}}" { t.Error("json did not match") } }
// Test looping over a slice func TestLoop(t *testing.T) { type Item struct{ Id int } items := []Item{Item{1}, Item{12}, Item{123}} result, err := goson.Render("templates/loop", goson.Args{"Items": items}) if err != nil { t.Error(err) } else if string(result) != "{\"items\":[{\"id\":1},{\"id\":12},{\"id\":123}]}" { t.Error("json did not match ") } }
// Test including a template with arguments func TestInclude(t *testing.T) { type MyStruct struct{ MyString string } myStruct := MyStruct{"hej!"} result, err := goson.Render("templates/include", goson.Args{"MyStruct": myStruct}) if err != nil { t.Error(err) } else if string(result) != "{\"a_string\":\"rendering a include\",\"my_included_string\":\"hej!\"}" { t.Error("json did not match") } }
// Test rendering a json.Marshaler within a slice func TestJSONMarshalerCollection(t *testing.T) { v1 := []time.Time{time.Time{}} v2 := []*time.Time{&time.Time{}} result, err := goson.Render("templates/marshaler_collection", goson.Args{"v1": v1, "v2": v2}) if err != nil { t.Error(err) } else if string(result) != `{"v1":["0001-01-01T00:00:00Z"],"v2":["0001-01-01T00:00:00Z"]}` { t.Error("json did not match") } }
// Test rendering a slice of maps. func TestSliceOfMaps(t *testing.T) { type Object map[string]string objects := []Object{Object{"StringField": "hej"}, Object{"StringField": "jag"}, Object{"StringField": "heter"}, Object{"StringField": "emil"}} result, err := goson.Render("templates/slice_of_objects", goson.Args{"Objects": objects}) if err != nil { t.Error(err) } else if string(result) != "{\"objects\":[{\"string\":\"hej\"},{\"string\":\"jag\"},{\"string\":\"heter\"},{\"string\":\"emil\"}]}" { t.Error("json did not match") } }
// Test aliasing a struct func TestAlias(t *testing.T) { type InnerStruct struct{ MyString string } type MyStruct struct{ MyInnerStruct InnerStruct } myStruct := MyStruct{InnerStruct{"hej!"}} result, err := goson.Render("templates/alias", goson.Args{"MyStruct": myStruct}) if err != nil { t.Error(err) } else if string(result) != "{\"object\":{\"string\":\"hej!\"}}" { t.Error("json did not match") } }
// Test rendering a slice of primitives passed as a json argument, should not be wrapped in json objects. func TestSliceOfAnonymousPrimitives(t *testing.T) { person := struct { Name string Nicknames []string }{"Emil", []string{"mardox", "odjuret", "kodarn"}} result, err := goson.Render("templates/slice_of_anonymous_strings", goson.Args{"Person": person}) if err != nil { t.Error(err) } else if string(result) != "{\"person\":{\"name\":\"Emil\",\"nicknames\":[\"mardox\",\"odjuret\",\"kodarn\"]}}" { t.Error("json did not match") } }
// Test rendering a json.Marshaler as struct field func TestJSONMarshalerStruct(t *testing.T) { value := struct { T *time.Time }{ &time.Time{}, } result, err := goson.Render("templates/marshaler_struct", goson.Args{"value": value}) if err != nil { t.Error(err) } else if string(result) != `{"s":{"json":"0001-01-01T00:00:00Z"}}` { t.Error("json did not match") } }
// Test rendering a slice of single return value functions. func TestSliceOfFunctions(t *testing.T) { i := 1 intFunc := func() int { defer func() { i *= 2 }() return i } ints := []func() int{intFunc, intFunc, intFunc, intFunc} result, err := goson.Render("templates/slice_of_ints", goson.Args{"Ints": ints}) if err != nil { t.Error(err) } else if string(result) != "{\"ints\":[{\"int\":1},{\"int\":2},{\"int\":4},{\"int\":8}]}" { t.Error("json did not match") } }
// Test rendering a collection. func TestCollection(t *testing.T) { ints := new(CollectionTester) ints.Add(1) ints.Add(1) ints.Add(2) ints.Add(3) ints.Add(5) ints.Add(8) result, err := goson.Render("templates/slice_of_ints", goson.Args{"Ints": ints}) if err != nil { t.Error(err) } else if string(result) != "{\"ints\":[{\"int\":1},{\"int\":1},{\"int\":2},{\"int\":3},{\"int\":5},{\"int\":8}]}" { t.Error("json did not match") } }
func main() { profileKind := os.Args[1] switch profileKind { case "cpu": defer profile.Start(profile.CPUProfile).Stop() case "mem": defer profile.Start(profile.MemProfile).Stop() case "block": defer profile.Start(profile.BlockProfile).Stop() default: fmt.Println("only cpu, mem and block are valid profile arguments") return } for i := 0; i < 1000000; i++ { user := &User{ Name: "Emil Sjölander", Repos: []Repo{ Repo{ Name: "goson", URL: "https://github.com/emilsjolander/goson", Stars: 0, Forks: 0, }, Repo{ Name: "StickyListHeaders", URL: "https://github.com/emilsjolander/StickyListHeaders", Stars: 722, Forks: 197, }, Repo{ Name: "android-FlipView", URL: "https://github.com/emilsjolander/android-FlipView", Stars: 157, Forks: 47, }, }, } goson.Render("user", goson.Args{"User": user}) } }
// Return a parsed goson document to w // views/ prefix is automatically added to view's name. // The arguments are of type hawk.Args, NOT goson.Args. // These are automatically converted when this function is called. func Send(w http.ResponseWriter, viewname string, args Args) { // Create a new goson.Args var gargs goson.Args gargs = make(goson.Args) // Convert hawk.Args to goson.Args // The type is pretty much the same for k, v := range args { gargs[k] = v } // Render the view result, err := goson.Render("views/"+viewname, gargs) // Probably file not found if err != nil { Log.Printf("JSON encoding failed; %s", err) Error(500, w) return } // Write the result w.Write([]byte(result)) }
// Test rendering to a non existing template and make sure an error is returned. func TestNoTemplate(t *testing.T) { _, err := goson.Render("templates/this_is_not_a_template", goson.Args{"string": "a string"}) if err == nil { t.Error("Template did not exist but Render method returned no error") } }
func BenchmarkGosonSerialization(b *testing.B) { for i := 0; i < b.N; i++ { goson.Render("templates/user", goson.Args{"User": user}) } }