ó
    ]`0j@B  ã                   ó  • S r SSKrSSKJs  Jr  SSKJr  SSK	J
r
JrJr  SSKJrJrJrJr   " S S5      r " S S	5      r " S
 S5      r " S S5      r " S S5      r " S S5      r " S S5      r " S S5      rS\4S jr " S S5      rg)z<Tests for table inference processor (non-LLM functionality).é    N)ÚOptional)Ú	MagicMockÚ	mock_openÚpatch)ÚExecutiveSummaryÚTableContextÚTableInferenceProcessorÚ	TableInfoc                   ó$   • \ rS rSrSrS rS rSrg)ÚTestTableContexté   zTests for TableContext model.c                 óä  • [        SSSS/SSSSS	S
9nUR                  nSo2U:H  oD(       dº  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS=n=pCUR                  nSo2U:H  oD(       dº  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS=n=pCUR                  nSS/o2U:H  oD(       dº  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS=n=pCUR                  nS	o2U:H  oD(       dº  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS=n=pCg)z&Test creating a TableContext instance.zTest summaryz
Test TableÚHeader1ÚHeader2zTable descriptionz| A | B |
|---|---|
| 1 | 2 |zSome text beforezPage contexté   )Úexecutive_summaryÚprocedural_titleÚheadersÚdescriptive_textÚtable_previewÚpreceding_textÚpage_contextÚpage_number©ú==)z9%(py2)s
{%(py2)s = %(py0)s.executive_summary
} == %(py5)sÚcontext©Úpy0Úpy2Úpy5úassert %(py7)sÚpy7N)z8%(py2)s
{%(py2)s = %(py0)s.procedural_title
} == %(py5)s)z/%(py2)s
{%(py2)s = %(py0)s.headers
} == %(py5)s)z3%(py2)s
{%(py2)s = %(py0)s.page_number
} == %(py5)s)r   r   Ú
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanationr   r   r   ©Úselfr   Ú@py_assert1Ú@py_assert4Ú@py_assert3Ú@py_format6Ú@py_format8s          Ú?/home/mande/repo/quber/tests/processors/test_table_inference.pyÚtest_table_context_creationÚ,TestTableContext.test_table_context_creation   sú  € äØ,Ø)Ø 	Ð*Ø0Ø;Ø-Ø'Øñ	
ˆð ×(Ñ(Ð:¨NÐ:¨NÑ:×:×:×:Ò:Ð(×:×:×:×:×:Õ:ˆw×:×:×:Ñ:ˆw×:×:Õ:Ð(×:×:Ó:¨N×:×:×:×:×:×:Ó:Ø×'Ñ'Ð7¨<Ð7¨<Ñ7×7×7×7Ò7Ð'×7×7×7×7×7Õ7ˆw×7×7×7Ñ7ˆw×7×7Õ7Ð'×7×7Ó7¨<×7×7×7×7×7×7Ó7Ø�‰Ð8 9¨iÐ"8Ð8Ð"8Ñ8×8×8×8Ò8ˆ×8×8×8×8×8Õ8ˆw×8×8×8Ñ8ˆw×8×8Õ8ˆ×8×8Ó8Ð"8×8×8×8×8×8×8Ó8Ø×"Ñ"Ð' aÐ' aÑ'×'×'×'Ò'Ð"×'×'×'×'×'Õ'ˆw×'×'×'Ñ'ˆw×'×'Õ'Ð"×'×'Ó' a×'×'×'×'×'×'Ô'ó    c                 ó"  • [        SS/ SSS9nUR                  nSo2UL oD(       dº  [        R                  " SU4SX#45      S	[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	[        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n[        [        R                  " U5      5      eS=n=pCUR                  nSo2UL oD(       dº  [        R                  " SU4SX#45      S	[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	[        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n[        [        R                  " U5      5      eS=n=pCUR                  nSo2UL oD(       dº  [        R                  " SU4SX#45      S	[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	[        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n[        [        R                  " U5      5      eS=n=pCg)z/Test TableContext with optional fields as None.ÚSummaryÚTitleÚPreviewr   ©r   r   r   r   r   N©Úis)z8%(py2)s
{%(py2)s = %(py0)s.descriptive_text
} is %(py5)sr   r   r!   r"   )z6%(py2)s
{%(py2)s = %(py0)s.preceding_text
} is %(py5)s)z4%(py2)s
{%(py2)s = %(py0)s.page_context
} is %(py5)s)r   r   r#   r$   r%   r&   r'   r(   r)   r*   r   r   r+   s          r2   Ú"test_table_context_optional_fieldsÚ3TestTableContext.test_table_context_optional_fields#   sv  € äØ'Ø$ØØ#Øñ
ˆð ×'Ñ'Ð/¨4Ð/¨4Ð/×/×/×/Ò/Ð'×/×/×/×/×/Õ/ˆw×/×/×/Ñ/ˆw×/×/Õ/Ð'×/×/Ó/¨4×/×/×/×/×/×/Ó/Ø×%Ñ%Ð-¨Ð-¨Ð-×-×-×-Ò-Ð%×-×-×-×-×-Õ-ˆw×-×-×-Ñ-ˆw×-×-Õ-Ð%×-×-Ó-¨×-×-×-×-×-×-Ó-Ø×#Ñ#Ð+ tÐ+ tÐ+×+×+×+Ò+Ð#×+×+×+×+×+Õ+ˆw×+×+×+Ñ+ˆw×+×+Õ+Ð#×+×+Ó+ t×+×+×+×+×+×+Ô+r5   © N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r3   r=   Ú__static_attributes__r?   r5   r2   r   r      s   † Ù'ò(õ$,r5   r   c                   ó   • \ rS rSrSrS rSrg)ÚTestTableInfoé2   zTests for TableInfo model.c                 ót  • [        SSS9nUR                  nSo2U:H  oD(       dº  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS
=n=pCUR                  nSo2U:H  oD(       dº  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS
=n=pCg
)z#Test creating a TableInfo instance.úFinancial DatazQuarterly revenue breakdown)ÚtitleÚdescriptionr   )z-%(py2)s
{%(py2)s = %(py0)s.title
} == %(py5)sÚinfor   r!   r"   N)z3%(py2)s
{%(py2)s = %(py0)s.description
} == %(py5)s)r
   rK   r#   r$   r%   r&   r'   r(   r)   r*   rL   )r,   rM   r-   r.   r/   r0   r1   s          r2   Útest_table_info_creationÚ&TestTableInfo.test_table_info_creation5   sø   € äÐ/Ð=ZÑ[ˆà�z‰zÐ-Ð-Ð-Ð-Ñ-×-×-×-Ò-ˆz×-×-×-×-×-Õ-ˆt×-×-×-Ñ-ˆt×-×-Õ-ˆz×-×-Ó-Ð-×-×-×-×-×-×-Ó-Ø×ÑÐ@Ð#@Ð@Ð#@Ñ@×@×@×@Ò@Ð×@×@×@×@×@Õ@ˆt×@×@×@Ñ@ˆt×@×@Õ@Ð×@×@Ó@Ð#@×@×@×@×@×@×@Ô@r5   r?   N)r@   rA   rB   rC   rD   rN   rE   r?   r5   r2   rG   rG   2   s   † Ù$õAr5   rG   c                   ó   • \ rS rSrSrS rSrg)ÚTestExecutiveSummaryé=   z!Tests for ExecutiveSummary model.c                 óÄ  • [        SS9nUR                  nSo2U:H  oD(       dº  [        R                  " SU4SX#45      S[        R
                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS	=n=pCg	)
z+Test creating an ExecutiveSummary instance.z'This is a test summary of the document.)Úsummaryr   )z/%(py2)s
{%(py2)s = %(py0)s.summary
} == %(py5)srT   r   r!   r"   N)
r   rT   r#   r$   r%   r&   r'   r(   r)   r*   )r,   rT   r-   r.   r/   r0   r1   s          r2   Útest_executive_summary_creationÚ4TestExecutiveSummary.test_executive_summary_creation@   s   € ä"Ð+TÑUˆà�‰ÐKÐ"KÐKÐ"KÑK×K×K×KÒKˆ×K×K×K×K×KÕKˆw×K×K×KÑKˆw×K×KÕKˆ×K×KÓKÐ"K×K×K×K×K×K×KÔKr5   r?   N)r@   rA   rB   rC   rD   rU   rE   r?   r5   r2   rQ   rQ   =   s   † Ù+õLr5   rQ   c                   ó¾   • \ rS rSrSr\" S5      \" S5      \" S5      \" S5      S 5       5       5       5       r\" S5      \" S5      \" S5      S 5       5       5       rS	rg
)ÚTestTableInferenceProcessorInitéG   z1Tests for TableInferenceProcessor initialization.ú.quber.processors.table_inference.setup_loggingú,quber.processors.table_inference.load_promptú-quber.processors.table_inference.AgentFactoryú-quber.processors.table_inference.get_settingsc                 óD  • [        5       nSUR                  l        SUl        XQl        SUl        [        5       nXbl        [        5       nUR                  oˆU:H  o™(       dð  [        R                  " SU	4SX…45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  n
S	S
U
0-  n[        [        R                  " U5      5      eS=p‰UR                  nSoÈUL o™(       dº  [        R                  " SU	4SXŒ45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS=n=pœUR                   nSoÈUL o™(       dº  [        R                  " SU	4SXŒ45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS=n=pœUR#                  5         UR%                  SS5        g)z,Test initialization with default parameters.FÚINFOúSystem promptr   ©z0%(py2)s
{%(py2)s = %(py0)s.settings
} == %(py4)sÚ	processorÚmock_settings©r   r   Úpy4úassert %(py6)sÚpy6Nr;   )z0%(py2)s
{%(py2)s = %(py0)s.provider
} is %(py5)sr   r!   r"   )z-%(py2)s
{%(py2)s = %(py0)s.model
} is %(py5)sÚtable_inferenceÚsystem)r   ÚobsÚenable_logfireÚ	log_levelÚreturn_valuer	   Úsettingsr#   r$   r%   r&   r'   r(   r)   r*   ÚproviderÚmodelÚassert_called_onceÚassert_called_once_with)r,   Úmock_get_settingsÚmock_agent_factoryÚmock_load_promptÚmock_setup_loggingrc   Úmock_factoryrb   r-   r/   Ú@py_format5Ú@py_format7r.   r0   r1   s                  r2   Útest_init_with_defaultsÚ7TestTableInferenceProcessorInit.test_init_with_defaultsJ   sÉ  € ô "›ˆØ+0ˆ×ÑÔ(Ø"(ˆÔØ)6Ô&à(7ÐÔ%ä “{ˆØ*6Ô'ä+Ó-ˆ	à×!Ñ!Ð2 ]Ñ2×2×2×2Ò2Ð!×2×2×2×2×2Õ2ˆy×2×2×2Ñ2ˆy×2×2Õ2Ð!×2×2×2×2×2Ô2 ]×2×2×2Ñ2 ]×2×2×2×2×2×2Ó2Ø×!Ñ!Ð) TÐ) TÐ)×)×)×)Ò)Ð!×)×)×)×)×)Õ)ˆy×)×)×)Ñ)ˆy×)×)Õ)Ð!×)×)Ó) T×)×)×)×)×)×)Ó)Ø�‰Ð& $Ð& $Ð&×&×&×&Ò&ˆ×&×&×&×&×&Õ&ˆy×&×&×&Ñ&ˆy×&×&Õ&ˆ×&×&Ó& $×&×&×&×&×&×&Ó&Ø×-Ñ-Ô/Ø×0Ñ0Ð1BÀHÕMr5   c                 óÄ  • SSK Jn  [        5       nSUR                  l        SUl        SUl        [        5       nXal        [        UR                  SUS9nUR                  o„R                  o˜U	:H  oª(       Gd  [        R                  " SU
4S	X‰45      S
[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS
[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U	5      S.-  nSSU0-  n[!        [        R"                  " U5      5      eS=n=p©UR$                  nSoØU:H  oª(       dº  [        R                  " SU
4SX�45      S
[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS
[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[!        [        R"                  " U5      5      eS=n=p­UR&                  oˆU:H  oª(       dð  [        R                  " SU
4SX…45      S
[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS
[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[!        [        R"                  " U5      5      eS=pŠg)z+Test initialization with custom parameters.r   )ÚModelProviderTÚDEBUGr`   úclaude-3-5-sonnet-20241022)ro   rp   rn   r   )zO%(py2)s
{%(py2)s = %(py0)s.provider
} == %(py6)s
{%(py6)s = %(py4)s.ANTHROPIC
}rb   r}   )r   r   re   rg   úassert %(py8)sÚpy8N)z-%(py2)s
{%(py2)s = %(py0)s.model
} == %(py5)sr   r!   r"   ra   rc   rd   rf   rg   )Úquber.agents.factoryr}   r   rj   rk   rl   rm   r	   Ú	ANTHROPICro   r#   r$   r%   r&   r'   r(   r)   r*   rp   rn   )r,   rt   ru   rv   r}   rc   rw   rb   r-   Ú@py_assert5r/   ry   Ú@py_format9r.   r0   r1   rx   s                    r2   Ú test_init_with_custom_parametersÚ@TestTableInferenceProcessorInit.test_init_with_custom_parametersd   sç  € õ
 	7ä!›ˆØ+/ˆ×ÑÔ(Ø")ˆÔà(7ÐÔ%Ü “{ˆØ*6Ô'ä+Ø"×,Ñ,Ð4PÐ[hñ
ˆ	ð ×!Ñ!Ð<×%<Ñ%<Ð<Ð%<Ñ<×<×<×<Ó<Ð!×<×<×<×<×<Õ<ˆy×<×<×<Ñ<ˆy×<×<Õ<Ð!×<×<×<×<×<Ô< ]×<×<×<Ñ< ]×<×<Õ<Ð%<×<×<×<×<×<×<Ó<Ø�‰Ð>Ð">Ð>Ð">Ñ>×>×>×>Ò>ˆ×>×>×>×>×>Õ>ˆy×>×>×>Ñ>ˆy×>×>Õ>ˆ×>×>Ó>Ð">×>×>×>×>×>×>Ó>Ø×!Ñ!Ð2 ]Ñ2×2×2×2Ò2Ð!×2×2×2×2×2Õ2ˆy×2×2×2Ñ2ˆy×2×2Õ2Ð!×2×2×2×2×2Ô2 ]×2×2×2Ñ2 ]×2×2×2×2×2×2Ô2r5   r?   N)	r@   rA   rB   rC   rD   r   rz   r†   rE   r?   r5   r2   rX   rX   G   s   † Ù;á
Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;ñNó <ó <ó ;ó =ðNñ, Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;ñ3ó <ó ;ó =ó3r5   rX   c                   ó2  • \ rS rSrSr\" S5      \" S5      \" S5      \" S5      S 5       5       5       5       r\" S5      \" S5      \" S5      \" S5      S 5       5       5       5       r\" S5      \" S5      \" S5      \" S5      S	 5       5       5       5       rS
r	g)Ú"TestTableInferenceProcessorHelpersé|   zTests for helper methods.rZ   r[   r\   r]   c                 ó¾  • [        5       nSUR                  l        SUl        XQl        SUl        [        5       n[        SSSS/SS	S
9nUR                  U5      nSo™U;   oª(       d¥  [        R                  " SU
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS=pšSo™U;   oª(       d¥  [        R                  " SU
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS=pšSo™U;   oª(       d¥  [        R                  " SU
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS=pšSo™U;   oª(       d¥  [        R                  " SU
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS=pšSo™U;   oª(       d¥  [        R                  " SU
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS=pšg)zTest format_prompt method.Fr_   r`   zDocument summaryúTable 1ÚCol1ÚCol2ú| A | B |
| 1 | 2 |r   r:   ©Úin©z%(py1)s in %(py3)sÚprompt©Úpy1Úpy3úassert %(py5)sr    Nz
Col1, Col2zpage 1z	| A | B |)r   rj   rk   rl   rm   r	   r   Úformat_promptr#   r$   r(   r%   r&   r'   r)   r*   )r,   rs   rt   ru   rv   rc   rb   r   r“   Ú@py_assert0Ú@py_assert2Ú@py_format4r0   s                r2   Útest_format_promptÚ5TestTableInferenceProcessorHelpers.test_format_prompt   s1  € ô "›ˆØ+0ˆ×ÑÔ(Ø"(ˆÔØ)6Ô&Ø(7ÐÔ%ä+Ó-ˆ	äØ0Ø&Ø˜VÐ$Ø0Øñ
ˆð ×(Ñ(¨Ó1ˆà!Ð+ VÑ+×+×+×+Ò+Ð!×+×+Ô+Ð!×+×+×+×+×+Ô+ V×+×+×+Ñ+ V×+×+×+×+×+×+Ó+ØÐ"˜FÑ"×"×"×"Ò"ˆy×"×"Ô"ˆy×"×"×"×"×"Ô"˜F×"×"×"Ñ"˜F×"×"×"×"×"×"Ó"ØÐ%˜vÑ%×%×%×%Ò%ˆ|×%×%Ô%ˆ|×%×%×%×%×%Ô%˜v×%×%×%Ñ%˜v×%×%×%×%×%×%Ó%ØÐ!˜6Ñ!×!×!×!Ò!ˆx×!×!Ô!ˆx×!×!×!×!×!Ô!˜6×!×!×!Ñ!˜6×!×!×!×!×!×!Ó!ØÐ$˜fÑ$×$×$×$Ò$ˆ{×$×$Ô$ˆ{×$×$×$×$×$Ô$˜f×$×$×$Ñ$˜f×$×$×$×$×$×$Ô$r5   c                 ó  • [        5       nSUR                  l        XQl        SUl        [	        5       nSnUR                  USS9nUR                  S5      n	[        U	5      n
SoºU:*  oÌ(       Gd  [        R                  " SU4S	X«45      S
[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS
S[        R                  " 5       ;   d  [        R                  " U	5      (       a  [        R                  " U	5      OS[        R                  " U
5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS=n
=pËg)zTest get_table_preview method.Fr`   z5| A | B |
| --- | --- |
| 1 | 2 |
| 3 | 4 |
| 5 | 6 |é   )Úmax_rowsÚ
é   )ú<=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} <= %(py6)sÚlenÚlines)r   r•   r–   rg   r€   r�   N)r   rj   rk   rm   r	   Úget_table_previewÚsplitr¤   r#   r$   r%   r&   r'   r(   r)   r*   )r,   rs   rt   ru   rv   rc   rb   ÚmarkdownÚpreviewr¥   rš   r„   r.   ry   r…   s                  r2   Útest_get_table_previewÚ9TestTableInferenceProcessorHelpers.test_get_table_preview�   sê   € ô "›ˆØ+0ˆ×ÑÔ(Ø)6Ô&Ø(7ÐÔ%ä+Ó-ˆ	àNˆØ×-Ñ-¨hÀÐ-ÐCˆð —‘˜dÓ#ˆÜ�5‹zÐ˜QÐ˜Q‰×××Óˆz×××××ÕŒs×××ÑŒs×××××Ö�5×××Ñ�5××Õˆz××Ó˜Q××××××Ôr5   c                 ó|  • [        5       nSUR                  l        XQl        SUl        [	        5       nUR                  S5      nSo‡U:H  o™(       d¥  [        R                  " SU	4SXx45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S.-  n
S	S
U
0-  n[        [        R                  " U5      5      eS=p˜UR                  S5      nSo‡U:H  o™(       d¥  [        R                  " SU	4SXx45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S.-  n
S	S
U
0-  n[        [        R                  " U5      5      eS=p˜g)z+Test get_table_preview with empty markdown.Fr`   NzNo table content availabler   ©z%(py0)s == %(py3)sr©   ©r   r–   r—   r    Ú )r   rj   rk   rm   r	   r¦   r#   r$   r%   r&   r'   r(   r)   r*   )r,   rs   rt   ru   rv   rc   rb   r©   rš   r-   r›   r0   s               r2   Útest_get_table_preview_emptyÚ?TestTableInferenceProcessorHelpers.test_get_table_preview_empty³   s
  € ô "›ˆØ+0ˆ×ÑÔ(Ø)6Ô&Ø(7ÐÔ%ä+Ó-ˆ	à×-Ñ-¨dÓ3ˆØ6Ð6Ð6Ñ6×6×6×6Ò6ˆw×6×6×6×6×6Õ6ˆw×6×6×6Ñ6ˆw×6×6Õ6Ð6×6×6×6×6×6×6Ñ6à×-Ñ-¨bÓ1ˆØ6Ð6Ð6Ñ6×6×6×6Ò6ˆw×6×6×6×6×6Õ6ˆw×6×6×6Ñ6ˆw×6×6Õ6Ð6×6×6×6×6×6×6Ò6r5   r?   N)
r@   rA   rB   rC   rD   r   rœ   rª   r°   rE   r?   r5   r2   r‰   r‰   |   sÏ   † Ù#á
Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;ñ%ó <ó <ó ;ó =ð%ñ4 Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;ñó <ó <ó ;ó =ðñ$ Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;ñ7ó <ó <ó ;ó =ó7r5   r‰   c            	       ón  • \ rS rSrSr\" S5      \" S5      \" S5      \" S5      \" S\S9S	 5       5       5       5       5       r\" S5      \" S5      \" S5      \" S5      \" S\S9S
 5       5       5       5       5       r\" S5      \" S5      \" S5      \" S5      \" S\S9S 5       5       5       5       5       r	Sr
g)Ú&TestTableInferenceProcessorSaveMethodséÉ   zTests for save methods.rZ   r[   r\   r]   zbuiltins.open)Únew_callablec                 ój  • [        5       nSUR                  l        Xbl        SUl        [	        5       nSSS.nUR                  US5        UR                  SSSS	9  U" 5       n	S
R                  S U	R                  R                   5       5      n
/ nSoÌU
;   oÝoí(       d  U	R                  oÿR                  nUnU(       Gdj  [        R                  " SU4SXÊ45      [        R                  " U5      S[        R                  " 5       ;   d  [        R                   " U
5      (       a  [        R                  " U
5      OSS.-  nSSU0-  nUR#                  U5        U(       dŒ  SS[        R                  " 5       ;   d  [        R                   " U	5      (       a  [        R                  " U	5      OS[        R                  " W5      [        R                  " W5      S.-  nUR#                  U5        [        R$                  " US5      0 -  nSSU0-  n['        [        R(                  " U5      5      eS=n=n=n=n=nng)zTest save_json method.Fr`   útest.pdfrŸ   )ÚdocumentÚtotal_tablesz/output/test.jsonÚwúutf-8©Úencodingr¯   c              3   ó>   #   • U  H  oR                   S    v •  M     g7f)r   N)Úargs)Ú.0Úcalls     r2   Ú	<genexpr>ÚHTestTableInferenceProcessorSaveMethods.test_save_json.<locals>.<genexpr>â   s   é € Ð!WÒ;V°4§)¡)¨A¦,Ò;Vùs   ‚r�   ©z%(py3)s in %(py5)sÚwritten_content©r–   r    ú%(py7)sr"   zB%(py13)s
{%(py13)s = %(py11)s
{%(py11)s = %(py9)s.write
}.called
}Úhandle)Úpy9Úpy11Úpy13r   zassert %(py16)sÚpy16N)r   rj   rk   rm   r	   Ú	save_jsonrr   ÚjoinÚwriteÚcall_args_listÚcalledr#   r$   r(   r%   r&   r'   ÚappendÚ_format_boolopr)   r*   )r,   Ú	mock_filers   rt   ru   rv   rc   rb   ÚdatarÈ   rÅ   r-   rš   r.   r™   Ú@py_assert10Ú@py_assert12r0   r1   Ú@py_format14Ú@py_format15Ú@py_format17s                         r2   Útest_save_jsonÚ5TestTableInferenceProcessorSaveMethods.test_save_jsonÌ   sU  € ô "›ˆØ+0ˆ×ÑÔ(Ø)6Ô&Ø(7ÐÔ%ä+Ó-ˆ	à&¸Ñ:ˆØ×Ñ˜DÐ"5Ô6à×)Ñ)Ð*=¸sÈWÐ)ÑUá“ˆØŸ'™'Ñ!W¸6¿<¹<×;VÒ;VÓ!WÓWˆáCˆzÐC˜_Ñ,×C°·±ÐC×0CÑ0CÐCÐ0C×C×C×CÔCˆz×C×CÔCˆz×C×C×C×C×CÔC˜_×C×C×CÑC˜_×C×C×C×C×C×C×C×C×C×CÓC°×C×C×CÑC°×C×CÕC°×C×CÓCÐ0C×C×C×C×C×C×C×C×C×C×C×C×CÖCr5   c                 ód  • [        5       nSUR                  l        Xbl        SUl        [	        5       nSSSSSSSS	S
S/SSSSSSSS.S.	/S.nUR                  US5        UR                  SSSS9  U" 5       n	U	R                  oªR                  o»(       dš  SS[        R                  " 5       ;   d  [        R                  " U	5      (       a  [        R                  " U	5      OS[        R                  " U
5      [        R                  " U5      S.-  n[        [        R                  " U5      5      eS=p«g)zTest save_summary method.Fr`   r·   ú
2024-01-01Ú	anthropicr   r   r   rŒ   r�   rŽ   zTest descriptionrJ   zQuarterly revenuer�   rŸ   ÚA)ÚrowsÚcolsÚ
first_cell)	Útable_idÚpager   r   r   Ú	llm_titleÚllm_descriptionÚtable_markdownÚmetadata©r¸   Úextraction_dateÚmodel_providerrp   r¹   Útablesz/output/test_summary.mdrº   r»   r¼   zEassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.write
}.called
}rÈ   rd   N)r   rj   rk   rm   r	   Úsave_summaryrr   rÏ   rÑ   r%   r&   r#   r'   r(   r)   r*   )r,   rÔ   rs   rt   ru   rv   rc   rb   rÕ   rÈ   r-   r/   rx   s                r2   Útest_save_summaryÚ8TestTableInferenceProcessorSaveMethods.test_save_summaryæ   s  € ô "›ˆØ+0ˆ×ÑÔ(Ø)6Ô&Ø(7ÐÔ%ä+Ó-ˆ	ð #Ø+Ø)Ø1Øð !"ØØ(1Ø &¨Ð/Ø(:Ø!1Ø':Ø&<Ø)*°AÀSÑ Iñ
ðñ
ˆð* 	×Ñ˜tÐ%>Ô?à×)Ñ)Ð*CÀSÐSZÐ)Ñ[Ù“ˆà�|‰|Ð"×"Ñ"Ð"Õ"×"×"×"×"×"Ñ"ˆv×"×"×"Ñ"ˆv×"×"Õ"ˆ|×"×"Ó"Ð"×"×"×"×"×"Ó"r5   c                 óÄ  ^• [        5       nSUR                  l        Xbl        SUl        [	        5       nSSSSSSSS	S
SSSSS.S./S.n/ mU4S jn	X‘" 5       R
                  l        UR                  US5        SR                  T5      n
So»U
;   oÌ(       d¥  [        R                  " SU4SXº45      [        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U
5      (       a  [        R                  " U
5      OSS.-  nSSU0-  n[        [        R                   " U5      5      eS=p¼/ nS	oÌU
;   nUnU(       d	  S
nUU
;   nUnU(       Gdv  [        R                  " SU4SXÊ45      [        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U
5      (       a  [        R                  " U
5      OSS.-  nSSU0-  nUR#                  U5        U(       d˜  [        R                  " SW4SWU
45      [        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U
5      (       a  [        R                  " U
5      OSS .-  nS!S"U0-  nUR#                  U5        [        R$                  " US5      0 -  nS#S$U0-  n[        [        R                   " U5      5      eS=n=n=n=n=nng)%z,Test save_summary generates correct content.Fr`   r·   rÞ   rß   r   r   r   rŒ   rJ   zRevenue breakdownz| Q1 | Q2 |
| 100 | 200 |rŸ   )rá   râ   )rä   rå   r   ræ   rç   rè   ré   rê   c                 ó(   >• TR                  U 5        g ©N)rÒ   )ÚcontentÚwritten_liness    €r2   Úwrite_side_effectÚ[TestTableInferenceProcessorSaveMethods.test_save_summary_content.<locals>.write_side_effect8  s   ø€ Ø× Ñ  Õ)r5   z/output/summary.mdr¯   r�   r’   rÅ   r”   r—   r    NrÄ   rÆ   rÇ   r"   )z%(py10)s in %(py12)s)Úpy10Úpy12z%(py14)sÚpy14zassert %(py17)sÚpy17)r   rj   rk   rm   r	   rÏ   Úside_effectrî   rÎ   r#   r$   r(   r%   r&   r'   r)   r*   rÒ   rÓ   )r,   rÔ   rs   rt   ru   rv   rc   rb   rÕ   rö   rÅ   r™   rš   r›   r0   r-   r.   Ú@py_assert9Ú@py_assert11r1   Ú@py_format13rÙ   Ú@py_format16Ú@py_format18rõ   s                           @r2   Útest_save_summary_contentÚ@TestTableInferenceProcessorSaveMethods.test_save_summary_content  sÚ  ø€ ô "›ˆØ+0ˆ×ÑÔ(Ø)6Ô&Ø(7ÐÔ%ä+Ó-ˆ	ð #Ø+Ø)Ø1Øð !"ØØ(1Ø!1Ø':Ø&BØ)*°AÑ 6ñð
ñ
ˆð( ˆõ	*ð ):ˆ	‹×ÑÔ%à×Ñ˜tÐ%9Ô:àŸ'™' -Ó0ˆð Ð,˜_Ñ,×,×,×,Ò,ˆz×,×,Ô,ˆz×,×,×,×,×,Ô,˜_×,×,×,Ñ,˜_×,×,×,×,×,×,Ó,ÙRˆyÐR˜OÑ+×RÑRÐ/?ÐRÐ/?À?Ñ/R×R×R×RÖRˆy×R×RÔRˆy×R×R×R×R×RÔR˜O×R×R×RÑR˜O×R×R×R×R×R×R×RÕRÐ/?À?×R×RÔRÐ/?×R×R×R×R×RÔRÀ?×R×R×RÑRÀ?×R×R×R×R×R×R×R×R×R×R×R×R×R×Rr5   r?   N)r@   rA   rB   rC   rD   r   r   rÛ   rï   r  rE   r?   r5   r2   r³   r³   É   s  † Ù!á
Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;Ù
ˆ?¨Ñ3ñDó 4ó <ó <ó ;ó =ð
Dñ* Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;Ù
ˆ?¨Ñ3ñ%#ó 4ó <ó <ó ;ó =ð
%#ñN Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;Ù
ˆ?¨Ñ3ñ,Só 4ó <ó <ó ;ó =ó
,Sr5   r³   c                   ó&   • \ rS rSrSrS\4S jrSrg)ÚFakeProviF  zHStand-in for a docling ProvenanceItem: just carries a 1-indexed page_no.Úpage_noc                 ó   • Xl         g ró   ©r  )r,   r  s     r2   Ú__init__ÚFakeProv.__init__I  s   € Ø�r5   r  N)r@   rA   rB   rC   rD   Úintr	  rE   r?   r5   r2   r  r  F  s   † ÙRð ÷ r5   r  c                   ó8   • \ rS rSrSrS	S\S\S\\   4S jjrSr	g)
ÚFakeItemiM  a<  Stand-in for a docling node item as yielded by iterate_items().

Mirrors the real contract the code depends on: the page lives in a `prov`
list (not a `_page` attribute), text items have `text`, and header items
additionally have a `level`. iterate_items() yields (item, level) tuples,
so tests wrap these in tuples.Nrå   ÚtextÚlevelc                 óF   • [        U5      /U l        X l        Ub  X0l        g g ró   )r  Úprovr  r  )r,   rå   r  r  s       r2   r	  ÚFakeItem.__init__U  s%   € Ü˜d“^Ð$ˆŒ	ØŒ	ØÑØ�Jð r5   )r  r  r  )r¯   N)
r@   rA   rB   rC   rD   r  Ústrr   r	  rE   r?   r5   r2   r  r  M  s*   † ñ&ñ˜Sð ¨ð ¸À#¹÷ ð r5   r  Úitemsc                  ó4   • U  Vs/ s H  oS4PM     sn$ s  snf )zCWrap items as the (item, tree-level) tuples iterate_items() yields.r   r?   )r  Úitems     r2   Ú_itemsr  \  s   € á"'Ó(¢%˜$�1‹I¡%Ñ(Ð(ùÒ(s   …c                   ó2  • \ rS rSrSr\" S5      \" S5      \" S5      \" S5      S 5       5       5       5       r\" S5      \" S5      \" S5      \" S5      S 5       5       5       5       r\" S5      \" S5      \" S5      \" S5      S	 5       5       5       5       rS
r	g)ÚTestExtractPageContextia  z&Tests for extract_page_context method.rZ   r[   r\   r]   c           	      ó¦  • [        5       nSUR                  l        XQl        SUl        [	        5       n[        5       n[        [        SSSS9[        SSS9[        SS	S95      UR                  l        UR                  USS
9nSo™U;   oª(       d¥  [        R                  " SU
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                   " U5      5      eS=pšSo™U;   oª(       d¥  [        R                  " SU
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                   " U5      5      eS=pšSo™U;   oª(       d¥  [        R                  " SU
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                   " U5      5      eS=pšS	o™U;  oª(       d¥  [        R                  " SU
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                   " U5      5      eS=pšg)a   Page text and headers on the table's page are collected; other pages excluded.

Drives iterate_items() with the real contract (tuples of (item, level);
page read from item.prov[*].page_no), so it fails against the prior code
that looked for a non-existent `_page` attribute on the tuple.
Fr`   r   zHeader text)rå   r  r  z	Body text©rå   r  rŸ   zOther page text©r   r�   r’   r   r”   r—   r    Nz[Header L1])únot in)z%(py1)s not in %(py3)s©r   rj   rk   rm   r	   r  r  Úiterate_itemsÚextract_page_contextr#   r$   r(   r%   r&   r'   r)   r*   ©r,   rs   rt   ru   rv   rc   rb   Úmock_documentr   r™   rš   r›   r0   s                r2   Útest_extract_page_contextÚ0TestExtractPageContext.test_extract_page_contextd  sð  € ô "›ˆØ+0ˆ×ÑÔ(Ø)6Ô&Ø(7ÐÔ%ä+Ó-ˆ	ä!›ˆÜ39Ü˜! -°qÑ9Ü˜! +Ñ.Ü˜!Ð"3Ñ4ó4
ˆ×#Ñ#Ô0ð ×0Ñ0°ÈAÐ0ÐNˆàÐ' Ñ'×'×'×'Ò'ˆ}×'×'Ô'ˆ}×'×'×'×'×'Ô' ×'×'×'Ñ' ×'×'×'×'×'×'Ó'ØÐ%˜gÑ%×%×%×%Ò%ˆ{×%×%Ô%ˆ{×%×%×%×%×%Ô%˜g×%×%×%Ñ%˜g×%×%×%×%×%×%Ó%ØÐ' Ñ'×'×'×'Ò'ˆ}×'×'Ô'ˆ}×'×'×'×'×'Ô' ×'×'×'Ñ' ×'×'×'×'×'×'Ó'Ø Ð/¨Ñ/×/×/×/Ò/Ð ×/×/Ô/Ð ×/×/×/×/×/Ô/¨×/×/×/Ñ/¨×/×/×/×/×/×/Ô/r5   c                 ó*  • [        5       nSUR                  l        XQl        SUl        [	        5       n[        5       n[        [        SSS9[        SSS95      UR                  l        UR                  USS9nS	o™U;   oª(       d¥  [        R                  " S
U
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                   " U5      5      eS=pšSo™U;   oª(       d¥  [        R                  " S
U
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                   " U5      5      eS=pšSo™U;   oª(       d¥  [        R                  " S
U
4SX˜45      [        R                  " U	5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                   " U5      5      eS=pšg)zFWhen the table's page is sparse, a tail of the previous page is added.Fr`   r   zIntro on the prior pager  rŸ   ÚShortr  z=== Previous Page Context ===r�   r’   r   r”   r—   r    Nr  r!  s                r2   Ú5test_extract_page_context_includes_previous_page_tailÚLTestExtractPageContext.test_extract_page_context_includes_previous_page_tail†  s‹  € ô "›ˆØ+0ˆ×ÑÔ(Ø)6Ô&Ø(7ÐÔ%ä+Ó-ˆ	ä!›ˆÜ39Ü˜!Ð";Ñ<Ü˜! 'Ñ*ó4
ˆ×#Ñ#Ô0ð
 ×0Ñ0°ÈAÐ0ÐNˆà.Ð9°'Ñ9×9×9×9Ò9Ð.×9×9Ô9Ð.×9×9×9×9×9Ô9°'×9×9×9Ñ9°'×9×9×9×9×9×9Ó9Ø(Ð3¨GÑ3×3×3×3Ò3Ð(×3×3Ô3Ð(×3×3×3×3×3Ô3¨G×3×3×3Ñ3¨G×3×3×3×3×3×3Ó3ØÐ!˜'Ñ!×!×!×!Ò!ˆw×!×!Ô!ˆw×!×!×!×!×!Ô!˜'×!×!×!Ñ!˜'×!×!×!×!×!×!Ô!r5   c                 ó&  • [        5       nSUR                  l        XQl        SUl        [	        5       n[        5       n/ UR
                  l        UR                  USS9nSo˜U	:H  oª(       d¥  [        R                  " SU
4SX‰45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U	5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS=p©g)z*Test extract_page_context with no content.Fr`   r   r  zNo page context availabler   r­   r   r®   r—   r    N)r   rj   rk   rm   r	   r  r   r#   r$   r%   r&   r'   r(   r)   r*   )r,   rs   rt   ru   rv   rc   rb   r"  r   rš   r-   r›   r0   s                r2   Ú$test_extract_page_context_no_contentÚ;TestExtractPageContext.test_extract_page_context_no_content¡  s·   € ô "›ˆØ+0ˆ×ÑÔ(Ø)6Ô&Ø(7ÐÔ%ä+Ó-ˆ	ä!›ˆØ35ˆ×#Ñ#Ô0à×0Ñ0°ÈAÐ0ÐNˆà5Ð5Ð5Ñ5×5×5×5Ò5ˆw×5×5×5×5×5Õ5ˆw×5×5×5Ñ5ˆw×5×5Õ5Ð5×5×5×5×5×5×5Ò5r5   r?   N)
r@   rA   rB   rC   rD   r   r#  r'  r*  rE   r?   r5   r2   r  r  a  sÏ   † Ù0á
Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;ñ0ó <ó <ó ;ó =ð0ñ< Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;ñ"ó <ó <ó ;ó =ð"ñ. Ð;Ó<Ù
Ð9Ó:Ù
Ð:Ó;Ù
Ð:Ó;ñ6ó <ó <ó ;ó =ó6r5   r  )rD   Úbuiltinsr%   Ú_pytest.assertion.rewriteÚ	assertionÚrewriter#   Útypingr   Úunittest.mockr   r   r   Ú quber.processors.table_inferencer   r   r	   r
   r   rG   rQ   rX   r‰   r³   r  r  r  r  r?   r5   r2   Ú<module>r3     s–   ðÙ Bç  „ Õ ß 5Ñ 5÷ó ÷!,ñ !,÷HAñ A÷Lñ L÷23ñ 23÷jJ7ñ J7÷ZzSñ zS÷zñ ÷ñ ð)�8ô )÷
T6ò T6r5   