config: Add Config.fiscal_year_begin() method.
This commit is contained in:
parent
7f45788235
commit
894f044093
2 changed files with 61 additions and 0 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue