From 97e121785fac63e0308c9a55a0fe29e47567fcad Mon Sep 17 00:00:00 2001 From: Konstantin Date: Thu, 7 Nov 2024 14:56:29 +0100 Subject: [PATCH 1/8] make main testable --- docker-compose.yaml | 4 +++- src/ebd_toolchain/main.py | 8 ++++++++ unittests/test_main.py | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 unittests/test_main.py diff --git a/docker-compose.yaml b/docker-compose.yaml index c6339fd..ec6319c 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,7 +1,9 @@ services: kroki: image: yuzutech/kroki:0.24.1 - + ports: + - "8000:8000" # Expose localhost:8000 + # this is required for the test_main.py to directly use kroki scrape-and-plot: build: . image: ghcr.io/hochfrequenz/ebd_toolchain:latest diff --git a/src/ebd_toolchain/main.py b/src/ebd_toolchain/main.py index d4c4268..6c095fa 100644 --- a/src/ebd_toolchain/main.py +++ b/src/ebd_toolchain/main.py @@ -113,6 +113,11 @@ def main(input_path: Path, output_path: Path, export_types: list[Literal["puml", """ A program to get a machine-readable version of the AHBs docx files published by edi@energy. """ + _main(input_path, output_path, export_types) + + +def _main(input_path: Path, output_path: Path, export_types: list[Literal["puml", "dot", "json", "svg"]]) -> None: + """same as main but without the click decorators""" settings = Settings() # type:ignore[call-arg] # read settings from environment variable/.env file kroki_client = Kroki(kroki_host=f"http://{settings.kroki_host}:{settings.kroki_port}") @@ -195,6 +200,9 @@ def handle_known_error(error: Exception, ebd_key: str) -> None: # e.g. AssertionError: If indegree > 1, the number of paths should always be greater than 1 too. click.secho(str(assertion_error), fg="red") # both the SVG and dot path require graphviz to work, hence the common error handling block + except Exception as unknown_error: + click.secho(str(unknown_error), fg="red") + continue click.secho(json.dumps({str(k): v for k, v in error_sources.items()}, indent=4)) click.secho("🏁Finished") diff --git a/unittests/test_main.py b/unittests/test_main.py new file mode 100644 index 0000000..f1c7c97 --- /dev/null +++ b/unittests/test_main.py @@ -0,0 +1,35 @@ +""" +tests the main script +""" + +from pathlib import Path +from typing import Literal +from _pytest.monkeypatch import MonkeyPatch +import pytest + +from ebd_toolchain.main import _main + +repo_root = Path(__file__).parent.parent +recent_docx_file = ( + repo_root + / "edi_energy_mirror" + / "edi_energy_de" + / "FV2504" + / "Entscheidungsbaum-DiagrammeundCodelisten-informatorischeLesefassung4.0a_99991231_20250404.docx" +) +assert recent_docx_file.exists() + + +@pytest.mark.parametrize( + "input_path, export_types", [pytest.param(recent_docx_file, ["puml", "dot", "json", "svg"], id="recent call")] +) +def test_main( + input_path: Path, + export_types: list[Literal["puml", "dot", "json", "svg"]], + tmp_path: Path, + monkeypatch: MonkeyPatch, +) -> None: + monkeypatch.setenv("KROKI_PORT", "8000") + monkeypatch.setenv("KROKI_HOST", "localhost") + _main(input_path, tmp_path, export_types) + # we don't assert on the results but instead just check that it doesn't crash From 938bc3bb0cb29b36cab0071fd45739cfbe3b7a88 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Thu, 7 Nov 2024 14:58:59 +0100 Subject: [PATCH 2/8] with submoudle --- .github/workflows/unittests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index 3cf5358..ec1ce60 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -13,6 +13,8 @@ jobs: os: [ubuntu-latest] steps: - uses: actions/checkout@v4 + with: + submodules: 'recursive' - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: From 1bcd70606f3f43e7751b8e912cd34a3240c490a3 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Thu, 7 Nov 2024 15:01:06 +0100 Subject: [PATCH 3/8] isort . --- unittests/test_main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unittests/test_main.py b/unittests/test_main.py index f1c7c97..afc271d 100644 --- a/unittests/test_main.py +++ b/unittests/test_main.py @@ -4,8 +4,9 @@ from pathlib import Path from typing import Literal -from _pytest.monkeypatch import MonkeyPatch + import pytest +from _pytest.monkeypatch import MonkeyPatch from ebd_toolchain.main import _main From 489dfd3a8e8c68a52f3b3552f68e76acda528fa3 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Thu, 7 Nov 2024 15:10:51 +0100 Subject: [PATCH 4/8] comment --- unittests/test_main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/unittests/test_main.py b/unittests/test_main.py index afc271d..e0d0988 100644 --- a/unittests/test_main.py +++ b/unittests/test_main.py @@ -32,5 +32,8 @@ def test_main( ) -> None: monkeypatch.setenv("KROKI_PORT", "8000") monkeypatch.setenv("KROKI_HOST", "localhost") + # if you run into ConnectionErrors use + # docker-compose up -d + # in the repo root _main(input_path, tmp_path, export_types) # we don't assert on the results but instead just check that it doesn't crash From b66b8286e98dacf4acebb67a7b172a470ae8fee1 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Thu, 7 Nov 2024 15:39:41 +0100 Subject: [PATCH 5/8] wip --- pyproject.toml | 2 +- src/ebd_toolchain/main.py | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5f0cf24..01bd931 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ classifiers = [ ] dependencies = [ "ebdamame>=0.1.3", - "rebdhuhn>=0.4.0", + "rebdhuhn>=0.5.1", "cattrs", "click", "pydantic-settings" diff --git a/src/ebd_toolchain/main.py b/src/ebd_toolchain/main.py index 6c095fa..2da7a1c 100644 --- a/src/ebd_toolchain/main.py +++ b/src/ebd_toolchain/main.py @@ -36,7 +36,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict from rebdhuhn.graph_conversion import convert_table_to_graph from rebdhuhn.graphviz import convert_dot_to_svg_kroki, convert_graph_to_dot -from rebdhuhn.kroki import DotToSvgConverter, Kroki +from rebdhuhn.kroki import DotToSvgConverter, Kroki, KrokiDotBadRequestError, KrokiPlantUmlBadRequestError from rebdhuhn.models.ebd_graph import EbdGraph from rebdhuhn.models.ebd_table import EbdTable from rebdhuhn.models.errors import ( @@ -180,7 +180,11 @@ def handle_known_error(error: Exception, ebd_key: str) -> None: except AssertionError as assertion_error: # https://github.com/Hochfrequenz/rebdhuhn/issues/35 click.secho(str(assertion_error), fg="red") - except (NotExactlyTwoOutgoingEdgesError, GraphTooComplexForPlantumlError) as known_issue: + except ( + NotExactlyTwoOutgoingEdgesError, + GraphTooComplexForPlantumlError, + KrokiPlantUmlBadRequestError, + ) as known_issue: handle_known_error(known_issue, ebd_key) except Exception as general_error: # pylint:disable=broad-exception-caught click.secho(f"Error while exporting {ebd_key} as UML: {str(general_error)}; Skip!", fg="yellow") @@ -194,15 +198,12 @@ def handle_known_error(error: Exception, ebd_key: str) -> None: svg_path = output_path / Path(f"{ebd_key}.svg") _dump_svg(svg_path, ebd_graph, kroki_client) click.secho(f"💾 Successfully exported '{ebd_key}.svg' to {svg_path.absolute()}") - except PathsNotGreaterThanOneError as known_issue: + except (PathsNotGreaterThanOneError, KrokiDotBadRequestError) as known_issue: handle_known_error(known_issue, ebd_key) except AssertionError as assertion_error: # e.g. AssertionError: If indegree > 1, the number of paths should always be greater than 1 too. click.secho(str(assertion_error), fg="red") # both the SVG and dot path require graphviz to work, hence the common error handling block - except Exception as unknown_error: - click.secho(str(unknown_error), fg="red") - continue click.secho(json.dumps({str(k): v for k, v in error_sources.items()}, indent=4)) click.secho("🏁Finished") From f0dc4f30b1d0065bf6963f0c921459c8b5b2edcd Mon Sep 17 00:00:00 2001 From: Konstantin Date: Thu, 7 Nov 2024 15:48:03 +0100 Subject: [PATCH 6/8] shutup plylint --- src/ebd_toolchain/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ebd_toolchain/main.py b/src/ebd_toolchain/main.py index 2da7a1c..158b1a8 100644 --- a/src/ebd_toolchain/main.py +++ b/src/ebd_toolchain/main.py @@ -108,14 +108,13 @@ def _dump_json(json_path: Path, ebd_table: EbdTable) -> None: multiple=True, help="Choose which file you'd like to create", ) -# pylint:disable=too-many-locals, too-many-branches, too-many-statements, def main(input_path: Path, output_path: Path, export_types: list[Literal["puml", "dot", "json", "svg"]]) -> None: """ A program to get a machine-readable version of the AHBs docx files published by edi@energy. """ _main(input_path, output_path, export_types) - +# pylint:disable=too-many-locals, too-many-branches, too-many-statements, def _main(input_path: Path, output_path: Path, export_types: list[Literal["puml", "dot", "json", "svg"]]) -> None: """same as main but without the click decorators""" settings = Settings() # type:ignore[call-arg] From e47b546beeaffe1b496069df80061ed18fef14bb Mon Sep 17 00:00:00 2001 From: Konstantin Date: Thu, 7 Nov 2024 15:49:27 +0100 Subject: [PATCH 7/8] black --- src/ebd_toolchain/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ebd_toolchain/main.py b/src/ebd_toolchain/main.py index 158b1a8..7979af4 100644 --- a/src/ebd_toolchain/main.py +++ b/src/ebd_toolchain/main.py @@ -114,6 +114,7 @@ def main(input_path: Path, output_path: Path, export_types: list[Literal["puml", """ _main(input_path, output_path, export_types) + # pylint:disable=too-many-locals, too-many-branches, too-many-statements, def _main(input_path: Path, output_path: Path, export_types: list[Literal["puml", "dot", "json", "svg"]]) -> None: """same as main but without the click decorators""" From 6eaa0d8ba487239b17853c0908456f75e8e68ab2 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Thu, 7 Nov 2024 15:50:05 +0100 Subject: [PATCH 8/8] update coverage flow --- .github/workflows/coverage.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 98fe259..e138c8f 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -13,6 +13,8 @@ jobs: os: [ubuntu-latest] steps: - uses: actions/checkout@v4 + with: + submodules: 'recursive' - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: