oss.indeed.com/go/go-opine@v1.3.0/internal/gotest/workaround_go_issue_35180.go (about)

     1  package gotest
     2  
     3  import (
     4  	"regexp"
     5  	"strconv"
     6  	"strings"
     7  	"time"
     8  )
     9  
    10  var workaroundGoIssue35180Regexp = regexp.MustCompile(`\n((?:exit status \d+\n)?FAIL\s+(\S+)\s+(\S+)(?:\s+coverage:[^\n]+)?\n)$`)
    11  
    12  const (
    13  	workaroundGoIssue35180RegexpOutput  = 1
    14  	workaroundGoIssue35180RegexpPackage = 2
    15  	workaroundGoIssue35180RegexpElapsed = 3
    16  )
    17  
    18  // workaroundGoIssue35180ResultAccepter detects when a failed
    19  // test result ends with output normally associated with a package
    20  // result and injects the package result. This is to work around Go
    21  // issue https://github.com/golang/go/issues/35180.
    22  type workaroundGoIssue35180ResultAccepter struct {
    23  	next resultAccepter
    24  }
    25  
    26  var _ resultAccepter = (*workaroundGoIssue35180ResultAccepter)(nil)
    27  
    28  func newWorkaroundGoIssue35180ResultAccepter(next resultAccepter) resultAccepter {
    29  	return &workaroundGoIssue35180ResultAccepter{next: next}
    30  }
    31  
    32  func (w *workaroundGoIssue35180ResultAccepter) Accept(res result) error {
    33  	if res.Outcome != "fail" || res.Key.Test == "" {
    34  		return w.next.Accept(res)
    35  	}
    36  
    37  	match := workaroundGoIssue35180Regexp.FindStringSubmatch(res.Output)
    38  	if match == nil || match[workaroundGoIssue35180RegexpPackage] != res.Key.Package { //nolint:gocritic
    39  		return w.next.Accept(res)
    40  	}
    41  	matchOutput := match[workaroundGoIssue35180RegexpOutput]
    42  	matchElapsed := match[workaroundGoIssue35180RegexpElapsed]
    43  
    44  	res.Output = res.Output[:len(res.Output)-len(matchOutput)]
    45  	if err := w.next.Accept(res); err != nil {
    46  		return err
    47  	}
    48  
    49  	pkgRes := result{
    50  		Key:     resultKey{Package: res.Key.Package},
    51  		Outcome: "fail",
    52  		Output:  matchOutput,
    53  	}
    54  	if strings.HasSuffix(matchElapsed, "s") {
    55  		if elapsedSecs, err := strconv.ParseFloat(matchElapsed[:len(matchElapsed)-1], 64); err == nil {
    56  			pkgRes.Elapsed = time.Duration(elapsedSecs * float64(time.Second))
    57  		}
    58  	}
    59  	return w.next.Accept(pkgRes)
    60  }