mirror of https://github.com/stretchr/testify.git
TestErrorIs/TestNotErrorIs: check error contents
parent
5105b61304
commit
002647e9f8
|
@ -2908,52 +2908,202 @@ func Test_truncatingFormat(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseLabeledOutput(output string) []labeledContent {
|
||||||
|
labelPattern := regexp.MustCompile(`^\t([^\t]*): *\t(.*)$`)
|
||||||
|
contentPattern := regexp.MustCompile(`^\t *\t(.*)$`)
|
||||||
|
var contents []labeledContent
|
||||||
|
lines := strings.Split(output, "\n")
|
||||||
|
i := -1
|
||||||
|
for _, line := range lines {
|
||||||
|
if line == "" {
|
||||||
|
// skip blank lines
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
matches := labelPattern.FindStringSubmatch(line)
|
||||||
|
if len(matches) == 3 {
|
||||||
|
// a label
|
||||||
|
contents = append(contents, labeledContent{
|
||||||
|
label: matches[1],
|
||||||
|
content: matches[2] + "\n",
|
||||||
|
})
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
matches = contentPattern.FindStringSubmatch(line)
|
||||||
|
if len(matches) == 2 {
|
||||||
|
// just content
|
||||||
|
if i >= 0 {
|
||||||
|
contents[i].content += matches[1] + "\n"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Couldn't parse output
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return contents
|
||||||
|
}
|
||||||
|
|
||||||
|
type captureTestingT struct {
|
||||||
|
msg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctt *captureTestingT) Errorf(format string, args ...interface{}) {
|
||||||
|
ctt.msg = fmt.Sprintf(format, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkResultAndErrMsg(t *testing.T, expectedRes, res bool, expectedErrMsg, rawErrOutput string) {
|
||||||
|
t.Helper()
|
||||||
|
if res != expectedRes {
|
||||||
|
t.Errorf("Should return %t", expectedRes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
contents := parseLabeledOutput(rawErrOutput)
|
||||||
|
if res == true {
|
||||||
|
if contents != nil {
|
||||||
|
t.Errorf("Should not log an error")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if contents == nil {
|
||||||
|
t.Errorf("Should log an error. Log output: %v", rawErrOutput)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, content := range contents {
|
||||||
|
if content.label == "Error" {
|
||||||
|
if expectedErrMsg == content.content {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Errorf("Logged Error: %v", content.content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Errorf("Should log Error: %v", expectedErrMsg)
|
||||||
|
}
|
||||||
|
|
||||||
func TestErrorIs(t *testing.T) {
|
func TestErrorIs(t *testing.T) {
|
||||||
mockT := new(testing.T)
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
err error
|
err error
|
||||||
target error
|
target error
|
||||||
result bool
|
result bool
|
||||||
|
resultErrMsg string
|
||||||
}{
|
}{
|
||||||
{io.EOF, io.EOF, true},
|
{
|
||||||
{fmt.Errorf("wrap: %w", io.EOF), io.EOF, true},
|
err: io.EOF,
|
||||||
{io.EOF, io.ErrClosedPipe, false},
|
target: io.EOF,
|
||||||
{nil, io.EOF, false},
|
result: true,
|
||||||
{io.EOF, nil, false},
|
},
|
||||||
{nil, nil, true},
|
{
|
||||||
|
err: fmt.Errorf("wrap: %w", io.EOF),
|
||||||
|
target: io.EOF,
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: io.EOF,
|
||||||
|
target: io.ErrClosedPipe,
|
||||||
|
result: false,
|
||||||
|
resultErrMsg: "Target error should be in err chain:\n" +
|
||||||
|
"expected: \"io: read/write on closed pipe\"\n" +
|
||||||
|
"in chain: \"EOF\"\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: nil,
|
||||||
|
target: io.EOF,
|
||||||
|
result: false,
|
||||||
|
resultErrMsg: "Target error should be in err chain:\n" +
|
||||||
|
"expected: \"EOF\"\n" +
|
||||||
|
"in chain: \n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: io.EOF,
|
||||||
|
target: nil,
|
||||||
|
result: false,
|
||||||
|
resultErrMsg: "Target error should be in err chain:\n" +
|
||||||
|
"expected: \"\"\n" +
|
||||||
|
"in chain: \"EOF\"\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: nil,
|
||||||
|
target: nil,
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: fmt.Errorf("abc: %w", errors.New("def")),
|
||||||
|
target: io.EOF,
|
||||||
|
result: false,
|
||||||
|
resultErrMsg: "Target error should be in err chain:\n" +
|
||||||
|
"expected: \"EOF\"\n" +
|
||||||
|
"in chain: \"abc: def\"\n" +
|
||||||
|
"\t\"def\"\n",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
tt := tt
|
tt := tt
|
||||||
|
mockT := new(captureTestingT)
|
||||||
t.Run(fmt.Sprintf("ErrorIs(%#v,%#v)", tt.err, tt.target), func(t *testing.T) {
|
t.Run(fmt.Sprintf("ErrorIs(%#v,%#v)", tt.err, tt.target), func(t *testing.T) {
|
||||||
res := ErrorIs(mockT, tt.err, tt.target)
|
res := ErrorIs(mockT, tt.err, tt.target)
|
||||||
if res != tt.result {
|
checkResultAndErrMsg(t, tt.result, res, tt.resultErrMsg, mockT.msg)
|
||||||
t.Errorf("ErrorIs(%#v,%#v) should return %t", tt.err, tt.target, tt.result)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNotErrorIs(t *testing.T) {
|
func TestNotErrorIs(t *testing.T) {
|
||||||
mockT := new(testing.T)
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
err error
|
err error
|
||||||
target error
|
target error
|
||||||
result bool
|
result bool
|
||||||
|
resultErrMsg string
|
||||||
}{
|
}{
|
||||||
{io.EOF, io.EOF, false},
|
{
|
||||||
{fmt.Errorf("wrap: %w", io.EOF), io.EOF, false},
|
err: io.EOF,
|
||||||
{io.EOF, io.ErrClosedPipe, true},
|
target: io.EOF,
|
||||||
{nil, io.EOF, true},
|
result: false,
|
||||||
{io.EOF, nil, true},
|
resultErrMsg: "Target error should not be in err chain:\n" +
|
||||||
{nil, nil, false},
|
"found: \"EOF\"\n" +
|
||||||
|
"in chain: \"EOF\"\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: fmt.Errorf("wrap: %w", io.EOF),
|
||||||
|
target: io.EOF,
|
||||||
|
result: false,
|
||||||
|
resultErrMsg: "Target error should not be in err chain:\n" +
|
||||||
|
"found: \"EOF\"\n" +
|
||||||
|
"in chain: \"wrap: EOF\"\n" +
|
||||||
|
"\t\"EOF\"\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: io.EOF,
|
||||||
|
target: io.ErrClosedPipe,
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: nil,
|
||||||
|
target: io.EOF,
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: io.EOF,
|
||||||
|
target: nil,
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: nil,
|
||||||
|
target: nil,
|
||||||
|
result: false,
|
||||||
|
resultErrMsg: "Target error should not be in err chain:\n" +
|
||||||
|
"found: \"\"\n" +
|
||||||
|
"in chain: \n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: fmt.Errorf("abc: %w", errors.New("def")),
|
||||||
|
target: io.EOF,
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
tt := tt
|
tt := tt
|
||||||
|
mockT := new(captureTestingT)
|
||||||
t.Run(fmt.Sprintf("NotErrorIs(%#v,%#v)", tt.err, tt.target), func(t *testing.T) {
|
t.Run(fmt.Sprintf("NotErrorIs(%#v,%#v)", tt.err, tt.target), func(t *testing.T) {
|
||||||
res := NotErrorIs(mockT, tt.err, tt.target)
|
res := NotErrorIs(mockT, tt.err, tt.target)
|
||||||
if res != tt.result {
|
checkResultAndErrMsg(t, tt.result, res, tt.resultErrMsg, mockT.msg)
|
||||||
t.Errorf("NotErrorIs(%#v,%#v) should return %t", tt.err, tt.target, tt.result)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue