Skip to content

Commit

Permalink
refactor: basic test concepts to introduce test timeout (#93)
Browse files Browse the repository at this point in the history
Signed-off-by: Tronje Krop <[email protected]>
  • Loading branch information
Tronje Krop committed Oct 16, 2024
1 parent 9f2193c commit 02c0265
Show file tree
Hide file tree
Showing 25 changed files with 1,658 additions and 1,451 deletions.
20 changes: 15 additions & 5 deletions internal/mock/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ const (
dirTop = "../../.."
dirMock = "mock"

dirTest = "./test"
dirSubTest = "./test"
dirOther = "../other"
dirUnknown = "../unknown"
dirTesting = "../../test"
dirTest = "../../test"

pathMock = "github.com/tkrop/go-testing/internal/mock"
pathTest = "github.com/tkrop/go-testing/internal/mock/test"
Expand All @@ -43,7 +43,7 @@ const (
fileOther = "mock_other_test.go"
fileTemplate = "mock_template_test.go"
fileUnknown = "unnkown_test.go"
fileTesting = "testing.go"
fileContext = "context.go"

aliasMock = "mock_" + pkgTest
aliasInt = "internal_" + aliasMock
Expand All @@ -60,6 +60,8 @@ const (
var (
errAny = errors.New("any error")

absUnknown, _ = filepath.Abs(dirUnknown)

nameIFace = &Type{Name: iface}
nameIFaceMock = &Type{Name: ifaceMock}

Expand Down Expand Up @@ -126,7 +128,7 @@ func methodsMockIFaceFunc(mocktest, test, mock string) []*Method {
}, {
Name: "CallC",
Params: []*Param{{
Name: "test", Type: aliasType(test, "Tester"),
Name: "test", Type: aliasType(test, "Context"),
}},
Results: []*Param{},
Variadic: false,
Expand All @@ -136,7 +138,7 @@ func methodsMockIFaceFunc(mocktest, test, mock string) []*Method {
var (
// Use two different singleton loaders.
loaderMock = NewLoader(DirDefault)
loaderTest = NewLoader(dirTest)
loaderTest = NewLoader(dirSubTest)
loaderFail = NewLoader(dirUnknown)

// Use singleton template for testing.
Expand Down Expand Up @@ -170,6 +172,14 @@ var (
pathTest, pathTesting, pathMock)

methodsTestTest = []*Method{{
Name: "Deadline",
Params: []*Param{},
Results: []*Param{
{Name: "deadline", Type: "time.Time"},
{Name: "ok", Type: "bool"},
},
Variadic: false,
}, {
Name: "Errorf",
Params: []*Param{
{Name: "format", Type: "string"},
Expand Down
12 changes: 9 additions & 3 deletions internal/mock/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/tools/go/packages"

"github.com/tkrop/go-testing/test"

Expand All @@ -36,7 +37,7 @@ var (
return dir
}()

fileFailure = filepath.Join(testDirGenerate, dirTest, fileUnknown)
fileFailure = filepath.Join(testDirGenerate, dirSubTest, fileUnknown)
)

var testGenerateParams = map[string]GenerateParams{
Expand All @@ -49,8 +50,13 @@ var testGenerateParams = map[string]GenerateParams{
"failure parsing": {
file: filepath.Join(testDirGenerate, MockFileDefault),
args: []string{pathUnknown},
expectStderr: "argument invalid [pos: 3, arg: " + pathUnknown +
"]: not found\n",
expectStderr: NewErrArgFailure(3, ".",
NewErrPackageParsing(pathUnknown, []*packages.Package{
{Errors: []packages.Error{{
Msg: "no required module provides package " + pathUnknown +
"; to add it:\n\tgo get " + pathUnknown,
}}},
})).Error() + "\n",
expectCode: 1,
},

Expand Down
4 changes: 2 additions & 2 deletions internal/mock/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ var testLoaderLoadParams = map[string]LoaderLoadParams{
"failure loading": {
loader: loaderFail,
source: targetTest.With(&Type{
File: filepath.Join(dirUp, dirMock, dirTest, fileIFace),
File: filepath.Join(dirUp, dirMock, dirSubTest, fileIFace),
}),
expectError: NewErrLoading(pathTest, fmt.Errorf(
"err: chdir %s: no such file or directory: stderr: ",
Expand Down Expand Up @@ -315,7 +315,7 @@ var testLoaderIFacesParams = map[string]LoaderIFacesParams{
"failure loading": {
loader: loaderFail,
source: targetTest.With(&Type{
File: filepath.Join(dirUp, dirMock, dirTest, fileIFace),
File: filepath.Join(dirUp, dirMock, dirSubTest, fileIFace),
}),
expectError: NewErrLoading(pathTest, fmt.Errorf(
"err: chdir %s: no such file or directory: stderr: ",
Expand Down
4 changes: 2 additions & 2 deletions internal/mock/mock_iface_test.gox
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ func (mr *MockIFaceRecorder) CallB() *gomock.Call {
}

// CallC is the mock method to capture a coresponding call.
func (m *MockIFace) CallC(test testing_test.Tester) {
func (m *MockIFace) CallC(test testing_test.Context) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "CallC", test)
}

// CallC is the recorder method to indicates an expected call.
func (mr *MockIFaceRecorder) CallC(test testing_test.Tester) *gomock.Call {
func (mr *MockIFaceRecorder) CallC(test testing_test.Context) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallC",
reflect.TypeOf((*MockIFace)(nil).CallC), test)
Expand Down
25 changes: 8 additions & 17 deletions internal/mock/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ func (parser *Parser) Parse(args ...string) ([]*Mock, []error) {
// value and returns the argument type with the remaining argument value.
func (parser *Parser) argType(arg string) (argType, string) {
if strings.Index(arg, "--") == 0 {
if !strings.Contains(arg, "=") {
return argTypeUnknown, arg
}
return parser.argTypeParse(arg)
}
return parser.argTypeGuess(arg)
Expand Down Expand Up @@ -217,26 +220,14 @@ func (parser *Parser) argTypeGuess(arg string) (argType, string) {
}
}

// TODO: Reconsider the early failure handling approach here.
//
// This early failure handing may not be necessary and undesired. It has
// the drawback to prevents generating mocks for broken code, as well as
// for partially loaded packages defined by incomplete sets of files.
//
// It looks not to complicated to drop the early failure handling and
// change the four effected tests. The alternative solution to drop support
// for partial package loading via single file loading or automatically
// load the whole package is not very desirable and complicates code.
//
// pkgs, _ := parser.loader.Load(arg).Get()
// if len(pkgs) > 0 {
pkgs, err := parser.loader.Load(arg).Get()
if len(pkgs) > 0 && err == nil {
pkgs, _ := parser.loader.Load(arg).Get()
if len(pkgs) > 0 {
if pkgs[0].PkgPath == ReadFromFile {
return argTypeSourceFile, arg
}
return argTypeSourcePath, arg
}
// #no-cover: impossible to reach this code?
return argTypeNotFound, arg
}

Expand Down Expand Up @@ -270,7 +261,7 @@ func (state *ParseState) ensureSource() *ParseState {
// interfaces in the source package.
func (state *ParseState) ensureIFace(pos int) {
if state.source.IsPartial() {
state.creatMocks(pos, "")
state.creatMocks(pos, ".")
}
}

Expand All @@ -282,7 +273,7 @@ func (state *ParseState) ensureState(arg string) {
state.source.Update(state.loader)
state.target.Update(state.loader)

if arg == "" {
if arg == "." {
state.source.Name = MatchPatternDefault
state.target.Name = MockPatternDefault
return
Expand Down
59 changes: 41 additions & 18 deletions internal/mock/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/assert"
. "github.com/tkrop/go-testing/internal/mock"
"github.com/tkrop/go-testing/test"
"golang.org/x/tools/go/packages"
)

var (
Expand All @@ -34,11 +35,17 @@ var testParseParams = map[string]ParseParams{
Methods: methodsLoadIFace,
}},
},
"invalid argument": {
"invalid argument flag": {
loader: loaderTest,
args: []string{"--test"},
expectError: []error{NewErrArgInvalid(0, "--test")},
},
"invalid argument unknown": {
loader: loaderTest,
args: []string{"--unknown=any"},
expectError: []error{NewErrArgInvalid(0, "--unknown=any")},
},
// TODO: add test case for invalid argument for guessed type not found.

"default file": {
loader: loaderTest,
Expand Down Expand Up @@ -140,13 +147,19 @@ var testParseParams = map[string]ParseParams{
loader: loaderMock,
args: []string{pathUnknown},
expectError: []error{
NewErrArgNotFound(0, pathUnknown),
NewErrArgFailure(0, ".",
NewErrPackageParsing(absUnknown, []*packages.Package{{
Errors: []packages.Error{{
Msg: "stat " + absUnknown + ": directory not found",
}},
}}),
),
},
},

"source file explicit": {
loader: loaderMock,
args: []string{"--source-file=" + dirTest + "/" + fileIFace},
args: []string{"--source-file=" + dirSubTest + "/" + fileIFace},
expectMocks: []*Mock{{
Source: sourceIFaceAny,
Target: targetMockTestIFace,
Expand All @@ -155,7 +168,7 @@ var testParseParams = map[string]ParseParams{
},
"source file derived": {
loader: loaderMock,
args: []string{"--source=" + dirTest + "/" + fileIFace},
args: []string{"--source=" + dirSubTest + "/" + fileIFace},
expectMocks: []*Mock{{
Source: sourceIFaceAny,
Target: targetMockTestIFace,
Expand All @@ -174,7 +187,7 @@ var testParseParams = map[string]ParseParams{
},
"source file guessed": {
loader: loaderMock,
args: []string{dirTest + "/" + fileIFace},
args: []string{dirSubTest + "/" + fileIFace},
expectMocks: []*Mock{{
Source: sourceIFaceAny,
Target: targetMockTestIFace,
Expand All @@ -185,13 +198,20 @@ var testParseParams = map[string]ParseParams{
loader: loaderMock,
args: []string{fileUnknown},
expectError: []error{
NewErrArgNotFound(0, fileUnknown),
NewErrArgFailure(0, ".",
NewErrPackageParsing(fileUnknown, []*packages.Package{{
Errors: []packages.Error{{
Msg: "no required module provides package " + fileUnknown +
"; to add it:\n\tgo get " + fileUnknown,
}},
}}),
),
},
},

"source directory explicit": {
loader: loaderMock,
args: []string{"--source-file=" + dirTest},
args: []string{"--source-file=" + dirSubTest},
expectMocks: []*Mock{{
Source: sourceIFaceAny,
Target: targetMockTestIFace,
Expand All @@ -200,7 +220,7 @@ var testParseParams = map[string]ParseParams{
},
"source directory derived": {
loader: loaderMock,
args: []string{"--source=" + dirTest},
args: []string{"--source=" + dirSubTest},
expectMocks: []*Mock{{
Source: sourceIFaceAny,
Target: targetMockTestIFace,
Expand All @@ -209,7 +229,7 @@ var testParseParams = map[string]ParseParams{
},
"source directory guessed": {
loader: loaderMock,
args: []string{dirTest},
args: []string{dirSubTest},
expectMocks: []*Mock{{
Source: sourceIFaceAny,
Target: targetMockTestIFace,
Expand All @@ -220,7 +240,13 @@ var testParseParams = map[string]ParseParams{
loader: loaderMock,
args: []string{dirUnknown},
expectError: []error{
NewErrArgNotFound(0, dirUnknown),
NewErrArgFailure(0, ".",
NewErrPackageParsing(dirUnknown, []*packages.Package{{
Errors: []packages.Error{{
Msg: "stat " + absUnknown + ": directory not found",
}},
}}),
),
},
},

Expand Down Expand Up @@ -457,10 +483,10 @@ var testParseParams = map[string]ParseParams{
"failure loading": {
loader: loaderFail,
args: []string{
"--source-file=" + filepath.Join(dirUp, dirMock, dirTest, fileIFace),
"--source-file=" + filepath.Join(dirUp, dirMock, dirSubTest, fileIFace),
},
expectError: []error{
NewErrArgFailure(0, "", NewErrLoading("", fmt.Errorf(
NewErrArgFailure(0, ".", NewErrLoading("", fmt.Errorf(
"err: chdir %s: no such file or directory: stderr: ",
dirUnknown))),
},
Expand Down Expand Up @@ -488,7 +514,7 @@ var testParseAddParams = map[string]ParseParams{
"package test path": {
loader: loaderMock,
args: []string{
dirTesting, "Test",
dirTest, "Test",
"--target=" + pkgMock, "Reporter=Reporter",
},
expectMocks: []*Mock{{
Expand All @@ -505,7 +531,7 @@ var testParseAddParams = map[string]ParseParams{
"package test file": {
loader: loaderMock,
args: []string{
dirTesting + "/" + fileTesting, "Test",
dirTest + "/" + fileContext, "Test",
"--target=" + pkgMock, "Reporter=Reporter",
},
expectMocks: []*Mock{{
Expand Down Expand Up @@ -569,8 +595,5 @@ func TestParseMain(t *testing.T) {
}

func TestParseAdd(t *testing.T) {
test.Map(t, testParseAddParams).
// TODO: removed when Find feature migration implemented.
// Filter("package-test-file", true).
Run(testParse)
test.Map(t, testParseAddParams).Run(testParse)
}
2 changes: 1 addition & 1 deletion internal/mock/test/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type IFace interface {
CallA(value *Struct, args ...*reflect.Value) ([]any, error)
//revive:disable-next-line:use-any // needed for testing
CallB() (fn func([]*mock.File) []interface{}, err error)
CallC(test test.Tester)
CallC(test test.Context)
}

// Struct is a non-interface for testing.
Expand Down
2 changes: 1 addition & 1 deletion internal/mock/testx/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type IFace interface {
CallA(value *Struct, args ...*reflect.Value) ([]any, error)
//revive:disable-next-line:use-any // needed for testing
CallB() (fn func([]*mock.File) []interface{}, err error)
CallC(test test.Tester)
CallC(test test.Context)
}

// Struct is a non-interface for testing.
Expand Down
Loading

0 comments on commit 02c0265

Please sign in to comment.