
    (<i*                       d Z ddlmZ ddlZddlZddlmZ ddlmZ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 ddZ G d d	      Z G d
 d      Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Zy)u@   utils/event_hooks.py 테스트 스위트 (TDD — RED → GREEN)    )annotationsN)Path)	MagicMockpatch)EventHookRegistryemitget_registryc                     t               S )u+   싱글턴 우회용 독립 레지스트리.)r        M/home/jay/workspace/.worktrees/task-2057-dev2/utils/tests/test_event_hooks.py_fresh_registryr      s
    >r   c                  .    e Zd ZdZd Zd Zd Zd Zd Zy)TestHandlerRegistrationu   핸들러 등록 기본 동작c                    t               }g fd}|j                  t        j                  |       t	        j
                  |j                  t        j                  ddi             ddigk(  sJ y)u=   동기 핸들러를 이벤트 타입에 등록할 수 있다.c                (    j                  |        y Nappendctxcalleds    r   handlerzCTestHandlerRegistration.test_register_sync_handler.<locals>.handler(   s    MM#r   x   Nr   registerr   DISPATCH_STARTasynciorunr	   selfregr   r   s      @r   test_register_sync_handlerz2TestHandlerRegistration.test_register_sync_handler#   s`    	 	U))73CHHU11C8<=3(###r   c                    t               }g fd}|j                  t        j                  |       t	        j
                  |j                  t        j                  d             dgk(  sJ y)u@   비동기 핸들러를 이벤트 타입에 등록할 수 있다.c                0   K   j                  |        y wr   r   r   s    r   r   zDTestHandlerRegistration.test_register_async_handler.<locals>.handler4   s     MM#   helloN)r   r   r   SESSION_STARTr    r!   r	   r"   s      @r   test_register_async_handlerz3TestHandlerRegistration.test_register_async_handler/   sX    	 	U(('2CHHU00':;'"""r   c                    t               }d }|j                  t        j                  |d       |j                  j                  t        j                  g       D cg c]  }|d   	 }}d|v sJ yc c}w )u@   name 파라미터로 핸들러에 이름 부여가 가능하다.c                     y r   r   r   s    r   r   zDTestHandlerRegistration.test_register_named_handler.<locals>.handler?   s    r   
my_handler)namer0   N)r   r   r   
AGENT_STEP	_handlersget)r#   r$   r   infonamess        r   test_register_named_handlerz3TestHandlerRegistration.test_register_named_handler;   sk    	 	U%%w\B*---*;*;E<L<Lb*QR$fRRu$$$ Ss   A1c                $   t               }g |j                  t        j                  fd       |j                  t        j                  fd       t	        j
                  |j                  t        j                  d             dv rdv sJ y)u=   같은 이벤트에 여러 핸들러를 등록할 수 있다.c                &    j                  d      S )NAr   r   resultss    r   <lambda>zOTestHandlerRegistration.test_multiple_handlers_for_same_event.<locals>.<lambda>K       W^^C5H r   c                &    j                  d      S )NBr   r:   s    r   r<   zOTestHandlerRegistration.test_multiple_handlers_for_same_event.<locals>.<lambda>L   r=   r   Nr9   r?   )r   r   r   DISPATCH_ENDr    r!   r	   r#   r$   r;   s     @r   %test_multiple_handlers_for_same_eventz=TestHandlerRegistration.test_multiple_handlers_for_same_eventF   sl    U'')HIU'')HICHHU//67g~#.00.r   c                b    t               }t        j                  |j                  di              y)uM   핸들러가 없는 이벤트에 emit해도 예외가 발생하지 않는다.znonexistent:eventN)r   r    r!   r	   r#   r$   s     r   test_no_handlers_emit_is_noopz5TestHandlerRegistration.test_no_handlers_emit_is_noopP   s"    CHH0"56r   N)	__name__
