Gopher2600/debugger/debugger_test.go
JetSetIlly 85adbca367 improved gopher2600.go structure
removed modalflags package. modalflags was added very early in the
project. it's neater and simpler to implement command-line modes with
the standard flag package directly

improved log message for unsupported terminal type

remove rand.Seed(time) on startup. rand.Seed() is a deprecated function
2023-11-19 20:16:17 +00:00

189 lines
4 KiB
Go

// This file is part of Gopher2600.
//
// Gopher2600 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Gopher2600 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Gopher2600. If not, see <https://www.gnu.org/licenses/>.
package debugger_test
import (
"fmt"
"testing"
"time"
"github.com/jetsetilly/gopher2600/debugger"
"github.com/jetsetilly/gopher2600/debugger/terminal"
"github.com/jetsetilly/gopher2600/gui"
"github.com/jetsetilly/gopher2600/prefs"
)
type mockGUI struct{}
func (g *mockGUI) SetFeature(request gui.FeatureReq, args ...gui.FeatureReqData) error {
return nil
}
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, _ terminal.Prompt, _ *terminal.ReadEvents) (int, error) {
s := <-trm.inp
copy(buffer, s)
return len(s) + 1, nil
}
func (trm *mockTerm) TermReadCheck() bool {
return false
}
func (trm *mockTerm) IsInteractive() bool {
return false
}
func (trm *mockTerm) IsRealTerminal() bool {
return false
}
func (trm *mockTerm) TermPrintLine(sty terminal.Style, s string) {
if sty == terminal.StyleEcho {
return
}
trm.out <- s
}
func (trm *mockTerm) sndInput(s string) {
trm.output = make([]string, 0, 10)
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
}
}
}
// cmpOutput compares the string argument with the *last line* of the most
// recent output. it can easily be adapted to compare the whole output if
// necessary.
func (trm *mockTerm) cmpOutput(s string) {
trm.rcvOutput()
if len(trm.output) == 0 {
if len(s) != 0 {
trm.t.Errorf(fmt.Sprintf("unexpected debugger output (nothing) should be (%s)", s))
return
}
return
}
l := len(trm.output) - 1
if trm.output[l] == s {
return
}
trm.t.Errorf(fmt.Sprintf("unexpected debugger output (%s) should be (%s)", trm.output[l], s))
}
func (trm *mockTerm) testSequence() {
defer func() { trm.sndInput("QUIT") }()
trm.testBreakpoints()
trm.testTraps()
trm.testWatches()
}
func TestDebugger_withNonExistantInitScript(t *testing.T) {
prefs.DisableSaving = true
var trm *mockTerm
create := func(dbg *debugger.Debugger) (gui.GUI, terminal.Terminal, error) {
trm = newMockTerm(t)
return &mockGUI{}, trm, nil
}
var opts debugger.CommandLineOptions
dbg, err := debugger.NewDebugger(opts, create)
if err != nil {
t.Fatalf(err.Error())
}
go trm.testSequence()
err = dbg.StartInDebugMode("")
if err != nil {
t.Fatalf(err.Error())
}
}
func TestDebugger(t *testing.T) {
prefs.DisableSaving = true
var trm *mockTerm
create := func(dbg *debugger.Debugger) (gui.GUI, terminal.Terminal, error) {
trm = newMockTerm(t)
return &mockGUI{}, trm, nil
}
var opts debugger.CommandLineOptions
dbg, err := debugger.NewDebugger(opts, create)
if err != nil {
t.Fatalf(err.Error())
}
go trm.testSequence()
err = dbg.StartInDebugMode("")
if err != nil {
t.Fatalf(err.Error())
}
}