test: improve some tests, docs for rattail.config
module
still some left to do, just a stopping point
This commit is contained in:
parent
937f54681f
commit
c5c8c06ea7
|
@ -27,6 +27,7 @@
|
|||
model.batch.product
|
||||
model.batch.purchase
|
||||
model.batch.vendorcatalog
|
||||
model.core
|
||||
model.customers
|
||||
model.datasync
|
||||
model.labels
|
||||
|
|
33
docs/api/rattail/db/model.core.rst
Normal file
33
docs/api/rattail/db/model.core.rst
Normal file
|
@ -0,0 +1,33 @@
|
|||
|
||||
``rattail.db.model.core``
|
||||
=========================
|
||||
|
||||
.. automodule:: rattail.db.model.core
|
||||
|
||||
.. autoclass:: ModelBase
|
||||
|
||||
.. attribute:: model_title
|
||||
|
||||
Optionally set this to a "humanized" version of the model name, for
|
||||
display in templates etc. Default value will be guessed from the model
|
||||
class name, e.g. 'Product' => "Products" and 'CustomerOrder' => "Customer
|
||||
Order".
|
||||
|
||||
.. attribute:: model_title_plural
|
||||
|
||||
Optionally set this to a "humanized" version of the *plural* model name,
|
||||
for display in templates etc. Default value will be guessed from the
|
||||
model class name, e.g. 'Product' => "Products" and 'CustomerOrder' =>
|
||||
"Customer Orders".
|
||||
|
||||
.. autoclass:: Setting
|
||||
:members:
|
||||
|
||||
.. autoclass:: Change
|
||||
:members:
|
||||
|
||||
.. automodule:: rattail.db.model.contact
|
||||
:members:
|
||||
|
||||
.. todo::
|
||||
Geez a lot of work left here...
|
|
@ -2,32 +2,4 @@
|
|||
``rattail.db.model``
|
||||
====================
|
||||
|
||||
.. automodule:: rattail.db.model.core
|
||||
|
||||
.. autoclass:: ModelBase
|
||||
|
||||
.. attribute:: model_title
|
||||
|
||||
Optionally set this to a "humanized" version of the model name, for
|
||||
display in templates etc. Default value will be guessed from the model
|
||||
class name, e.g. 'Product' => "Products" and 'CustomerOrder' => "Customer
|
||||
Order".
|
||||
|
||||
.. attribute:: model_title_plural
|
||||
|
||||
Optionally set this to a "humanized" version of the *plural* model name,
|
||||
for display in templates etc. Default value will be guessed from the
|
||||
model class name, e.g. 'Product' => "Products" and 'CustomerOrder' =>
|
||||
"Customer Orders".
|
||||
|
||||
.. autoclass:: Setting
|
||||
:members:
|
||||
|
||||
.. autoclass:: Change
|
||||
:members:
|
||||
|
||||
.. automodule:: rattail.db.model.contact
|
||||
:members:
|
||||
|
||||
.. todo::
|
||||
Geez a lot of work left here...
|
||||
.. automodule:: rattail.db.model
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
try:
|
||||
from importlib.metadata import version
|
||||
except ImportError:
|
||||
except ImportError: # pragma: no cover
|
||||
from importlib_metadata import version
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ from wuttjamaican.conf import (WuttaConfig, WuttaConfigExtension,
|
|||
generic_default_files)
|
||||
from wuttjamaican.util import (parse_bool as wutta_parse_bool,
|
||||
parse_list as wutta_parse_list)
|
||||
from wuttjamaican.exc import ConfigurationError as WuttaConfigurationError
|
||||
|
||||
from rattail.exceptions import WindowsExtensionsNotInstalled, ConfigurationError
|
||||
|
||||
|
@ -44,13 +45,7 @@ log = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def parse_bool(value): # pragma: no cover
|
||||
"""
|
||||
Compatibility wrapper for
|
||||
:func:`wuttjamaican:wuttjamaican.util.parse_bool()`.
|
||||
|
||||
This function is deprecated; new code should use the upstream
|
||||
function instead.
|
||||
"""
|
||||
""" """
|
||||
warnings.warn("rattail.config.parse_bool() is deprecated; "
|
||||
"please use wuttjamaican.util.parse_bool() instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
@ -58,13 +53,7 @@ def parse_bool(value): # pragma: no cover
|
|||
|
||||
|
||||
def parse_list(value): # pragma: no cover
|
||||
"""
|
||||
Compatibility wrapper for
|
||||
:func:`wuttjamaican:wuttjamaican.util.parse_list()`.
|
||||
|
||||
This function is deprecated; new code should use the upstream
|
||||
function instead.
|
||||
"""
|
||||
""" """
|
||||
warnings.warn("rattail.config.parse_list() is deprecated; "
|
||||
"please use wuttjamaican.util.parse_list() instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
@ -120,7 +109,8 @@ class RattailConfig(WuttaConfig):
|
|||
normally expects just ``(key, value)`` args, but we also (for
|
||||
now) support the older style of ``(section, option, value)`` -
|
||||
*eventually* that will go away but probably not in the near
|
||||
future.
|
||||
future. However new code should pass ``(key, value)`` since
|
||||
that is now the preferred signature.
|
||||
"""
|
||||
# figure out what sort of args were passed
|
||||
if len(args) == 2:
|
||||
|
@ -143,7 +133,8 @@ class RattailConfig(WuttaConfig):
|
|||
normally expects just ``(key, ...)`` args, but we also (for
|
||||
now) support the older style of ``(section, option, ...)`` -
|
||||
*eventually* that will go away but probably not in the near
|
||||
future.
|
||||
future. However new code should pass ``(key, ...)`` since
|
||||
that is now the preferred signature.
|
||||
"""
|
||||
# figure out what sort of args were passed
|
||||
if len(args) == 1:
|
||||
|
@ -171,6 +162,30 @@ class RattailConfig(WuttaConfig):
|
|||
# DeprecationWarning, stacklevel=2)
|
||||
return self.get_bool(*args, **kwargs)
|
||||
|
||||
def get_date(self, *args, **kwargs):
|
||||
"""
|
||||
Retrieve a date value from config.
|
||||
|
||||
Accepts same params as :meth:`get()` but if a value is found,
|
||||
it will be coerced to date via
|
||||
:meth:`rattail.app.AppHandler.parse_date()`.
|
||||
"""
|
||||
value = self.get(*args, **kwargs)
|
||||
app = self.get_app()
|
||||
return app.parse_date(value)
|
||||
|
||||
def getdate(self, *args, **kwargs):
|
||||
"""
|
||||
Backward-compatible alias for :meth:`get_date()`.
|
||||
|
||||
New code should use ``get_date()`` instead of this method.
|
||||
"""
|
||||
# TODO: eventually
|
||||
# warnings.warn("config.getbool() method is deprecated; "
|
||||
# "please use config.get_bool() instead",
|
||||
# DeprecationWarning, stacklevel=2)
|
||||
return self.get_date(*args, **kwargs)
|
||||
|
||||
def getint(self, *args, **kwargs):
|
||||
"""
|
||||
Backward-compatible alias for
|
||||
|
@ -201,30 +216,14 @@ class RattailConfig(WuttaConfig):
|
|||
"""
|
||||
Convenience method around the
|
||||
:func:`~wuttjamaican:wuttjamaican.util.parse_bool()` function.
|
||||
|
||||
Usage of this method is discouraged, at least until some more
|
||||
dust settles. This probably belongs on the app handler
|
||||
instead so it can be overridden more easily.
|
||||
"""
|
||||
# TODO: eventually
|
||||
# warnings.warn("config.parse_bool() method is deprecated; "
|
||||
# "please use app.parse_bool() instead",
|
||||
# DeprecationWarning, stacklevel=2)
|
||||
return wutta_parse_bool(value)
|
||||
|
||||
def parse_list(self, value):
|
||||
"""
|
||||
Convenience method around the
|
||||
:func:`~wuttjamaican:wuttjamaican.util.parse_list()` function.
|
||||
|
||||
Usage of this method is discouraged, at least until some more
|
||||
dust settles. This probably belongs on the app handler
|
||||
instead so it can be overridden more easily.
|
||||
"""
|
||||
# TODO: eventually
|
||||
# warnings.warn("config.parse_list() method is deprecated; "
|
||||
# "please use app.parse_list() instead",
|
||||
# DeprecationWarning, stacklevel=2)
|
||||
return wutta_parse_list(value)
|
||||
|
||||
def make_list_string(self, values):
|
||||
|
@ -254,7 +253,7 @@ class RattailConfig(WuttaConfig):
|
|||
|
||||
def beaker_invalidate_setting(self, name):
|
||||
"""
|
||||
Backward-compatible method for unused Beaker caching logic.
|
||||
Deprecated method for unused Beaker caching logic.
|
||||
|
||||
This method has no effect and should not be used.
|
||||
"""
|
||||
|
@ -262,18 +261,6 @@ class RattailConfig(WuttaConfig):
|
|||
# warnings.warn("config.beaker_invalidate_setting() method is deprecated",
|
||||
# DeprecationWarning, stacklevel=2)
|
||||
|
||||
def node_type(self, default=None):
|
||||
"""
|
||||
Returns the "type" of current node. What this means will
|
||||
generally depend on the app logic.
|
||||
"""
|
||||
try:
|
||||
return self.require('rattail', 'node_type', usedb=False)
|
||||
except ConfigurationError:
|
||||
if default:
|
||||
return default
|
||||
raise
|
||||
|
||||
def production(self):
|
||||
"""
|
||||
Returns boolean indicating whether the app is running in
|
||||
|
@ -281,10 +268,23 @@ class RattailConfig(WuttaConfig):
|
|||
"""
|
||||
return self.getbool('rattail', 'production', default=False)
|
||||
|
||||
def node_type(self, default=None):
|
||||
"""
|
||||
Returns the "type" of current node as string. What this means
|
||||
will generally depend on the app logic. There is no default
|
||||
node type unless caller provides one.
|
||||
"""
|
||||
try:
|
||||
return self.require('rattail', 'node_type', usedb=False)
|
||||
except WuttaConfigurationError:
|
||||
if default:
|
||||
return default
|
||||
raise
|
||||
|
||||
def get_model(self):
|
||||
"""
|
||||
Returns a reference to configured 'model' module; defaults to
|
||||
:mod:`rattail.db.model`.
|
||||
Returns a reference to the module containing data models;
|
||||
defaults to :mod:`rattail.db.model`.
|
||||
"""
|
||||
spec = self.get('rattail', 'model', usedb=False,
|
||||
default='rattail.db.model')
|
||||
|
@ -303,7 +303,8 @@ class RattailConfig(WuttaConfig):
|
|||
"""
|
||||
Returns a reference to the configured data 'model' module for
|
||||
Trainwreck. Note that there is *not* a default value for
|
||||
this; it must be configured.
|
||||
this; it must be configured or else calling this method will
|
||||
result in an error.
|
||||
"""
|
||||
spec = self.require('rattail.trainwreck', 'model', usedb=False)
|
||||
return importlib.import_module(spec)
|
||||
|
@ -315,29 +316,15 @@ class RattailConfig(WuttaConfig):
|
|||
return self.getbool('rattail.db', 'versioning.enabled', usedb=False,
|
||||
default=False)
|
||||
|
||||
def getdate(self, *args, **kwargs):
|
||||
"""
|
||||
Retrieve a date value from config.
|
||||
"""
|
||||
value = self.get(*args, **kwargs)
|
||||
app = self.get_app()
|
||||
return app.parse_date(value)
|
||||
|
||||
def product_key(self, **kwargs):
|
||||
"""
|
||||
Deprecated; instead please see
|
||||
:meth:`rattail.app.AppHandler.get_product_key_field()`.
|
||||
"""
|
||||
def product_key(self, **kwargs): # pragma: no cover
|
||||
""" """
|
||||
warnings.warn("config.product_key() is deprecated; please "
|
||||
"use app.get_product_key_field() instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return self.get_app().get_product_key_field()
|
||||
|
||||
def product_key_title(self, key=None):
|
||||
"""
|
||||
Deprecated; instead please see
|
||||
:meth:`rattail.app.AppHandler.get_product_key_label()`.
|
||||
"""
|
||||
def product_key_title(self, key=None): # pragma: no cover
|
||||
""" """
|
||||
warnings.warn("config.product_key_title() is deprecated; please "
|
||||
"use app.get_product_key_label() instead",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
|
@ -352,14 +339,20 @@ class RattailConfig(WuttaConfig):
|
|||
return self.get('rattail', 'app_package', default=default)
|
||||
|
||||
def app_title(self, **kwargs):
|
||||
""" DEPRECATED """
|
||||
"""
|
||||
DEPRECATED; use :meth:`rattail.app.AppHandler.get_title()`
|
||||
instead.
|
||||
"""
|
||||
# TODO: should put a deprecation warning here, but it could
|
||||
# make things noisy for a while and i'm not ready for that
|
||||
app = self.get_app()
|
||||
return app.get_title(**kwargs)
|
||||
|
||||
def node_title(self, **kwargs):
|
||||
""" DEPRECATED """
|
||||
"""
|
||||
DEPRECATED; use
|
||||
:meth:`rattail.app.AppHandler.get_node_title()` instead.
|
||||
"""
|
||||
# TODO: should put a deprecation warning here, but it could
|
||||
# make things noisy for a while and i'm not ready for that
|
||||
app = self.get_app()
|
||||
|
@ -369,18 +362,28 @@ class RattailConfig(WuttaConfig):
|
|||
"""
|
||||
Returns boolean indicating whether the app is running from
|
||||
source, as opposed to official release.
|
||||
|
||||
.. warning::
|
||||
|
||||
The utility of this method is questionable and it ideally
|
||||
will go away in the future.
|
||||
"""
|
||||
return self.getbool('rattail', 'running_from_source', default=False)
|
||||
|
||||
def demo(self):
|
||||
"""
|
||||
Returns boolean indicating whether the app is running in demo mode
|
||||
|
||||
.. warning::
|
||||
|
||||
The utility of this method is questionable and it ideally
|
||||
will go away in the future.
|
||||
"""
|
||||
return self.getbool('rattail', 'demo', default=False)
|
||||
|
||||
def appdir(self, require=True, **kwargs):
|
||||
"""
|
||||
Returns path to the 'app' dir, if known.
|
||||
Returns path to the local 'app' dir.
|
||||
"""
|
||||
if require:
|
||||
path = os.path.join(sys.prefix, 'app')
|
||||
|
@ -405,7 +408,7 @@ class RattailConfig(WuttaConfig):
|
|||
def batch_filedir(self, key=None):
|
||||
"""
|
||||
Returns path to root folder where batches (optionally of type
|
||||
'key') are stored.
|
||||
``key``) are stored.
|
||||
"""
|
||||
path = os.path.abspath(self.require('rattail', 'batch.files'))
|
||||
if key:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
################################################################################
|
||||
#
|
||||
# Rattail -- Retail Software Framework
|
||||
# Copyright © 2010-2023 Lance Edgar
|
||||
# Copyright © 2010-2024 Lance Edgar
|
||||
#
|
||||
# This file is part of Rattail.
|
||||
#
|
||||
|
@ -22,6 +22,9 @@
|
|||
################################################################################
|
||||
"""
|
||||
Rattail data models
|
||||
|
||||
This namespace will be populated with all data model classes defined
|
||||
by Rattail.
|
||||
"""
|
||||
|
||||
from .core import Base, ModelBase, uuid_column, getset_factory, GPCType, Setting, Change, Note
|
||||
|
|
|
@ -3,120 +3,17 @@
|
|||
import configparser
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
from unittest import TestCase
|
||||
from unittest.mock import patch
|
||||
|
||||
from wuttjamaican.testing import FileConfigTestCase
|
||||
from wuttjamaican.exc import ConfigurationError
|
||||
|
||||
from rattail import config
|
||||
from rattail.app import AppHandler
|
||||
|
||||
|
||||
class TestRattailConfig(FileConfigTestCase):
|
||||
|
||||
def setup_files(self):
|
||||
self.site_path = self.write_file('site.conf', """
|
||||
[rattail]
|
||||
""")
|
||||
|
||||
self.host_path = self.write_file('host.conf', """
|
||||
[rattail.config]
|
||||
include = "{}"
|
||||
""".format(self.site_path))
|
||||
|
||||
self.app_path = self.write_file('app.conf', """
|
||||
[rattail.config]
|
||||
include = "{}"
|
||||
""".format(self.host_path))
|
||||
|
||||
self.custom_path = self.write_file('custom.conf', """
|
||||
[rattail.config]
|
||||
include = "%(here)s/app.conf"
|
||||
""")
|
||||
|
||||
def test_init_defaults(self):
|
||||
cfg = config.RattailConfig()
|
||||
self.assertEqual(cfg.files_requested, [])
|
||||
self.assertEqual(cfg.files_read, [])
|
||||
|
||||
def test_init_params(self):
|
||||
self.setup_files()
|
||||
|
||||
# files
|
||||
cfg = config.RattailConfig()
|
||||
self.assertEqual(cfg.files_requested, [])
|
||||
self.assertEqual(cfg.files_read, [])
|
||||
cfg = config.RattailConfig(files=[self.site_path])
|
||||
self.assertEqual(cfg.files_requested, [self.site_path])
|
||||
self.assertEqual(cfg.files_read, [self.site_path])
|
||||
|
||||
# usedb
|
||||
cfg = config.RattailConfig()
|
||||
self.assertFalse(cfg.usedb)
|
||||
cfg = config.RattailConfig(usedb=True)
|
||||
self.assertTrue(cfg.usedb)
|
||||
|
||||
# preferdb
|
||||
cfg = config.RattailConfig()
|
||||
self.assertFalse(cfg.preferdb)
|
||||
cfg = config.RattailConfig(preferdb=True)
|
||||
self.assertTrue(cfg.preferdb)
|
||||
|
||||
def test_read_file_with_recurse(self):
|
||||
self.setup_files()
|
||||
cfg = config.RattailConfig()
|
||||
cfg.read_file(self.custom_path, recurse=True)
|
||||
self.assertEqual(cfg.files_requested, [self.custom_path, self.app_path, self.host_path, self.site_path])
|
||||
self.assertEqual(cfg.files_read, [self.site_path, self.host_path, self.app_path, self.custom_path])
|
||||
|
||||
def test_read_file_once_only(self):
|
||||
self.setup_files()
|
||||
|
||||
another_path = self.write_file('another.conf', """
|
||||
[rattail.config]
|
||||
include = "{custom}" "{site}" "{app}" "{site}" "{custom}"
|
||||
""".format(custom=self.custom_path, app=self.app_path, site=self.site_path))
|
||||
|
||||
cfg = config.RattailConfig()
|
||||
cfg.read_file(another_path, recurse=True)
|
||||
self.assertEqual(cfg.files_requested, [another_path, self.custom_path, self.app_path, self.host_path, self.site_path])
|
||||
self.assertEqual(cfg.files_read, [self.site_path, self.host_path, self.app_path, self.custom_path, another_path])
|
||||
|
||||
def test_read_file_skip_missing(self):
|
||||
self.setup_files()
|
||||
bogus_path = '/tmp/does-not/exist'
|
||||
self.assertFalse(os.path.exists(bogus_path))
|
||||
|
||||
another_path = self.write_file('another.conf', """
|
||||
[rattail.config]
|
||||
include = "{bogus}" "{app}" "{bogus}" "{site}"
|
||||
""".format(bogus=bogus_path, app=self.app_path, site=self.site_path))
|
||||
|
||||
cfg = config.RattailConfig()
|
||||
cfg.read_file(another_path, recurse=True)
|
||||
self.assertEqual(cfg.files_requested, [another_path, bogus_path, self.app_path, self.host_path, self.site_path])
|
||||
self.assertEqual(cfg.files_read, [self.site_path, self.host_path, self.app_path, another_path])
|
||||
|
||||
@patch('rattail.config.logging.config.fileConfig')
|
||||
def test_configure_logging(self, fileConfig):
|
||||
cfg = config.RattailConfig()
|
||||
|
||||
# logging not configured by default
|
||||
cfg.configure_logging()
|
||||
self.assertFalse(fileConfig.called)
|
||||
|
||||
# but config option can enable it
|
||||
cfg.set('rattail.config', 'configure_logging', 'true')
|
||||
cfg.configure_logging()
|
||||
self.assertEqual(fileConfig.call_count, 1)
|
||||
fileConfig.reset_mock()
|
||||
|
||||
# invalid logging config is ignored
|
||||
fileConfig.side_effect = configparser.NoSectionError('loggers')
|
||||
cfg.configure_logging()
|
||||
self.assertEqual(fileConfig.call_count, 1)
|
||||
|
||||
|
||||
class TestRattailConfig(FileConfigTestCase):
|
||||
|
||||
def test_prioritized_files(self):
|
||||
|
@ -135,7 +32,6 @@ require = %(here)s/first.conf
|
|||
self.assertEqual(len(files), 2)
|
||||
self.assertEqual(files[0], second)
|
||||
self.assertEqual(files[1], first)
|
||||
self.assertIs(files, myconfig.get_prioritized_files())
|
||||
|
||||
def test_setdefault(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
@ -164,12 +60,42 @@ require = %(here)s/first.conf
|
|||
# try that for get() too
|
||||
self.assertRaises(ValueError, myconfig.get, 'foo', 'bar', 'blarg', 'blast')
|
||||
|
||||
def test_get(self):
|
||||
myconfig = config.RattailConfig()
|
||||
myconfig.setdefault('foo.bar', 'baz')
|
||||
|
||||
# can pass section + option
|
||||
self.assertEqual(myconfig.get('foo', 'bar'), 'baz')
|
||||
|
||||
# or can pass just a key
|
||||
self.assertEqual(myconfig.get('foo.bar'), 'baz')
|
||||
|
||||
# so 1 or 2 args required, otherwise error
|
||||
self.assertRaises(ValueError, myconfig.get, 'foo', 'bar', 'baz')
|
||||
self.assertRaises(ValueError, myconfig.get)
|
||||
|
||||
def test_getbool(self):
|
||||
myconfig = config.RattailConfig()
|
||||
self.assertFalse(myconfig.getbool('foo.bar'))
|
||||
myconfig.setdefault('foo.bar', 'true')
|
||||
self.assertTrue(myconfig.getbool('foo.bar'))
|
||||
|
||||
def test_get_date(self):
|
||||
myconfig = config.RattailConfig()
|
||||
self.assertIsNone(myconfig.get_date('foo.date'))
|
||||
myconfig.setdefault('foo.date', '2023-11-20')
|
||||
value = myconfig.get_date('foo.date')
|
||||
self.assertIsInstance(value, datetime.date)
|
||||
self.assertEqual(value, datetime.date(2023, 11, 20))
|
||||
|
||||
def test_getdate(self):
|
||||
myconfig = config.RattailConfig()
|
||||
self.assertIsNone(myconfig.getdate('foo.date'))
|
||||
myconfig.setdefault('foo.date', '2023-11-20')
|
||||
value = myconfig.getdate('foo.date')
|
||||
self.assertIsInstance(value, datetime.date)
|
||||
self.assertEqual(value, datetime.date(2023, 11, 20))
|
||||
|
||||
def test_getint(self):
|
||||
myconfig = config.RattailConfig()
|
||||
self.assertIsNone(myconfig.getint('foo.bar'))
|
||||
|
@ -182,20 +108,6 @@ require = %(here)s/first.conf
|
|||
myconfig.setdefault('foo.bar', 'hello world')
|
||||
self.assertEqual(myconfig.getlist('foo.bar'), ['hello', 'world'])
|
||||
|
||||
def test_getdate(self):
|
||||
myconfig = config.RattailConfig()
|
||||
self.assertIsNone(myconfig.getdate('foo.date'))
|
||||
myconfig.setdefault('foo.date', '2023-11-20')
|
||||
value = myconfig.getdate('foo.date')
|
||||
self.assertIsInstance(value, datetime.date)
|
||||
self.assertEqual(value, datetime.date(2023, 11, 20))
|
||||
|
||||
def test_get_app(self):
|
||||
myconfig = config.RattailConfig()
|
||||
app = myconfig.get_app()
|
||||
self.assertIsInstance(app, AppHandler)
|
||||
self.assertIs(type(app), AppHandler)
|
||||
|
||||
def test_parse_bool(self):
|
||||
myconfig = config.RattailConfig()
|
||||
self.assertTrue(myconfig.parse_bool('true'))
|
||||
|
@ -218,11 +130,195 @@ require = %(here)s/first.conf
|
|||
value = myconfig.make_list_string(["you don't", 'say'])
|
||||
self.assertEqual(value, "\"you don't\", say")
|
||||
|
||||
def test_get_app(self):
|
||||
myconfig = config.RattailConfig()
|
||||
app = myconfig.get_app()
|
||||
self.assertIsInstance(app, AppHandler)
|
||||
self.assertIs(type(app), AppHandler)
|
||||
|
||||
def test_beaker_invalidate_setting(self):
|
||||
# TODO: this doesn't really test anything, just gives coverage
|
||||
myconfig = config.RattailConfig()
|
||||
myconfig.beaker_invalidate_setting('foo')
|
||||
|
||||
def test_production(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# false if not defined
|
||||
self.assertFalse(myconfig.production())
|
||||
|
||||
# but config may specify
|
||||
myconfig.setdefault('rattail.production', 'true')
|
||||
self.assertTrue(myconfig.production())
|
||||
|
||||
def test_node_type(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# error if node type not defined
|
||||
self.assertRaises(ConfigurationError, myconfig.node_type)
|
||||
|
||||
# unless default is provided
|
||||
self.assertEqual(myconfig.node_type(default='foo'), 'foo')
|
||||
|
||||
# or config contains the definition
|
||||
myconfig.setdefault('rattail.node_type', 'bar')
|
||||
self.assertEqual(myconfig.node_type(), 'bar')
|
||||
|
||||
def test_get_model(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# default is rattail.db.model
|
||||
model = myconfig.get_model()
|
||||
self.assertIs(model, sys.modules['rattail.db.model'])
|
||||
|
||||
# or config may specify
|
||||
myconfig.setdefault('rattail.model', 'rattail.trainwreck.db.model')
|
||||
model = myconfig.get_model()
|
||||
self.assertIs(model, sys.modules['rattail.trainwreck.db.model'])
|
||||
|
||||
def test_get_enum(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# default is rattail.enum
|
||||
enum = myconfig.get_enum()
|
||||
self.assertIs(enum, sys.modules['rattail.enum'])
|
||||
|
||||
# or config may specify
|
||||
# (nb. using bogus example module here)
|
||||
myconfig.setdefault('rattail.enum', 'rattail.auth')
|
||||
enum = myconfig.get_enum()
|
||||
self.assertIs(enum, sys.modules['rattail.auth'])
|
||||
|
||||
def test_get_trainwreck_model(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# error if not defined
|
||||
self.assertRaises(ConfigurationError, myconfig.get_trainwreck_model)
|
||||
|
||||
# but config may specify
|
||||
myconfig.setdefault('rattail.trainwreck.model', 'rattail.trainwreck.db.model')
|
||||
model = myconfig.get_trainwreck_model()
|
||||
self.assertIs(model, sys.modules['rattail.trainwreck.db.model'])
|
||||
|
||||
def test_versioning_enabled(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# false by default
|
||||
self.assertFalse(myconfig.versioning_enabled())
|
||||
|
||||
# but config may enable
|
||||
myconfig.setdefault('rattail.db.versioning.enabled', 'true')
|
||||
self.assertTrue(myconfig.versioning_enabled())
|
||||
|
||||
def test_app_package(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# error if not defined
|
||||
self.assertRaises(ConfigurationError, myconfig.app_package)
|
||||
|
||||
# unless default is provided
|
||||
self.assertEqual(myconfig.app_package(default='foo'), 'foo')
|
||||
|
||||
# but config may specify
|
||||
myconfig.setdefault('rattail.app_package', 'bar')
|
||||
self.assertEqual(myconfig.app_package(), 'bar')
|
||||
|
||||
def test_app_title(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# default title
|
||||
self.assertEqual(myconfig.app_title(), 'Rattail')
|
||||
|
||||
# but config may specify
|
||||
myconfig.setdefault('rattail.app_title', 'Foo')
|
||||
self.assertEqual(myconfig.app_title(), 'Foo')
|
||||
|
||||
def test_node_title(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# default title
|
||||
self.assertEqual(myconfig.app_title(), 'Rattail')
|
||||
|
||||
# but config may specify
|
||||
myconfig.setdefault('rattail.node_title', 'Foo (node)')
|
||||
self.assertEqual(myconfig.node_title(), 'Foo (node)')
|
||||
|
||||
def test_running_from_source(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# false by default
|
||||
self.assertFalse(myconfig.running_from_source())
|
||||
|
||||
# but config may enable
|
||||
myconfig.setdefault('rattail.running_from_source', 'true')
|
||||
self.assertTrue(myconfig.running_from_source())
|
||||
|
||||
def test_demo(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# false by default
|
||||
self.assertFalse(myconfig.demo())
|
||||
|
||||
# but config may enable
|
||||
myconfig.setdefault('rattail.demo', 'true')
|
||||
self.assertTrue(myconfig.demo())
|
||||
|
||||
def test_appdir(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# can be none if required is false
|
||||
self.assertIsNone(myconfig.appdir(require=False))
|
||||
|
||||
# otherwise sane fallback is used
|
||||
with patch('rattail.config.sys') as sys:
|
||||
sys.prefix = 'foo'
|
||||
path = os.path.join('foo', 'app')
|
||||
self.assertEqual(myconfig.appdir(), path)
|
||||
|
||||
# or config may specify
|
||||
myconfig.setdefault('rattail.appdir', '/foo/bar/baz')
|
||||
self.assertEqual(myconfig.appdir(), '/foo/bar/baz')
|
||||
|
||||
def test_datadir(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# error if not defined
|
||||
self.assertRaises(ConfigurationError, myconfig.datadir)
|
||||
|
||||
# but can avoid error if not required
|
||||
self.assertIsNone(myconfig.datadir(require=False))
|
||||
|
||||
# or config may specify
|
||||
myconfig.setdefault('rattail.datadir', '/foo/bar/baz')
|
||||
self.assertEqual(myconfig.datadir(), '/foo/bar/baz')
|
||||
|
||||
def test_workdir(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# error if not defined
|
||||
self.assertRaises(ConfigurationError, myconfig.workdir)
|
||||
|
||||
# but can avoid error if not required
|
||||
self.assertIsNone(myconfig.workdir(require=False))
|
||||
|
||||
# or config may specify
|
||||
myconfig.setdefault('rattail.workdir', '/foo/bar/baz')
|
||||
self.assertEqual(myconfig.workdir(), '/foo/bar/baz')
|
||||
|
||||
def test_batch_filedir(self):
|
||||
myconfig = config.RattailConfig()
|
||||
|
||||
# error if not defined
|
||||
self.assertRaises(ConfigurationError, myconfig.batch_filedir)
|
||||
|
||||
# config may specify
|
||||
path = os.path.join(os.sep, 'foo', 'files')
|
||||
myconfig.setdefault('rattail.batch.files', path)
|
||||
self.assertEqual(myconfig.batch_filedir(), path)
|
||||
|
||||
# caller may specify a key
|
||||
self.assertEqual(myconfig.batch_filedir(key='bar'), os.path.join(path, 'bar'))
|
||||
|
||||
|
||||
class TestRattailDefaultFiles(FileConfigTestCase):
|
||||
|
||||
|
|
Loading…
Reference in a new issue