Files
test-samurai.nvim/runner-agents.md

5.7 KiB

runner-agents.md — test-samurai Runner-API

Ziel: Diese Datei beschreibt die öffentliche Runner-API, die ein neuer Runner implementieren muss, damit alle Commands vollständig unterstützt werden.

Modulform (Pflicht)

  • Der Runner ist ein Lua-Modul, das eine Table mit Funktionen zurückgibt.
  • Beispiel:
    • local runner = {}
    • return runner
  • Der Modulpfad in runner_modules muss exakt zum Dateipfad unter lua/ passen.
    • Beispiel: lua/test-samurai-go-runner/init.lua -> require("test-samurai-go-runner").
    • lua/init.lua wäre require("init") und ist kollisionsanfällig; vermeiden.

Pflichtfunktionen (volle Command-Unterstützung)

  • is_test_file(bufnr) -> boolean
    • Wird für die Runner-Auswahl genutzt.
  • find_nearest(bufnr, row, col) -> spec|nil, err?
    • Für TSamNearest.
    • spec.file muss gesetzt sein.
    • Bei Fehler/kein Treffer: nil, "reason" zurückgeben.
  • build_command(spec) -> command_spec
    • Für TSamNearest.
  • build_file_command(bufnr) -> command_spec
    • Für TSamFile.
  • build_all_command(bufnr) -> command_spec
    • Für TSamAll.
  • build_failed_command(last_command, failures, scope_kind) -> command_spec
    • Für TSamFailedOnly.

Output-Parsing (Listing + Summary)

Genau eine der folgenden Varianten muss vorhanden sein:

  • parse_results(output) -> results
    • results muss enthalten:
      • passes (Array von Namen)
      • failures (Array von Namen)
      • skips (Array von Namen)
    • Optional:
      • display = { passes = {}, failures = {}, skips = {} }
      • failures_all (für Streaming-Parser, um alle bisherigen Failures zu liefern)
    • Wenn display fehlt, werden passes/failures/skips direkt im Listing angezeigt.
  • oder output_parser() -> { on_line, on_complete }
    • on_line(line, state) kann results liefern (siehe oben).
    • on_complete(output, state) kann results liefern (siehe oben).

Listing-Gruppierung fuer Parent/Subtests

  • Wenn Testnamen das Format Parent/Subtest oder verschachtelt Parent/Sub/Subtest haben und der Parent ebenfalls in den Ergebnissen vorhanden ist, gruppiert das Listing:
    • Parent kommt vor seinen direkten Kindern.
    • Mehrstufige Subtests werden hierarchisch gruppiert (Parent -> Kind -> Enkel).
    • Die Reihenfolge der Kinder folgt der Eingangsreihenfolge des Runners.
    • Ohne Parent-Eintrag bleibt die normale Reihenfolge erhalten.

Detail-Output (TSamShowOutput / im Listing)

  • parse_test_output(output) -> table
    • Rückgabeform:
      • { [test_name] = { "line1", "line2", ... } }
    • test_name muss mit results.* korrespondieren (gleiches Namensschema).

Quickfix-Unterstützung (Failures)

  • collect_failed_locations(failures, command, scope_kind) -> items
    • items: Array von Quickfix-Items
      • { filename = "...", lnum = <number>, col = <number>, text = "..." }

Erwartete Datenformen

  • command_spec:
    • { cmd = { "binary", "arg1", ... }, cwd = "..." }
    • cmd darf nicht leer sein.
    • cwd ist optional; wenn nicht gesetzt, nutzt der Core das aktuelle CWD.
  • spec (von find_nearest):
    • Muss mindestens file enthalten, z. B.:
      • { file = "...", cwd = "...", test_name = "...", full_name = "...", kind = "..." }

Optional empfohlene Metadaten

  • name (String)
    • Wird in Fehlermeldungen und Logs angezeigt.
  • framework (String)
    • Wird zur Framework-Auswahl (z. B. JS) genutzt.

Prompt-Beispiel

"Erstelle mir anhand der runner-agents.md einen neuen Runner für Rust."

Minimaler Runner-Skeleton (Template)

local runner = {
  name = "my-runner",
  framework = "my-framework",
}

function runner.is_test_file(bufnr)
  return false
end

function runner.find_nearest(bufnr, row, col)
  return nil, "no test call found"
end

function runner.build_command(spec)
  return { cmd = { "echo", "not-implemented" }, cwd = spec.cwd }
end

function runner.build_file_command(bufnr)
  return { cmd = { "echo", "not-implemented" } }
end

function runner.build_all_command(bufnr)
  return { cmd = { "echo", "not-implemented" } }
end

function runner.build_failed_command(last_command, failures, scope_kind)
  return { cmd = { "echo", "not-implemented" }, cwd = last_command and last_command.cwd or nil }
end

function runner.parse_results(output)
  return { passes = {}, failures = {}, skips = {}, display = { passes = {}, failures = {}, skips = {} } }
end

function runner.parse_test_output(output)
  return {}
end

function runner.collect_failed_locations(failures, command, scope_kind)
  return {}
end

return runner

Checkliste für neue Runner

  • is_test_file implementiert
  • find_nearest implementiert (setzt spec.file)
  • build_command implementiert
  • build_file_command implementiert
  • build_all_command implementiert
  • build_failed_command implementiert
  • parse_results oder output_parser implementiert
  • parse_test_output implementiert
  • collect_failed_locations implementiert
  • command_spec { cmd, cwd } korrekt zurückgegeben

Projekt- und Prozessanforderungen

  • Eine englischsprachige README.md ist zu erstellen.
    • Sie muss bei jedem weiteren Prompt aktualisiert werden, wenn die Aenderungen es erfordern.
  • TDD-Vorgaben (aus AGENTS.md) uebernehmen:
    • Neue Funktionen/Commands/Verhaltensaenderungen muessen getestet werden.
    • Tests nach jeder Code-Aenderung ausfuehren.
    • Im Runner erstellter Quellcode ist ebenfalls zu testen.
    • Eine eigene run_test.sh darf im Runner-Repo angelegt werden.
  • Eine Gitea-Action ist zu erstellen, die bei jedem Push die Tests ausfuehrt.
    • Beispiel (anpassbarer Workflow):
name: tests

on:
  push:
    branches:
      - "**"

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Run tests
        run: bash run_test.sh