Metadata-Version: 2.4
Name: asciidoctest
Version: 0.1.0a3
Summary: A Python doctest runner for AsciiDoc documents and docstrings.
Author-email: Michael Bernstein <zopemaven@gmail.com>
License: Apache-2.0
Project-URL: Homepage, https://github.com/webmaven/asciidoctest
Project-URL: Repository, https://github.com/webmaven/asciidoctest
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Framework :: Pytest
Requires-Python: >=3.14
Description-Content-Type: text/plain
License-File: LICENSE
Requires-Dist: asciidoctrine>=0.1.0a8
Requires-Dist: asciidocstring>=0.1.0a3
Requires-Dist: lark>=1.3.1
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Requires-Dist: pytest-cov>=4.0; extra == "test"
Dynamic: license-file

= AsciiDoctest: Python Doctest Runner for AsciiDoc
:toc: left
:idprefix:
:idseparator: -

image:https://github.com/webmaven/asciidoctest/actions/workflows/ci.yml/badge.svg[CI Status, link=https://github.com/webmaven/asciidoctest/actions/workflows/ci.yml]
image:https://img.shields.io/pypi/v/asciidoctest.svg[PyPI Version, link=https://pypi.org/project/asciidoctest/]
image:https://img.shields.io/badge/python-3.14-blue.svg[Python Version]
image:https://img.shields.io/badge/coverage-97%25-green.svg[Test Coverage]
image:https://img.shields.io/badge/License-Apache_2.0-blue.svg[License, link=https://opensource.org/licenses/Apache-2.0]

AsciiDoctest is a Python doctest runner designed to parse, collect, and execute tests from AsciiDoc (`.adoc`) files and Python docstrings. 

It integrates AST-based parsing using `asciidoctrine` and `asciidocstring` to provide accurate and standard-compliant testing of documentation.

== Features

* **AST-Based Parsing**: Structural parsing using `asciidoctrine` (AsciiDoc parser) and `asciidocstring` (AsciiDoc docstring parser).
* **Execution Modes**:
  - `explicit` (default): Only executes blocks with the `test` attribute or role (e.g., `[source,python,test]` or `[.test]\n[source,python]`).
  - `eager`: Executes all `[source,python]` code blocks across the document.
* **Shared State**: Within a single AsciiDoc document, subsequent blocks share execution state sequentially top-to-bottom. Execution state is completely isolated between separate files.
* **Pytest Integration**: Automatic discovery and execution of `.adoc` files and Python docstrings via registered pytest collectors.
* **Unittest Compatibility**: Suite wrappers (`DocTestSuite` and `DocFileSuite`) designed to integrate with the standard library `unittest` runner.

== Installation

[source,bash]
----
pip install asciidoctest
----

== Pytest Integration

AsciiDoctest automatically registers as a `pytest` plugin. Simply execute `pytest` in your project directory:

[source,bash]
----
pytest
----

=== Configuration

You can configure collection behavior in your `pyproject.toml` or `pytest.ini`:

[source,ini]
----
[pytest]
asciidoctest_mode = eager
----

Alternatively, you can supply the `--asciidoctest-mode` flag:

[source,bash]
----
pytest --asciidoctest-mode=eager
----

== Unittest Integration

To use the standard library `unittest` package, load tests using `DocFileSuite` or `DocTestSuite`:

[source,python]
----
import unittest
from asciidoctest import DocFileSuite

def suite():
    return DocFileSuite("README.adoc")

if __name__ == "__main__":
    unittest.main(defaultTest="suite")
----

== Examples

Below are standard test blocks demonstrating interactive and script-based execution.

=== Interactive Session

We can run interactive Python sessions with expected outputs:

[source,python,test]
----
>>> x = "asciidoctest"
>>> x.upper()
'ASCIIDOCTEST'
----

=== Sequential Script Block

We can run script-based test blocks with standard Python assertions. Because they share execution state sequentially, variables defined in previous blocks are accessible:

[source,python,test]
----
assert x == "asciidoctest"
y = len(x)
assert y == 12
----

=== Directives Support

Standard `doctest` directives such as `ELLIPSIS` are supported:

[source,python,test]
----
>>> print("Hello ... World")
Hello ... World
----
