from backend.metrics_extractor import ( extract_metrics, find_metric_in_text, normalize_currency_symbols, normalize_grouped_digits, parse_value, score_confidence, demote_confidence, ) HDFC_TEXT = """ HDFC Bank reported total income of ₹250,000 crore for FY2024. Net interest income stood at ₹89,000 crore. Profit after tax was ₹60,812 crore. Total deposits were ₹2,300,000 crore. Gross NPA ratio was 1.24%. Net NPA was 0.33%. CASA ratio stood at 38.2%. Capital adequacy ratio was 19.3%. """ # real RIL-style artifacts: backtick for ₹, space-grouped digits, a # related-party figure that must not beat a consolidated figure RIL_TEXT = """ Results of Operations and the State of Company's Affairs During the year, the Company's Net profit was ` 983 lakh as compared to ` 1,021 lakh in the previous year. Revenue of ` 48 88 Lakh (Previous Year ` 57 43 Lakh) arose from Sale of Services to Reliance Industries Limited (Entity exercising significant influence, the largest customer). The Consolidated total revenue from operations for the year was ` 9,64,693 crore, compared to ` 9,01,064 crore in the previous year. """ BUNDLED_TEXT = """ Mumbai, April 16, 2025 Corporate Governance Report Reliance Industrial Infrastructure Limited Independent Auditor's Report on Financial Statement Balance Sheet as at March 31, 2025 Revenue from operations was ` 5,000 lakh for the year ended March 31, 2025. Reliance Industries Limited Consolidated Financial Statement Revenue from operations for the year ended was ` 9,64,693 crore. """ def test_bank_metrics_extracted_with_confidence_shape(): metrics = extract_metrics(HDFC_TEXT, company="HDFC Bank") assert "profit_after_tax" in metrics pat = metrics["profit_after_tax"] assert isinstance(pat, dict) assert pat["value"] == 60_812 * 10_000_000 assert pat["currency"] == "INR" assert pat["confidence"] in ("high", "medium", "low") def test_bank_ratios_are_bare_floats(): metrics = extract_metrics(HDFC_TEXT, company="HDFC Bank") assert metrics["gross_npa_pct"] == 1.24 assert metrics["casa_ratio"] == 38.2 def test_garbled_rupee_glyph_recovered(): m = find_metric_in_text(RIL_TEXT, ["consolidated total revenue"], company="RIL") assert m is not None assert m["value"] == 9_64_693 * 10_000_000 def test_consolidated_beats_related_party_figure(): m = find_metric_in_text( RIL_TEXT, ["revenue from operations", "total revenue", "revenue"], company="RIL", ) # the related-party "48 88 Lakh" figure must not win over the # consolidated crore figure assert m["value"] == 9_64_693 * 10_000_000 def test_bundled_subsidiary_demoted(): m = find_metric_in_text( BUNDLED_TEXT, ["revenue from operations"], company="RIL" ) # the subsidiary's 5,000 lakh must not be chosen for RIL assert m["value"] == 9_64_693 * 10_000_000 def test_normalize_currency_symbols_is_length_preserving(): for text in ["Rs. 5,000 crore", "Rs 100 lakh", "` 983 lakh", "₨ 42 crore"]: assert len(normalize_currency_symbols(text)) == len(text) def test_normalize_grouped_digits(): assert normalize_grouped_digits("48 88") == "4888" assert normalize_grouped_digits("9,64,693") == "9,64,693" def test_parse_value_units(): assert parse_value("$394.3 billion") == 394.3e9 assert parse_value("₹60,812 crore") == 60_812 * 10_000_000 assert parse_value("5 lakh") == 500_000 assert parse_value("garbage") is None def test_score_confidence_rules(): assert score_confidence("consolidated revenue was", True, False) == "high" assert score_confidence("sale of services to subsidiary", True, False) == "low" assert score_confidence("revenue was", False, False) == "low" # no unit assert score_confidence("consolidated revenue was", True, True) == "medium" def test_demote_confidence_ladder(): assert demote_confidence("high") == "medium" assert demote_confidence("medium") == "low" assert demote_confidence("low") == "low"