родитель
							
								
									a3d1f1a514
								
							
						
					
					
						коммит
						208e1719ad
					
				
					 9 изменённых файлов: 288 добавлений и 13 удалений
				
			
		
							
								
								
									
										4
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -38,6 +38,7 @@ fmt:
 | 
			
		|||
fmt-check:
 | 
			
		||||
	@unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo "  $$fn"; done; exit 1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
gen-device: gen-device-avr gen-device-nrf gen-device-sam gen-device-stm32
 | 
			
		||||
 | 
			
		||||
gen-device-avr:
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +86,9 @@ build/tinygo:
 | 
			
		|||
test:
 | 
			
		||||
	CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" go test -v -tags byollvm .
 | 
			
		||||
 | 
			
		||||
tinygo-test:
 | 
			
		||||
	cd tests/tinygotest && tinygo test
 | 
			
		||||
 | 
			
		||||
.PHONY: smoketest smoketest-no-avr
 | 
			
		||||
smoketest: smoketest-no-avr
 | 
			
		||||
	tinygo build -size short -o test.elf -target=arduino             examples/blinky1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,12 @@ type Config struct {
 | 
			
		|||
	TINYGOROOT    string   // GOROOT for TinyGo
 | 
			
		||||
	GOPATH        string   // GOPATH, like `go env GOPATH`
 | 
			
		||||
	BuildTags     []string // build tags for TinyGo (empty means {Config.GOOS/Config.GOARCH})
 | 
			
		||||
	TestConfig    TestConfig
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type TestConfig struct {
 | 
			
		||||
	CompileTestBinary bool
 | 
			
		||||
	// TODO: Filter the test functions to run, include verbose flag, etc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Compiler struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -214,7 +220,7 @@ func (c *Compiler) Compile(mainPath string) []error {
 | 
			
		|||
				path = path[len(tinygoPath+"/src/"):]
 | 
			
		||||
			}
 | 
			
		||||
			switch path {
 | 
			
		||||
			case "machine", "os", "reflect", "runtime", "runtime/volatile", "sync":
 | 
			
		||||
			case "machine", "os", "reflect", "runtime", "runtime/volatile", "sync", "testing":
 | 
			
		||||
				return path
 | 
			
		||||
			default:
 | 
			
		||||
				if strings.HasPrefix(path, "device/") || strings.HasPrefix(path, "examples/") {
 | 
			
		||||
| 
						 | 
				
			
			@ -241,6 +247,7 @@ func (c *Compiler) Compile(mainPath string) []error {
 | 
			
		|||
		CFlags:       c.CFlags,
 | 
			
		||||
		ClangHeaders: c.ClangHeaders,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if strings.HasSuffix(mainPath, ".go") {
 | 
			
		||||
		_, err = lprogram.ImportFile(mainPath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -252,12 +259,13 @@ func (c *Compiler) Compile(mainPath string) []error {
 | 
			
		|||
			return []error{err}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err = lprogram.Import("runtime", "")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return []error{err}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = lprogram.Parse()
 | 
			
		||||
	err = lprogram.Parse(c.TestConfig.CompileTestBinary)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return []error{err}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										137
									
								
								loader/loader.go
									
										
									
									
									
								
							
							
						
						
									
										137
									
								
								loader/loader.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
package loader
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"go/ast"
 | 
			
		||||
	"go/build"
 | 
			
		||||
| 
						 | 
				
			
			@ -10,12 +11,15 @@ import (
 | 
			
		|||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"text/template"
 | 
			
		||||
 | 
			
		||||
	"github.com/tinygo-org/tinygo/cgo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Program holds all packages and some metadata about the program as a whole.
 | 
			
		||||
type Program struct {
 | 
			
		||||
	mainPkg      string
 | 
			
		||||
	Build        *build.Context
 | 
			
		||||
	OverlayBuild *build.Context
 | 
			
		||||
	OverlayPath  func(path string) string
 | 
			
		||||
| 
						 | 
				
			
			@ -64,6 +68,11 @@ func (p *Program) Import(path, srcDir string) (*Package, error) {
 | 
			
		|||
	p.sorted = nil // invalidate the sorted order of packages
 | 
			
		||||
	pkg := p.newPackage(buildPkg)
 | 
			
		||||
	p.Packages[buildPkg.ImportPath] = pkg
 | 
			
		||||
 | 
			
		||||
	if p.mainPkg == "" {
 | 
			
		||||
		p.mainPkg = buildPkg.ImportPath
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pkg, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +102,11 @@ func (p *Program) ImportFile(path string) (*Package, error) {
 | 
			
		|||
	p.sorted = nil // invalidate the sorted order of packages
 | 
			
		||||
	pkg := p.newPackage(buildPkg)
 | 
			
		||||
	p.Packages[buildPkg.ImportPath] = pkg
 | 
			
		||||
 | 
			
		||||
	if p.mainPkg == "" {
 | 
			
		||||
		p.mainPkg = buildPkg.ImportPath
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pkg, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -171,10 +185,12 @@ func (p *Program) sort() {
 | 
			
		|||
// The returned error may be an Errors error, which contains a list of errors.
 | 
			
		||||
//
 | 
			
		||||
// Idempotent.
 | 
			
		||||
func (p *Program) Parse() error {
 | 
			
		||||
func (p *Program) Parse(compileTestBinary bool) error {
 | 
			
		||||
	includeTests := compileTestBinary
 | 
			
		||||
 | 
			
		||||
	// Load all imports
 | 
			
		||||
	for _, pkg := range p.Sorted() {
 | 
			
		||||
		err := pkg.importRecursively()
 | 
			
		||||
		err := pkg.importRecursively(includeTests)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if err, ok := err.(*ImportCycleError); ok {
 | 
			
		||||
				if pkg.ImportPath != err.Packages[0] {
 | 
			
		||||
| 
						 | 
				
			
			@ -187,7 +203,14 @@ func (p *Program) Parse() error {
 | 
			
		|||
 | 
			
		||||
	// Parse all packages.
 | 
			
		||||
	for _, pkg := range p.Sorted() {
 | 
			
		||||
		err := pkg.Parse()
 | 
			
		||||
		err := pkg.Parse(includeTests)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if compileTestBinary {
 | 
			
		||||
		err := p.SwapTestMain()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -204,6 +227,83 @@ func (p *Program) Parse() error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Program) SwapTestMain() error {
 | 
			
		||||
	var tests []string
 | 
			
		||||
 | 
			
		||||
	isTestFunc := func(f *ast.FuncDecl) bool {
 | 
			
		||||
		// TODO: improve signature check
 | 
			
		||||
		if strings.HasPrefix(f.Name.Name, "Test") && f.Name.Name != "TestMain" {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	mainPkg := p.Packages[p.mainPkg]
 | 
			
		||||
	for _, f := range mainPkg.Files {
 | 
			
		||||
		for i, d := range f.Decls {
 | 
			
		||||
			switch v := d.(type) {
 | 
			
		||||
			case *ast.FuncDecl:
 | 
			
		||||
				if isTestFunc(v) {
 | 
			
		||||
					tests = append(tests, v.Name.Name)
 | 
			
		||||
				}
 | 
			
		||||
				if v.Name.Name == "main" {
 | 
			
		||||
					// Remove main
 | 
			
		||||
					if len(f.Decls) == 1 {
 | 
			
		||||
						f.Decls = make([]ast.Decl, 0)
 | 
			
		||||
					} else {
 | 
			
		||||
						f.Decls[i] = f.Decls[len(f.Decls)-1]
 | 
			
		||||
						f.Decls = f.Decls[:len(f.Decls)-1]
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO: Check if they defined a TestMain and call it instead of testing.TestMain
 | 
			
		||||
	const mainBody = `package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main () {
 | 
			
		||||
	m := &testing.M{
 | 
			
		||||
		Tests: []testing.TestToCall{
 | 
			
		||||
{{range .TestFunctions}}
 | 
			
		||||
			{Name: "{{.}}", Func: {{.}}},
 | 
			
		||||
{{end}}
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	testing.TestMain(m)
 | 
			
		||||
}
 | 
			
		||||
`
 | 
			
		||||
	tmpl := template.Must(template.New("testmain").Parse(mainBody))
 | 
			
		||||
	b := bytes.Buffer{}
 | 
			
		||||
	tmplData := struct {
 | 
			
		||||
		TestFunctions []string
 | 
			
		||||
	}{
 | 
			
		||||
		TestFunctions: tests,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := tmpl.Execute(&b, tmplData)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	path := filepath.Join(p.mainPkg, "$testmain.go")
 | 
			
		||||
 | 
			
		||||
	if p.fset == nil {
 | 
			
		||||
		p.fset = token.NewFileSet()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	newMain, err := parser.ParseFile(p.fset, path, b.Bytes(), parser.AllErrors)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	mainPkg.Files = append(mainPkg.Files, newMain)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseFile is a wrapper around parser.ParseFile.
 | 
			
		||||
func (p *Program) parseFile(path string, mode parser.Mode) (*ast.File, error) {
 | 
			
		||||
	if p.fset == nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -228,7 +328,7 @@ func (p *Program) parseFile(path string, mode parser.Mode) (*ast.File, error) {
 | 
			
		|||
// Parse parses and typechecks this package.
 | 
			
		||||
//
 | 
			
		||||
// Idempotent.
 | 
			
		||||
func (p *Package) Parse() error {
 | 
			
		||||
func (p *Package) Parse(includeTests bool) error {
 | 
			
		||||
	if len(p.Files) != 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +342,7 @@ func (p *Package) Parse() error {
 | 
			
		|||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	files, err := p.parseFiles()
 | 
			
		||||
	files, err := p.parseFiles(includeTests)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -281,11 +381,21 @@ func (p *Package) Check() error {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// parseFiles parses the loaded list of files and returns this list.
 | 
			
		||||
func (p *Package) parseFiles() ([]*ast.File, error) {
 | 
			
		||||
func (p *Package) parseFiles(includeTests bool) ([]*ast.File, error) {
 | 
			
		||||
	// TODO: do this concurrently.
 | 
			
		||||
	var files []*ast.File
 | 
			
		||||
	var fileErrs []error
 | 
			
		||||
	for _, file := range p.GoFiles {
 | 
			
		||||
 | 
			
		||||
	var gofiles []string
 | 
			
		||||
	if includeTests {
 | 
			
		||||
		gofiles = make([]string, 0, len(p.GoFiles)+len(p.TestGoFiles))
 | 
			
		||||
		gofiles = append(gofiles, p.GoFiles...)
 | 
			
		||||
		gofiles = append(gofiles, p.TestGoFiles...)
 | 
			
		||||
	} else {
 | 
			
		||||
		gofiles = p.GoFiles
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, file := range gofiles {
 | 
			
		||||
		f, err := p.parseFile(filepath.Join(p.Package.Dir, file), parser.ParseComments)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fileErrs = append(fileErrs, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -320,6 +430,7 @@ func (p *Package) parseFiles() ([]*ast.File, error) {
 | 
			
		|||
	if len(fileErrs) != 0 {
 | 
			
		||||
		return nil, Errors{p, fileErrs}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return files, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -340,9 +451,15 @@ func (p *Package) Import(to string) (*types.Package, error) {
 | 
			
		|||
// importRecursively() on the imported packages as well.
 | 
			
		||||
//
 | 
			
		||||
// Idempotent.
 | 
			
		||||
func (p *Package) importRecursively() error {
 | 
			
		||||
func (p *Package) importRecursively(includeTests bool) error {
 | 
			
		||||
	p.Importing = true
 | 
			
		||||
	for _, to := range p.Package.Imports {
 | 
			
		||||
 | 
			
		||||
	imports := p.Package.Imports
 | 
			
		||||
	if includeTests {
 | 
			
		||||
		imports = append(imports, p.Package.TestImports...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, to := range imports {
 | 
			
		||||
		if to == "C" {
 | 
			
		||||
			// Do CGo processing in a later stage.
 | 
			
		||||
			continue
 | 
			
		||||
| 
						 | 
				
			
			@ -360,7 +477,7 @@ func (p *Package) importRecursively() error {
 | 
			
		|||
		if importedPkg.Importing {
 | 
			
		||||
			return &ImportCycleError{[]string{p.ImportPath, importedPkg.ImportPath}, p.ImportPos[to]}
 | 
			
		||||
		}
 | 
			
		||||
		err = importedPkg.importRecursively()
 | 
			
		||||
		err = importedPkg.importRecursively(false)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if err, ok := err.(*ImportCycleError); ok {
 | 
			
		||||
				err.Packages = append([]string{p.ImportPath}, err.Packages...)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										33
									
								
								main.go
									
										
									
									
									
								
							
							
						
						
									
										33
									
								
								main.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -54,6 +54,7 @@ type BuildConfig struct {
 | 
			
		|||
	cFlags        []string
 | 
			
		||||
	ldFlags       []string
 | 
			
		||||
	wasmAbi       string
 | 
			
		||||
	testConfig    compiler.TestConfig
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Helper function for Compiler object.
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +109,7 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
 | 
			
		|||
		GOROOT:        goroot,
 | 
			
		||||
		GOPATH:        getGopath(),
 | 
			
		||||
		BuildTags:     tags,
 | 
			
		||||
		TestConfig:    config.testConfig,
 | 
			
		||||
	}
 | 
			
		||||
	c, err := compiler.NewCompiler(pkgName, compilerConfig)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -349,6 +351,30 @@ func Build(pkgName, outpath, target string, config *BuildConfig) error {
 | 
			
		|||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Test(pkgName, target string, config *BuildConfig) error {
 | 
			
		||||
	spec, err := LoadTarget(target)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spec.BuildTags = append(spec.BuildTags, "test")
 | 
			
		||||
	config.testConfig.CompileTestBinary = true
 | 
			
		||||
	return Compile(pkgName, ".elf", spec, config, func(tmppath string) error {
 | 
			
		||||
		cmd := exec.Command(tmppath)
 | 
			
		||||
		cmd.Stdout = os.Stdout
 | 
			
		||||
		cmd.Stderr = os.Stderr
 | 
			
		||||
		err := cmd.Run()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// Propagate the exit code
 | 
			
		||||
			if err, ok := err.(*exec.ExitError); ok {
 | 
			
		||||
				os.Exit(err.ExitCode())
 | 
			
		||||
			}
 | 
			
		||||
			return &commandError{"failed to run compiled binary", tmppath, err}
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Flash(pkgName, target, port string, config *BuildConfig) error {
 | 
			
		||||
	spec, err := LoadTarget(target)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -656,6 +682,13 @@ func main() {
 | 
			
		|||
		}
 | 
			
		||||
		err := Run(flag.Arg(0), *target, config)
 | 
			
		||||
		handleCompilerError(err)
 | 
			
		||||
	case "test":
 | 
			
		||||
		pkgRoot := "."
 | 
			
		||||
		if flag.NArg() == 1 {
 | 
			
		||||
			pkgRoot = flag.Arg(0)
 | 
			
		||||
		}
 | 
			
		||||
		err := Test(pkgRoot, *target, config)
 | 
			
		||||
		handleCompilerError(err)
 | 
			
		||||
	case "clean":
 | 
			
		||||
		// remove cache directory
 | 
			
		||||
		dir := cacheDir()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,7 +92,7 @@ func (v Value) Pointer() uintptr {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (v Value) IsValid() bool {
 | 
			
		||||
	panic("unimplemented: (reflect.Value).IsValid()")
 | 
			
		||||
	return v.typecode != 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v Value) CanInterface() bool {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								src/testing/doc.go
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										6
									
								
								src/testing/doc.go
									
										
									
									
									
										Обычный файл
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
package testing
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 This is a sad stub of the upstream testing package because it doesn't compile
 | 
			
		||||
 with tinygo right now.
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										77
									
								
								src/testing/testing.go
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										77
									
								
								src/testing/testing.go
									
										
									
									
									
										Обычный файл
									
								
							| 
						 | 
				
			
			@ -0,0 +1,77 @@
 | 
			
		|||
package testing
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// T is a test helper.
 | 
			
		||||
type T struct {
 | 
			
		||||
	name   string
 | 
			
		||||
	output io.Writer
 | 
			
		||||
 | 
			
		||||
	// flags the test as having failed when non-zero
 | 
			
		||||
	failed int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestToCall is a reference to a test that should be called during a test suite run.
 | 
			
		||||
type TestToCall struct {
 | 
			
		||||
	// Name of the test to call.
 | 
			
		||||
	Name string
 | 
			
		||||
	// Function reference to the test.
 | 
			
		||||
	Func func(*T)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// M is a test suite.
 | 
			
		||||
type M struct {
 | 
			
		||||
	// tests is a list of the test names to execute
 | 
			
		||||
	Tests []TestToCall
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run the test suite.
 | 
			
		||||
func (m *M) Run() int {
 | 
			
		||||
	failures := 0
 | 
			
		||||
	for _, test := range m.Tests {
 | 
			
		||||
		t := &T{
 | 
			
		||||
			name:   test.Name,
 | 
			
		||||
			output: &bytes.Buffer{},
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Printf("=== RUN   %s\n", test.Name)
 | 
			
		||||
		test.Func(t)
 | 
			
		||||
 | 
			
		||||
		if t.failed == 0 {
 | 
			
		||||
			fmt.Printf("--- PASS: %s\n", test.Name)
 | 
			
		||||
		} else {
 | 
			
		||||
			fmt.Printf("--- FAIL: %s\n", test.Name)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Println(t.output)
 | 
			
		||||
 | 
			
		||||
		failures += t.failed
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if failures > 0 {
 | 
			
		||||
		fmt.Printf("exit status %d\n", failures)
 | 
			
		||||
		fmt.Println("FAIL")
 | 
			
		||||
	}
 | 
			
		||||
	return failures
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestMain(m *M) {
 | 
			
		||||
	os.Exit(m.Run())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Error is equivalent to Log followed by Fail
 | 
			
		||||
func (t *T) Error(args ...interface{}) {
 | 
			
		||||
	// This doesn't print the same as in upstream go, but works good enough
 | 
			
		||||
	// TODO: buffer test output like go does
 | 
			
		||||
	fmt.Fprintf(t.output, "\t")
 | 
			
		||||
	fmt.Fprintln(t.output, args...)
 | 
			
		||||
	t.Fail()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *T) Fail() {
 | 
			
		||||
	t.failed = 1
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								tests/tinygotest/main.go
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										14
									
								
								tests/tinygotest/main.go
									
										
									
									
									
										Обычный файл
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	Thing()
 | 
			
		||||
	fmt.Println("normal main")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Thing() {
 | 
			
		||||
	fmt.Println("THING")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								tests/tinygotest/main_test.go
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										16
									
								
								tests/tinygotest/main_test.go
									
										
									
									
									
										Обычный файл
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing" // This is the tinygo testing package
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestFail1(t *testing.T) {
 | 
			
		||||
	t.Error("TestFail1 failed because of stuff and things")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestFail2(t *testing.T) {
 | 
			
		||||
	t.Error("TestFail2 failed for reasons")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPass(t *testing.T) {
 | 
			
		||||
}
 | 
			
		||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче