112 lines
4.4 KiB
Python
112 lines
4.4 KiB
Python
"""Tests for IPSAS presentation layer."""
|
|
|
|
import pytest
|
|
from fqbm.state import FQBMState
|
|
from fqbm.ipsas.presentation import (
|
|
statement_of_financial_position,
|
|
budget_vs_actual_structure,
|
|
)
|
|
|
|
|
|
def test_statement_of_financial_position_central_bank():
|
|
state = FQBMState(B=100, R=50, C=30, E_cb=20)
|
|
df = statement_of_financial_position(state, entity="central_bank")
|
|
assert "Line item" in df.columns
|
|
assert "Amount" in df.columns
|
|
total_assets = df[df["Line item"] == "TOTAL ASSETS"]["Amount"].iloc[0]
|
|
assert total_assets == 100
|
|
total_liab = df[df["Line item"] == "TOTAL LIABILITIES AND NET ASSETS"]["Amount"].iloc[0]
|
|
assert total_liab == 30 + 50 + 20
|
|
|
|
|
|
def test_statement_of_financial_position_commercial_bank():
|
|
state = FQBMState(Loans=900, Deposits=800, E_b=100)
|
|
df = statement_of_financial_position(state, entity="commercial_bank")
|
|
total_assets = df[df["Line item"] == "TOTAL ASSETS"]["Amount"].iloc[0]
|
|
assert total_assets == 900
|
|
total_liab = df[df["Line item"] == "TOTAL LIABILITIES AND NET ASSETS"]["Amount"].iloc[0]
|
|
assert total_liab == 800 + 100
|
|
|
|
|
|
def test_statement_of_financial_position_consolidated():
|
|
state = FQBMState(B=50, R=100, C=20, Loans=500, Deposits=480, E_cb=50, E_b=100)
|
|
df = statement_of_financial_position(state, entity="consolidated")
|
|
total_assets = df[df["Line item"] == "TOTAL ASSETS"]["Amount"].iloc[0]
|
|
assert total_assets == 50 + 100 + 500
|
|
total_liab = df[df["Line item"] == "TOTAL LIABILITIES AND NET ASSETS"]["Amount"].iloc[0]
|
|
assert total_liab == 20 + 480 + 50 + 100
|
|
|
|
|
|
def test_budget_vs_actual_structure():
|
|
df = budget_vs_actual_structure()
|
|
assert "Original budget" in df.columns
|
|
assert "Final budget" in df.columns
|
|
assert "Actual" in df.columns
|
|
assert "Variance" in df.columns
|
|
assert "Material (Y/N)" in df.columns
|
|
assert len(df) >= 6
|
|
assert df.attrs.get("ipsas_24") is True
|
|
|
|
|
|
def test_budget_vs_actual_custom_lines():
|
|
df = budget_vs_actual_structure(line_items=["Revenue", "Expense"])
|
|
assert list(df["Line item"]) == ["Revenue", "Expense"]
|
|
assert df["Actual"].isna().all()
|
|
|
|
|
|
def test_cash_flow_statement_structure():
|
|
from fqbm.ipsas.presentation import cash_flow_statement_structure
|
|
df = cash_flow_statement_structure()
|
|
assert "Category" in df.columns
|
|
assert "Line item" in df.columns
|
|
assert "Amount" in df.columns
|
|
assert df.attrs.get("ipsas_2") is True
|
|
cats = set(df["Category"].dropna().unique())
|
|
assert "Operating" in cats
|
|
assert "Investing" in cats
|
|
assert "Financing" in cats
|
|
|
|
|
|
def test_statement_of_financial_performance_structure():
|
|
from fqbm.ipsas.presentation import statement_of_financial_performance_structure
|
|
df = statement_of_financial_performance_structure()
|
|
assert "Line item" in df.columns
|
|
assert "Amount" in df.columns
|
|
assert df.attrs.get("ipsas_1_performance") is True
|
|
assert "Revenue" in " ".join(df["Line item"].astype(str))
|
|
|
|
|
|
def test_notes_to_financial_statements_structure():
|
|
from fqbm.ipsas.presentation import notes_to_financial_statements_structure
|
|
df = notes_to_financial_statements_structure()
|
|
assert "Note" in df.columns
|
|
assert "Title" in df.columns
|
|
assert "Content" in df.columns
|
|
assert df.attrs.get("notes_template") is True
|
|
assert len(df) >= 5
|
|
|
|
|
|
def test_statement_of_financial_position_comparative():
|
|
from fqbm.ipsas.presentation import statement_of_financial_position_comparative
|
|
prior = FQBMState(B=80, R=40, Loans=400, Deposits=380, E_b=20)
|
|
current = FQBMState(B=90, R=45, Loans=420, Deposits=398, E_b=22)
|
|
df = statement_of_financial_position_comparative(prior, current, entity="commercial_bank")
|
|
assert "Prior" in df.columns
|
|
assert "Current" in df.columns
|
|
assert "Change" in df.columns
|
|
assert df.attrs.get("comparative") is True
|
|
# Change should equal Current - Prior for numeric rows
|
|
num_mask = df["Prior"].apply(lambda x: isinstance(x, (int, float)))
|
|
if num_mask.any():
|
|
assert (df.loc[num_mask, "Current"] - df.loc[num_mask, "Prior"] - df.loc[num_mask, "Change"]).abs().max() < 1e-6
|
|
|
|
|
|
def test_maturity_risk_disclosure_structure():
|
|
from fqbm.ipsas.presentation import maturity_risk_disclosure_structure
|
|
df = maturity_risk_disclosure_structure()
|
|
assert "0-1Y" in df.columns
|
|
assert "1-5Y" in df.columns
|
|
assert "Interest rate +100bp" in df.columns
|
|
assert "ECL" in df.columns
|
|
assert df.attrs.get("maturity_risk_disclosure") is True
|