1 package testutils
2
3 import (
4 "bytes"
5 "fmt"
6 "io/ioutil"
7 "math/rand"
8 "path"
9 "path/filepath"
10 "regexp"
11 "strings"
12 "testing"
13
14 "github.com/pmezard/go-difflib/difflib"
15
16 "github.com/noirbizarre/gonja"
17 "github.com/noirbizarre/gonja/loaders"
18
19 u "github.com/noirbizarre/gonja/utils"
20 )
21
22 func TestEnv(root string) *gonja.Environment {
23 cfg := gonja.NewConfig()
24 cfg.KeepTrailingNewline = true
25 loader := loaders.MustNewFileSystemLoader(root)
26 env := gonja.NewEnvironment(cfg, loader)
27 env.Autoescape = true
28 env.Globals.Set("lorem", u.Lorem)
29 return env
30 }
31
32 func GlobTemplateTests(t *testing.T, root string, env *gonja.Environment) {
33 pattern := filepath.Join(root, `*.tpl`)
34 matches, err := filepath.Glob(pattern)
35
36 if err != nil {
37 t.Fatal(err)
38 }
39 for _, match := range matches {
40 filename, err := filepath.Rel(root, match)
41 if err != nil {
42 t.Fatalf("Unable to compute path from `%s`:\n%s", match, err.Error())
43 }
44 testName := strings.Replace(path.Base(match), ".tpl", "", 1)
45 t.Run(testName, func(t *testing.T) {
46 defer func() {
47 if err := recover(); err != nil {
48 t.Error(err)
49 }
50 }()
51
52 rand.Seed(42)
53
54 tpl, err := env.FromFile(filename)
55 if err != nil {
56 t.Fatalf("Error on FromFile('%s'):\n%s", filename, err.Error())
57 }
58 testFilename := fmt.Sprintf("%s.out", match)
59 expected, rerr := ioutil.ReadFile(testFilename)
60 if rerr != nil {
61 t.Fatalf("Error on ReadFile('%s'):\n%s", testFilename, rerr.Error())
62 }
63 rendered, err := tpl.ExecuteBytes(Fixtures)
64 if err != nil {
65 t.Fatalf("Error on Execute('%s'):\n%s", filename, err.Error())
66 }
67
68 if bytes.Compare(expected, rendered) != 0 {
69 diff := difflib.UnifiedDiff{
70 A: difflib.SplitLines(string(expected)),
71 B: difflib.SplitLines(string(rendered)),
72 FromFile: "Expected",
73 ToFile: "Rendered",
74 Context: 2,
75 Eol: "\n",
76 }
77 result, _ := difflib.GetUnifiedDiffString(diff)
78 t.Errorf("%s rendered with diff:\n%v", testFilename, result)
79 }
80 })
81 }
82 }
83
84 func GlobErrorTests(t *testing.T, root string) {
85 pattern := filepath.Join(root, `*.err`)
86 matches, err := filepath.Glob(pattern)
87 env := TestEnv(root)
88 if err != nil {
89 t.Fatal(err)
90 }
91 for _, match := range matches {
92 testName := strings.Replace(path.Base(match), ".err", "", 1)
93 t.Run(testName, func(t *testing.T) {
94 defer func() {
95 if err := recover(); err != nil {
96 t.Error(err)
97 }
98 }()
99
100 testData, err := ioutil.ReadFile(match)
101 tests := strings.Split(string(testData), "\n")
102
103 checkFilename := fmt.Sprintf("%s.out", match)
104 checkData, err := ioutil.ReadFile(checkFilename)
105 if err != nil {
106 t.Fatalf("Error on ReadFile('%s'):\n%s", checkFilename, err.Error())
107 }
108 checks := strings.Split(string(checkData), "\n")
109
110 if len(checks) != len(tests) {
111 t.Fatal("Template lines != Checks lines")
112 }
113
114 for idx, test := range tests {
115 if strings.TrimSpace(test) == "" {
116 continue
117 }
118 if strings.TrimSpace(checks[idx]) == "" {
119 t.Fatalf("[%s Line %d] Check is empty (must contain an regular expression).",
120 match, idx+1)
121 }
122
123 tpl, err := env.FromString(test)
124 if err != nil {
125 t.Fatalf("Error on FromString('%s'):\n%s", test, err.Error())
126 }
127
128 tpl, err = env.FromBytes([]byte(test))
129 if err != nil {
130 t.Fatalf("Error on FromBytes('%s'):\n%s", test, err.Error())
131 }
132
133 _, err = tpl.ExecuteBytes(Fixtures)
134 if err == nil {
135 t.Fatalf("[%s Line %d] Expected error for (got none): %s",
136 match, idx+1, tests[idx])
137 }
138
139 re := regexp.MustCompile(fmt.Sprintf("^%s$", checks[idx]))
140 if !re.MatchString(err.Error()) {
141 t.Fatalf("[%s Line %d] Error for '%s' (err = '%s') does not match the (regexp-)check: %s",
142 match, idx+1, test, err.Error(), checks[idx])
143 }
144 }
145 })
146 }
147 }
148
View as plain text