Skip to content

Commit

Permalink
move to travis and satisfy lint and vet
Browse files Browse the repository at this point in the history
  • Loading branch information
nelsam committed May 30, 2018
1 parent 1cb8121 commit 21d62e1
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 13 deletions.
24 changes: 24 additions & 0 deletions .travis.yml
@@ -0,0 +1,24 @@
language: go

os:
- linux
- osx

go:
- "1.9.6"
- "1.10.2"
- tip

matrix:
allow_failures:
- go: tip

install:
- go get golang.org/x/lint/golint
- go get -t -v -d ./...

script:
- go vet ./...
- golint -set_exit_status ./...
- go test -v -race -parallel 4 ./...
- go build
2 changes: 1 addition & 1 deletion README.md
@@ -1,4 +1,4 @@
[![Build Status](https://drone.io/github.com/nelsam/hel/status.png)](https://drone.io/github.com/nelsam/hel/latest)
[![Build Status](https://travis-ci.org/nelsam/hel.svg?branch=master)](https://travis-ci.org/nelsam/hel)

# Hel

Expand Down
2 changes: 1 addition & 1 deletion main.go
Expand Up @@ -42,7 +42,7 @@ func init() {
"guess how much I like mocks.",
Run: func(cmd *cobra.Command, args []string) {
if len(args) > 0 {
fmt.Println("Invalid usage. Help:\n")
fmt.Print("Invalid usage. Help:\n\n")
cmd.HelpFunc()(nil, nil)
os.Exit(1)
}
Expand Down
File renamed without changes.
9 changes: 9 additions & 0 deletions mocks/method.go
Expand Up @@ -19,12 +19,15 @@ const (
receiverName = "m"
)

// Method represents a method that is being mocked.
type Method struct {
receiver Mock
name string
implements *ast.FuncType
}

// MethodFor returns a Method representing typ, using receiver as
// the Method's receiver type and name as the method name.
func MethodFor(receiver Mock, name string, typ *ast.FuncType) Method {
return Method{
receiver: receiver,
Expand All @@ -33,6 +36,7 @@ func MethodFor(receiver Mock, name string, typ *ast.FuncType) Method {
}
}

// Ast returns the ast representation of m.
func (m Method) Ast() *ast.FuncDecl {
f := &ast.FuncDecl{}
f.Name = &ast.Ident{Name: m.name}
Expand All @@ -42,6 +46,8 @@ func (m Method) Ast() *ast.FuncDecl {
return f
}

// Fields returns the fields that need to be a part of the receiver
// struct for this method.
func (m Method) Fields() []*ast.Field {
fields := []*ast.Field{
{
Expand Down Expand Up @@ -268,6 +274,9 @@ func (m Method) inputs() (stmts []ast.Stmt) {
return stmts
}

// PrependLocalPackage prepends name as the package name for local types
// in m's signature. This is most often used when mocking types that are
// imported by the local package.
func (m Method) PrependLocalPackage(name string) {
m.prependPackage(name, m.implements.Results)
m.prependPackage(name, m.implements.Params)
Expand Down
15 changes: 15 additions & 0 deletions mocks/mock.go
Expand Up @@ -12,12 +12,15 @@ import (
"unicode"
)

// Mock is a mock of an interface type.
type Mock struct {
typeName string
implements *ast.InterfaceType
blockingReturn *bool
}

// For returns a Mock representing typ. An error will be returned
// if a mock cannot be created from typ.
func For(typ *ast.TypeSpec) (Mock, error) {
inter, ok := typ.Type.(*ast.InterfaceType)
if !ok {
Expand All @@ -32,10 +35,13 @@ func For(typ *ast.TypeSpec) (Mock, error) {
return m, nil
}

// Name returns the type name for m.
func (m Mock) Name() string {
return "mock" + strings.ToUpper(m.typeName[0:1]) + m.typeName[1:]
}

// Methods returns the methods that need to be created with m
// as a receiver.
func (m Mock) Methods() (methods []Method) {
for _, method := range m.implements.Methods.List {
switch methodType := method.Type.(type) {
Expand All @@ -46,16 +52,23 @@ func (m Mock) Methods() (methods []Method) {
return
}

// PrependLocalPackage prepends name as the package name for local types
// in m's signature. This is most often used when mocking types that are
// imported by the local package.
func (m Mock) PrependLocalPackage(name string) {
for _, m := range m.Methods() {
m.PrependLocalPackage(name)
}
}

// SetBlockingReturn sets whether or not methods will include a blocking
// return channel, most often used for testing data races.
func (m Mock) SetBlockingReturn(blockingReturn bool) {
*m.blockingReturn = blockingReturn
}

// Constructor returns a function AST to construct m. chanSize will be
// the buffer size for all channels initialized in the constructor.
func (m Mock) Constructor(chanSize int) *ast.FuncDecl {
decl := &ast.FuncDecl{}
typeRunes := []rune(m.Name())
Expand All @@ -72,6 +85,7 @@ func (m Mock) Constructor(chanSize int) *ast.FuncDecl {
return decl
}

// Decl returns the declaration AST for m.
func (m Mock) Decl() *ast.GenDecl {
spec := &ast.TypeSpec{}
spec.Name = &ast.Ident{Name: m.Name()}
Expand All @@ -82,6 +96,7 @@ func (m Mock) Decl() *ast.GenDecl {
}
}

// Ast returns all declaration AST for m.
func (m Mock) Ast(chanSize int) []ast.Decl {
decls := []ast.Decl{
m.Decl(),
Expand Down
17 changes: 15 additions & 2 deletions mocks/mocks.go
Expand Up @@ -2,6 +2,8 @@
// domain. For more information, see <http://unlicense.org> or the
// accompanying UNLICENSE file.

//go:generate hel

package mocks

import (
Expand All @@ -26,15 +28,19 @@ const commentHeader = `// This file was generated by github.com/nelsam/hel. Do
`

//go:generate hel --type TypeFinder --output mock_type_finder_test.go

// TypeFinder represents a type which knows about types and dependencies.
type TypeFinder interface {
ExportedTypes() (types []*ast.TypeSpec)
Dependencies(inter *ast.InterfaceType) (dependencies []types.Dependency)
}

// Mocks is a slice of Mock values.
type Mocks []Mock

// Output writes the go code representing m to dest. pkg will be the
// package name; dir is the destination directory (needed for formatting
// the file); chanSize is the buffer size of any channels created in
// constructors.
func (m Mocks) Output(pkg, dir string, chanSize int, dest io.Writer) error {
if _, err := dest.Write([]byte(commentHeader)); err != nil {
return err
Expand Down Expand Up @@ -66,12 +72,17 @@ func (m Mocks) Output(pkg, dir string, chanSize int, dest io.Writer) error {
return format.Node(dest, fset, file)
}

// PrependLocalPackage prepends name as the package name for local types
// in m's signature. This is most often used when mocking types that are
// imported by the local package.
func (m Mocks) PrependLocalPackage(name string) {
for _, m := range m {
m.PrependLocalPackage(name)
}
}

// SetBlockingReturn sets whether or not methods will include a blocking
// return channel, most often used for testing data races.
func (m Mocks) SetBlockingReturn(blockingReturn bool) {
for _, m := range m {
m.SetBlockingReturn(blockingReturn)
Expand Down Expand Up @@ -127,6 +138,8 @@ func getImports(dirPath string, fset *token.FileSet) ([]*ast.ImportSpec, error)
return imports, nil
}

// Generate generates a Mocks value for all exported interface
// types returned by finder.
func Generate(finder TypeFinder) (Mocks, error) {
base := finder.ExportedTypes()
var (
Expand Down
14 changes: 6 additions & 8 deletions mocks/mocks_test.go
Expand Up @@ -63,10 +63,8 @@ func TestOutput(t *testing.T) {
expect(err).To.Be.Nil().Else.FailNow()

buf := bytes.Buffer{}
m.Output("foo", "test/without_imports", 100, &buf)
m.Output("foo", "test/withoutimports", 100, &buf)

// TODO: For some reason, functions are coming out without
// whitespace between them. We need to figure that out.
expected, err := format.Source([]byte(`
// This file was generated by github.com/nelsam/hel. Do not
// edit this code by hand unless you *really* know what you're
Expand Down Expand Up @@ -141,7 +139,7 @@ func TestOutput(t *testing.T) {

m.PrependLocalPackage("foo")
buf = bytes.Buffer{}
m.Output("foo_test", "test/without_imports", 100, &buf)
m.Output("foo_test", "test/withoutimports", 100, &buf)

expected, err = format.Source([]byte(`
// This file was generated by github.com/nelsam/hel. Do not
Expand Down Expand Up @@ -217,7 +215,7 @@ func TestOutput(t *testing.T) {

m.SetBlockingReturn(true)
buf = bytes.Buffer{}
m.Output("foo_test", "test/without_imports", 100, &buf)
m.Output("foo_test", "test/withoutimports", 100, &buf)

expected, err = format.Source([]byte(`
// This file was generated by github.com/nelsam/hel. Do not
Expand Down Expand Up @@ -362,7 +360,7 @@ func TestOutput_Dependencies(t *testing.T) {
expect(err).To.Be.Nil().Else.FailNow()

buf := bytes.Buffer{}
m.Output("foo", "test/without_imports", 100, &buf)
m.Output("foo", "test/withoutimports", 100, &buf)

// TODO: For some reason, functions are coming out without
// whitespace between them. We need to figure that out.
Expand Down Expand Up @@ -480,7 +478,7 @@ func TestOutputWithPackageInputs(t *testing.T) {
expect(err).To.Be.Nil().Else.FailNow()

buf := bytes.Buffer{}
m.Output("foo", "test/with_imports", 100, &buf)
m.Output("foo", "test/withimports", 100, &buf)

expected, err := format.Source([]byte(`
// This file was generated by github.com/nelsam/hel. Do not
Expand Down Expand Up @@ -577,7 +575,7 @@ func TestOutput_ReceiverNameInArgs(t *testing.T) {
expect(err).To.Be.Nil().Else.FailNow()

buf := bytes.Buffer{}
m.Output("foo", "test/without_imports", 100, &buf)
m.Output("foo", "test/withoutimports", 100, &buf)

expected, err := format.Source([]byte(`
// This file was generated by github.com/nelsam/hel. Do not
Expand Down
File renamed without changes.
9 changes: 9 additions & 0 deletions packages/packages.go
Expand Up @@ -29,10 +29,14 @@ func init() {
}
}

// Dir represents a directory containing go files.
type Dir struct {
path string
}

// Load looks for directories matching the passed in package patterns
// and returns Dir values for each directory that can be successfully
// imported and is found to match one of the patterns.
func Load(pkgPatterns ...string) (dirs []Dir) {
pkgPatterns = parsePatterns(pkgPatterns...)
for _, pkgPattern := range pkgPatterns {
Expand All @@ -45,10 +49,12 @@ func Load(pkgPatterns ...string) (dirs []Dir) {
return
}

// Path returns the file path to d.
func (d Dir) Path() string {
return d.path
}

// Packages returns the AST for all packages in d.
func (d Dir) Packages() map[string]*ast.Package {
packages, err := parser.ParseDir(token.NewFileSet(), d.Path(), nil, 0)
if err != nil {
Expand All @@ -57,6 +63,9 @@ func (d Dir) Packages() map[string]*ast.Package {
return packages
}

// Import imports path from srcDir, then loads the ast for that package.
// It ensures that the returned ast is for the package that would be
// imported by an import clause.
func (d Dir) Import(path, srcDir string) (string, *ast.Package, error) {
pkgInfo, err := build.Import(path, srcDir, 0)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion types/helheim_test.go
Expand Up @@ -5,7 +5,9 @@

package types_test

import "go/ast"
import (
"go/ast"
)

type mockGoDir struct {
PathCalled chan bool
Expand Down

0 comments on commit 21d62e1

Please sign in to comment.