encadre

Encadre, petit framework web Python (Flask) : contrôleurs en greffons, validation, tests
git clone https://git.schurger.org/encadre.git
Log | Files | Refs

commit 038c0ecc7a9757e3197b1ebd39054281493c14ce
parent 9fe5e43f881e39d59f051d93bf0a3725d9177dd0
Author: Jean Schurger <jean@schurger.org>
Date:   Sat, 17 Oct 2026 16:15:31 -0400

Tests internes réparés (unittest au lieu de nose) ; version 0.3.2

- Encadre(None) refonctionne : sans moteur configuré, le constructeur ne
  crée pas de framework (cassé depuis 1783a7a « Expose framework », qui
  créait le moteur dans __init__) ; les applications configurées ne
  changent pas.
- make tests : unittest + coverage (nose ne marche plus depuis Python
  3.12, module imp retiré) ; extra « test » sans nose.
- get_controllers_tsts ne recopie plus testcase_cls (unittest le prenait
  pour un test) ; TestFramework.send_bytes referme le fichier comme
  send_file.
- Test ajouté pour Hello_3.dividebyzero.

35 tests OK, sans avertissement (DeprecationWarning et ResourceWarning en
erreur) ; galva charge ses 531 routes avec ce code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NezW9k9RsGdD9Po82BD4Vv

Diffstat:
MMakefile | 4+++-
MREADME.org | 7+++++++
Mencadre/__init__.py | 13+++++++++----
Mencadre/controllers.py | 7+++++--
Mencadre_test_controllers/__init__.py | 3+++
Aencadre_test_controllers/__pycache__/__init__.cpython-313.pyc | 0
Mpyproject.toml | 3+--
7 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/Makefile b/Makefile @@ -12,4 +12,6 @@ routes.org: encadre_test_controllers/*.py encadre-test-app-dump-routes config.ini >routes.org tests: - nosetests --nocapture --with-coverage --cover-inclusive --cover-package=encadre,encadre_flask,encadre_test_controllers,encadre_test_app + python -m coverage run --source=encadre,encadre_flask,encadre_test_controllers,encadre_test_app \ + -m unittest -v test encadre_flask.test + python -m coverage report diff --git a/README.org b/README.org @@ -13,3 +13,10 @@ Flask is the one implemented. - Code: https://git.schurger.org/encadre/ (=git clone https://git.schurger.org/encadre.git=) - Package: https://pypi.org/project/encadre/ (=pip install encadre=) - License: GPLv3, Python >= 3.13 + +* Running encadre's own tests + +#+begin_example shell +pip install -e '.[test]' +make tests +#+end_example diff --git a/encadre/__init__.py b/encadre/__init__.py @@ -45,10 +45,15 @@ class Encadre(): print("You'd better configure logging in '%s':\n%s" % (self.config_filename, traceback.format_exc())) setattr(sys.modules['encadre'], 'config', self.config) - self.framework = framework_from_config(self.__class__.__name__.lower(), - self.config) - self.framework.setup_application(self) - load_controllers(self.framework, self.application) + # Without a configured framework (unit tests create the application + # with no configuration file: Encadre(None)), there is nothing to set + # up here; the tests run the controllers on encadre's TestFramework. + self.framework = None + name = self.__class__.__name__.lower() + if (self.config.get(name) or {}).get('framework'): + self.framework = framework_from_config(name, self.config) + self.framework.setup_application(self) + load_controllers(self.framework, self.application) def read_config(self, filename): config = {self.__class__.__name__.lower(): {}} diff --git a/encadre/controllers.py b/encadre/controllers.py @@ -112,7 +112,8 @@ class TestFramework(Framework): self._cookies[key] = value def send_bytes(self, bytes_like, **kwargs): # pylint: disable=W0613 - return bytes_like.read() + with bytes_like: # like Flask's send_file, which closes it + return bytes_like.read() def get_controllers_tsts(app): @@ -128,7 +129,9 @@ def get_controllers_tsts(app): attributes = {} for name in [a for a in dir(cls) if a[0] != '_']: attr = getattr(cls, name) - if not name.startswith('test_'): + # testcase_cls only picks the base class below; copied, its + # "test" prefix would make unittest run it as a test. + if not name.startswith('test_') and name != 'testcase_cls': attributes[name] = attr if isinstance(attr, types.FunctionType) and \ not name.startswith('test_'): diff --git a/encadre_test_controllers/__init__.py b/encadre_test_controllers/__init__.py @@ -176,6 +176,9 @@ class Hello_3(Hello_2): def dividebyzero(self): return 1 / 0 + def test_dividebyzero(self): + self.assertRaises(ZeroDivisionError, self.dividebyzero) + class StrangeTestCase(unittest.TestCase): diff --git a/encadre_test_controllers/__pycache__/__init__.cpython-313.pyc b/encadre_test_controllers/__pycache__/__init__.cpython-313.pyc Binary files differ. diff --git a/pyproject.toml b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "encadre" -version = "0.3.1" +version = "0.3.2" description = "Encadre framework" authors = [ {name = "Jean Schurger", email = "jean@schurger.org"} @@ -26,7 +26,6 @@ Source = "https://git.schurger.org/encadre.git" [project.optional-dependencies] test = [ - "nose", "coverage", ]