Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
222 commits
Select commit Hold shift + click to select a range
766b70c
Python: add pytest + pytest-cov as optional test dependencies
gusthoff Jun 19, 2026
86e6668
Python: configure pytest and coverage in pyproject.toml
gusthoff Jun 19, 2026
dee9d29
Makefile: add test_rst_pipeline target for epub VM
gusthoff Jun 19, 2026
64d9c07
Python: add unit tests for colors.py
gusthoff Jun 19, 2026
5bcb0a5
Docs: document how to install test deps and run the pytest suite
gusthoff Jun 19, 2026
2c0cc45
Python: add unit tests for fmt_utils.py
gusthoff Jun 19, 2026
49f2133
Docs: cross-link unit test suite from root README testing section
gusthoff Jun 19, 2026
e41637c
Python: add unit tests for resource.py
gusthoff Jun 19, 2026
4e5932b
Merge feat/pytest-infra: pytest + coverage setup for rst_code_example…
gusthoff Jun 19, 2026
6ec64f5
Python: add pragma: no cover to structurally unreachable blocks
gusthoff Jun 19, 2026
e4b1ea5
Python: add unit tests for toolchain_info.py
gusthoff Jun 19, 2026
f6a3ade
Python: add pragma: no cover to extract_projects ConfigBlock guard
gusthoff Jun 19, 2026
9c53c1d
Python: add unit tests for toolchain_setup.py
gusthoff Jun 19, 2026
e91ce1d
Python: add pragma: no branch to colors TTY check
gusthoff Jun 19, 2026
7c4ea31
Python: add unit tests for extract_projects.py
gusthoff Jun 19, 2026
2704113
Python: add unit tests for checks.py
gusthoff Jun 19, 2026
0d37dfa
Python: extend unit tests for blocks.py (gnatprove/gprbuild version s…
gusthoff Jun 19, 2026
3648c30
Python: add unit tests for check_projects.py
gusthoff Jun 19, 2026
6220fa8
Python: add unit tests for blocks.py
gusthoff Jun 19, 2026
9f23299
Python: extend unit tests for extract_projects.py (Diag class, verbos…
gusthoff Jun 19, 2026
1a79324
Python: add unit tests for check_code_block.py
gusthoff Jun 19, 2026
8ffd3ac
Python: add edge-case unit tests for chop.py
gusthoff Jun 19, 2026
9a3de58
Python: extend unit tests for check_projects.py (verbose, inactive bl…
gusthoff Jun 19, 2026
27804fa
Python: update coverage threshold and exclude CLI entry points
gusthoff Jun 19, 2026
d8f69e3
Merge feat/pure-module-tests: unit tests for pure Python modules
gusthoff Jun 19, 2026
ba42502
Python: add pragma: no cover to __main__ blocks in three modules
gusthoff Jun 20, 2026
8050eb8
Python: extend unit tests for chop.py (real_gnatchop — valid Ada, com…
gusthoff Jun 19, 2026
94e9a13
Merge feat/toolchain-module-tests: unit tests for toolchain-dependent…
gusthoff Jun 19, 2026
b527680
Python: add pragma: no cover / no branch to remaining dead paths
gusthoff Jul 24, 2026
c89f503
Python: extend integration tests for check_code_block.py
gusthoff Jun 20, 2026
b58fdcf
Python: extend unit tests for toolchain_setup.py (uninitialised TOOLC…
gusthoff Jun 19, 2026
d847d49
Infra: ignore *.egg-info/ directories
gusthoff Jun 19, 2026
5175107
Python: extend unit tests for check_code_block.py
gusthoff Jul 24, 2026
db26413
Python: extend integration tests for extract_projects.py
gusthoff Jun 20, 2026
69b8a8c
Merge feat/coverage-improvements: pragmas and extended unit tests
gusthoff Jun 19, 2026
ff3b742
Python: extend unit tests for extract_projects.py
gusthoff Jul 24, 2026
22b1261
Python: extend integration tests for check_projects.py
gusthoff Jun 20, 2026
a7d6d30
Python: remove references from test file headers
gusthoff Jun 20, 2026
208d106
Python: extend unit tests for blocks.py
gusthoff Jul 24, 2026
17fcd50
Merge feat/integration-tests: integration tests for Ada compilation/r…
gusthoff Jun 20, 2026
b177292
Python: register a toolchain marker for tests needing the Ada toolchain
gusthoff Aug 28, 2026
2ea8e41
Python: extend unit tests for chop.py
gusthoff Jul 24, 2026
cbebc23
Python: raise coverage threshold to 90
gusthoff Jun 20, 2026
9514394
Python: make an unregistered pytest marker a collection error
gusthoff Aug 28, 2026
1c79ae0
Python: extend unit tests for check_code_block.py
gusthoff Jul 24, 2026
2292704
Merge feat/coverage-completion: pragmas and clean-path coverage tests
gusthoff Jul 24, 2026
d6043cf
Python: move the cwd-restoring test fixture into a shared conftest.py
gusthoff Aug 28, 2026
7ef60e5
Python: extend unit tests for extract_projects.py
gusthoff Jul 24, 2026
148bb0f
Python: raise coverage threshold to 95
gusthoff Jul 24, 2026
3d7761b
Python: mark the tests that need the Ada toolchain
gusthoff Aug 28, 2026
e356ca8
Python: remove dead has_error assignment in C cleanup handler
gusthoff Jul 24, 2026
a7056bd
Python: extend unit tests for blocks.py
gusthoff Jul 24, 2026
45eb455
Python: extend unit tests for check_code_block.py
gusthoff Jul 24, 2026
8dd39bd
Merge feat/coverage-real-input-tests: real-input coverage for previou…
gusthoff Jul 24, 2026
c38bb28
Python: assert toolchain.ini invariants instead of frozen version sets
gusthoff Aug 28, 2026
612eab1
Python: extend unit tests for check_code_block.py
gusthoff Jul 25, 2026
6719276
Python: extend unit tests for check_code_block.py
gusthoff Jul 24, 2026
17b5920
Merge feat/coverage-missing-toolchain-test: environment-isolated miss…
gusthoff Jul 24, 2026
833c276
Python: derive toolchain setup versions from the declared toolchains
gusthoff Aug 28, 2026
578effe
CI: install test extras before running pyright on code_projects
gusthoff Jul 25, 2026
772d677
Python: extend unit tests for extract_projects.py
gusthoff Jul 25, 2026
6143db9
Merge feat/coverage-bonus-pickups: small coverage gaps found during t…
gusthoff Jul 24, 2026
d7802e9
Python: read the configured toolchain versions instead of copying them
gusthoff Aug 28, 2026
d94d7f8
Python: narrow blocks to CodeBlock/ConfigBlock before accessing subcl…
gusthoff Jul 25, 2026
0ece602
Merge feat/coverage-cleanup-failure-tests: cleanup-failure and gnatch…
gusthoff Jul 25, 2026
27e202e
Python: correct the toolchain notes in the pipeline test modules
gusthoff Aug 28, 2026
49bcf6c
CI: rename workflow and add a job that runs the pytest suite
gusthoff Jul 25, 2026
d9b00da
Python: raise coverage threshold to 99
gusthoff Jul 25, 2026
a28fc20
Python: describe the covered behaviour instead of source line numbers
gusthoff Aug 28, 2026
ff4bd03
Merge feat/ci-tests: pyright fixes and a CI job for the pytest suite
gusthoff Jul 25, 2026
6eb1b29
Python: restore the colour setting when a no_colors block raises
gusthoff Aug 28, 2026
03e624b
Merge feat/test-suite-portability: shared fixtures, toolchain marker,…
gusthoff Aug 28, 2026
a6915ff
Python: add shared constants for cross-module artifact filenames
gusthoff Aug 29, 2026
8aa9ddd
Python: expect a JSON round-trip to keep the per-block checks
gusthoff Aug 28, 2026
2c0219f
Python: add a constants module for the RST directive vocabulary
gusthoff Aug 29, 2026
36a7654
Python: remove tests that restate the source instead of testing it
gusthoff Aug 29, 2026
ea9d3dd
Python: expect per-block extraction errors to fail the run
gusthoff Aug 28, 2026
66b7851
Python: locate generated project files through the record, not by name
gusthoff Aug 29, 2026
10b212b
Python: add extractor-driven check_block tests for compile/run/prove
gusthoff Aug 29, 2026
68a6ebe
Python: remove test assertions subsumed by an exact-output sibling
gusthoff Aug 29, 2026
87a0607
Python: assert no_colors restores the setting when a block raises
gusthoff Aug 28, 2026
16d5c98
Python: report gnatprove clean-up failures like gprclean's
gusthoff Aug 30, 2026
f24bee6
Python: check the generated project names the pragma file it wrote
gusthoff Aug 29, 2026
fdf2102
Python: centralize per-file reset fixtures into conftest.py
gusthoff Aug 29, 2026
9b678bb
Python: test forcing the checks against a real cached failure
gusthoff Aug 29, 2026
3b071a9
Python: assert the diagnostic text instead of only not crashing
gusthoff Aug 29, 2026
71f5a47
Python: expect a block with no buttons to fail the extraction run
gusthoff Aug 28, 2026
6af1f48
Python: report an unreadable block info file instead of crashing
gusthoff Aug 30, 2026
2f1b4c4
Python: locate the remaining generated files by what was written
gusthoff Aug 29, 2026
95c49ce
Python: enter the temporary directory through the shared fixture
gusthoff Aug 29, 2026
f1acc96
Python: assert extracted artifacts by content and owner, not by name
gusthoff Aug 29, 2026
0ee4bd6
Python: pin exact parser line numbers and generated file contents
gusthoff Aug 29, 2026
19906cb
Docs: document the exit status of the pipeline commands
gusthoff Aug 28, 2026
a4e6b54
Python: stop recording a run phase for unrecognized languages
gusthoff Aug 30, 2026
0a8acce
Python: pin the switches a prove class selects, report-all as an xfail
gusthoff Aug 29, 2026
e6667f6
Python: make three tests assert what their names promise
gusthoff Aug 29, 2026
0349bfb
Python: drive the C and expect-error check paths from the extractor
gusthoff Aug 29, 2026
de8a2e1
Python: test text hashes for determinism and distinctness
gusthoff Aug 29, 2026
9629c66
Docs: record that no_colors restores the setting on exception
gusthoff Aug 28, 2026
4f22e16
Python: compile a C block that asks only for a compile
gusthoff Aug 30, 2026
b3b2da4
Python: document why only a runnable block names a main
gusthoff Aug 29, 2026
dc749d5
Python: convert test_smoke.py from unittest to pytest
gusthoff Aug 29, 2026
d531403
Python: drop three check_block tests the extractor-driven ones subsume
gusthoff Aug 29, 2026
2e29ab2
Python: relax the over-specified cleanup-log-count assertion
gusthoff Aug 29, 2026
b292e63
Python: split the diagnostic assertions out of the xfail tests
gusthoff Aug 28, 2026
8023334
Python: report a missing executable instead of crashing
gusthoff Aug 30, 2026
f5ef925
Python: document what the code-block text hashes must guarantee
gusthoff Aug 29, 2026
4443de6
Python: check the package version against the installed metadata
gusthoff Aug 29, 2026
fa18c09
Python: share one minimal Ada source across the check_block tests
gusthoff Aug 29, 2026
57cc5bb
Python: check hash stability across processes, not within one
gusthoff Aug 29, 2026
8245ad5
Makefile: add a toolchain-free smoke-test target
gusthoff Aug 28, 2026
c9fda85
Python: use American spelling in a test docstring
gusthoff Aug 28, 2026
8973615
Docs: say how an unreadable block info file is reported
gusthoff Aug 30, 2026
1f580f7
Python: qualify the directive-class list in the constants module
gusthoff Aug 29, 2026
60caff6
Python: add end-to-end CLI tests for cli entry points
gusthoff Aug 29, 2026
32a06f6
Python: replace a positional cross-reference in a test docstring
gusthoff Aug 29, 2026
59cb0c0
Python: restore detection power to two checker assertions
gusthoff Aug 29, 2026
1ece0d4
Docs: document the toolchain-free smoke-test target
gusthoff Aug 29, 2026
35a2dce
Docs: correct the return value documented for `analyze_file()`
gusthoff Aug 28, 2026
78802f9
Docs: name the clean-up failure as an ERROR line that is not a failure
gusthoff Aug 30, 2026
7ddc58b
Docs: document the C and prove-error code-block testing classes
gusthoff Aug 29, 2026
9372fc6
Python: reword comments and docstrings that narrate the source
gusthoff Aug 29, 2026
0c46668
Python: mark one assertion in the run test as a localizer
gusthoff Aug 29, 2026
c8b572e
Python: drop dead test helpers and pin a container shape
gusthoff Aug 29, 2026
7531ff9
Makefile: shorten the smoke-test help text
gusthoff Aug 29, 2026
fcc6603
Docs: correct the exit-status section of the pipeline README
gusthoff Aug 28, 2026
e987e8c
Docs: describe what a compile button alone builds
gusthoff Aug 30, 2026
bcda293
Python: name the remaining directive class the checker compares
gusthoff Aug 30, 2026
3d40bd6
Python: remove three unused imports from the test modules
gusthoff Aug 29, 2026
c38ea37
Python: pin the chopped sources the Ada seam tests are checked against
gusthoff Aug 29, 2026
a37707d
Python: hash the same text in a block that differs in every other field
gusthoff Aug 29, 2026
13e7027
Docs: correct the unit-test section of the root README
gusthoff Aug 29, 2026
d23a9c7
Merge feat/xfail-known-defects: track known defects, fix the color leak
gusthoff Aug 28, 2026
513611c
Python: fail the run when a block info file cannot be read
gusthoff Aug 30, 2026
98c6d05
Python: scope the constants module's guarantee to the package
gusthoff Aug 30, 2026
fdb17fd
Python: tolerate an editable install's duplicate metadata
gusthoff Aug 29, 2026
d2d6c1d
Python: correct the tracking note on the C compile xfail
gusthoff Aug 29, 2026
91a11a5
Python: pin diagnostic line remapping against the compiler's own numb…
gusthoff Aug 29, 2026
964c7a2
Merge feat/toolchain-free-smoke-subset: optional smoke run without a …
gusthoff Aug 29, 2026
875874e
Docs: record that an unreadable block info file fails the run
gusthoff Aug 30, 2026
ba4b839
Python: read back the pipeline's artifacts by what was written
gusthoff Aug 30, 2026
66e7619
Python: check that a course reported as checked really ran
gusthoff Aug 29, 2026
d8ec2d5
Python: say which command lines the project-file helper can read
gusthoff Aug 29, 2026
71dd536
Merge feat/assertion-quality: delete redundant tests and strengthen t…
gusthoff Aug 29, 2026
7007b99
Python: fail the run when a block is skipped for having no project
gusthoff Aug 30, 2026
7d4313b
Python: assert the gnatprove switches each prove indicator selects
gusthoff Aug 30, 2026
f6aaea0
Python: read the pipeline defaults from the modules declaring them
gusthoff Aug 29, 2026
bf13810
Merge feat/extractor-driven-check-tests: drive check_block from the r…
gusthoff Aug 29, 2026
688429c
Python: assert each clean-up failure is reported on its own
gusthoff Aug 30, 2026
fbfce9a
Python: record what a rename of the project file names still costs
gusthoff Aug 30, 2026
b31f344
Merge feat/suite-hygiene-cleanup: conftest centralization, unittest t…
gusthoff Aug 29, 2026
88b692a
Python: assert no run phase is recorded for a language the check cann…
gusthoff Aug 30, 2026
e5b9844
Merge feat/de-hardcode-source-constants: single source of truth for f…
gusthoff Aug 30, 2026
c029f8e
Python: cover a run that has no executable to run
gusthoff Aug 30, 2026
18671cc
Python: pin how a C block is built with and without a main file
gusthoff Aug 30, 2026
83f0736
Python: cover a block record that is present but cannot be read
gusthoff Aug 30, 2026
8bf7daf
Python: cover a block that is dropped before it is ever checked
gusthoff Aug 30, 2026
49705a1
Python: say when a damaged block record is being rebuilt
gusthoff Aug 30, 2026
03dbd50
Docs: record that a block naming no project fails the run
gusthoff Aug 30, 2026
aa88c77
Docs: describe the warning that names a rebuilt block record
gusthoff Aug 30, 2026
7565c54
Python: cover the warning formatter's output
gusthoff Aug 30, 2026
2678bf9
Python: cover the rebuilding of a damaged block record
gusthoff Aug 30, 2026
4176926
Python: report a block record that is not valid UTF-8
gusthoff Aug 30, 2026
7d500a1
Python: make the rebuild warning match what actually happens
gusthoff Aug 30, 2026
3fcf3c0
Docs: widen how an unreadable block record is reported
gusthoff Sep 4, 2026
62ebb0d
Python: delete a helper the extractor never calls
gusthoff Sep 6, 2026
657dd6d
Python: read a real boolean as a boolean in the block configuration
gusthoff Sep 6, 2026
8d2f21a
Docs: match the rebuild warning to what it now promises
gusthoff Sep 4, 2026
c056aec
Python: reword the notes on the declared toolchain versions
gusthoff Sep 6, 2026
eca61d6
Python: run C blocks that ask to be run by class
gusthoff Sep 6, 2026
9c3d605
Python: match two assertions to the narrowed rebuild message
gusthoff Sep 5, 2026
4cd3058
Docs: rewrite the extraction command's help text
gusthoff Sep 6, 2026
6aa7bf1
Python: select the report-all proof switch from the class that names it
gusthoff Sep 6, 2026
9661412
Python: cover a block record that is not valid UTF-8
gusthoff Sep 5, 2026
b1aac71
Docs: state what an unmet error expectation does
gusthoff Sep 6, 2026
8ba6df1
Docs: say what deactivating a run leaves behind
gusthoff Sep 6, 2026
398caad
Python: check what the rebuild warning claims, not only its wording
gusthoff Sep 6, 2026
f4dd8ed
Docs: describe how ConfigBlock coerces its values
gusthoff Sep 6, 2026
a0afb59
Python: delete an unreachable copy of the compile step
gusthoff Sep 6, 2026
a7c848b
Python: use American spelling throughout the test suite
gusthoff Sep 6, 2026
ea69508
Python: cover the C run classes a block declares
gusthoff Sep 6, 2026
4781fdf
Python: cover a block record whose name is held by a directory
gusthoff Sep 6, 2026
6fa168a
Docs: fix the package README's introduction link
gusthoff Sep 6, 2026
b9bfa52
Python: let coverage see the button validation it always ran
gusthoff Sep 6, 2026
94e7384
Docs: say what the package needs on PATH instead of how it is deployed
gusthoff Sep 6, 2026
7ac3770
Python: cover a real boolean in the block configuration
gusthoff Sep 6, 2026
330a98d
Python: put both blocks of the rebuild fixture in one project
gusthoff Sep 6, 2026
0b50f20
Python: report a C compile error that was expected and did not happen
gusthoff Sep 6, 2026
2e25ba4
Python: cover an expected compile or prove error that never happened
gusthoff Sep 6, 2026
8f54cd5
Docs: make check-block's help describe the checker it has
gusthoff Sep 6, 2026
9f33c51
Python: cover the switches a proof selects from its class
gusthoff Sep 6, 2026
f029ba1
Python: describe what the rebuild warning actually promises
gusthoff Sep 6, 2026
8e22949
Docs: state the expected-error contract without an exception
gusthoff Sep 6, 2026
5052aad
Python: check an unmet compile-error expectation through the command
gusthoff Sep 6, 2026
7f1b478
Docs: record the order the checks for a code block run in
gusthoff Sep 6, 2026
0701280
Python: cover a quiet run that fails the way the block expects
gusthoff Sep 6, 2026
72cebcf
Merge feat/checker-reporting-fixes: report checker failures instead o…
gusthoff Sep 6, 2026
6e8b145
Docs: point the package README's course links at the course
gusthoff Sep 6, 2026
0632a4e
Python: drive the previous-check lookup both ways
gusthoff Sep 6, 2026
691bbaf
Docs: state that an unreadable block record reads back as no block
gusthoff Sep 6, 2026
4d63bfb
Merge feat/honor-block-declarations: act on the classes and configura…
gusthoff Sep 6, 2026
db504f4
Docs: let the extraction and block commands name themselves
gusthoff Sep 6, 2026
bb4692d
Python: force both answers to the terminal test made at import
gusthoff Sep 6, 2026
27b7971
Merge feat/help-text-and-spelling: say what the checker does and how …
gusthoff Sep 6, 2026
6e1de98
Python: test the C compile error that was expected and never happened
gusthoff Sep 6, 2026
436e7b2
Merge feat/expect-error-core-promise: test the expected error that ne…
gusthoff Sep 6, 2026
e94aff4
Merge feat/closing-text-and-cleanup: close the last gaps in the check…
gusthoff Sep 6, 2026
22c005b
Python: report a run class that names the other language
gusthoff Sep 18, 2026
b4af98b
Python: apply each run class only to the language it names
gusthoff Sep 18, 2026
4dcf108
Docs: state where the syntax check does not reach
gusthoff Sep 18, 2026
494e91d
Python: test that a run class applies only to its own language
gusthoff Sep 18, 2026
18c7085
Python: test the report for a run class naming the other language
gusthoff Sep 18, 2026
42ff483
Python: test that a mis-classed run class fails the command
gusthoff Sep 18, 2026
bff9656
Python: report a mis-declared run class before reusing a recorded result
gusthoff Sep 19, 2026
edd403c
Python: test the report a recorded result used to absorb
gusthoff Sep 19, 2026
6016438
Python: test a class-only edit through the installed command
gusthoff Sep 19, 2026
13c5c5c
Merge feat/review-follow-ups: apply each run class only to the langua…
gusthoff Sep 19, 2026
5001273
CI: remove duplicate stale-named pyright workflow
gusthoff Sep 19, 2026
a081100
Python: drop references to the rest of the repository
gusthoff Sep 19, 2026
52fa174
Python: bump the package version to 0.3.0
gusthoff Sep 19, 2026
57cd21a
Python: trim the exit-status section of the pipeline README
gusthoff Sep 19, 2026
30f993c
Docs: drop the fix-plan paragraph from analyze_file()'s docstring
gusthoff Sep 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions .github/workflows/code-projects-type-check.yml

This file was deleted.

62 changes: 62 additions & 0 deletions .github/workflows/rst-code-example-pipeline-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: rst_code_example_pipeline CI

on:
push:
paths:
- 'frontend/python/rst_code_example_pipeline/**'
pull_request:
branches:
- main
paths:
- 'frontend/python/rst_code_example_pipeline/**'

jobs:
pyright:

runs-on: ubuntu-26.04

strategy:
matrix:
python-version: ['3.14']

steps:
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- name: Install pyright
run: pip install pyright
- name: Install rst_code_example_pipeline
run: pip install -e 'frontend/python/rst_code_example_pipeline[test]'
- name: Run pyright on rst_code_example_pipeline
working-directory: frontend/python/rst_code_example_pipeline
run: pyright .

pytest:

runs-on: ubuntu-26.04

strategy:
matrix:
python-version: ['3.14']

steps:
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- name: Install OS deps
run: |
sudo apt-get update && \
sudo apt-get install -y \
crudini
- name: Install GNAT FSF
run: |
${GITHUB_WORKSPACE}/.github/workflows/install_toolchain.sh --gnat --gnatprove --gprbuild
- name: Install rst_code_example_pipeline
run: pip install -e 'frontend/python/rst_code_example_pipeline[test]'
- name: Run rst_code_example_pipeline test suite
working-directory: frontend
run: make test_rst_pipeline
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.DS_Store
*.pyc
*.egg-info/
env
.idea
.vagrant*
Expand Down
32 changes: 28 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ The following button-related parameters are available for this directive:
| `prove_flow_report_all_button` | examine SPARK data and control flow and report all findings |
| `submit_button` | submit code for a lab |

When `compile_button` is used and nothing else asks for the code to be run —
no `run_button`, and no class that asks for a run — the code is compiled but
not linked. No executable is produced, so such a code block does not have to
contain a main subprogram (in Ada) or a `main` function (in C).

### Project parameter and code accumulation

A `project` parameter must be provided. For this parameter, we use the
Expand Down Expand Up @@ -586,7 +591,8 @@ block in the generated HTML or e-book output.

The following classes are available for the testing phase:

- `ada-nocheck`: testing of this specific code block is completely skipped.
- `ada-nocheck` and `c-nocheck`: testing of this specific code block is
completely skipped, for Ada or C code respectively.

- `nosyntax-check`: code must not be checked for syntax errors. (Note that
the code block is still compiled in the testing phase.)
Expand All @@ -597,9 +603,21 @@ The following classes are available for the testing phase:
If an error is expected during the testing phase, one of the following classes
must be used:

- `ada-expect-compile-error`: a compilation error is expected.
- `ada-expect-compile-error` and `c-expect-compile-error`: a compilation
error is expected, in Ada or C code respectively.

- `ada-run-expect-failure` and `c-run-expect-failure`: a run-time error is
expected, in Ada or C code respectively.

- `ada-run-expect-failure`: a run-time error is expected.
- `ada-expect-prove-error`: a proof error is expected. The code block must
also be proved, either through one of the prove buttons or through one of
the `ada-prove` classes listed below.

These classes state a requirement on the testing phase, not a hint about the
generated output: the expected error has to actually occur. If it does not —
the code compiles, runs or proves cleanly — that absence is reported as an
error and fails the check, so one of these classes left behind after the code
example was fixed makes the testing phase fail rather than passing quietly.

When the `no_button` parameter is used, the following classes are available to
compile or run the code examples:
Expand All @@ -618,7 +636,13 @@ output.
When the `run_button` parameter is used, the following classes are available:

- `ada-norun` and `c-norun`: to explicitly deactivate the run of Ada or C
code, respectively, during the testing phase.
code, respectively, during the testing phase. These classes also take
precedence over a class that asks for a run, such as `ada-run` or `c-run`.

The code is built in order to be run, so deactivating the run also
deactivates the build unless something else asks for the code to be
compiled — a `compile_button`, or the `ada-compile` or `c-compile` class.
Without one of those, the code block is only checked for syntax errors.

## Lab exercises

Expand Down
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,71 @@ check-code \

For more examples and alternative configurations, please refer to the
[README of the rst_code_example_pipeline package](frontend/python/rst_code_example_pipeline/README.md)

#### Running the package's unit tests

The package also has its own pytest-based unit test suite. Run the whole
suite with `make test_rst_pipeline`, from the `frontend/` directory:

```sh
# Full suite -- the validation run, and the only one
make test_rst_pipeline
```

This needs an Ada toolchain *installation*, not merely a compiler on `PATH`.
The package exists to extract, build and run source-code examples, so the
tests covering that work invoke the toolchain for real -- and some of them
create and remove symlinks under the installation tree configured in the
package's `src/rst_code_example_pipeline/data/toolchain.ini` (`/opt/ada` and
below). A distribution-packaged GNAT on `PATH`, without that tree, is not
enough: the suite goes red. This is the only run that validates the
module (the `rst_code_example_pipeline` package). The epub VM has such an
installation; so does the `pytest` job in
`.github/workflows/rst-code-example-pipeline-ci.yml`, which provisions one
and then runs this same target on a GitHub runner.

For developers working on a machine without an Ada toolchain, a second
target runs just the subset of tests that need no toolchain:

```sh
# Toolchain-free subset -- does not validate the module
make test_rst_pipeline_smoke
```

**This smoke run does not validate the module.** It compiles nothing, so it
proves nothing about the module's actual job. Its reach is narrower than
"every test that does not need a toolchain" may suggest: it executes roughly
half of the module's lines and leaves `check_code_block.py`, the file that
drives the toolchain, almost entirely unexecuted. Ordinary Python inside
the toolchain-facing files -- diagnostic parsing, message formatting,
writing the JSON check report -- is deselected wholesale along with the
tests that cover it, so breaking any of that still leaves the smoke run
green. A green smoke run must never be mistaken for a passing suite.
Coverage is switched off for it, because a coverage figure measured from a
subset would invite the same misreading.

So before considering a change tested, run the full suite where a toolchain
installation exists: on the epub VM, or on a machine provisioned the way the
CI runner is. `.github/workflows/install_toolchain.sh` is the specification
for that provisioning -- it reads every path and version from the package's
`toolchain.ini` and unpacks the GNAT FSF builds into that tree. It is
written for the CI runner (it expects `GITHUB_WORKSPACE`, needs `crudini`,
and exports the `bin` directories through `GITHUB_PATH`), so read it rather
than run it unchanged on a workstation.

Both targets are thin wrappers around `pytest`. `make` itself runs from
`frontend/`, where the `Makefile` lives -- there is no `Makefile` in the
package directory. It is the recipes that `cd` into
`frontend/python/rst_code_example_pipeline`; `pytest` runs there. Without
the Makefile, run the equivalent commands from that directory:

```sh
# Full suite -- the validation run, and the only one
pytest

# Smoke subset -- does not validate the module
pytest -m "not toolchain" --no-cov
```

See the "Development" section of the package README for installation and
usage details.
6 changes: 6 additions & 0 deletions frontend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ test_parser: #
@coverage run --source=widget,rst_code_example_pipeline.chop,rst_code_example_pipeline.resource -m unittest discover --start-directory sphinx
@coverage report --fail-under=90 -m

test_rst_pipeline: ## Test the rst_code_example_pipeline package (epub VM).
@cd python/rst_code_example_pipeline && pytest

test_rst_pipeline_smoke: ## Toolchain-free smoke test; does NOT validate the package.
@cd python/rst_code_example_pipeline && pytest -m "not toolchain" --no-cov

##@ Build website
publish: ## [DEPRECATED] Publish contents to the learn website.
@echo "Publishing current branch to learn..."
Expand Down
68 changes: 62 additions & 6 deletions frontend/python/rst_code_example_pipeline/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

## Introduction

The [rst_code_example_pipeline](frontend/python/rst_code_example_pipeline) package contains
scripts to extract, build and run the code blocks from the ReST files. These are the main
entry points:
The `rst_code_example_pipeline` package contains scripts to extract, build and
run the code blocks from the ReST files. These are the main entry points:

- `extract-code` extracts all code blocks and stores into the specified
build directory;
Expand All @@ -13,18 +12,23 @@ entry points:

- `check-block` checks a single (previously extracted) code block.

The package is installed in editable mode as part of the VM provisioning:
Install the package from the repository, in editable mode:
```sh
pip install -e frontend/python/rst_code_example_pipeline
```

The entry points drive an Ada toolchain directly and expect it on `PATH`:
`extract-code` splits an Ada code block with `gnatchop`, and the two checking
commands syntax-check and compile with `gcc`, build with `gprbuild`, clean up
with `gprclean`, and prove with `gnatprove`.


## Simple usage

To build and run the source-code examples from a course, just run
`extract-code` followed by `check-code`. For example, to test
the source-code examples from the
[Introduction to Ada course](content/courses/intro-to-ada), run:
[Introduction to Ada course](../../../content/courses/intro-to-ada), run:

```sh
extract-code \
Expand All @@ -41,6 +45,26 @@ for each code block (source-code example) that is extracted from the ReST files.
and checks the source-code example described in each of those JSON files.


## Exit status

All three entry points report the outcome of a run through their exit status:

- `check-code` and `check-block` exit `1` if any checked code block failed a
check, and `0` otherwise. A code block that could not be read or checked
also counts as a failure.

- `extract-code` exits `1` when it cannot run at all — for example, a code
block has no project name, or neither `--build-dir` nor
`--extracted_projects` was given — and `0` otherwise.

An invalid command line is rejected before any work is done, with exit
status `2`.

Some malformed code blocks are reported only through an `ERROR` line in the
output, while `extract-code` itself still exits `0`. Check the output, not
only the exit code, to catch these.


## Verbose mode

All the scripts have a `--verbose` / `-v` switch. For example:
Expand All @@ -62,7 +86,7 @@ check-code \
It's possible to store the list of extracted projects into a JSON file and
use that file for checking the projects. For example, to build the source-code
examples from the
[Introduction to Ada course](content/courses/intro-to-ada), run:
[Introduction to Ada course](../../../content/courses/intro-to-ada), run:

```sh
extract-code \
Expand Down Expand Up @@ -168,3 +192,35 @@ check-block \
--max-columns 80 \
test_output/projects/Courses/Intro_To_Ada/Imperative_Language/Greet/cba89a34b87c9dfa71533d982d05e6ab/block_info.json
```


## Development

### Installing with test dependencies

The package declares an optional `test` extras group that installs
[pytest](https://docs.pytest.org/) and
[pytest-cov](https://pytest-cov.readthedocs.io/).
Install the package in editable mode together with those extras:

```sh
pip install -e ".[test]"
```

### Running the unit tests

Coverage options and test paths are configured in `pyproject.toml`, so a plain
`pytest` invocation from the package root is enough:

```sh
pytest
```

Some modules require an Ada toolchain (GNAT) to be on `PATH`; run the full
suite in an environment where GNAT is available.

To pass coverage options explicitly:

```sh
pytest --cov=rst_code_example_pipeline --cov-report=term-missing tests/
```
Loading
Loading