diff --git a/apps/ttkode/ttkode/plugins/_010_findplugin.py b/apps/ttkode/ttkode/plugins/_010_findplugin.py index 10e4364e..b8ed51de 100644 --- a/apps/ttkode/ttkode/plugins/_010_findplugin.py +++ b/apps/ttkode/ttkode/plugins/_010_findplugin.py @@ -46,5 +46,4 @@ ttkode.TTkodePlugin( icon=ttk.TTkString(_icon) ) ] - - ) +) diff --git a/apps/ttkode/ttkode/plugins/_030_pytestplugin.py b/apps/ttkode/ttkode/plugins/_030_pytestplugin.py new file mode 100644 index 00000000..10598877 --- /dev/null +++ b/apps/ttkode/ttkode/plugins/_030_pytestplugin.py @@ -0,0 +1,51 @@ +# MIT License +# +# Copyright (c) 2025 Eugenio Parodi +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +__all__:list[str] = [] + +import os, sys + +current_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, current_dir) + +import TermTk as ttk + +import ttkode + +_icon:str = ( + "╒╦╕\n" + "╶╨╴") + +ttkode.TTkodePlugin( + name="PyTest Plugin", + widgets = [ + ttkode.TTkodePluginWidgetActivity( + activityName='Testing', + widget=ttk.TTkTestWidget(), + icon=ttk.TTkString(_icon) + ), + ttkode.TTkodePluginWidgetPanel( + panelName='Test Results', + widget=ttk.TTkTestWidget() + ) + ] +) \ No newline at end of file diff --git a/tests/t.generic/test.pytest.01.collector.py b/tests/t.generic/test.pytest.01.collector.py new file mode 100644 index 00000000..42b986fd --- /dev/null +++ b/tests/t.generic/test.pytest.01.collector.py @@ -0,0 +1,39 @@ +import pytest + +class ResultCollector: + def __init__(self): + self.results = [] + + def pytest_runtest_logreport(self, report): + if report.when == "call": + self.results.append({ + "nodeid": report.nodeid, + "outcome": report.outcome, + "duration": report.duration, + "longrepr": str(report.longrepr) if report.failed else None + }) + +def run_tests_and_collect(): + collector = ResultCollector() + pytest.main(["tests/"], plugins=[collector]) + return collector.results + +def run_tests_and_collect_2(): + collector = ResultCollector() + pytest.main(["--collect-only", "-q", "tests/"], plugins=[collector]) + return collector.results + +if __name__ == "__main__": + results = run_tests_and_collect() + for r in results: + print(f"{r['nodeid']}: {r['outcome']} ({r['duration']:.2f}s)") + if r['outcome'] == 'failed': + print(" ↳ Error:", r['longrepr']) + + print() + + results = run_tests_and_collect_2() + for r in results: + print(f"{r['nodeid']}: {r['outcome']} ({r['duration']:.2f}s)") + if r['outcome'] == 'failed': + print(" ↳ Error:", r['longrepr'])