Changeset - 08073f752bc8
[Not reviewed]
0 2 0
Brett Smith - 7 years ago 2017-05-17 15:32:05
brettcsmith@brettcsmith.org
Configuration: Parse more conversion arguments for historical subcommand.
2 files changed with 80 insertions and 2 deletions:
0 comments (0 inline, 0 general)
oxrlib/config.py
Show inline comments
...
 
@@ -3,2 +3,3 @@ import configparser
 
import datetime
 
import decimal
 
import os.path
...
 
@@ -15,3 +16,3 @@ base=USD
 
def currency_code(s):
 
    if not (len(s) == 3) and s.isalpha():
 
    if not ((len(s) == 3) and s.isalpha()):
 
        raise ValueError("bad currency code: {!r}".format(s))
...
 
@@ -26,2 +27,3 @@ class Configuration:
 
    DEFAULT_CONFIG_PATH = pathlib.Path(HOME_PATH, '.config', 'oxrlib.ini')
 
    PREPOSITIONS = frozenset(['in', 'to', 'into'])
 

	
...
 
@@ -58,5 +60,10 @@ class Configuration:
 
        hist_parser = subparsers.add_parser('historical', aliases=['hist'])
 
        hist_parser.set_defaults(command='historical')
 
        hist_parser.set_defaults(
 
            command='historical',
 
            amount=None,
 
            from_currency=None,
 
        )
 
        hist_parser.add_argument(
 
            '--base',
 
            type=currency_code,
 
            help="Base currency (default USD)",
...
 
@@ -67,2 +74,6 @@ class Configuration:
 
        )
 
        hist_parser.add_argument(
 
            'remainder',
 
            nargs=argparse.REMAINDER,
 
        )
 

	
...
 
@@ -75,2 +86,15 @@ class Configuration:
 

	
 
    def _convert_or_error(self, argtype, s_value, argname=None, typename=None):
 
        try:
 
            return argtype(s_value)
 
        except (decimal.InvalidOperation, TypeError, ValueError):
 
            errmsg = []
 
            if argname:
 
                errmsg.append("argument {}".format(argname))
 
            if typename is None:
 
                typename = argtype.__name__.replace('_', ' ')
 
            errmsg.append("invalid {} value".format(typename))
 
            errmsg.append(repr(s_value))
 
            self.error(': '.join(errmsg))
 

	
 
    def _post_hook_historical(self):
...
 
@@ -78,2 +102,22 @@ class Configuration:
 
            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")
 

	
tests/test_Configuration.py
Show inline comments
 
import decimal
 
import os
...
 
@@ -44 +45,34 @@ def test_historical_default_base(ini_filename, expected_currency, use_switch, an
 
    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)
 
    config = config_from(os.devnull, arglist)
 
    assert config.args.amount == amount
 
    assert config.args.from_currency == from_curr.upper()
 
    if to_curr is not None:
 
        assert config.args.to_currency == to_curr.upper()
 

	
 
@pytest.mark.parametrize('arglist', [
 
    ['100'],
 
    ['120', 'dollars'],
 
    ['to', '42', 'usd'],
 
    ['99', 'usd', 'minus', 'jpy'],
 
    ['usdjpy'],
 
    ['44', 'eur', 'in', 'chf', 'pronto'],
 
])
 
def test_historical_argparsing_failure(arglist, any_date):
 
    arglist = ['historical', any_date.isoformat()] + arglist
 
    try:
 
        config = config_from(os.devnull, arglist)
 
    except SystemExit:
 
        pass
 
    else:
 
        assert not vars(config.args), "bad arglist succeeded"
0 comments (0 inline, 0 general)