mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
206 lines
4.7 KiB
Go
206 lines
4.7 KiB
Go
package ui
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"io/fs"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/safedep/dry/usefulerror"
|
|
"github.com/safedep/pmg/errcodes"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func Test_ErrorConverters(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
inputError error
|
|
wantCode string
|
|
wantHumanError string
|
|
wantContains string
|
|
wantNil bool
|
|
}{
|
|
{
|
|
name: "AlreadyUseful",
|
|
inputError: usefulerror.NewUsefulError().
|
|
WithCode("CUSTOM").
|
|
WithHumanError("Already useful").
|
|
WithMsg("test"),
|
|
wantCode: "CUSTOM",
|
|
wantHumanError: "Already useful",
|
|
},
|
|
{
|
|
name: "FileNotExist",
|
|
inputError: &fs.PathError{Op: "open", Path: "/nonexistent/file.txt", Err: os.ErrNotExist},
|
|
wantCode: errcodes.NotFound,
|
|
wantContains: "/nonexistent/file.txt",
|
|
},
|
|
{
|
|
name: "PermissionDenied",
|
|
inputError: &fs.PathError{Op: "open", Path: "/root/secret", Err: os.ErrPermission},
|
|
wantCode: errcodes.PermissionDenied,
|
|
wantContains: "/root/secret",
|
|
},
|
|
{
|
|
name: "ContextTimeout",
|
|
inputError: context.DeadlineExceeded,
|
|
wantCode: errcodes.Timeout,
|
|
wantContains: "timed out",
|
|
},
|
|
{
|
|
name: "ContextCanceled",
|
|
inputError: context.Canceled,
|
|
wantCode: errcodes.Canceled,
|
|
wantContains: "canceled",
|
|
},
|
|
{
|
|
name: "UnexpectedEOF",
|
|
inputError: io.ErrUnexpectedEOF,
|
|
wantCode: errcodes.UnexpectedEOF,
|
|
},
|
|
{
|
|
name: "WrappedError",
|
|
inputError: fmt.Errorf("failed to read config: %w", os.ErrNotExist),
|
|
wantCode: errcodes.NotFound,
|
|
},
|
|
{
|
|
name: "UnknownError",
|
|
inputError: errors.New("some unknown error"),
|
|
wantNil: true,
|
|
},
|
|
{
|
|
name: "UnknownWrappedError",
|
|
inputError: fmt.Errorf("more context: %w",
|
|
fmt.Errorf("outer context: %w",
|
|
errors.New("root cause error"))),
|
|
wantNil: true,
|
|
},
|
|
{
|
|
name: "Nil",
|
|
inputError: nil,
|
|
wantNil: true,
|
|
},
|
|
{
|
|
name: "NetworkErrorMessage",
|
|
inputError: errors.New("connection refused"),
|
|
wantCode: errcodes.Network,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result, ok := usefulerror.AsUsefulError(tt.inputError)
|
|
|
|
if tt.wantNil {
|
|
assert.False(t, ok)
|
|
return
|
|
}
|
|
|
|
assert.True(t, ok)
|
|
assert.NotNil(t, result)
|
|
assert.Equal(t, tt.wantCode, result.Code())
|
|
|
|
if tt.wantHumanError != "" {
|
|
assert.Equal(t, tt.wantHumanError, result.HumanError())
|
|
}
|
|
|
|
if tt.wantContains != "" {
|
|
assert.Contains(t, result.HumanError(), tt.wantContains)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_convertToUsefulError(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
inputError error
|
|
wantCode string
|
|
wantHumanError string
|
|
wantNil bool
|
|
}{
|
|
{
|
|
name: "Nil",
|
|
inputError: nil,
|
|
wantNil: true,
|
|
},
|
|
{
|
|
name: "AlreadyUseful",
|
|
inputError: usefulerror.NewUsefulError().
|
|
WithCode("CUSTOM").
|
|
WithHumanError("Already useful"),
|
|
wantCode: "CUSTOM",
|
|
wantHumanError: "Already useful",
|
|
},
|
|
{
|
|
name: "Converted",
|
|
inputError: &fs.PathError{Op: "open", Path: "/nonexistent/file.txt", Err: os.ErrNotExist},
|
|
wantCode: errcodes.NotFound,
|
|
wantHumanError: "File or directory not found: /nonexistent/file.txt",
|
|
},
|
|
{
|
|
name: "UnknownFallsBackToRootCause",
|
|
inputError: errors.New("some unknown error"),
|
|
wantCode: errcodes.Unknown,
|
|
wantHumanError: "some unknown error",
|
|
},
|
|
{
|
|
name: "UnknownWrappedExtractsRootCause",
|
|
inputError: fmt.Errorf("more context: %w",
|
|
fmt.Errorf("outer context: %w",
|
|
errors.New("root cause error"))),
|
|
wantCode: errcodes.Unknown,
|
|
wantHumanError: "root cause error",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := convertToUsefulError(tt.inputError)
|
|
|
|
if tt.wantNil {
|
|
assert.Nil(t, result)
|
|
return
|
|
}
|
|
|
|
assert.NotNil(t, result)
|
|
assert.Equal(t, tt.wantCode, result.Code())
|
|
assert.Equal(t, tt.wantHumanError, result.HumanError())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractPathFromError(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
inputErr error
|
|
wantPath string
|
|
}{
|
|
{
|
|
name: "PathError",
|
|
inputErr: &fs.PathError{Op: "open", Path: "/some/path", Err: os.ErrNotExist},
|
|
wantPath: "/some/path",
|
|
},
|
|
{
|
|
name: "LinkError",
|
|
inputErr: &os.LinkError{Op: "link", Old: "/old/path", New: "/new/path", Err: os.ErrPermission},
|
|
wantPath: "/old/path",
|
|
},
|
|
{
|
|
name: "generic error",
|
|
inputErr: errors.New("some error"),
|
|
wantPath: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
path := extractPathFromError(tt.inputErr)
|
|
assert.Equal(t, tt.wantPath, path)
|
|
})
|
|
}
|
|
}
|