func (b *Builder) runTests(p *pkg) []*lex8.Error { lib := p.pkg.Lib tests := p.pkg.Tests testMain := p.pkg.TestMain if testMain != "" && lib.HasFunc(testMain) { log := lex8.NewErrorList() if len(tests) > 0 { bs := new(bytes.Buffer) lex8.LogError(log, b.link(bs, p, testMain)) fout := b.home.CreateTestBin(p.path) img := bs.Bytes() _, err := fout.Write(img) lex8.LogError(log, err) lex8.LogError(log, fout.Close()) if es := log.Errs(); es != nil { return es } runTests(log, tests, img, b.Verbose) if es := log.Errs(); es != nil { return es } } } return nil }
func runPkgTests(c *context, p *pkg) []*lex8.Error { lib := p.pkg.Lib tests := p.pkg.Tests testMain := p.pkg.TestMain if testMain != "" && lib.HasFunc(testMain) { log := lex8.NewErrorList() if len(tests) > 0 { bs := new(bytes.Buffer) lex8.LogError(log, link(c, bs, p, testMain)) fout := c.output.TestBin(p.path) img := bs.Bytes() _, err := fout.Write(img) lex8.LogError(log, err) lex8.LogError(log, fout.Close()) if es := log.Errs(); es != nil { return es } runTests(log, tests, img, c.Options) if es := log.Errs(); es != nil { return es } } } return nil }
func (b *Builder) buildMain(p *pkg) []*lex8.Error { lib := p.pkg.Lib main := p.pkg.Main if main == "" || !lib.HasFunc(main) { return nil } log := lex8.NewErrorList() fout := b.output.Bin(p.path) lex8.LogError(log, b.link(fout, p, main)) lex8.LogError(log, fout.Close()) return log.Errs() }
func buildMain(c *context, p *pkg) []*lex8.Error { lib := p.pkg.Lib main := p.pkg.Main if main == "" || !lib.HasFunc(main) { return nil } log := lex8.NewErrorList() fout := c.output.Bin(p.path) lex8.LogError(log, link(c, fout, p, main)) lex8.LogError(log, fout.Close()) return log.Errs() }
// CheckRect checks if a program is within a rectangular area. func CheckRect(file string, r io.Reader, h, w int) []*lex8.Error { br := bufio.NewReader(r) row := 0 col := 0 errs := lex8.NewErrorList() pos := func() *lex8.Pos { return &lex8.Pos{file, row + 1, col + 1} } newLine := func() { if col > w { errs.Errorf(pos(), "line too wide") } row++ col = 0 } for { r, _, e := br.ReadRune() if e == io.EOF { if col > 0 { newLine() } break } else if lex8.LogError(errs, e) { break } if r == '\n' { newLine() } else { col += runeWidth(r) } } if row > h { errs.Errorf(pos(), "too many lines") } return errs.Errs() }
func runTests( log lex8.Logger, tests map[string]uint32, img []byte, verbose bool, ) { report := func(name string, pass bool, err error) { if !pass { lex8.LogError(log, fmt.Errorf("%s failed: got %s", name, err)) if verbose { fmt.Println("FAILED") } return } if verbose { fmt.Println("pass") } } var testNames []string for name := range tests { testNames = append(testNames, name) } sort.Strings(testNames) for _, test := range testNames { if verbose { fmt.Printf(" - %s: ", test) } arg := tests[test] _, err := arch8.RunImageArg(img, arg) if strings.HasPrefix(test, "TestBad") { report(test, arch8.IsPanic(err), err) } else { report(test, arch8.IsHalt(err), err) } } }
func runTests( log lex8.Logger, tests map[string]uint32, img []byte, opt *Options, ) { logln := func(s string) { if opt.LogLine == nil { fmt.Println(s) } else { opt.LogLine(s) } } // TODO(h8liu): this reporting should go with JSON for better formatting. report := func( name string, ncycle int, pass bool, m *arch8.Machine, err error, ) { if pass { if opt.Verbose { logln(fmt.Sprintf( " - %s: passed (%s)", name, cycleStr(ncycle), )) } return } if err == nil { err = errTimeOut } lex8.LogError(log, fmt.Errorf("%s failed: got %s", name, err)) if opt.Verbose { logln(fmt.Sprintf( " - %s: FAILED (%s, got %s)", name, cycleStr(ncycle), err, )) // TODO(h8liu): this is too ugly here... excep, ok := err.(*arch8.CoreExcep) if !arch8.IsHalt(err) && ok { stackTrace := new(bytes.Buffer) arch8.FprintStack(stackTrace, m, excep) logln(stackTrace.String()) } } } var testNames []string for name := range tests { testNames = append(testNames, name) } sort.Strings(testNames) for _, test := range testNames { arg := tests[test] m := arch8.NewMachine(&arch8.Config{ BootArg: arg, }) if err := m.LoadImageBytes(img); err != nil { report(test, 0, false, m, err) continue } var err error n, excep := m.Run(opt.TestCycles) if excep == nil { err = errTimeOut } else { err = excep } if strings.HasPrefix(test, "TestBad") { report(test, n, arch8.IsPanic(err), m, err) } else { report(test, n, arch8.IsHalt(err), m, err) } } }