- Engine: Add ppa_revenue_cr, mcp_revenue_cr, tariff, units to PnLRow - Engine: Split PPA vs MCP revenue in P&L computation - Web: Collapsible rows for PPA/MCP Revenue and Opex - Web: Highlighted rows (Total Revenue, EBITDA, EBIT, PBT, PAT) - Web: Units above Tariff in breakdown, bg-blue-50 highlight - Fix sticky column z-index for horizontal scroll - CLAUDE.md: Add project documentation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
"""S8-T06: Excel export tests."""
|
|
|
|
from io import BytesIO
|
|
|
|
from openpyxl import load_workbook
|
|
|
|
from remodel_engine.io.excel_export import export_to_bytes
|
|
from remodel_engine.scenarios.runner import run_scenario
|
|
from remodel_engine.schemas.scenario import ScenarioInput
|
|
|
|
|
|
def _run_base() -> object:
|
|
return run_scenario(ScenarioInput())
|
|
|
|
|
|
def test_export_returns_bytes() -> None:
|
|
result = _run_base()
|
|
data = export_to_bytes(result)
|
|
assert isinstance(data, bytes)
|
|
assert len(data) > 1000
|
|
|
|
|
|
def test_export_has_correct_sheets() -> None:
|
|
result = _run_base()
|
|
data = export_to_bytes(result)
|
|
wb = load_workbook(BytesIO(data))
|
|
assert set(wb.sheetnames) == {"KPIs", "PnL", "CFS", "BS", "DebtSched", "Inputs"}
|
|
|
|
|
|
def test_kpi_sheet_has_data() -> None:
|
|
result = _run_base()
|
|
data = export_to_bytes(result)
|
|
wb = load_workbook(BytesIO(data))
|
|
ws = wb["KPIs"]
|
|
labels = [ws.cell(row=r, column=1).value for r in range(2, 20) if ws.cell(row=r, column=1).value]
|
|
assert "Equity IRR" in labels
|
|
assert "Solved Tariff (₹/kWh)" in labels
|
|
|
|
|
|
def test_pnl_sheet_has_25_rows() -> None:
|
|
result = _run_base()
|
|
data = export_to_bytes(result)
|
|
wb = load_workbook(BytesIO(data))
|
|
ws = wb["PnL"]
|
|
data_rows = [r for r in range(2, 30) if ws.cell(row=r, column=1).value is not None]
|
|
assert len(data_rows) == 25
|
|
|
|
|
|
def test_inputs_sheet_has_section_column() -> None:
|
|
result = _run_base()
|
|
data = export_to_bytes(result)
|
|
wb = load_workbook(BytesIO(data))
|
|
ws = wb["Inputs"]
|
|
sections = [ws.cell(row=r, column=1).value for r in range(2, 30) if ws.cell(row=r, column=1).value]
|
|
assert "Project" in sections
|
|
assert "Commercial" in sections
|