package main import ( "encoding/json" "fmt" "html/template" "net/http" "net/http/httptest" "os" "os/exec" "reflect" "text/tabwriter" "time" "github.com/fatih/color" "github.com/julienschmidt/httprouter" ) var templates *template.Template var tw *tabwriter.Writer var testData = []*Person{ &Person{ Name: "Foo", Surname: "Bar", Age: 57, BirthDate: time.Date(1960, 1, 1, 0, 0, 0, 0, time.UTC), Animal: "Dog", Checklist: []string{ "Milk", }, }, nil, &Person{ Name: "Crow", Surname: "CrowCrow", Age: 22, BirthDate: time.Date(1995, 1, 5, 0, 0, 0, 0, time.UTC), Languages: []Language{ { Language: "Dutch", SkillLevel: 9.99, Native: true, }, { Language: "English", SkillLevel: 8.4, Native: false, }, { Language: "Japanese", SkillLevel: -9000.9, Native: false, }, }, Animal: "Dog", Checklist: []string{ "Milk", }, }, } func main() { router := httprouter.New() router.GET("/", getTest) router.POST("/", postTest) router.ServeFiles("/static/*filepath", http.Dir("../")) var err error templates, err = template.ParseGlob(`templates/*.gohtml`) if err != nil { fmt.Println(err) return } tw = tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) server := httptest.NewServer(router) testBrowser("chrome", "--headless", "--disable-gpu", server.URL) testBrowser("chromium", "--headless", "--disable-gpu", server.URL) // Firefox is being annoying, enable if you like // testBrowser("firefox", "-headless", server.URL) } // Person ... type Person struct { Name string `json:"name"` Surname string `json:"surname"` Age int `json:"age"` BirthDate time.Time `json:"birth_date"` Languages []Language `json:"languages"` Checklist []string `json:"checklist"` Animal string `json:"animal"` } // Language ... type Language struct { Language string `json:"language"` SkillLevel float64 `json:"skill_level"` Native bool `json:"native"` } func getTest(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { templates.ExecuteTemplate(w, `test.gohtml`, testData) } func postTest(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { var p []*Person body := json.NewDecoder(r.Body) err := body.Decode(&p) if err != nil { fmt.Println(color.RedString(err.Error())) } for k := range p { if p[k] == nil && testData[k] == nil { continue } isEq(*p[k], *testData[k]) } tw.Flush() } func testBrowser(command string, flags ...string) { fmt.Println("\nTesting", color.RedString(command)) err := exec.Command(command, flags...).Run() if err != nil { fmt.Println(color.RedString(err.Error())) } } func isEq(p1, p2 Person) { assert(p1.Name, p2.Name, "Name") assert(p1.Surname, p2.Surname, "Surname") assert(p1.Age, p2.Age, "Age") assert(p1.BirthDate, p2.BirthDate, "BirthDate") assert(p1.Animal, p2.Animal, "Animal") if !assert(len(p2.Languages), len(p1.Languages), "Languages length") { return } if !assert(len(p2.Checklist), len(p1.Checklist), "Checklist length") { return } for k := range p2.Languages { assert(p1.Languages[k].Language, p2.Languages[k].Language, "Languages.Language") assert(p1.Languages[k].SkillLevel, p2.Languages[k].SkillLevel, "Languages.SkillLevel") assert(p1.Languages[k].Native, p2.Languages[k].Native, "Languages.Native") } for k := range p2.Checklist { assert(p1.Checklist[k], p2.Checklist[k], "Checklist") } } func assert(v, v2 interface{}, ident string) bool { pass := true if !reflect.DeepEqual(v, v2) { fmt.Fprint(tw, color.RedString("FAIL\t")) pass = false } else { fmt.Fprint(tw, color.GreenString("PASS\t")) } fmt.Fprintf(tw, "%s\t%s\n", color.BlueString(ident), color.YellowString(fmt.Sprintf("'%v'\t'%v'", v, v2))) return pass }