"""Tests for the historical factor store (P4 enabler).""" from __future__ import annotations import json import tempfile import unittest from pathlib import Path from app.factor_history import FactorHistory, FactorHistoryError class FactorHistoryTest(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() self.dir = Path(self._tmp.name) self.fh = FactorHistory(self.dir) def tearDown(self): self._tmp.cleanup() def test_record_and_series_roundtrip(self): self.assertTrue(self.fh.record("macro_consumption", 4.9, ts="2026-01-01T00:00:00+00:00")) self.assertTrue(self.fh.record("macro_consumption", 5.2, ts="2026-02-01T00:00:00+00:00")) series = self.fh.series("macro_consumption") self.assertEqual(len(series), 2) self.assertEqual(series[0]["value"], 4.9) self.assertEqual(series[1]["value"], 5.2) def test_duplicate_value_not_rewritten(self): self.assertTrue(self.fh.record("f", 1.0, ts="2026-01-01T00:00:00+00:00")) self.assertFalse(self.fh.record("f", 1.0, ts="2026-02-01T00:00:00+00:00")) self.assertEqual(len(self.fh.series("f")), 1) def test_none_value_not_recorded(self): self.assertFalse(self.fh.record("f", None)) self.assertEqual(len(self.fh.series("f")), 0) def test_non_finite_not_recorded(self): self.assertFalse(self.fh.record("f", float("nan"))) self.assertFalse(self.fh.record("f", float("inf"))) self.assertEqual(len(self.fh.series("f")), 0) def test_last_value(self): self.fh.record("f", 3.0) self.fh.record("f", 4.0) self.assertEqual(self.fh.last_value("f"), 4.0) self.assertIsNone(self.fh.last_value("missing")) class RecordAllTest(unittest.TestCase): def test_record_all_uses_fetched_dicts(self): import tempfile from pathlib import Path with tempfile.TemporaryDirectory() as td: fh = FactorHistory(Path(td)) fetched = { "macro_thai": { "private_consumption_yoy": 4.9, "private_investment_yoy": 18.1, "headline_inflation_yoy": 1.95, "manufacturing_yoy": -3.1, "tourists_ytd_mn": 16.2, }, "auto_credit": {"new_car_sales_yoy": 20.07, "vehicle_production": 117383.0, "auto_exports": 81526.0}, "auto_npl": {"pct_of_npls": 3.95}, "bank_npl": {"pct_of_npls": 1.07}, } writes = fh.record_all(fetched) # Every registered factor with a fetch module present gets a write. self.assertGreaterEqual(len([w for w in writes.values() if w]), 5) # macro_consumption should have a recorded value 4.9 norm path. self.assertEqual(fh.last_value("macro_consumption"), 4.9) if __name__ == "__main__": unittest.main()