about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNguyễn Gia Phong <cnx@loang.net>2025-05-30 00:38:26 +0900
committerNguyễn Gia Phong <cnx@loang.net>2025-05-30 00:38:26 +0900
commitdcb363d429b7c284946e04c53f1fc21456e8faff (patch)
tree89f6686a801de3e14630f9ca332a9226ec529dc0
parent82b754bdcf781eabf182293561838fabe21a467d (diff)
downloadscadere-dcb363d429b7c284946e04c53f1fc21456e8faff.tar.gz
Gotta go fast
Coverage does not seem to work with pytest-xdist without pytest-cov.
-rw-r--r--README.md14
-rw-r--r--pyproject.toml8
-rw-r--r--src/scadere/listen.py11
3 files changed, 17 insertions, 16 deletions
diff --git a/README.md b/README.md
index 1967b9d..d07b743 100644
--- a/README.md
+++ b/README.md
@@ -40,8 +40,9 @@ Options:
 
 ## Hacking
 
-Unit testing is done with [pytest], [pytest-asyncio],
-[Hypothesis] and [trustme].  Since scadere itself does not depend
+Unit testing is done with [Hypothesis],
+[pytest]-{[asyncio][pytest-asyncio],[cov][pytest-cov],[xdist][pytest-xdist]}
+and [trustme].  Since scadere itself does not depend
 on any Python package, it is safe to be tested in-tree:
 
     PYTHONPATH=src pytest
@@ -51,10 +52,8 @@ on any Python package, it is safe to be tested in-tree:
 Issues should be reported to [chung@loa.loang.net][loang mailing list].
 
 The mailing list also welcomes patches.  Please maintain
-a full branch [coverage] and keep the [hobgoblins][flake8] happy:
+a full branch coverage and keep the [hobgoblins][flake8] happy:
 
-    PYTHONPATH=src coverage run
-    coverage report
     flake8
 
 Patches should be sent using [`git send-email`][git send-email]
@@ -71,12 +70,13 @@ Scadere is free software: you can redistribute and/or modify it
 under the terms of the GNU [Affero General Public License][agpl]
 version 3 or later.
 
+[Hypothesis]: https://hypothesis.rtfd.io
 [pytest]: https://docs.pytest.org
 [pytest-asyncio]: https://pytest-asyncio.rtfd.io
-[Hypothesis]: https://hypothesis.rtfd.io
+[pytest-cov]: https://pytest-cov.rtfd.io
+[pytest-xdist]: https://pytest-xdist.rtfd.io
 [trustme]: https://trustme.rtfd.io
 [loang mailing list]: https://loa.loang.net/chung
-[coverage]: https://coverage.rtfd.io
 [flake8]: https://flake8.pycqa.org
 [git send-email]: https://git-send-email.io
 [agpl]: https://www.gnu.org/licenses/agpl
diff --git a/pyproject.toml b/pyproject.toml
index 60291a8..11c5c89 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -27,11 +27,12 @@ Source = 'https://trong.loang.net/scadere'
 Inbox = 'https://loa.loang.net/chung'
 
 [project.optional-dependencies]
-dev = [ 'coverage',
-        'flake8',
+dev = [ 'flake8',
         'hypothesis',
         'pytest',
         'pytest-asyncio',
+        'pytest-cov',
+        'pytest-xdist',
         'trustme >= 1.2.0' ]
 
 [project.scripts]
@@ -39,6 +40,7 @@ scadere-check = 'scadere.check:main'
 scadere-listen = 'scadere.listen:main'
 
 [tool.pytest.ini_options]
+addopts = '-n auto --cov=.'
 asyncio_mode = 'auto'
 asyncio_default_fixture_loop_scope = 'function'
 testpaths = [ 'tst' ]
@@ -46,8 +48,6 @@ verbosity_assertions = 2
 
 [tool.coverage.run]
 branch = true
-command_line = '-m pytest'
-source = [ '.' ]
 
 [tool.coverage.report]
 fail_under = 100
diff --git a/src/scadere/listen.py b/src/scadere/listen.py
index 085664d..8d115ae 100644
--- a/src/scadere/listen.py
+++ b/src/scadere/listen.py
@@ -67,12 +67,13 @@ async def describe_status(writer, status):
 
 
 async def write_xml(writer, document):
-    content = strings_from_xml(xml(document), 'unicode',
-                               xml_declaration=True, default_namespace=None)
-    length = len(''.join(content))
-    writer.write(f'Content-Length: {length}\r\n\r\n'.encode())
+    content = tuple(map(str.encode,
+                        strings_from_xml(xml(document), 'unicode',
+                                         xml_declaration=True,
+                                         default_namespace=None)))
+    writer.write(f'Content-Length: {sum(map(len, content))}\r\n\r\n'.encode())
     for part in content:
-        writer.write(part.encode())
+        writer.write(part)
         await writer.drain()