config: Add Config.fiscal_year_begin() method.

This commit is contained in:
Brett Smith 2020-04-20 14:31:22 -04:00
parent 7f45788235
commit 894f044093
2 changed files with 61 additions and 0 deletions

View file

@ -15,9 +15,11 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import configparser
import datetime
import decimal
import functools
import os
import re
import urllib.parse as urlparse
import requests.auth
@ -27,6 +29,7 @@ from pathlib import Path
from typing import (
NamedTuple,
Optional,
Tuple,
Type,
)
@ -84,6 +87,9 @@ class Config:
with config_path.open() as config_file:
self.file_config.read_file(config_file)
def load_string(self, config_str: str) -> None:
self.file_config.read_string(config_str)
def _dir_or_none(self, path: Path) -> Optional[Path]:
try:
path.mkdir(exist_ok=True)
@ -124,6 +130,24 @@ class Config:
config_root = self._path_from_environ('XDG_CONFIG_HOME')
return Path(config_root, name, 'config.ini')
def fiscal_year_begin(self) -> Tuple[int, int]:
s = self.file_config.get('Beancount', 'fiscal year begin', fallback='3 1')
match = re.match(r'([01]?[0-9])(?:\s*[-./ ]\s*([0-3]?[0-9]))?$', s.strip())
if match is None:
raise ValueError(f"fiscal year begin {s!r} has unknown format")
try:
month = int(match.group(1))
day = int(match.group(2) or 1)
# To check date validity we use an arbitrary year that's
# 1. definitely using the modern calendar
# 2. far enough in the past to not have books (pre-Unix epoch)
# 3. not a leap year
datetime.date(1959, month, day)
except ValueError as e:
raise ValueError(f"fiscal year begin {s!r} is invalid date: {e.args[0]}")
else:
return (month, day)
def payment_threshold(self) -> decimal.Decimal:
return decimal.Decimal(0)

View file

@ -342,3 +342,40 @@ def test_load_file_error(tmp_path, path_func):
def test_no_books_path():
config = config_mod.Config()
assert config.books_path() is None
@pytest.mark.parametrize('value,month,day', [
('2', 2, 1),
('3 ', 3, 1),
(' 4', 4, 1),
(' 5 ', 5, 1),
('6 1', 6, 1),
(' 06 03 ', 6, 3),
('6-05', 6, 5),
('06 - 10', 6, 10),
('6/15', 6, 15),
('06 / 20', 6, 20),
('10.25', 10, 25),
(' 10 . 30 ', 10, 30),
])
def test_fiscal_year_begin(value, month, day):
config = config_mod.Config()
config.load_string(f'[Beancount]\nfiscal year begin = {value}\n')
assert config.fiscal_year_begin() == (month, day)
@pytest.mark.parametrize('value', [
'text',
'1900',
'13',
'010',
'2 30',
'4-31',
])
def test_bad_fiscal_year_begin(value):
config = config_mod.Config()
config.load_string(f'[Beancount]\nfiscal year begin = {value}\n')
with pytest.raises(ValueError):
config.fiscal_year_begin()
def test_default_fiscal_year_begin():
config = config_mod.Config()
assert config.fiscal_year_begin() == (3, 1)