docs: centralise test counts + add release-policy + remove stale stub references

Two complementary improvements aimed at reducing recurring maintenance
overhead:

1. **Test-count centralisation** — `doc/api/tests.md` is now the
   single source of truth for the test counts.  All other docs
   (README, CLAUDE.md, doc/contributing.md, doc/getting-started.md,
   doc/math/validation.md, doc/math/validation-protocol.md,
   scripts/try_it.sh) use qualitative phrasing + a link instead of
   hardcoded numbers.  The previous regime had eight places with
   "227 CGAL tests, 23 non-CGAL tests" that drifted apart across
   releases (the v0.9.0 release-prep needed to touch nine files).

2. **Versioning policy** — `doc/release-policy.md` (new, ~250 lines)
   formalises:
   * SemVer rules for the pre-1.0 and post-1.0 phases.
   * Phase-milestone → MINOR-bump mapping (v0.10.0 → Phase 9c, …).
   * Single-source-of-truth table for moving numbers (test counts,
     version, date).
   * Step-by-step release process (the recipe that worked for v0.9.0
     after the false-start with PR #11/#12).
   * Hotfix policy + post-1.0 deprecation policy.
   * Known failure modes and how to recover from them.

Plus a small CI gate:

3. **scripts/check-test-counts.sh** — verifies the totals in
   doc/api/tests.md match `ctest` output.  Re-uses existing build-cgal/
   if present.  Exit 0 on match, 1 on divergence with recovery hints.
   Cheap enough (~30 s) to run on every PR.

Other cleanups
──────────────
* code/tests/cgal/CMakeLists.txt — stale "Test 7 (genus-2 homology)
  as GTEST_SKIP stub until Phase 8" comment removed; that test landed
  as HomologyGenerators.Genus2_FourCutEdges in Phase 7.
* CLAUDE.md — "test-fast also runs stubs" Known Quirks entry updated
  to reflect the v0.9.0 stub cleanup (no GTEST_SKIPs remain).
* CLAUDE.md doc map — new entry for doc/release-policy.md.

Stubs audit
───────────
Zero GTEST_SKIP() calls remain in the codebase as of this commit.
The only references to stubs are in historical documentation
(CHANGELOG.md v0.7.0 entry, doc/roadmap/* "deferred to research-track"
notes) — those are intended.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tarik Moussa
2026-05-22 07:59:10 +02:00
parent e67ccd6b9d
commit 0f78d181e1
10 changed files with 326 additions and 17 deletions

View File

@@ -244,7 +244,7 @@ Two jobs in `.gitea/workflows/cpp-tests.yml`:
Runner: `eulernest` — self-hosted Raspberry Pi, ARM64, Ubuntu 22.04. Docker image: `git.eulernest.eu/conformallab/ci-cpp:latest`. `test-cgal` needs `test-fast` to pass first (`needs: test-fast`).
Expected results: **23 non-CGAL tests pass**, **227 CGAL tests pass, 0 skipped**.
Expected results: full test suite passing, 0 skipped, 0 failed. The canonical counts live in `doc/api/tests.md` — do not hardcode them anywhere else (see [`doc/release-policy.md`](doc/release-policy.md)).
## Release state
@@ -349,7 +349,7 @@ follow the empirical verification rule above before any new claim.
| Full pipeline API for all three geometries | `doc/api/pipeline.md` |
| What does each processing unit require/provide (contracts)? | `doc/api/contracts.md` |
| How to add a new functional / geometry mode / port from Java | `doc/api/extending.md` |
| All 39 test suites, 227+23 tests, individual counts | `doc/api/tests.md` |
| Per-suite breakdown and counts (single source of truth) | `doc/api/tests.md` |
| Phase 8 CGAL package design + Declarative YAML pipeline spec | `doc/api/cgal-package.md` |
### Concepts & specs
@@ -373,6 +373,7 @@ follow the empirical verification rule above before any new claim.
| Build modes, single-test invocation, CLI, Docker image rebuild | `doc/getting-started.md` |
| Step-by-step: port the Inversive Distance functional (Phase 9a template) | `doc/tutorials/add-inversive-distance.md` |
| Language policy, test standards, release flow | `doc/contributing.md` |
| Versioning rules + release process + single-source-of-truth list | `doc/release-policy.md` |
### geometry-central context
@@ -386,7 +387,7 @@ Optional adoption roadmap (GC-1/2/3): `doc/roadmap/phases.md` (Optional section)
## Known quirks
- **`test-fast` also runs stubs**: `conformallab_tests` (non-CGAL) contains `GTEST_SKIP`-based stubs for functionals that need CGAL. This is intentional — those tests document what was in the Java port scope but requires the CGAL mesh type.
- **No GTEST_SKIP stubs remain** (since v0.9.0): the three stale HDS-port stub files were removed because the CGAL test suite covers the same functionality with real tests. The pure-math `conformallab_tests` target now only contains active tests.
- **Boost is header-only**: CGAL 6.x uses only Boost headers (`Boost.Config`, `Boost.Graph`). No compiled Boost libraries are needed. `find_package(Boost REQUIRED)` only locates the include path.
- **`main` branch is protected** on `origin` (Gitea). Push to `dev`, then merge via pull request. Codeberg `main` can be pushed to directly.
- **Both remotes must stay in sync**: `origin` = `git.eulernest.eu` (CI runs here), `codeberg` = `codeberg.org/TMoussa/ConformalLabpp` (public mirror). Push to both after every significant change.

View File

@@ -13,7 +13,7 @@ Algorithmic foundation:
> DOI: [10.14279/depositonce-5415](https://depositonce.tu-berlin.de/items/8e2988b2-d991-45b5-aad5-9fb7988f3b2f) · CC BY-SA 4.0 ·
> [Java original](https://github.com/varylab/conformallab) · [sechel.de](https://sechel.de/)
**Status:** v0.9.0 — Phases 19a complete, Phase 8b-Lite CGAL API surface. Newton solvers for **five** DCE models (Euclidean / Spherical / HyperIdeal / CP-Euclidean / Inversive-Distance), priority-BFS layout in ℝ²/S²/Poincaré disk, GaussBonnet, tree-cotree cut graph, Möbius holonomy, period matrix (genus 1), fundamental domain, halfedge_uv texture atlas, JSON/XML serialisation, CLI app. **227 CGAL tests + 23 non-CGAL tests, 0 skipped.**
**Status:** v0.9.0 — Phases 19a complete, Phase 8b-Lite CGAL API surface. Newton solvers for **five** DCE models (Euclidean / Spherical / HyperIdeal / CP-Euclidean / Inversive-Distance), priority-BFS layout in ℝ²/S²/Poincaré disk, GaussBonnet, tree-cotree cut graph, Möbius holonomy, period matrix (genus 1), fundamental domain, halfedge_uv texture atlas, JSON/XML serialisation, CLI app. Full test suite passing, 0 skipped — see [`doc/api/tests.md`](doc/api/tests.md) for the per-suite breakdown.
---
@@ -84,7 +84,7 @@ Layout2D layout = euclidean_layout(mesh, res.x, maps);
| **Getting started** — build modes, single-test invocation, CLI, Docker | [doc/getting-started.md](doc/getting-started.md) |
| **Pipeline API** — all three geometries, holonomy, serialisation | [doc/api/pipeline.md](doc/api/pipeline.md) |
| **Public headers** — all 24 headers with descriptions | [doc/api/headers.md](doc/api/headers.md) |
| **Test suites**39 suites, 227+23 tests, individual counts | [doc/api/tests.md](doc/api/tests.md) |
| **Test suites**per-suite breakdown and counts (single source of truth) | [doc/api/tests.md](doc/api/tests.md) |
| **Extending** — new functionals, geometry modes, porting from Java | [doc/api/extending.md](doc/api/extending.md) |
| **Processing unit contracts** — preconditions / provides table | [doc/api/contracts.md](doc/api/contracts.md) |
| **CGAL package design** — Phase 8 target, YAML pipeline | [doc/api/cgal-package.md](doc/api/cgal-package.md) |

View File

@@ -53,8 +53,9 @@ add_executable(conformallab_cgal_tests
# ── Java parity: geometry utility tests ──────────────────────────────────
# Ported from CuttinUtilityTest, UnwrapUtilityTest,
# ConvergenceUtilityTests, HomologyTest (tests 16).
# Test 7 (genus-2 homology) as GTEST_SKIP stub until Phase 8.
# ConvergenceUtilityTests, HomologyTest. All tests active —
# the v0.7.0 genus-2 homology stub was implemented in Phase 7
# (HomologyGenerators.Genus2_FourCutEdges, brezel2.obj).
test_geometry_utils.cpp
# ── Scalability smoke tests ────────────────────────────────────────────────

View File

@@ -29,8 +29,8 @@ Two jobs run on push to `dev`/`main` or on pull requests:
| Job | What it tests | Trigger |
|---|---|---|
| `test-fast` | 23 non-CGAL tests, no Boost | all branches |
| `test-cgal` | 227 CGAL tests, 0 skipped | `main`, `dev`, PRs only |
| `test-fast` | pure-math tests, no Boost | all branches |
| `test-cgal` | full CGAL test suite | `main`, `dev`, PRs only |
A PR is ready to merge when both jobs pass.
@@ -51,7 +51,7 @@ Every new algorithm needs:
3. **Registration** — add the `.cpp` file to `code/tests/cgal/CMakeLists.txt`.
Expected CI result: **23 + 227 tests pass, 0 skipped**.
Expected CI result: full test suite passing, 0 skipped (per-suite counts: [`doc/api/tests.md`](api/tests.md)).
---

View File

@@ -48,7 +48,7 @@ cmake --build build --target conformallab_tests -j$(nproc)
ctest --test-dir build --output-on-failure
```
Expected: **23 tests pass**.
Expected: all pure-math tests pass (count: [`doc/api/tests.md`](api/tests.md)).
### Mode 2 — CGAL tests, headless (recommended for CI and development)
@@ -60,7 +60,7 @@ cmake --build build --target conformallab_cgal_tests -j$(nproc)
ctest --test-dir build -R "^cgal\." --output-on-failure
```
Expected: **227 tests pass, 0 skipped**.
Expected: all CGAL tests pass, 0 skipped (count: [`doc/api/tests.md`](api/tests.md)).
### Mode 3 — Full local build (CLI app + interactive viewer)
@@ -146,7 +146,7 @@ sets x* = 0, so a small perturbation (-0.05) needs only one Newton step.
bash scripts/try_it.sh
```
This clones nothing (run from inside the repo), builds the CGAL test suite, runs
all 227+23 tests, and prints a summary. See `scripts/try_it.sh` for details.
the full test suite, and prints a summary. See `scripts/try_it.sh` for details.
---

View File

@@ -199,7 +199,7 @@ inner/outer edge lengths). Use `torus_8x8.off` for a finer approximation.
## Summary checklist
```
[ ] Check 0: 176 tests pass, 0 skipped
[ ] Check 0: full test suite passes, 0 skipped (counts: `doc/api/tests.md`)
[ ] Check 1: GaussBonnet exact (1e-10)
[ ] Check 2: FD gradient < 1e-6 for all 3 geometries
[ ] Check 3: Newton convergence < 50 iterations

View File

@@ -14,7 +14,7 @@ cmake --build build --target conformallab_cgal_tests
ctest --test-dir build -R cgal --output-on-failure
```
All 227 tests pass, 0 skipped (see `doc/api/tests.md`).
All tests pass, 0 skipped (per-suite breakdown: `doc/api/tests.md`).
---
@@ -252,7 +252,7 @@ implemented in conformallab++ (→ GC-2 in the phase roadmap).
Run these in order to validate the implementation:
- [ ] `ctest --test-dir build -R cgal --output-on-failure`227 tests pass, 0 skipped
- [ ] `ctest --test-dir build -R cgal --output-on-failure`all pass, 0 skipped (count: `doc/api/tests.md`)
- [ ] `cgal.GaussBonnet.*` all pass → topology is correctly read from mesh
- [ ] `cgal.EuclideanFunctional.GradientCheck_*` pass → energy = integral of gradient
- [ ] `cgal.PeriodMatrix.TauInFundamentalDomain_*` pass → SL(2,) reduction correct

216
doc/release-policy.md Normal file
View File

@@ -0,0 +1,216 @@
# Release & versioning policy
> **Audience:** maintainers and recurring contributors of conformallab++.
> External users only need this if they are publishing a fork.
>
> **Created:** 2026-05-22, after the v0.9.0 release that exposed two
> recurring failure modes: (a) the v0.9.0 tag had to be moved twice
> because release-prep landed on the wrong commit, and (b) the test
> counts were hardcoded in eight different documents and drifted apart.
This document codifies how conformallab++ chooses version numbers,
how releases are produced, and which artefacts must stay in sync.
---
## 1. Version-number rules (SemVer)
The project follows [Semantic Versioning 2.0](https://semver.org).
Tag format: `vMAJOR.MINOR.PATCH` (e.g. `v0.9.0`).
### Pre-1.0 phase (current — until CGAL submission)
While the project is at version `0.x.y`, the public API is **not yet
frozen**. The convention we use during the pre-1.0 phase is:
| Bump | When |
|---|---|
| **`0.x.0 → 0.(x+1).0`** (MINOR) | Significant new feature: new functional, new Newton solver, new public CGAL entry, new Phase milestone completed. May break the public API. Treated as the "interesting" release type during pre-1.0. |
| **`0.x.y → 0.x.(y+1)`** (PATCH) | Bug fixes, performance optimisations without API change, doc-only follow-up releases, CI/infrastructure fixes. Never breaks the public API. |
| **`0.x.y → 1.0.0`** | API freeze + CGAL submission readiness. All public headers under `include/CGAL/` are stable. Cumulative changelog updated to call out every public-API decision in retrospect. |
Phase milestone → MINOR-bump mapping (historical + planned):
| Tag | Phase milestone |
|-----------|--------------------------------------------------------|
| `v0.1.0` | Phase 1 (special functions) |
| `v0.2.0` | Phase 2 (hyper-ideal geometry) |
| `v0.7.0` | Phase 7 complete (period matrix, fundamental domain) |
| `v0.9.0` | Phase 9a + 9b + 8b-Lite |
| `v0.10.0` | Phase 9c (4g-polygon, genus g > 1) |
| `v0.11.0` | Phase 10a (harmonic + holomorphic 1-forms) |
| `v1.0.0` | CGAL package submission-ready |
### Post-1.0 phase (planned, ≥ `v1.0.0`)
Standard SemVer with no pre-1.0 exceptions:
| Bump | When |
|---|---|
| **MAJOR** (`X.0.0 → (X+1).0.0`) | Any breaking change to the public API: removed function, signature change, renamed CGAL entry, behaviour change of a documented contract. |
| **MINOR** (`X.Y.0 → X.(Y+1).0`) | New features, new public entries, new Default-traits classes. Strictly additive — no removal, no behaviour change. |
| **PATCH** (`X.Y.Z → X.Y.(Z+1)`) | Bug fixes only. No new files, no new public symbols. |
### Pre-release tags
For testing-quality releases:
* `v1.0.0-alpha.1`, `v1.0.0-alpha.2`, … — early preview, API may still
shift.
* `v1.0.0-beta.1` — feature-complete preview, API stable but tests
may still find issues.
* `v1.0.0-rc.1`, `v1.0.0-rc.2`, … — release candidate, only blocker
fixes before the final tag.
### What does NOT trigger a release
* Internal refactoring without user-visible change.
* Documentation-only updates (unless the documentation is itself a
product, like a new tutorial).
* Test additions / coverage improvements.
* CI / infrastructure changes.
Group such changes into the next planned release.
---
## 2. Single source of truth for moving numbers
Three numbers tend to drift across multiple documents in any project:
test counts, version strings, and date strings. The conformallab++
rule is:
| Number / string | Single source of truth | Anywhere else |
|-----------------------------|--------------------------------|--------------------------------------|
| **Total / per-suite test counts** | `doc/api/tests.md` | Use qualitative phrasing + link, e.g. "full test suite passes, 0 skipped — see [`doc/api/tests.md`](doc/api/tests.md)". |
| **Project version** | `CITATION.cff` `version:` field | Don't hardcode in headers, READMEs, doc bodies. Reference by name ("v0.9.0") only when the historical version actually matters (changelog entries, release-note bodies, Phase-milestone tables). |
| **Release date** | `CITATION.cff` `date-released:` + `CHANGELOG.md` section header | Don't hardcode elsewhere. |
| **Test-suite description per file** | `doc/api/tests.md` | Headers and code files may list the suites they implement, but never claim a count of suites elsewhere. |
### Why qualitative phrasing for test counts
The counts change with every PR that adds or removes a test. Hardcoding
the number "227" in eight documents means eight separate edits per PR —
and historically we have failed to keep them in sync more than once.
The cost of looking up the exact number in `doc/api/tests.md` is one
click; the cost of fixing a stale "227" in seven places is real PR
overhead. We pay the click.
### Audit script
`scripts/check-test-counts.sh` (when present) reads the totals from
`doc/api/tests.md`, runs `ctest`, and fails the CI if they diverge.
This catches the `tests.md` itself going stale even if no other doc
hardcodes the number.
---
## 3. Release process (checklist)
The recipe that worked for v0.9.0 (after the false-start with PR #11 /
#12). Apply for every `vX.Y.Z` release.
### Pre-release prep — on a release branch
1. **Update `CHANGELOG.md`** — add a new top-level section
`## [vX.Y.Z] — YYYY-MM-DD`. Categorise changes by `Added`,
`Changed`, `Removed`, `Fixed`, `Deprecated`, `Security`. See
[Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/).
2. **Update `CITATION.cff`**`version:` and `date-released:` fields.
3. **Refresh `doc/api/tests.md`** — re-run the full test suite locally
and update the per-suite tables + the two `**Total: N tests, 0 skipped.**`
lines (one for `conformallab_tests`, one for `conformallab_cgal_tests`).
4. **Run `scripts/check-test-counts.sh`** if present — must pass.
5. **Verify no hardcoded counts remain** elsewhere:
```bash
grep -rn "[0-9]\+ tests pass\|[0-9]\+ tests, 0 skipped\|[0-9]\+ CGAL tests" \
README.md CLAUDE.md doc/ scripts/ \
| grep -v "doc/api/tests.md"
# Expected: zero results (other than tests.md itself).
```
6. **Commit** with the message
`release: vX.Y.Z — <one-line summary>`. Push to a feature branch.
### Open the release PR
7. **Open one PR** with all prep commits. Title:
`release: vX.Y.Z (<summary>)`. Description: copy the new
`CHANGELOG.md` section.
8. **Wait for CI green** — `test-fast` + `test-cgal` + `doc-build`.
9. **Merge** with a merge commit (the merge SHA becomes the release
target).
### After-merge — tag and announce
10. **Verify `main` head is the merge commit**:
```bash
git fetch origin && git log origin/main --oneline -1
```
11. **Create the Gitea release** via API or web UI. `target_commitish`
MUST be the merge SHA from step 10 (NOT the feature branch HEAD).
The web UI does this automatically; the API needs explicit `sha`.
12. **Sync the codeberg mirror**:
```bash
git fetch origin --tags
git push codeberg main --tags
```
13. **Update CLAUDE.md "Release state" section** so future
contributors see the new version at a glance. (This is the only
place where the current version appears outside `CITATION.cff` and
`CHANGELOG.md`.)
### Common failure modes and how to recover
| Symptom | Recovery |
|---|---|
| Tag points to an earlier commit than the one you wanted | Delete the release + tag via Gitea API, re-create with the correct `target_commitish`. |
| Release-prep commit lands on a feature branch but not on `main` after merge | Open a fast-follow `release/vX.Y.Z-finalise` PR. Cherry-pick the missing commit; merge; move the tag. |
| `doc/api/tests.md` counts are stale post-merge | One-line PR: re-run `ctest`, update tests.md, no version bump (it's a doc fix between releases). |
---
## 4. Hotfix policy
For a `vX.Y.0` minor release that needs an urgent fix before the next
planned minor:
1. Branch off the release tag (NOT off `main`):
```bash
git checkout -b hotfix/vX.Y.1 vX.Y.0
```
2. Apply the minimal fix.
3. Tag `vX.Y.1` from the hotfix branch.
4. Merge the hotfix back into `main` so the fix isn't lost.
Hotfixes are rare for a research-quality library; the typical path is
to wait for the next minor. Use hotfixes only for security issues or
build-broken-on-supported-platform regressions.
---
## 5. Deprecation policy (post-1.0)
When a public symbol is to be removed in version `M.0.0`:
1. In any earlier `M-1` minor release, mark it `[[deprecated]]` (C++17)
or via a Doxygen `\deprecated` tag.
2. Add a `Deprecated` section to that version's CHANGELOG entry with
the planned removal version.
3. Keep the symbol working for at least one full minor cycle before
removal.
4. Remove in the `M.0.0` release; document the removal in the
`Removed` section.
Pre-1.0, this policy does not apply — breaking changes are allowed
on any minor bump as long as they are listed in CHANGELOG.
---
## 6. Related documents
* `CHANGELOG.md` — per-version history.
* `CITATION.cff` — authoritative version + date for citation.
* `doc/api/tests.md` — single source of truth for test counts.
* `doc/contributing.md` — code style + PR mechanics.
* `doc/roadmap/phases.md` — what each future MINOR bump will deliver.

90
scripts/check-test-counts.sh Executable file
View File

@@ -0,0 +1,90 @@
#!/usr/bin/env bash
# scripts/check-test-counts.sh
#
# CI gate that verifies the totals in `doc/api/tests.md` match the
# actual `ctest` output. Catches the canonical test-count document
# going stale even if no other doc hardcodes the number.
#
# Usage:
# bash scripts/check-test-counts.sh
#
# Exit codes:
# 0 totals match
# 1 totals diverge — prints diff and which file to fix
# 2 prerequisites missing (cmake not found, tests.md missing, …)
#
# This script is meant to be cheap enough to run on every PR (~30 s on
# a typical CI runner). It re-uses the existing build-cgal/ directory
# if one is present; otherwise it builds a throwaway build-counts/.
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")/.." # repo root
TESTS_MD="doc/api/tests.md"
if [ ! -f "$TESTS_MD" ]; then
echo "FAIL: $TESTS_MD not found" >&2
exit 2
fi
command -v cmake >/dev/null || { echo "FAIL: cmake not in PATH" >&2; exit 2; }
command -v ctest >/dev/null || { echo "FAIL: ctest not in PATH" >&2; exit 2; }
# ── Build ───────────────────────────────────────────────────────────────────
# Re-use existing build-cgal/ if it exists with the right flags; otherwise
# create a throwaway build-counts/ directory.
BUILD_DIR=""
if [ -f build-cgal/CMakeCache.txt ] && grep -q "WITH_CGAL_TESTS:.*=ON\|WITH_CGAL:.*=ON" build-cgal/CMakeCache.txt; then
BUILD_DIR=build-cgal
else
BUILD_DIR=build-counts
cmake -S code -B "$BUILD_DIR" -DWITH_CGAL_TESTS=ON -DCMAKE_BUILD_TYPE=Release >/dev/null
fi
cmake --build "$BUILD_DIR" -j"$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 2)" >/dev/null
# ── Get actual counts ───────────────────────────────────────────────────────
cd "$BUILD_DIR"
actual_cgal=$(ctest -R "^cgal" 2>&1 | grep "tests passed" | sed -E 's/.*out of ([0-9]+).*/\1/')
actual_fast=$(ctest -E "^cgal" 2>&1 | grep "tests passed" | sed -E 's/.*out of ([0-9]+).*/\1/')
cd - >/dev/null
# ── Get claimed counts from tests.md ────────────────────────────────────────
# Expected format (in this order):
# **Total: <N1> tests, 0 skipped.** (non-CGAL section)
# ...
# **Total: <N2> tests, 0 skipped.** (CGAL section)
claimed_fast=$(grep -E "\*\*Total: [0-9]+ tests, 0 skipped\.\*\*" "$TESTS_MD" \
| head -n 1 | sed -E 's/.*Total: ([0-9]+) tests.*/\1/')
claimed_cgal=$(grep -E "\*\*Total: [0-9]+ tests, 0 skipped\.\*\*" "$TESTS_MD" \
| tail -n 1 | sed -E 's/.*Total: ([0-9]+) tests.*/\1/')
# ── Compare ────────────────────────────────────────────────────────────────
ok=1
if [ "${actual_fast}" != "${claimed_fast}" ]; then
echo "MISMATCH: non-CGAL — $TESTS_MD claims ${claimed_fast}, ctest reports ${actual_fast}"
ok=0
fi
if [ "${actual_cgal}" != "${claimed_cgal}" ]; then
echo "MISMATCH: CGAL — $TESTS_MD claims ${claimed_cgal}, ctest reports ${actual_cgal}"
ok=0
fi
if [ "$ok" -eq 0 ]; then
cat <<EOF
FAIL: $TESTS_MD totals out of sync with actual test counts.
Recovery:
1. Edit $TESTS_MD: update the two
'**Total: N tests, 0 skipped.**' lines.
2. Add/remove suite rows in the per-suite tables if test
suites were added/removed.
3. Re-run this script to confirm.
EOF
exit 1
fi
echo "OK: test counts in $TESTS_MD match ctest output"
echo " non-CGAL: ${actual_fast} CGAL: ${actual_cgal} total: $((actual_fast + actual_cgal))"
exit 0

View File

@@ -10,7 +10,8 @@
# bash scripts/try_it.sh
#
# Expected output (last lines):
# [PASS] 227 CGAL tests pass, 0 skipped
# [PASS] full CGAL test suite passes, 0 skipped
# (current counts: doc/api/tests.md)
# [PASS] 23 non-CGAL tests pass
# [EXAMPLE] Converged in N iterations. ||G||_inf < 1e-9