def test_get_fiscal_period( year: int, quarter: Optional[int], fye: Optional[str], expect_start: str, expect_end: str, ) -> None: fye = parse_fye_string(fye) start_date, end_date = get_fiscal_period(year, fye, quarter) assert str(start_date) == expect_start assert str(end_date) == expect_end
def test_fiscal_substitute(fye: str, test_date: str, string: str, output: Optional[str]) -> None: fye = parse_fye_string(fye) with mock.patch("fava.util.date.datetime.date") as mock_date: mock_date.today.return_value = _to_date(test_date) mock_date.side_effect = date if output is None: with pytest.raises(ValueError): substitute(string, fye) else: assert substitute(string, fye) == output
def test_get_fiscal_period( year: int, quarter: int | None, fye_str: str | None, expect_start: str, expect_end: str, ) -> None: fye = parse_fye_string(fye_str) if fye_str else None start_date, end_date = get_fiscal_period(year, fye, quarter) assert str(start_date) == expect_start assert str(end_date) == expect_end
def parse_option_custom_entry(entry: Custom, options: FavaOptions) -> None: """Parse a single custom fava-option entry and set option accordingly.""" key = entry.values[0].value.replace("-", "_") assert key in All_OPTS, f"unknown option `{key}`" if key == "default_file": options.default_file = entry.meta["filename"] return value = entry.values[1].value assert isinstance(value, str), f"expected string value for option `{key}`" if key == "insert_entry": try: pattern = re.compile(value) except re.error: assert False, f"Should be a regular expression: '{value}'." opt = InsertEntryOption(entry.date, pattern, entry.meta["filename"], entry.meta["lineno"]) options.insert_entry.append(opt) elif key == "collapse_pattern": try: pattern = re.compile(value) except re.error: assert False, f"Should be a regular expression: '{value}'." options.collapse_pattern.append(pattern) elif key == "locale": try: Locale.parse(value) options.locale = value except UnknownLocaleError: assert False, f"Unknown locale: '{value}'." elif key == "fiscal_year_end": fye = parse_fye_string(value) assert fye, "Invalid 'fiscal_year_end' option." options.fiscal_year_end = fye elif key in STR_OPTS: setattr(options, key, value) elif key in BOOL_OPTS: setattr(options, key, value.lower() == "true") elif key in INT_OPTS: setattr(options, key, int(value)) else: assert key in TUPLE_OPTS, f"unknown option `{key}`" setattr(options, key, tuple(value.strip().split(" ")))
def parse_options( custom_entries: List[Custom], ) -> Tuple[FavaOptions, Iterable[BeancountError]]: """Parse custom entries for Fava options. The format for option entries is the following:: 2016-04-01 custom "fava-option" "[name]" "[value]" Args: custom_entries: A list of Custom entries. Returns: A tuple (options, errors) where options is a dictionary of all options to values, and errors contains possible parsing errors. """ options: FavaOptions = copy.deepcopy(DEFAULTS) errors = [] for entry in (e for e in custom_entries if e.type == "fava-option"): try: key = entry.values[0].value assert key in DEFAULTS.keys(), f"unknown option `{key}`" if key == "default-file": options[key] = entry.meta["filename"] elif key == "insert-entry": opt = InsertEntryOption( entry.date, re.compile(entry.values[1].value), entry.meta["filename"], entry.meta["lineno"], ) options[key].append(opt) else: value = entry.values[1].value assert isinstance( value, str ), f"expected value for option `{key}` to be a string" processed_value = None if key in STR_OPTS: processed_value = value elif key == "fiscal-year-end": processed_value = parse_fye_string(value) assert processed_value, "Invalid 'fiscal-year-end' option." elif key in BOOL_OPTS: processed_value = value.lower() == "true" elif key in INT_OPTS: processed_value = int(value) elif key in LIST_OPTS: processed_value = str(value).strip().split(" ") if processed_value is not None: if key in MULTI_OPTS: options[key].append(processed_value) else: options[key] = processed_value except (IndexError, TypeError, AssertionError) as err: msg = f"Failed to parse fava-option entry: {str(err)}" errors.append(OptionError(entry.meta, msg, entry)) return options, errors
def test_parse_fye_string(fye: str, expected: Optional[Tuple[int, int]]) -> None: fye_tuple = parse_fye_string(fye) assert fye_tuple == expected
def test_parse_fye_string(fye: str, expected: tuple[int, int] | None) -> None: fye_tuple = parse_fye_string(fye) assert fye_tuple == expected