Skip to content

Commit

Permalink
Merge pull request #2 from utgwkk/generator-better-error-message
Browse files Browse the repository at this point in the history
generator: better error message
  • Loading branch information
utgwkk committed Jul 9, 2023
2 parents 1f8bb72 + 0b7b77b commit 3754ed3
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 9 deletions.
5 changes: 5 additions & 0 deletions generator/fixtures/ng/invalid_expr/prog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package invalidexpr

var Iset = []any{
1,
}
1 change: 1 addition & 0 deletions generator/fixtures/ng/no_mock_set/prog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package foo
9 changes: 9 additions & 0 deletions generator/fixtures/ng/not_a_new_function/prog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package foo

var Iset = []any{
f(2),
}

func f(x int) int {
return x + 1
}
3 changes: 3 additions & 0 deletions generator/fixtures/ng/not_a_slice/prog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package notaslice

var Iset = 1
5 changes: 5 additions & 0 deletions generator/fixtures/ng/not_an_interface/prog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package foo

var Iset = []any{
new(*error),
}
23 changes: 14 additions & 9 deletions generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (g *Generator) findMockSetFromDirectory(sourceDir string) ([]string, error)
}
for _, p := range parsed {
for _, f := range p.Files {
mockSet, err := lookupFromScope(f.Scope, g.MockSetName)
mockSet, err := lookupFromScope(fset, f.Scope, g.MockSetName)
if err != nil {
if errors.Is(err, errMockSetNotFound) {
continue
Expand All @@ -95,7 +95,7 @@ func (g *Generator) findMockSetFromDirectory(sourceDir string) ([]string, error)

var errMockSetNotFound = errors.New("mock set notfound")

func lookupFromScope(s *ast.Scope, mockSetName string) ([]string, error) {
func lookupFromScope(fset *token.FileSet, s *ast.Scope, mockSetName string) ([]string, error) {
obj := s.Lookup(mockSetName)
if obj == nil {
return nil, errMockSetNotFound
Expand All @@ -112,34 +112,39 @@ func lookupFromScope(s *ast.Scope, mockSetName string) ([]string, error) {
for _, v := range vs.Values {
cmp, ok := v.(*ast.CompositeLit)
if !ok {
return nil, errors.New("not a interface slice")
return nil, newInvalidMockSetError("mock set is not a slice", fset, v)
}
for _, v := range cmp.Elts {
funCall, ok := v.(*ast.CallExpr)
if !ok {
return nil, errors.New("invalid mock set (contains non-new(...) expression)")
return nil, newInvalidMockSetError("mock set contains not a function call", fset, v)
}
// new(...)
newIdent, ok := funCall.Fun.(*ast.Ident)
if !ok {
return nil, errors.New("invalid mock set (contains non-new(...) expression)")
return nil, newInvalidMockSetError("mock set contains not a new(...) function call", fset, v)
}
if newIdent.Name != "new" {
return nil, errors.New("invalid mock set (contains non-new(...) expression)")
return nil, newInvalidMockSetError("mock set contains not a new(...) function call", fset, v)
}
if len(funCall.Args) != 1 {
return nil, errors.New("invalid mock set (contains non-new(...) expression)")
return nil, newInvalidMockSetError("mock set contains not a new(...) function call", fset, v)
}
arg := funCall.Args[0]
argIdent, ok := arg.(*ast.Ident)
if !ok {
return nil, errors.New("invalid mock set (contains non-new(...) expression)")
return nil, newInvalidMockSetError("not an interface is passed to new(...) function call", fset, arg)
}
if len(funCall.Args) != 1 {
return nil, errors.New("invalid mock set (contains non-new(...) expression)")
return nil, newInvalidMockSetError("mock set contains not a new(...) function call", fset, v)
}
mockSet = append(mockSet, argIdent.Name)
}
}
return mockSet, nil
}

func newInvalidMockSetError(msg string, fset *token.FileSet, e ast.Expr) error {
pos := fset.Position(e.Pos())
return fmt.Errorf("%s at file %s, line %d, column %d", msg, pos.Filename, pos.Line, pos.Column)
}
62 changes: 62 additions & 0 deletions generator/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package generator

import (
"context"
"go/ast"
"go/parser"
"go/token"
"os"
"testing"

Expand Down Expand Up @@ -78,3 +81,62 @@ func TestGenerate(t *testing.T) {
})
}
}

func prepareScope(t *testing.T, file string) (*token.FileSet, *ast.Scope) {
t.Helper()

fset := token.NewFileSet()
parsed, err := parser.ParseFile(fset, file, nil, 0)
require.NoError(t, err)

return fset, parsed.Scope
}

func TestLookupFromScope(t *testing.T) {
testcases := []struct {
name string
inputFile string
inputMockSetName string
wantErrMsg string
}{
{
name: "not found",
inputFile: "./fixtures/ng/no_mock_set/prog.go",
inputMockSetName: "NotFound",
wantErrMsg: "mock set notfound",
},
{
name: "invalid expression",
inputFile: "./fixtures/ng/invalid_expr/prog.go",
inputMockSetName: "Iset",
wantErrMsg: "mock set contains not a function call at file ./fixtures/ng/invalid_expr/prog.go, line 4, column 2",
},
{
name: "not a new function call",
inputFile: "./fixtures/ng/not_a_new_function/prog.go",
inputMockSetName: "Iset",
wantErrMsg: "mock set contains not a new(...) function call at file ./fixtures/ng/not_a_new_function/prog.go, line 4, column 2",
},
{
name: "new takes not an interface",
inputFile: "./fixtures/ng/not_an_interface/prog.go",
inputMockSetName: "Iset",
wantErrMsg: "not an interface is passed to new(...) function call at file ./fixtures/ng/not_an_interface/prog.go, line 4, column 6",
},
{
name: "not a slice",
inputFile: "./fixtures/ng/not_a_slice/prog.go",
inputMockSetName: "Iset",
wantErrMsg: "mock set is not a slice at file ./fixtures/ng/not_a_slice/prog.go, line 3, column 12",
},
}
for _, tc := range testcases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
fset, s := prepareScope(t, tc.inputFile)
_, err := lookupFromScope(fset, s, tc.inputMockSetName)
require.Error(t, err)
assert.Equal(t, tc.wantErrMsg, err.Error())
})
}
}

0 comments on commit 3754ed3

Please sign in to comment.