spb/company-atlas
Public
Python 66.3%
TypeScript 22.7%
JavaScript 8.6%
HTML 1.4%
CSS 0.7%
1from __future__ import annotations23from conftest import fixture_text45from companyatlas.sdk import normalize as N6from companyatlas.sdk.diff import compare7from companyatlas.taxonomy import ChangeKind, change_kind89URL = "https://www.acme-cloud.example/pricing"101112def _page(name: str, url: str = URL) -> N.NormalizedPage:13 return N.parse(fixture_text("generic_html", name), url=url)141516def test_same_page_twice_is_zero() -> None:17 a = _page("pricing.html")18 d = compare(a.blocks, a.blocks, surface="pricing", before_text=a.text, after_text=a.text)19 assert d.significance == 0.0 and d.is_empty and d.reasons == ["identical"]202122def test_footer_year_change_is_noise() -> None:23 html = fixture_text("generic_html", "pricing.html")24 a, b = N.parse(html, url=URL), N.parse(html.replace("© 2025", "© 2026"), url=URL)25 d = compare(a.blocks, b.blocks, surface="pricing", before_text=a.text, after_text=b.text)26 assert d.significance < 0.2027 assert change_kind(d.significance) is ChangeKind.NOISE282930def test_nav_only_churn_is_noise() -> None:31 html = fixture_text("generic_html", "pricing.html")32 b = N.parse(html.replace('<a href="/docs">Docs</a>', '<a href="/docs">Docs</a> <a href="/partners">Partners</a>'), url=URL)33 a = N.parse(html, url=URL)34 d = compare(a.blocks, b.blocks, surface="pricing", before_text=a.text, after_text=b.text)35 assert d.significance < 0.2036 assert any("nav/footer" in r for r in d.reasons)373839def test_price_change_with_typed_delta_is_major() -> None:40 a, b = _page("pricing.html"), _page("pricing_v2.html")41 delta = {"plans": {"added": [], "removed": [], "price_changed": [{"plan_name": "Starter", "before": 29, "after": 39, "currency": "USD", "billing_period": "month", "pct": 34.5}]}}42 d = compare(a.blocks, b.blocks, surface="pricing", before_text=a.text, after_text=b.text, structured_delta=delta)43 assert d.significance >= 0.6544 assert len(d.modified) == 1 and d.modified[0].kind == "pricing_plan"45 assert any("typed delta plans.price_changed" in r for r in d.reasons)464748def test_tiny_text_edit_without_typed_delta_is_noise() -> None:49 html = fixture_text("generic_html", "pricing.html")50 a = N.parse(html, url=URL)51 b = N.parse(html.replace("No credit card required.", "No credit card needed."), url=URL)52 d = compare(a.blocks, b.blocks, surface="pricing", before_text=a.text, after_text=b.text)53 assert d.significance < 0.20545556def test_new_job_listings_are_meaningful() -> None:57 a = _page("careers.html", "https://www.acme-cloud.example/careers")58 b = _page("careers_v2.html", "https://www.acme-cloud.example/careers")59 delta = {"jobs": {"added": [{"title": "AI Research Scientist"}, {"title": "Data Platform Engineer"}], "removed": [{"title": "People Operations Lead"}],60 "open_before": 5, "open_after": 6}}61 d = compare(a.blocks, b.blocks, surface="careers", before_text=a.text, after_text=b.text, structured_delta=delta)62 assert change_kind(d.significance) in (ChangeKind.MEANINGFUL, ChangeKind.MAJOR)63 assert len(d.added) >= 2 and len(d.removed) >= 1646566def test_whole_redesign_is_major() -> None:67 a = _page("legal_terms.html", "https://www.acme-cloud.example/")68 b = _page("homepage.html", "https://www.acme-cloud.example/")69 d = compare(a.blocks, b.blocks, surface="homepage", before_text=a.text, after_text=b.text)70 assert change_kind(d.significance) in (ChangeKind.MAJOR, ChangeKind.CRITICAL)71 assert d.text_delta_ratio > 0.5727374def test_reordered_blocks_are_moves_not_add_remove() -> None:75 html = fixture_text("generic_html", "legal_terms.html")76 a = N.parse(html, url=URL)77 sec2 = html[html.index("<h2>2. Accounts</h2>"):html.index("<h2>3. Fees")]78 sec3 = html[html.index("<h2>3. Fees"):html.index("<h2>4. Termination")]79 b = N.parse(html.replace(sec2 + sec3, sec3 + sec2), url=URL)80 d = compare(a.blocks, b.blocks, surface="legal_terms", before_text=a.text, after_text=b.text)81 assert not d.added and not d.removed and not d.modified82 assert d.moved838485def test_novelty_boost_and_churn_penalty_are_deterministic() -> None:86 a = _page("careers.html", "https://www.acme-cloud.example/careers")87 b = _page("careers_v2.html", "https://www.acme-cloud.example/careers")88 base = compare(a.blocks, b.blocks, surface="careers", before_text=a.text, after_text=b.text).significance89 novel = compare(a.blocks, b.blocks, surface="careers", before_text=a.text, after_text=b.text, history={"consecutive_unchanged": 50}).significance90 churn = compare(a.blocks, b.blocks, surface="careers", before_text=a.text, after_text=b.text, history={"observation_count": 20, "change_count": 15}).significance91 assert novel > base > churn92 assert base == compare(a.blocks, b.blocks, surface="careers", before_text=a.text, after_text=b.text).significance93