
    mXi+                       d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
mZ ddlZe	j                  j                  d e ee      j"                  j"                  j"                               ddlmZmZmZmZmZ ddlmZ ej4                  d        Zej4                  d        Z G d	 d
      Z G d d      Z G d d      Z G d d      Z  G d d      Z!y)uC   utils/session_search.py 테스트 스위트 (TDD — RED → GREEN)    )annotationsN)Path)_format_conversation_resolve_lineage_root_truncate_around_matchessanitize_fts5_querysearch_sessions)SessionStorec              #  h   K   t        | dz        }t        |      }| |j                          yw)u.   임시 DB 경로를 사용하는 SessionStore.ztest_search.db)db_pathN)strr
   close)tmp_pathr   ss      6/home/jay/workspace/utils/tests/test_session_search.pystorer      s0      (--.GW%A
GGGIs   02c                   | j                  dd       | j                  ddd       | j                  ddd       | j                  d	d       | j                  d	dd
       | j                  dd       | j                  ddd       | S )u5   검색 테스트용 세션/메시지가 있는 store.
sess-alphaapisourceuserzhello world FTS5 testrolecontent	assistantzresponse to helloz	sess-betazpython programming rocksz
sess-gammazcompletely unrelated content)create_sessionappend_message)r   s    r   populated_storer   $   s     
e4	F<ST	KATU	U3	6;UV	e4	F<Z[L    c                  X    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zy)TestSanitizeFts5Queryu   FTS5 쿼리 특수문자 처리c                   d}t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}}y)	u,   일반 단어는 변경 없이 반환된다.hello==z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sr   py0py2py4py7assert %(py9)spy9N	r   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationself@py_assert1@py_assert3@py_assert6@py_assert5@py_format8@py_format10s          r   test_plain_word_unchangedz/TestSanitizeFts5Query.test_plain_word_unchanged;   s    #*6"7+6w6+w6666+w666666"666"6667666+666w6666666r    c                   t        d      }d}||v}|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}d
}||v}|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)u   괄호가 제거된다.z(hello world)(not inz%(py1)s not in %(py3)sresultpy1py3assert %(py5)spy5N)	r   r0   r1   r5   r2   r3   r4   r6   r7   r9   rF   @py_assert0@py_assert2@py_format4@py_format6s         r   test_removes_parenthesesz.TestSanitizeFts5Query.test_removes_parentheses?   s    $_5 s&    s&   s      &   &        s&    s&   s      &   &       r    c                d   t        d      }d}||v}|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)
u   + 연산자가 제거된다.zhello+world+rC   rE   rF   rG   rJ   rK   NrM   rN   s         r   test_removes_plus_operatorz0TestSanitizeFts5Query.test_removes_plus_operatorE   se    $]3 s&    s&   s      &   &       r    c                d   t        d      }d}||v}|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)
u   * 연산자가 제거된다.zhello**rC   rE   rF   rG   rJ   rK   NrM   rN   s         r   test_removes_star_operatorz0TestSanitizeFts5Query.test_removes_star_operatorJ   se    $X. s&    s&   s      &   &       r    c                d   t        d      }d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}y)	u!   인용구("...")는 보호된다.z"hello world"inz%(py1)s in %(py3)srF   rG   rJ   rK   NrM   rN   s         r   test_quoted_phrase_preservedz2TestSanitizeFts5Query.test_quoted_phrase_preservedO   se    $_5(&((((&(((((((((&(((&(((((((r    c                   t        d      }d}||v}|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}d
}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)u   AND 연산자가 제거된다.zhello AND worldANDrC   rE   rF   rG   rJ   rK   Nr$   r[   r]   worldrM   rN   s         r   test_removes_and_operatorz/TestSanitizeFts5Query.test_removes_and_operatorT   s   $%67"uF""""uF"""u""""""F"""F""""""" w&    w&   w      &   &        w&    w&   w      &   &       r    c                d   t        d      }d}||v}|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)
u   OR 연산자가 제거된다.zhello OR worldORrC   rE   rF   rG   rJ   rK   NrM   rN   s         r   test_removes_or_operatorz.TestSanitizeFts5Query.test_removes_or_operator[   sf    $%56!t6!!!!t6!!!t!!!!!!6!!!6!!!!!!!r    c                d   t        d      }d}||v}|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)
u   NOT 연산자가 제거된다.zhello NOT worldNOTrC   rE   rF   rG   rJ   rK   NrM   rN   s         r   test_removes_not_operatorz/TestSanitizeFts5Query.test_removes_not_operator`   sf    $%67"uF""""uF"""u""""""F"""F"""""""r    c                d   t        d      }d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}y)	u1   ANDROID 같은 단어 안의 AND는 보호된다.ANDROIDr[   r]   rF   rG   rJ   rK   NrM   rN   s         r   test_android_preservedz,TestSanitizeFts5Query.test_android_preservede   se    $Y/"yF""""yF"""y""""""F"""F"""""""r    c                d   t        d      }d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)
u3   하이픈 단어(chat-send)가 인용 처리된다.z	chat-sendz"chat-send"r[   r]   rF   rG   rJ   rK   NrM   rN   s         r   test_hyphenated_word_quotedz1TestSanitizeFts5Query.test_hyphenated_word_quotedj   se    $[1&}&&&&}&&&}&&&&&&&&&&&&&&&&r    c                   d}t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}}y)	u#   빈 쿼리는 빈 문자열 반환. r%   r'   r   r(   r-   r.   Nr/   r8   s          r   test_empty_query_returns_emptyz4TestSanitizeFts5Query.test_empty_query_returns_emptyo   s    #%,"2&,",&",,,,&",,,,,,",,,",,,2,,,&,,,",,,,,,,r    c                   t        d      }d}|j                  } |       }||v}|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}x}}y	)
u!   연속 공백이 정규화된다.zhello   worldz  rC   )zH%(py1)s not in %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.strip
}()
}rF   )rH   rI   rK   r,   r-   r.   N)
r   stripr0   r1   r5   r2   r3   r4   r6   r7   )r9   rF   rO   @py_assert4r<   rP   r>   r?   s           r   test_whitespace_normalizedz0TestSanitizeFts5Query.test_whitespace_normalizeds   s    $_5)6<<)<>)t>))))t>)))t))))))6)))6)))<)))>)))))))r    N)__name__
__module____qualname____doc__r@   rS   rV   rY   r^   rb   re   rh   rk   rm   rp   rt    r    r   r"   r"   8   sA    )7!!
!
)
!"
#
#
'
-*r    r"   c                  F    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)TestSearchSessionsu   FTS5 세션 검색 동작c                   t        d|      }t        |t              }|sddt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}d}||v }|st        j                  d	|fd
||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}y)u(   기본 검색이 결과를 반환한다.r$   5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancerF   dictr)   rH   r*   r+   Nresultsr[   r]   rG   rJ   rK   )r	   r~   r   r2   r3   r0   r4   r5   r6   r7   r1   )	r9   r   rF   r;   @py_format5rO   rP   rQ   rR   s	            r   !test_basic_search_returns_resultsz4TestSearchSessions.test_basic_search_returns_results   s     /:&$''''''''z'''z''''''&'''&''''''$'''$''''''''''"yF""""yF"""y""""""F"""F"""""""r    c                   t        d|      }|d   D cg c]  }|d   	 }}d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }d	d
|iz  }t        t        j                  |            dx}}yc c}w )u(   매칭 세션이 결과에 포함된다.r$   r   
session_idr   r[   r]   session_idsrG   rJ   rK   N	r	   r0   r1   r5   r2   r3   r4   r6   r7   	r9   r   rF   rr   rO   rP   rQ   rR   s	            r   test_matching_session_foundz.TestSearchSessions.test_matching_session_found   s     /:06y0AB1qBB*|{****|{***|******{***{******* Cs   Cc                   t        d|d      }|d   }t        |      }d}||k  }|st        j                  d|fd||f      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}x}x}}y)u1   limit 파라미터가 결과 수를 제한한다.r$      )limitr   <=)z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} <= %(py7)slenr(   r-   r.   N)
r	   r   r0   r1   r2   r3   r4   r5   r6   r7   )	r9   r   rF   r:   r;   r<   r=   r>   r?   s	            r   test_limit_respectedz'TestSearchSessions.test_limit_respected   s     /C)$*s$%**%****%******s***s***$***%**********r    c                   t        d|      }|d   }g }||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t	        t        j
                  |            dx}x}}y)	u)   빈 쿼리는 빈 결과를 반환한다.ro   r   r%   z%(py1)s == %(py4)srH   r+   assert %(py6)spy6Nr	   r0   r1   r5   r6   r7   r9   r   rF   rO   r;   rP   r   @py_format7s           r   &test_empty_query_returns_empty_resultsz9TestSearchSessions.test_empty_query_returns_empty_results   s`     _5i &B& B&&&& B&&& &&&B&&&&&&&r    c                   t        d|      }|d   }g }||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t	        t        j
                  |            dx}x}}y)	u#   매칭 없는 쿼리는 빈 결과.xyzzy_no_match_everr   r%   r   r   r   r   Nr   r   s           r   test_no_match_returns_emptyz.TestSearchSessions.test_no_match_returns_empty   sa     !6Hi &B& B&&&& B&&& &&&B&&&&&&&r    c                   t        d|dg      }|d   D cg c]  }|d   	 }}g }d}||v}|}|s|d   }	t        |	      }
d}|
|k(  }|}|st        j                  d|fd	||f      t        j                  |      d
t        j                         v st        j                  |      rt        j                  |      nd
dz  }dd|iz  }|j                  |       |st        j                  dfd
f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  	      t        j                  |
      t        j                  |      dz  }dd|iz  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            dx}x}x}x}x}	x}
x}}yc c}w )u:   role_filter=['user']이면 user 메시지만 검색한다.responser   )role_filterr   r   r   r   rC   )z%(py3)s not in %(py5)sr   )rI   rK   z%(py7)sr,   r%   )z4%(py13)s
{%(py13)s = %(py9)s(%(py11)s)
} == %(py16)sr   )r.   py11py13py16z%(py18)spy18r   zassert %(py21)spy21N)r	   r   r0   r1   r5   r2   r3   r4   append_format_boolopr6   r7   )r9   r   rF   r   r   r:   rP   rs   rO   @py_assert10@py_assert12@py_assert15@py_assert14rR   r>   @py_format17@py_format19@py_format20@py_format22s                      r   test_role_filter_user_onlyz-TestSearchSessions.test_role_filter_user_only   s(    _6(S06y0AB1qBBM|M|;.MfY6GM#6G2HMAM2HA2MMMMM|;MMM|MMMMMM;MMM;MMMMMMM2HAMMMMMM#MMM#MMM6GMMM2HMMMAMMMMMMMMMMMMMM Cs   G&c                   t        d|d      }|d   D cg c]  }|d   	 }}d}||v}|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndd	z  }d
d|iz  }t        t        j                  |            dx}}yc c}w )uN   current_session_id가 설정되면 해당 세션이 결과에서 제외된다.r$   r   )current_session_idr   r   rC   rE   r   rG   rJ   rK   Nr   r   s	            r   test_current_session_excludedz0TestSearchSessions.test_current_session_excluded   s     /l[06y0AB1qBB.|;....|;...|......;...;....... Cs   C
c                ,   t        d|      }|d   rd}|d   d   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t	        t        j
                  |            d
x}x}}y
y
)u*   결과 항목에 summary 필드가 있다.r$   r   summaryr   r[   z%(py1)s in %(py4)sr   r   r   Nr   r   s           r   test_result_contains_summaryz/TestSearchSessions.test_result_contains_summary   sr     /:)4y 1! 449 444449 44449444 44444444 r    c                ,   t        d|      }|d   rd}|d   d   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd	|iz  }t	        t        j
                  |            d
x}x}}y
y
)u-   결과 항목에 session_id 필드가 있다.r$   r   r   r   r[   r   r   r   r   Nr   r   s           r   test_result_contains_session_idz2TestSearchSessions.test_result_contains_session_id   sr     /:)76)#4Q#77<#77777<#7777<777#77777777 r    N)ru   rv   rw   rx   r   r   r   r   r   r   r   r   r   ry   r    r   r{   r{   ~   s3    ##++
'
'
N/58r    r{   c                  .    e Zd ZdZd Zd Zd Zd Zd Zy)TestResolveLineageRootu   위임 체인 루트 탐색c                ~   |j                  dd       d}t        ||      }d}||k(  }|s
t        j                  d|fd||f      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}x}x}}y)u0   parent_session_id가 없으면 자신이 루트.z	root-onlyr   r   r%   z9%(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
} == %(py8)sr   r   r)   r*   rI   rK   py8assert %(py10)spy10N
r   r   r0   r1   r2   r3   r4   r5   r6   r7   r9   r   r:   rs   @py_assert7r<   @py_format9@py_format11s           r    test_single_session_returns_selfz7TestResolveLineageRoot.test_single_session_returns_self   s    [7%0G$[%8GKG8KGGGG8KGGGGGG$GGG$GGG[GGGGGG%GGG%GGG8GGGKGGGGGGGr    c                   |j                  dd       |j                  ddd       d}t        ||      }d}||k(  }|s
t        j                  d|fd||f      dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            dx}x}x}}y)u,   부모 체인을 타고 루트를 찾는다.zroot-1r   r   zchild-1r   parent_session_idr%   r   r   r   r   r   r   Nr   r   s           r   test_child_returns_rootz.TestResolveLineageRoot.test_child_returns_root   s    Xe4YuQ%.B$Y6B(B6(BBBB6(BBBBBB$BBB$BBBYBBBBBBBBBBBB6BBB(BBBBBBBr    c                   |j                  dd       |j                  ddd       |j                  ddd       d}t        ||      }d}||k(  }|s
t        j                  d|fd||f      d	t	        j
                         v st        j                  t              rt        j                  t              nd	t        j                  |      d
t	        j
                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}}y)u,   3단계 체인에서도 루트를 찾는다.r   r   r   c1r   c2r%   r   r   r   r   r   r   Nr   r   s           r   test_deep_chain_returns_rootz3TestResolveLineageRoot.test_deep_chain_returns_root   s    S/T%3GT%4H%)8$T518S81S88881S888888$888$888T888888588858881888S8888888r    c                X   d}t        ||      }d}||k(  }|s
t        j                  d|fd||f      dt        j                         v st        j
                  t               rt        j                  t               ndt        j                  |      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}x}}y	)
uI   존재하지 않는 session_id는 자신을 반환한다 (안전 폴백).nonexistentr%   r   r   r   r   r   r   N)	r   r0   r1   r2   r3   r4   r5   r6   r7   r   s           r   !test_unknown_session_returns_selfz8TestResolveLineageRoot.test_unknown_session_returns_self   s    %2K$]E:KmK:mKKKK:mKKKKKK$KKK$KKK]KKKKKKEKKKEKKK:KKKmKKKKKKKr    c                J   ddl }|j                  dd       |j                  ddd       |j                  |j                        }|j	                  d       |j                          |j                          t        d|      }t        |t              }|sd	d
t        j                         v st        j                  t              rt        j                  t              nd
dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                   |            d}y)u<   순환 참조가 있어도 무한루프 없이 종료된다.r   Nzcycle-ar   r   zcycle-br   zJUPDATE sessions SET parent_session_id='cycle-b' WHERE session_id='cycle-a'r}   r~   rF   r   r   )sqlite3r   connectr   executecommitr   r   r~   r   r2   r3   r0   r4   r5   r6   r7   )r9   r   r   connrF   r;   r   s          r   test_cycle_guardz'TestResolveLineageRoot.test_cycle_guard   s     	Yu5Yu	Ru}}-ab

&y%8&#&&&&&&&&z&&&z&&&&&&&&&&&&&&&&&#&&&#&&&&&&&&&&r    N)	ru   rv   rw   rx   r   r   r   r   r   ry   r    r   r   r      s!    %H
C9L'r    r   c                  (    e Zd ZdZd Zd Zd Zd Zy)TestTruncateAroundMatchesu0   쿼리 매칭 위치 중심 텍스트 창 추출c                n   d}t        |dd      }d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }d	d
|iz  }t        t        j                  |            dx}}y)u;   max_chars보다 짧은 텍스트는 그대로 반환된다.zhello worldr$   i  	max_charsr[   r]   rF   rG   rJ   rK   N	r   r0   r1   r5   r2   r3   r4   r6   r7   )r9   textrF   rO   rP   rQ   rR   s          r   test_short_text_returned_as_isz8TestTruncateAroundMatches.test_short_text_returned_as_is   sn    )$4H w&    w&   w      &   &       r    c                J   ddz  }t        |dd      }t        |      }d}||k  }|st        j                  d|fd||f      d	t	        j
                         v st        j                  t              rt        j                  t              nd	d
t	        j
                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)u+   max_chars보다 긴 텍스트는 잘린다.xi@ xxxd   r      r   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} <= %(py6)sr   rF   r)   rH   rI   r   assert %(py8)sr   N
r   r   r0   r1   r2   r3   r4   r5   r6   r7   r9   r   rF   rP   r=   rs   r   r   s           r   test_long_text_truncatedz2TestTruncateAroundMatches.test_long_text_truncated   s    W})$E6{!c!{c!!!!{c!!!!!!s!!!s!!!!!!6!!!6!!!{!!!c!!!!!!!r    c                   ddz  }|dz   ddz  z   }t        |dd      }d}||v }|st        j                  d|fd||f      t        j                  |      d	t	        j
                         v st        j                  |      rt        j                  |      nd	d
z  }dd|iz  }t        t        j                  |            dx}}y)u/   매칭 위치 주변 텍스트가 포함된다.aiP  TARGETbi  r   r[   r]   rF   rG   rJ   rK   Nr   )r9   prefixr   rF   rO   rP   rQ   rR   s           r   test_match_position_includedz6TestTruncateAroundMatches.test_match_position_included   s    v 3</)$CH!x6!!!!x6!!!x!!!!!!6!!!6!!!!!!!r    c                J   ddz  }t        |dd      }t        |      }d}||k  }|st        j                  d|fd||f      d	t	        j
                         v st        j                  t              rt        j                  t              nd	d
t	        j
                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)u2   빈 쿼리는 텍스트 앞부분을 반환한다.zhello world i'  ro   r   r   r   r   r   r   rF   r   r   r   Nr   r   s           r   test_empty_query_returns_headz7TestTruncateAroundMatches.test_empty_query_returns_head   s    %)$cB6{!c!{c!!!!{c!!!!!!s!!!s!!!!!!6!!!6!!!{!!!c!!!!!!!r    N)ru   rv   rw   rx   r   r   r   r   ry   r    r   r   r      s    :!"""r    r   c                  "    e Zd ZdZd Zd Zd Zy)TestFormatConversationu   메시지 직렬화c                Z   t        g       }t        |t              }|sddt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}y)u2   빈 메시지 목록은 문자열을 반환한다.r}   r~   rF   r   r   N)
r   r~   r   r2   r3   r0   r4   r5   r6   r7   )r9   rF   r;   r   s       r   "test_empty_messages_returns_stringz9TestFormatConversation.test_empty_messages_returns_string  s    %b)&#&&&&&&&&z&&&z&&&&&&&&&&&&&&&&&#&&&#&&&&&&&&&&r    c                r   ddddg}t        |      }d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }d	d
|iz  }t        t        j                  |            dx}}y)u)   메시지 role이 포맷에 포함된다.r   r$   z
2024-01-01)r   r   
created_atr[   r]   rF   rG   rJ   rK   N	r   r0   r1   r5   r2   r3   r4   r6   r7   r9   msgsrF   rO   rP   rQ   rR   s          r   test_message_role_includedz1TestFormatConversation.test_message_role_included  st    G<PQ%d+vvvr    c                p   dddg}t        |      }d}||v }|st        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }dd	|iz  }t        t        j                  |            d
x}}y
)u,   메시지 content가 포맷에 포함된다.r   unique_content_xyzr   r[   r]   rF   rG   rJ   rK   Nr   r   s          r   test_message_content_includedz4TestFormatConversation.test_message_content_included  sv    ,@AB%d+#-#v----#v---#------v---v-------r    N)ru   rv   rw   rx   r   r   r  ry   r    r   r   r     s    '
 .r    r   )"rx   
__future__r   builtinsr2   _pytest.assertion.rewrite	assertionrewriter0   syspathlibr   pytestpathinsertr   __file__parentutils.session_searchr   r   r   r   r	   utils.session_storer
   fixturer   r   r"   r{   r   r   r   ry   r    r   <module>r     s    I "   
   3tH~,,33::; <  -    &>* >*L68 68|&' &'\" "D. .r    