Files
SirRoboGarage/common_libs/test_framework/battle_result.nim
T
SirStone 57a1915b10 feat: add shared integration test framework for garages (#126)
Implements:
- BattleResult type and JSON-lines parser (#127)
- TR server lifecycle manager (#128)
- Bot compiler using nim c (#129)
- runBattle() orchestrator (#130)
- Example test in OscillatorBot_garage (#131)
- Framework usage guide (#132)
- TestBattleRunner.java for external server (#133)
- BattleRunner process lifecycle (#134)

Fix: runner_process.nim was redefining TimeoutError locally; now
uses std/net.TimeoutError consistently with server_manager.nim.
2026-08-30 12:03:35 +02:00

83 lines
2.8 KiB
Nim

import std/[json, strutils, sequtils]
type
BotRoundResult* = object
name*: string
score*: int
rank*: int
survived*: bool
RoundResult* = object
round*: int
results*: seq[BotRoundResult]
BotResult* = object
name*: string
totalScore*: int
rank*: int
firstPlaces*: int
survivalCount*: int
BattleResult* = object
bots*: seq[string]
rounds*: seq[RoundResult]
results*: seq[BotResult]
winners*: seq[string] # bots with rank == 1
proc parseServerOutput*(stdout: string): BattleResult =
for line in stdout.splitLines():
let s = line.strip()
if s.len == 0 or s[0] != '{': continue
let node = parseJson(s)
case node["event"].getStr()
of "game_started":
result.bots = node["bots"].getElems().mapIt(it.getStr())
of "round_ended":
var rr = RoundResult(round: node["round"].getInt())
for r in node["results"].getElems():
rr.results.add BotRoundResult(
name: r["name"].getStr(),
score: r["score"].getInt(),
rank: r["rank"].getInt(),
survived: r["survived"].getBool()
)
result.rounds.add rr
of "battle_ended":
for r in node["results"].getElems():
result.results.add BotResult(
name: r["name"].getStr(),
totalScore: r["totalScore"].getInt(),
rank: r["rank"].getInt(),
firstPlaces: r["firstPlaces"].getInt(),
survivalCount: r["survivalCount"].getInt()
)
result.winners = result.results.filterIt(it.rank == 1).mapIt(it.name)
else: discard
when isMainModule:
const sample = """
{"event":"game_started","bots":["Alpha","Beta"]}
{"event":"round_ended","round":1,"results":[{"name":"Alpha","score":150,"rank":1,"survived":true},{"name":"Beta","score":80,"rank":2,"survived":false}]}
{"event":"round_ended","round":2,"results":[{"name":"Beta","score":200,"rank":1,"survived":true},{"name":"Alpha","score":60,"rank":2,"survived":false}]}
{"event":"battle_ended","results":[{"name":"Alpha","totalScore":500,"rank":1,"firstPlaces":3,"survivalCount":5},{"name":"Beta","totalScore":300,"rank":2,"firstPlaces":1,"survivalCount":2}]}
not json, should be ignored
"""
let br = parseServerOutput(sample)
assert br.bots == @["Alpha", "Beta"]
assert br.rounds.len == 2
assert br.rounds[0].round == 1
assert br.rounds[0].results[0].name == "Alpha"
assert br.rounds[0].results[0].score == 150
assert br.rounds[0].results[0].rank == 1
assert br.rounds[0].results[0].survived == true
assert br.rounds[1].results[0].name == "Beta"
assert br.rounds[1].results[1].survived == false
assert br.results.len == 2
assert br.results[0].name == "Alpha"
assert br.results[0].totalScore == 500
assert br.results[0].firstPlaces == 3
assert br.results[0].survivalCount == 5
assert br.winners == @["Alpha"]
echo "all assertions passed"