Hello Marc, On Thu, 14 Nov 2024 17:06:11 +0100 Marc Chantreux <[email protected]> wrote:
> > I also realized I was unconfortable to touch anything without having a > test suite so I was trying to find some existing use of dformat to make > sure the rendering was ok. > Though a project of much smaller scale and lesser complexity than `dformat`, I experience(d) a similar situation. Instead of the intended edit/update to newer standards of the original source code itself, I started to build tests to learn how the program works _for now_; a bit like a safety net for future edits. Especially for processing options I usually don't use, or not that often. Today, I noticed the sequence of i) defining a structure in `chem`, ii) passing through the preprocessors to eventually iii) let `groff` write a postscript yields plain ASCII. This allows to monitor changes with Python's `pytest` «from the outside». That is, contrasting to check a specific Python function with `pytest`, to aliment the whole executable like black box with a string and only check if its digest/output still is the same. I compiled this concept in script `test_case.py` attached -- `pytest` would report if/which of these tests failed. In perspective to expand «test coverage» of `chem`, additional tests were useful. One could organize them with a label in the test script, to call `pytest` to probe only those sharing a marker in common. To illustrate this optional constraint, this email equally includes `pytest.ini`. Though seemingly simple (no processing of binary data like a .pdf), there might be other approaches more efficient and obvious to those in the know, backed by their studies of computer science. While I have not, suggestions are welcome to perhaps improve `chem` a little bit. (Personally I would prefer if the example tested would yield indentations expressed only by explicit blank spaces, instead of a mixture of spaces and tabs.) `Dformat` could be direction somewhat independent from `chem`. My first attempt to install it locally (based on commit `e74ea9a` in your repository) failed which I attribute to an unrecognized error on my side. I'll send you my log separately. Regards, Norwid
pytest.ini
Description: Binary data
#!/usr/bin/env python3
"""proposal to test the results generated by groff preprocessor chem
With plain text output of `chem`, it could be checked by Python's
non-standard module `pytest`. One possible workflow to use this script
in Linux Debian is
- have an instance of Python
- set up a Python virtual environment proper by the commands of
``` shell
python -m venv sup
source ./sup/bin/activate
pip install pytest # cable to PyPI
```
- to run tests by `python -m pytest`. The report to the CLI can be more
verbose (with the optional flag `-v`), include results of print command
(`-s`), or exit after the first test to fail (`-x`),
- optional: uncomment the marker in line 61; this and the then mandatory
file `pytest.ini` allow to constrain the tests performed to a sub set.
For the present case / as a demonstration, the call then were
```shell
python -m pytest -m chem
```
which still can be combined with all other optional pyest parameters.
Written in Linux Debian 13/trixie with Python (version 3.12.6) and
additional `pytest` (8.3.3) and `pluggy` (1.5.0, both installed from
Debian's repositories)."""
import os
import subprocess as sub
import pytest # resolve this dependency via PyPI/pip
def test_equality():
assert 67 == 67
def test_where_is_awk():
"""reach out to awk on the CLI
In Linux Debian 13/trixie `which awk` defaults to `/usr/bin/awk`"""
result = sub.run(
["which", "awk"],
stdout=sub.PIPE,
stderr=sub.PIPE,
text=True,
check=True)
assert result.stdout.strip() == "/usr/bin/awk"
def test_where_is_chem():
"""reach out to chem as packaged by Debian"""
result = sub.run(
["which", "chem"],
stdout=sub.PIPE,
stderr=sub.PIPE,
text=True,
check=True)
assert result.stdout.strip() == "/usr/bin/chem"
# @pytest.mark.chem # uncomment this for an optional `pytest -m chem`
def test_chem_example_01():
"""test first example in the documentation
Some characters in the strings submitted to be written or/and tested
may have a meaning to the shell (default Debian: bash). To prevent
this complication / a need to escape them, it is safer to process
them as r-strings, than plain strings."""
probe_in = str("""
.cstart
CH3
bond
CH2
bond
.cend
""")
expected_out = str(r""".PS
copy "/usr/share/groff/1.23.0/pic/chem.pic"
textht = 0.16; textwid = .1; cwid = 0.12
lineht = 0.2; linewid = 0.2
Last: 0,0
# CH3
Last: CH3: atom("CH\s-3\d3\u\s+3", 0.3, 0.16, 0.06, 0.16, 0.12, 0.015) with .L.w at Last.e
# bond
Last: bond(0.2, 90, from Last.R.e )
# CH2
Last: CH2: atom("CH\s-3\d2\u\s+3", 0.3, 0.16, 0.06, 0.16, 0.12, 0.015) with .L.w at Last.end
# bond
Last: bond(0.2, 90, from Last.R.e )
.PE
""")
with open("input.ms", mode="w", encoding="utf8") as newfile:
newfile.write(probe_in)
sub.run(
"chem input.ms > output.txt",
shell=True,
text=True,
check=True)
with open("output.txt", mode="r", encoding="utf-8") as source:
read_out = source.read()
print(read_out) # for an optional more verbose output by `pytest -s`
assert read_out == expected_out
os.remove("output.txt")
