diff --git a/oxrlib/config.py b/oxrlib/config.py index e85cb3a..682a550 100644 --- a/oxrlib/config.py +++ b/oxrlib/config.py @@ -123,17 +123,17 @@ class Configuration: "If you omit the year or month, it fills in the current year/month." ) hist_parser.add_argument( - 'word1', nargs='?', metavar='first code', + 'word1', nargs='?', metavar='amount', + help="Convert this amount of currency. If not specified, show rates.", + ) + hist_parser.add_argument( + 'word2', nargs='?', metavar='first code', help="Convert or show rates from this currency, in three-letter code format. " "If not specified, show all rates on the given date.", ) - hist_parser.add_argument( - 'word2', nargs='?', metavar='amount', - help="Convert this amount of currency. If not specified, show rates.", - ) hist_parser.add_argument( 'word3', nargs='?', metavar='second code', - help="Convert to this currency, in three-letter code format. " + help="Convert or show rates to this currency, in three-letter code format. " "If not specified, defaults to the base currency.", ) hist_parser.add_argument('word4', nargs='?', help=argparse.SUPPRESS) @@ -184,21 +184,25 @@ class Configuration: currency_list, convert_fallback=True) self._read_from_conffile('ledger', 'Historical', False, getter='getboolean') self.args.to_currency = self.args.base - if self.args.word4 and (self.args.word3.lower() in self.PREPOSITIONS): - self.args.word3 = self.args.word4 - if self.args.word1 is None: + raw_words = iter(getattr(self.args, 'word' + c) for c in '1234') + words = iter(word for word in raw_words if word is not None) + try: + next_word = next(words) + try: + self.args.amount = decimal.Decimal(next_word) + except decimal.InvalidOperation: + pass + else: + # If an amount was given, a currency code must be given too. + # If it wasn't, set a value that can't be parsed as a currency. + next_word = next(words, 'none given') + self.args.from_currency = self._convert_or_error(currency_code, next_word) + next_word = next(words) + if next_word.lower() in self.PREPOSITIONS: + next_word = next(words, next_word) + self.args.to_currency = self._convert_or_error(currency_code, next_word) + except StopIteration: pass - elif self.args.word2 is None: - self.args.from_currency = self._convert_or_error( - currency_code, self.args.word1) - else: - self.args.amount = self._convert_or_error( - decimal.Decimal, self.args.word1) - self.args.from_currency = self._convert_or_error( - currency_code, self.args.word2) - if self.args.word3 is not None: - self.args.to_currency = self._convert_or_error( - currency_code, self.args.word3 or self.args.base) def _build_cache_loader(self): kwargs = dict(self.conffile.items('Cache')) diff --git a/tests/test_Configuration.py b/tests/test_Configuration.py index 0f5e94d..4b34e91 100644 --- a/tests/test_Configuration.py +++ b/tests/test_Configuration.py @@ -49,6 +49,8 @@ def test_historical_default_base(ini_filename, expected_currency, use_switch, an @pytest.mark.parametrize('amount,from_curr,preposition,to_curr', [ (None, 'JPY', None, None), + (None, 'gbp', None, 'Aud'), + (None, 'CHF', 'to', 'eur'), (decimal.Decimal('1000'), 'chf', None, None), (decimal.Decimal('999'), 'Eur', None, 'Chf'), (decimal.Decimal('12.34'), 'gbp', 'IN', 'eur'), @@ -70,6 +72,8 @@ def test_historical_argparsing_success(amount, from_curr, preposition, to_curr, ['99', 'usd', 'minus', 'jpy'], ['usdjpy'], ['44', 'eur', 'in', 'chf', 'pronto'], + ['eur', 'into'], + ['50', 'jpy', 'in'], ]) def test_historical_argparsing_failure(arglist, any_date): arglist = ['historical', any_date.isoformat()] + arglist