Wire the guarded conversational RAG answer layer end-to-end
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
from dataclasses import replace
|
||||
|
||||
import pytest
|
||||
|
||||
from ingestion.extract.models import Span
|
||||
@@ -50,6 +52,55 @@ def test_non_bold_combined_heading_value_span_confirmed_real_amitriptylin_case()
|
||||
m = list(assemble(spans))[0]
|
||||
assert m.sections["ma_atc"].text == "N06AA09."
|
||||
assert m.atc_codes == ["N06AA09"]
|
||||
part = m.sections["ma_atc"].parts[0]
|
||||
assert part.physical_page == 184
|
||||
assert part.bbox != [0.0, 0.0, 0.0, 0.0]
|
||||
assert part.source_span_ids == [spans[3].span_id]
|
||||
|
||||
|
||||
def test_combined_international_name_and_atc_heading_is_a_title_anchor():
|
||||
# Confirmed real GnRH class-monograph variant on physical page 1371.
|
||||
spans = [
|
||||
_span("THUỐC TƯƠNG TỰ HORMON GIẢI PHÓNG", 1371, 664.0),
|
||||
_span("GONADOTROPIN", 1371, 676.0),
|
||||
_span("Tên chung quốc tế và mã ATC", 1371, 690.0),
|
||||
_span("Gonadorelin: H01CA01; Triptorelin: L02AE04.", 1371, 702.0, bold=False),
|
||||
_span("Chỉ định", 1371, 714.0),
|
||||
_span("Kích thích phóng noãn.", 1371, 726.0, bold=False),
|
||||
]
|
||||
m = list(assemble(spans))[0]
|
||||
assert m.drug_name == "THUỐC TƯƠNG TỰ HORMON GIẢI PHÓNG GONADOTROPIN"
|
||||
assert m.atc_codes == ["H01CA01", "L02AE04"]
|
||||
|
||||
|
||||
def test_plain_wrapped_section_label_is_body_not_a_heading():
|
||||
# NADROPARIN CALCI p1016: "không phải là" / "chống chỉ định."
|
||||
# are adjacent lines of one sentence in the same PDF block.
|
||||
spans = [
|
||||
_span("NADROPARIN CALCI", 1016, 60.0),
|
||||
_span("Tên chung quốc tế", 1016, 80.0),
|
||||
_span("Nadroparin calcium.", 1016, 92.0, bold=False),
|
||||
_span("Thời kỳ cho con bú", 1016, 110.0),
|
||||
]
|
||||
lead = replace(_span("Việc dùng thuốc không phải là", 1016, 122.0, bold=False),
|
||||
block=4, line=7)
|
||||
tail = replace(_span("chống chỉ định.", 1016, 134.0, bold=False),
|
||||
block=4, line=8)
|
||||
m = list(assemble(spans + [lead, tail]))[0]
|
||||
assert m.sections["thoi_ky_cho_con_bu"].text.endswith("chống chỉ định.")
|
||||
assert "chong_chi_dinh" not in m.sections
|
||||
|
||||
|
||||
def test_plain_heading_after_completed_prose_still_opens_section():
|
||||
spans = [
|
||||
_span("TESTDRUG", 300, 60.0),
|
||||
_span("Tên chung quốc tế", 300, 80.0),
|
||||
replace(_span("Testdrug.", 300, 92.0, bold=False), block=2, line=0),
|
||||
replace(_span("Chỉ định", 300, 104.0, bold=False), block=2, line=1),
|
||||
replace(_span("Điều trị thử nghiệm.", 300, 116.0, bold=False), block=2, line=2),
|
||||
]
|
||||
m = list(assemble(spans))[0]
|
||||
assert m.sections["chi_dinh"].text == "Điều trị thử nghiệm."
|
||||
|
||||
|
||||
def test_atc_stated_absent_propagates():
|
||||
@@ -330,3 +381,71 @@ def test_a_bold_label_line_still_opens_its_section():
|
||||
]
|
||||
monograph = list(assemble(spans))[0]
|
||||
assert monograph.sections["chong_chi_dinh"].text == "Suy tủy nặng."
|
||||
|
||||
|
||||
def test_a_section_name_printed_mid_line_is_body_not_a_heading():
|
||||
"""CISPLATIN, physical page 402 — confirmed content loss.
|
||||
|
||||
The book prints "Suy thận: Chống chỉ định." inside the dosing section. The
|
||||
second half is itself a section name, so it was matched as a heading: the
|
||||
renal-impairment contraindication vanished from the dosing text and the
|
||||
section ended on a bare "Suy thận:". ISOPRENALIN had the same shape. A
|
||||
real heading opens its line; this one does not.
|
||||
"""
|
||||
spans = [
|
||||
_span("CISPLATIN", 401, 60.0),
|
||||
_span("Tên chung quốc tế", 401, 80.0),
|
||||
_span("Cisplatinum.", 401, 92.0, bold=False),
|
||||
_span("Liều lượng và cách dùng", 401, 110.0),
|
||||
_span("Truyền tĩnh mạch mỗi 3 tuần.", 401, 122.0, bold=False),
|
||||
]
|
||||
label = _span("Suy thận: ", 401, 140.0, bold=False)
|
||||
label = replace(label, block=4, line=0, x0=35.0, x1=70.0)
|
||||
trailing = _span("Chống chỉ định.", 401, 140.0, bold=False)
|
||||
trailing = replace(trailing, block=4, line=0, x0=70.0, x1=140.0)
|
||||
|
||||
monograph = list(assemble(spans + [label, trailing]))[0]
|
||||
dosing = monograph.sections["lieu_luong_va_cach_dung"].text
|
||||
assert "Suy thận: Chống chỉ định." in dosing
|
||||
assert "chong_chi_dinh" not in monograph.sections
|
||||
|
||||
|
||||
def test_italic_cross_reference_overlapping_its_neighbour_by_a_hairline_is_body():
|
||||
"""NEVIRAPIN, physical page 1045 — confirmed misassignment, whole-corpus.
|
||||
|
||||
The book prints `Xem thêm mục ` (x1=104.89) immediately before an italic
|
||||
`Liều lượng và cách dùng` (x0=104.88): the trailing space's advance width
|
||||
makes the neighbour end 0.01pt *after* the cross-reference starts. An
|
||||
end-before-start test therefore read a mid-line cross-reference as a
|
||||
heading. Same shape, same cause, in CALCI LACTAT (p296, `xem thêm mục
|
||||
Tương tác thuốc`, 0.02pt) and CEFAZOLIN (p344, `ghi ở mục: Dạng thuốc và
|
||||
hàm lượng.`), where 4,533 characters of adult dosing were filed under
|
||||
dosage forms.
|
||||
"""
|
||||
spans = [
|
||||
_span("NEVIRAPIN", 1044, 60.0),
|
||||
_span("Tên chung quốc tế", 1044, 80.0),
|
||||
_span("Nevirapine.", 1044, 92.0, bold=False),
|
||||
_span("Hướng dẫn cách xử trí ADR", 1044, 110.0),
|
||||
_span("Điều trị các phản ứng bất lợi theo triệu chứng.", 1044, 122.0, bold=False),
|
||||
]
|
||||
lead = replace(_span("Xem thêm mục ", 1044, 140.0, bold=False),
|
||||
block=4, line=0, x0=43.94, x1=104.89)
|
||||
reference = replace(_span("Liều lượng và cách dùng", 1044, 140.0, bold=False),
|
||||
block=4, line=0, x0=104.88, x1=199.57)
|
||||
|
||||
monograph = list(assemble(spans + [lead, reference]))[0]
|
||||
assert "Xem thêm mục Liều lượng và cách dùng" in monograph.sections["huong_dan_xu_tri_adr"].text
|
||||
assert "lieu_luong_va_cach_dung" not in monograph.sections
|
||||
|
||||
|
||||
def test_a_section_name_opening_its_own_line_is_still_a_heading():
|
||||
spans = [
|
||||
_span("CISPLATIN", 401, 60.0),
|
||||
_span("Tên chung quốc tế", 401, 80.0),
|
||||
_span("Cisplatinum.", 401, 92.0, bold=False),
|
||||
_span("Chống chỉ định", 401, 110.0),
|
||||
_span("Suy tủy nặng.", 401, 122.0, bold=False),
|
||||
]
|
||||
monograph = list(assemble(spans))[0]
|
||||
assert monograph.sections["chong_chi_dinh"].text == "Suy tủy nặng."
|
||||
|
||||
Reference in New Issue
Block a user