WIP: restore lost C behaviors (schtick message, forced redraw, greeting)
Incomplete checkpoint, preserved after the implementing session hit a capacity limit partway through mutation verification. NOT reviewed and NOT gate-clean: make fmt has not been run, so fmt-check currently fails on ARCHITECTURE.md and TODO.md. Work still outstanding before this is fit for review: - run make fmt and fold the result in - finish mutation-proving each of the three behaviors - verify every message string byte-for-byte against the C sources - confirm TestSeedCompatItemTables passes with its golden untouched Refs #13.
This commit is contained in:
@@ -40,6 +40,13 @@ func run() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// C printed its greeting just before initscr(); here that means just
|
||||
// before the tcell screen takes the terminal, and on stdout, exactly
|
||||
// as C did (main.c main).
|
||||
if digsNewDungeon(*deathDemo, flag.Args()) {
|
||||
fmt.Print(game.Greeting(params))
|
||||
}
|
||||
|
||||
t, err := term.New()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
@@ -87,6 +94,23 @@ func run() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// digsNewDungeon reports whether this invocation is the one that digs a
|
||||
// fresh dungeon, and so the only one that greets.
|
||||
//
|
||||
// C's printf is the last statement before initscr(), and everything that
|
||||
// does something else has already left by then: -s scores and exits, -d
|
||||
// runs the death demo and exits, and restore() — the argc == 2 case that
|
||||
// is neither — never returns. So a saved game resumes without a greeting,
|
||||
// which is right: nothing is being dug.
|
||||
//
|
||||
// The restore test is duplicated from run's own, deliberately. Keeping
|
||||
// them as one predicate would mean deciding the startup path before the
|
||||
// terminal exists and carrying it past the error returns, which is more
|
||||
// rearrangement of run than a greeting is worth.
|
||||
func digsNewDungeon(deathDemo bool, args []string) bool {
|
||||
return !deathDemo && len(args) != 1
|
||||
}
|
||||
|
||||
// loadParams gathers the game parameters from the environment: home
|
||||
// directory, ROGUEOPTS, user name, wizard mode, and the dungeon seed
|
||||
// (main.c's startup).
|
||||
|
||||
@@ -380,3 +380,40 @@ func (s *stuckSaver) AutoSaveOnSignal(time.Duration) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// TestDigsNewDungeon pins which invocations reach C's greeting. In main.c
|
||||
// the printf is the last statement before initscr(), so -s and -d, which
|
||||
// exit earlier, never see it, and neither does a restored game, because
|
||||
// restore() does not return. The saved-game case is the one worth having
|
||||
// a test for: resuming a dungeon must not announce that one is being dug.
|
||||
func TestDigsNewDungeon(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
deathDemo bool
|
||||
args []string
|
||||
want bool
|
||||
}{
|
||||
{name: "new game", args: nil, want: true},
|
||||
{name: "restore a save", args: []string{"rogue.save"}, want: false},
|
||||
{name: "death demo", deathDemo: true, want: false},
|
||||
{
|
||||
name: "death demo wins over a save argument",
|
||||
deathDemo: true,
|
||||
args: []string{"rogue.save"},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if got := digsNewDungeon(tc.deathDemo, tc.args); got != tc.want {
|
||||
t.Errorf("digsNewDungeon(%v, %v) = %v, want %v",
|
||||
tc.deathDemo, tc.args, got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user