-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathexample_test.go
More file actions
99 lines (88 loc) · 2.42 KB
/
example_test.go
File metadata and controls
99 lines (88 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package check_test
import (
"fmt"
"go/token"
"log"
"slices"
"text/template"
"text/template/parse"
"golang.org/x/tools/go/packages"
"github.com/typelate/check"
)
type Person struct {
Name string
}
func ExampleExecute() {
// 1. Load Go packages with type info.
fset := token.NewFileSet()
pkgs, err := packages.Load(&packages.Config{
Fset: fset,
Tests: true,
Mode: packages.NeedTypes |
packages.NeedTypesInfo |
packages.NeedSyntax |
packages.NeedFiles |
packages.NeedName |
packages.NeedModule,
Dir: ".",
}, ".")
if err != nil {
log.Fatal(err)
}
const testPackageName = "check_test"
packageIndex := slices.IndexFunc(pkgs, func(p *packages.Package) bool {
return p.Name == testPackageName
})
if packageIndex < 0 {
log.Fatalf("%s package not found", testPackageName)
}
testPackage := pkgs[packageIndex]
// 2. Parse a template.
tmpl, err := template.New("example").Parse(
/* language=gotemplate */ `
{{define "unknown field" -}}
{{.UnknownField}}
{{- end}}
{{define "known field" -}}
Hello, {{.Name}}!
{{- end}}"
`)
if err != nil {
log.Fatalf("parse error: %v", err)
}
// 3. Create a TreeFinder (wraps Template.Lookup).
treeFinder := check.FindTreeFunc(func(name string) (*parse.Tree, bool) {
if named := tmpl.Lookup(name); named != nil {
return named.Tree, true
}
return nil, false
})
// 4. Build a function checker.
functions := check.DefaultFunctions(testPackage.Types)
// 5. Initialize a Global.
global := check.NewGlobal(testPackage.Types, fset, treeFinder, functions)
// 6. Look up a type used by the template.
personObj := testPackage.Types.Scope().Lookup("Person")
if personObj == nil {
log.Fatalf("type Person not found in %s", testPackage.PkgPath)
}
// 7. Type-check the template.
{
const templateName = "unknown field"
if err := check.Execute(global, tmpl.Lookup("unknown field").Tree, personObj.Type()); err != nil {
fmt.Println(err.Error())
} else {
fmt.Printf("template %q type-check passed\n", templateName)
}
}
{
const templateName = "known field"
if err := check.Execute(global, tmpl.Lookup("known field").Tree, personObj.Type()); err != nil {
fmt.Println(err.Error())
} else {
fmt.Printf("template %q type-check passed\n", templateName)
}
}
// Output: type check failed: example:3:3: executing "unknown field" at <.UnknownField>: UnknownField not found on github.com/typelate/check_test.Person
// template "known field" type-check passed
}