Add Initial unit tests#40
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an initial pytest-based unit test suite and a GitHub Actions CI workflow to run type checks and tests, while also applying a few small wxPython-related fixes/typing adjustments in the widget layer.
Changes:
- Add initial
tests/suite (core logic tests + wx-widget placeholders) and pytest configuration. - Add a Windows CI workflow running
uv sync,poe typecheck, andpytestacross a Python-version matrix. - Apply minor wx-related fixes/typing tweaks in several wx widget modules and in
core/entries.pycontext-menu imports.
Reviewed changes
Copilot reviewed 27 out of 28 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Adds locked dev dependencies for pytest/pytest-mock (and transitive deps). |
| pyproject.toml | Adds pytest dev deps, pytest config (testpaths, addopts), and tool.uv setting. |
| CONTRIBUTORS.md | Documents uv-based setup and how to run tests/typechecks. |
| .github/workflows/ci.yml | Adds CI workflow to run type checks and pytest on Windows across Python versions. |
| construct_editor/wx_widgets/wx_python_code_editor.py | Fixes SetSelBackground call to use a boolean. |
| construct_editor/wx_widgets/wx_obj_view.py | Fixes wx.TextCtrl initialization (avoids incorrect super(wx.TextCtrl, self)). |
| construct_editor/wx_widgets/wx_hex_editor.py | Minor wx constant/typing fixes and safer handling of startValue. |
| construct_editor/wx_widgets/wx_construct_editor.py | Tightens typing around GetParent() and adds a type-ignore for overload mismatch. |
| construct_editor/core/entries.py | Switches context-menu imports to module-qualified usage to simplify typing/imports. |
| tests/init.py | Adds tests package marker. |
| tests/core/init.py | Adds tests.core package marker. |
| tests/core/test_preprocessor.py | Adds tests for metadata instrumentation helpers. |
| tests/core/test_model.py | Adds enum/index tests for core model types. |
| tests/core/test_entries.py | Adds tests for parsing/format helpers and path formatting. |
| tests/core/test_custom.py | Adds smoke tests for custom construct registration APIs. |
| tests/core/test_context_menu.py | Adds tests for context-menu dataclasses and callbacks. |
| tests/core/test_construct_editor.py | Adds placeholder (skipped) tests for abstract ConstructEditor contract. |
| tests/core/test_commands.py | Adds tests for core command processor undo/redo behavior. |
| tests/core/test_callbacks.py | Adds tests for CallbackList. |
| tests/wx_widgets/init.py | Adds wx_widgets test package marker. |
| tests/wx_widgets/conftest.py | Adds session-scoped wx.App and a wx.Frame fixture for widget tests. |
| tests/wx_widgets/test_wx_python_code_editor.py | Adds placeholder (skipped) tests for code editor widget. |
| tests/wx_widgets/test_wx_obj_view.py | Adds placeholder (skipped) tests for object view/editor widgets. |
| tests/wx_widgets/test_wx_hex_editor.py | Adds a couple non-placeholder tests for HexEditorFormat and placeholders for wx-dependent parts. |
| tests/wx_widgets/test_wx_exception_dialog.py | Adds a non-placeholder test for ExceptionInfo plus a skipped dialog placeholder. |
| tests/wx_widgets/test_wx_context_menu.py | Adds placeholder (skipped) tests for wx context menu. |
| tests/wx_widgets/test_wx_construct_hex_editor.py | Adds placeholder (skipped) tests for construct hex editor widgets. |
| tests/wx_widgets/test_wx_construct_editor.py | Adds placeholder (skipped) tests for wx construct editor/model. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import pytest | ||
|
|
||
| pytestmark = pytest.mark.usefixtures("wx_app") | ||
|
|
||
|
|
||
| class TestHexEditorFormat: |
| import pytest | ||
|
|
||
| pytestmark = pytest.mark.usefixtures("wx_app") | ||
|
|
||
|
|
||
| class TestExceptionInfo: |
| def test_invalid_string_raises(self) -> None: | ||
| with pytest.raises(Exception): | ||
| str_to_int("not_a_number") | ||
|
|
There was a problem hiding this comment.
"What he said." Only that ValueError is rather broad as well and should be tested using match="<(part of) expected error message>"
| def test_invalid_hex_raises(self) -> None: | ||
| with pytest.raises(Exception): | ||
| str_to_bytes("zz") | ||
|
|
|
|
||
| # pass throught "modify_context_menu" to subentry ######################### | ||
| def modify_context_menu(self, menu: ContextMenu): | ||
| def modify_context_menu(self, menu: "context_menu.ContextMenu"): |
There was a problem hiding this comment.
Are you certain that this enhances readability?
| @@ -0,0 +1 @@ | |||
| # -*- coding: utf-8 -*- | |||
There was a problem hiding this comment.
This is Python default. Why add the explicit markers?
| def test_invalid_string_raises(self) -> None: | ||
| with pytest.raises(Exception): | ||
| str_to_int("not_a_number") | ||
|
|
There was a problem hiding this comment.
"What he said." Only that ValueError is rather broad as well and should be tested using match="<(part of) expected error message>"
| dev = [ | ||
| "poethepoet>=0.46.0", | ||
| "pyright>=1.1.410", | ||
| "pytest>=8.0.0", |
There was a problem hiding this comment.
| "pytest>=8.0.0", | |
| "pytest>=9.0.3", |
| "poethepoet>=0.46.0", | ||
| "pyright>=1.1.410", | ||
| "pytest>=8.0.0", | ||
| "pytest-mock>=3.14.0", |
There was a problem hiding this comment.
Maybe add pytest_cov as well and have the CI do a coverage check?
This adds AI generated initial unit-test and a CI test pipeline. It only acts as a first smoke test for e.g. some import errors. The test files has to be filled in the future.