mirror of
https://github.com/jstemmer/go-junit-report.git
synced 2025-04-05 05:00:15 -05:00
parser/gotest: refactor parser so Parse is no longer a top level func
Making Parse a method on a Parser struct makes it possible to later define an common parser interface.
This commit is contained in:
parent
0e7d095a28
commit
832cc97037
@ -76,7 +76,8 @@ func main() {
|
|||||||
in = io.TeeReader(in, os.Stdout)
|
in = io.TeeReader(in, os.Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
events, err := gotest.Parse(in)
|
parser := gotest.New()
|
||||||
|
events, err := parser.Parse(in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exitf("error reading input: %s\n", err)
|
exitf("error reading input: %s\n", err)
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,8 @@ func testReport(input, reportFile, packageName string, t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
events, err := gotest.Parse(file)
|
parser := gotest.New()
|
||||||
|
events, err := parser.Parse(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,35 @@ var (
|
|||||||
`(?:\s+coverage:\s+(\d+\.\d+)%\sof\sstatements(?:\sin\s(.+))?)?$`)
|
`(?:\s+coverage:\s+(\d+\.\d+)%\sof\sstatements(?:\sin\s(.+))?)?$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parse parses Go test output from the given io.Reader r.
|
// Option defines options that can be passed to gotest.New.
|
||||||
func Parse(r io.Reader) ([]gtr.Event, error) {
|
type Option func(*Parser)
|
||||||
p := &parser{}
|
|
||||||
|
|
||||||
|
// PackageName sets the default package name to use when it cannot be
|
||||||
|
// determined from the test output.
|
||||||
|
func PackageName(name string) Option {
|
||||||
|
return func(p *Parser) {
|
||||||
|
p.packageName = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new Go test output parser.
|
||||||
|
func New(options ...Option) *Parser {
|
||||||
|
p := &Parser{}
|
||||||
|
for _, option := range options {
|
||||||
|
option(p)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parser is a Go test output Parser.
|
||||||
|
type Parser struct {
|
||||||
|
packageName string
|
||||||
|
|
||||||
|
events []gtr.Event
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse parses Go test output from the given io.Reader r.
|
||||||
|
func (p *Parser) Parse(r io.Reader) ([]gtr.Event, error) {
|
||||||
s := bufio.NewScanner(r)
|
s := bufio.NewScanner(r)
|
||||||
for s.Scan() {
|
for s.Scan() {
|
||||||
p.parseLine(s.Text())
|
p.parseLine(s.Text())
|
||||||
@ -46,11 +71,7 @@ func Parse(r io.Reader) ([]gtr.Event, error) {
|
|||||||
return p.events, s.Err()
|
return p.events, s.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
type parser struct {
|
func (p *Parser) parseLine(line string) {
|
||||||
events []gtr.Event
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *parser) parseLine(line string) {
|
|
||||||
if strings.HasPrefix(line, "=== RUN ") {
|
if strings.HasPrefix(line, "=== RUN ") {
|
||||||
p.runTest(strings.TrimSpace(line[8:]))
|
p.runTest(strings.TrimSpace(line[8:]))
|
||||||
} else if strings.HasPrefix(line, "=== PAUSE ") {
|
} else if strings.HasPrefix(line, "=== PAUSE ") {
|
||||||
@ -80,23 +101,23 @@ func (p *parser) parseLine(line string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) add(event gtr.Event) {
|
func (p *Parser) add(event gtr.Event) {
|
||||||
p.events = append(p.events, event)
|
p.events = append(p.events, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) runTest(name string) {
|
func (p *Parser) runTest(name string) {
|
||||||
p.add(gtr.Event{Type: "run_test", Name: name})
|
p.add(gtr.Event{Type: "run_test", Name: name})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) pauseTest(name string) {
|
func (p *Parser) pauseTest(name string) {
|
||||||
p.add(gtr.Event{Type: "pause_test", Name: name})
|
p.add(gtr.Event{Type: "pause_test", Name: name})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) contTest(name string) {
|
func (p *Parser) contTest(name string) {
|
||||||
p.add(gtr.Event{Type: "cont_test", Name: name})
|
p.add(gtr.Event{Type: "cont_test", Name: name})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) endTest(line, indent, result, name, duration string) {
|
func (p *Parser) endTest(line, indent, result, name, duration string) {
|
||||||
if idx := strings.Index(line, fmt.Sprintf("%s--- %s:", indent, result)); idx > 0 {
|
if idx := strings.Index(line, fmt.Sprintf("%s--- %s:", indent, result)); idx > 0 {
|
||||||
p.output(line[:idx])
|
p.output(line[:idx])
|
||||||
}
|
}
|
||||||
@ -110,11 +131,11 @@ func (p *parser) endTest(line, indent, result, name, duration string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) status(result string) {
|
func (p *Parser) status(result string) {
|
||||||
p.add(gtr.Event{Type: "status", Result: result})
|
p.add(gtr.Event{Type: "status", Result: result})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) summary(result, name, duration, cached, status, covpct, packages string) {
|
func (p *Parser) summary(result, name, duration, cached, status, covpct, packages string) {
|
||||||
p.add(gtr.Event{
|
p.add(gtr.Event{
|
||||||
Type: "summary",
|
Type: "summary",
|
||||||
Result: result,
|
Result: result,
|
||||||
@ -126,7 +147,7 @@ func (p *parser) summary(result, name, duration, cached, status, covpct, package
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) coverage(percent, packages string) {
|
func (p *Parser) coverage(percent, packages string) {
|
||||||
p.add(gtr.Event{
|
p.add(gtr.Event{
|
||||||
Type: "coverage",
|
Type: "coverage",
|
||||||
CovPct: parseFloat(percent),
|
CovPct: parseFloat(percent),
|
||||||
@ -134,7 +155,7 @@ func (p *parser) coverage(percent, packages string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) benchmark(name, iterations, nsPerOp, mbPerSec, bytesPerOp, allocsPerOp string) {
|
func (p *Parser) benchmark(name, iterations, nsPerOp, mbPerSec, bytesPerOp, allocsPerOp string) {
|
||||||
p.add(gtr.Event{
|
p.add(gtr.Event{
|
||||||
Type: "benchmark",
|
Type: "benchmark",
|
||||||
Name: name,
|
Name: name,
|
||||||
@ -146,14 +167,14 @@ func (p *parser) benchmark(name, iterations, nsPerOp, mbPerSec, bytesPerOp, allo
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) buildOutput(packageName string) {
|
func (p *Parser) buildOutput(packageName string) {
|
||||||
p.add(gtr.Event{
|
p.add(gtr.Event{
|
||||||
Type: "build_output",
|
Type: "build_output",
|
||||||
Name: packageName,
|
Name: packageName,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) output(line string) {
|
func (p *Parser) output(line string) {
|
||||||
p.add(gtr.Event{Type: "output", Data: line})
|
p.add(gtr.Event{Type: "output", Data: line})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,15 +185,12 @@ func TestParseLine(t *testing.T) {
|
|||||||
|
|
||||||
name := fmt.Sprintf("%d %s", i+1, strings.Join(types, ","))
|
name := fmt.Sprintf("%d %s", i+1, strings.Join(types, ","))
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
testParseLine(t, &parser{}, test.input, want)
|
parser := New()
|
||||||
|
parser.parseLine(test.input)
|
||||||
|
got := parser.events
|
||||||
|
if diff := cmp.Diff(got, want); diff != "" {
|
||||||
|
t.Errorf("parseLine(%q) returned unexpected events, diff (-got, +want):\n%v", test.input, diff)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testParseLine(t *testing.T, parser *parser, input string, want []gtr.Event) {
|
|
||||||
parser.parseLine(input)
|
|
||||||
got := parser.events
|
|
||||||
if diff := cmp.Diff(got, want); diff != "" {
|
|
||||||
t.Errorf("parseLine(%q) returned unexpected events, diff (-got, +want):\n%v", input, diff)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user