Changeset - 18f7ea7038d3
[Not reviewed]
0 2 0
Brett Smith - 7 years ago 2017-05-17 16:29:50
brettcsmith@brettcsmith.org
Configuration: Set up CacheWriter.
2 files changed with 4 insertions and 1 deletions:
0 comments (0 inline, 0 general)
oxrlib/config.py
Show inline comments
 
import argparse
 
import configparser
 
import datetime
 
import decimal
 
import os.path
 
import pathlib
 

	
 
from . import loaders
 
from . import cache, loaders
 

	
 
HOME_PATH = pathlib.Path(os.path.expanduser('~'))
 
CONFFILE_SEED = """
 
[Historical]
 
base=USD
 
"""
 

	
 
def currency_code(s):
 
    if not ((len(s) == 3) and s.isalpha()):
 
        raise ValueError("bad currency code: {!r}".format(s))
 
    return s.upper()
 

	
 
def date_from(fmt_s):
 
    def date_from_fmt(s):
 
        return datetime.datetime.strptime(s, fmt_s).date
 
    return date_from_fmt
 

	
 
class Configuration:
 
    DEFAULT_CONFIG_PATH = pathlib.Path(HOME_PATH, '.config', 'oxrlib.ini')
 
    PREPOSITIONS = frozenset(['in', 'to', 'into'])
 

	
 
    def __init__(self, arglist):
 
        argparser = self._build_argparser()
 
        self.error = argparser.error
 
        self.args = argparser.parse_args(arglist)
 

	
 
        if self.args.config_file is None:
 
            self.args.config_file = [self.DEFAULT_CONFIG_PATH]
 
        self.conffile = self._build_conffile()
 
        conffile_paths = [path.as_posix() for path in self.args.config_file]
 
        read_files = self.conffile.read(conffile_paths)
 
        for expected_path, read_path in zip(conffile_paths, read_files):
...
 
@@ -98,51 +98,52 @@ class Configuration:
 
            self.error(': '.join(errmsg))
 

	
 
    def _post_hook_historical(self):
 
        if self.args.base is None:
 
            self.args.base = self.conffile.get('Historical', 'base')
 
        self.args.to_currency = self.args.base
 
        remain_len = len(self.args.remainder)
 
        if (remain_len > 3) and (self.args.remainder[2].lower() in self.PREPOSITIONS):
 
            del self.args.remainder[2]
 
            remain_len -= 1
 
        if remain_len == 0:
 
            pass
 
        elif remain_len == 1:
 
            self.args.from_currency = self._convert_or_error(
 
                currency_code, self.args.remainder[0])
 
        elif remain_len < 4:
 
            self.args.amount = self._convert_or_error(
 
                decimal.Decimal, self.args.remainder[0])
 
            self.args.from_currency = self._convert_or_error(
 
                currency_code, self.args.remainder[1])
 
            if remain_len == 3:
 
                self.args.to_currency = self._convert_or_error(
 
                    currency_code, self.args.remainder[2])
 
        else:
 
            self.error("too many arguments")
 

	
 
    def _build_cache_loader(self):
 
        kwargs = dict(self.conffile.items('Cache'))
 
        try:
 
            kwargs['dir_path'] = kwargs.pop('directory')
 
        except KeyError:
 
            pass
 
        self.cache = cache.CacheWriter(**kwargs)
 
        return loaders.FileCache(**kwargs)
 

	
 
    def _build_oxrapi_loader(self):
 
        kwargs = dict(self.conffile.items('OXR'))
 
        return loaders.OXRAPIRequest(**kwargs)
 

	
 
    def get_loaders(self):
 
        loader_chain = loaders.LoaderChain()
 
        for build_func in [
 
                self._build_cache_loader,
 
                self._build_oxrapi_loader,
 
        ]:
 
            try:
 
                loader = build_func()
 
            except (TypeError, ValueError, configparser.NoSectionError):
 
                pass
 
            else:
 
                loader_chain.add_loader(loader)
 
        return loader_chain
tests/test_Configuration.py
Show inline comments
 
import decimal
 
import os
 

	
 
import pytest
 

	
 
from . import any_date, relpath
 

	
 
import oxrlib.cache
 
import oxrlib.config
 
import oxrlib.loaders
 

	
 
INI_DIR_PATH = relpath('config_ini')
 

	
 
def config_from(ini_filename, arglist=None):
 
    if arglist is None:
 
        arglist = ['historical', any_date().isoformat()]
 
    ini_path = INI_DIR_PATH / ini_filename
 
    return oxrlib.config.Configuration(['--config-file', ini_path.as_posix()] + arglist)
 

	
 
def test_full_config():
 
    config = config_from('full.ini')
 
    loaders = config.get_loaders().loaders
 
    assert type(loaders[0]) is oxrlib.loaders.FileCache
 
    assert type(loaders[1]) is oxrlib.loaders.OXRAPIRequest
 
    assert len(loaders) == 2
 
    assert type(config.cache) is oxrlib.cache.CacheWriter
 

	
 
def test_incomplete_config():
 
    config = config_from('incomplete.ini')
 
    assert not config.get_loaders().loaders
 

	
 
def test_empty_config():
 
    config = config_from(os.devnull)
 
    assert not config.get_loaders().loaders
 

	
 
@pytest.mark.parametrize('ini_filename,expected_currency,use_switch', [
 
    (os.devnull, 'USD', False),
 
    ('full.ini', 'INI', False),
 
    ('full.ini', 'EUR', True),
 
])
 
def test_historical_default_base(ini_filename, expected_currency, use_switch, any_date):
 
    arglist = ['historical']
 
    if use_switch:
 
        arglist.extend(['--base', expected_currency])
 
    arglist.append(any_date.isoformat())
 
    config = config_from(ini_filename, arglist)
 
    assert config.args.base == expected_currency
 

	
 
@pytest.mark.parametrize('amount,from_curr,preposition,to_curr', [
 
    (None, 'JPY', None, None),
 
    (decimal.Decimal('1000'), 'chf', None, None),
 
    (decimal.Decimal('999'), 'Eur', None, 'Chf'),
 
    (decimal.Decimal('12.34'), 'gbp', 'IN', 'eur'),
 
])
 
def test_historical_argparsing_success(amount, from_curr, preposition, to_curr, any_date):
 
    arglist = ['historical', any_date.isoformat()]
 
    arglist.extend(str(s) for s in [amount, from_curr, preposition, to_curr]
 
                   if s is not None)
0 comments (0 inline, 0 general)