Files
SirRoboGarage/AGENTS.md
T
SirStone 7e1f1483a4 docs(test_framework): add comprehensive integration test guide and fix runner blocking issue
- Document exception handling, zero-value BotResult trap, shared adversary bots
- Add offline parsing example using parseServerOutput
- Skip tests gracefully when JARs missing (guard before suite blocks)
- Fix blocking readLine in runner_process.nim: poll with 50ms sleep + atEnd check
  (was preventing timeout enforcement, now blocks correctly during battle)
- Add test task to QBot.nimble and config.nims setup docs to AGENTS.md
- Add debug logging to TestBattleRunner for bot identity tracking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-13 10:54:56 +02:00

123 lines
3.1 KiB
Markdown

## Agent skills
### Issue tracker
Gitea Issues at git.fossellini.top:SirStone/SirRoboGarage. See `docs/agents/issue-tracker.md`.
### Triage labels
Default label vocabulary. See `docs/agents/triage-labels.md`.
### Domain docs
Single-context layout. See `docs/agents/domain.md`.
### Folders
## SirGarage Directory Layout
**SirGarage** (root directory)
- `botname_garage/` — each bot gets its own directory following this pattern
- src/
- botname.nim
- botname.json
- botname.sh
- config.nim
- botname/ — bot-specific modules
- *.nim files
- tests/
- test*.nim files
- out/
- compiled binaries
- prototypes or spikes for this bot (not at root)
- docs/ — generic project documentation
- tools/ — generic tools valid for all bots (battle runners, scripts, etc.)
- common_libs/ — shared libraries valid for all bots
- worktrees/ — git worktrees (gitignored)
- AGENTS.md
- CONTEXT.md
- README.md
- .gitignore
## How to use
- These indications are for files that are always present, for files not mentioned here should be claer from context where belongs too.
- Each bot development must be done in each folder in isolation.
- If the bot requires extra folders during runtime, these must be created by the bot itself if not present already.
### NIM
This repsoitory's main language is Nim, when you need to work with nim use the /nim mcp.
---
## Writing tests for a bot
Framework lives at `common_libs/test_framework/`. Full docs: `common_libs/test_framework/README.md`.
### One-liner
```nim
import test_framework/test_framework
let r = runBattle(@[myBotDir, adversaryDir], rounds = 10)
```
`runBattle` blocks, returns `BattleResult`, raises on failure.
### Types
```
BattleResult → bots, rounds: seq[RoundResult], results: seq[BotResult], winners: seq[string]
BotResult → name, totalScore, rank, firstPlaces, survivalCount
RoundResult → round, results: seq[BotRoundResult]
BotRoundResult→ name, score, rank, survived
```
### Shared adversaries
```nim
const tfAdversaries = currentSourcePath().parentDir.parentDir.parentDir /
"common_libs" / "test_framework" / "adversaries"
const sittingDuck = tfAdversaries / "SittingDuck" # passive — does nothing
const oscillator = tfAdversaries / "OscillatorBot" # fights back
```
### Setup (once per garage)
**`tests/config.nims`**
```nim
--path:"../../common_libs" # adjust depth to match garage location in repo
```
**`YourBot.nimble`** test task:
```nim
task test, "Run integration tests":
exec "nim c -r --path:../common_libs tests/test_basic_battle.nim"
```
### Skip when JARs are absent (put before any suite block)
```nim
import std/os
if not existsEnv("TR_SERVER_JAR") or not existsEnv("TR_BATTLE_RUNNER"):
echo "Skipping: TR_SERVER_JAR / TR_BATTLE_RUNNER not set"
quit(0)
```
### Offline parsing (no Java needed)
```nim
import test_framework/battle_result
let r = parseServerOutput(rawJsonLines)
```
### Exceptions
| Exception | Cause |
|---|---|
| `OSError` | Bot compilation failed |
| `IOError` | Battle runner exited non-zero |
| `TimeoutError` | Server startup (15s), compile (30s/bot), or battle runner timeout |