__module____qualname____doc__r%   r+   r6   rB   rE   r   r   r   r   r       s    (
$
#	%17r   r   c                  (    e Zd ZdZd Zd Zd Zd Zy)TestWildcardMatchingu+   dispatch:* 스타일 와일드카드 매칭c                    t               }g |j                  dfd       t        j                  |j	                  t
        j                  d             dv sJ y)u8   dispatch:* 핸들러가 dispatch:start 에 호출된다.
dispatch:*c                &    j                  |       S r   r   r   callss    r   r<   zLTestWildcardMatching.test_wildcard_matches_prefixed_events.<locals>.<lambda>c       u||C/@ r   sNr   r   r    r!   r	   r   r   r#   r$   rP   s     @r   %test_wildcard_matches_prefixed_eventsz:TestWildcardMatching.test_wildcard_matches_prefixed_events^   sH    \#@ACHHU11378e||r   c                &   t               }g |j                  dfd       t        j                  |j	                  t
        j                  d             t        j                  |j	                  t
        j                  d             ddgk(  sJ y)u9   dispatch:* 핸들러가 dispatch:end 에도 호출된다.rM   c                &    j                  |       S r   r   rO   s    r   r<   zLTestWildcardMatching.test_wildcard_matches_multiple_events.<locals>.<lambda>l   rQ   r   r      N)r   r   r    r!   r	   r   r   r@   rT   s     @r   %test_wildcard_matches_multiple_eventsz:TestWildcardMatching.test_wildcard_matches_multiple_eventsg   si    \#@ACHHU11156CHHU//34Ar   c                    t               }g |j                  dfd       t        j                  |j	                  t
        j                  d             g k(  sJ y)uA   session:* 핸들러가 dispatch:start 에 호출되지 않는다.z	session:*c                &    j                  |       S r   r   rO   s    r   r<   zTTestWildcardMatching.test_wildcard_does_not_match_different_prefix.<locals>.<lambda>v   s    ell3.? r   r   NrS   rT   s     @r   -test_wildcard_does_not_match_different_prefixzBTestWildcardMatching.test_wildcard_does_not_match_different_prefixq   sH    ["?@CHHU11378{{r   c                   t               }g |j                  t        j                  fd       |j                  dfd       t	        j
                  |j                  t        j                  d             dv rdv sJ y)uR   정확한 이벤트 핸들러와 와일드카드 핸들러가 함께 호출된다.c                &    j                  d      S )Nexactr   rO   s    r   r<   zHTestWildcardMatching.test_exact_and_wildcard_both_fire.<locals>.<lambda>   s    u||G7L r   rM   c                &    j                  d      S )Nwildr   rO   s    r   r<   zHTestWildcardMatching.test_exact_and_wildcard_both_fire.<locals>.<lambda>   s    u||F/C r   Nr_   ra   r   rT   s     @r   !test_exact_and_wildcard_both_firez6TestWildcardMatching.test_exact_and_wildcard_both_firez   sg    U))+LM\#CDCHHU11489%FeO33Or   N)rF   rG   rH   rI   rU   rY   r\   rb   r   r   r   rK   rK   [   s    54r   rK   c                  "    e Zd ZdZd Zd Zd Zy)TestErrorIsolationuA   핸들러 예외가 메인 파이프라인을 블록하지 않음c                $   t               }g d }fd}|j                  t        j                  |       |j                  t        j                  |       t	        j
                  |j                  t        j                  i              dgk(  sJ y)uI   동기 핸들러 예외가 catch 되어 다음 핸들러가 실행된다.c                    t        d      )Nboom)RuntimeErrorr.   s    r   bad_handlerzMTestErrorIsolation.test_sync_handler_exception_is_caught.<locals>.bad_handler   s    v&&r   c                (    j                  d       y NTr   r   second_calleds    r   good_handlerzNTestErrorIsolation.test_sync_handler_exception_is_caught.<locals>.good_handler         &r   TN)r   r   r   DISPATCH_ERRORr    r!   r	   r#   r$   ri   rn   rm   s       @r   %test_sync_handler_exception_is_caughtz8TestErrorIsolation.test_sync_handler_exception_is_caught   sq    	'	' 	U));7U))<8CHHU11267&&&r   c                $   t               }g d }fd}|j                  t        j                  |       |j                  t        j                  |       t	        j
                  |j                  t        j                  i              dgk(  sJ y)uL   비동기 핸들러 예외도 catch 되어 다음 핸들러가 실행된다.c                    K   t        d      w)Nz
