From e531135bf3e1eea9d5a87eac8019047165e2eb30 Mon Sep 17 00:00:00 2001 From: Matteo Cherubini Date: Thu, 4 Jun 2026 10:59:08 +0200 Subject: [PATCH] feat: Introduce Bats testing framework and helpers --- tests/README.md | 56 ++++++++++++++++++++++++++ tests/helpers.bash | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 tests/README.md create mode 100644 tests/helpers.bash diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..669ff41 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,56 @@ +# Tests + +Deterministic tests for the mechanical layer of the framework — **no LLM, no GPU, no +network**. They simulate pi's output with fixtures and exercise the scripts directly, so +they run anywhere (laptop, CI, a git hook). They do **not** belong on vm101 or in n8n. + +## What's covered + +| File | Covers | +|------|--------| +| `scripts.bats` | `slug.sh`, `log-append.sh`, `index-append.py` (insert, sort, bump, idempotent) | +| `lint.bats` | `lib/lint.sh` validators + `scoped-lint.sh` reuse | +| `structure.bats` | `lib/structure.sh` report/sync | +| `run-ingest.bats` | `run-ingest.sh` end-to-end (DRY_RUN, local bare remote) — needs `jq` | + +`run-ingest.bats` auto-`skip`s if `jq` is missing; everything else needs only bash + git +(+ `python3` for the index tests). + +## Install bats + +```bash +# Debian/Ubuntu +sudo apt install bats +# or pinned, as a vendored submodule +git submodule add https://github.com/bats-core/bats-core.git test/bats +``` + +## Run + +```bash +bats tests/ # whole suite +bats tests/lint.bats # one file +bats -f "sorted" tests/scripts.bats # filter by name +``` + +Each test builds its own throwaway genome under `BATS_TEST_TMPDIR` (auto-cleaned) with a +local bare git remote, so `open-pr.sh --DRY_RUN` can branch/commit/push without touching +Forgejo. + +## Makefile targets + +```make +test: + @bats tests/ + +verify-structure: + @bash scripts/verify-genomes.sh + +sync-structure: + @bash scripts/verify-genomes.sh --sync +``` + +## Note on `helpers.bash` + +`FIXTURE_DIRS` in `helpers.bash` must match `GENOME_DIRS` in `lib/structure.sh`. If you +change the canonical layout, update both (the structure tests assume a clean baseline). diff --git a/tests/helpers.bash b/tests/helpers.bash new file mode 100644 index 0000000..1b31397 --- /dev/null +++ b/tests/helpers.bash @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +# tests/helpers.bash — shared helpers for the bats suite. + +REPO_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)" +LIB_DIR="${REPO_ROOT}/lib" +SKILL_SCRIPTS="${REPO_ROOT}/skills/ingest/scripts" + +# Canonical dirs a fresh genome must contain (kept in sync with lib/structure.sh). +FIXTURE_DIRS=( + raw/articles raw/transcripts raw/code-packs raw/assets raw/private + wiki/sources wiki/entities wiki/concepts wiki/queries wiki/private +) + +# make_fixture_genome → echoes the path to a throwaway genome checkout with a +# local bare remote, the full canonical structure, and rendered index/log. +# Uses BATS_TEST_TMPDIR so bats cleans it up automatically. +make_fixture_genome() { + local base; base="$(mktemp -d "${BATS_TEST_TMPDIR:-/tmp}/genome.XXXXXX")" + git init --bare -q "${base}/origin.git" + + local g="${base}/genome" + local d + for d in "${FIXTURE_DIRS[@]}"; do mkdir -p "${g}/${d}"; touch "${g}/${d}/.gitkeep"; done + + cat > "${g}/wiki/index.md" <<'EOF' +--- +title: "Index — genome-test" +type: index +domain: genome-test +maturity: stable +last_updated: 2026-01-01 +private: false +--- + +# Master Index: genome-test + +--- + +## Sources (`wiki/sources/`) +*Ingested raw materials.* + + +## Entities (`wiki/entities/`) +*People, tools.* + + +## Concepts (`wiki/concepts/`) +*Patterns.* + + +## Queries (`wiki/queries/`) +*Answers.* + + +## Conflicts Pending Review (`wiki/queries/conflict-*.md`) +*slugs only.* +EOF + + cat > "${g}/wiki/log.md" <<'EOF' +--- +title: "Operations Log — genome-test" +type: log +domain: genome-test +maturity: stable +last_updated: 2026-01-01 +private: false +--- + +# Operations Log + +--- + +## [2026-01-01] CONFIG | scaffolded +- run_id: `init` +EOF + + echo "raw test" > "${g}/raw/articles/test.md" + + mkdir -p "${base}/nohooks" + + ( + cd "${g}" + git init -q + # Hermetic: ignore the user's global git config (signing, global hooks); + # otherwise commit.gpgsign or a global core.hooksPath makes git commit fail here. + git config commit.gpgsign false + git config core.hooksPath "${base}/nohooks" + git config user.email t@t + git config user.name tester + git add . + git commit -qm init + git branch -M main + git remote add origin "${base}/origin.git" + git push -q -u origin main + ) >/dev/null + + echo "${g}" +}