You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.9 KiB
Python

"""Unit tests for rule-based parser."""
SAMPLE_TEXT_POSITIVE = """
Item 2.02 Results of Operations
Apple today announced record quarterly revenue of $124.3 billion, up 9 percent year over year.
Guidance raised for Q2: The Company expects revenue to be between $125 billion and $131 billion.
Demand remains strong across all product categories.
Gross margin expansion driven by Services mix.
Customer additions in enterprise continue to accelerate.
Backlog increased significantly year over year.
Adjusted EPS excludes certain non-GAAP items.
"""
SAMPLE_TEXT_NEGATIVE = """
Item 2.02 Results of Operations
Company reported revenue of $5.2 billion, missing expectations.
Guidance lowered for next quarter due to demand softness.
Margin compression continues. Financing need announced with dilutive convertible note offering.
"""
SAMPLE_TEXT_CONTRACT = """
Item 1.01 Entry into Material Agreement
The Company has entered into a definitive agreement with a major enterprise customer
for a multi-year supply contract worth $500 million. The contract includes recurring revenue.
"""
def test_parse_earnings_positive():
from libs.parser.rule_parser import RuleBasedParser
p = RuleBasedParser()
out = p.parse("DOC::test", "8-K", SAMPLE_TEXT_POSITIVE, {"filing_date": "2026-01-29"})
assert out.event_type == "earnings_release"
assert out.guidance.status == "raised"
assert out.signals.demand_strength == "strong"
assert out.event_direction == "bullish"
def test_parse_earnings_negative():
from libs.parser.rule_parser import RuleBasedParser
p = RuleBasedParser()
out = p.parse("DOC::test", "8-K", SAMPLE_TEXT_NEGATIVE, {"filing_date": "2026-02-01"})
assert out.event_type == "earnings_release"
assert out.guidance.status == "lowered"
assert out.event_direction in ("bearish", "mixed")
def test_parse_material_contract():
from libs.parser.rule_parser import RuleBasedParser
p = RuleBasedParser()
out = p.parse("DOC::test", "8-K", SAMPLE_TEXT_CONTRACT, {"filing_date": "2026-02-15"})
assert out.event_type == "material_contract"
def test_parse_non_gaap_flag():
from libs.parser.rule_parser import RuleBasedParser
p = RuleBasedParser()
out = p.parse("DOC::test", "8-K", SAMPLE_TEXT_POSITIVE, {"filing_date": "2026-01-29"})
assert out.risk_flags.non_gaap_heavy is True
def test_parse_margin_improving():
from libs.parser.rule_parser import RuleBasedParser
p = RuleBasedParser()
out = p.parse("DOC::test", "8-K", SAMPLE_TEXT_POSITIVE, {"filing_date": "2026-01-29"})
assert out.signals.margin_quality == "improving"
def test_parse_confidence_range():
from libs.parser.rule_parser import RuleBasedParser
p = RuleBasedParser()
out = p.parse("DOC::test", "8-K", SAMPLE_TEXT_POSITIVE, {"filing_date": "2026-01-29"})
assert 0.0 <= out.confidence.overall <= 1.0
def test_parse_document_id_preserved():
from libs.parser.rule_parser import RuleBasedParser
p = RuleBasedParser()
out = p.parse("DOC::my-id", "8-K", SAMPLE_TEXT_POSITIVE, {"filing_date": "2026-01-29"})
assert out.document_id == "DOC::my-id"
def test_parse_schema_version():
from libs.parser.rule_parser import SCHEMA_VERSION, RuleBasedParser
p = RuleBasedParser()
out = p.parse("DOC::test", "8-K", SAMPLE_TEXT_POSITIVE, {"filing_date": "2026-01-29"})
assert out.schema_version == SCHEMA_VERSION
def test_parse_unknown_event():
from libs.parser.rule_parser import RuleBasedParser
p = RuleBasedParser()
out = p.parse("DOC::test", "8-K", "No items mentioned here.", {"filing_date": "2026-01-29"})
assert out.event_type == "unknown"
assert len(out.warnings) > 0
def test_parse_filing_time_bucket_set():
from libs.parser.rule_parser import RuleBasedParser
p = RuleBasedParser()
out = p.parse(
"DOC::test",
"8-K",
SAMPLE_TEXT_POSITIVE,
{"filing_date": "2026-01-29", "accepted_at_utc": "2026-01-29T21:05:00Z"},
)
assert out.filing_time_bucket == "post_market"