Runs an extension author's Python tests (test_*.py / *_test.py) through
the built-in pytest-compat shim, each in its own TRUSTED GraalPy context
(same trust level as the extension it covers). Tests import the extension's
own package through the SAME sys.path sugar the loader gives extension.py,
so an author ships real Python tests next to the code and runs them with the
project's own tooling. Pure Python end to end — the shim is stdlib-only, no
host bridge, no pip.
Split out of python-extensions (which owns loading/registration) so the
runner is a single, testable responsibility. It depends on that namespace's
trusted-context builder; the reverse wiring (/test slash + vis ext test
CLI) is resolved lazily there to avoid a require cycle.
The source of truth for the outcome is the shim's PER-TEST record list (nodeid, outcome, message). Counts and pass/fail are DERIVED from those records on the host side — never a separate tally that could drift, and never scraped from stdout.
Runs an extension author's Python tests (`test_*.py` / `*_test.py`) through the built-in `pytest`-compat shim, each in its own TRUSTED GraalPy context (same trust level as the extension it covers). Tests import the extension's own package through the SAME `sys.path` sugar the loader gives `extension.py`, so an author ships real Python tests next to the code and runs them with the project's own tooling. Pure Python end to end — the shim is stdlib-only, no host bridge, no pip. Split out of `python-extensions` (which owns loading/registration) so the runner is a single, testable responsibility. It depends on that namespace's trusted-context builder; the reverse wiring (`/test` slash + `vis ext test` CLI) is resolved lazily there to avoid a require cycle. The source of truth for the outcome is the shim's PER-TEST record list (nodeid, outcome, message). Counts and pass/fail are DERIVED from those records on the host side — never a separate tally that could drift, and never scraped from stdout.
(test-python-extensions!)(test-python-extensions! {:keys [dirs]})Discover and run every Python test (test_*.py / *_test.py) across the
extension dirs (default: ~/.vis/extensions and <cwd>/.vis/extensions),
each in its own TRUSTED GraalPy context via the built-in pytest-compat
shim. Tests import the extension's own package through the sys.path sugar,
exactly like extension.py does.
Returns {:files n :ok? bool :passed n :failed n :errored n :skipped n :tests [{:file :nodeid :outcome :message}] :results [{:file :ok? :tests …}]}.
Counts are DERIVED from :tests (the flat per-test list) — the single source
of truth. Never throws: a file that blows up at import is one :errored
result, not a crash.
Discover and run every Python test (`test_*.py` / `*_test.py`) across the
extension dirs (default: `~/.vis/extensions` and `<cwd>/.vis/extensions`),
each in its own TRUSTED GraalPy context via the built-in `pytest`-compat
shim. Tests import the extension's own package through the `sys.path` sugar,
exactly like `extension.py` does.
Returns `{:files n :ok? bool :passed n :failed n :errored n :skipped n
:tests [{:file :nodeid :outcome :message}] :results [{:file :ok? :tests …}]}`.
Counts are DERIVED from `:tests` (the flat per-test list) — the single source
of truth. Never throws: a file that blows up at import is one `:errored`
result, not a crash.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |