├── vendor ├── github.com │ ├── stretchr │ │ ├── objx │ │ │ ├── README.md │ │ │ ├── security.go │ │ │ ├── value.go │ │ │ ├── constants.go │ │ │ ├── tests.go │ │ │ ├── LICENSE.md │ │ │ ├── mutations.go │ │ │ ├── doc.go │ │ │ ├── conversions.go │ │ │ ├── accessors.go │ │ │ └── map.go │ │ └── testify │ │ │ ├── assert │ │ │ ├── errors.go │ │ │ ├── doc.go │ │ │ ├── http_assertions.go │ │ │ └── forward_assertions.go │ │ │ └── mock │ │ │ └── doc.go │ ├── davecgh │ │ └── go-spew │ │ │ ├── LICENSE │ │ │ └── spew │ │ │ ├── bypasssafe.go │ │ │ ├── testdata │ │ │ └── dumpcgo.go │ │ │ ├── bypass.go │ │ │ ├── spew.go │ │ │ └── doc.go │ └── pmezard │ │ └── go-difflib │ │ └── LICENSE ├── golang.org │ └── x │ │ └── tools │ │ ├── go │ │ └── ast │ │ │ └── astutil │ │ │ ├── util.go │ │ │ └── imports.go │ │ ├── PATENTS │ │ └── LICENSE └── vendor.json ├── doc.go ├── .travis.yml ├── unmarshalmap ├── testpkg │ ├── debug_test.go │ ├── array_unmarshalmap_test.go │ ├── nested_unmarshalmap_test.go │ ├── composed_unmarshalmap_test.go │ ├── simple_struct_unmarshalmap_test.go │ ├── composed_unmarshalmap.go │ ├── array_unmarshalmap.go │ ├── structs.go │ ├── simple_struct_unmarshalmap.go │ └── nested_unmarshalmap.go ├── field.go ├── testunmarshalmap │ └── test.go ├── generator.go └── generator_test.go ├── cmd ├── gounmarshalmap │ ├── README.md │ └── main.go ├── gospecific │ ├── main.go │ └── README.md ├── goexportdefault │ ├── README.md │ └── main.go ├── gosimplemock │ ├── README.md │ └── main.go └── goautomock │ ├── README.md │ └── main.go ├── .gitignore ├── exportdefault ├── _testpkg │ ├── embedded.go │ ├── exported_default_exported_struct_funcs.go │ ├── exported_default_unexported_struct_funcs.go │ ├── unexported_default_exported_struct_funcs.go │ ├── exported_default_exported_struct_ptr_funcs.go │ ├── unexported_default_unexported_struct_funcs.go │ ├── exported_default_unexported_struct_ptr_funcs.go │ ├── unexported_default_exported_struct_ptr_funcs.go │ ├── unexported_default_unexported_struct_ptr_funcs.go │ ├── unexported_interface.go │ ├── exported_default_exported_interface_funcs.go │ ├── exported_default_unexported_interface_funcs.go │ ├── unexported_default_exported_interface_funcs.go │ ├── exported_interface.go │ ├── unexported_default_unexported_interface_funcs.go │ ├── unexported_struct.go │ └── exported_struct.go ├── testdata │ ├── filter_and_exclude.go │ ├── excluded.go │ ├── filtered.go │ └── simple_example.go ├── _integration_test │ ├── integration_test.go │ └── funcs_test.go ├── generator_test.go └── generator.go ├── specific ├── package_test.go ├── testpkg │ ├── vars_test.go │ └── vars.go ├── target_type.go ├── package.go ├── _testpkg │ └── vars.go ├── target_type_test.go ├── process_test.go └── process.go ├── gogenutil └── remove_gopath.go ├── strconv ├── snake_case.go └── snake_case_test.go ├── imports ├── imports_test.go └── imports.go ├── automock ├── io_writer_mock_test.go ├── unexported_mock_test.go ├── http_cookie_jar_mock_test.go ├── method.go ├── io_byte_scanner_mock_test.go ├── generator_test.go └── generator.go ├── cleanimports └── clean.go ├── LICENSE └── importer └── importer.go /vendor/github.com/stretchr/objx/README.md: -------------------------------------------------------------------------------- 1 | # objx 2 | 3 | * Jump into the [API Documentation](http://godoc.org/github.com/stretchr/objx) 4 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // Package gogen provides a set of code generation packages and command line tools to reduce boilerplate in your go projects 2 | package gogen 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.6 5 | - 1.7 6 | - tip 7 | 8 | env: 9 | - GO15VENDOREXPERIMENT=1 10 | 11 | script: go test -v -race ./... 12 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/debug_test.go: -------------------------------------------------------------------------------- 1 | package testpkg 2 | 3 | import ( 4 | "github.com/ernesto-jimenez/gogen/unmarshalmap/testunmarshalmap" 5 | ) 6 | 7 | func init() { 8 | testunmarshalmap.Debug = true 9 | } 10 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/ast/astutil/util.go: -------------------------------------------------------------------------------- 1 | package astutil 2 | 3 | import "go/ast" 4 | 5 | // Unparen returns e with any enclosing parentheses stripped. 6 | func Unparen(e ast.Expr) ast.Expr { 7 | for { 8 | p, ok := e.(*ast.ParenExpr) 9 | if !ok { 10 | return e 11 | } 12 | e = p.X 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /cmd/gounmarshalmap/README.md: -------------------------------------------------------------------------------- 1 | # gounmarshalmap 2 | 3 | Given a struct S outputs function that unmarshals a 4 | `map[string]interface{}` into the struct. e.g: 5 | 6 | ```bash 7 | $ gounmarshal S 8 | ``` 9 | 10 | will output 11 | 12 | ```go 13 | (s *S) UnmarshalMap(m map[string]interface{}) (error) { 14 | // autogenerated code 15 | } 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/security.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | import ( 4 | "crypto/sha1" 5 | "encoding/hex" 6 | ) 7 | 8 | // HashWithKey hashes the specified string using the security 9 | // key. 10 | func HashWithKey(data, key string) string { 11 | hash := sha1.New() 12 | hash.Write([]byte(data + ":" + key)) 13 | return hex.EncodeToString(hash.Sum(nil)) 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/embedded.go: -------------------------------------------------------------------------------- 1 | package testpkg 2 | 3 | type embeddedInterface interface { 4 | Embedded() 5 | } 6 | 7 | type embeddedStruct struct { 8 | } 9 | 10 | func (_ embeddedStruct) EmbeddedVal() {} 11 | func (_ *embeddedStruct) EmbeddedPtr() {} 12 | func (_ embeddedStruct) unexportedEmbeddedVal() {} 13 | func (_ *embeddedStruct) uenxportedEmbeddedPtr() {} 14 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/value.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | // Value provides methods for extracting interface{} data in various 4 | // types. 5 | type Value struct { 6 | // data contains the raw data being managed by this Value 7 | data interface{} 8 | } 9 | 10 | // Data returns the raw data contained by this Value 11 | func (v *Value) Data() interface{} { 12 | return v.data 13 | } 14 | -------------------------------------------------------------------------------- /specific/package_test.go: -------------------------------------------------------------------------------- 1 | package specific 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestFindPackage(t *testing.T) { 10 | p, err := findPackage("container/ring") 11 | assert.NoError(t, err) 12 | assert.NotEqual(t, 0, len(p.Dir)) 13 | assert.Equal(t, []string{"ring.go"}, p.GoFiles) 14 | assert.Equal(t, []string{"ring_test.go"}, p.TestGoFiles) 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/errors.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | // AnError is an error instance useful for testing. If the code does not care 8 | // about error specifics, and only needs to return the error for example, this 9 | // error should be used to make the test code more readable. 10 | var AnError = errors.New("assert.AnError general error for testing") 11 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/array_unmarshalmap_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package testpkg 7 | 8 | import ( 9 | test "github.com/ernesto-jimenez/gogen/unmarshalmap/testunmarshalmap" 10 | "testing" 11 | ) 12 | 13 | func TestArrayUnmarshalMap(t *testing.T) { 14 | test.Run(t, &Array{}) 15 | } 16 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/nested_unmarshalmap_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package testpkg 7 | 8 | import ( 9 | test "github.com/ernesto-jimenez/gogen/unmarshalmap/testunmarshalmap" 10 | "testing" 11 | ) 12 | 13 | func TestNestedUnmarshalMap(t *testing.T) { 14 | test.Run(t, &Nested{}) 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/constants.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | const ( 4 | // PathSeparator is the character used to separate the elements 5 | // of the keypath. 6 | // 7 | // For example, `location.address.city` 8 | PathSeparator string = "." 9 | 10 | // SignatureSeparator is the character that is used to 11 | // separate the Base64 string from the security signature. 12 | SignatureSeparator = "_" 13 | ) 14 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/composed_unmarshalmap_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package testpkg 7 | 8 | import ( 9 | test "github.com/ernesto-jimenez/gogen/unmarshalmap/testunmarshalmap" 10 | "testing" 11 | ) 12 | 13 | func TestComposedUnmarshalMap(t *testing.T) { 14 | test.Run(t, &Composed{}) 15 | } 16 | -------------------------------------------------------------------------------- /gogenutil/remove_gopath.go: -------------------------------------------------------------------------------- 1 | package gogenutil 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "strings" 7 | ) 8 | 9 | // StripGopath teks the directory to a package and remove the gopath to get the 10 | // cannonical package name 11 | func StripGopath(p string) string { 12 | for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") { 13 | p = strings.Replace(p, path.Join(gopath, "src")+"/", "", 1) 14 | } 15 | return p 16 | } 17 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/simple_struct_unmarshalmap_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package testpkg 7 | 8 | import ( 9 | test "github.com/ernesto-jimenez/gogen/unmarshalmap/testunmarshalmap" 10 | "testing" 11 | ) 12 | 13 | func TestSimpleStructUnmarshalMap(t *testing.T) { 14 | test.Run(t, &SimpleStruct{}) 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/tests.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | // Has gets whether there is something at the specified selector 4 | // or not. 5 | // 6 | // If m is nil, Has will always return false. 7 | func (m Map) Has(selector string) bool { 8 | if m == nil { 9 | return false 10 | } 11 | return !m.Get(selector).IsNil() 12 | } 13 | 14 | // IsNil gets whether the data is nil or not. 15 | func (v *Value) IsNil() bool { 16 | return v == nil || v.data == nil 17 | } 18 | -------------------------------------------------------------------------------- /strconv/snake_case.go: -------------------------------------------------------------------------------- 1 | package strconv 2 | 3 | import ( 4 | "regexp" 5 | "strings" 6 | ) 7 | 8 | var ( 9 | upper = regexp.MustCompile("([A-Z])") 10 | under = regexp.MustCompile("_+") 11 | ) 12 | 13 | // SnakeCase converst camel case to snake case 14 | func SnakeCase(s string) string { 15 | res := upper.ReplaceAllString(s, "_$1") 16 | res = strings.ToLower(res) 17 | res = under.ReplaceAllString(res, "_") 18 | return strings.TrimFunc(res, func(r rune) bool { 19 | return r == '_' 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /exportdefault/testdata/filter_and_exclude.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import ( 12 | io "io" 13 | ) 14 | 15 | // Wrapped is a wrapper around ExportedDefaultExportedInterface.Wrapped 16 | func Wrapped(something string) (io.Writer, error) { 17 | return ExportedDefaultExportedInterface.Wrapped(something) 18 | } 19 | -------------------------------------------------------------------------------- /strconv/snake_case_test.go: -------------------------------------------------------------------------------- 1 | package strconv 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSnakeCase(t *testing.T) { 8 | tests := []struct { 9 | in string 10 | out string 11 | }{ 12 | {"makeSnakeCase", "make_snake_case"}, 13 | {"StartWithCaps", "start_with_caps"}, 14 | {"double_Underscore", "double_underscore"}, 15 | } 16 | 17 | for _, test := range tests { 18 | res := SnakeCase(test.in) 19 | if res != test.out { 20 | t.Errorf("invalid conversion: SnakeCase(%q) should return %q, returned %q", test.in, test.out, res) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /specific/testpkg/vars_test.go: -------------------------------------------------------------------------------- 1 | package testpkg 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | //go:generate go run ../../cmd/gospecific/main.go -specific-type=string -pkg=github.com/ernesto-jimenez/gogen/specific/_testpkg -out-dir=./ 8 | 9 | func TestProperTypes(t *testing.T) { 10 | var ( 11 | _ map[string]string = MapKey 12 | _ map[string]string = MapValue 13 | _ []string = Array 14 | _ chan string = Channel 15 | _ <-chan string = ROChannel 16 | _ chan<- string = SOChannel 17 | _ struct{ Field string } = AnonymousStruct 18 | _ func(string) string = Fn 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/exported_default_exported_struct_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import () 12 | 13 | // EDESMethodVal is a wrapper around ExportedDefaultExportedStruct.MethodVal 14 | func EDESMethodVal() { 15 | ExportedDefaultExportedStruct.MethodVal() 16 | } 17 | 18 | // EDESMethodPtr is a wrapper around ExportedDefaultExportedStruct.MethodPtr 19 | func EDESMethodPtr() { 20 | ExportedDefaultExportedStruct.MethodPtr() 21 | } 22 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/exported_default_unexported_struct_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import () 12 | 13 | // EDUSMethodVal is a wrapper around ExportedDefaultUnexportedStruct.MethodVal 14 | func EDUSMethodVal() { 15 | ExportedDefaultUnexportedStruct.MethodVal() 16 | } 17 | 18 | // EDUSMethodPtr is a wrapper around ExportedDefaultUnexportedStruct.MethodPtr 19 | func EDUSMethodPtr() { 20 | ExportedDefaultUnexportedStruct.MethodPtr() 21 | } 22 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/unexported_default_exported_struct_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import () 12 | 13 | // UDESMethodVal is a wrapper around unexportedDefaultExportedStruct.MethodVal 14 | func UDESMethodVal() { 15 | unexportedDefaultExportedStruct.MethodVal() 16 | } 17 | 18 | // UDESMethodPtr is a wrapper around unexportedDefaultExportedStruct.MethodPtr 19 | func UDESMethodPtr() { 20 | unexportedDefaultExportedStruct.MethodPtr() 21 | } 22 | -------------------------------------------------------------------------------- /specific/target_type.go: -------------------------------------------------------------------------------- 1 | package specific 2 | 3 | import ( 4 | "path" 5 | "strings" 6 | ) 7 | 8 | type targetType struct { 9 | newPkg string 10 | newType string 11 | isPointer bool 12 | } 13 | 14 | func parseTargetType(fullType string) targetType { 15 | t := targetType{} 16 | deref := strings.TrimLeft(fullType, "*") 17 | if len(deref) != len(fullType) { 18 | t.isPointer = true 19 | } 20 | t.newType = path.Base(deref) 21 | t.newPkg = pkg(deref) 22 | return t 23 | } 24 | 25 | func pkg(fullType string) string { 26 | for i := len(fullType) - 1; i >= 0; i-- { 27 | if fullType[i] == '.' { 28 | return fullType[0:i] 29 | } 30 | } 31 | return "" 32 | } 33 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/exported_default_exported_struct_ptr_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import () 12 | 13 | // EDESPMethodVal is a wrapper around ExportedDefaultExportedStructPtr.MethodVal 14 | func EDESPMethodVal() { 15 | ExportedDefaultExportedStructPtr.MethodVal() 16 | } 17 | 18 | // EDESPMethodPtr is a wrapper around ExportedDefaultExportedStructPtr.MethodPtr 19 | func EDESPMethodPtr() { 20 | ExportedDefaultExportedStructPtr.MethodPtr() 21 | } 22 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/unexported_default_unexported_struct_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import () 12 | 13 | // UDUSMethodVal is a wrapper around unexportedDefaultUnexportedStruct.MethodVal 14 | func UDUSMethodVal() { 15 | unexportedDefaultUnexportedStruct.MethodVal() 16 | } 17 | 18 | // UDUSMethodPtr is a wrapper around unexportedDefaultUnexportedStruct.MethodPtr 19 | func UDUSMethodPtr() { 20 | unexportedDefaultUnexportedStruct.MethodPtr() 21 | } 22 | -------------------------------------------------------------------------------- /exportdefault/testdata/excluded.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import ( 12 | io "io" 13 | ) 14 | 15 | // Embedded is a wrapper around ExportedDefaultExportedInterface.Embedded 16 | func Embedded() { 17 | ExportedDefaultExportedInterface.Embedded() 18 | } 19 | 20 | // Wrapped is a wrapper around ExportedDefaultExportedInterface.Wrapped 21 | func Wrapped(something string) (io.Writer, error) { 22 | return ExportedDefaultExportedInterface.Wrapped(something) 23 | } 24 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/exported_default_unexported_struct_ptr_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import () 12 | 13 | // EDUSPMethodVal is a wrapper around ExportedDefaultUnexportedStructPtr.MethodVal 14 | func EDUSPMethodVal() { 15 | ExportedDefaultUnexportedStructPtr.MethodVal() 16 | } 17 | 18 | // EDUSPMethodPtr is a wrapper around ExportedDefaultUnexportedStructPtr.MethodPtr 19 | func EDUSPMethodPtr() { 20 | ExportedDefaultUnexportedStructPtr.MethodPtr() 21 | } 22 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/unexported_default_exported_struct_ptr_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import () 12 | 13 | // UDESPMethodVal is a wrapper around unexportedDefaultExportedStructPtr.MethodVal 14 | func UDESPMethodVal() { 15 | unexportedDefaultExportedStructPtr.MethodVal() 16 | } 17 | 18 | // UDESPMethodPtr is a wrapper around unexportedDefaultExportedStructPtr.MethodPtr 19 | func UDESPMethodPtr() { 20 | unexportedDefaultExportedStructPtr.MethodPtr() 21 | } 22 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/unexported_default_unexported_struct_ptr_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import () 12 | 13 | // UDUSPMethodVal is a wrapper around unexportedDefaultUnexportedStructPtr.MethodVal 14 | func UDUSPMethodVal() { 15 | unexportedDefaultUnexportedStructPtr.MethodVal() 16 | } 17 | 18 | // UDUSPMethodPtr is a wrapper around unexportedDefaultUnexportedStructPtr.MethodPtr 19 | func UDUSPMethodPtr() { 20 | unexportedDefaultUnexportedStructPtr.MethodPtr() 21 | } 22 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/unexported_interface.go: -------------------------------------------------------------------------------- 1 | package testpkg 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=EDUI ExportedDefaultUnexportedInterface 8 | 9 | // ExportedDefaultunexportedInterface to be generated 10 | var ExportedDefaultUnexportedInterface unexportedInterface = impl{} 11 | 12 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=UDUI unexportedDefaultUnexportedInterface 13 | var unexportedDefaultUnexportedInterface unexportedInterface = impl{} 14 | 15 | type unexportedInterface interface { 16 | embeddedInterface 17 | Wrapped(something string) (io.Writer, error) 18 | WrappedVariadric(something ...string) error 19 | } 20 | -------------------------------------------------------------------------------- /exportdefault/testdata/filtered.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import ( 12 | io "io" 13 | ) 14 | 15 | // Wrapped is a wrapper around ExportedDefaultExportedInterface.Wrapped 16 | func Wrapped(something string) (io.Writer, error) { 17 | return ExportedDefaultExportedInterface.Wrapped(something) 18 | } 19 | 20 | // WrappedVariadric is a wrapper around ExportedDefaultExportedInterface.WrappedVariadric 21 | func WrappedVariadric(something ...string) error { 22 | return ExportedDefaultExportedInterface.WrappedVariadric(something...) 23 | } 24 | -------------------------------------------------------------------------------- /imports/imports_test.go: -------------------------------------------------------------------------------- 1 | package imports_test 2 | 3 | import ( 4 | "go/token" 5 | "go/types" 6 | "testing" 7 | 8 | "github.com/ernesto-jimenez/gogen/imports" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | // TestDevendorizeImportPaths checks if vendored 13 | // import paths are devendorized correctly. 14 | func TestDevendorizeImportPaths(t *testing.T) { 15 | i := imports.New("github.com/ernesto-jimenez/gogen/imports") 16 | pkg := types.NewPackage("github.com/ernesto-jimenez/gogen/vendor/github.com/stretchr/testify/mock", "mock") 17 | named := types.NewNamed(types.NewTypeName(token.Pos(0), pkg, "", &types.Array{}), &types.Array{}, nil) 18 | i.AddImportsFrom(named) 19 | require.Equal(t, map[string]string{"github.com/stretchr/testify/mock": "mock"}, i.Imports()) 20 | } 21 | -------------------------------------------------------------------------------- /specific/testpkg/vars.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/specific 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package testpkg 7 | 8 | var ( 9 | Str = "something" 10 | MapKey map[string]string = make(map[string]string) 11 | MapValue map[string]string = make(map[string]string) 12 | Array []string = make([]string, 0) 13 | Channel chan string = make(chan string) 14 | ROChannel <-chan string = make(chan string) 15 | SOChannel chan<- string = make(chan string) 16 | Var interface{} = Str 17 | AnonymousStruct struct{ Field string } = struct{ Field string }{"value"} 18 | AnonymousFn func(string) string = func(param string) string { return param } 19 | ) 20 | 21 | func Fn(param string) string { 22 | return param 23 | } 24 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013 Dave Collins 2 | 3 | Permission to use, copy, modify, and distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /specific/package.go: -------------------------------------------------------------------------------- 1 | // Package specific copies the source from a package and generates a second 2 | // package replacing some of the types used. It's aimed at taking generic 3 | // packages that rely on interface{} and generating packages that use a 4 | // specific type. 5 | package specific 6 | 7 | import ( 8 | "encoding/json" 9 | "errors" 10 | "os/exec" 11 | ) 12 | 13 | func findPackage(pkg string) (Package, error) { 14 | var p Package 15 | data, err := exec.Command("go", "list", "-json", pkg).CombinedOutput() 16 | if err != nil && len(data) > 0 { 17 | return p, errors.New(string(data)) 18 | } else if err != nil { 19 | return p, err 20 | } 21 | err = json.Unmarshal(data, &p) 22 | return p, err 23 | } 24 | 25 | type Package struct { 26 | Dir string 27 | GoFiles []string 28 | TestGoFiles []string 29 | } 30 | -------------------------------------------------------------------------------- /automock/io_writer_mock_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/automock 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package automock 7 | 8 | import ( 9 | "fmt" 10 | mock "github.com/stretchr/testify/mock" 11 | ) 12 | 13 | // WriterMock mock 14 | type WriterMock struct { 15 | mock.Mock 16 | } 17 | 18 | // Write mocked method 19 | func (m *WriterMock) Write(p0 []byte) (int, error) { 20 | 21 | ret := m.Called(p0) 22 | 23 | var r0 int 24 | switch res := ret.Get(0).(type) { 25 | case nil: 26 | case int: 27 | r0 = res 28 | default: 29 | panic(fmt.Sprintf("unexpected type: %v", res)) 30 | } 31 | 32 | var r1 error 33 | switch res := ret.Get(1).(type) { 34 | case nil: 35 | case error: 36 | r1 = res 37 | default: 38 | panic(fmt.Sprintf("unexpected type: %v", res)) 39 | } 40 | 41 | return r0, r1 42 | 43 | } 44 | -------------------------------------------------------------------------------- /automock/unexported_mock_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/automock 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package automock 7 | 8 | import ( 9 | "fmt" 10 | mock "github.com/stretchr/testify/mock" 11 | ) 12 | 13 | // unexportedMock mock 14 | type unexportedMock struct { 15 | mock.Mock 16 | } 17 | 18 | // Read mocked method 19 | func (m *unexportedMock) Read(p0 []byte) (int, error) { 20 | 21 | ret := m.Called(p0) 22 | 23 | var r0 int 24 | switch res := ret.Get(0).(type) { 25 | case nil: 26 | case int: 27 | r0 = res 28 | default: 29 | panic(fmt.Sprintf("unexpected type: %v", res)) 30 | } 31 | 32 | var r1 error 33 | switch res := ret.Get(1).(type) { 34 | case nil: 35 | case error: 36 | r1 = res 37 | default: 38 | panic(fmt.Sprintf("unexpected type: %v", res)) 39 | } 40 | 41 | return r0, r1 42 | 43 | } 44 | -------------------------------------------------------------------------------- /specific/_testpkg/vars.go: -------------------------------------------------------------------------------- 1 | package testpkg 2 | 3 | var ( 4 | Str = "something" 5 | MapKey map[interface{}]string = make(map[interface{}]string) 6 | MapValue map[string]interface{} = make(map[string]interface{}) 7 | Array []interface{} = make([]interface{}, 0) 8 | Channel chan interface{} = make(chan interface{}) 9 | ROChannel <-chan interface{} = make(chan interface{}) 10 | SOChannel chan<- interface{} = make(chan interface{}) 11 | Var interface{} = Str 12 | AnonymousStruct struct{ Field interface{} } = struct{ Field interface{} }{"value"} 13 | AnonymousFn func(interface{}) interface{} = func(param interface{}) interface{} { return param } 14 | ) 15 | 16 | func Fn(param interface{}) interface{} { 17 | return param 18 | } 19 | -------------------------------------------------------------------------------- /exportdefault/_integration_test/integration_test.go: -------------------------------------------------------------------------------- 1 | package integration 2 | 3 | import ( 4 | "os/exec" 5 | "testing" 6 | ) 7 | 8 | func TestGenerateAndBuildTestPackage(t *testing.T) { 9 | cmd := exec.Command("go", "generate", "github.com/ernesto-jimenez/gogen/exportdefault/_testpkg") 10 | out, err := cmd.CombinedOutput() 11 | if err != nil { 12 | t.Fatalf("error generating wrappers: %s\nOutput:\n%s", err.Error(), out) 13 | } 14 | 15 | cmd = exec.Command("go", "build", "github.com/ernesto-jimenez/gogen/exportdefault/_testpkg") 16 | out, err = cmd.CombinedOutput() 17 | if err != nil { 18 | t.Fatalf("error buildinjg package: %s\nOutput:\n%s", err.Error(), out) 19 | } 20 | 21 | cmd = exec.Command("go", "test", "github.com/ernesto-jimenez/gogen/exportdefault/_testpkg") 22 | out, err = cmd.CombinedOutput() 23 | if err != nil { 24 | t.Fatalf("error testing package: %s\nOutput:\n%s", err.Error(), out) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /exportdefault/testdata/simple_example.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import ( 12 | io "io" 13 | ) 14 | 15 | // Embedded is a wrapper around ExportedDefaultExportedInterface.Embedded 16 | func Embedded() { 17 | ExportedDefaultExportedInterface.Embedded() 18 | } 19 | 20 | // Wrapped is a wrapper around ExportedDefaultExportedInterface.Wrapped 21 | func Wrapped(something string) (io.Writer, error) { 22 | return ExportedDefaultExportedInterface.Wrapped(something) 23 | } 24 | 25 | // WrappedVariadric is a wrapper around ExportedDefaultExportedInterface.WrappedVariadric 26 | func WrappedVariadric(something ...string) error { 27 | return ExportedDefaultExportedInterface.WrappedVariadric(something...) 28 | } 29 | -------------------------------------------------------------------------------- /automock/http_cookie_jar_mock_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/automock 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package automock 7 | 8 | import ( 9 | "fmt" 10 | mock "github.com/stretchr/testify/mock" 11 | 12 | http "net/http" 13 | url "net/url" 14 | ) 15 | 16 | // CookieJarMock mock 17 | type CookieJarMock struct { 18 | mock.Mock 19 | } 20 | 21 | // Cookies mocked method 22 | func (m *CookieJarMock) Cookies(p0 *url.URL) []*http.Cookie { 23 | 24 | ret := m.Called(p0) 25 | 26 | var r0 []*http.Cookie 27 | switch res := ret.Get(0).(type) { 28 | case nil: 29 | case []*http.Cookie: 30 | r0 = res 31 | default: 32 | panic(fmt.Sprintf("unexpected type: %v", res)) 33 | } 34 | 35 | return r0 36 | 37 | } 38 | 39 | // SetCookies mocked method 40 | func (m *CookieJarMock) SetCookies(p0 *url.URL, p1 []*http.Cookie) { 41 | 42 | m.Called(p0, p1) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /cmd/gospecific/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | 7 | "github.com/ernesto-jimenez/gogen/specific" 8 | ) 9 | 10 | var ( 11 | pkg = flag.String("pkg", "", "generic package") 12 | out = flag.String("out-dir", "", "directory to store the specific package") 13 | specificType = flag.String("specific-type", "", "what specific type to use instead of interface{}") 14 | skipTests = flag.Bool("skip-tests", false, "whether to skip generating test files") 15 | ) 16 | 17 | func main() { 18 | flag.Parse() 19 | 20 | if *pkg == "" { 21 | flag.Usage() 22 | log.Fatal("missing generic package") 23 | } 24 | 25 | if *specificType == "" { 26 | flag.Usage() 27 | log.Fatal("missing specific type") 28 | } 29 | 30 | if err := specific.Process(*pkg, *out, *specificType, func(opts *specific.Options) { 31 | opts.SkipTestFiles = *skipTests 32 | }); err != nil { 33 | log.Fatal(err) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/exported_default_exported_interface_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import ( 12 | io "io" 13 | ) 14 | 15 | // EDEIEmbedded is a wrapper around ExportedDefaultExportedInterface.Embedded 16 | func EDEIEmbedded() { 17 | ExportedDefaultExportedInterface.Embedded() 18 | } 19 | 20 | // EDEIWrapped is a wrapper around ExportedDefaultExportedInterface.Wrapped 21 | func EDEIWrapped(something string) (io.Writer, error) { 22 | return ExportedDefaultExportedInterface.Wrapped(something) 23 | } 24 | 25 | // EDEIWrappedVariadric is a wrapper around ExportedDefaultExportedInterface.WrappedVariadric 26 | func EDEIWrappedVariadric(something ...string) error { 27 | return ExportedDefaultExportedInterface.WrappedVariadric(something...) 28 | } 29 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/exported_default_unexported_interface_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import ( 12 | io "io" 13 | ) 14 | 15 | // EDUIEmbedded is a wrapper around ExportedDefaultUnexportedInterface.Embedded 16 | func EDUIEmbedded() { 17 | ExportedDefaultUnexportedInterface.Embedded() 18 | } 19 | 20 | // EDUIWrapped is a wrapper around ExportedDefaultUnexportedInterface.Wrapped 21 | func EDUIWrapped(something string) (io.Writer, error) { 22 | return ExportedDefaultUnexportedInterface.Wrapped(something) 23 | } 24 | 25 | // EDUIWrappedVariadric is a wrapper around ExportedDefaultUnexportedInterface.WrappedVariadric 26 | func EDUIWrappedVariadric(something ...string) error { 27 | return ExportedDefaultUnexportedInterface.WrappedVariadric(something...) 28 | } 29 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/unexported_default_exported_interface_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import ( 12 | io "io" 13 | ) 14 | 15 | // UDEIEmbedded is a wrapper around unexportedDefaultExportedInterface.Embedded 16 | func UDEIEmbedded() { 17 | unexportedDefaultExportedInterface.Embedded() 18 | } 19 | 20 | // UDEIWrapped is a wrapper around unexportedDefaultExportedInterface.Wrapped 21 | func UDEIWrapped(something string) (io.Writer, error) { 22 | return unexportedDefaultExportedInterface.Wrapped(something) 23 | } 24 | 25 | // UDEIWrappedVariadric is a wrapper around unexportedDefaultExportedInterface.WrappedVariadric 26 | func UDEIWrappedVariadric(something ...string) error { 27 | return unexportedDefaultExportedInterface.WrappedVariadric(something...) 28 | } 29 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/exported_interface.go: -------------------------------------------------------------------------------- 1 | package testpkg 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=EDEI ExportedDefaultExportedInterface 8 | 9 | // ExportedDefaultExportedInterface to be generated 10 | var ExportedDefaultExportedInterface ExportedInterface = impl{} 11 | 12 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=UDEI unexportedDefaultExportedInterface 13 | var unexportedDefaultExportedInterface ExportedInterface = impl{} 14 | 15 | // ExportedInterface for tests 16 | type ExportedInterface interface { 17 | embeddedInterface 18 | // Wrapped documentation goes here 19 | Wrapped(something string) (io.Writer, error) 20 | WrappedVariadric(something ...string) error 21 | } 22 | 23 | type impl struct { 24 | } 25 | 26 | func (impl) Wrapped(string) (io.Writer, error) { return nil, nil } 27 | func (impl) WrappedVariadric(...string) error { return nil } 28 | func (impl) Embedded() {} 29 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/unexported_default_unexported_interface_funcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 3 | * THIS FILE MUST NOT BE EDITED BY HAND 4 | * 5 | * Install goexportdefault with: 6 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 7 | */ 8 | 9 | package testpkg 10 | 11 | import ( 12 | io "io" 13 | ) 14 | 15 | // UDUIEmbedded is a wrapper around unexportedDefaultUnexportedInterface.Embedded 16 | func UDUIEmbedded() { 17 | unexportedDefaultUnexportedInterface.Embedded() 18 | } 19 | 20 | // UDUIWrapped is a wrapper around unexportedDefaultUnexportedInterface.Wrapped 21 | func UDUIWrapped(something string) (io.Writer, error) { 22 | return unexportedDefaultUnexportedInterface.Wrapped(something) 23 | } 24 | 25 | // UDUIWrappedVariadric is a wrapper around unexportedDefaultUnexportedInterface.WrappedVariadric 26 | func UDUIWrappedVariadric(something ...string) error { 27 | return unexportedDefaultUnexportedInterface.WrappedVariadric(something...) 28 | } 29 | -------------------------------------------------------------------------------- /cmd/gospecific/README.md: -------------------------------------------------------------------------------- 1 | # gospecific 2 | 3 | Avoid using generic packages with `interface{}` by generating specific 4 | packages that can be used with safe types. 5 | 6 | # Usage 7 | 8 | Install gospecific 9 | 10 | ```go 11 | go get github.com/ernesto-jimenez/gogen/cmd/gospecific 12 | ``` 13 | 14 | Add a go generate comment to generate a package 15 | 16 | ```go 17 | //go:generate gospecific -pkg=container/list -specific-type=string 18 | ``` 19 | 20 | Generate the code 21 | 22 | ```go 23 | go generate 24 | ``` 25 | 26 | Now you will have your own `list` package to store strings rather than 27 | `interface{}` 28 | 29 | ```sh 30 | % godoc github.com/ernesto-jimenez/gogen/list | egrep 'func.+string' 31 | ``` 32 | 33 | ```go 34 | func (l *List) InsertAfter(v string, mark *Element) *Element 35 | func (l *List) InsertBefore(v string, mark *Element) *Element 36 | func (l *List) PushBack(v string) *Element 37 | func (l *List) PushFront(v string) *Element 38 | func (l *List) Remove(e *Element) string 39 | ``` 40 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/composed_unmarshalmap.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package testpkg 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // UnmarshalMap takes a map and unmarshals the fieds into the struct 13 | func (s *Composed) UnmarshalMap(m map[string]interface{}) error { 14 | 15 | // Anonymous Embedded 16 | if scoped := true; scoped { 17 | var s *Embedded = &s.Embedded 18 | // Fill object 19 | 20 | if v, ok := m["Field"].(string); ok { 21 | s.Field = v 22 | 23 | } else if v, exists := m["Field"]; exists && v != nil { 24 | return fmt.Errorf("expected field Field to be string but got %T", m["Field"]) 25 | } 26 | 27 | } 28 | 29 | if v, ok := m["Base"].(string); ok { 30 | s.Base = v 31 | 32 | } else if v, exists := m["Base"]; exists && v != nil { 33 | return fmt.Errorf("expected field Base to be string but got %T", m["Base"]) 34 | } 35 | 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /cleanimports/clean.go: -------------------------------------------------------------------------------- 1 | // Package cleanimports provides functionality to clean unused imports from the 2 | // given source code 3 | package cleanimports 4 | 5 | import ( 6 | "go/ast" 7 | "go/format" 8 | "go/parser" 9 | "go/token" 10 | "io" 11 | "strings" 12 | 13 | "golang.org/x/tools/go/ast/astutil" 14 | ) 15 | 16 | // Clean writes the clean source to io.Writer. The source can be a io.Reader, 17 | // string or []bytes 18 | func Clean(w io.Writer, src interface{}) error { 19 | fset := token.NewFileSet() 20 | file, err := parser.ParseFile(fset, "clean.go", src, parser.ParseComments) 21 | if err != nil { 22 | return err 23 | } 24 | // Clean unused imports 25 | imports := astutil.Imports(fset, file) 26 | for _, group := range imports { 27 | for _, imp := range group { 28 | path := strings.Trim(imp.Path.Value, `"`) 29 | if !astutil.UsesImport(file, path) { 30 | astutil.DeleteImport(fset, file, path) 31 | } 32 | } 33 | } 34 | ast.SortImports(fset, file) 35 | // Write formatted code without unused imports 36 | return format.Node(w, fset, file) 37 | } 38 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/array_unmarshalmap.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package testpkg 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // UnmarshalMap takes a map and unmarshals the fieds into the struct 13 | func (s *Array) UnmarshalMap(m map[string]interface{}) error { 14 | 15 | // ArrayOrSlice List 16 | 17 | if v, ok := m["List"].([]string); ok { 18 | 19 | s.List = make([]string, len(v)) 20 | 21 | for i, el := range v { 22 | s.List[i] = el 23 | } 24 | } else if v, ok := m["List"].([]interface{}); ok { 25 | 26 | s.List = make([]string, len(v)) 27 | 28 | for i, el := range v { 29 | if v, ok := el.(string); ok { 30 | s.List[i] = v 31 | 32 | } else { 33 | return fmt.Errorf("expected field List[%d] to be string but got %T", i, el) 34 | } 35 | } 36 | } else if v, exists := m["List"]; exists && v != nil { 37 | return fmt.Errorf("expected field List to be []string but got %T", m["List"]) 38 | } 39 | 40 | return nil 41 | } 42 | -------------------------------------------------------------------------------- /exportdefault/_integration_test/funcs_test.go: -------------------------------------------------------------------------------- 1 | package integration 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ernesto-jimenez/gogen/exportdefault/_testpkg" 7 | ) 8 | 9 | func TestGeneratedFuncs(t *testing.T) { 10 | testpkg.EDEIEmbedded() 11 | testpkg.EDEIWrappedVariadric("a", "b") 12 | testpkg.EDESMethodPtr() 13 | testpkg.EDESMethodVal() 14 | testpkg.EDESPMethodPtr() 15 | testpkg.EDESPMethodVal() 16 | testpkg.EDUIEmbedded() 17 | testpkg.EDUIWrappedVariadric("a", "b") 18 | testpkg.EDUSMethodPtr() 19 | testpkg.EDUSMethodVal() 20 | testpkg.EDUSPMethodPtr() 21 | testpkg.EDUSPMethodVal() 22 | testpkg.UDEIEmbedded() 23 | testpkg.UDEIWrappedVariadric("a", "b") 24 | testpkg.UDESMethodPtr() 25 | testpkg.UDESMethodVal() 26 | testpkg.UDESPMethodPtr() 27 | testpkg.UDESPMethodVal() 28 | testpkg.UDUIEmbedded() 29 | testpkg.UDUIWrappedVariadric("a", "b") 30 | testpkg.UDUSMethodPtr() 31 | testpkg.UDUSMethodVal() 32 | testpkg.UDUSPMethodPtr() 33 | testpkg.UDUSPMethodVal() 34 | testpkg.EDEIWrapped("a") 35 | testpkg.EDUIWrapped("a") 36 | testpkg.UDEIWrapped("a") 37 | testpkg.UDUIWrapped("a") 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Ernesto Jiménez 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/unexported_struct.go: -------------------------------------------------------------------------------- 1 | package testpkg 2 | 3 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=EDUS ExportedDefaultUnexportedStruct 4 | 5 | // ExportedDefaultUnexportedStruct to be generated 6 | var ExportedDefaultUnexportedStruct = unexportedStruct{} 7 | 8 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=UDUS unexportedDefaultUnexportedStruct 9 | var unexportedDefaultUnexportedStruct = unexportedStruct{} 10 | 11 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=EDUSP ExportedDefaultUnexportedStructPtr 12 | 13 | // ExportedDefaultUnexportedStructPtr to be generated 14 | var ExportedDefaultUnexportedStructPtr = &unexportedStruct{} 15 | 16 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=UDUSP unexportedDefaultUnexportedStructPtr 17 | var unexportedDefaultUnexportedStructPtr = &unexportedStruct{} 18 | 19 | type unexportedStruct struct { 20 | embeddedStruct 21 | } 22 | 23 | func (unexportedStruct) MethodVal() {} 24 | func (*unexportedStruct) MethodPtr() {} 25 | func (unexportedStruct) unexportedMethodVal() {} 26 | func (*unexportedStruct) uenxportedMethodPtr() {} 27 | -------------------------------------------------------------------------------- /automock/method.go: -------------------------------------------------------------------------------- 1 | package automock 2 | 3 | import "go/types" 4 | import "strings" 5 | 6 | // Method contains the details from an interface method 7 | type Method struct { 8 | gen *Generator 9 | fn *types.Func 10 | } 11 | 12 | // Name returns the method name 13 | func (m Method) Name() string { 14 | return m.fn.Name() 15 | } 16 | 17 | // ParamTypes returns the list of types for the params 18 | func (m Method) ParamTypes() []string { 19 | sig := m.signature() 20 | types := m.listTypes(sig.Params()) 21 | n := len(types) 22 | if n > 0 && sig.Variadic() { 23 | types[n-1] = strings.Replace(types[n-1], "[]", "...", 1) 24 | } 25 | return types 26 | } 27 | 28 | // ReturnTypes returns the list of types for the params 29 | func (m Method) ReturnTypes() []string { 30 | sig := m.signature() 31 | return m.listTypes(sig.Results()) 32 | } 33 | 34 | func (m Method) listTypes(t *types.Tuple) []string { 35 | num := t.Len() 36 | list := make([]string, num) 37 | for i := 0; i < num; i++ { 38 | list[i] = types.TypeString(t.At(i).Type(), m.gen.qf) 39 | } 40 | return list 41 | } 42 | 43 | func (m Method) signature() *types.Signature { 44 | return m.fn.Type().(*types.Signature) 45 | } 46 | -------------------------------------------------------------------------------- /exportdefault/_testpkg/exported_struct.go: -------------------------------------------------------------------------------- 1 | package testpkg 2 | 3 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=EDES ExportedDefaultExportedStruct 4 | 5 | // ExportedDefaultExportedStruct to be generated 6 | var ExportedDefaultExportedStruct = ExportedStruct{} 7 | 8 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=UDES unexportedDefaultExportedStruct 9 | var unexportedDefaultExportedStruct = ExportedStruct{} 10 | 11 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=EDESP ExportedDefaultExportedStructPtr 12 | 13 | // ExportedDefaultExportedStructPtr to be generated 14 | var ExportedDefaultExportedStructPtr = &ExportedStruct{} 15 | 16 | //go:generate go run ../../cmd/goexportdefault/main.go -prefix=UDESP unexportedDefaultExportedStructPtr 17 | var unexportedDefaultExportedStructPtr = &ExportedStruct{} 18 | 19 | // ExportedStruct is a random test struct 20 | type ExportedStruct struct { 21 | embeddedStruct 22 | } 23 | 24 | // MethodVal docs 25 | func (ExportedStruct) MethodVal() {} 26 | 27 | // MethodPtr docs 28 | func (*ExportedStruct) MethodPtr() {} 29 | func (ExportedStruct) unexportedMethodVal() {} 30 | func (*ExportedStruct) uenxportedMethodPtr() {} 31 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/LICENSE.md: -------------------------------------------------------------------------------- 1 | objx - by Mat Ryer and Tyler Bunnell 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2014 Stretchr, Inc. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /automock/io_byte_scanner_mock_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/automock 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package automock 7 | 8 | import ( 9 | "fmt" 10 | mock "github.com/stretchr/testify/mock" 11 | ) 12 | 13 | // ByteScannerMock mock 14 | type ByteScannerMock struct { 15 | mock.Mock 16 | } 17 | 18 | // ReadByte mocked method 19 | func (m *ByteScannerMock) ReadByte() (byte, error) { 20 | 21 | ret := m.Called() 22 | 23 | var r0 byte 24 | switch res := ret.Get(0).(type) { 25 | case nil: 26 | case byte: 27 | r0 = res 28 | default: 29 | panic(fmt.Sprintf("unexpected type: %v", res)) 30 | } 31 | 32 | var r1 error 33 | switch res := ret.Get(1).(type) { 34 | case nil: 35 | case error: 36 | r1 = res 37 | default: 38 | panic(fmt.Sprintf("unexpected type: %v", res)) 39 | } 40 | 41 | return r0, r1 42 | 43 | } 44 | 45 | // UnreadByte mocked method 46 | func (m *ByteScannerMock) UnreadByte() error { 47 | 48 | ret := m.Called() 49 | 50 | var r0 error 51 | switch res := ret.Get(0).(type) { 52 | case nil: 53 | case error: 54 | r0 = res 55 | default: 56 | panic(fmt.Sprintf("unexpected type: %v", res)) 57 | } 58 | 59 | return r0 60 | 61 | } 62 | -------------------------------------------------------------------------------- /cmd/goexportdefault/README.md: -------------------------------------------------------------------------------- 1 | # goexportdefault 2 | 3 | It is a common pattern in Go packages to implement a default instance of an exported struct and export functions that call the underlying default instance. 4 | 5 | A couple of examples from the stdlib: 6 | 7 | - `net/http` has `http.DefaultClient` and functions like `http.Get` just call the default `http.DefaultClient.Get` 8 | - `log` has `log.Logger` and functions like `log.Print` just call the default `log.std.Print` 9 | 10 | The exported package functions simply call the corresponding methods from the default instance. 11 | 12 | `goexportdefault` allows you to automatically generate a exported function for each method from a default struct. 13 | 14 | # Usage 15 | 16 | Given the following code: 17 | 18 | ```go 19 | var DefaultClient = New() 20 | //go:generate goexportdefault DefaultClient 21 | 22 | type Client struct {} 23 | 24 | func New() *Client { 25 | return &Client{} 26 | } 27 | 28 | // Do won't really do anything in this example 29 | func (c *Client) Do(interface{}) error { 30 | return nil 31 | } 32 | ``` 33 | 34 | The it will automatically generate a `default_client_funcs.go` file with the following contents: 35 | 36 | ```go 37 | // Do is a wrapper around DefaultClient.Do 38 | func Do(v interface{}) error { 39 | return DefaultClient.Do(v) 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /exportdefault/generator_test.go: -------------------------------------------------------------------------------- 1 | package exportdefault 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "regexp" 8 | "testing" 9 | ) 10 | 11 | func TestGenerateCode(t *testing.T) { 12 | tests := []struct { 13 | name string 14 | include *regexp.Regexp 15 | exclude *regexp.Regexp 16 | }{ 17 | { 18 | name: "simple_example", 19 | }, 20 | { 21 | name: "filtered", 22 | include: regexp.MustCompile("Wrapped.*"), 23 | }, 24 | { 25 | name: "excluded", 26 | exclude: regexp.MustCompile("Variadric"), 27 | }, 28 | { 29 | name: "filter_and_exclude", 30 | include: regexp.MustCompile("Wrapped"), 31 | exclude: regexp.MustCompile("Variadric"), 32 | }, 33 | } 34 | pkg := "./_testpkg" 35 | variable := "ExportedDefaultExportedInterface" 36 | for _, test := range tests { 37 | g, err := New(pkg, variable) 38 | if err != nil { 39 | t.Fatalf("%s: failed initializing generator %s", test.name, err.Error()) 40 | } 41 | g.Include = test.include 42 | g.Exclude = test.exclude 43 | var buf bytes.Buffer 44 | g.Write(&buf) 45 | code, err := ioutil.ReadFile(fmt.Sprintf("testdata/%s.go", test.name)) 46 | if err != nil { 47 | t.Fatalf("%s: %s", test.name, err.Error()) 48 | } 49 | exp := string(code) 50 | if buf.String() != exp { 51 | t.Fatalf("%s\nexpected: %s\nreturned: %s", test.name, exp, buf.String()) 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /cmd/gounmarshalmap/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "flag" 6 | "fmt" 7 | "io/ioutil" 8 | "log" 9 | "strings" 10 | 11 | "github.com/ernesto-jimenez/gogen/unmarshalmap" 12 | ) 13 | 14 | var ( 15 | out = flag.String("o", "", "what file to write") 16 | tOut = flag.String("o-test", "", "what file to write the test to") 17 | pkg = flag.String("pkg", ".", "what package to get the interface from") 18 | ) 19 | 20 | func main() { 21 | flag.Parse() 22 | log.SetFlags(0) 23 | 24 | st := flag.Arg(0) 25 | 26 | if st == "" { 27 | log.Fatal("need to specify a struct name") 28 | } 29 | 30 | gen, err := unmarshalmap.NewGenerator(*pkg, st) 31 | if err != nil { 32 | log.Fatal(err) 33 | } 34 | 35 | var buf bytes.Buffer 36 | 37 | log.Printf("Generating func (*%s) UnmarshalMap(map[string]interface{}) error", st) 38 | err = gen.Write(&buf) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | 43 | if *out != "" { 44 | err := ioutil.WriteFile(*out, buf.Bytes(), 0666) 45 | if err != nil { 46 | log.Fatal(err) 47 | } 48 | if *tOut == "" { 49 | *tOut = fmt.Sprintf("%s_test.go", strings.TrimRight(*out, ".go")) 50 | } 51 | } else { 52 | fmt.Println(buf.String()) 53 | } 54 | 55 | buf.Reset() 56 | 57 | err = gen.WriteTest(&buf) 58 | if err != nil { 59 | log.Fatal(err) 60 | } 61 | 62 | if *tOut != "" { 63 | err := ioutil.WriteFile(*tOut, buf.Bytes(), 0666) 64 | if err != nil { 65 | log.Fatal(err) 66 | } 67 | } else { 68 | fmt.Println(buf.String()) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /vendor/vendor.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "", 3 | "ignore": "test", 4 | "package": [ 5 | { 6 | "checksumSHA1": "5rPfda8jFccr3A6heL+JAmi9K9g=", 7 | "path": "github.com/davecgh/go-spew/spew", 8 | "revision": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d" 9 | }, 10 | { 11 | "checksumSHA1": "a2yC46a1qsJomgY6rb+FkTFiqmE=", 12 | "path": "github.com/davecgh/go-spew/spew/testdata", 13 | "revision": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d" 14 | }, 15 | { 16 | "checksumSHA1": "zKKp5SZ3d3ycKe4EKMNT0BqAWBw=", 17 | "path": "github.com/pmezard/go-difflib/difflib", 18 | "revision": "d8ed2627bdf02c080bf22230dbb337003b7aba2d" 19 | }, 20 | { 21 | "checksumSHA1": "EO+jcRet/AJ6IY3lBO8l8BLsZWg=", 22 | "path": "github.com/stretchr/objx", 23 | "revision": "cbeaeb16a013161a98496fad62933b1d21786672" 24 | }, 25 | { 26 | "checksumSHA1": "5XAzjZrdlLh1mgd7xEvoK6LeLCA=", 27 | "comment": "v1.0-85-ga1f9799", 28 | "path": "github.com/stretchr/testify/assert", 29 | "revision": "a1f97990ddc16022ec7610326dd9bce31332c116" 30 | }, 31 | { 32 | "checksumSHA1": "30IdH2X8uhLBS/sdBi6Lw+fcFTA=", 33 | "comment": "v1.0-85-ga1f9799", 34 | "path": "github.com/stretchr/testify/mock", 35 | "revision": "a1f97990ddc16022ec7610326dd9bce31332c116" 36 | }, 37 | { 38 | "checksumSHA1": "n7QcM+WctJpMsi0d1m4OKSqW4xU=", 39 | "path": "golang.org/x/tools/go/ast/astutil", 40 | "revision": "b7f0150d16f143e2d871156fa142dd6fa372ffdf" 41 | } 42 | ], 43 | "rootPath": "github.com/ernesto-jimenez/gogen" 44 | } 45 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/structs.go: -------------------------------------------------------------------------------- 1 | package testpkg 2 | 3 | //go:generate go run ../../cmd/gounmarshalmap/main.go -o simple_struct_unmarshalmap.go SimpleStruct 4 | 5 | type SimpleStruct struct { 6 | SimpleField string 7 | SimpleJSONTagged string `json:"field2"` 8 | SimpleJSONTaggedOmitted string `json:"field3,omitempty"` 9 | SimpleOmitEmptyNoName string `json:",omitempty"` 10 | SimpleSkipped string `json:"-,omitempty"` 11 | SimplePointer *string `json:"pointer"` 12 | SimpleInteger int `json:"integer"` 13 | SimpleIntegerPtr *int `json:"integer_ptr"` 14 | Ignored string `json:"-"` 15 | } 16 | 17 | //go:generate go run ../../cmd/gounmarshalmap/main.go -o array_unmarshalmap.go Array 18 | 19 | type Array struct { 20 | List []string 21 | //ListPointers []*string 22 | // PointerToList *[]string 23 | } 24 | 25 | type Embedded struct { 26 | Field string 27 | } 28 | 29 | //go:generate go run ../../cmd/gounmarshalmap/main.go -o composed_unmarshalmap.go Composed 30 | 31 | type Composed struct { 32 | Embedded 33 | Base string 34 | } 35 | 36 | //go:generate go run ../../cmd/gounmarshalmap/main.go -o nested_unmarshalmap.go Nested 37 | 38 | type Nested struct { 39 | First Embedded 40 | Second *Embedded 41 | Third []Embedded 42 | Fourth []*Embedded 43 | Fifth [3]Embedded 44 | Sixth [3]*Embedded 45 | // TODO: Implement map support 46 | // Seventh map[string]Embedded 47 | // Eight map[string]*Embedded 48 | // Nineth map[int]Embedded 49 | // Tenth map[int]*Embedded 50 | } 51 | -------------------------------------------------------------------------------- /vendor/github.com/pmezard/go-difflib/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Patrick Mezard 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | The names of its contributors may not be used to endorse or promote 14 | products derived from this software without specific prior written 15 | permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 18 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 23 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/doc.go: -------------------------------------------------------------------------------- 1 | // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. 2 | // 3 | // Example Usage 4 | // 5 | // The following is a complete example using assert in a standard test function: 6 | // import ( 7 | // "testing" 8 | // "github.com/stretchr/testify/assert" 9 | // ) 10 | // 11 | // func TestSomething(t *testing.T) { 12 | // 13 | // var a string = "Hello" 14 | // var b string = "Hello" 15 | // 16 | // assert.Equal(t, a, b, "The two words should be the same.") 17 | // 18 | // } 19 | // 20 | // if you assert many times, use the format below: 21 | // 22 | // import ( 23 | // "testing" 24 | // "github.com/stretchr/testify/assert" 25 | // ) 26 | // 27 | // func TestSomething(t *testing.T) { 28 | // assert := assert.New(t) 29 | // 30 | // var a string = "Hello" 31 | // var b string = "Hello" 32 | // 33 | // assert.Equal(a, b, "The two words should be the same.") 34 | // } 35 | // 36 | // Assertions 37 | // 38 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package. 39 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the 40 | // testing framework. This allows the assertion funcs to write the failings and other details to 41 | // the correct place. 42 | // 43 | // Every assertion function also takes an optional string message as the final argument, 44 | // allowing custom error messages to be appended to the message the assertion method outputs. 45 | package assert 46 | -------------------------------------------------------------------------------- /specific/target_type_test.go: -------------------------------------------------------------------------------- 1 | package specific 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | var targetTypeTests = []struct { 8 | src string 9 | expected targetType 10 | }{ 11 | { 12 | src: "string", 13 | expected: targetType{ 14 | newPkg: "", 15 | newType: "string", 16 | isPointer: false, 17 | }, 18 | }, 19 | { 20 | src: "*string", 21 | expected: targetType{ 22 | newPkg: "", 23 | newType: "string", 24 | isPointer: true, 25 | }, 26 | }, 27 | { 28 | src: "*os.File", 29 | expected: targetType{ 30 | newPkg: "os", 31 | newType: "os.File", 32 | isPointer: true, 33 | }, 34 | }, 35 | { 36 | src: "os.File", 37 | expected: targetType{ 38 | newPkg: "os", 39 | newType: "os.File", 40 | isPointer: false, 41 | }, 42 | }, 43 | { 44 | src: "dummyexample.com/whatever/pkg.Type", 45 | expected: targetType{ 46 | newPkg: "dummyexample.com/whatever/pkg", 47 | newType: "pkg.Type", 48 | isPointer: false, 49 | }, 50 | }, 51 | } 52 | 53 | func TestParseTargetType(t *testing.T) { 54 | errStr := "%s mismatch for %q\n expected: %q\n returned: %q" 55 | for _, test := range targetTypeTests { 56 | res := parseTargetType(test.src) 57 | if res.isPointer != test.expected.isPointer { 58 | t.Errorf(errStr, "isPointer", test.src, test.expected.isPointer, res.isPointer) 59 | } 60 | if res.newPkg != test.expected.newPkg { 61 | t.Errorf(errStr, "newPkg", test.src, test.expected.newPkg, res.newPkg) 62 | } 63 | if res.newType != test.expected.newType { 64 | t.Errorf(errStr, "newType", test.src, test.expected.newType, res.newType) 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/mock/doc.go: -------------------------------------------------------------------------------- 1 | // Provides a system by which it is possible to mock your objects and verify calls are happening as expected. 2 | // 3 | // Example Usage 4 | // 5 | // The mock package provides an object, Mock, that tracks activity on another object. It is usually 6 | // embedded into a test object as shown below: 7 | // 8 | // type MyTestObject struct { 9 | // // add a Mock object instance 10 | // mock.Mock 11 | // 12 | // // other fields go here as normal 13 | // } 14 | // 15 | // When implementing the methods of an interface, you wire your functions up 16 | // to call the Mock.Called(args...) method, and return the appropriate values. 17 | // 18 | // For example, to mock a method that saves the name and age of a person and returns 19 | // the year of their birth or an error, you might write this: 20 | // 21 | // func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) { 22 | // args := o.Called(firstname, lastname, age) 23 | // return args.Int(0), args.Error(1) 24 | // } 25 | // 26 | // The Int, Error and Bool methods are examples of strongly typed getters that take the argument 27 | // index position. Given this argument list: 28 | // 29 | // (12, true, "Something") 30 | // 31 | // You could read them out strongly typed like this: 32 | // 33 | // args.Int(0) 34 | // args.Bool(1) 35 | // args.String(2) 36 | // 37 | // For objects of your own type, use the generic Arguments.Get(index) method and make a type assertion: 38 | // 39 | // return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine) 40 | // 41 | // This may cause a panic if the object you are getting is nil (the type assertion will fail), in those 42 | // cases you should check for nil first. 43 | package mock 44 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/bypasssafe.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when either the code is running on Google App Engine or "-tags disableunsafe" 17 | // is added to the go build command line. 18 | // +build appengine disableunsafe 19 | 20 | package spew 21 | 22 | import "reflect" 23 | 24 | const ( 25 | // UnsafeDisabled is a build-time constant which specifies whether or 26 | // not access to the unsafe package is available. 27 | UnsafeDisabled = true 28 | ) 29 | 30 | // unsafeReflectValue typically converts the passed reflect.Value into a one 31 | // that bypasses the typical safety restrictions preventing access to 32 | // unaddressable and unexported data. However, doing this relies on access to 33 | // the unsafe package. This is a stub version which simply returns the passed 34 | // reflect.Value when the unsafe package is not available. 35 | func unsafeReflectValue(v reflect.Value) reflect.Value { 36 | return v 37 | } 38 | -------------------------------------------------------------------------------- /cmd/goexportdefault/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "log" 7 | "os" 8 | "regexp" 9 | 10 | "github.com/ernesto-jimenez/gogen/exportdefault" 11 | "github.com/ernesto-jimenez/gogen/strconv" 12 | ) 13 | 14 | var ( 15 | out = flag.String("o", "", "specify the name of the generated code. Default value is by generated based on the name of the variable, e.g.: DefaultClient -> default_client_funcs.go (use \"-\" to print to stdout)") 16 | pref = flag.String("prefix", "", "prefix for the exported function names") 17 | include = flag.String("include", "", "export only those methods that match this regexp") 18 | exclude = flag.String("exclude", "", "exclude those methods that match this regexp") 19 | ) 20 | 21 | func main() { 22 | flag.Parse() 23 | log.SetFlags(0) 24 | 25 | // Variable whose methods we want to wrap 26 | v := flag.Arg(0) 27 | 28 | gen, err := exportdefault.New(".", v) 29 | if err != nil { 30 | log.Fatal(err) 31 | } 32 | 33 | gen.FuncNamePrefix = *pref 34 | 35 | if expr, err := regexp.Compile(*include); *include != "" && err == nil { 36 | gen.Include = expr 37 | } else if *include != "" { 38 | log.Fatalf("-include contains a invalid regular expression: %s", err.Error()) 39 | } 40 | 41 | if expr, err := regexp.Compile(*include); *exclude != "" && err == nil { 42 | gen.Exclude = expr 43 | } else if *exclude != "" { 44 | log.Fatalf("-exclude contains a invalid regular expression: %s", err.Error()) 45 | } 46 | 47 | w := os.Stdout 48 | if *out == "" { 49 | *out = fmt.Sprintf("%s_funcs.go", v) 50 | } 51 | if *out != "-" { 52 | log.Printf("Generating funcs for %s", v) 53 | *out = strconv.SnakeCase(*out) 54 | w, err = os.OpenFile(*out, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666) 55 | if err != nil { 56 | log.Fatal(err) 57 | } 58 | } 59 | 60 | err = gen.Write(w) 61 | if err != nil { 62 | log.Fatal(err) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /specific/process_test.go: -------------------------------------------------------------------------------- 1 | package specific 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "os/exec" 8 | "testing" 9 | ) 10 | 11 | func TestProcessContainerRingBuildsWithString(t *testing.T) { 12 | out, err := ioutil.TempDir("", "container-ring") 13 | if err != nil { 14 | t.Fatal(err) 15 | } 16 | defer os.Remove(out) 17 | 18 | Process("container/ring", out, "string", func(opts *Options) { 19 | opts.SkipTestFiles = true 20 | }) 21 | 22 | if err := build(out); err != nil { 23 | t.Fatalf("failed to build resulting package\n%s", err.Error()) 24 | } 25 | } 26 | 27 | func TestProcessContainerRingBuildsWithOsFile(t *testing.T) { 28 | out, err := ioutil.TempDir("", "container-ring") 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | defer os.Remove(out) 33 | 34 | Process("container/ring", out, "*os.File", func(opts *Options) { 35 | opts.SkipTestFiles = true 36 | }) 37 | 38 | if err := build(out); err != nil { 39 | t.Fatalf("failed to build resulting package\n%s", err.Error()) 40 | } 41 | } 42 | 43 | func TestProcessContainerList(t *testing.T) { 44 | out, err := ioutil.TempDir("", "container-list") 45 | if err != nil { 46 | t.Fatal(err) 47 | } 48 | defer os.Remove(out) 49 | 50 | Process("container/list", out, "string", func(opts *Options) { 51 | opts.SkipTestFiles = true 52 | }) 53 | 54 | if err := build(out); err != nil { 55 | t.Fatalf("failed to build resulting package\n%s", err.Error()) 56 | } 57 | } 58 | 59 | func TestProcessTestPkg(t *testing.T) { 60 | out, err := ioutil.TempDir("", "testpkg") 61 | if err != nil { 62 | t.Fatal(err) 63 | } 64 | defer os.Remove(out) 65 | 66 | Process("github.com/ernesto-jimenez/gogen/specific/_testpkg", out, "string", func(opts *Options) { 67 | opts.SkipTestFiles = true 68 | }) 69 | 70 | if err := build(out); err != nil { 71 | t.Fatalf("failed to build resulting package\n%s", err.Error()) 72 | } 73 | } 74 | 75 | func build(dir string) error { 76 | os.Chdir(dir) 77 | cmd := exec.Command("go", "build") 78 | out, err := cmd.CombinedOutput() 79 | if err != nil { 80 | return fmt.Errorf("%s\n%s", err.Error(), out) 81 | } 82 | return nil 83 | } 84 | -------------------------------------------------------------------------------- /cmd/gosimplemock/README.md: -------------------------------------------------------------------------------- 1 | # gosimplemock 2 | 3 | Automatically generate simple mocks with zero dependencies 4 | 5 | # Usage 6 | 7 | Creating an interface in your code to mock a dependency 8 | 9 | ```go 10 | type server interface { 11 | Serve(string) ([]byte, error) 12 | } 13 | 14 | func request(s server, path string) ([]byte, error) { 15 | return s.Serve(path) 16 | } 17 | 18 | //go:generate gosimplemock server 19 | 20 | // Dummy test 21 | func TestRequestReturnsServerError(t *testing.T) { 22 | m := &requestMock{ 23 | ServeFunc: func(path string) ([]byte, error) { 24 | return nil, errors.New("failure") 25 | }, 26 | } 27 | _, err := request(m, "/something") 28 | assert.Error(t, err) 29 | } 30 | ``` 31 | 32 | Mocking an interface from the standard library 33 | 34 | ```go 35 | //go:generate gosimplemock io.Writer 36 | 37 | // Dummy test using the generated mock 38 | func TestWriter(t *testing.T) { 39 | expected := []byte("hello world") 40 | m := &WriterMock{ 41 | WriteFunc: func(actual []byte) (int, error) { 42 | assert.Equal(t, expected, actual) 43 | return len(actual), nil 44 | }, 45 | } 46 | n, err := m.Write(expected) 47 | assert.Equal(t, 11, n) 48 | assert.Equal(t, nil, err) 49 | } 50 | ``` 51 | 52 | Printing the generated code: 53 | 54 | ```go 55 | $ gosimplemock -o=- io.ReadCloser 56 | /* 57 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/cmd/gosimplemock 58 | * THIS FILE SHOULD NOT BE EDITED BY HAND 59 | */ 60 | 61 | package gogen 62 | 63 | // ReadCloserMock mock 64 | type ReadCloserMock struct { 65 | CloseFunc func() error 66 | 67 | ReadFunc func([]byte) (int, error) 68 | } 69 | 70 | // Close mocked method 71 | func (m *ReadCloserMock) Close() error { 72 | if m.CloseFunc == nil { 73 | panic("unexpected call to mocked method Close") 74 | } 75 | return m.CloseFunc() 76 | } 77 | 78 | // Read mocked method 79 | func (m *ReadCloserMock) Read(p0 []byte) (int, error) { 80 | if m.ReadFunc == nil { 81 | panic("unexpected call to mocked method Read") 82 | } 83 | return m.ReadFunc(p0) 84 | } 85 | ``` 86 | -------------------------------------------------------------------------------- /imports/imports.go: -------------------------------------------------------------------------------- 1 | package imports 2 | 3 | import ( 4 | "go/types" 5 | "os" 6 | "path/filepath" 7 | "strings" 8 | ) 9 | 10 | type Importer interface { 11 | AddImportsFrom(t types.Type) 12 | Imports() map[string]string 13 | } 14 | 15 | // imports contains metadata about all the imports from a given package 16 | type imports struct { 17 | currentpkg string 18 | imp map[string]string 19 | } 20 | 21 | // AddImportsFrom adds imports used in the passed type 22 | func (imp *imports) AddImportsFrom(t types.Type) { 23 | switch el := t.(type) { 24 | case *types.Basic: 25 | case *types.Slice: 26 | imp.AddImportsFrom(el.Elem()) 27 | case *types.Pointer: 28 | imp.AddImportsFrom(el.Elem()) 29 | case *types.Named: 30 | pkg := el.Obj().Pkg() 31 | if pkg == nil { 32 | return 33 | } 34 | if pkg.Name() == imp.currentpkg { 35 | return 36 | } 37 | imp.imp[cleanImportPath(pkg.Path())] = pkg.Name() 38 | case *types.Tuple: 39 | for i := 0; i < el.Len(); i++ { 40 | imp.AddImportsFrom(el.At(i).Type()) 41 | } 42 | default: 43 | } 44 | } 45 | 46 | func cleanImportPath(ipath string) string { 47 | return gopathlessImportPath( 48 | vendorlessImportPath(ipath), 49 | ) 50 | } 51 | 52 | func gopathlessImportPath(ipath string) string { 53 | paths := strings.Split(os.Getenv("GOPATH"), ":") 54 | for _, p := range paths { 55 | ipath = strings.TrimPrefix(ipath, filepath.Join(p, "src")+string(filepath.Separator)) 56 | } 57 | return ipath 58 | } 59 | 60 | // vendorlessImportPath returns the devendorized version of the provided import path. 61 | // e.g. "foo/bar/vendor/a/b" => "a/b" 62 | func vendorlessImportPath(ipath string) string { 63 | // Devendorize for use in import statement. 64 | if i := strings.LastIndex(ipath, "/vendor/"); i >= 0 { 65 | return ipath[i+len("/vendor/"):] 66 | } 67 | if strings.HasPrefix(ipath, "vendor/") { 68 | return ipath[len("vendor/"):] 69 | } 70 | return ipath 71 | } 72 | 73 | // AddImportsFrom adds imports used in the passed type 74 | func (imp *imports) Imports() map[string]string { 75 | return imp.imp 76 | } 77 | 78 | // New initializes a new structure to track packages imported by the currentpkg 79 | func New(currentpkg string) Importer { 80 | return &imports{ 81 | currentpkg: currentpkg, 82 | imp: make(map[string]string), 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/simple_struct_unmarshalmap.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package testpkg 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // UnmarshalMap takes a map and unmarshals the fieds into the struct 13 | func (s *SimpleStruct) UnmarshalMap(m map[string]interface{}) error { 14 | 15 | if v, ok := m["SimpleField"].(string); ok { 16 | s.SimpleField = v 17 | 18 | } else if v, exists := m["SimpleField"]; exists && v != nil { 19 | return fmt.Errorf("expected field SimpleField to be string but got %T", m["SimpleField"]) 20 | } 21 | 22 | if v, ok := m["field2"].(string); ok { 23 | s.SimpleJSONTagged = v 24 | 25 | } else if v, exists := m["field2"]; exists && v != nil { 26 | return fmt.Errorf("expected field field2 to be string but got %T", m["field2"]) 27 | } 28 | 29 | if v, ok := m["field3"].(string); ok { 30 | s.SimpleJSONTaggedOmitted = v 31 | 32 | } else if v, exists := m["field3"]; exists && v != nil { 33 | return fmt.Errorf("expected field field3 to be string but got %T", m["field3"]) 34 | } 35 | 36 | if v, ok := m["SimpleOmitEmptyNoName"].(string); ok { 37 | s.SimpleOmitEmptyNoName = v 38 | 39 | } else if v, exists := m["SimpleOmitEmptyNoName"]; exists && v != nil { 40 | return fmt.Errorf("expected field SimpleOmitEmptyNoName to be string but got %T", m["SimpleOmitEmptyNoName"]) 41 | } 42 | 43 | // Pointer SimplePointer 44 | if p, ok := m["pointer"]; ok { 45 | 46 | if m, ok := p.(string); ok { 47 | s.SimplePointer = &m 48 | 49 | } else if p == nil { 50 | s.SimplePointer = nil 51 | } 52 | 53 | } 54 | 55 | if v, ok := m["integer"].(int); ok { 56 | s.SimpleInteger = v 57 | 58 | } else if p, ok := m["integer"].(float64); ok { 59 | v := int(p) 60 | s.SimpleInteger = v 61 | 62 | } else if v, exists := m["integer"]; exists && v != nil { 63 | return fmt.Errorf("expected field integer to be int but got %T", m["integer"]) 64 | } 65 | 66 | // Pointer SimpleIntegerPtr 67 | if p, ok := m["integer_ptr"]; ok { 68 | 69 | if m, ok := p.(int); ok { 70 | s.SimpleIntegerPtr = &m 71 | 72 | } else if m, ok := p.(float64); ok { 73 | v := int(m) 74 | s.SimpleIntegerPtr = &v 75 | 76 | } else if p == nil { 77 | s.SimpleIntegerPtr = nil 78 | } 79 | 80 | } 81 | 82 | return nil 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/mutations.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | // Exclude returns a new Map with the keys in the specified []string 4 | // excluded. 5 | func (d Map) Exclude(exclude []string) Map { 6 | 7 | excluded := make(Map) 8 | for k, v := range d { 9 | var shouldInclude bool = true 10 | for _, toExclude := range exclude { 11 | if k == toExclude { 12 | shouldInclude = false 13 | break 14 | } 15 | } 16 | if shouldInclude { 17 | excluded[k] = v 18 | } 19 | } 20 | 21 | return excluded 22 | } 23 | 24 | // Copy creates a shallow copy of the Obj. 25 | func (m Map) Copy() Map { 26 | copied := make(map[string]interface{}) 27 | for k, v := range m { 28 | copied[k] = v 29 | } 30 | return New(copied) 31 | } 32 | 33 | // Merge blends the specified map with a copy of this map and returns the result. 34 | // 35 | // Keys that appear in both will be selected from the specified map. 36 | // This method requires that the wrapped object be a map[string]interface{} 37 | func (m Map) Merge(merge Map) Map { 38 | return m.Copy().MergeHere(merge) 39 | } 40 | 41 | // Merge blends the specified map with this map and returns the current map. 42 | // 43 | // Keys that appear in both will be selected from the specified map. The original map 44 | // will be modified. This method requires that 45 | // the wrapped object be a map[string]interface{} 46 | func (m Map) MergeHere(merge Map) Map { 47 | 48 | for k, v := range merge { 49 | m[k] = v 50 | } 51 | 52 | return m 53 | 54 | } 55 | 56 | // Transform builds a new Obj giving the transformer a chance 57 | // to change the keys and values as it goes. This method requires that 58 | // the wrapped object be a map[string]interface{} 59 | func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map { 60 | newMap := make(map[string]interface{}) 61 | for k, v := range m { 62 | modifiedKey, modifiedVal := transformer(k, v) 63 | newMap[modifiedKey] = modifiedVal 64 | } 65 | return New(newMap) 66 | } 67 | 68 | // TransformKeys builds a new map using the specified key mapping. 69 | // 70 | // Unspecified keys will be unaltered. 71 | // This method requires that the wrapped object be a map[string]interface{} 72 | func (m Map) TransformKeys(mapping map[string]string) Map { 73 | return m.Transform(func(key string, value interface{}) (string, interface{}) { 74 | 75 | if newKey, ok := mapping[key]; ok { 76 | return newKey, value 77 | } 78 | 79 | return key, value 80 | }) 81 | } 82 | -------------------------------------------------------------------------------- /cmd/goautomock/README.md: -------------------------------------------------------------------------------- 1 | # goautomock 2 | 3 | Automatically generate mocks 4 | 5 | # Usage 6 | 7 | Creating an interface in your code to mock a dependency 8 | 9 | ```go 10 | type server interface { 11 | Serve(string) ([]byte, error) 12 | } 13 | 14 | func request(s server, path string) ([]byte, error) { 15 | return s.Serve(path) 16 | } 17 | 18 | //go:generate goautomock server 19 | 20 | // Dummy test 21 | func TestRequestReturnsServerError(t *testing.T) { 22 | m := &requestMock{} 23 | m.On("Serve", "/something").Return(nil, errors.New("failure")) 24 | _, err := request(m, "/something") 25 | assert.Error(t, err) 26 | } 27 | ``` 28 | 29 | Mocking an interface from the standard library 30 | 31 | ```go 32 | //go:generate goautomock io.Writer 33 | 34 | // Dummy test using the generated mock 35 | func TestWriter(t *testing.T) { 36 | m := &WriterMock{} 37 | expected := []byte("hello world") 38 | m.On("Write", expected).Return(11, nil) 39 | 40 | n, err := m.Write(expected) 41 | assert.Equal(t, 11, n) 42 | assert.Equal(t, nil, err) 43 | } 44 | ``` 45 | 46 | Printing the generated code: 47 | 48 | ```go 49 | $ goautomock -o=- io.ReadCloser 50 | /* 51 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/automock 52 | * THIS FILE SHOULD NOT BE EDITED BY HAND 53 | */ 54 | 55 | package gogen 56 | 57 | import ( 58 | "fmt" 59 | mock "github.com/stretchr/testify/mock" 60 | ) 61 | 62 | // ReadCloserMock mock 63 | type ReadCloserMock struct { 64 | mock.Mock 65 | } 66 | 67 | // Close mocked method 68 | func (m *ReadCloserMock) Close() error { 69 | 70 | ret := m.Called() 71 | 72 | var r0 error 73 | switch res := ret.Get(0).(type) { 74 | case nil: 75 | case error: 76 | r0 = res 77 | default: 78 | panic(fmt.Sprintf("unexpected type: %v", res)) 79 | } 80 | 81 | return r0 82 | 83 | } 84 | 85 | // Read mocked method 86 | func (m *ReadCloserMock) Read(p0 []byte) (int, error) { 87 | 88 | ret := m.Called(p0) 89 | 90 | var r0 int 91 | switch res := ret.Get(0).(type) { 92 | case nil: 93 | case int: 94 | r0 = res 95 | default: 96 | panic(fmt.Sprintf("unexpected type: %v", res)) 97 | } 98 | 99 | var r1 error 100 | switch res := ret.Get(1).(type) { 101 | case nil: 102 | case error: 103 | r1 = res 104 | default: 105 | panic(fmt.Sprintf("unexpected type: %v", res)) 106 | } 107 | 108 | return r0, r1 109 | 110 | } 111 | ``` 112 | -------------------------------------------------------------------------------- /cmd/goautomock/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "log" 7 | "os" 8 | "path" 9 | "regexp" 10 | "strings" 11 | 12 | "github.com/ernesto-jimenez/gogen/automock" 13 | "github.com/ernesto-jimenez/gogen/importer" 14 | "github.com/ernesto-jimenez/gogen/strconv" 15 | ) 16 | 17 | var ( 18 | out = flag.String("o", "", "override the name of the generated code. Default value is by generated based on the name of the interface, e.g.: Reader -> reader_mock_test.go (use \"-\" to print to stdout)") 19 | mockName = flag.String("mock-name", "", "override the name for the mock struct") 20 | mockPkg = flag.String("mock-pkg", "", "override the package name for the mock") 21 | pkg = flag.String("pkg", ".", "override package to get the interface from. It can be specified in the interface name, e.g.: goautomock io.Reader") 22 | ) 23 | 24 | func main() { 25 | flag.Parse() 26 | log.SetFlags(0) 27 | 28 | iface := flag.Arg(0) 29 | 30 | if iface == "" { 31 | log.Fatal("need to specify an interface name") 32 | } 33 | 34 | parts := strings.Split(iface, ".") 35 | switch len(parts) { 36 | case 1: 37 | case 2: 38 | if *pkg != "." { 39 | log.Fatalf("unexpected -pkg value (%q), package is already defined in the interface name as %s", *pkg, parts[0]) 40 | } 41 | *pkg = parts[0] 42 | iface = parts[1] 43 | default: 44 | log.Fatalf("invalid interface %q", iface) 45 | } 46 | 47 | gen, err := automock.NewGenerator(*pkg, iface) 48 | if err != nil { 49 | log.Fatal(err) 50 | } 51 | 52 | if *mockName != "" { 53 | gen.SetName(*mockName) 54 | } 55 | inPkg := *pkg == "." && path.Dir(*out) == "." 56 | gen.SetInternal(inPkg) 57 | if *mockPkg == "" && !inPkg { 58 | p, err := importer.Default().Import(".") 59 | if err != nil { 60 | log.Fatal(err) 61 | } 62 | *mockPkg = p.Name() 63 | } 64 | if *mockPkg != "" { 65 | gen.SetPackage(*mockPkg) 66 | } 67 | 68 | w := os.Stdout 69 | if *out == "" { 70 | *out = fmt.Sprintf("%s_test.go", gen.Name()) 71 | if p := regexp.MustCompile(".*/").ReplaceAllString(*pkg, ""); !inPkg && p != "" && p != "." { 72 | *out = p + "_" + *out 73 | } 74 | } 75 | if *out != "-" { 76 | *out = strconv.SnakeCase(*out) 77 | log.Printf("Generating mock for %s in %s", iface, *out) 78 | w, err = os.OpenFile(*out, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666) 79 | if err != nil { 80 | log.Fatal(err) 81 | } 82 | } 83 | 84 | err = gen.Write(w) 85 | switch err := err.(type) { 86 | case automock.GenerationError: 87 | log.Println(err.CodeWithLineNumbers()) 88 | log.Fatal(err) 89 | case error: 90 | log.Fatal(err) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/doc.go: -------------------------------------------------------------------------------- 1 | // objx - Go package for dealing with maps, slices, JSON and other data. 2 | // 3 | // Overview 4 | // 5 | // Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes 6 | // a powerful `Get` method (among others) that allows you to easily and quickly get 7 | // access to data within the map, without having to worry too much about type assertions, 8 | // missing data, default values etc. 9 | // 10 | // Pattern 11 | // 12 | // Objx uses a preditable pattern to make access data from within `map[string]interface{}'s 13 | // easy. 14 | // 15 | // Call one of the `objx.` functions to create your `objx.Map` to get going: 16 | // 17 | // m, err := objx.FromJSON(json) 18 | // 19 | // NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong, 20 | // the rest will be optimistic and try to figure things out without panicking. 21 | // 22 | // Use `Get` to access the value you're interested in. You can use dot and array 23 | // notation too: 24 | // 25 | // m.Get("places[0].latlng") 26 | // 27 | // Once you have saught the `Value` you're interested in, you can use the `Is*` methods 28 | // to determine its type. 29 | // 30 | // if m.Get("code").IsStr() { /* ... */ } 31 | // 32 | // Or you can just assume the type, and use one of the strong type methods to 33 | // extract the real value: 34 | // 35 | // m.Get("code").Int() 36 | // 37 | // If there's no value there (or if it's the wrong type) then a default value 38 | // will be returned, or you can be explicit about the default value. 39 | // 40 | // Get("code").Int(-1) 41 | // 42 | // If you're dealing with a slice of data as a value, Objx provides many useful 43 | // methods for iterating, manipulating and selecting that data. You can find out more 44 | // by exploring the index below. 45 | // 46 | // Reading data 47 | // 48 | // A simple example of how to use Objx: 49 | // 50 | // // use MustFromJSON to make an objx.Map from some JSON 51 | // m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) 52 | // 53 | // // get the details 54 | // name := m.Get("name").Str() 55 | // age := m.Get("age").Int() 56 | // 57 | // // get their nickname (or use their name if they 58 | // // don't have one) 59 | // nickname := m.Get("nickname").Str(name) 60 | // 61 | // Ranging 62 | // 63 | // Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For 64 | // example, to `range` the data, do what you would expect: 65 | // 66 | // m := objx.MustFromJSON(json) 67 | // for key, value := range m { 68 | // 69 | // /* ... do your magic ... */ 70 | // 71 | // } 72 | package objx 73 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/conversions.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | import ( 4 | "bytes" 5 | "encoding/base64" 6 | "encoding/json" 7 | "errors" 8 | "fmt" 9 | "net/url" 10 | ) 11 | 12 | // JSON converts the contained object to a JSON string 13 | // representation 14 | func (m Map) JSON() (string, error) { 15 | 16 | result, err := json.Marshal(m) 17 | 18 | if err != nil { 19 | err = errors.New("objx: JSON encode failed with: " + err.Error()) 20 | } 21 | 22 | return string(result), err 23 | 24 | } 25 | 26 | // MustJSON converts the contained object to a JSON string 27 | // representation and panics if there is an error 28 | func (m Map) MustJSON() string { 29 | result, err := m.JSON() 30 | if err != nil { 31 | panic(err.Error()) 32 | } 33 | return result 34 | } 35 | 36 | // Base64 converts the contained object to a Base64 string 37 | // representation of the JSON string representation 38 | func (m Map) Base64() (string, error) { 39 | 40 | var buf bytes.Buffer 41 | 42 | jsonData, err := m.JSON() 43 | if err != nil { 44 | return "", err 45 | } 46 | 47 | encoder := base64.NewEncoder(base64.StdEncoding, &buf) 48 | encoder.Write([]byte(jsonData)) 49 | encoder.Close() 50 | 51 | return buf.String(), nil 52 | 53 | } 54 | 55 | // MustBase64 converts the contained object to a Base64 string 56 | // representation of the JSON string representation and panics 57 | // if there is an error 58 | func (m Map) MustBase64() string { 59 | result, err := m.Base64() 60 | if err != nil { 61 | panic(err.Error()) 62 | } 63 | return result 64 | } 65 | 66 | // SignedBase64 converts the contained object to a Base64 string 67 | // representation of the JSON string representation and signs it 68 | // using the provided key. 69 | func (m Map) SignedBase64(key string) (string, error) { 70 | 71 | base64, err := m.Base64() 72 | if err != nil { 73 | return "", err 74 | } 75 | 76 | sig := HashWithKey(base64, key) 77 | 78 | return base64 + SignatureSeparator + sig, nil 79 | 80 | } 81 | 82 | // MustSignedBase64 converts the contained object to a Base64 string 83 | // representation of the JSON string representation and signs it 84 | // using the provided key and panics if there is an error 85 | func (m Map) MustSignedBase64(key string) string { 86 | result, err := m.SignedBase64(key) 87 | if err != nil { 88 | panic(err.Error()) 89 | } 90 | return result 91 | } 92 | 93 | /* 94 | URL Query 95 | ------------------------------------------------ 96 | */ 97 | 98 | // URLValues creates a url.Values object from an Obj. This 99 | // function requires that the wrapped object be a map[string]interface{} 100 | func (m Map) URLValues() url.Values { 101 | 102 | vals := make(url.Values) 103 | 104 | for k, v := range m { 105 | //TODO: can this be done without sprintf? 106 | vals.Set(k, fmt.Sprintf("%v", v)) 107 | } 108 | 109 | return vals 110 | } 111 | 112 | // URLQuery gets an encoded URL query representing the given 113 | // Obj. This function requires that the wrapped object be a 114 | // map[string]interface{} 115 | func (m Map) URLQuery() (string, error) { 116 | return m.URLValues().Encode(), nil 117 | } 118 | -------------------------------------------------------------------------------- /automock/generator_test.go: -------------------------------------------------------------------------------- 1 | package automock 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/mock" 13 | ) 14 | 15 | func TestNewGenerator(t *testing.T) { 16 | _, err := NewGenerator("io", "Writer") 17 | assert.NoError(t, err) 18 | } 19 | 20 | func TestNewGeneratorErrors(t *testing.T) { 21 | _, err := NewGenerator("someNonsense", "Writer") 22 | assert.Error(t, err) 23 | 24 | _, err = NewGenerator("io", "SomeWriter") 25 | assert.Error(t, err) 26 | } 27 | 28 | func TestMethods(t *testing.T) { 29 | g, err := NewGenerator("io", "Writer") 30 | assert.NoError(t, err) 31 | assert.Len(t, g.Methods(), 1) 32 | } 33 | 34 | func TestImports(t *testing.T) { 35 | g, err := NewGenerator("io", "Writer") 36 | assert.NoError(t, err) 37 | assert.Equal(t, map[string]string{}, g.Imports()) 38 | 39 | g, err = NewGenerator("net/http", "CookieJar") 40 | assert.NoError(t, err) 41 | assert.Equal(t, map[string]string{ 42 | "net/http": "http", 43 | "net/url": "url", 44 | }, g.Imports()) 45 | } 46 | 47 | func TestWritesProperly(t *testing.T) { 48 | tests := []struct { 49 | pkg string 50 | iface string 51 | }{ 52 | {"net/http", "CookieJar"}, 53 | {"io", "Writer"}, 54 | {"io", "ByteScanner"}, 55 | {"github.com/ernesto-jimenez/gogen/automock", "unexported"}, 56 | {".", "unexported"}, 57 | } 58 | for _, test := range tests { 59 | var out bytes.Buffer 60 | g, err := NewGenerator(test.pkg, test.iface) 61 | if err != nil { 62 | t.Error(err) 63 | continue 64 | } 65 | err = g.Write(&out) 66 | if !assert.NoError(t, err) { 67 | fmt.Println(test) 68 | fmt.Println(err) 69 | printWithLines(bytes.NewBuffer(out.Bytes())) 70 | } 71 | } 72 | } 73 | 74 | func printWithLines(txt io.Reader) { 75 | line := 0 76 | scanner := bufio.NewScanner(txt) 77 | for scanner.Scan() { 78 | line++ 79 | fmt.Printf("%-4d| %s\n", line, scanner.Text()) 80 | } 81 | } 82 | 83 | //go:generate go run ../cmd/goautomock/main.go io.Writer 84 | //go:generate go run ../cmd/goautomock/main.go -pkg=io ByteScanner 85 | //go:generate go run ../cmd/goautomock/main.go net/http.CookieJar 86 | 87 | func TestMockedIOWriter(t *testing.T) { 88 | m := &WriterMock{} 89 | expected := []byte("hello") 90 | m.On("Write", expected).Return(5, nil) 91 | n, err := m.Write(expected) 92 | assert.Equal(t, 5, n) 93 | assert.Equal(t, nil, err) 94 | } 95 | 96 | func TestMockedCookieJar(t *testing.T) { 97 | jar := &CookieJarMock{} 98 | cookie := http.Cookie{Name: "hello", Value: "World"} 99 | jar.On("Cookies", mock.AnythingOfType("*url.URL")).Return([]*http.Cookie{&cookie}).Once() 100 | c := http.Client{Jar: jar} 101 | c.Get("http://localhost") 102 | 103 | jar.On("Cookies", mock.AnythingOfType("*url.URL")).Return(nil).Once() 104 | c.Get("http://localhost") 105 | } 106 | 107 | func TestMockByteScanner(t *testing.T) { 108 | var s io.ByteScanner 109 | m := &ByteScannerMock{} 110 | s = m 111 | m.On("ReadByte").Return(byte('_'), nil) 112 | b, err := s.ReadByte() 113 | assert.Equal(t, byte('_'), b) 114 | assert.Equal(t, nil, err) 115 | } 116 | 117 | type unexported interface { 118 | io.Reader 119 | } 120 | 121 | //go:generate go run ../cmd/goautomock/main.go unexported 122 | 123 | func TestUnexported(t *testing.T) { 124 | m := &unexportedMock{} 125 | m.On("Read", mock.Anything).Return(1, nil) 126 | m.Read([]byte{}) 127 | } 128 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when both cgo is supported and "-tags testcgo" is added to the go test 17 | // command line. This code should really only be in the dumpcgo_test.go file, 18 | // but unfortunately Go will not allow cgo in test files, so this is a 19 | // workaround to allow cgo types to be tested. This configuration is used 20 | // because spew itself does not require cgo to run even though it does handle 21 | // certain cgo types specially. Rather than forcing all clients to require cgo 22 | // and an external C compiler just to run the tests, this scheme makes them 23 | // optional. 24 | // +build cgo,testcgo 25 | 26 | package testdata 27 | 28 | /* 29 | #include 30 | typedef unsigned char custom_uchar_t; 31 | 32 | char *ncp = 0; 33 | char *cp = "test"; 34 | char ca[6] = {'t', 'e', 's', 't', '2', '\0'}; 35 | unsigned char uca[6] = {'t', 'e', 's', 't', '3', '\0'}; 36 | signed char sca[6] = {'t', 'e', 's', 't', '4', '\0'}; 37 | uint8_t ui8ta[6] = {'t', 'e', 's', 't', '5', '\0'}; 38 | custom_uchar_t tuca[6] = {'t', 'e', 's', 't', '6', '\0'}; 39 | */ 40 | import "C" 41 | 42 | // GetCgoNullCharPointer returns a null char pointer via cgo. This is only 43 | // used for tests. 44 | func GetCgoNullCharPointer() interface{} { 45 | return C.ncp 46 | } 47 | 48 | // GetCgoCharPointer returns a char pointer via cgo. This is only used for 49 | // tests. 50 | func GetCgoCharPointer() interface{} { 51 | return C.cp 52 | } 53 | 54 | // GetCgoCharArray returns a char array via cgo and the array's len and cap. 55 | // This is only used for tests. 56 | func GetCgoCharArray() (interface{}, int, int) { 57 | return C.ca, len(C.ca), cap(C.ca) 58 | } 59 | 60 | // GetCgoUnsignedCharArray returns an unsigned char array via cgo and the 61 | // array's len and cap. This is only used for tests. 62 | func GetCgoUnsignedCharArray() (interface{}, int, int) { 63 | return C.uca, len(C.uca), cap(C.uca) 64 | } 65 | 66 | // GetCgoSignedCharArray returns a signed char array via cgo and the array's len 67 | // and cap. This is only used for tests. 68 | func GetCgoSignedCharArray() (interface{}, int, int) { 69 | return C.sca, len(C.sca), cap(C.sca) 70 | } 71 | 72 | // GetCgoUint8tArray returns a uint8_t array via cgo and the array's len and 73 | // cap. This is only used for tests. 74 | func GetCgoUint8tArray() (interface{}, int, int) { 75 | return C.ui8ta, len(C.ui8ta), cap(C.ui8ta) 76 | } 77 | 78 | // GetCgoTypdefedUnsignedCharArray returns a typedefed unsigned char array via 79 | // cgo and the array's len and cap. This is only used for tests. 80 | func GetCgoTypdefedUnsignedCharArray() (interface{}, int, int) { 81 | return C.tuca, len(C.tuca), cap(C.tuca) 82 | } 83 | -------------------------------------------------------------------------------- /importer/importer.go: -------------------------------------------------------------------------------- 1 | package importer 2 | 3 | import ( 4 | "fmt" 5 | "go/ast" 6 | "go/importer" 7 | "go/parser" 8 | "go/token" 9 | "go/types" 10 | "io/ioutil" 11 | "os" 12 | "path" 13 | "path/filepath" 14 | "strings" 15 | 16 | "github.com/ernesto-jimenez/gogen/gogenutil" 17 | ) 18 | 19 | type customImporter struct { 20 | imported map[string]*types.Package 21 | base types.Importer 22 | skipTestFiles bool 23 | } 24 | 25 | func (i *customImporter) Import(path string) (*types.Package, error) { 26 | var err error 27 | if path == "" || path[0] == '.' { 28 | path, err = filepath.Abs(filepath.Clean(path)) 29 | if err != nil { 30 | return nil, err 31 | } 32 | path = gogenutil.StripGopath(path) 33 | } 34 | if pkg, ok := i.imported[path]; ok { 35 | return pkg, nil 36 | } 37 | pkg, err := i.fsPkg(path) 38 | if err != nil { 39 | return nil, err 40 | } 41 | i.imported[path] = pkg 42 | return pkg, nil 43 | } 44 | 45 | func gopathDir(pkg string) (string, error) { 46 | for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") { 47 | absPath, err := filepath.Abs(path.Join(gopath, "src", pkg)) 48 | if err != nil { 49 | return "", err 50 | } 51 | if dir, err := os.Stat(absPath); err == nil && dir.IsDir() { 52 | return absPath, nil 53 | } 54 | } 55 | return "", fmt.Errorf("%s not in $GOPATH", pkg) 56 | } 57 | 58 | func removeGopath(p string) string { 59 | for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") { 60 | p = strings.Replace(p, path.Join(gopath, "src")+"/", "", 1) 61 | } 62 | return p 63 | } 64 | 65 | func (i *customImporter) fsPkg(pkg string) (*types.Package, error) { 66 | dir, err := gopathDir(pkg) 67 | if err != nil { 68 | return importOrErr(i.base, pkg, err) 69 | } 70 | 71 | dirFiles, err := ioutil.ReadDir(dir) 72 | if err != nil { 73 | return importOrErr(i.base, pkg, err) 74 | } 75 | 76 | fset := token.NewFileSet() 77 | var files []*ast.File 78 | for _, fileInfo := range dirFiles { 79 | if fileInfo.IsDir() { 80 | continue 81 | } 82 | n := fileInfo.Name() 83 | if path.Ext(fileInfo.Name()) != ".go" { 84 | continue 85 | } 86 | if i.skipTestFiles && strings.Contains(fileInfo.Name(), "_test.go") { 87 | continue 88 | } 89 | file := path.Join(dir, n) 90 | src, err := ioutil.ReadFile(file) 91 | if err != nil { 92 | return nil, err 93 | } 94 | f, err := parser.ParseFile(fset, file, src, 0) 95 | if err != nil { 96 | return nil, err 97 | } 98 | files = append(files, f) 99 | } 100 | conf := types.Config{ 101 | Importer: i, 102 | } 103 | p, err := conf.Check(pkg, fset, files, nil) 104 | 105 | if err != nil { 106 | return importOrErr(i.base, pkg, err) 107 | } 108 | return p, nil 109 | } 110 | 111 | func importOrErr(base types.Importer, pkg string, err error) (*types.Package, error) { 112 | p, impErr := base.Import(pkg) 113 | if impErr != nil { 114 | return nil, err 115 | } 116 | return p, nil 117 | } 118 | 119 | // Default returns an importer that will try to import code from gopath before using go/importer.Default and skipping test files 120 | func Default() types.Importer { 121 | return &customImporter{ 122 | imported: make(map[string]*types.Package), 123 | base: importer.Default(), 124 | skipTestFiles: true, 125 | } 126 | } 127 | 128 | // DefaultWithTestFiles same as Default but it parses test files too 129 | func DefaultWithTestFiles() types.Importer { 130 | return &customImporter{ 131 | imported: make(map[string]*types.Package), 132 | base: importer.Default(), 133 | skipTestFiles: false, 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /cmd/gosimplemock/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "log" 7 | "os" 8 | "path" 9 | "regexp" 10 | "strings" 11 | 12 | "github.com/ernesto-jimenez/gogen/automock" 13 | "github.com/ernesto-jimenez/gogen/importer" 14 | "github.com/ernesto-jimenez/gogen/strconv" 15 | ) 16 | 17 | var ( 18 | out = flag.String("o", "", "override the name of the generated code. Default value is by generated based on the name of the interface, e.g.: Reader -> reader_mock_test.go (use \"-\" to print to stdout)") 19 | mockName = flag.String("mock-name", "", "override the name for the mock struct") 20 | mockPkg = flag.String("mock-pkg", "", "override the package name for the mock") 21 | pkg = flag.String("pkg", ".", "override package to get the interface from. It can be specified in the interface name, e.g.: goautomock io.Reader") 22 | ) 23 | 24 | func main() { 25 | flag.Parse() 26 | log.SetFlags(0) 27 | 28 | iface := flag.Arg(0) 29 | 30 | if iface == "" { 31 | log.Fatal("need to specify an interface name") 32 | } 33 | 34 | parts := strings.Split(iface, ".") 35 | switch len(parts) { 36 | case 1: 37 | case 2: 38 | if *pkg != "." { 39 | log.Fatalf("unexpected -pkg value (%q), package is already defined in the interface name as %s", *pkg, parts[0]) 40 | } 41 | *pkg = parts[0] 42 | iface = parts[1] 43 | default: 44 | log.Fatalf("invalid interface %q", iface) 45 | } 46 | 47 | gen, err := automock.NewGenerator(*pkg, iface) 48 | if err != nil { 49 | log.Fatal(err) 50 | } 51 | 52 | gen.SetTemplate(template) 53 | 54 | if *mockName != "" { 55 | gen.SetName(*mockName) 56 | } 57 | inPkg := *pkg == "." && path.Dir(*out) == "." 58 | gen.SetInternal(inPkg) 59 | if *mockPkg == "" && !inPkg { 60 | p, err := importer.Default().Import(".") 61 | if err != nil { 62 | log.Fatal(err) 63 | } 64 | *mockPkg = p.Name() 65 | } 66 | if *mockPkg != "" { 67 | gen.SetPackage(*mockPkg) 68 | } 69 | 70 | w := os.Stdout 71 | if *out == "" { 72 | *out = fmt.Sprintf("%s_test.go", gen.Name()) 73 | if p := regexp.MustCompile(".*/").ReplaceAllString(*pkg, ""); !inPkg && p != "" && p != "." { 74 | *out = p + "_" + *out 75 | } 76 | } 77 | if *out != "-" { 78 | *out = strconv.SnakeCase(*out) 79 | log.Printf("Generating mock for %s in %s", iface, *out) 80 | w, err = os.OpenFile(*out, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666) 81 | if err != nil { 82 | log.Fatal(err) 83 | } 84 | } 85 | 86 | err = gen.Write(w) 87 | switch err := err.(type) { 88 | case automock.GenerationError: 89 | log.Println(err.CodeWithLineNumbers()) 90 | log.Fatal(err) 91 | case error: 92 | log.Fatal(err) 93 | } 94 | } 95 | 96 | var template = `/* 97 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/cmd/gosimplemock 98 | * THIS FILE SHOULD NOT BE EDITED BY HAND 99 | */ 100 | 101 | package {{.Package}} 102 | 103 | import ( 104 | "fmt" 105 | {{range $path, $name := .Imports}} 106 | {{$name}} "{{$path}}"{{end}} 107 | ) 108 | 109 | // {{.Name}} mock 110 | type {{.Name}} struct { 111 | {{range .Methods}} 112 | {{.Name}}Func func({{range $index, $type := .ParamTypes}}{{if $index}}, {{end}}{{$type}}{{end}}) ({{range $index, $type := .ReturnTypes}}{{if $index}}, {{end}}{{$type}}{{end}}) 113 | {{end}} 114 | } 115 | 116 | {{$gen := .}} 117 | {{range .Methods}} 118 | // {{.Name}} mocked method 119 | func (m *{{$gen.Name}}) {{.Name}}({{range $index, $type := .ParamTypes}}{{if $index}}, {{end}}p{{$index}} {{$type}}{{end}}) ({{range $index, $type := .ReturnTypes}}{{if $index}}, {{end}}{{$type}}{{end}}) { 120 | if m.{{.Name}}Func == nil { 121 | panic("unexpected call to mocked method {{.Name}}") 122 | } 123 | {{if .ReturnTypes}}return {{end}} m.{{.Name}}Func({{range $index, $type := .ParamTypes}}{{if $index}}, {{end}}p{{$index}}{{end}}) 124 | } 125 | {{end}} 126 | ` 127 | -------------------------------------------------------------------------------- /unmarshalmap/field.go: -------------------------------------------------------------------------------- 1 | package unmarshalmap 2 | 3 | import ( 4 | "go/types" 5 | "reflect" 6 | "strings" 7 | ) 8 | 9 | // Field contains the details from an struct field 10 | type Field struct { 11 | gen *Generator 12 | tag string 13 | v *types.Var 14 | } 15 | 16 | // Name returns the method name 17 | func (f Field) Name() string { 18 | return f.v.Name() 19 | } 20 | 21 | func (f Field) IsExported() bool { 22 | return f.v.Exported() 23 | } 24 | 25 | func (f Field) Field() string { 26 | if f.tag == "" { 27 | return f.Name() 28 | } 29 | tag := reflect.StructTag(f.tag) 30 | j := tag.Get("json") 31 | if j == "" { 32 | return f.Name() 33 | } 34 | name := strings.Split(j, ",")[0] 35 | if name == "" { 36 | return f.Name() 37 | } 38 | if name == "-" { 39 | name = "" 40 | } 41 | return name 42 | } 43 | 44 | func (f Field) IsArrayOrSlice() bool { 45 | if _, ok := f.v.Type().(*types.Slice); ok { 46 | return true 47 | } 48 | _, ok := f.v.Type().(*types.Array) 49 | return ok 50 | } 51 | 52 | func (f Field) IsSlice() bool { 53 | _, ok := f.v.Type().(*types.Slice) 54 | return ok 55 | } 56 | 57 | func (f Field) IsPointer() bool { 58 | _, ok := f.v.Type().(*types.Pointer) 59 | return ok 60 | } 61 | 62 | func (f Field) IsStruct() bool { 63 | _, ok := f.v.Type().(*types.Named) 64 | return ok 65 | } 66 | 67 | func (f Field) Type() string { 68 | return types.TypeString(f.v.Type(), f.gen.qf) 69 | } 70 | 71 | func (f Field) UnderlyingTypeName() string { 72 | return types.TypeString(f.UnderlyingType(), f.gen.qf) 73 | } 74 | 75 | func (f Field) UnderlyingTarget() fieldser { 76 | var t types.Type 77 | switch v := f.v.Type().(type) { 78 | case elemer: 79 | t = v.Elem() 80 | case *types.Named: 81 | t = v 82 | } 83 | if _, ok := t.(underlyinger); !ok { 84 | return nil 85 | } 86 | u := t.(underlyinger).Underlying() 87 | switch t := u.(type) { 88 | case *types.Struct: 89 | return fields{ 90 | g: f.gen, 91 | target: t, 92 | } 93 | case *types.Pointer: 94 | return fields{ 95 | g: f.gen, 96 | target: t.Elem().(*types.Named).Underlying().(*types.Struct), 97 | } 98 | } 99 | return nil 100 | } 101 | 102 | type fields struct { 103 | g *Generator 104 | target *types.Struct 105 | } 106 | 107 | func (f fields) Fields() []Field { 108 | numFields := f.target.NumFields() 109 | fields := make([]Field, 0) 110 | for i := 0; i < numFields; i++ { 111 | f := Field{f.g, f.target.Tag(i), f.target.Field(i)} 112 | if f.Field() != "" { 113 | fields = append(fields, f) 114 | } 115 | } 116 | return fields 117 | } 118 | 119 | var fl *types.Basic 120 | 121 | func init() { 122 | for _, t := range types.Typ { 123 | if t.Kind() == types.Float64 { 124 | fl = t 125 | break 126 | } 127 | } 128 | } 129 | 130 | func (f Field) ConvertibleFromFloat64() bool { 131 | return types.ConvertibleTo(fl, f.v.Type()) 132 | } 133 | 134 | func (f Field) UnderlyingConvertibleFromFloat64() bool { 135 | return types.ConvertibleTo(fl, f.UnderlyingType()) 136 | } 137 | 138 | func (f Field) IsAnonymous() bool { 139 | return f.v.Anonymous() 140 | } 141 | 142 | type fieldser interface { 143 | Fields() []Field 144 | } 145 | 146 | func (f Field) UnderlyingIsBasic() bool { 147 | switch t := f.v.Type().(type) { 148 | case elemer: 149 | _, basic := t.Elem().(*types.Basic) 150 | return basic 151 | } 152 | _, basic := f.v.Type().(*types.Basic) 153 | return basic 154 | } 155 | 156 | func (f Field) UnderlyingIsPointer() bool { 157 | switch t := f.v.Type().(type) { 158 | case elemer: 159 | _, basic := t.Elem().(*types.Pointer) 160 | return basic 161 | } 162 | _, basic := f.v.Type().(*types.Pointer) 163 | return basic 164 | } 165 | 166 | func (f Field) UnderlyingType() types.Type { 167 | switch t := f.v.Type().(type) { 168 | case *types.Array: 169 | switch t := t.Elem().(type) { 170 | case *types.Pointer: 171 | return t.Elem() 172 | } 173 | return t.Elem() 174 | case *types.Slice: 175 | switch t := t.Elem().(type) { 176 | case *types.Pointer: 177 | return t.Elem() 178 | } 179 | return t.Elem() 180 | case elemer: 181 | return t.Elem() 182 | } 183 | return nil 184 | } 185 | 186 | type elemer interface { 187 | Elem() types.Type 188 | } 189 | 190 | type underlyinger interface { 191 | Underlying() types.Type 192 | } 193 | -------------------------------------------------------------------------------- /unmarshalmap/testunmarshalmap/test.go: -------------------------------------------------------------------------------- 1 | package testunmarshalmap 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "math/rand" 8 | "reflect" 9 | "strconv" 10 | "strings" 11 | "testing" 12 | 13 | "github.com/stretchr/testify/require" 14 | ) 15 | 16 | // Debug indicates we should log debugging information 17 | var Debug bool 18 | 19 | type unmarshalMapper interface { 20 | UnmarshalMap(map[string]interface{}) error 21 | } 22 | 23 | // Run tests that UnmarshalMap unmarshalls all fields 24 | func Run(t *testing.T, v unmarshalMapper) { 25 | // make an empty variable of the same type as v 26 | n := empty(t, v) 27 | 28 | // fill the variable with data 29 | fill(t, v) 30 | 31 | // generate a map[string]interface{} 32 | m := generateMap(t, v) 33 | 34 | // unmarshal generated map into the empty variable 35 | n.UnmarshalMap(m) 36 | 37 | require.Equal(t, v, n, "UnmarshalMap() method from %T out of date. regenerate the code", v) 38 | } 39 | 40 | func empty(t *testing.T, v unmarshalMapper) unmarshalMapper { 41 | n := makeNew(t, v) 42 | u, ok := n.(unmarshalMapper) 43 | if !ok { 44 | t.Fatalf("%T should implement UnmarshalMap", n) 45 | } 46 | return u 47 | } 48 | 49 | func generateMap(t *testing.T, v unmarshalMapper) map[string]interface{} { 50 | var buf bytes.Buffer 51 | err := json.NewEncoder(&buf).Encode(v) 52 | if err != nil { 53 | t.Fatal(err) 54 | } 55 | var m map[string]interface{} 56 | err = json.NewDecoder(&buf).Decode(&m) 57 | if err != nil { 58 | t.Fatal(err) 59 | } 60 | return m 61 | } 62 | 63 | func fill(t *testing.T, v interface{}) { 64 | val := reflect.ValueOf(v) 65 | fillReflect(t, "", val) 66 | } 67 | 68 | func makeNew(t *testing.T, v interface{}) interface{} { 69 | typ := reflect.TypeOf(v).Elem() 70 | val := reflect.New(typ) 71 | return val.Interface() 72 | } 73 | 74 | func fillReflect(t *testing.T, scope string, val reflect.Value) { 75 | if val.Kind() == reflect.Ptr { 76 | val = val.Elem() 77 | } 78 | typ := val.Type() 79 | if !val.IsValid() { 80 | t.Fatalf("invalid") 81 | } 82 | if Debug { 83 | t.Logf("%s %s", scope, typ.Kind()) 84 | } 85 | 86 | for i := 0; i < typ.NumField(); i++ { 87 | f := typ.Field(i) 88 | // Skip omitted fields 89 | if tag := strings.Split(f.Tag.Get("json"), ","); len(tag) > 0 && tag[0] == "-" { 90 | continue 91 | } 92 | if Debug { 93 | t.Logf("%s%s %s", scope, f.Name, f.Type.Kind()) 94 | } 95 | v := val.Field(i) 96 | fillValue(t, scope+f.Name+".", v) 97 | } 98 | } 99 | 100 | func fillValue(t *testing.T, scope string, v reflect.Value) { 101 | kind := v.Type().Kind() 102 | if kind == reflect.Ptr { 103 | v.Set(reflect.New(v.Type().Elem())) 104 | v = v.Elem() 105 | kind = v.Kind() 106 | } 107 | switch kind { 108 | case reflect.Ptr: 109 | t.Fatalf("%s should have been de-referenced", scope) 110 | case reflect.Interface, reflect.Chan, reflect.Func, reflect.Complex64, reflect.Complex128, reflect.Uintptr: 111 | t.Fatalf("%s cannot unmarshall %s", scope, kind) 112 | case reflect.Bool: 113 | v.SetBool(true) 114 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 115 | v.SetInt(newInt()) 116 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 117 | v.SetUint(newUint()) 118 | case reflect.Float32, reflect.Float64: 119 | v.SetFloat(newFloat()) 120 | case reflect.Array: 121 | l := v.Cap() 122 | for i := 0; i < l; i++ { 123 | fillValue(t, fmt.Sprintf("%s[%d].", scope, i), v.Index(i)) 124 | } 125 | case reflect.Slice: 126 | l := rand.Intn(5) + 1 127 | s := reflect.MakeSlice(v.Type(), l, l) 128 | v.Set(s) 129 | for i := 0; i < l; i++ { 130 | fillValue(t, fmt.Sprintf("%s[%d].", scope, i), s.Index(i)) 131 | } 132 | // case reflect.Map: 133 | // t.Fatalf("%s unmarshalling maps is still pending", scope) 134 | case reflect.String: 135 | v.SetString(newStr()) 136 | case reflect.Struct: 137 | fillReflect(t, scope, v) 138 | default: 139 | t.Fatalf("gounmarshalmap is missing support for %s unmarshalling", kind) 140 | } 141 | } 142 | 143 | var i uint64 144 | 145 | func newInt() int64 { 146 | i++ 147 | return int64(i) 148 | } 149 | 150 | func newFloat() float64 { 151 | i++ 152 | return float64(i) 153 | } 154 | 155 | func newUint() uint64 { 156 | i++ 157 | return i 158 | } 159 | 160 | func newStr() string { 161 | i++ 162 | return strconv.FormatInt(int64(i), 10) 163 | } 164 | -------------------------------------------------------------------------------- /unmarshalmap/testpkg/nested_unmarshalmap.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 3 | * THIS FILE SHOULD NOT BE EDITED BY HAND 4 | */ 5 | 6 | package testpkg 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // UnmarshalMap takes a map and unmarshals the fieds into the struct 13 | func (s *Nested) UnmarshalMap(m map[string]interface{}) error { 14 | 15 | // Struct First 16 | if m, ok := m["First"].(map[string]interface{}); ok { 17 | var s *Embedded = &s.First 18 | // Fill object 19 | 20 | if v, ok := m["Field"].(string); ok { 21 | s.Field = v 22 | 23 | } else if v, exists := m["Field"]; exists && v != nil { 24 | return fmt.Errorf("expected field Field to be string but got %T", m["Field"]) 25 | } 26 | 27 | } else if v, exists := m["First"]; exists && v != nil { 28 | return fmt.Errorf("expected field First to be map[string]interface{} but got %T", m["First"]) 29 | } 30 | 31 | // Pointer Second 32 | if p, ok := m["Second"]; ok { 33 | 34 | if m, ok := p.(map[string]interface{}); ok { 35 | if s.Second == nil { 36 | s.Second = &Embedded{} 37 | } 38 | s := s.Second 39 | 40 | if v, ok := m["Field"].(string); ok { 41 | s.Field = v 42 | 43 | } else if v, exists := m["Field"]; exists && v != nil { 44 | return fmt.Errorf("expected field Field to be string but got %T", m["Field"]) 45 | } 46 | 47 | } else if p == nil { 48 | s.Second = nil 49 | } else { 50 | return fmt.Errorf("expected field Second to be map[string]interface{} but got %T", p) 51 | } 52 | 53 | } 54 | 55 | // ArrayOrSlice Third 56 | 57 | if v, ok := m["Third"].([]interface{}); ok { 58 | 59 | s.Third = make([]Embedded, len(v)) 60 | 61 | prev := s 62 | for i, el := range v { 63 | var s *Embedded 64 | 65 | s = &prev.Third[i] 66 | 67 | if m, ok := el.(map[string]interface{}); ok { 68 | // Fill object 69 | 70 | if v, ok := m["Field"].(string); ok { 71 | s.Field = v 72 | 73 | } else if v, exists := m["Field"]; exists && v != nil { 74 | return fmt.Errorf("expected field Field to be string but got %T", m["Field"]) 75 | } 76 | 77 | } 78 | } 79 | } else if v, exists := m["Third"]; exists && v != nil { 80 | return fmt.Errorf("expected field Third to be []interface{} but got %T", m["Third"]) 81 | } 82 | 83 | // ArrayOrSlice Fourth 84 | 85 | if v, ok := m["Fourth"].([]interface{}); ok { 86 | 87 | s.Fourth = make([]*Embedded, len(v)) 88 | 89 | prev := s 90 | for i, el := range v { 91 | var s *Embedded 92 | 93 | if el == nil { 94 | continue 95 | } 96 | prev.Fourth[i] = &Embedded{} 97 | s = prev.Fourth[i] 98 | 99 | if m, ok := el.(map[string]interface{}); ok { 100 | // Fill object 101 | 102 | if v, ok := m["Field"].(string); ok { 103 | s.Field = v 104 | 105 | } else if v, exists := m["Field"]; exists && v != nil { 106 | return fmt.Errorf("expected field Field to be string but got %T", m["Field"]) 107 | } 108 | 109 | } 110 | } 111 | } else if v, exists := m["Fourth"]; exists && v != nil { 112 | return fmt.Errorf("expected field Fourth to be []interface{} but got %T", m["Fourth"]) 113 | } 114 | 115 | // ArrayOrSlice Fifth 116 | 117 | if v, ok := m["Fifth"].([]interface{}); ok { 118 | 119 | if len(s.Fifth) < len(v) { 120 | return fmt.Errorf("expected field Fifth to be an array with %d elements, but got an array with %d", len(s.Fifth), len(v)) 121 | } 122 | 123 | prev := s 124 | for i, el := range v { 125 | var s *Embedded 126 | 127 | s = &prev.Fifth[i] 128 | 129 | if m, ok := el.(map[string]interface{}); ok { 130 | // Fill object 131 | 132 | if v, ok := m["Field"].(string); ok { 133 | s.Field = v 134 | 135 | } else if v, exists := m["Field"]; exists && v != nil { 136 | return fmt.Errorf("expected field Field to be string but got %T", m["Field"]) 137 | } 138 | 139 | } 140 | } 141 | } else if v, exists := m["Fifth"]; exists && v != nil { 142 | return fmt.Errorf("expected field Fifth to be []interface{} but got %T", m["Fifth"]) 143 | } 144 | 145 | // ArrayOrSlice Sixth 146 | 147 | if v, ok := m["Sixth"].([]interface{}); ok { 148 | 149 | if len(s.Sixth) < len(v) { 150 | return fmt.Errorf("expected field Sixth to be an array with %d elements, but got an array with %d", len(s.Sixth), len(v)) 151 | } 152 | 153 | prev := s 154 | for i, el := range v { 155 | var s *Embedded 156 | 157 | if el == nil { 158 | continue 159 | } 160 | prev.Sixth[i] = &Embedded{} 161 | s = prev.Sixth[i] 162 | 163 | if m, ok := el.(map[string]interface{}); ok { 164 | // Fill object 165 | 166 | if v, ok := m["Field"].(string); ok { 167 | s.Field = v 168 | 169 | } else if v, exists := m["Field"]; exists && v != nil { 170 | return fmt.Errorf("expected field Field to be string but got %T", m["Field"]) 171 | } 172 | 173 | } 174 | } 175 | } else if v, exists := m["Sixth"]; exists && v != nil { 176 | return fmt.Errorf("expected field Sixth to be []interface{} but got %T", m["Sixth"]) 177 | } 178 | 179 | return nil 180 | } 181 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/accessors.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | // arrayAccesRegexString is the regex used to extract the array number 11 | // from the access path 12 | const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$` 13 | 14 | // arrayAccesRegex is the compiled arrayAccesRegexString 15 | var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString) 16 | 17 | // Get gets the value using the specified selector and 18 | // returns it inside a new Obj object. 19 | // 20 | // If it cannot find the value, Get will return a nil 21 | // value inside an instance of Obj. 22 | // 23 | // Get can only operate directly on map[string]interface{} and []interface. 24 | // 25 | // Example 26 | // 27 | // To access the title of the third chapter of the second book, do: 28 | // 29 | // o.Get("books[1].chapters[2].title") 30 | func (m Map) Get(selector string) *Value { 31 | rawObj := access(m, selector, nil, false, false) 32 | return &Value{data: rawObj} 33 | } 34 | 35 | // Set sets the value using the specified selector and 36 | // returns the object on which Set was called. 37 | // 38 | // Set can only operate directly on map[string]interface{} and []interface 39 | // 40 | // Example 41 | // 42 | // To set the title of the third chapter of the second book, do: 43 | // 44 | // o.Set("books[1].chapters[2].title","Time to Go") 45 | func (m Map) Set(selector string, value interface{}) Map { 46 | access(m, selector, value, true, false) 47 | return m 48 | } 49 | 50 | // access accesses the object using the selector and performs the 51 | // appropriate action. 52 | func access(current, selector, value interface{}, isSet, panics bool) interface{} { 53 | 54 | switch selector.(type) { 55 | case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: 56 | 57 | if array, ok := current.([]interface{}); ok { 58 | index := intFromInterface(selector) 59 | 60 | if index >= len(array) { 61 | if panics { 62 | panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array))) 63 | } 64 | return nil 65 | } 66 | 67 | return array[index] 68 | } 69 | 70 | return nil 71 | 72 | case string: 73 | 74 | selStr := selector.(string) 75 | selSegs := strings.SplitN(selStr, PathSeparator, 2) 76 | thisSel := selSegs[0] 77 | index := -1 78 | var err error 79 | 80 | // https://github.com/stretchr/objx/issues/12 81 | if strings.Contains(thisSel, "[") { 82 | 83 | arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel) 84 | 85 | if len(arrayMatches) > 0 { 86 | 87 | // Get the key into the map 88 | thisSel = arrayMatches[1] 89 | 90 | // Get the index into the array at the key 91 | index, err = strconv.Atoi(arrayMatches[2]) 92 | 93 | if err != nil { 94 | // This should never happen. If it does, something has gone 95 | // seriously wrong. Panic. 96 | panic("objx: Array index is not an integer. Must use array[int].") 97 | } 98 | 99 | } 100 | } 101 | 102 | if curMap, ok := current.(Map); ok { 103 | current = map[string]interface{}(curMap) 104 | } 105 | 106 | // get the object in question 107 | switch current.(type) { 108 | case map[string]interface{}: 109 | curMSI := current.(map[string]interface{}) 110 | if len(selSegs) <= 1 && isSet { 111 | curMSI[thisSel] = value 112 | return nil 113 | } else { 114 | current = curMSI[thisSel] 115 | } 116 | default: 117 | current = nil 118 | } 119 | 120 | if current == nil && panics { 121 | panic(fmt.Sprintf("objx: '%v' invalid on object.", selector)) 122 | } 123 | 124 | // do we need to access the item of an array? 125 | if index > -1 { 126 | if array, ok := current.([]interface{}); ok { 127 | if index < len(array) { 128 | current = array[index] 129 | } else { 130 | if panics { 131 | panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array))) 132 | } 133 | current = nil 134 | } 135 | } 136 | } 137 | 138 | if len(selSegs) > 1 { 139 | current = access(current, selSegs[1], value, isSet, panics) 140 | } 141 | 142 | } 143 | 144 | return current 145 | 146 | } 147 | 148 | // intFromInterface converts an interface object to the largest 149 | // representation of an unsigned integer using a type switch and 150 | // assertions 151 | func intFromInterface(selector interface{}) int { 152 | var value int 153 | switch selector.(type) { 154 | case int: 155 | value = selector.(int) 156 | case int8: 157 | value = int(selector.(int8)) 158 | case int16: 159 | value = int(selector.(int16)) 160 | case int32: 161 | value = int(selector.(int32)) 162 | case int64: 163 | value = int(selector.(int64)) 164 | case uint: 165 | value = int(selector.(uint)) 166 | case uint8: 167 | value = int(selector.(uint8)) 168 | case uint16: 169 | value = int(selector.(uint16)) 170 | case uint32: 171 | value = int(selector.(uint32)) 172 | case uint64: 173 | value = int(selector.(uint64)) 174 | default: 175 | panic("objx: array access argument is not an integer type (this should never happen)") 176 | } 177 | 178 | return value 179 | } 180 | -------------------------------------------------------------------------------- /specific/process.go: -------------------------------------------------------------------------------- 1 | // Package specific copies the source from a package and generates a second 2 | // package replacing some of the types used. It's aimed at taking generic 3 | // packages that rely on interface{} and generating packages that use a 4 | // specific type. 5 | package specific 6 | 7 | import ( 8 | "fmt" 9 | "go/ast" 10 | "go/parser" 11 | "go/printer" 12 | "go/token" 13 | "golang.org/x/tools/go/ast/astutil" 14 | "io/ioutil" 15 | "os" 16 | "path" 17 | ) 18 | 19 | type Options struct { 20 | SkipTestFiles bool 21 | } 22 | 23 | var DefaultOptions = Options{ 24 | SkipTestFiles: false, 25 | } 26 | 27 | // Process creates a specific package from the generic specified in pkg 28 | func Process(pkg, outdir string, newType string, optset ...func(*Options)) error { 29 | opts := DefaultOptions 30 | for _, fn := range optset { 31 | fn(&opts) 32 | } 33 | 34 | p, err := findPackage(pkg) 35 | if err != nil { 36 | return err 37 | } 38 | 39 | if outdir == "" { 40 | outdir = path.Base(pkg) 41 | } 42 | 43 | if err := os.MkdirAll(outdir, os.ModePerm); err != nil { 44 | return err 45 | } 46 | 47 | t := parseTargetType(newType) 48 | 49 | files, err := processFiles(p, p.GoFiles, t) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | if err := write(outdir, files); err != nil { 55 | return err 56 | } 57 | 58 | if opts.SkipTestFiles { 59 | return nil 60 | } 61 | 62 | files, err = processFiles(p, p.TestGoFiles, t) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | return write(outdir, files) 68 | } 69 | 70 | func processFiles(p Package, files []string, t targetType) ([]processedFile, error) { 71 | var result []processedFile 72 | for _, f := range files { 73 | res, err := processFile(p, f, t) 74 | if err != nil { 75 | return result, err 76 | } 77 | result = append(result, res) 78 | } 79 | return result, nil 80 | } 81 | 82 | func processFile(p Package, filename string, t targetType) (processedFile, error) { 83 | res := processedFile{filename: filename} 84 | 85 | in, err := os.Open(path.Join(p.Dir, filename)) 86 | if err != nil { 87 | return res, FileError{Package: p.Dir, File: filename, Err: err} 88 | } 89 | src, err := ioutil.ReadAll(in) 90 | if err != nil { 91 | return res, FileError{Package: p.Dir, File: filename, Err: err} 92 | } 93 | 94 | res.fset = token.NewFileSet() 95 | res.file, err = parser.ParseFile(res.fset, res.filename, src, parser.ParseComments|parser.AllErrors|parser.DeclarationErrors) 96 | if err != nil { 97 | return res, FileError{Package: p.Dir, File: filename, Err: err} 98 | } 99 | 100 | if replace(t, res.file) && t.newPkg != "" { 101 | astutil.AddImport(res.fset, res.file, t.newPkg) 102 | } 103 | 104 | return res, err 105 | } 106 | 107 | func replace(t targetType, n ast.Node) (replaced bool) { 108 | newType := t.newType 109 | ast.Walk(visitFn(func(node ast.Node) { 110 | if node == nil { 111 | return 112 | } 113 | switch n := node.(type) { 114 | case *ast.ArrayType: 115 | if t, ok := n.Elt.(*ast.InterfaceType); ok && t.Methods.NumFields() == 0 { 116 | str := ast.NewIdent(newType) 117 | str.NamePos = t.Pos() 118 | n.Elt = str 119 | replaced = true 120 | } 121 | case *ast.ChanType: 122 | if t, ok := n.Value.(*ast.InterfaceType); ok && t.Methods.NumFields() == 0 { 123 | str := ast.NewIdent(newType) 124 | str.NamePos = t.Pos() 125 | n.Value = str 126 | replaced = true 127 | } 128 | case *ast.MapType: 129 | if t, ok := n.Key.(*ast.InterfaceType); ok && t.Methods.NumFields() == 0 { 130 | str := ast.NewIdent(newType) 131 | str.NamePos = t.Pos() 132 | n.Key = str 133 | replaced = true 134 | } 135 | if t, ok := n.Value.(*ast.InterfaceType); ok && t.Methods.NumFields() == 0 { 136 | str := ast.NewIdent(newType) 137 | str.NamePos = t.Pos() 138 | n.Value = str 139 | replaced = true 140 | } 141 | case *ast.Field: 142 | if t, ok := n.Type.(*ast.InterfaceType); ok && t.Methods.NumFields() == 0 { 143 | str := ast.NewIdent(newType) 144 | str.NamePos = t.Pos() 145 | n.Type = str 146 | replaced = true 147 | } 148 | } 149 | }), n) 150 | return replaced 151 | } 152 | 153 | type visitFn func(node ast.Node) 154 | 155 | func (fn visitFn) Visit(node ast.Node) ast.Visitor { 156 | fn(node) 157 | return fn 158 | } 159 | 160 | func write(outdir string, files []processedFile) error { 161 | for _, f := range files { 162 | out, err := os.Create(path.Join(outdir, f.filename)) 163 | if err != nil { 164 | return FileError{Package: outdir, File: f.filename, Err: err} 165 | } 166 | 167 | fmt.Fprintf(out, "/*\n"+ 168 | "* CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/specific\n"+ 169 | "* THIS FILE SHOULD NOT BE EDITED BY HAND\n"+ 170 | "*/\n\n") 171 | printer.Fprint(out, f.fset, f.file) 172 | } 173 | return nil 174 | } 175 | 176 | type FileError struct { 177 | Package string 178 | File string 179 | Err error 180 | } 181 | 182 | func (ferr FileError) Error() string { 183 | return fmt.Sprintf("error in %s: %s", path.Join(ferr.Package, ferr.File), ferr.Err.Error()) 184 | } 185 | 186 | type processedFile struct { 187 | filename string 188 | fset *token.FileSet 189 | file *ast.File 190 | } 191 | -------------------------------------------------------------------------------- /automock/generator.go: -------------------------------------------------------------------------------- 1 | package automock 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "fmt" 7 | "go/types" 8 | "io" 9 | "text/template" 10 | 11 | "github.com/ernesto-jimenez/gogen/cleanimports" 12 | "github.com/ernesto-jimenez/gogen/importer" 13 | "github.com/ernesto-jimenez/gogen/imports" 14 | ) 15 | 16 | // Generator produces code to mock an interface 17 | type Generator struct { 18 | name string 19 | ifaceName string 20 | namePkg string 21 | inPkg bool 22 | pkg *types.Package 23 | iface *types.Interface 24 | mockTmpl *template.Template 25 | } 26 | 27 | // NewGenerator initializes a Generator that will mock the given interface from the specified package. 28 | func NewGenerator(pkg, iface string) (*Generator, error) { 29 | p, err := importer.DefaultWithTestFiles().Import(pkg) 30 | if err != nil { 31 | return nil, err 32 | } 33 | obj := p.Scope().Lookup(iface) 34 | if obj == nil { 35 | return nil, fmt.Errorf("interface %s missing", iface) 36 | } 37 | if !types.IsInterface(obj.Type()) { 38 | return nil, fmt.Errorf("%s should be an interface, was %s", iface, obj.Type()) 39 | } 40 | g := &Generator{ 41 | ifaceName: iface, 42 | pkg: p, 43 | iface: obj.Type().Underlying().(*types.Interface).Complete(), 44 | } 45 | g.SetTemplate(defaultMockTemplate) 46 | return g, nil 47 | } 48 | 49 | // Methods returns information about all the methods required to satisfy the interface 50 | func (g Generator) Methods() []Method { 51 | numMethods := g.iface.NumMethods() 52 | methods := make([]Method, numMethods) 53 | for i := 0; i < numMethods; i++ { 54 | methods[i] = Method{&g, g.iface.Method(i)} 55 | } 56 | return methods 57 | } 58 | 59 | func (g Generator) qf(pkg *types.Package) string { 60 | if g.inPkg && g.pkg == pkg { 61 | return "" 62 | } 63 | return pkg.Name() 64 | } 65 | 66 | // Name returns the mock type's name by default it is {interfaceName}Mock 67 | func (g Generator) Name() string { 68 | if g.name != "" { 69 | return g.name 70 | } 71 | return g.ifaceName + "Mock" 72 | } 73 | 74 | // SetName changes the mock type's name 75 | func (g *Generator) SetName(name string) { 76 | g.name = name 77 | } 78 | 79 | // Package returns the name of the package containing the mock 80 | func (g Generator) Package() string { 81 | if g.namePkg != "" { 82 | return g.namePkg 83 | } 84 | if g.inPkg { 85 | return g.pkg.Name() 86 | } 87 | return "mocks" 88 | } 89 | 90 | // SetPackage changes the package containing the mock 91 | func (g *Generator) SetPackage(name string) { 92 | g.namePkg = name 93 | } 94 | 95 | func (g *Generator) SetInternal(inPkg bool) { 96 | g.inPkg = inPkg 97 | } 98 | 99 | // Imports returns all the packages that have to be imported for the 100 | func (g Generator) Imports() map[string]string { 101 | imports := imports.New(g.Package()) 102 | for _, m := range g.Methods() { 103 | s := m.signature() 104 | imports.AddImportsFrom(s.Params()) 105 | imports.AddImportsFrom(s.Results()) 106 | } 107 | return imports.Imports() 108 | } 109 | 110 | // SetTemplate allows defining a different template to generate the mock. It will be parsed with text/template and execuded with the Generator. 111 | func (g *Generator) SetTemplate(tmpl string) error { 112 | t, err := template.New("mock").Parse(tmpl) 113 | if err != nil { 114 | return err 115 | } 116 | g.mockTmpl = t 117 | return nil 118 | } 119 | 120 | // Write writes the generated code in the io.Writer 121 | func (g Generator) Write(wr io.Writer) error { 122 | var buf bytes.Buffer 123 | if err := g.mockTmpl.Execute(&buf, g); err != nil { 124 | return err 125 | } 126 | err := cleanimports.Clean(wr, buf.Bytes()) 127 | if err != nil { 128 | err = GenerationError{ 129 | Err: err, 130 | Code: buf.Bytes(), 131 | } 132 | } 133 | return err 134 | } 135 | 136 | // GenerationError is returned by Write when an error is encountered 137 | type GenerationError struct { 138 | Err error 139 | Code []byte 140 | } 141 | 142 | func (err GenerationError) Error() string { 143 | return err.Err.Error() 144 | } 145 | 146 | // CodeWithLineNumbers returns all the code including line numbers 147 | func (err GenerationError) CodeWithLineNumbers() string { 148 | var buf bytes.Buffer 149 | scanner := bufio.NewScanner(bytes.NewReader(err.Code)) 150 | var i int 151 | for scanner.Scan() { 152 | i++ 153 | fmt.Fprintf(&buf, "%d: %s\n", i, scanner.Text()) 154 | } 155 | return buf.String() 156 | } 157 | 158 | var ( 159 | defaultMockTemplate = `/* 160 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/automock 161 | * THIS FILE SHOULD NOT BE EDITED BY HAND 162 | */ 163 | 164 | package {{.Package}} 165 | 166 | import ( 167 | "fmt" 168 | mock "github.com/stretchr/testify/mock" 169 | {{range $path, $name := .Imports}} 170 | {{$name}} "{{$path}}"{{end}} 171 | ) 172 | 173 | // {{.Name}} mock 174 | type {{.Name}} struct { 175 | mock.Mock 176 | } 177 | 178 | {{$gen := .}} 179 | {{range .Methods}} 180 | // {{.Name}} mocked method 181 | func (m *{{$gen.Name}}) {{.Name}}({{range $index, $type := .ParamTypes}}{{if $index}}, {{end}}p{{$index}} {{$type}}{{end}}) ({{range $index, $type := .ReturnTypes}}{{if $index}}, {{end}}{{$type}}{{end}}) { 182 | {{if .ReturnTypes}} 183 | ret := m.Called({{range $index, $type := .ParamTypes}}{{if $index}}, {{end}}p{{$index}}{{end}}) 184 | {{range $index, $type := .ReturnTypes}} 185 | var r{{$index}} {{$type}} 186 | switch res := ret.Get({{$index}}).(type) { 187 | case nil: 188 | case {{$type}}: 189 | r{{$index}} = res 190 | default: 191 | panic(fmt.Sprintf("unexpected type: %v", res)) 192 | } 193 | {{end}} 194 | return {{range $index, $type := .ReturnTypes}}{{if $index}}, {{end}}r{{$index}}{{end}} 195 | {{else}} 196 | m.Called({{range $index, $type := .ParamTypes}}{{if $index}}, {{end}}p{{$index}}{{end}}) 197 | {{end}} 198 | } 199 | {{end}} 200 | ` 201 | ) 202 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/bypass.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is not running on Google App Engine and "-tags disableunsafe" 17 | // is not added to the go build command line. 18 | // +build !appengine,!disableunsafe 19 | 20 | package spew 21 | 22 | import ( 23 | "reflect" 24 | "unsafe" 25 | ) 26 | 27 | const ( 28 | // UnsafeDisabled is a build-time constant which specifies whether or 29 | // not access to the unsafe package is available. 30 | UnsafeDisabled = false 31 | 32 | // ptrSize is the size of a pointer on the current arch. 33 | ptrSize = unsafe.Sizeof((*byte)(nil)) 34 | ) 35 | 36 | var ( 37 | // offsetPtr, offsetScalar, and offsetFlag are the offsets for the 38 | // internal reflect.Value fields. These values are valid before golang 39 | // commit ecccf07e7f9d which changed the format. The are also valid 40 | // after commit 82f48826c6c7 which changed the format again to mirror 41 | // the original format. Code in the init function updates these offsets 42 | // as necessary. 43 | offsetPtr = uintptr(ptrSize) 44 | offsetScalar = uintptr(0) 45 | offsetFlag = uintptr(ptrSize * 2) 46 | 47 | // flagKindWidth and flagKindShift indicate various bits that the 48 | // reflect package uses internally to track kind information. 49 | // 50 | // flagRO indicates whether or not the value field of a reflect.Value is 51 | // read-only. 52 | // 53 | // flagIndir indicates whether the value field of a reflect.Value is 54 | // the actual data or a pointer to the data. 55 | // 56 | // These values are valid before golang commit 90a7c3c86944 which 57 | // changed their positions. Code in the init function updates these 58 | // flags as necessary. 59 | flagKindWidth = uintptr(5) 60 | flagKindShift = uintptr(flagKindWidth - 1) 61 | flagRO = uintptr(1 << 0) 62 | flagIndir = uintptr(1 << 1) 63 | ) 64 | 65 | func init() { 66 | // Older versions of reflect.Value stored small integers directly in the 67 | // ptr field (which is named val in the older versions). Versions 68 | // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named 69 | // scalar for this purpose which unfortunately came before the flag 70 | // field, so the offset of the flag field is different for those 71 | // versions. 72 | // 73 | // This code constructs a new reflect.Value from a known small integer 74 | // and checks if the size of the reflect.Value struct indicates it has 75 | // the scalar field. When it does, the offsets are updated accordingly. 76 | vv := reflect.ValueOf(0xf00) 77 | if unsafe.Sizeof(vv) == (ptrSize * 4) { 78 | offsetScalar = ptrSize * 2 79 | offsetFlag = ptrSize * 3 80 | } 81 | 82 | // Commit 90a7c3c86944 changed the flag positions such that the low 83 | // order bits are the kind. This code extracts the kind from the flags 84 | // field and ensures it's the correct type. When it's not, the flag 85 | // order has been changed to the newer format, so the flags are updated 86 | // accordingly. 87 | upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag) 88 | upfv := *(*uintptr)(upf) 89 | flagKindMask := uintptr((1<>flagKindShift != uintptr(reflect.Int) { 91 | flagKindShift = 0 92 | flagRO = 1 << 5 93 | flagIndir = 1 << 6 94 | 95 | // Commit adf9b30e5594 modified the flags to separate the 96 | // flagRO flag into two bits which specifies whether or not the 97 | // field is embedded. This causes flagIndir to move over a bit 98 | // and means that flagRO is the combination of either of the 99 | // original flagRO bit and the new bit. 100 | // 101 | // This code detects the change by extracting what used to be 102 | // the indirect bit to ensure it's set. When it's not, the flag 103 | // order has been changed to the newer format, so the flags are 104 | // updated accordingly. 105 | if upfv&flagIndir == 0 { 106 | flagRO = 3 << 5 107 | flagIndir = 1 << 7 108 | } 109 | } 110 | } 111 | 112 | // unsafeReflectValue converts the passed reflect.Value into a one that bypasses 113 | // the typical safety restrictions preventing access to unaddressable and 114 | // unexported data. It works by digging the raw pointer to the underlying 115 | // value out of the protected value and generating a new unprotected (unsafe) 116 | // reflect.Value to it. 117 | // 118 | // This allows us to check for implementations of the Stringer and error 119 | // interfaces to be used for pretty printing ordinarily unaddressable and 120 | // inaccessible values such as unexported struct fields. 121 | func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { 122 | indirects := 1 123 | vt := v.Type() 124 | upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr) 125 | rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag)) 126 | if rvf&flagIndir != 0 { 127 | vt = reflect.PtrTo(v.Type()) 128 | indirects++ 129 | } else if offsetScalar != 0 { 130 | // The value is in the scalar field when it's not one of the 131 | // reference types. 132 | switch vt.Kind() { 133 | case reflect.Uintptr: 134 | case reflect.Chan: 135 | case reflect.Func: 136 | case reflect.Map: 137 | case reflect.Ptr: 138 | case reflect.UnsafePointer: 139 | default: 140 | upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + 141 | offsetScalar) 142 | } 143 | } 144 | 145 | pv := reflect.NewAt(vt, upv) 146 | rv = pv 147 | for i := 0; i < indirects; i++ { 148 | rv = rv.Elem() 149 | } 150 | return rv 151 | } 152 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/http_assertions.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httptest" 7 | "net/url" 8 | "strings" 9 | ) 10 | 11 | // httpCode is a helper that returns HTTP code of the response. It returns -1 12 | // if building a new request fails. 13 | func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int { 14 | w := httptest.NewRecorder() 15 | req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) 16 | if err != nil { 17 | return -1 18 | } 19 | handler(w, req) 20 | return w.Code 21 | } 22 | 23 | // HTTPSuccess asserts that a specified handler returns a success status code. 24 | // 25 | // assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) 26 | // 27 | // Returns whether the assertion was successful (true) or not (false). 28 | func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { 29 | code := httpCode(handler, method, url, values) 30 | if code == -1 { 31 | return false 32 | } 33 | return code >= http.StatusOK && code <= http.StatusPartialContent 34 | } 35 | 36 | // HTTPRedirect asserts that a specified handler returns a redirect status code. 37 | // 38 | // assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} 39 | // 40 | // Returns whether the assertion was successful (true) or not (false). 41 | func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { 42 | code := httpCode(handler, method, url, values) 43 | if code == -1 { 44 | return false 45 | } 46 | return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect 47 | } 48 | 49 | // HTTPError asserts that a specified handler returns an error status code. 50 | // 51 | // assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} 52 | // 53 | // Returns whether the assertion was successful (true) or not (false). 54 | func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { 55 | code := httpCode(handler, method, url, values) 56 | if code == -1 { 57 | return false 58 | } 59 | return code >= http.StatusBadRequest 60 | } 61 | 62 | // HTTPBody is a helper that returns HTTP body of the response. It returns 63 | // empty string if building a new request fails. 64 | func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { 65 | w := httptest.NewRecorder() 66 | req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) 67 | if err != nil { 68 | return "" 69 | } 70 | handler(w, req) 71 | return w.Body.String() 72 | } 73 | 74 | // HTTPBodyContains asserts that a specified handler returns a 75 | // body that contains a string. 76 | // 77 | // assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") 78 | // 79 | // Returns whether the assertion was successful (true) or not (false). 80 | func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { 81 | body := HTTPBody(handler, method, url, values) 82 | 83 | contains := strings.Contains(body, fmt.Sprint(str)) 84 | if !contains { 85 | Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) 86 | } 87 | 88 | return contains 89 | } 90 | 91 | // HTTPBodyNotContains asserts that a specified handler returns a 92 | // body that does not contain a string. 93 | // 94 | // assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") 95 | // 96 | // Returns whether the assertion was successful (true) or not (false). 97 | func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { 98 | body := HTTPBody(handler, method, url, values) 99 | 100 | contains := strings.Contains(body, fmt.Sprint(str)) 101 | if contains { 102 | Fail(t, "Expected response body for %s to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body) 103 | } 104 | 105 | return !contains 106 | } 107 | 108 | // 109 | // Assertions Wrappers 110 | // 111 | 112 | // HTTPSuccess asserts that a specified handler returns a success status code. 113 | // 114 | // assert.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) 115 | // 116 | // Returns whether the assertion was successful (true) or not (false). 117 | func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method, url string, values url.Values) bool { 118 | return HTTPSuccess(a.t, handler, method, url, values) 119 | } 120 | 121 | // HTTPRedirect asserts that a specified handler returns a redirect status code. 122 | // 123 | // assert.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} 124 | // 125 | // Returns whether the assertion was successful (true) or not (false). 126 | func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method, url string, values url.Values) bool { 127 | return HTTPRedirect(a.t, handler, method, url, values) 128 | } 129 | 130 | // HTTPError asserts that a specified handler returns an error status code. 131 | // 132 | // assert.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} 133 | // 134 | // Returns whether the assertion was successful (true) or not (false). 135 | func (a *Assertions) HTTPError(handler http.HandlerFunc, method, url string, values url.Values) bool { 136 | return HTTPError(a.t, handler, method, url, values) 137 | } 138 | 139 | // HTTPBodyContains asserts that a specified handler returns a 140 | // body that contains a string. 141 | // 142 | // assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") 143 | // 144 | // Returns whether the assertion was successful (true) or not (false). 145 | func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { 146 | return HTTPBodyContains(a.t, handler, method, url, values, str) 147 | } 148 | 149 | // HTTPBodyNotContains asserts that a specified handler returns a 150 | // body that does not contain a string. 151 | // 152 | // assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") 153 | // 154 | // Returns whether the assertion was successful (true) or not (false). 155 | func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { 156 | return HTTPBodyNotContains(a.t, handler, method, url, values, str) 157 | } 158 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/map.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | import ( 4 | "encoding/base64" 5 | "encoding/json" 6 | "errors" 7 | "io/ioutil" 8 | "net/url" 9 | "strings" 10 | ) 11 | 12 | // MSIConvertable is an interface that defines methods for converting your 13 | // custom types to a map[string]interface{} representation. 14 | type MSIConvertable interface { 15 | // MSI gets a map[string]interface{} (msi) representing the 16 | // object. 17 | MSI() map[string]interface{} 18 | } 19 | 20 | // Map provides extended functionality for working with 21 | // untyped data, in particular map[string]interface (msi). 22 | type Map map[string]interface{} 23 | 24 | // Value returns the internal value instance 25 | func (m Map) Value() *Value { 26 | return &Value{data: m} 27 | } 28 | 29 | // Nil represents a nil Map. 30 | var Nil Map = New(nil) 31 | 32 | // New creates a new Map containing the map[string]interface{} in the data argument. 33 | // If the data argument is not a map[string]interface, New attempts to call the 34 | // MSI() method on the MSIConvertable interface to create one. 35 | func New(data interface{}) Map { 36 | if _, ok := data.(map[string]interface{}); !ok { 37 | if converter, ok := data.(MSIConvertable); ok { 38 | data = converter.MSI() 39 | } else { 40 | return nil 41 | } 42 | } 43 | return Map(data.(map[string]interface{})) 44 | } 45 | 46 | // MSI creates a map[string]interface{} and puts it inside a new Map. 47 | // 48 | // The arguments follow a key, value pattern. 49 | // 50 | // Panics 51 | // 52 | // Panics if any key arugment is non-string or if there are an odd number of arguments. 53 | // 54 | // Example 55 | // 56 | // To easily create Maps: 57 | // 58 | // m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true)) 59 | // 60 | // // creates an Map equivalent to 61 | // m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}}) 62 | func MSI(keyAndValuePairs ...interface{}) Map { 63 | 64 | newMap := make(map[string]interface{}) 65 | keyAndValuePairsLen := len(keyAndValuePairs) 66 | 67 | if keyAndValuePairsLen%2 != 0 { 68 | panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.") 69 | } 70 | 71 | for i := 0; i < keyAndValuePairsLen; i = i + 2 { 72 | 73 | key := keyAndValuePairs[i] 74 | value := keyAndValuePairs[i+1] 75 | 76 | // make sure the key is a string 77 | keyString, keyStringOK := key.(string) 78 | if !keyStringOK { 79 | panic("objx: MSI must follow 'string, interface{}' pattern. " + keyString + " is not a valid key.") 80 | } 81 | 82 | newMap[keyString] = value 83 | 84 | } 85 | 86 | return New(newMap) 87 | } 88 | 89 | // ****** Conversion Constructors 90 | 91 | // MustFromJSON creates a new Map containing the data specified in the 92 | // jsonString. 93 | // 94 | // Panics if the JSON is invalid. 95 | func MustFromJSON(jsonString string) Map { 96 | o, err := FromJSON(jsonString) 97 | 98 | if err != nil { 99 | panic("objx: MustFromJSON failed with error: " + err.Error()) 100 | } 101 | 102 | return o 103 | } 104 | 105 | // FromJSON creates a new Map containing the data specified in the 106 | // jsonString. 107 | // 108 | // Returns an error if the JSON is invalid. 109 | func FromJSON(jsonString string) (Map, error) { 110 | 111 | var data interface{} 112 | err := json.Unmarshal([]byte(jsonString), &data) 113 | 114 | if err != nil { 115 | return Nil, err 116 | } 117 | 118 | return New(data), nil 119 | 120 | } 121 | 122 | // FromBase64 creates a new Obj containing the data specified 123 | // in the Base64 string. 124 | // 125 | // The string is an encoded JSON string returned by Base64 126 | func FromBase64(base64String string) (Map, error) { 127 | 128 | decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String)) 129 | 130 | decoded, err := ioutil.ReadAll(decoder) 131 | if err != nil { 132 | return nil, err 133 | } 134 | 135 | return FromJSON(string(decoded)) 136 | } 137 | 138 | // MustFromBase64 creates a new Obj containing the data specified 139 | // in the Base64 string and panics if there is an error. 140 | // 141 | // The string is an encoded JSON string returned by Base64 142 | func MustFromBase64(base64String string) Map { 143 | 144 | result, err := FromBase64(base64String) 145 | 146 | if err != nil { 147 | panic("objx: MustFromBase64 failed with error: " + err.Error()) 148 | } 149 | 150 | return result 151 | } 152 | 153 | // FromSignedBase64 creates a new Obj containing the data specified 154 | // in the Base64 string. 155 | // 156 | // The string is an encoded JSON string returned by SignedBase64 157 | func FromSignedBase64(base64String, key string) (Map, error) { 158 | parts := strings.Split(base64String, SignatureSeparator) 159 | if len(parts) != 2 { 160 | return nil, errors.New("objx: Signed base64 string is malformed.") 161 | } 162 | 163 | sig := HashWithKey(parts[0], key) 164 | if parts[1] != sig { 165 | return nil, errors.New("objx: Signature for base64 data does not match.") 166 | } 167 | 168 | return FromBase64(parts[0]) 169 | } 170 | 171 | // MustFromSignedBase64 creates a new Obj containing the data specified 172 | // in the Base64 string and panics if there is an error. 173 | // 174 | // The string is an encoded JSON string returned by Base64 175 | func MustFromSignedBase64(base64String, key string) Map { 176 | 177 | result, err := FromSignedBase64(base64String, key) 178 | 179 | if err != nil { 180 | panic("objx: MustFromSignedBase64 failed with error: " + err.Error()) 181 | } 182 | 183 | return result 184 | } 185 | 186 | // FromURLQuery generates a new Obj by parsing the specified 187 | // query. 188 | // 189 | // For queries with multiple values, the first value is selected. 190 | func FromURLQuery(query string) (Map, error) { 191 | 192 | vals, err := url.ParseQuery(query) 193 | 194 | if err != nil { 195 | return nil, err 196 | } 197 | 198 | m := make(map[string]interface{}) 199 | for k, vals := range vals { 200 | m[k] = vals[0] 201 | } 202 | 203 | return New(m), nil 204 | } 205 | 206 | // MustFromURLQuery generates a new Obj by parsing the specified 207 | // query. 208 | // 209 | // For queries with multiple values, the first value is selected. 210 | // 211 | // Panics if it encounters an error 212 | func MustFromURLQuery(query string) Map { 213 | 214 | o, err := FromURLQuery(query) 215 | 216 | if err != nil { 217 | panic("objx: MustFromURLQuery failed with error: " + err.Error()) 218 | } 219 | 220 | return o 221 | 222 | } 223 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/spew.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package spew 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | ) 23 | 24 | // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were 25 | // passed with a default Formatter interface returned by NewFormatter. It 26 | // returns the formatted string as a value that satisfies error. See 27 | // NewFormatter for formatting details. 28 | // 29 | // This function is shorthand for the following syntax: 30 | // 31 | // fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 32 | func Errorf(format string, a ...interface{}) (err error) { 33 | return fmt.Errorf(format, convertArgs(a)...) 34 | } 35 | 36 | // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were 37 | // passed with a default Formatter interface returned by NewFormatter. It 38 | // returns the number of bytes written and any write error encountered. See 39 | // NewFormatter for formatting details. 40 | // 41 | // This function is shorthand for the following syntax: 42 | // 43 | // fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) 44 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) { 45 | return fmt.Fprint(w, convertArgs(a)...) 46 | } 47 | 48 | // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were 49 | // passed with a default Formatter interface returned by NewFormatter. It 50 | // returns the number of bytes written and any write error encountered. See 51 | // NewFormatter for formatting details. 52 | // 53 | // This function is shorthand for the following syntax: 54 | // 55 | // fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) 56 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { 57 | return fmt.Fprintf(w, format, convertArgs(a)...) 58 | } 59 | 60 | // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it 61 | // passed with a default Formatter interface returned by NewFormatter. See 62 | // NewFormatter for formatting details. 63 | // 64 | // This function is shorthand for the following syntax: 65 | // 66 | // fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) 67 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { 68 | return fmt.Fprintln(w, convertArgs(a)...) 69 | } 70 | 71 | // Print is a wrapper for fmt.Print that treats each argument as if it were 72 | // passed with a default Formatter interface returned by NewFormatter. It 73 | // returns the number of bytes written and any write error encountered. See 74 | // NewFormatter for formatting details. 75 | // 76 | // This function is shorthand for the following syntax: 77 | // 78 | // fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) 79 | func Print(a ...interface{}) (n int, err error) { 80 | return fmt.Print(convertArgs(a)...) 81 | } 82 | 83 | // Printf is a wrapper for fmt.Printf that treats each argument as if it were 84 | // passed with a default Formatter interface returned by NewFormatter. It 85 | // returns the number of bytes written and any write error encountered. See 86 | // NewFormatter for formatting details. 87 | // 88 | // This function is shorthand for the following syntax: 89 | // 90 | // fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 91 | func Printf(format string, a ...interface{}) (n int, err error) { 92 | return fmt.Printf(format, convertArgs(a)...) 93 | } 94 | 95 | // Println is a wrapper for fmt.Println that treats each argument as if it were 96 | // passed with a default Formatter interface returned by NewFormatter. It 97 | // returns the number of bytes written and any write error encountered. See 98 | // NewFormatter for formatting details. 99 | // 100 | // This function is shorthand for the following syntax: 101 | // 102 | // fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) 103 | func Println(a ...interface{}) (n int, err error) { 104 | return fmt.Println(convertArgs(a)...) 105 | } 106 | 107 | // Sprint is a wrapper for fmt.Sprint that treats each argument as if it were 108 | // passed with a default Formatter interface returned by NewFormatter. It 109 | // returns the resulting string. See NewFormatter for formatting details. 110 | // 111 | // This function is shorthand for the following syntax: 112 | // 113 | // fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) 114 | func Sprint(a ...interface{}) string { 115 | return fmt.Sprint(convertArgs(a)...) 116 | } 117 | 118 | // Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were 119 | // passed with a default Formatter interface returned by NewFormatter. It 120 | // returns the resulting string. See NewFormatter for formatting details. 121 | // 122 | // This function is shorthand for the following syntax: 123 | // 124 | // fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 125 | func Sprintf(format string, a ...interface{}) string { 126 | return fmt.Sprintf(format, convertArgs(a)...) 127 | } 128 | 129 | // Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it 130 | // were passed with a default Formatter interface returned by NewFormatter. It 131 | // returns the resulting string. See NewFormatter for formatting details. 132 | // 133 | // This function is shorthand for the following syntax: 134 | // 135 | // fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) 136 | func Sprintln(a ...interface{}) string { 137 | return fmt.Sprintln(convertArgs(a)...) 138 | } 139 | 140 | // convertArgs accepts a slice of arguments and returns a slice of the same 141 | // length with each argument converted to a default spew Formatter interface. 142 | func convertArgs(args []interface{}) (formatters []interface{}) { 143 | formatters = make([]interface{}, len(args)) 144 | for index, arg := range args { 145 | formatters[index] = NewFormatter(arg) 146 | } 147 | return formatters 148 | } 149 | -------------------------------------------------------------------------------- /unmarshalmap/generator.go: -------------------------------------------------------------------------------- 1 | package unmarshalmap 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "go/types" 7 | "io" 8 | "path/filepath" 9 | "text/template" 10 | 11 | "github.com/ernesto-jimenez/gogen/cleanimports" 12 | "github.com/ernesto-jimenez/gogen/gogenutil" 13 | "github.com/ernesto-jimenez/gogen/importer" 14 | "github.com/ernesto-jimenez/gogen/imports" 15 | ) 16 | 17 | // Generator will generate the UnmarshalMap function 18 | type Generator struct { 19 | name string 20 | targetName string 21 | namePkg string 22 | pkg *types.Package 23 | target *types.Struct 24 | } 25 | 26 | // NewGenerator initializes a Generator 27 | func NewGenerator(pkg, target string) (*Generator, error) { 28 | var err error 29 | if pkg == "" || pkg[0] == '.' { 30 | pkg, err = filepath.Abs(filepath.Clean(pkg)) 31 | if err != nil { 32 | return nil, err 33 | } 34 | pkg = gogenutil.StripGopath(pkg) 35 | } 36 | p, err := importer.Default().Import(pkg) 37 | if err != nil { 38 | return nil, err 39 | } 40 | obj := p.Scope().Lookup(target) 41 | if obj == nil { 42 | return nil, fmt.Errorf("struct %s missing", target) 43 | } 44 | if _, ok := obj.Type().Underlying().(*types.Struct); !ok { 45 | return nil, fmt.Errorf("%s should be an struct, was %s", target, obj.Type().Underlying()) 46 | } 47 | return &Generator{ 48 | targetName: target, 49 | pkg: p, 50 | target: obj.Type().Underlying().(*types.Struct), 51 | }, nil 52 | } 53 | 54 | func (g Generator) Fields() []Field { 55 | numFields := g.target.NumFields() 56 | fields := make([]Field, 0) 57 | for i := 0; i < numFields; i++ { 58 | f := Field{&g, g.target.Tag(i), g.target.Field(i)} 59 | if f.Field() != "" { 60 | fields = append(fields, f) 61 | } 62 | } 63 | return fields 64 | } 65 | 66 | func (g Generator) qf(pkg *types.Package) string { 67 | if g.pkg == pkg { 68 | return "" 69 | } 70 | return pkg.Name() 71 | } 72 | 73 | func (g Generator) Name() string { 74 | name := g.targetName 75 | return name 76 | } 77 | 78 | func (g Generator) Package() string { 79 | if g.namePkg != "" { 80 | return g.namePkg 81 | } 82 | return g.pkg.Name() 83 | } 84 | 85 | func (g *Generator) SetPackage(name string) { 86 | g.namePkg = name 87 | } 88 | 89 | func (g Generator) Imports() map[string]string { 90 | imports := imports.New(g.Package()) 91 | fields := g.Fields() 92 | for i := 0; i < len(fields); i++ { 93 | m := fields[i] 94 | imports.AddImportsFrom(m.v.Type()) 95 | imports.AddImportsFrom(m.UnderlyingType()) 96 | if sub := m.UnderlyingTarget(); sub != nil { 97 | fields = append(fields, sub.Fields()...) 98 | } 99 | } 100 | return imports.Imports() 101 | } 102 | 103 | func (g Generator) Write(wr io.Writer) error { 104 | var buf bytes.Buffer 105 | if err := fnTmpl.Execute(&buf, g); err != nil { 106 | return err 107 | } 108 | return cleanimports.Clean(wr, buf.Bytes()) 109 | } 110 | 111 | func (g Generator) WriteTest(wr io.Writer) error { 112 | var buf bytes.Buffer 113 | if err := testTmpl.Execute(&buf, g); err != nil { 114 | return err 115 | } 116 | return cleanimports.Clean(wr, buf.Bytes()) 117 | } 118 | 119 | var ( 120 | testTmpl = template.Must(template.New("test").Parse(`/* 121 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 122 | * THIS FILE SHOULD NOT BE EDITED BY HAND 123 | */ 124 | 125 | package {{.Package}} 126 | 127 | import ( 128 | "testing" 129 | test "github.com/ernesto-jimenez/gogen/unmarshalmap/testunmarshalmap" 130 | ) 131 | 132 | func Test{{.Name}}UnmarshalMap(t *testing.T) { 133 | test.Run(t, &{{.Name}}{}) 134 | } 135 | `)) 136 | fnTmpl = template.Must(template.New("func").Parse(`/* 137 | * CODE GENERATED AUTOMATICALLY WITH github.com/ernesto-jimenez/gogen/unmarshalmap 138 | * THIS FILE SHOULD NOT BE EDITED BY HAND 139 | */ 140 | 141 | package {{.Package}} 142 | 143 | import ( 144 | "fmt" 145 | {{range $path, $name := .Imports}} 146 | {{$name}} "{{$path}}"{{end}} 147 | ) 148 | 149 | {{define "UNMARSHALFIELDS"}} 150 | {{range .Fields}} 151 | {{if .IsAnonymous}} 152 | // Anonymous {{.Name}} 153 | if scoped := true; scoped { 154 | var s *{{.Type}} = &s.{{.Name}} 155 | // Fill object 156 | {{template "UNMARSHALFIELDS" .UnderlyingTarget}} 157 | } 158 | {{else if .IsArrayOrSlice}} 159 | // ArrayOrSlice {{.Name}} 160 | {{if .UnderlyingIsBasic}} 161 | if v, ok := m["{{.Field}}"].([]{{.UnderlyingType}}); ok { 162 | {{if .IsSlice}} 163 | s.{{.Name}} = make({{.Type}}, len(v)) 164 | {{else}} 165 | if len(s.{{.Name}}) < len(v) { 166 | return fmt.Errorf("expected field {{.Field}} to be an array with %d elements, but got an array with %d", len(s.{{.Name}}), len(v)) 167 | } 168 | {{end}} 169 | for i, el := range v { 170 | s.{{.Name}}[i] = el 171 | } 172 | } else if v, ok := m["{{.Field}}"].([]interface{}); ok { 173 | {{if .IsSlice}} 174 | s.{{.Name}} = make({{.Type}}, len(v)) 175 | {{else}} 176 | if len(s.{{.Name}}) < len(v) { 177 | return fmt.Errorf("expected field {{.Field}} to be an array with %d elements, but got an array with %d", len(s.{{.Name}}), len(v)) 178 | } 179 | {{end}} 180 | for i, el := range v { 181 | if v, ok := el.({{.UnderlyingType}}); ok { 182 | s.{{.Name}}[i] = v 183 | {{if .UnderlyingConvertibleFromFloat64}} 184 | } else if m, ok := el.(float64); ok { 185 | v := {{.UnderlyingType}}(m) 186 | s.{{.Name}} = v 187 | {{end}} 188 | } else { 189 | return fmt.Errorf("expected field {{.Field}}[%d] to be {{.UnderlyingType}} but got %T", i, el) 190 | } 191 | } 192 | } else if v, exists := m["{{.Field}}"]; exists && v != nil { 193 | return fmt.Errorf("expected field {{.Field}} to be []{{.UnderlyingType}} but got %T", m["{{.Field}}"]) 194 | } 195 | {{else}} 196 | if v, ok := m["{{.Field}}"].([]interface{}); ok { 197 | {{if .IsSlice}} 198 | s.{{.Name}} = make({{.Type}}, len(v)) 199 | {{else}} 200 | if len(s.{{.Name}}) < len(v) { 201 | return fmt.Errorf("expected field {{.Field}} to be an array with %d elements, but got an array with %d", len(s.{{.Name}}), len(v)) 202 | } 203 | {{end}} 204 | prev := s 205 | for i, el := range v { 206 | var s *{{.UnderlyingTypeName}} 207 | {{if .UnderlyingIsPointer}} 208 | if el == nil { 209 | continue 210 | } 211 | prev.{{.Name}}[i] = &{{.UnderlyingTypeName}}{} 212 | s = prev.{{.Name}}[i] 213 | {{else}} 214 | s = &prev.{{.Name}}[i] 215 | {{end}} 216 | if m, ok := el.(map[string]interface{}); ok { 217 | // Fill object 218 | {{template "UNMARSHALFIELDS" .UnderlyingTarget}} 219 | } 220 | } 221 | } else if v, exists := m["{{.Field}}"]; exists && v != nil { 222 | return fmt.Errorf("expected field {{.Field}} to be []interface{} but got %T", m["{{.Field}}"]) 223 | } 224 | {{end}} 225 | {{else if .IsPointer}} 226 | // Pointer {{.Name}} 227 | if p, ok := m["{{.Field}}"]; ok { 228 | {{if .UnderlyingIsBasic}} 229 | if m, ok := p.({{.UnderlyingType}}); ok { 230 | s.{{.Name}} = &m 231 | {{if .UnderlyingConvertibleFromFloat64}} 232 | } else if m, ok := p.(float64); ok { 233 | v := {{.UnderlyingType}}(m) 234 | s.{{.Name}} = &v 235 | {{end}} 236 | } else if p == nil { 237 | s.{{.Name}} = nil 238 | } 239 | {{else}} 240 | if m, ok := p.(map[string]interface{}); ok { 241 | if s.{{.Name}} == nil { 242 | s.{{.Name}} = &{{.UnderlyingTypeName}}{} 243 | } 244 | s := s.{{.Name}} 245 | {{template "UNMARSHALFIELDS" .UnderlyingTarget}} 246 | } else if p == nil { 247 | s.{{.Name}} = nil 248 | } else { 249 | return fmt.Errorf("expected field {{.Field}} to be map[string]interface{} but got %T", p) 250 | } 251 | {{end}} 252 | } 253 | {{else if .IsStruct}} 254 | // Struct {{.Name}} 255 | if m, ok := m["{{.Field}}"].(map[string]interface{}); ok { 256 | var s *{{.Type}} = &s.{{.Name}} 257 | // Fill object 258 | {{template "UNMARSHALFIELDS" .UnderlyingTarget}} 259 | } else if v, exists := m["{{.Field}}"]; exists && v != nil { 260 | return fmt.Errorf("expected field {{.Field}} to be map[string]interface{} but got %T", m["{{.Field}}"]) 261 | } 262 | {{else}} 263 | if v, ok := m["{{.Field}}"].({{.Type}}); ok { 264 | s.{{.Name}} = v 265 | {{if .ConvertibleFromFloat64}} 266 | } else if p, ok := m["{{.Field}}"].(float64); ok { 267 | v := {{.Type}}(p) 268 | s.{{.Name}} = v 269 | {{end}} 270 | } else if v, exists := m["{{.Field}}"]; exists && v != nil { 271 | return fmt.Errorf("expected field {{.Field}} to be {{.Type}} but got %T", m["{{.Field}}"]) 272 | } 273 | {{end}} 274 | {{end}} 275 | {{end}} 276 | 277 | // UnmarshalMap takes a map and unmarshals the fieds into the struct 278 | func (s *{{.Name}}) UnmarshalMap(m map[string]interface{}) error { 279 | {{template "UNMARSHALFIELDS" .}} 280 | return nil 281 | } 282 | `)) 283 | ) 284 | -------------------------------------------------------------------------------- /exportdefault/generator.go: -------------------------------------------------------------------------------- 1 | // Package exportdefault provides the functionality to automatically generate 2 | // package-level exported functions wrapping calls to a package-level default 3 | // instance of a type. 4 | // 5 | // This helps auto-generating code for the common use case where a package 6 | // implements certain information as methods within a stub and, for 7 | // convenience, exports functions that wrap calls to those methods on a default 8 | // variable. 9 | // 10 | // Some examples of that behaviour in the stdlib: 11 | // 12 | // - `net/http` has `http.DefaultClient` and functions like `http.Get` just 13 | // call the default `http.DefaultClient.Get` 14 | // - `log` has `log.Logger` and functions like `log.Print` just call the 15 | // default `log.std.Print` 16 | package exportdefault 17 | 18 | import ( 19 | "bytes" 20 | "fmt" 21 | "go/ast" 22 | "go/build" 23 | "go/doc" 24 | "go/importer" 25 | "go/parser" 26 | "go/token" 27 | "go/types" 28 | "io" 29 | "io/ioutil" 30 | "path" 31 | "regexp" 32 | "text/template" 33 | 34 | "github.com/ernesto-jimenez/gogen/cleanimports" 35 | "github.com/ernesto-jimenez/gogen/imports" 36 | ) 37 | 38 | // Generator contains the metadata needed to generate all the function wrappers 39 | // arround methods from a package variable 40 | type Generator struct { 41 | Name string 42 | Imports map[string]string 43 | funcs []fn 44 | FuncNamePrefix string 45 | Include *regexp.Regexp 46 | Exclude *regexp.Regexp 47 | } 48 | 49 | // New initialises a new Generator for the corresponding package's variable 50 | // 51 | // Returns an error if the package or variable are invalid 52 | func New(pkg string, variable string) (*Generator, error) { 53 | scope, docs, err := parsePackageSource(pkg) 54 | if err != nil { 55 | return nil, err 56 | } 57 | 58 | importer, funcs, err := analyzeCode(scope, docs, variable) 59 | if err != nil { 60 | return nil, err 61 | } 62 | 63 | return &Generator{ 64 | Name: docs.Name, 65 | Imports: importer.Imports(), 66 | funcs: funcs, 67 | }, nil 68 | } 69 | 70 | // Write the generated code into the given io.Writer 71 | // 72 | // Returns an error if there is a problem generating the code 73 | func (g *Generator) Write(w io.Writer) error { 74 | buff := bytes.NewBuffer(nil) 75 | 76 | // Generate header 77 | if err := headerTpl.Execute(buff, g); err != nil { 78 | return err 79 | } 80 | 81 | // Generate funcs 82 | for _, fn := range g.funcs { 83 | if g.Include != nil && !g.Include.MatchString(fn.Name) { 84 | continue 85 | } 86 | if g.Exclude != nil && g.Exclude.MatchString(fn.Name) { 87 | continue 88 | } 89 | fn.FuncNamePrefix = g.FuncNamePrefix 90 | buff.Write([]byte("\n\n")) 91 | if err := funcTpl.Execute(buff, &fn); err != nil { 92 | return err 93 | } 94 | } 95 | 96 | return cleanimports.Clean(w, buff.Bytes()) 97 | } 98 | 99 | type fn struct { 100 | FuncNamePrefix string 101 | WrappedVar string 102 | Name string 103 | CurrentPkg string 104 | TypeInfo *types.Func 105 | } 106 | 107 | func (f *fn) Qualifier(p *types.Package) string { 108 | if p == nil || p.Name() == f.CurrentPkg { 109 | return "" 110 | } 111 | return p.Name() 112 | } 113 | 114 | func (f *fn) Params() string { 115 | sig := f.TypeInfo.Type().(*types.Signature) 116 | params := sig.Params() 117 | p := "" 118 | comma := "" 119 | to := params.Len() 120 | var i int 121 | 122 | if sig.Variadic() { 123 | to-- 124 | } 125 | for i = 0; i < to; i++ { 126 | param := params.At(i) 127 | name := param.Name() 128 | if name == "" { 129 | name = fmt.Sprintf("p%d", i) 130 | } 131 | p += fmt.Sprintf("%s%s %s", comma, name, types.TypeString(param.Type(), f.Qualifier)) 132 | comma = ", " 133 | } 134 | if sig.Variadic() { 135 | param := params.At(params.Len() - 1) 136 | name := param.Name() 137 | if name == "" { 138 | name = fmt.Sprintf("p%d", to) 139 | } 140 | p += fmt.Sprintf("%s%s ...%s", comma, name, types.TypeString(param.Type().(*types.Slice).Elem(), f.Qualifier)) 141 | } 142 | return p 143 | } 144 | 145 | func (f *fn) ReturnsAnything() bool { 146 | sig := f.TypeInfo.Type().(*types.Signature) 147 | params := sig.Results() 148 | return params.Len() > 0 149 | } 150 | 151 | func (f *fn) ReturnTypes() string { 152 | sig := f.TypeInfo.Type().(*types.Signature) 153 | params := sig.Results() 154 | p := "" 155 | comma := "" 156 | to := params.Len() 157 | var i int 158 | 159 | for i = 0; i < to; i++ { 160 | param := params.At(i) 161 | p += fmt.Sprintf("%s %s", comma, types.TypeString(param.Type(), f.Qualifier)) 162 | comma = ", " 163 | } 164 | if to > 1 { 165 | p = fmt.Sprintf("(%s)", p) 166 | } 167 | return p 168 | } 169 | 170 | func (f *fn) ForwardedParams() string { 171 | sig := f.TypeInfo.Type().(*types.Signature) 172 | params := sig.Params() 173 | p := "" 174 | comma := "" 175 | to := params.Len() 176 | var i int 177 | 178 | if sig.Variadic() { 179 | to-- 180 | } 181 | for i = 0; i < to; i++ { 182 | param := params.At(i) 183 | name := param.Name() 184 | if name == "" { 185 | name = fmt.Sprintf("p%d", i) 186 | } 187 | p += fmt.Sprintf("%s%s", comma, name) 188 | comma = ", " 189 | } 190 | if sig.Variadic() { 191 | param := params.At(params.Len() - 1) 192 | name := param.Name() 193 | if name == "" { 194 | name = fmt.Sprintf("p%d", to) 195 | } 196 | p += fmt.Sprintf("%s%s...", comma, name) 197 | } 198 | return p 199 | } 200 | 201 | // parsePackageSource returns the types scope and the package documentation from the specified package 202 | func parsePackageSource(pkg string) (*types.Scope, *doc.Package, error) { 203 | pd, err := build.Import(pkg, ".", 0) 204 | if err != nil { 205 | return nil, nil, err 206 | } 207 | 208 | fset := token.NewFileSet() 209 | files := make(map[string]*ast.File) 210 | fileList := make([]*ast.File, len(pd.GoFiles)) 211 | for i, fname := range pd.GoFiles { 212 | src, err := ioutil.ReadFile(path.Join(pd.SrcRoot, pd.ImportPath, fname)) 213 | if err != nil { 214 | return nil, nil, err 215 | } 216 | f, err := parser.ParseFile(fset, fname, src, parser.ParseComments|parser.AllErrors) 217 | if err != nil { 218 | return nil, nil, err 219 | } 220 | files[fname] = f 221 | fileList[i] = f 222 | } 223 | 224 | cfg := types.Config{ 225 | Importer: importer.Default(), 226 | } 227 | info := types.Info{ 228 | Defs: make(map[*ast.Ident]types.Object), 229 | } 230 | tp, err := cfg.Check(pkg, fset, fileList, &info) 231 | if err != nil { 232 | return nil, nil, err 233 | } 234 | 235 | scope := tp.Scope() 236 | 237 | ap, _ := ast.NewPackage(fset, files, nil, nil) 238 | docs := doc.New(ap, pkg, doc.AllDecls|doc.AllMethods) 239 | 240 | return scope, docs, nil 241 | } 242 | 243 | func analyzeCode(scope *types.Scope, docs *doc.Package, variable string) (imports.Importer, []fn, error) { 244 | pkg := docs.Name 245 | v, ok := scope.Lookup(variable).(*types.Var) 246 | if v == nil { 247 | return nil, nil, fmt.Errorf("impossible to find variable %s", variable) 248 | } 249 | if !ok { 250 | return nil, nil, fmt.Errorf("%s must be a variable", variable) 251 | } 252 | var vType interface { 253 | NumMethods() int 254 | Method(int) *types.Func 255 | } 256 | switch t := v.Type().(type) { 257 | case *types.Interface: 258 | vType = t 259 | case *types.Pointer: 260 | vType = t.Elem().(*types.Named) 261 | case *types.Named: 262 | vType = t 263 | if t, ok := t.Underlying().(*types.Interface); ok { 264 | vType = t 265 | } 266 | default: 267 | return nil, nil, fmt.Errorf("variable is of an invalid type: %T", v.Type().Underlying()) 268 | } 269 | 270 | importer := imports.New(pkg) 271 | var funcs []fn 272 | for i := 0; i < vType.NumMethods(); i++ { 273 | f := vType.Method(i) 274 | 275 | if !f.Exported() { 276 | continue 277 | } 278 | 279 | sig := f.Type().(*types.Signature) 280 | 281 | funcs = append(funcs, fn{ 282 | WrappedVar: variable, 283 | Name: f.Name(), 284 | CurrentPkg: pkg, 285 | TypeInfo: f, 286 | }) 287 | importer.AddImportsFrom(sig.Params()) 288 | importer.AddImportsFrom(sig.Results()) 289 | } 290 | return importer, funcs, nil 291 | } 292 | 293 | var headerTpl = template.Must(template.New("header").Parse(`/* 294 | * CODE GENERATED AUTOMATICALLY WITH goexportdefault 295 | * THIS FILE MUST NOT BE EDITED BY HAND 296 | * 297 | * Install goexportdefault with: 298 | * go get github.com/ernesto-jimenez/gogen/cmd/goexportdefault 299 | */ 300 | 301 | package {{.Name}} 302 | 303 | import ( 304 | {{range $path, $name := .Imports}} 305 | {{$name}} "{{$path}}"{{end}} 306 | ) 307 | `)) 308 | 309 | var funcTpl = template.Must(template.New("func").Parse(`// {{.FuncNamePrefix}}{{.Name}} is a wrapper around {{.WrappedVar}}.{{.Name}} 310 | func {{.FuncNamePrefix}}{{.Name}}({{.Params}}) {{.ReturnTypes}} { 311 | {{if .ReturnsAnything}}return {{end}}{{.WrappedVar}}.{{.Name}}({{.ForwardedParams}}) 312 | }`)) 313 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /* 18 | Package spew implements a deep pretty printer for Go data structures to aid in 19 | debugging. 20 | 21 | A quick overview of the additional features spew provides over the built-in 22 | printing facilities for Go data types are as follows: 23 | 24 | * Pointers are dereferenced and followed 25 | * Circular data structures are detected and handled properly 26 | * Custom Stringer/error interfaces are optionally invoked, including 27 | on unexported types 28 | * Custom types which only implement the Stringer/error interfaces via 29 | a pointer receiver are optionally invoked when passing non-pointer 30 | variables 31 | * Byte arrays and slices are dumped like the hexdump -C command which 32 | includes offsets, byte values in hex, and ASCII output (only when using 33 | Dump style) 34 | 35 | There are two different approaches spew allows for dumping Go data structures: 36 | 37 | * Dump style which prints with newlines, customizable indentation, 38 | and additional debug information such as types and all pointer addresses 39 | used to indirect to the final value 40 | * A custom Formatter interface that integrates cleanly with the standard fmt 41 | package and replaces %v, %+v, %#v, and %#+v to provide inline printing 42 | similar to the default %v while providing the additional functionality 43 | outlined above and passing unsupported format verbs such as %x and %q 44 | along to fmt 45 | 46 | Quick Start 47 | 48 | This section demonstrates how to quickly get started with spew. See the 49 | sections below for further details on formatting and configuration options. 50 | 51 | To dump a variable with full newlines, indentation, type, and pointer 52 | information use Dump, Fdump, or Sdump: 53 | spew.Dump(myVar1, myVar2, ...) 54 | spew.Fdump(someWriter, myVar1, myVar2, ...) 55 | str := spew.Sdump(myVar1, myVar2, ...) 56 | 57 | Alternatively, if you would prefer to use format strings with a compacted inline 58 | printing style, use the convenience wrappers Printf, Fprintf, etc with 59 | %v (most compact), %+v (adds pointer addresses), %#v (adds types), or 60 | %#+v (adds types and pointer addresses): 61 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) 62 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 63 | spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) 64 | spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 65 | 66 | Configuration Options 67 | 68 | Configuration of spew is handled by fields in the ConfigState type. For 69 | convenience, all of the top-level functions use a global state available 70 | via the spew.Config global. 71 | 72 | It is also possible to create a ConfigState instance that provides methods 73 | equivalent to the top-level functions. This allows concurrent configuration 74 | options. See the ConfigState documentation for more details. 75 | 76 | The following configuration options are available: 77 | * Indent 78 | String to use for each indentation level for Dump functions. 79 | It is a single space by default. A popular alternative is "\t". 80 | 81 | * MaxDepth 82 | Maximum number of levels to descend into nested data structures. 83 | There is no limit by default. 84 | 85 | * DisableMethods 86 | Disables invocation of error and Stringer interface methods. 87 | Method invocation is enabled by default. 88 | 89 | * DisablePointerMethods 90 | Disables invocation of error and Stringer interface methods on types 91 | which only accept pointer receivers from non-pointer variables. 92 | Pointer method invocation is enabled by default. 93 | 94 | * ContinueOnMethod 95 | Enables recursion into types after invoking error and Stringer interface 96 | methods. Recursion after method invocation is disabled by default. 97 | 98 | * SortKeys 99 | Specifies map keys should be sorted before being printed. Use 100 | this to have a more deterministic, diffable output. Note that 101 | only native types (bool, int, uint, floats, uintptr and string) 102 | and types which implement error or Stringer interfaces are 103 | supported with other types sorted according to the 104 | reflect.Value.String() output which guarantees display 105 | stability. Natural map order is used by default. 106 | 107 | * SpewKeys 108 | Specifies that, as a last resort attempt, map keys should be 109 | spewed to strings and sorted by those strings. This is only 110 | considered if SortKeys is true. 111 | 112 | Dump Usage 113 | 114 | Simply call spew.Dump with a list of variables you want to dump: 115 | 116 | spew.Dump(myVar1, myVar2, ...) 117 | 118 | You may also call spew.Fdump if you would prefer to output to an arbitrary 119 | io.Writer. For example, to dump to standard error: 120 | 121 | spew.Fdump(os.Stderr, myVar1, myVar2, ...) 122 | 123 | A third option is to call spew.Sdump to get the formatted output as a string: 124 | 125 | str := spew.Sdump(myVar1, myVar2, ...) 126 | 127 | Sample Dump Output 128 | 129 | See the Dump example for details on the setup of the types and variables being 130 | shown here. 131 | 132 | (main.Foo) { 133 | unexportedField: (*main.Bar)(0xf84002e210)({ 134 | flag: (main.Flag) flagTwo, 135 | data: (uintptr) 136 | }), 137 | ExportedField: (map[interface {}]interface {}) (len=1) { 138 | (string) (len=3) "one": (bool) true 139 | } 140 | } 141 | 142 | Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C 143 | command as shown. 144 | ([]uint8) (len=32 cap=32) { 145 | 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | 146 | 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| 147 | 00000020 31 32 |12| 148 | } 149 | 150 | Custom Formatter 151 | 152 | Spew provides a custom formatter that implements the fmt.Formatter interface 153 | so that it integrates cleanly with standard fmt package printing functions. The 154 | formatter is useful for inline printing of smaller data types similar to the 155 | standard %v format specifier. 156 | 157 | The custom formatter only responds to the %v (most compact), %+v (adds pointer 158 | addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb 159 | combinations. Any other verbs such as %x and %q will be sent to the the 160 | standard fmt package for formatting. In addition, the custom formatter ignores 161 | the width and precision arguments (however they will still work on the format 162 | specifiers not handled by the custom formatter). 163 | 164 | Custom Formatter Usage 165 | 166 | The simplest way to make use of the spew custom formatter is to call one of the 167 | convenience functions such as spew.Printf, spew.Println, or spew.Printf. The 168 | functions have syntax you are most likely already familiar with: 169 | 170 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) 171 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 172 | spew.Println(myVar, myVar2) 173 | spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) 174 | spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 175 | 176 | See the Index for the full list convenience functions. 177 | 178 | Sample Formatter Output 179 | 180 | Double pointer to a uint8: 181 | %v: <**>5 182 | %+v: <**>(0xf8400420d0->0xf8400420c8)5 183 | %#v: (**uint8)5 184 | %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 185 | 186 | Pointer to circular struct with a uint8 field and a pointer to itself: 187 | %v: <*>{1 <*>} 188 | %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} 189 | %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} 190 | %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} 191 | 192 | See the Printf example for details on the setup of variables being shown 193 | here. 194 | 195 | Errors 196 | 197 | Since it is possible for custom Stringer/error interfaces to panic, spew 198 | detects them and handles them internally by printing the panic information 199 | inline with the output. Since spew is intended to provide deep pretty printing 200 | capabilities on structures, it intentionally does not return any errors. 201 | */ 202 | package spew 203 | -------------------------------------------------------------------------------- /unmarshalmap/generator_test.go: -------------------------------------------------------------------------------- 1 | package unmarshalmap 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "encoding/json" 7 | "fmt" 8 | "io" 9 | "testing" 10 | 11 | "github.com/ernesto-jimenez/gogen/unmarshalmap/testpkg" 12 | "github.com/mitchellh/mapstructure" 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | func TestNewGenerator(t *testing.T) { 17 | _, err := NewGenerator("github.com/ernesto-jimenez/gogen/unmarshalmap/testpkg", "SimpleStruct") 18 | assert.NoError(t, err) 19 | } 20 | 21 | func TestNewGeneratorErrors(t *testing.T) { 22 | _, err := NewGenerator("someNonsense", "Writer") 23 | assert.Error(t, err) 24 | 25 | _, err = NewGenerator("io", "SomeWriter") 26 | assert.Error(t, err) 27 | } 28 | 29 | func TestFields(t *testing.T) { 30 | g, err := NewGenerator("./testpkg", "SimpleStruct") 31 | assert.NoError(t, err) 32 | assert.Len(t, g.Fields(), 7) 33 | } 34 | 35 | func TestImports(t *testing.T) { 36 | //g, err := NewGenerator("", "SimpleStruct") 37 | //assert.NoError(t, err) 38 | //assert.Equal(t, map[string]string{}, g.Imports()) 39 | 40 | //g, err = NewGenerator("", "SimpleStruct") 41 | //assert.NoError(t, err) 42 | //assert.Equal(t, map[string]string{ 43 | //"net/http": "http", 44 | //"net/url": "url", 45 | //}, g.Imports()) 46 | } 47 | 48 | func TestWritesProperly(t *testing.T) { 49 | tests := []struct { 50 | pkg string 51 | iface string 52 | }{ 53 | {"./testpkg", "SimpleStruct"}, 54 | } 55 | for _, test := range tests { 56 | var out bytes.Buffer 57 | g, err := NewGenerator(test.pkg, test.iface) 58 | if err != nil { 59 | t.Error(err) 60 | continue 61 | } 62 | err = g.Write(&out) 63 | if !assert.NoError(t, err) { 64 | fmt.Println(test) 65 | fmt.Println(err) 66 | printWithLines(bytes.NewBuffer(out.Bytes())) 67 | } 68 | } 69 | } 70 | 71 | func printWithLines(txt io.Reader) { 72 | line := 0 73 | scanner := bufio.NewScanner(txt) 74 | for scanner.Scan() { 75 | line++ 76 | fmt.Printf("%-4d| %s\n", line, scanner.Text()) 77 | } 78 | } 79 | 80 | func TestSimpleStruct(t *testing.T) { 81 | var s testpkg.SimpleStruct 82 | expected := testpkg.SimpleStruct{ 83 | SimpleField: "hello", 84 | SimpleJSONTagged: "second field", 85 | SimpleJSONTaggedOmitted: "third field", 86 | SimpleOmitEmptyNoName: "noname", 87 | } 88 | m := map[string]interface{}{ 89 | "SimpleField": "hello", 90 | "field2": "second field", 91 | "field3": "third field", 92 | "SimpleSkipped": "skipped", 93 | "Ignored": "ignore", 94 | "-": "ignore", 95 | "SimpleOmitEmptyNoName": "noname", 96 | } 97 | 98 | err := s.UnmarshalMap(m) 99 | assert.NoError(t, err) 100 | assert.Equal(t, expected, s) 101 | 102 | equalJSONs(t, expected, m) 103 | } 104 | 105 | func equalJSONs(t assert.TestingT, exp, act interface{}) bool { 106 | e, err := json.Marshal(exp) 107 | if assert.NoError(t, err) { 108 | return false 109 | } 110 | a, err := json.Marshal(act) 111 | if assert.NoError(t, err) { 112 | return false 113 | } 114 | return assert.JSONEq(t, string(e), string(a)) 115 | } 116 | 117 | func TestArrayStruct(t *testing.T) { 118 | var s testpkg.Array 119 | expected := testpkg.Array{ 120 | List: []string{"1", "2", "3"}, 121 | } 122 | m := map[string]interface{}{ 123 | "List": []string{"1", "2", "3"}, 124 | } 125 | 126 | err := s.UnmarshalMap(m) 127 | assert.NoError(t, err) 128 | assert.Equal(t, expected, s) 129 | equalJSONs(t, expected, m) 130 | 131 | s = testpkg.Array{} 132 | m = map[string]interface{}{} 133 | data, err := json.Marshal(expected) 134 | assert.NoError(t, err) 135 | json.Unmarshal(data, &m) 136 | 137 | err = s.UnmarshalMap(m) 138 | assert.NoError(t, err) 139 | assert.Equal(t, expected, s) 140 | equalJSONs(t, expected, m) 141 | 142 | s = testpkg.Array{} 143 | expected = testpkg.Array{} 144 | m = map[string]interface{}{} 145 | data, err = json.Marshal(expected) 146 | assert.NoError(t, err) 147 | json.Unmarshal(data, &m) 148 | 149 | err = s.UnmarshalMap(m) 150 | assert.NoError(t, err) 151 | assert.Equal(t, expected, s) 152 | equalJSONs(t, expected, m) 153 | } 154 | 155 | func TestFailWithInvalidType(t *testing.T) { 156 | tests := []struct { 157 | s unmarshalmapper 158 | m map[string]interface{} 159 | }{ 160 | { 161 | &testpkg.Array{}, 162 | map[string]interface{}{ 163 | "List": []int{1, 2, 3}, 164 | }, 165 | }, 166 | { 167 | &testpkg.SimpleStruct{}, 168 | map[string]interface{}{ 169 | "SimpleField": 12, 170 | }, 171 | }, 172 | } 173 | 174 | for _, test := range tests { 175 | err := test.s.UnmarshalMap(test.m) 176 | assert.Error(t, err) 177 | } 178 | } 179 | 180 | type unmarshalmapper interface { 181 | UnmarshalMap(map[string]interface{}) error 182 | } 183 | 184 | func TestNestedStruct(t *testing.T) { 185 | var s testpkg.Nested 186 | expected := testpkg.Nested{ 187 | First: testpkg.Embedded{Field: "first embedded"}, 188 | Second: &testpkg.Embedded{Field: "second embedded"}, 189 | Third: []testpkg.Embedded{{Field: "third embedded"}}, 190 | Fourth: []*testpkg.Embedded{&testpkg.Embedded{Field: "fourth embedded"}}, 191 | Fifth: [3]testpkg.Embedded{{Field: "fifth embedded"}}, 192 | Sixth: [3]*testpkg.Embedded{{Field: "sixth embedded"}}, 193 | } 194 | m := map[string]interface{}{ 195 | "First": map[string]interface{}{"Field": "first embedded"}, 196 | "Second": map[string]interface{}{"Field": "second embedded"}, 197 | "Third": []interface{}{map[string]interface{}{"Field": "third embedded"}}, 198 | "Fourth": []interface{}{map[string]interface{}{"Field": "fourth embedded"}}, 199 | "Fifth": []interface{}{map[string]interface{}{"Field": "fifth embedded"}}, 200 | "Sixth": []interface{}{map[string]interface{}{"Field": "sixth embedded"}}, 201 | } 202 | 203 | err := s.UnmarshalMap(m) 204 | assert.NoError(t, err) 205 | assert.Equal(t, expected, s) 206 | equalJSONs(t, expected, m) 207 | 208 | s = testpkg.Nested{} 209 | m = map[string]interface{}{} 210 | data, err := json.Marshal(expected) 211 | assert.NoError(t, err) 212 | json.Unmarshal(data, &m) 213 | 214 | err = s.UnmarshalMap(m) 215 | assert.NoError(t, err) 216 | t.Logf("map: %#v", m) 217 | t.Logf("obj: %#v", s) 218 | assert.Equal(t, expected, s) 219 | equalJSONs(t, expected, m) 220 | 221 | s = testpkg.Nested{} 222 | expected = testpkg.Nested{} 223 | m = map[string]interface{}{} 224 | data, err = json.Marshal(expected) 225 | assert.NoError(t, err) 226 | json.Unmarshal(data, &m) 227 | 228 | err = s.UnmarshalMap(m) 229 | assert.NoError(t, err) 230 | t.Logf("map: %#v", m) 231 | t.Logf("obj: %#v", s) 232 | assert.Equal(t, expected, s) 233 | equalJSONs(t, expected, m) 234 | 235 | s = testpkg.Nested{} 236 | expected = testpkg.Nested{} 237 | m = map[string]interface{}{} 238 | 239 | err = s.UnmarshalMap(m) 240 | assert.NoError(t, err) 241 | assert.Equal(t, expected, s) 242 | equalJSONs(t, expected, m) 243 | } 244 | 245 | func TestEmbeddedStruct(t *testing.T) { 246 | var s testpkg.Composed 247 | expected := testpkg.Composed{ 248 | Embedded: testpkg.Embedded{Field: "first embedded"}, 249 | Base: "hello", 250 | } 251 | m := map[string]interface{}{ 252 | "Field": "first embedded", 253 | "Base": "hello", 254 | } 255 | 256 | err := s.UnmarshalMap(m) 257 | assert.NoError(t, err) 258 | assert.Equal(t, expected, s) 259 | equalJSONs(t, expected, m) 260 | 261 | s = testpkg.Composed{} 262 | m = map[string]interface{}{} 263 | data, err := json.Marshal(expected) 264 | assert.NoError(t, err) 265 | json.Unmarshal(data, &m) 266 | 267 | err = s.UnmarshalMap(m) 268 | assert.NoError(t, err) 269 | assert.Equal(t, expected, s) 270 | equalJSONs(t, expected, m) 271 | 272 | s = testpkg.Composed{} 273 | expected = testpkg.Composed{} 274 | m = map[string]interface{}{} 275 | data, err = json.Marshal(expected) 276 | assert.NoError(t, err) 277 | json.Unmarshal(data, &m) 278 | 279 | err = s.UnmarshalMap(m) 280 | assert.NoError(t, err) 281 | assert.Equal(t, expected, s) 282 | equalJSONs(t, expected, m) 283 | 284 | s = testpkg.Composed{} 285 | expected = testpkg.Composed{} 286 | m = map[string]interface{}{} 287 | 288 | err = s.UnmarshalMap(m) 289 | assert.NoError(t, err) 290 | assert.Equal(t, expected, s) 291 | equalJSONs(t, expected, m) 292 | } 293 | 294 | func BenchmarkUnmarshalmap(b *testing.B) { 295 | to := testpkg.SimpleStruct{} 296 | m := map[string]interface{}{ 297 | "SimpleField": "hello", 298 | "field2": "second field", 299 | "field3": "third field", 300 | "SimpleSkipped": "skipped", 301 | "Ignored": "ignore", 302 | "-": "ignore", 303 | "SimpleOmitEmptyNoName": "noname", 304 | } 305 | for i := 0; i < b.N; i++ { 306 | to.UnmarshalMap(m) 307 | } 308 | } 309 | 310 | func BenchmarkMapstructure(b *testing.B) { 311 | to := testpkg.SimpleStruct{} 312 | m := map[string]interface{}{ 313 | "SimpleField": "hello", 314 | "field2": "second field", 315 | "field3": "third field", 316 | "SimpleSkipped": "skipped", 317 | "Ignored": "ignore", 318 | "-": "ignore", 319 | "SimpleOmitEmptyNoName": "noname", 320 | } 321 | for i := 0; i < b.N; i++ { 322 | mapstructure.Decode(m, &to) 323 | } 324 | } 325 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/ast/astutil/imports.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package astutil contains common utilities for working with the Go AST. 6 | package astutil // import "golang.org/x/tools/go/ast/astutil" 7 | 8 | import ( 9 | "fmt" 10 | "go/ast" 11 | "go/token" 12 | "strconv" 13 | "strings" 14 | ) 15 | 16 | // AddImport adds the import path to the file f, if absent. 17 | func AddImport(fset *token.FileSet, f *ast.File, ipath string) (added bool) { 18 | return AddNamedImport(fset, f, "", ipath) 19 | } 20 | 21 | // AddNamedImport adds the import path to the file f, if absent. 22 | // If name is not empty, it is used to rename the import. 23 | // 24 | // For example, calling 25 | // AddNamedImport(fset, f, "pathpkg", "path") 26 | // adds 27 | // import pathpkg "path" 28 | func AddNamedImport(fset *token.FileSet, f *ast.File, name, ipath string) (added bool) { 29 | if imports(f, ipath) { 30 | return false 31 | } 32 | 33 | newImport := &ast.ImportSpec{ 34 | Path: &ast.BasicLit{ 35 | Kind: token.STRING, 36 | Value: strconv.Quote(ipath), 37 | }, 38 | } 39 | if name != "" { 40 | newImport.Name = &ast.Ident{Name: name} 41 | } 42 | 43 | // Find an import decl to add to. 44 | // The goal is to find an existing import 45 | // whose import path has the longest shared 46 | // prefix with ipath. 47 | var ( 48 | bestMatch = -1 // length of longest shared prefix 49 | lastImport = -1 // index in f.Decls of the file's final import decl 50 | impDecl *ast.GenDecl // import decl containing the best match 51 | impIndex = -1 // spec index in impDecl containing the best match 52 | ) 53 | for i, decl := range f.Decls { 54 | gen, ok := decl.(*ast.GenDecl) 55 | if ok && gen.Tok == token.IMPORT { 56 | lastImport = i 57 | // Do not add to import "C", to avoid disrupting the 58 | // association with its doc comment, breaking cgo. 59 | if declImports(gen, "C") { 60 | continue 61 | } 62 | 63 | // Match an empty import decl if that's all that is available. 64 | if len(gen.Specs) == 0 && bestMatch == -1 { 65 | impDecl = gen 66 | } 67 | 68 | // Compute longest shared prefix with imports in this group. 69 | for j, spec := range gen.Specs { 70 | impspec := spec.(*ast.ImportSpec) 71 | n := matchLen(importPath(impspec), ipath) 72 | if n > bestMatch { 73 | bestMatch = n 74 | impDecl = gen 75 | impIndex = j 76 | } 77 | } 78 | } 79 | } 80 | 81 | // If no import decl found, add one after the last import. 82 | if impDecl == nil { 83 | impDecl = &ast.GenDecl{ 84 | Tok: token.IMPORT, 85 | } 86 | if lastImport >= 0 { 87 | impDecl.TokPos = f.Decls[lastImport].End() 88 | } else { 89 | // There are no existing imports. 90 | // Our new import goes after the package declaration and after 91 | // the comment, if any, that starts on the same line as the 92 | // package declaration. 93 | impDecl.TokPos = f.Package 94 | 95 | file := fset.File(f.Package) 96 | pkgLine := file.Line(f.Package) 97 | for _, c := range f.Comments { 98 | if file.Line(c.Pos()) > pkgLine { 99 | break 100 | } 101 | impDecl.TokPos = c.End() 102 | } 103 | } 104 | f.Decls = append(f.Decls, nil) 105 | copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:]) 106 | f.Decls[lastImport+1] = impDecl 107 | } 108 | 109 | // Insert new import at insertAt. 110 | insertAt := 0 111 | if impIndex >= 0 { 112 | // insert after the found import 113 | insertAt = impIndex + 1 114 | } 115 | impDecl.Specs = append(impDecl.Specs, nil) 116 | copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:]) 117 | impDecl.Specs[insertAt] = newImport 118 | pos := impDecl.Pos() 119 | if insertAt > 0 { 120 | // Assign same position as the previous import, 121 | // so that the sorter sees it as being in the same block. 122 | pos = impDecl.Specs[insertAt-1].Pos() 123 | } 124 | if newImport.Name != nil { 125 | newImport.Name.NamePos = pos 126 | } 127 | newImport.Path.ValuePos = pos 128 | newImport.EndPos = pos 129 | 130 | // Clean up parens. impDecl contains at least one spec. 131 | if len(impDecl.Specs) == 1 { 132 | // Remove unneeded parens. 133 | impDecl.Lparen = token.NoPos 134 | } else if !impDecl.Lparen.IsValid() { 135 | // impDecl needs parens added. 136 | impDecl.Lparen = impDecl.Specs[0].Pos() 137 | } 138 | 139 | f.Imports = append(f.Imports, newImport) 140 | return true 141 | } 142 | 143 | // DeleteImport deletes the import path from the file f, if present. 144 | func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) { 145 | var delspecs []*ast.ImportSpec 146 | 147 | // Find the import nodes that import path, if any. 148 | for i := 0; i < len(f.Decls); i++ { 149 | decl := f.Decls[i] 150 | gen, ok := decl.(*ast.GenDecl) 151 | if !ok || gen.Tok != token.IMPORT { 152 | continue 153 | } 154 | for j := 0; j < len(gen.Specs); j++ { 155 | spec := gen.Specs[j] 156 | impspec := spec.(*ast.ImportSpec) 157 | if importPath(impspec) != path { 158 | continue 159 | } 160 | 161 | // We found an import spec that imports path. 162 | // Delete it. 163 | delspecs = append(delspecs, impspec) 164 | deleted = true 165 | copy(gen.Specs[j:], gen.Specs[j+1:]) 166 | gen.Specs = gen.Specs[:len(gen.Specs)-1] 167 | 168 | // If this was the last import spec in this decl, 169 | // delete the decl, too. 170 | if len(gen.Specs) == 0 { 171 | copy(f.Decls[i:], f.Decls[i+1:]) 172 | f.Decls = f.Decls[:len(f.Decls)-1] 173 | i-- 174 | break 175 | } else if len(gen.Specs) == 1 { 176 | gen.Lparen = token.NoPos // drop parens 177 | } 178 | if j > 0 { 179 | lastImpspec := gen.Specs[j-1].(*ast.ImportSpec) 180 | lastLine := fset.Position(lastImpspec.Path.ValuePos).Line 181 | line := fset.Position(impspec.Path.ValuePos).Line 182 | 183 | // We deleted an entry but now there may be 184 | // a blank line-sized hole where the import was. 185 | if line-lastLine > 1 { 186 | // There was a blank line immediately preceding the deleted import, 187 | // so there's no need to close the hole. 188 | // Do nothing. 189 | } else { 190 | // There was no blank line. Close the hole. 191 | fset.File(gen.Rparen).MergeLine(line) 192 | } 193 | } 194 | j-- 195 | } 196 | } 197 | 198 | // Delete them from f.Imports. 199 | for i := 0; i < len(f.Imports); i++ { 200 | imp := f.Imports[i] 201 | for j, del := range delspecs { 202 | if imp == del { 203 | copy(f.Imports[i:], f.Imports[i+1:]) 204 | f.Imports = f.Imports[:len(f.Imports)-1] 205 | copy(delspecs[j:], delspecs[j+1:]) 206 | delspecs = delspecs[:len(delspecs)-1] 207 | i-- 208 | break 209 | } 210 | } 211 | } 212 | 213 | if len(delspecs) > 0 { 214 | panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs)) 215 | } 216 | 217 | return 218 | } 219 | 220 | // RewriteImport rewrites any import of path oldPath to path newPath. 221 | func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool) { 222 | for _, imp := range f.Imports { 223 | if importPath(imp) == oldPath { 224 | rewrote = true 225 | // record old End, because the default is to compute 226 | // it using the length of imp.Path.Value. 227 | imp.EndPos = imp.End() 228 | imp.Path.Value = strconv.Quote(newPath) 229 | } 230 | } 231 | return 232 | } 233 | 234 | // UsesImport reports whether a given import is used. 235 | func UsesImport(f *ast.File, path string) (used bool) { 236 | spec := importSpec(f, path) 237 | if spec == nil { 238 | return 239 | } 240 | 241 | name := spec.Name.String() 242 | switch name { 243 | case "": 244 | // If the package name is not explicitly specified, 245 | // make an educated guess. This is not guaranteed to be correct. 246 | lastSlash := strings.LastIndex(path, "/") 247 | if lastSlash == -1 { 248 | name = path 249 | } else { 250 | name = path[lastSlash+1:] 251 | } 252 | case "_", ".": 253 | // Not sure if this import is used - err on the side of caution. 254 | return true 255 | } 256 | 257 | ast.Walk(visitFn(func(n ast.Node) { 258 | sel, ok := n.(*ast.SelectorExpr) 259 | if ok && isTopName(sel.X, name) { 260 | used = true 261 | } 262 | }), f) 263 | 264 | return 265 | } 266 | 267 | type visitFn func(node ast.Node) 268 | 269 | func (fn visitFn) Visit(node ast.Node) ast.Visitor { 270 | fn(node) 271 | return fn 272 | } 273 | 274 | // imports returns true if f imports path. 275 | func imports(f *ast.File, path string) bool { 276 | return importSpec(f, path) != nil 277 | } 278 | 279 | // importSpec returns the import spec if f imports path, 280 | // or nil otherwise. 281 | func importSpec(f *ast.File, path string) *ast.ImportSpec { 282 | for _, s := range f.Imports { 283 | if importPath(s) == path { 284 | return s 285 | } 286 | } 287 | return nil 288 | } 289 | 290 | // importPath returns the unquoted import path of s, 291 | // or "" if the path is not properly quoted. 292 | func importPath(s *ast.ImportSpec) string { 293 | t, err := strconv.Unquote(s.Path.Value) 294 | if err == nil { 295 | return t 296 | } 297 | return "" 298 | } 299 | 300 | // declImports reports whether gen contains an import of path. 301 | func declImports(gen *ast.GenDecl, path string) bool { 302 | if gen.Tok != token.IMPORT { 303 | return false 304 | } 305 | for _, spec := range gen.Specs { 306 | impspec := spec.(*ast.ImportSpec) 307 | if importPath(impspec) == path { 308 | return true 309 | } 310 | } 311 | return false 312 | } 313 | 314 | // matchLen returns the length of the longest path segment prefix shared by x and y. 315 | func matchLen(x, y string) int { 316 | n := 0 317 | for i := 0; i < len(x) && i < len(y) && x[i] == y[i]; i++ { 318 | if x[i] == '/' { 319 | n++ 320 | } 321 | } 322 | return n 323 | } 324 | 325 | // isTopName returns true if n is a top-level unresolved identifier with the given name. 326 | func isTopName(n ast.Expr, name string) bool { 327 | id, ok := n.(*ast.Ident) 328 | return ok && id.Name == name && id.Obj == nil 329 | } 330 | 331 | // Imports returns the file imports grouped by paragraph. 332 | func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec { 333 | var groups [][]*ast.ImportSpec 334 | 335 | for _, decl := range f.Decls { 336 | genDecl, ok := decl.(*ast.GenDecl) 337 | if !ok || genDecl.Tok != token.IMPORT { 338 | break 339 | } 340 | 341 | group := []*ast.ImportSpec{} 342 | 343 | var lastLine int 344 | for _, spec := range genDecl.Specs { 345 | importSpec := spec.(*ast.ImportSpec) 346 | pos := importSpec.Path.ValuePos 347 | line := fset.Position(pos).Line 348 | if lastLine > 0 && pos > 0 && line-lastLine > 1 { 349 | groups = append(groups, group) 350 | group = []*ast.ImportSpec{} 351 | } 352 | group = append(group, importSpec) 353 | lastLine = line 354 | } 355 | groups = append(groups, group) 356 | } 357 | 358 | return groups 359 | } 360 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/forward_assertions.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import "time" 4 | 5 | // Assertions provides assertion methods around the 6 | // TestingT interface. 7 | type Assertions struct { 8 | t TestingT 9 | } 10 | 11 | // New makes a new Assertions object for the specified TestingT. 12 | func New(t TestingT) *Assertions { 13 | return &Assertions{ 14 | t: t, 15 | } 16 | } 17 | 18 | // Fail reports a failure through 19 | func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { 20 | return Fail(a.t, failureMessage, msgAndArgs...) 21 | } 22 | 23 | // Implements asserts that an object is implemented by the specified interface. 24 | // 25 | // assert.Implements((*MyInterface)(nil), new(MyObject), "MyObject") 26 | func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { 27 | return Implements(a.t, interfaceObject, object, msgAndArgs...) 28 | } 29 | 30 | // IsType asserts that the specified objects are of the same type. 31 | func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { 32 | return IsType(a.t, expectedType, object, msgAndArgs...) 33 | } 34 | 35 | // Equal asserts that two objects are equal. 36 | // 37 | // assert.Equal(123, 123, "123 and 123 should be equal") 38 | // 39 | // Returns whether the assertion was successful (true) or not (false). 40 | func (a *Assertions) Equal(expected, actual interface{}, msgAndArgs ...interface{}) bool { 41 | return Equal(a.t, expected, actual, msgAndArgs...) 42 | } 43 | 44 | // EqualValues asserts that two objects are equal or convertable to the same types 45 | // and equal. 46 | // 47 | // assert.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") 48 | // 49 | // Returns whether the assertion was successful (true) or not (false). 50 | func (a *Assertions) EqualValues(expected, actual interface{}, msgAndArgs ...interface{}) bool { 51 | return EqualValues(a.t, expected, actual, msgAndArgs...) 52 | } 53 | 54 | // Exactly asserts that two objects are equal is value and type. 55 | // 56 | // assert.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") 57 | // 58 | // Returns whether the assertion was successful (true) or not (false). 59 | func (a *Assertions) Exactly(expected, actual interface{}, msgAndArgs ...interface{}) bool { 60 | return Exactly(a.t, expected, actual, msgAndArgs...) 61 | } 62 | 63 | // NotNil asserts that the specified object is not nil. 64 | // 65 | // assert.NotNil(err, "err should be something") 66 | // 67 | // Returns whether the assertion was successful (true) or not (false). 68 | func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { 69 | return NotNil(a.t, object, msgAndArgs...) 70 | } 71 | 72 | // Nil asserts that the specified object is nil. 73 | // 74 | // assert.Nil(err, "err should be nothing") 75 | // 76 | // Returns whether the assertion was successful (true) or not (false). 77 | func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { 78 | return Nil(a.t, object, msgAndArgs...) 79 | } 80 | 81 | // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or a 82 | // slice with len == 0. 83 | // 84 | // assert.Empty(obj) 85 | // 86 | // Returns whether the assertion was successful (true) or not (false). 87 | func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { 88 | return Empty(a.t, object, msgAndArgs...) 89 | } 90 | 91 | // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a 92 | // slice with len == 0. 93 | // 94 | // if assert.NotEmpty(obj) { 95 | // assert.Equal("two", obj[1]) 96 | // } 97 | // 98 | // Returns whether the assertion was successful (true) or not (false). 99 | func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { 100 | return NotEmpty(a.t, object, msgAndArgs...) 101 | } 102 | 103 | // Len asserts that the specified object has specific length. 104 | // Len also fails if the object has a type that len() not accept. 105 | // 106 | // assert.Len(mySlice, 3, "The size of slice is not 3") 107 | // 108 | // Returns whether the assertion was successful (true) or not (false). 109 | func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { 110 | return Len(a.t, object, length, msgAndArgs...) 111 | } 112 | 113 | // True asserts that the specified value is true. 114 | // 115 | // assert.True(myBool, "myBool should be true") 116 | // 117 | // Returns whether the assertion was successful (true) or not (false). 118 | func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { 119 | return True(a.t, value, msgAndArgs...) 120 | } 121 | 122 | // False asserts that the specified value is false. 123 | // 124 | // assert.False(myBool, "myBool should be false") 125 | // 126 | // Returns whether the assertion was successful (true) or not (false). 127 | func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { 128 | return False(a.t, value, msgAndArgs...) 129 | } 130 | 131 | // NotEqual asserts that the specified values are NOT equal. 132 | // 133 | // assert.NotEqual(obj1, obj2, "two objects shouldn't be equal") 134 | // 135 | // Returns whether the assertion was successful (true) or not (false). 136 | func (a *Assertions) NotEqual(expected, actual interface{}, msgAndArgs ...interface{}) bool { 137 | return NotEqual(a.t, expected, actual, msgAndArgs...) 138 | } 139 | 140 | // Contains asserts that the specified string contains the specified substring. 141 | // 142 | // assert.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") 143 | // 144 | // Returns whether the assertion was successful (true) or not (false). 145 | func (a *Assertions) Contains(s, contains interface{}, msgAndArgs ...interface{}) bool { 146 | return Contains(a.t, s, contains, msgAndArgs...) 147 | } 148 | 149 | // NotContains asserts that the specified string does NOT contain the specified substring. 150 | // 151 | // assert.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") 152 | // 153 | // Returns whether the assertion was successful (true) or not (false). 154 | func (a *Assertions) NotContains(s, contains interface{}, msgAndArgs ...interface{}) bool { 155 | return NotContains(a.t, s, contains, msgAndArgs...) 156 | } 157 | 158 | // Condition uses a Comparison to assert a complex condition. 159 | func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { 160 | return Condition(a.t, comp, msgAndArgs...) 161 | } 162 | 163 | // Panics asserts that the code inside the specified PanicTestFunc panics. 164 | // 165 | // assert.Panics(func(){ 166 | // GoCrazy() 167 | // }, "Calling GoCrazy() should panic") 168 | // 169 | // Returns whether the assertion was successful (true) or not (false). 170 | func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { 171 | return Panics(a.t, f, msgAndArgs...) 172 | } 173 | 174 | // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. 175 | // 176 | // assert.NotPanics(func(){ 177 | // RemainCalm() 178 | // }, "Calling RemainCalm() should NOT panic") 179 | // 180 | // Returns whether the assertion was successful (true) or not (false). 181 | func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { 182 | return NotPanics(a.t, f, msgAndArgs...) 183 | } 184 | 185 | // WithinDuration asserts that the two times are within duration delta of each other. 186 | // 187 | // assert.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") 188 | // 189 | // Returns whether the assertion was successful (true) or not (false). 190 | func (a *Assertions) WithinDuration(expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { 191 | return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) 192 | } 193 | 194 | // InDelta asserts that the two numerals are within delta of each other. 195 | // 196 | // assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) 197 | // 198 | // Returns whether the assertion was successful (true) or not (false). 199 | func (a *Assertions) InDelta(expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 200 | return InDelta(a.t, expected, actual, delta, msgAndArgs...) 201 | } 202 | 203 | // InEpsilon asserts that expected and actual have a relative error less than epsilon 204 | // 205 | // Returns whether the assertion was successful (true) or not (false). 206 | func (a *Assertions) InEpsilon(expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { 207 | return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) 208 | } 209 | 210 | // NoError asserts that a function returned no error (i.e. `nil`). 211 | // 212 | // actualObj, err := SomeFunction() 213 | // if assert.NoError(err) { 214 | // assert.Equal(actualObj, expectedObj) 215 | // } 216 | // 217 | // Returns whether the assertion was successful (true) or not (false). 218 | func (a *Assertions) NoError(theError error, msgAndArgs ...interface{}) bool { 219 | return NoError(a.t, theError, msgAndArgs...) 220 | } 221 | 222 | // Error asserts that a function returned an error (i.e. not `nil`). 223 | // 224 | // actualObj, err := SomeFunction() 225 | // if assert.Error(err, "An error was expected") { 226 | // assert.Equal(err, expectedError) 227 | // } 228 | // 229 | // Returns whether the assertion was successful (true) or not (false). 230 | func (a *Assertions) Error(theError error, msgAndArgs ...interface{}) bool { 231 | return Error(a.t, theError, msgAndArgs...) 232 | } 233 | 234 | // EqualError asserts that a function returned an error (i.e. not `nil`) 235 | // and that it is equal to the provided error. 236 | // 237 | // actualObj, err := SomeFunction() 238 | // if assert.Error(err, "An error was expected") { 239 | // assert.Equal(err, expectedError) 240 | // } 241 | // 242 | // Returns whether the assertion was successful (true) or not (false). 243 | func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { 244 | return EqualError(a.t, theError, errString, msgAndArgs...) 245 | } 246 | 247 | // Regexp asserts that a specified regexp matches a string. 248 | // 249 | // assert.Regexp(t, regexp.MustCompile("start"), "it's starting") 250 | // assert.Regexp(t, "start...$", "it's not starting") 251 | // 252 | // Returns whether the assertion was successful (true) or not (false). 253 | func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { 254 | return Regexp(a.t, rx, str, msgAndArgs...) 255 | } 256 | 257 | // NotRegexp asserts that a specified regexp does not match a string. 258 | // 259 | // assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") 260 | // assert.NotRegexp(t, "^start", "it's not starting") 261 | // 262 | // Returns whether the assertion was successful (true) or not (false). 263 | func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { 264 | return NotRegexp(a.t, rx, str, msgAndArgs...) 265 | } 266 | 267 | // Zero asserts that i is the zero value for its type and returns the truth. 268 | func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { 269 | return Zero(a.t, i, msgAndArgs...) 270 | } 271 | 272 | // NotZero asserts that i is not the zero value for its type and returns the truth. 273 | func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { 274 | return NotZero(a.t, i, msgAndArgs...) 275 | } 276 | 277 | // JSONEq asserts that two JSON strings are equivalent. 278 | // 279 | // assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) 280 | // 281 | // Returns whether the assertion was successful (true) or not (false). 282 | func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { 283 | return JSONEq(a.t, expected, actual, msgAndArgs...) 284 | } 285 | --------------------------------------------------------------------------------