func TestExecutionErrors(t *testing.T) { //debug = true matches, err := filepath.Glob("./template_tests/*-execution.err") if err != nil { t.Fatal(err) } for idx, match := range matches { t.Logf("[Errors %3d] Testing '%s'", idx+1, match) testData, err := ioutil.ReadFile(match) tests := strings.Split(string(testData), "\n") checkFilename := fmt.Sprintf("%s.out", match) checkData, err := ioutil.ReadFile(checkFilename) if err != nil { t.Fatalf("Error on ReadFile('%s'): %s", checkFilename, err.Error()) } checks := strings.Split(string(checkData), "\n") if len(checks) != len(tests) { t.Fatal("Template lines != Checks lines") } for idx, test := range tests { if strings.TrimSpace(test) == "" { continue } if strings.TrimSpace(checks[idx]) == "" { t.Fatalf("[%s Line %d] Check is empty (must contain an regular expression).", match, idx+1) } tpl, err := pongo2.FromString(test) if err != nil { t.Fatalf("Error on FromString('%s'): %s", test, err.Error()) } tpl, err = pongo2.FromBytes([]byte(test)) if err != nil { t.Fatalf("Error on FromBytes('%s'): %s", test, err.Error()) } _, err = tpl.ExecuteBytes(tplContext) if err == nil { t.Fatalf("[%s Line %d] Expected error for (got none): %s", match, idx+1, tests[idx]) } re := regexp.MustCompile(fmt.Sprintf("^%s$", checks[idx])) if !re.MatchString(err.Error()) { t.Fatalf("[%s Line %d] Error for '%s' (err = '%s') does not match the (regexp-)check: %s", match, idx+1, test, err.Error(), checks[idx]) } } } }
// Expose functions that are related to rendering text, to the given Lua state func exportRenderFunctions(w http.ResponseWriter, req *http.Request, L *lua.LState) { // Output Markdown as HTML L.SetGlobal("mprint", L.NewFunction(func(L *lua.LState) int { // Retrieve all the function arguments as a bytes.Buffer buf := arguments2buffer(L, true) // Convert the buffer to markdown and output the translated string w.Write(blackfriday.MarkdownCommon([]byte(buf.String()))) return 0 // number of results })) // Output text as rendered amber. L.SetGlobal("aprint", L.NewFunction(func(L *lua.LState) int { // Retrieve all the function arguments as a bytes.Buffer buf := arguments2buffer(L, true) // Use the buffer as a template. // Options are "Pretty printing, but without line numbers." tpl, err := amber.Compile(buf.String(), amber.Options{PrettyPrint: true, LineNumbers: false}) if err != nil { if debugMode { fmt.Fprint(w, "Could not compile Amber template:\n\t"+err.Error()+"\n\n"+buf.String()) } else { log.Errorf("Could not compile Amber template:\n%s\n%s", err, buf.String()) } return 0 // number of results } // Using "MISSING" instead of nil for a slightly better error message // if the values in the template should not be found. tpl.Execute(w, "MISSING") return 0 // number of results })) // Output text as rendered Pongo2 L.SetGlobal("poprint", L.NewFunction(func(L *lua.LState) int { // Retrieve all the function arguments as a bytes.Buffer buf := arguments2buffer(L, true) // Use the buffer as a template. // Options are "Pretty printing, but without line numbers." tpl, err := pongo2.FromBytes(buf.Bytes()) if err != nil { if debugMode { fmt.Fprint(w, "Could not compile Pongo2 template:\n\t"+err.Error()+"\n\n"+buf.String()) } else { log.Errorf("Could not compile Pongo2 template:\n%s\n%s", err, buf.String()) } return 0 // number of results } // nil is the template context (variables etc in a map) if err := tpl.ExecuteWriter(nil, w); err != nil { if debugMode { fmt.Fprint(w, "Could not compile Pongo2:\n\t"+err.Error()+"\n\n"+buf.String()) } else { log.Errorf("Could not compile Pongo2:\n%s\n%s", err, buf.String()) } } return 0 // number of results })) // Output text as rendered GCSS L.SetGlobal("gprint", L.NewFunction(func(L *lua.LState) int { // Retrieve all the function arguments as a bytes.Buffer buf := arguments2buffer(L, true) // Transform GCSS to CSS and output the result. // Ignoring the number of bytes written. if _, err := gcss.Compile(w, &buf); err != nil { if debugMode { fmt.Fprint(w, "Could not compile GCSS:\n\t"+err.Error()+"\n\n"+buf.String()) } else { log.Errorf("Could not compile GCSS:\n%s\n%s", err, buf.String()) } //return 0 // number of results } return 0 // number of results })) // Output text as rendered JSX L.SetGlobal("jprint", L.NewFunction(func(L *lua.LState) int { // Retrieve all the function arguments as a bytes.Buffer buf := arguments2buffer(L, true) // Transform JSX to JavaScript and output the result. prog, err := parser.ParseFile(nil, "<input>", &buf, parser.IgnoreRegExpErrors) if err != nil { if debugMode { // TODO: Use a similar error page as for Lua fmt.Fprint(w, "Could not parse JSX:\n\t"+err.Error()+"\n\n"+buf.String()) } else { log.Errorf("Could not parse JSX:\n%s\n%s", err, buf.String()) } return 0 // number of results } gen, err := generator.Generate(prog) if err != nil { if debugMode { // TODO: Use a similar error page as for Lua fmt.Fprint(w, "Could not generate JavaScript:\n\t"+err.Error()+"\n\n"+buf.String()) } else { log.Errorf("Could not generate JavaScript:\n%s\n%s", err, buf.String()) } return 0 // number of results } if gen != nil { io.Copy(w, gen) } return 0 // number of results })) }