async boom)
ValueErrorr.   s    r   ri   zNTestErrorIsolation.test_async_handler_exception_is_caught.<locals>.bad_handler   s     \**s   c                (    j                  d       y rk   r   rl   s    r   rn   zOTestErrorIsolation.test_async_handler_exception_is_caught.<locals>.good_handler   ro   r   TN)r   r   r   SESSION_ENDr    r!   r	   rq   s       @r   &test_async_handler_exception_is_caughtz9TestErrorIsolation.test_async_handler_exception_is_caught   sq    	+	' 	U&&4U&&5CHHU..34&&&r   c                    t               }d }|j                  t        j                  |       t	        j
                  |j                  t        j                  i              y)u<   emit()을 호출한 쪽에 예외가 전파되지 않는다.c                    t        d      )Nzshould not propagate)	Exceptionr.   s    r   	explodingzQTestErrorIsolation.test_exception_does_not_propagate_to_caller.<locals>.exploding   s    233r   N)r   r   r   SECURITY_BLOCKr    r!   r	   )r#   r$   r|   s      r   +test_exception_does_not_propagate_to_callerz>TestErrorIsolation.test_exception_does_not_propagate_to_caller   sB    	4 	U))95CHHU11267r   N)rF   rG   rH   rI   rr   rx   r~   r   r   r   rd   rd      s    K' ' 	8r   rd   c                      e Zd ZdZd Zd Zy)TestEmitSyncu    동기 컨텍스트용 emit_syncc                    t               }g |j                  t        j                  fd       |j	                  t        j                  d       dgk(  sJ y)u)   emit_sync()가 핸들러를 호출한다.c                &    j                  |       S r   r   r:   s    r   r<   z;TestEmitSync.test_emit_sync_calls_handler.<locals>.<lambda>   s    gnnS6I r   pkgNr   r   r   SKILL_INSTALL	emit_syncrA   s     @r   test_emit_sync_calls_handlerz)TestEmitSync.test_emit_sync_calls_handler   sI    U((*IJe))515'!!!r   c                    t               }g fd}|j                  t        j                  |       |j	                  t        j                  d       dgk(  sJ y)u3   emit_sync()가 비동기 핸들러도 실행한다.c                0   K   j                  |        y wr   r   r:   s    r   ahandlerz@TestEmitSync.test_emit_sync_runs_async_handler.<locals>.ahandler   s     NN3r(   	async_pkgNr   )r#   r$   r   r;   s      @r   !test_emit_sync_runs_async_handlerz.TestEmitSync.test_emit_sync_runs_async_handler   sO    	  	U(((3e));7;-'''r   N)rF   rG   rH   rI   r   r   r   r   r   r   r      s    *"
(r   r   c                      e Zd ZdZd Zd Zy)TestSingletonu%   get_registry()가 싱글턴을 반환c                8    t               }t               }||u sJ y)uE   get_registry()를 두 번 호출하면 같은 객체를 반환한다.N)r
   )r#   r1r2s      r   'test_get_registry_returns_same_instancez5TestSingleton.test_get_registry_returns_same_instance   s    ^^Rxxr   c                    t               }g d}|j                  |fd       t        j                  t	        |d             dv sJ y)uR   전역 emit()이 싱글턴 레지스트리에 등록된 핸들러를 호출한다.ztest:singleton_emit_checkc                &    j                  |       S r   r   r:   s    r   r<   z?TestSingleton.test_global_emit_uses_singleton.<locals>.<lambda>   s    w~~c/B r   pingN)r
   r   r    r!   r	   )r#   r$   unique_eventr;   s      @r   test_global_emit_uses_singletonz-TestSingleton.test_global_emit_uses_singleton   sD    n2\#BCDv./   r   N)rF   rG   rH   rI   r   r   r   r   r   r   r      s    /!r   r   c                  (    e Zd ZdZd Zd Zd Zd Zy)TestDiscoverAndLoadu8   HOOK.yaml + handler.py 디렉토리 기반 동적 로드c                |   |dz  }|j                          |dz  j                  dd       |dz  j                  dd       t               }|j                  t	        |             |j
                  j                  t        j                  g       |j
                  j                  dg       z   }t        |      d	k\  sJ y
)uC   HOOK.yaml과 handler.py가 있는 훅이 자동으로 등록된다.myhook	HOOK.yamlz&event: dispatch:start
name: test_hook
utf-8encoding
handler.pyzdef handle(ctx):
    pass
zdispatch:startr   N)
mkdir
write_textr   discover_and_loadstrr2   r3   r   r   len)r#   tmp_pathhook_dirr$   handlerss        r   .test_discover_registers_handler_from_directoryzBTestDiscoverAndLoad.test_discover_registers_handler_from_directory   s    h&	K	++,Vah+i	L	 ,,* 	- 	

 c(m,==$$U%9%92>ARARScegAhh8}!!!r   c                    |dz  }|j                          |dz  j                  dd       t               }|j                  t	        |             y)u1   HOOK.yaml이 없는 디렉토리는 무시된다.badhookr   zdef handle(ctx): pass
r   r   Nr   r   r   r   r   r#   r   r   r$   s       r    test_discover_skips_missing_yamlz4TestDiscoverAndLoad.test_discover_skips_missing_yaml	  sM    i'	L	 ,,-FQX,Yc(m,r   c                    |dz  }|j                          |dz  j                  dd       t               }|j                  t	        |             y)u2   handler.py가 없는 디렉토리는 무시된다.nohookr   z!event: dispatch:start
name: test
r   r   Nr   r   s       r   #test_discover_skips_missing_handlerz7TestDiscoverAndLoad.test_discover_skips_missing_handler  sM    h&	K	++,Q\c+dc(m,r   c                :    t               }|j                  d       y)uM   존재하지 않는 디렉토리에 discover_and_load해도 예외가 없다.z!/tmp/nonexistent_hooks_dir_xyz123N)r   r   rD   s     r   %test_discover_nonexistent_dir_is_noopz9TestDiscoverAndLoad.test_discover_nonexistent_dir_is_noop  s    ABr   N)rF   rG   rH   rI   r   r   r   r   r   r   r   r   r      s    B""	r   r   c                      e Zd ZdZd Zy)TestEventConstantsu$   Event 클래스 상수 존재 확인c                H   t         j                  sJ t         j                  sJ t         j                  sJ t         j                  sJ t         j
                  sJ t         j                  sJ t         j                  sJ t         j                  sJ t         j                  sJ y)u+   모든 Event 상수가 정의되어 있다.N)
r   r   r@   rp   r*   rw   r1   r}   SECURITY_WARNr   )r#   s    r   test_event_constants_definedz/TestEventConstants.test_event_constants_defined-  s    ####!!!!####""""    ####""""""""r   N)rF   rG   rH   rI   r   r   r   r   r   r   *  s
    .
#r   r   )returnr   )rI   
__future__r   r    syspathlibr   unittest.mockr   r   pytestpathinsertr   __file__parentutils.event_hooksr   r   r	   r
   r   r   rK   rd   r   r   r   r   r   r   r   <module>r      s    F "  
  *  3tH~,,33::; < E E37 37v'4 '4^,8 ,8h( (<! !2- -j# #r   