feat: Introduce Bats testing framework and helpers
This commit is contained in:
parent
33697e9b82
commit
e531135bf3
2 changed files with 154 additions and 0 deletions
56
tests/README.md
Normal file
56
tests/README.md
Normal file
|
|
@ -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).
|
||||||
98
tests/helpers.bash
Normal file
98
tests/helpers.bash
Normal file
|
|
@ -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}"
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue