2
0
Fork 0

Compare commits

..

2 commits

Author SHA1 Message Date
Lance Edgar 7002986cb7 bump: version 0.13.0 → 0.13.1 2024-08-27 19:11:30 -05:00
Lance Edgar 2edeac0d83 fix: add common DataTestCase for use in other packages 2024-08-27 19:11:26 -05:00
6 changed files with 105 additions and 42 deletions

View file

@ -5,6 +5,12 @@ All notable changes to WuttJamaican will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## v0.13.1 (2024-08-27)
### Fix
- add common `DataTestCase` for use in other packages
## v0.13.0 (2024-08-26) ## v0.13.0 (2024-08-26)
### Feat ### Feat

View file

@ -6,7 +6,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "WuttJamaican" name = "WuttJamaican"
version = "0.13.0" version = "0.13.1"
description = "Base package for Wutta Framework" description = "Base package for Wutta Framework"
readme = "README.md" readme = "README.md"
authors = [{name = "Lance Edgar", email = "lance@edbob.org"}] authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]

View file

@ -30,22 +30,27 @@ import tempfile
import warnings import warnings
from unittest import TestCase from unittest import TestCase
from wuttjamaican.conf import WuttaConfig
class FileConfigTestCase(TestCase):
class FileTestCase(TestCase):
""" """
Common base class for test suites which write temporary files, for Base class for test suites which (may) write temporary files, for
sake of testing the config constructor etc. sake of testing the config constructor etc. It inherits from
:class:`python:unittest.TestCase`.
This inherits from :class:`python:unittest.TestCase` and adds the This class creates a temporary folder on setup, and removes it on
following features: teardown. See below for features exposed to work with the folder.
Creates a temporary folder on setup, and removes it on teardown.
Adds the :meth:`write_file()` method to help with creating
temporary files.
.. attribute:: tempdir .. attribute:: tempdir
Path to the temporary folder created during setup. 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): def setUp(self):
@ -54,8 +59,6 @@ class FileConfigTestCase(TestCase):
def setup_files(self): def setup_files(self):
""" """
Setup logic specific to the ``FileConfigTestCase``.
This creates the temporary folder. This creates the temporary folder.
""" """
self.tempdir = tempfile.mkdtemp() self.tempdir = tempfile.mkdtemp()
@ -73,8 +76,6 @@ class FileConfigTestCase(TestCase):
def teardown_files(self): def teardown_files(self):
""" """
Teardown logic specific to the ``FileConfigTestCase``.
This removes the temporary folder. This removes the temporary folder.
""" """
shutil.rmtree(self.tempdir) shutil.rmtree(self.tempdir)
@ -105,3 +106,73 @@ class FileConfigTestCase(TestCase):
Note that this will be created *underneath* :attr:`tempdir`. Note that this will be created *underneath* :attr:`tempdir`.
""" """
return tempfile.mkdtemp(dir=self.tempdir) return tempfile.mkdtemp(dir=self.tempdir)
# TODO: deprecate / remove this
FileConfigTestCase = FileTestCase
class DataTestCase(FileTestCase):
"""
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.
"""
def setUp(self):
""" """
self.setup_db()
def setup_db(self):
"""
Perform config/app/db setup operations for the test.
"""
self.setup_files()
self.config = self.make_config(defaults={
'wutta.db.default.url': 'sqlite://',
})
self.app = self.config.get_app()
# init db
model = self.app.model
model.Base.metadata.create_all(bind=self.config.appdb_engine)
self.session = self.app.make_session()
def tearDown(self):
""" """
self.teardown_db()
def teardown_db(self):
"""
Perform config/app/db teardown operations for the test.
"""
self.teardown_files()
def make_config(self, **kwargs):
""" """
return WuttaConfig(**kwargs)

View file

@ -15,10 +15,10 @@ from wuttjamaican import app
from wuttjamaican.progress import ProgressBase from wuttjamaican.progress import ProgressBase
from wuttjamaican.conf import WuttaConfig from wuttjamaican.conf import WuttaConfig
from wuttjamaican.util import UNSPECIFIED from wuttjamaican.util import UNSPECIFIED
from wuttjamaican.testing import FileConfigTestCase from wuttjamaican.testing import FileTestCase
class TestAppHandler(FileConfigTestCase): class TestAppHandler(FileTestCase):
def setUp(self): def setUp(self):
self.setup_files() self.setup_files()

View file

@ -10,10 +10,10 @@ import pytest
from wuttjamaican import conf from wuttjamaican import conf
from wuttjamaican.exc import ConfigurationError from wuttjamaican.exc import ConfigurationError
from wuttjamaican.app import AppHandler from wuttjamaican.app import AppHandler
from wuttjamaican.testing import FileConfigTestCase from wuttjamaican.testing import FileTestCase
class TestWuttaConfig(FileConfigTestCase): class TestWuttaConfig(FileTestCase):
def test_contstructor_basic(self): def test_contstructor_basic(self):
config = conf.WuttaConfig() config = conf.WuttaConfig()
@ -505,7 +505,7 @@ class TestGenericDefaultFiles(TestCase):
self.assertEqual(len(files), 0) self.assertEqual(len(files), 0)
class TestGetConfigPaths(FileConfigTestCase): class TestGetConfigPaths(FileTestCase):
def test_winsvc(self): def test_winsvc(self):
myconf = self.write_file('my.conf', """ myconf = self.write_file('my.conf', """
@ -523,7 +523,7 @@ winsvc.RattailFileMonitor = /path/to/other/file
self.assertEqual(files, []) self.assertEqual(files, [])
class TestMakeConfig(FileConfigTestCase): class TestMakeConfig(FileTestCase):
# nb. we use appname='wuttatest' in this suite to avoid any # nb. we use appname='wuttatest' in this suite to avoid any
# "valid" default config files, env vars etc. which may be present # "valid" default config files, env vars etc. which may be present

View file

@ -1,9 +1,7 @@
# -*- coding: utf-8; -*- # -*- coding: utf-8; -*-
from unittest import TestCase
from wuttjamaican import people as mod from wuttjamaican import people as mod
from wuttjamaican.conf import WuttaConfig from wuttjamaican.testing import DataTestCase
try: try:
import sqlalchemy as sa import sqlalchemy as sa
@ -12,41 +10,29 @@ except ImportError:
else: else:
class TestPeopleHandler(TestCase): class TestPeopleHandler(DataTestCase):
def setUp(self): def make_handler(self):
self.config = WuttaConfig() return mod.PeopleHandler(self.config)
self.app = self.config.get_app()
self.handler = mod.PeopleHandler(self.config)
self.engine = sa.create_engine('sqlite://')
self.app.model.Base.metadata.create_all(bind=self.engine)
self.session = self.make_session()
def tearDown(self):
self.session.close()
self.app.model.Base.metadata.drop_all(bind=self.engine)
def make_session(self):
return self.app.make_session(bind=self.engine)
def test_get_person(self): def test_get_person(self):
model = self.app.model model = self.app.model
myperson = model.Person(full_name='Barny Rubble') myperson = model.Person(full_name='Barny Rubble')
self.session.add(myperson) self.session.add(myperson)
self.session.commit() self.session.commit()
handler = self.make_handler()
# empty obj is ignored # empty obj is ignored
person = self.handler.get_person(None) person = handler.get_person(None)
self.assertIsNone(person) self.assertIsNone(person)
# person is returned as-is # person is returned as-is
person = self.handler.get_person(myperson) person = handler.get_person(myperson)
self.assertIs(person, myperson) self.assertIs(person, myperson)
# find person from user # find person from user
myuser = model.User(username='barney', person=myperson) myuser = model.User(username='barney', person=myperson)
self.session.add(myuser) self.session.add(myuser)
self.session.commit() self.session.commit()
person = self.handler.get_person(myuser) person = handler.get_person(myuser)
self.assertIs(person, myperson) self.assertIs(person, myperson)