Files @ 5784068904e8
Branch filter:

Location: NPO-Accounting/conservancy_beancount/tests/test_books_fiscal_year.py

bkuhn
payroll-type — US:403b:Employee:Roth — needed separate since taxable

Since Roth contributions are taxable, there are some reports that
need to include these amounts in total salary (i.e., when running a
report that seeks to show total taxable income for an employee). As
such, we need a `payroll-type` specifically for Roth 403(b)
contributions.
"""test_books_fiscal_year - Unit tests for books.FiscalYear"""
# Copyright © 2020  Brett Smith
# License: AGPLv3-or-later WITH Beancount-Plugin-Additional-Permission-1.0
#
# Full copyright and licensing details can be found at toplevel file
# LICENSE.txt in the repository.

import datetime
import itertools

import pytest

from conservancy_beancount import books

@pytest.fixture(scope='module')
def conservancy_fy():
    return books.FiscalYear(3, 1)

@pytest.fixture(scope='module')
def cy_fy():
    return books.FiscalYear(1, 1)

# Not bothering because it's too much trouble to override __new__
# @pytest.mark.parametrize('month,day', [
#     (0, 0),
#     (2, 29),
#     (4, 31),
#     (13, 15),
#     (-1, 1),
#     (1, -5),
# ])
# def test_values_checked(month, day):
#     with pytest.raises(ValueError):
#         books.FiscalYear(month, day)

def test_attribute_access():
    fy = books.FiscalYear(2, 15)
    assert fy.month == 2
    assert fy.day == 15
    with pytest.raises(AttributeError):
        fy.year

@pytest.mark.parametrize('month,day,expected', [
    (1, 1, 2019),
    (2, 15, 2019),
    (2, 28, 2019),
    (2, 29, 2019),
    (3, 1, 2020),
    (3, 9, 2020),
    (6, 1, 2020),
    (12, 31, 2020),
])
def test_for_date(conservancy_fy, month, day, expected):
    date = datetime.date(2020, month, day)
    assert conservancy_fy.for_date(date) == expected

def test_for_date_default_today(cy_fy):
    assert cy_fy.for_date() == datetime.date.today().year

@pytest.mark.parametrize('begin_date,end_date,expected', [
    ((2020, 3, 1), (2021, 2, 28), [2020]),
    ((2020, 1, 1), (2020, 3, 1), [2019]),
    ((2020, 1, 1), (2020, 3, 5), [2019, 2020]),
    ((2019, 2, 1), (2020, 6, 1), [2018, 2019, 2020]),
])
def test_range_two_dates(conservancy_fy, begin_date, end_date, expected):
    actual = list(conservancy_fy.range(datetime.date(*begin_date), datetime.date(*end_date)))
    assert actual == expected

@pytest.mark.parametrize('year_offset', range(3))
def test_range_one_date(cy_fy, year_offset):
    this_year = datetime.date.today().year
    actual = list(cy_fy.range(datetime.date(this_year - year_offset, 1, 1)))
    assert actual == list(range(this_year - year_offset, this_year + 1))

@pytest.mark.parametrize('begin_year,end_year', [
    (2006, 2020),
    (2019, 2020),
    (2020, 2020),
])
def test_range_two_years(conservancy_fy, begin_year, end_year):
    actual = list(conservancy_fy.range(begin_year, end_year))
    assert actual == list(range(begin_year, end_year + 1))

@pytest.mark.parametrize('year_offset', range(3))
def test_range_one_year(cy_fy, year_offset):
    this_year = datetime.date.today().year
    actual = list(cy_fy.range(this_year - year_offset))
    assert actual == list(range(this_year - year_offset, this_year + 1))

@pytest.mark.parametrize('year_offset,month_offset', itertools.product(
    range(-3, 3),
    [-1, 1]
))
def test_range_offset_and_date(conservancy_fy, year_offset, month_offset):
    end_date = datetime.date(2020, conservancy_fy.month + month_offset, 10)
    base_year = end_date.year
    if month_offset < 0:
        base_year -= 1
    if year_offset < 0:
        expected = range(base_year + year_offset, base_year + 1)
    else:
        expected = range(base_year, base_year + year_offset + 1)
    actual = list(conservancy_fy.range(year_offset, end_date))
    assert actual == list(expected)

@pytest.mark.parametrize('year_offset,year', itertools.product(
    range(-3, 3),
    [2010, 2015],
))
def test_range_offset_and_year(conservancy_fy, year_offset, year):
    if year_offset < 0:
        expected = range(year + year_offset, year + 1)
    else:
        expected = range(year, year + year_offset + 1)
    actual = list(conservancy_fy.range(year_offset, year))
    assert actual == list(expected)

@pytest.mark.parametrize('year_offset', range(-3, 3))
def test_range_offset_only(cy_fy, year_offset):
    year = datetime.date.today().year
    if year_offset < 0:
        expected = range(year + year_offset, year + 1)
    else:
        expected = range(year, year + year_offset + 1)
    actual = list(cy_fy.range(year_offset))
    assert actual == list(expected)

@pytest.mark.parametrize('year', range(2016, 2022))
def test_first_date_year_arg(conservancy_fy, year):
    assert conservancy_fy.first_date(year) == datetime.date(year, 3, 1)

@pytest.mark.parametrize('date', [
    datetime.date(2019, 1, 1),
    datetime.date(2019, 10, 10),
    datetime.date(2020, 2, 2),
    datetime.date(2020, 12, 12),
])
def test_first_date_date_arg(conservancy_fy, date):
    year = date.year
    if date.month < 3:
        year -= 1
    assert conservancy_fy.first_date(date) == datetime.date(year, 3, 1)

@pytest.mark.parametrize('year', range(2016, 2022))
def test_last_date_year_arg(conservancy_fy, year):
    day = 28 if year % 4 else 29
    assert conservancy_fy.last_date(year - 1) == datetime.date(year, 2, day)

@pytest.mark.parametrize('date', [
    datetime.date(2019, 1, 1),
    datetime.date(2019, 10, 10),
    datetime.date(2020, 2, 2),
    datetime.date(2020, 12, 12),
])
def test_last_date_date_arg(conservancy_fy, date):
    year = date.year
    if date.month >= 3:
        year += 1
    day = 28 if year % 4 else 29
    assert conservancy_fy.last_date(date) == datetime.date(year, 2, day)

@pytest.mark.parametrize('year', range(2016, 2022))
def test_next_fy_date_year_arg(conservancy_fy, year):
    assert conservancy_fy.next_fy_date(year) == datetime.date(year + 1, 3, 1)

@pytest.mark.parametrize('date', [
    datetime.date(2019, 1, 1),
    datetime.date(2019, 10, 10),
    datetime.date(2020, 2, 29),
    datetime.date(2020, 12, 12),
])
def test_next_fy_date_date_arg(conservancy_fy, date):
    year = date.year
    if date.month >= 3:
        year += 1
    assert conservancy_fy.next_fy_date(date) == datetime.date(year, 3, 1)