1// Copyright 2015 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package main 16 17import ( 18 "bytes" 19 "flag" 20 "fmt" 21 "go/ast" 22 "go/parser" 23 "go/token" 24 "io/ioutil" 25 "os" 26 "sort" 27 "strings" 28 "text/template" 29) 30 31var ( 32 output = flag.String("o", "", "output filename") 33 pkg = flag.String("pkg", "", "test package") 34 exitCode = 0 35) 36 37type data struct { 38 Package string 39 Tests []string 40} 41 42func findTests(srcs []string) (tests []string) { 43 for _, src := range srcs { 44 f, err := parser.ParseFile(token.NewFileSet(), src, nil, 0) 45 if err != nil { 46 panic(err) 47 } 48 for _, obj := range f.Scope.Objects { 49 if obj.Kind != ast.Fun || !strings.HasPrefix(obj.Name, "Test") { 50 continue 51 } 52 tests = append(tests, obj.Name) 53 } 54 } 55 sort.Strings(tests) 56 return 57} 58 59func main() { 60 flag.Parse() 61 62 if flag.NArg() == 0 { 63 fmt.Fprintln(os.Stderr, "error: must pass at least one input") 64 exitCode = 1 65 return 66 } 67 68 buf := &bytes.Buffer{} 69 70 d := data{ 71 Package: *pkg, 72 Tests: findTests(flag.Args()), 73 } 74 75 err := testMainTmpl.Execute(buf, d) 76 if err != nil { 77 panic(err) 78 } 79 80 err = ioutil.WriteFile(*output, buf.Bytes(), 0666) 81 if err != nil { 82 panic(err) 83 } 84} 85 86var testMainTmpl = template.Must(template.New("testMain").Parse(` 87package main 88 89import ( 90 "regexp" 91 "testing" 92 93 pkg "{{.Package}}" 94) 95 96var t = []testing.InternalTest{ 97{{range .Tests}} 98 {"{{.}}", pkg.{{.}}}, 99{{end}} 100} 101 102var matchPat string 103var matchRe *regexp.Regexp 104 105func matchString(pat, str string) (result bool, err error) { 106 if matchRe == nil || matchPat != pat { 107 matchPat = pat 108 matchRe, err = regexp.Compile(matchPat) 109 if err != nil { 110 return 111 } 112 } 113 return matchRe.MatchString(str), nil 114} 115 116func main() { 117 testing.Main(matchString, t, nil, nil) 118} 119`)) 120