mirror of
https://github.com/kevinveenbirkenbach/homepage.veen.world.git
synced 2026-04-07 05:12:19 +00:00
feat: migrate to pyproject.toml, add test suites, split CI workflows
- Replace requirements.txt with pyproject.toml for modern Python packaging - Add unit, integration, lint and security test suites under tests/ - Add utils/export_runtime_requirements.py and utils/check_hadolint_sarif.py - Split monolithic CI into reusable lint.yml, security.yml and tests.yml - Refactor ci.yml to orchestrate reusable workflows; publish on semver tag only - Modernize Dockerfile: pin python:3.12-slim, install via pyproject.toml - Expand Makefile with lint, security, test and CI targets - Add test-e2e via act with portfolio container stop/start around run - Fix navbar_logo_visibility.spec.js: win.fullscreen() → win.enterFullscreen() - Set use_reloader=False in app.run() to prevent double-start in CI - Add app/core.* and build artifacts to .gitignore - Fix apt-get → sudo apt-get in tests.yml e2e job - Fix pip install --ignore-installed to handle stale act cache Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
54
tests/integration/test_python_packaging.py
Normal file
54
tests/integration/test_python_packaging.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import tomllib
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class TestPythonPackaging(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.repo_root = Path(__file__).resolve().parents[2]
|
||||
self.pyproject_path = self.repo_root / "pyproject.toml"
|
||||
|
||||
with self.pyproject_path.open("rb") as handle:
|
||||
self.pyproject = tomllib.load(handle)
|
||||
|
||||
def test_pyproject_defines_build_system_and_runtime_dependencies(self):
|
||||
build_system = self.pyproject["build-system"]
|
||||
project = self.pyproject["project"]
|
||||
|
||||
self.assertEqual(build_system["build-backend"], "setuptools.build_meta")
|
||||
self.assertIn("setuptools>=69", build_system["requires"])
|
||||
self.assertGreaterEqual(
|
||||
set(project["dependencies"]),
|
||||
{"flask", "pyyaml", "requests"},
|
||||
)
|
||||
self.assertEqual(project["requires-python"], ">=3.12")
|
||||
|
||||
def test_pyproject_defines_dev_dependencies_and_package_contents(self):
|
||||
project = self.pyproject["project"]
|
||||
setuptools_config = self.pyproject["tool"]["setuptools"]
|
||||
package_find = setuptools_config["packages"]["find"]
|
||||
package_data = setuptools_config["package-data"]["app"]
|
||||
|
||||
self.assertGreaterEqual(
|
||||
set(project["optional-dependencies"]["dev"]),
|
||||
{"bandit", "pip-audit", "ruff"},
|
||||
)
|
||||
self.assertEqual(setuptools_config["py-modules"], ["main"])
|
||||
self.assertEqual(package_find["include"], ["app", "app.*"])
|
||||
self.assertIn("config.sample.yaml", package_data)
|
||||
self.assertIn("templates/**/*.j2", package_data)
|
||||
self.assertIn("static/css/*.css", package_data)
|
||||
self.assertIn("static/js/*.js", package_data)
|
||||
|
||||
def test_legacy_requirements_files_are_removed(self):
|
||||
self.assertFalse((self.repo_root / "requirements.txt").exists())
|
||||
self.assertFalse((self.repo_root / "requirements-dev.txt").exists())
|
||||
self.assertFalse((self.repo_root / "app" / "requirements.txt").exists())
|
||||
|
||||
def test_package_init_files_exist(self):
|
||||
self.assertTrue((self.repo_root / "app" / "__init__.py").is_file())
|
||||
self.assertTrue((self.repo_root / "app" / "utils" / "__init__.py").is_file())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user