mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2024-05-20 13:48:02 -04:00
85adbca367
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
189 lines
4 KiB
Go
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())
|
|
}
|
|
}
|