Gopher2600/debugger/debugger_test.go
steve f39d1d33e3 o debugger
- removed REFLECT ON/OFF system
    - the performance hit is not that great

o cpu
    - added backward branching test
    - added branching page fault test

o debugger_test
    - increased timeout for rcvOutput()
2020-01-05 18:58:42 +00:00

164 lines
3 KiB
Go

package debugger_test
import (
"fmt"
"gopher2600/cartridgeloader"
"gopher2600/debugger"
"gopher2600/debugger/terminal"
"gopher2600/gui"
"gopher2600/television"
"testing"
"time"
)
type mockTV struct{}
type mockGUI struct{}
func (t *mockTV) String() string {
return ""
}
func (t *mockTV) Reset() error {
return nil
}
func (t *mockTV) AddPixelRenderer(_ television.PixelRenderer) {
}
func (t *mockTV) AddAudioMixer(_ television.AudioMixer) {
}
func (t *mockTV) Signal(_ television.SignalAttributes) error {
return nil
}
func (t *mockTV) GetState(_ television.StateReq) (int, error) {
return 0, nil
}
func (t *mockTV) GetSpec() *television.Specification {
return television.SpecNTSC
}
func (t *mockTV) IsStable() bool {
return true
}
func (t *mockTV) End() error {
return nil
}
func (g *mockGUI) SetMetaPixel(_ gui.MetaPixel) error {
return nil
}
func (g *mockGUI) IsVisible() bool {
return false
}
func (g *mockGUI) SetFeature(request gui.FeatureReq, args ...interface{}) error {
return nil
}
func (g *mockGUI) SetEventChannel(_ chan (gui.Event)) {
}
type mockTerm struct {
t *testing.T
inp chan string
out chan string
output []string
}
func newMockTerm(t *testing.T) *mockTerm {
trm := &mockTerm{
t: t,
inp: make(chan string),
out: make(chan string, 100),
}
return trm
}
func (trm *mockTerm) Initialise() error {
return nil
}
func (trm *mockTerm) CleanUp() {
}
func (trm *mockTerm) RegisterTabCompletion(_ terminal.TabCompletion) {
}
func (trm *mockTerm) Silence(silenced bool) {
}
func (trm *mockTerm) TermRead(buffer []byte, prompt terminal.Prompt, eventChannel chan gui.Event, eventHandler func(gui.Event) error) (int, error) {
s := <-trm.inp
copy(buffer, []byte(s))
return len(s) + 1, nil
}
func (trm *mockTerm) IsInteractive() bool {
return false
}
func (trm *mockTerm) TermPrint(sty terminal.Style, s string, a ...interface{}) {
trm.out <- fmt.Sprintf(s, a...)
}
func (trm *mockTerm) sndInput(s string) {
trm.output = make([]string, 0)
trm.inp <- s
}
func (trm *mockTerm) rcvOutput() {
empty := false
for !empty {
select {
case s := <-trm.out:
trm.output = append(trm.output, s)
// the amount of output sent by the debugger is unpredictable so a
// timeout is necessary. a matter of milliseconds should be sufficient
case <-time.After(10 * time.Millisecond):
empty = true
}
}
}
func (trm *mockTerm) prtOutput() {
trm.rcvOutput()
fmt.Println(trm.output)
}
func (trm *mockTerm) cmpOutput(s string) bool {
trm.rcvOutput()
if len(trm.output) == 0 || trm.output[len(trm.output)-1] == s {
return true
}
trm.t.Errorf(fmt.Sprintf("unexpected debugger output (%s)", trm.output))
return false
}
func (trm *mockTerm) testSequence() {
defer func() { trm.sndInput("QUIT") }()
trm.testBreakpoints()
}
func TestDebugger(t *testing.T) {
trm := newMockTerm(t)
dbg, err := debugger.NewDebugger(&mockTV{}, &mockGUI{}, trm)
if err != nil {
t.Fatalf(err.Error())
}
go trm.testSequence()
err = dbg.Start("", cartridgeloader.Loader{})
if err != nil {
t.Fatalf(err.Error())
}
}