mirror of
https://github.com/jstemmer/go-junit-report.git
synced 2025-05-21 03:14:29 -05:00
Parse successful tests
This commit is contained in:
parent
8fcd615a51
commit
4b851d63d2
@ -6,12 +6,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Report struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Read input
|
// Read input
|
||||||
report, err := parse(os.Stdin)
|
report, err := Parse(os.Stdin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error reading input: %s\n", err)
|
fmt.Printf("Error reading input: %s\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -25,10 +22,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse(reader io.Reader) (Report, error) {
|
|
||||||
return Report{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r Report) XML(io.Writer) error {
|
func (r Report) XML(io.Writer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,85 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
const testOutputPass = `=== RUN TestOne
|
func TestOutputPass(t *testing.T) {
|
||||||
|
testOutputPass := `=== RUN TestOne
|
||||||
--- PASS: TestOne (0.06 seconds)
|
--- PASS: TestOne (0.06 seconds)
|
||||||
=== RUN TestTwo
|
=== RUN TestTwo
|
||||||
--- PASS: TestTwo (0.10 seconds)
|
--- PASS: TestTwo (0.10 seconds)
|
||||||
PASS
|
PASS
|
||||||
ok package/name 0.160s`
|
ok package/name 0.160s`
|
||||||
|
|
||||||
func TestOutputPass(t *testing.T) {
|
expected := Report{
|
||||||
_, err := parse(strings.NewReader(testOutputPass))
|
Packages: []Package{
|
||||||
|
{
|
||||||
|
Name: "package/name",
|
||||||
|
Time: 160,
|
||||||
|
Tests: []Test{
|
||||||
|
{
|
||||||
|
Name: "TestOne",
|
||||||
|
Time: 60,
|
||||||
|
Result: PASS,
|
||||||
|
Output: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "TestTwo",
|
||||||
|
Time: 100,
|
||||||
|
Result: PASS,
|
||||||
|
Output: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
report, err := Parse(strings.NewReader(testOutputPass))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error parsing: %s", err)
|
t.Fatalf("error parsing: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if report == nil {
|
||||||
|
t.Fatalf("Report == nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(report.Packages) != len(expected.Packages) {
|
||||||
|
t.Fatalf("Report packages == %d, want %d", len(report.Packages), len(expected.Packages))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, pkg := range report.Packages {
|
||||||
|
expPkg := expected.Packages[i]
|
||||||
|
|
||||||
|
if pkg.Name != expPkg.Name {
|
||||||
|
t.Errorf("Package.Name == %s, want %s", pkg.Name, expPkg.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pkg.Time != expPkg.Time {
|
||||||
|
t.Errorf("Package.Time == %d, want %d", pkg.Time, expPkg.Time)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pkg.Tests) != len(expPkg.Tests) {
|
||||||
|
t.Fatalf("Package Tests == %d, want %d", len(pkg.Tests), len(expPkg.Tests))
|
||||||
|
}
|
||||||
|
|
||||||
|
for j, test := range pkg.Tests {
|
||||||
|
expTest := expPkg.Tests[j]
|
||||||
|
|
||||||
|
if test.Name != expTest.Name {
|
||||||
|
t.Errorf("Test.Name == %s, want %s", test.Name, expTest.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if test.Time != expTest.Time {
|
||||||
|
t.Errorf("Test.Time == %d, want %d", test.Time, expTest.Time)
|
||||||
|
}
|
||||||
|
|
||||||
|
if test.Result != expTest.Result {
|
||||||
|
t.Errorf("Test.Result == %d, want %d", test.Result, expTest.Result)
|
||||||
|
}
|
||||||
|
|
||||||
|
if test.Output != expTest.Output {
|
||||||
|
t.Errorf("Test.Output == %s, want %s", test.Output, expTest.Output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const testOutputFail = `=== RUN TestOne
|
const testOutputFail = `=== RUN TestOne
|
||||||
@ -32,7 +99,7 @@ exit status 1
|
|||||||
FAIL package/name 0.151s`
|
FAIL package/name 0.151s`
|
||||||
|
|
||||||
func TestOutputFail(t *testing.T) {
|
func TestOutputFail(t *testing.T) {
|
||||||
_, err := parse(strings.NewReader(testOutputPass))
|
_, err := Parse(strings.NewReader(testOutputFail))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error parsing: %s", err)
|
t.Fatalf("error parsing: %s", err)
|
||||||
}
|
}
|
||||||
|
109
parser.go
Normal file
109
parser.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Result int
|
||||||
|
|
||||||
|
const (
|
||||||
|
PASS Result = iota
|
||||||
|
FAIL Result = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
type Report struct {
|
||||||
|
Packages []Package
|
||||||
|
}
|
||||||
|
|
||||||
|
type Package struct {
|
||||||
|
Name string
|
||||||
|
Time int
|
||||||
|
Tests []Test
|
||||||
|
}
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
Name string
|
||||||
|
Time int
|
||||||
|
Result Result
|
||||||
|
Output string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
regexStatus = regexp.MustCompile(`^--- (PASS|FAIL): (.+) \((\d+\.\d+) seconds\)$`)
|
||||||
|
regexResult = regexp.MustCompile(`^(ok|FAIL)\s+(.+)\s(\d+\.\d+)s$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
func Parse(r io.Reader) (*Report, error) {
|
||||||
|
reader := bufio.NewReader(r)
|
||||||
|
|
||||||
|
report := &Report{make([]Package, 0)}
|
||||||
|
|
||||||
|
// keep track of tests we find
|
||||||
|
tests := make([]Test, 0)
|
||||||
|
|
||||||
|
// current test
|
||||||
|
var test *Test
|
||||||
|
|
||||||
|
// parse lines
|
||||||
|
for {
|
||||||
|
l, _, err := reader.ReadLine()
|
||||||
|
if err != nil && err == io.EOF {
|
||||||
|
break
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
line := string(l)
|
||||||
|
if test == nil {
|
||||||
|
// expecting new test or package result
|
||||||
|
if strings.HasPrefix(line, "=== RUN ") {
|
||||||
|
test = &Test{
|
||||||
|
Name: line[8:],
|
||||||
|
}
|
||||||
|
} else if matches := regexResult.FindStringSubmatch(line); len(matches) == 4 {
|
||||||
|
report.Packages = append(report.Packages, Package{
|
||||||
|
Name: matches[2],
|
||||||
|
Time: parseTime(matches[3]),
|
||||||
|
Tests: tests,
|
||||||
|
})
|
||||||
|
|
||||||
|
tests = make([]Test, 0)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// expecting test output or test status
|
||||||
|
if matches := regexStatus.FindStringSubmatch(line); len(matches) == 4 {
|
||||||
|
if matches[1] == "PASS" {
|
||||||
|
test.Result = PASS
|
||||||
|
} else {
|
||||||
|
test.Result = FAIL
|
||||||
|
}
|
||||||
|
|
||||||
|
test.Name = matches[2]
|
||||||
|
test.Time = parseTime(matches[3]) * 10
|
||||||
|
|
||||||
|
tests = append(tests, *test)
|
||||||
|
test = nil
|
||||||
|
} else {
|
||||||
|
if len(test.Output) > 0 {
|
||||||
|
test.Output += "\n" + line
|
||||||
|
} else {
|
||||||
|
test.Output = line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return report, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTime(time string) int {
|
||||||
|
t, err := strconv.Atoi(strings.Replace(time, ".", "", -1))
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user