Documentation
¶
Overview ¶
Package cover measures which lines of a template a program reaches when it runs.
It works the way the go toolchain does: a counter is injected before every statement while the templates are compiled, and executing them counts. The result is a profile in the format of go test, which go tool cover renders.
Granularity ¶
Counting is per line. The parser gives the offset of a token and not its extent, so a block covers the whole line it starts on, and two branches written on one line share a counter.
A line holding nothing but a define, an end or an else leaves no node in the parse tree, so nothing counts it and nothing is written for it. It renders as plain text, the way a go declaration does.
Reading the profile ¶
go tool cover finds the file a profile names by asking go list, so the paths have to read as an import path of a package that exists. The prefix a caller gives NewProfile is prepended to every asset path for that reason.
Only the html output is worth aiming at: go tool cover -func reads the file as go source and stops at the first template action.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Instrumented ¶
type Instrumented struct {
// Trees holds the rewritten tree of every template the asset declares, by name.
Trees map[string]*parse.Tree
// FuncName is the name the trees call to count a line.
FuncName string
// Func is the function that name must be bound to before the trees run.
Func func(int) string
}
Instrumented is a set of trees that count the lines they run, with the function to bind for them to count.
func (Instrumented) Bind ¶
func (i Instrumented) Bind() template.FuncMap
Bind returns the func map a set of instrumented trees needs to run.
type Profile ¶
type Profile struct {
// contains filtered or unexported fields
}
Profile counts the lines the templates of one repository reach when they run.
It is built while the repository is, and counts from then on. Counting is safe for concurrent use: a counter is an sync/atomic.Int64, and the lines a template holds are known before any of it runs, so nothing is written to the index once the repository is sealed.
func NewProfile ¶
NewProfile builds a profile of the templates of a repository.
prefix is prepended to the path of every asset, so that the profile reads as an import path go list resolves, so go tool cover finds the templates.
func (*Profile) Flush ¶
Flush writes the profile, in the format go test produces and go tool cover reads.
Counters are left as they are, so a caller may write the profile more than once, and go on running templates afterwards.
func (*Profile) Instrument ¶
func (p *Profile) Instrument(assetPath string, source []byte, trees map[string]*parse.Tree) Instrumented
Instrument rewrites the trees of an asset so that running them counts the lines they reach.
Every line a tree holds is recorded, whether it ever runs or not, so the profile distinguishes a line that was not reached from one that does not exist.
The trees are rewritten rather than altered: what the caller passed is left as it was.