Source code for wuttjamaican.testing

# -*- coding: utf-8; -*-
################################################################################
#
#  WuttJamaican -- Base package for Wutta Framework
#  Copyright © 2023-2025 Lance Edgar
#
#  This file is part of Wutta Framework.
#
#  Wutta Framework is free software: you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the Free
#  Software Foundation, either version 3 of the License, or (at your option) any
#  later version.
#
#  Wutta Framework is distributed in the hope that it will be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
#  more details.
#
#  You should have received a copy of the GNU General Public License along with
#  Wutta Framework.  If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
WuttJamaican - test utilities
"""

import os
import shutil
import tempfile
import warnings
from unittest import TestCase

from wuttjamaican.conf import WuttaConfig


[docs] class FileTestCase(TestCase): """ Base class for test suites which (may) write temporary files, for sake of testing the config constructor etc. It inherits from :class:`python:unittest.TestCase`. This class creates a temporary folder on setup, and removes it on teardown. See below for features exposed to work with the folder. .. attribute:: tempdir Path to the temporary folder created during setup. .. note:: If you subclass this and need to override setup/teardown, please be sure to call the corresponding methods for this class. """ def setUp(self): # pylint: disable=empty-docstring """ """ self.setup_files()
[docs] def setup_files(self): """ This creates the temporary folder. """ self.tempdir = tempfile.mkdtemp()
def setup_file_config(self): # pragma: no cover; pylint: disable=empty-docstring """ """ warnings.warn( "FileTestCase.setup_file_config() is deprecated; " "please use setup_files() instead", DeprecationWarning, stacklevel=2, ) self.setup_files() def tearDown(self): # pylint: disable=empty-docstring """ """ self.teardown_files()
[docs] def teardown_files(self): """ This removes the temporary folder. """ shutil.rmtree(self.tempdir)
def teardown_file_config(self): # pragma: no cover; pylint: disable=empty-docstring """ """ warnings.warn( "FileTestCase.teardown_file_config() is deprecated; " "please use teardown_files() instead", DeprecationWarning, stacklevel=2, ) self.teardown_files()
[docs] def write_file(self, filename, content): """ Write a new file (in temporary folder) with the given filename and content, and return its full path. For instance:: myconf = self.write_file('my.conf', '<file contents>') """ path = os.path.join(self.tempdir, filename) with open(path, "wt", encoding="utf_8") as f: f.write(content) return path
def mkdir( self, dirname ): # pragma: no cover; pylint: disable=unused-argument,empty-docstring """ """ warnings.warn( "FileTestCase.mkdir() is deprecated; " "please use FileTestCase.mkdtemp() instead", DeprecationWarning, stacklevel=2, ) return self.mkdtemp()
[docs] def mkdtemp(self): """ Make a new temporary folder and return its path. Note that this will be created *underneath* :attr:`tempdir`. """ return tempfile.mkdtemp(dir=self.tempdir)
# TODO: deprecate / remove this FileConfigTestCase = FileTestCase
[docs] class ConfigTestCase(FileTestCase): """ Base class for test suites requiring a config object. It inherits from :class:`FileTestCase` so also has the file-related methods. The running test has these attributes: .. attribute:: config Reference to the config object. .. attribute:: app Reference to the app handler. .. note:: If you subclass this directly and need to override setup/teardown, please be sure to call the corresponding methods for this class. """ def setUp(self): # pylint: disable=empty-docstring """ """ self.setup_config()
[docs] def setup_config(self): """ Perform config setup operations for the test. """ self.setup_files() self.config = self.make_config() self.app = self.config.get_app()
def tearDown(self): # pylint: disable=empty-docstring """ """ self.teardown_config()
[docs] def teardown_config(self): """ Perform config teardown operations for the test. """ self.teardown_files()
def make_config( # pylint: disable=missing-function-docstring self, files=None, **kwargs ): return WuttaConfig(files, **kwargs)
[docs] class DataTestCase(ConfigTestCase): """ Base class for test suites requiring a full (typical) database. It inherits from :class:`FileTestCase` so also has the file-related methods. This uses a SQLite in-memory database and creates all tables for the app model. The running test has these attributes: .. attribute:: config Reference to the config object. .. attribute:: app Reference to the app handler. .. attribute:: session Open session for the test DB. .. note:: If you subclass this and need to override setup/teardown, please be sure to call the corresponding methods for this class. However you do *not* need to call the file-related setup or teardown methods, as this class handles that automatically. """ sqlite_engine_url = "sqlite://" def setUp(self): # pylint: disable=empty-docstring """ """ self.setup_db()
[docs] def setup_db(self): """ Perform config/app/db setup operations for the test. """ self.setup_config() model = self.app.model model.Base.metadata.create_all(bind=self.config.appdb_engine) self.session = self.app.make_session()
def tearDown(self): # pylint: disable=empty-docstring """ """ self.teardown_db()
[docs] def teardown_db(self): """ Perform config/app/db teardown operations for the test. """ self.teardown_config()
def make_config(self, files=None, **kwargs): defaults = kwargs.setdefault("defaults", {}) defaults.setdefault("wutta.db.default.url", self.sqlite_engine_url) return super().make_config(files, **kwargs)