Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
93e77b5
Python: add pytest + pytest-cov as optional test dependencies
gusthoff Jun 19, 2026
52e7340
Python: configure pytest and coverage in pyproject.toml
gusthoff Jun 19, 2026
5dfd2f4
Makefile: add test_rst_pipeline target for epub VM
gusthoff Jun 19, 2026
c2eb7a5
Docs: document how to install test deps and run the pytest suite
gusthoff Jun 19, 2026
14a6496
Docs: cross-link unit test suite from root README testing section
gusthoff Jun 19, 2026
668771c
Merge feat/pytest-infra: pytest + coverage setup for rst_code_example…
gusthoff Jun 19, 2026
fc1946f
Python: add unit tests for colors.py
gusthoff Jun 19, 2026
aa08925
Python: add unit tests for fmt_utils.py
gusthoff Jun 19, 2026
252fce6
Python: add unit tests for resource.py
gusthoff Jun 19, 2026
9cb1455
Python: add unit tests for checks.py
gusthoff Jun 19, 2026
4fa8eb2
Python: add unit tests for blocks.py
gusthoff Jun 19, 2026
d9a2426
Python: add edge-case unit tests for chop.py
gusthoff Jun 19, 2026
83cd29a
Merge feat/pure-module-tests: unit tests for pure Python modules
gusthoff Jun 19, 2026
98f6fb4
Python: add unit tests for toolchain_info.py
gusthoff Jun 19, 2026
f7649e2
Python: add unit tests for toolchain_setup.py
gusthoff Jun 19, 2026
9ca038b
Python: add unit tests for extract_projects.py
gusthoff Jun 19, 2026
d9b98cc
Python: add unit tests for check_projects.py
gusthoff Jun 19, 2026
3d6868c
Python: add unit tests for check_code_block.py
gusthoff Jun 19, 2026
4d7b49f
Python: update coverage threshold and exclude CLI entry points
gusthoff Jun 19, 2026
04976b5
Merge feat/toolchain-module-tests: unit tests for toolchain-dependent…
gusthoff Jun 19, 2026
a9946d8
Infra: ignore *.egg-info/ directories
gusthoff Jun 19, 2026
1364c18
Python: add pragma: no cover to structurally unreachable blocks
gusthoff Jun 19, 2026
c46da28
Python: add pragma: no cover to extract_projects ConfigBlock guard
gusthoff Jun 19, 2026
a4e9864
Python: add pragma: no branch to colors TTY check
gusthoff Jun 19, 2026
ef8129d
Python: extend unit tests for blocks.py (gnatprove/gprbuild version s…
gusthoff Jun 19, 2026
f8be582
Python: extend unit tests for extract_projects.py (Diag class, verbos…
gusthoff Jun 19, 2026
af81695
Python: extend unit tests for check_projects.py (verbose, inactive bl…
gusthoff Jun 19, 2026
78aeede
Python: extend unit tests for chop.py (real_gnatchop — valid Ada, com…
gusthoff Jun 19, 2026
0ff0ad0
Python: extend unit tests for toolchain_setup.py (uninitialised TOOLC…
gusthoff Jun 19, 2026
ab578e6
Merge feat/coverage-improvements: pragmas and extended unit tests
gusthoff Jun 19, 2026
fd28391
Python: remove references from test file headers
gusthoff Jun 20, 2026
28cce10
Python: add pragma: no cover to __main__ blocks in three modules
gusthoff Jun 20, 2026
0681408
Python: extend integration tests for check_code_block.py
gusthoff Jun 20, 2026
c647a0a
Python: extend integration tests for extract_projects.py
gusthoff Jun 20, 2026
b53d34b
Python: extend integration tests for check_projects.py
gusthoff Jun 20, 2026
03a9330
Merge feat/integration-tests: integration tests for Ada compilation/r…
gusthoff Jun 20, 2026
bc3a655
Python: raise coverage threshold to 90
gusthoff Jun 20, 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
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
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,8 @@ 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)

The package also has its own pytest-based unit test suite. On the epub VM,
run it with `make test_rst_pipeline` (from the `frontend/` directory). See
the "Development" section of the package README for installation and usage
details.
3 changes: 3 additions & 0 deletions frontend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ 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

##@ Build website
publish: ## [DEPRECATED] Publish contents to the learn website.
@echo "Publishing current branch to learn..."
Expand Down
32 changes: 32 additions & 0 deletions frontend/python/rst_code_example_pipeline/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,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/
```
21 changes: 21 additions & 0 deletions frontend/python/rst_code_example_pipeline/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,32 @@ extract-code = "rst_code_example_pipeline.cli.extract:main"
check-code = "rst_code_example_pipeline.cli.check:main"
check-block = "rst_code_example_pipeline.cli.check_block:main"

[project.optional-dependencies]
test = ["pytest", "pytest-cov"]

[tool.setuptools.packages.find]
where = ["src"]

[tool.setuptools.package-data]
rst_code_example_pipeline = ["data/*.ini"]

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--cov=rst_code_example_pipeline --cov-report=term-missing"

[tool.coverage.run]
source = ["rst_code_example_pipeline"]
branch = true

[tool.coverage.report]
show_missing = true
fail_under = 90
exclude_lines = [
# Standard pragma for uncoverable lines
"pragma: no cover",
# CLI __main__ entry points are not exercised by unit tests
"if __name__ == .__main__.:",
]

[tool.pyright]
pythonVersion = "3.10"
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def cleanup_project(language, project_filename, main_file):
has_error = not ref_block_check.status_ok
if verbose:
print("Code block {} already checked. Skipping...".format(loc))
if __name__ == '__main__':
if __name__ == '__main__': # pragma: no cover
print("WARNING: Code block {} already checked: use '--force' to re-run the check. Skipping...".format(loc))
if has_error:
print_error(
Expand Down Expand Up @@ -372,7 +372,7 @@ def cleanup_project(language, project_filename, main_file):
if check_error:
has_error = True

if False:
if False: # pragma: no cover
check_error = False

for source_file in block.source_files:
Expand Down Expand Up @@ -473,7 +473,7 @@ def cleanup_project(language, project_filename, main_file):
has_error = True


if True:
if True: # pragma: no cover
check_error = False

if len(block.buttons) == 0:
Expand Down Expand Up @@ -556,7 +556,7 @@ def check_code_block_json(json_file: str) -> bool:
return has_error


if __name__ == "__main__":
if __name__ == "__main__": # pragma: no cover
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('json_files', type=str, nargs="+",
help="The JSON file for each code block")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def check_projects(build_dir: str, projects_list_file: str | None = None) -> boo
return check_error


if __name__ == "__main__":
if __name__ == "__main__": # pragma: no cover
import argparse

parser = argparse.ArgumentParser(description=__doc__)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def disable_colors(cls) -> None:

# Keep colors when we are running under GDB. Otherwise, disable colors as soon
# as one of stdout or stderr is not a TTY.
if not sys.stdout.isatty() or not sys.stderr.isatty():
if not sys.stdout.isatty() or not sys.stderr.isatty(): # pragma: no branch
Colors.disable_colors()


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ def init_project_dir(project):
print("Number of code blocks: {}".format(len(projects[project])))

for i, block in projects[project]:
if isinstance(block, blocks.ConfigBlock):
if isinstance(block, blocks.ConfigBlock): # pragma: no cover
current_config.update(block)
toolchain_setup.reset_toolchain()
continue
Expand Down Expand Up @@ -397,7 +397,7 @@ def get_main_filename(block):

return analysis_error

if __name__ == "__main__":
if __name__ == "__main__": # pragma: no cover
import argparse

parser = argparse.ArgumentParser(description=__doc__)
Expand Down
Loading
Loading