build basic test runner from package source and test files

* c2f6784 AST
* 9e4d962 Use x/tools/imports to insert import statement
* bb7649f move builder to godog package
* 2892dd1 add build func documentation
Этот коммит содержится в:
gedi 2015-06-11 17:43:17 +03:00
родитель 4afb53d310
коммит 620b8ef3f1
4 изменённых файлов: 175 добавлений и 1 удалений

129
builder.go Обычный файл
Просмотреть файл

@ -0,0 +1,129 @@
package godog
import (
"bytes"
"go/ast"
"go/format"
"go/parser"
"go/token"
"log"
"os"
"path/filepath"
"strings"
"golang.org/x/tools/imports"
)
var mainTpl = `package main
import (
"github.com/DATA-DOG/godog"
"os"
)
func main() {
godog.Run()
os.Exit(0)
}
`
type builder struct {
files map[string]*ast.File
fset *token.FileSet
}
func newBuilder() *builder {
return &builder{
files: make(map[string]*ast.File),
fset: token.NewFileSet(),
}
}
func (b *builder) parseFile(path string) error {
f, err := parser.ParseFile(b.fset, path, nil, 0)
if err != nil {
return err
}
b.deleteMainFunc(f)
b.deleteImports(f)
b.files[f.Name.Name] = f
return nil
}
func (b *builder) deleteImports(f *ast.File) {
var decls []ast.Decl
for _, d := range f.Decls {
fun, ok := d.(*ast.GenDecl)
if !ok {
decls = append(decls, d)
continue
}
if fun.Tok != token.IMPORT {
decls = append(decls, fun)
}
}
f.Decls = decls
}
func (b *builder) deleteMainFunc(f *ast.File) {
var decls []ast.Decl
for _, d := range f.Decls {
fun, ok := d.(*ast.FuncDecl)
if !ok {
decls = append(decls, d)
continue
}
if fun.Name.Name != "main" {
decls = append(decls, fun)
}
}
f.Decls = decls
}
func (b *builder) merge() (*ast.File, error) {
f, err := parser.ParseFile(b.fset, "", mainTpl, 0)
if err != nil {
log.Println("fail here")
return nil, err
}
b.deleteImports(f)
b.files["main.go"] = f
pkg, _ := ast.NewPackage(b.fset, b.files, nil, nil)
pkg.Name = "main"
return ast.MergePackageFiles(pkg, ast.FilterImportDuplicates), nil
}
// Build creates a runnable godog executable
// from current package go files
func Build() ([]byte, error) {
b := newBuilder()
err := filepath.Walk(".", func(path string, file os.FileInfo, err error) error {
if file.IsDir() && file.Name() != "." {
return filepath.SkipDir
}
if err == nil && strings.HasSuffix(path, ".go") {
if err := b.parseFile(path); err != nil {
return err
}
}
return err
})
if err != nil {
return nil, err
}
merged, err := b.merge()
if err != nil {
return nil, err
}
var buf bytes.Buffer
if err := format.Node(&buf, b.fset, merged); err != nil {
return nil, err
}
return imports.Process("", buf.Bytes(), nil)
}

Просмотреть файл

@ -1,5 +1,29 @@
package main
import (
"os"
"github.com/DATA-DOG/godog"
)
func main() {
// well, not runnable yet
builtFile := os.TempDir() + "/godog_build.go"
if err := os.Remove(builtFile); err != nil && !os.IsNotExist(err) {
panic(err)
}
buf, err := godog.Build()
if err != nil {
panic(err)
}
w, err := os.Create(builtFile)
if err != nil {
panic(err)
}
_, err = w.Write(buf)
if err != nil {
panic(err)
}
w.Close()
}

7
runner.go Обычный файл
Просмотреть файл

@ -0,0 +1,7 @@
package godog
import "log"
func Run() {
log.Println("running godoc, num registered steps:", len(stepHandlers))
}

14
steps_test.go Обычный файл
Просмотреть файл

@ -0,0 +1,14 @@
package godog
import (
"log"
"regexp"
)
func init() {
f := StepHandlerFunc(func(args ...interface{}) error {
log.Println("step triggered")
return nil
})
Step(regexp.MustCompile("hello"), f)
}