monop-state/cardinal-plugin/test_plugin.py
Jarvis 2b022f15c3 Add Cardinal plugin for monop state tracking
- Watches channel messages via @event('irc.privmsg')
- Feeds to MonopParser, writes game-state.json on state change
- Commands: .monop [status|players|board|owned]
- Bundled monop_parser.py in plugin dir
- Standalone test passes
2026-02-21 03:54:59 +00:00

109 lines
3.2 KiB
Python

"""Quick smoke test for the monop Cardinal plugin without running Cardinal."""
import sys
import os
import json
import tempfile
# Mock cardinal module before importing plugin
import types
cardinal_mod = types.ModuleType('cardinal')
cardinal_dec = types.ModuleType('cardinal.decorators')
def _passthrough(*args, **kwargs):
def wrap(f): return f
return wrap
cardinal_dec.command = _passthrough
cardinal_dec.event = _passthrough
cardinal_dec.help = _passthrough
cardinal_mod.decorators = cardinal_dec
sys.modules['cardinal'] = cardinal_mod
sys.modules['cardinal.decorators'] = cardinal_dec
sys.path.insert(0, os.path.dirname(__file__))
# Minimal mock of cardinal
class MockCardinal:
storage_path = tempfile.mkdtemp()
def get_db(self, name): pass
def sendMsg(self, channel, msg): print(f" [{channel}] {msg}")
class MockUser:
def __init__(self, nick):
self.nick = nick
# Import plugin
from monop import plugin as monop_plugin
# Instantiate
cardinal = MockCardinal()
config = {"bot_nick": "monop", "channels": ["#monop"]}
p = monop_plugin.MonopPlugin(cardinal, config)
# Simulate a game
messages = [
("monop", "How many players?"),
("alice", ".3"),
("monop", "Player 1, say ''me'' please."),
("alice", ".me"),
("monop", "Player 2, say ''me'' please."),
("bob", ".me"),
("monop", "Player 3, say ''me'' please."),
("charlie", ".me"),
("monop", "alice (1) rolls 8"),
("monop", "bob (2) rolls 5"),
("monop", "charlie (3) rolls 6"),
("monop", "alice (1) goes first"),
("monop", "alice (1) (cash $1500) on === GO ==="),
("monop", "-- Command: "),
("alice", "."),
("monop", "roll is 3, 4"),
("monop", "That puts you on Chance i"),
("monop", "bob (2) (cash $1500) on === GO ==="),
("monop", "-- Command: "),
("bob", "."),
("monop", "roll is 2, 4"),
("monop", "That puts you on Oriental ave. (L)"),
("monop", "That would cost $100"),
("monop", "Do you want to buy?"),
("bob", ".y"),
("monop", "charlie (3) (cash $1500) on === GO ==="),
("monop", "-- Command: "),
]
print("=== Feeding messages ===")
for sender, msg in messages:
user = MockUser(sender)
p.on_msg(cardinal, user, "#monop", msg)
# Check state
print("\n=== State ===")
state = p.parser.get_state()
if state:
print(f"Players: {len(state['players'])}")
for pl in state['players']:
print(f" {pl['name']} (${pl['money']}) at sq {pl['location']}")
# Check bob owns Oriental
for sq in state['squares']:
if sq.get('owner'):
print(f" Owned: {sq['name']} by player {sq['owner']}")
print(f"\n=== .monop status ===")
p.monop_cmd(cardinal, MockUser("test"), "#monop", ".monop")
print(f"\n=== .monop players ===")
p.monop_cmd(cardinal, MockUser("test"), "#monop", ".monop players")
print(f"\n=== .monop owned ===")
p.monop_cmd(cardinal, MockUser("test"), "#monop", ".monop owned")
else:
print("No state!")
# Check file was written
if os.path.exists(p.state_path):
with open(p.state_path) as f:
saved = json.load(f)
print(f"\n=== State file written: {p.state_path} ===")
print(f"Players: {len(saved['players'])}, Squares: {len(saved['squares'])}")
print("PASS")
else:
print("FAIL: state file not written")