package casino import "testing" type testWallet struct { chips, credits, paid int } func (w *testWallet) Wager(amount int) (Wager, bool) { if w.chips+w.credits < amount { return Wager{}, false } chips := amount if chips > w.chips { chips = w.chips } w.chips -= chips credits := amount - chips w.credits -= credits return Wager{Total: amount, Chips: chips, Credits: credits}, true } func (w *testWallet) PayCredits(amount int) { w.paid += amount } func TestMixedWagerUsesChipsFirst(t *testing.T) { w := &testWallet{chips: 7, credits: 50} wager, ok := w.Wager(12) if !ok || wager.Chips != 7 || wager.Credits != 5 || w.chips != 0 || w.credits != 45 { t.Fatalf("unexpected wager: %+v wallet=%+v", wager, w) } } func TestSoloBetResolvesImmediately(t *testing.T) { m := NewManager(1) cfg := TableConfig{ID: "slots", Game: GameSlots} m.Join(1, cfg, "alice") w := &testWallet{credits: 100} events := m.Bet(1, "slots", "alice", 10, w) found := false for _, event := range events { if event.Type == EventRoundStarted { found = true } } if !found { t.Fatal("solo bet did not resolve immediately") } } func TestMultiplePlayersWaitForBets(t *testing.T) { m := NewManager(1) cfg := TableConfig{ID: "slots", Game: GameSlots, BettingTicks: 2} m.Join(1, cfg, "alice") m.Join(1, cfg, "bob") wa, wb := &testWallet{credits: 100}, &testWallet{credits: 100} events := m.Bet(1, "slots", "alice", 10, wa) for _, event := range events { if event.Type == EventRoundStarted { t.Fatal("round started before all players bet or timeout") } } m.Bet(1, "slots", "bob", 10, wb) } func TestMachineAutobetCountdownAndStop(t *testing.T) { m := NewManager(1) cfg := MachineConfig{ID: "slots", Game: GameSlots, SpinTicks: 1} m.JoinMachine(1, cfg, "alice") m.SetMachineBet(1, "slots", "alice", 10) w := &testWallet{credits: 100} if events := m.EnableMachineAutoBet(1, "slots", "alice", w); len(events) != 0 { t.Fatalf("enabling autobet emitted events before countdown: %+v", events) } for i, want := range []string{"Autobet enabled!", `Type "stop" to stop playing`, "Betting... 10 credits."} { events := m.Tick() if len(events) == 0 || eventText(events) != want { t.Fatalf("tick %d message=%q events=%+v, want %q", i+1, eventText(events), events, want) } } if !m.MachineBusy("alice") { t.Fatal("autobet did not start a spin after countdown") } if events, stopped := m.StopMachineAutoBet(1, "slots", "alice"); !stopped || len(events) != 1 { t.Fatalf("stop autobet events=%+v stopped=%v", events, stopped) } if _, playing := m.MachineFor("alice"); !playing { t.Fatal("stopping autobet removed the player from the machine") } } func eventText(events []Event) string { for _, event := range events { if event.PrivateMessage != "" { return event.PrivateMessage } if event.Message != "" { return event.Message } } return "" }