Changeset - 2bd3e8b462d2
[Not reviewed]
0 3 0
Brett Smith - 4 years ago 2020-06-04 13:03:10
brettcsmith@brettcsmith.org
books: Loader.from_all() accepts a start FY argument.
3 files changed with 61 insertions and 26 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/books.py
Show inline comments
...
 
@@ -137,8 +137,19 @@ class Loader:
 

	
 
    def load_all(self) -> LoadResult:
 
        """Load all of the books
 
    def _path_year(self, path: Path) -> int:
 
        return int(path.stem)
 

	
 
        This method loads all of the books. It finds the books by simply
 
        globbing the filesystem. It still loads each fiscal year in sequence to
 
        provide the best cache utilization.
 
    def load_all(self, from_year: Optional[Year]=None) -> LoadResult:
 
        """Load all of the books from a starting FY
 

	
 
        This method loads all of the books, starting from the fiscal year you
 
        specify.
 

	
 
        * Pass in a date to start from the FY for that date.
 
        * Pass in an integer >= 1000 to start from that year.
 
        * Pass in a smaller integer to start from an FY relative to today
 
          (e.g., -2 starts two FYs before today).
 
        * Pass is no argument to load all books from the first available FY.
 

	
 
        This method finds books by globbing the filesystem. It still loads
 
        each fiscal year in sequence to provide the best cache utilization.
 
        """
...
 
@@ -146,3 +157,14 @@ class Loader:
 
        fy_paths = list(path.glob('[1-9][0-9][0-9][0-9].beancount'))
 
        fy_paths.sort(key=lambda path: int(path.stem))
 
        fy_paths.sort(key=self._path_year)
 
        if from_year is not None:
 
            if not isinstance(from_year, int):
 
                from_year = self.fiscal_year.for_date(from_year)
 
            elif from_year < 1000:
 
                from_year = self.fiscal_year.for_date() + from_year
 
            for index, path in enumerate(fy_paths):
 
                if self._path_year(path) >= from_year:
 
                    fy_paths = fy_paths[index:]
 
                    break
 
            else:
 
                fy_paths = []
 
        return self._load_paths(iter(fy_paths))
...
 
@@ -156,5 +178,4 @@ class Loader:
 
        This method generates a range of fiscal years by calling
 
        FiscalYear.range() with its first two arguments. It returns a string of
 
        Beancount directives to load the books from the first available fiscal
 
        year through the end of the range.
 
        FiscalYear.range() with its arguments. It loads all the books within
 
        that range.
 
        """
tests/test_books_loader.py
Show inline comments
...
 
@@ -29,2 +29,4 @@ from conservancy_beancount import books
 

	
 
FY_START_MONTH = 3
 

	
 
books_path = testutil.test_path('books')
...
 
@@ -33,3 +35,3 @@ books_path = testutil.test_path('books')
 
def conservancy_loader():
 
    return books.Loader(books_path, books.FiscalYear(3))
 
    return books.Loader(books_path, books.FiscalYear(FY_START_MONTH))
 

	
...
 
@@ -43,14 +45,9 @@ def check_openings(entries):
 

	
 
def check_narrations(entries, expected):
 
    expected = iter(expected)
 
    expected_next = next(expected)
 
def txn_dates(entries):
 
    for entry in entries:
 
        if (isinstance(entry, bc_data.Transaction)
 
            and entry.narration == expected_next):
 
            try:
 
                expected_next = next(expected)
 
            except StopIteration:
 
                break
 
    else:
 
        assert None, f"{expected_next} not found in entry narrations"
 
        if isinstance(entry, bc_data.Transaction):
 
            yield entry.date
 

	
 
def txn_years(entries):
 
    return frozenset(date.year for date in txn_dates(entries))
 

	
...
 
@@ -72,3 +69,3 @@ def test_load_fy_range(conservancy_loader, from_fy, to_fy, expect_years):
 
    assert not errors
 
    check_narrations(entries, [f'{year} donation' for year in expect_years])
 
    assert txn_years(entries).issuperset(expect_years)
 

	
...
 
@@ -84,6 +81,23 @@ def test_load_fy_range_empty(conservancy_loader):
 

	
 
def test_load_all(conservancy_loader):
 
    entries, errors, options_map = conservancy_loader.load_all()
 
@pytest.mark.parametrize('from_year', [None, *range(2018, 2021)])
 
def test_load_all(conservancy_loader, from_year):
 
    entries, errors, options_map = conservancy_loader.load_all(from_year)
 
    from_year = from_year or 2018
 
    assert not errors
 
    check_openings(entries)
 
    assert txn_years(entries).issuperset(range(from_year or 2018, 2021))
 

	
 
@pytest.mark.parametrize('from_date', [
 
    date(2019, 2, 1),
 
    date(2019, 9, 15),
 
    date(2020, 1, 20),
 
    date(2020, 5, 31),
 
])
 
def test_load_all_from_date(conservancy_loader, from_date):
 
    from_year = from_date.year
 
    if from_date.month < FY_START_MONTH:
 
        from_year -= 1
 
    entries, errors, options_map = conservancy_loader.load_all(from_date)
 
    assert not errors
 
    check_narrations(entries, [f'{year} donation' for year in range(2018, 2021)])
 
    check_openings(entries)
 
    assert txn_years(entries).issuperset(range(from_year, 2021))
tests/testutil.py
Show inline comments
...
 
@@ -219,3 +219,3 @@ class TestBooksLoader(books.Loader):
 

	
 
    def load_all(self):
 
    def load_all(self, from_year=None):
 
        return bc_loader.load_file(self.source)
0 comments (0 inline, 0 general)