
    (<i6                        d Z ddlZddlZddl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ej                  j                  dd            Z ee      ej                   vr"ej                   j#                  d ee             dedej$                  fd	Z ej(                         dedej$                  fd
       Z ej(                         dedefd       ZddgZde	fdZ G d d      Z G d d      Z G d d      Z G d d      Zy)ud  
test_dispatch_resume.py

dispatch.py --resume-from 옵션 단위 테스트 (스바로그 작성)

테스트 항목:
- resume_from=None이면 task_desc 변경 없음
- resume_from이 존재하는 파일 → task_desc 앞에 요약 prepend
- resume_from이 존재하지 않는 파일 → error 반환
- CLI argparse가 --resume-from 옵션을 정상 파싱
    N)Path)	MagicMockpatchWORKSPACE_ROOTz/home/jay/workspacetmp_pathreturnc                 >   t         }t        |      t        j                  vr)t        j                  j	                  dt        |             ddl}t        t        j                  j                               D ]  }|dk(  s	t        j                  |=  ddl	}| |_
        |S )uF   dispatch 모듈을 tmp_path를 WORKSPACE로 설정하여 로드한다.r   Ndispatch)
_WORKSPACEstrsyspathinsertprompts.team_promptslistmoduleskeysr
   	WORKSPACE)r   	workspacepromptsmod_name	_dispatchs        K/home/jay/workspace/.worktrees/task-2057-dev2/tests/test_dispatch_resume.py_load_dispatch_with_workspacer   !   sx    I
9~SXX%3y>*))+, &z!H%& !"I    c                 v    | dz  j                  dd       | dz  dz  j                  dd       t        |       S )u:   격리된 WORKSPACE를 사용하는 dispatch 모듈 반환memoryT)parentsexist_oktasks)mkdirr   )r   s    r   dispatch_modr"   8   sD     t<7"))$)F(22r   c                 6    | dz  }|j                  dd       |S )u   임시 요약 파일 생성zsession_summary.mduU   이전 세션에서 A 모듈 구현 완료.
남은 작업: B 모듈 테스트 작성.utf-8encoding)
write_text)r   summarys     r   summary_filer)   @   s0     --Go  {B  CNr   zdispatch.subprocess.runzdispatch.generate_task_idc                      t               } d| j                  _        t        j                  ddi      | j                  _        d| j                  _        | S )u1   성공 응답을 반환하는 subprocess.run mockr   
session_idztest-session )r   return_value
returncodejsondumpsstdoutstderr)mocks    r   _make_mock_subprocessr4   R   sF    ;D#$D #zz<*HID!DKr   c                   8    e Zd ZdZdej
                  deddfdZy)TestResumeFromNoneu?   resume_from이 None이면 기존 동작과 동일해야 한다.r"   r   r   Nc                    d}g 	 ddt         dt         dt         dt         dt        dt         ffd}t               }t        j                  |d	|
      5  t        j                  |d      5 }t        j                  |dd      5  t        d      5  d|j                  j
                  _        t        j                  ddi      |j                  j
                  _	        d|j                  j
                  _
        |j                  d|d        d d d        d d d        d d d        d d d        t              dk(  sJ d   |k(  sJ y # 1 sw Y   <xY w# 1 sw Y   @xY w# 1 sw Y   DxY w# 1 sw Y   HxY w)Nu   원래 작업 설명입니다.team_id	task_desctask_idlevelkwargsr   c                 (    j                  |       yNzfake-promptappendr8   r9   r:   r;   r<   captured_task_descs        r   _fake_build_promptz`TestResumeFromNone.test_task_desc_unchanged_when_resume_from_is_none.<locals>._fake_build_promptg        %%i0 r   build_promptside_effect
subprocessgenerate_task_idtask-1.1r-   !utils.bot_activity.set_bot_statusr   r+   testr,   	dev6-teamr8   r9   resume_from   normal)r   objectr4   r   runr-   r.   r/   r0   r1   r2   r
   len)selfr"   r   original_task_descrC   mock_subprocessmock_sprB   s          @r   1test_task_desc_unchanged_when_resume_from_is_nonezDTestResumeFromNone.test_task_desc_unchanged_when_resume_from_is_nonec   s{   =(* "		!	!	! 	! 		!
 	! 	! 01 LL~CUV	LL|4	8?LL'9
S	 56		 34GKK$$/.2jj,9O.PGKK$$+.0GKK$$+!!#,  " 	 	 	 	  %&!+++!!$(::::#	 	 	 	 	 	 	 	sU   E*+EEA;E	EEE*EEEEE'	#E**E3)__name__
__module____qualname____doc__types
ModuleTyper   r[    r   r   r6   r6   `   s'    I!;eN^N^ !;jn !;sw !;r   r6   c                   `    e Zd ZdZdej
                  deddfdZdej
                  deddfdZy)TestResumeFromExistingFileuR   resume_from이 존재하는 파일이면 task_desc 앞에 요약을 prepend한다.r"   r)   r   Nc                 ^   d}|j                  d      }d| d}g 	 ddt        dt        dt        d	t        d
t        dt        ffd}t        j                  |d|      5  t        j                  |d      5 }t        j                  |dd      5  t        d      5  d|j                  j
                  _        t        j                  ddi      |j                  j
                  _	        d|j                  j
                  _
        |j                  d|t        |             d d d        d d d        d d d        d d d        t              dk(  sJ d   j                  |      sJ d   j                  |      sJ y # 1 sw Y   ^xY w# 1 sw Y   bxY w# 1 sw Y   fxY w# 1 sw Y   jxY w)Nu&   새 작업: B 모듈 테스트 작성.r$   r%   L   ## 이전 세션 요약
아래 요약을 읽고 이어서 작업하세요.



---

r8   r9   r:   r;   r<   r   c                 (    j                  |       yr>   r?   rA   s        r   rC   zZTestResumeFromExistingFile.test_summary_prepended_to_task_desc.<locals>._fake_build_prompt   rD   r   rE   rF   rH   rI   rJ   rK   rL   r   r+   rM   r,   rN   rO   rQ   rR   )	read_textr   rT   r   rU   r-   r.   r/   r0   r1   r2   r
   rV   
startswithendswith)	rW   r"   r)   rX   summary_contentexpected_prefixrC   rZ   rB   s	           @r   #test_summary_prepended_to_task_descz>TestResumeFromExistingFile.test_summary_prepended_to_task_desc   s   
 F&00'0Bafuev  wF  G 	 )+ "		!	!	! 	! 		!
 	! 	! LL~CUV	LL|4	8?LL'9
S	 56		 34GKK$$/.2jj,9O.PGKK$$+.0GKK$$+!!#,- " 	 	 	 	  %&!+++!!$//@@@!!$--.@AAA%	 	 	 	 	 	 	 	sU   "F#9FFBE?	"F*F2F#?FFFFF 	F##F,c                    d}|j                  d      }d| d| }g 	 ddt        dt        dt        d	t        d
t        dt        ffd}t        j                  |d|      5  t        j                  |d      5 }t        j                  |dd      5  t        d      5  d|j                  j
                  _        t        j                  ddi      |j                  j
                  _	        d|j                  j
                  _
        |j                  d|t        |             ddd       ddd       ddd       ddd       t              dk(  sJ d   |k(  sJ y# 1 sw Y   <xY w# 1 sw Y   @xY w# 1 sw Y   DxY w# 1 sw Y   HxY w)u,   prepend된 task_desc의 전체 형식 검증u   새 작업: C 모듈 구현.r$   r%   rf   rg   r8   r9   r:   r;   r<   r   c                 (    j                  |       yr>   r?   rA   s        r   rC   zZTestResumeFromExistingFile.test_full_injected_task_desc_format.<locals>._fake_build_prompt   rD   r   rE   rF   rH   rI   rJ   rK   rL   r   r+   rM   r,   rN   rO   NrQ   rR   )ri   r   rT   r   rU   r-   r.   r/   r0   r1   r2   r
   rV   )	rW   r"   r)   rX   rl   expected_task_descrC   rZ   rB   s	           @r   #test_full_injected_task_desc_formatz>TestResumeFromExistingFile.test_full_injected_task_desc_format   s    <&00'0BE  !"	$ 	 )+ "		!	!	! 	! 		!
 	! 	! LL~CUV	LL|4	8?LL'9
S	 56		 34GKK$$/.2jj,9O.PGKK$$+.0GKK$$+!!#,- " 	 	 	 	  %&!+++!!$(::::#	 	 	 	 	 	 	 	sU   $F;E7E+ BE	$E+,E74FE($E++E40E77F 	<FF)	r\   r]   r^   r_   r`   ra   r   rn   rr   rb   r   r   rd   rd      sX    \)B&&)B )B 
	)BV-;&&-; -; 
	-;r   rd   c                   `    e Zd ZdZdej
                  deddfdZdej
                  deddfdZy)TestResumeFromNonExistentFileuF   resume_from이 존재하지 않는 파일이면 error를 반환한다.r"   r   r   Nc                 ~    t        |dz        }|j                  dd|      }|d   dk(  sJ d|d   v s
||d   v sJ y y )	Nzno_such_file.mdrN      작업 설명rO   statuserrorrP   messager   r
   rW   r"   r   non_existent_pathresults        r   &test_returns_error_when_file_not_foundzDTestResumeFromNonExistentFile.test_returns_error_when_file_not_found   sm    +< <=&&%) ' 
 h7***y 115F&QZJ[5[[[5[1r   c                 n    t        |dz        }|j                  dd|      }|d   dk(  sJ ||d   v sJ y )Nzmissing_summary.mdrN   rv   rO   rw   rx   ry   rz   r{   s        r    test_error_message_contains_pathz>TestResumeFromNonExistentFile.test_error_message_contains_path   sY    +? ?@&&%) ' 
 h7*** F9$5555r   )	r\   r]   r^   r_   r`   ra   r   r~   r   rb   r   r   rt   rt      sM    P
\5CSCS 
\_c 
\hl 
\
6U=M=M 
6Y] 
6bf 
6r   rt   c                   x    e Zd ZdZdej
                  fdZdeddfdZddZ	deddfdZ
deddfd	Zdeddfd
Zy)TestCliResumeParsinguH   argparse가 --resume-from 옵션을 정상 파싱하는지 확인한다.r   c                    t        j                  d      }|j                  d      }|j                  dd       |j                  dd       |j                  d      }|j                  d	d       |j                  d
d       |j                  dd       |j                  dd       |j                  dd       |j                  dd       |j                  dd       |j                  dt         j                  d       |j                  dd       |j                  dt
        d       |j                  ddd       |j                  ddd       |S )uM   dispatch.main()에서 사용하는 argparse parser를 재생성하여 반환.u   작업 위임 디스패처)descriptionF)required--teamN)defaultz--composite--task--task-filez--levelrS   z--typecodingz	--sessionz	--projectz--chainz--refresh-mapT)actionr   z	--task-idz--phases)typer   z--force
store_true--resume-fromrP   )r   dest)argparseArgumentParseradd_mutually_exclusive_groupadd_argumentBooleanOptionalActionint)rW   parserteam_or_composite
task_groups       r   _get_parserz TestCliResumeParsing._get_parser  sZ    ((5QR"???O&&x&>&&}d&C88%8H
$7t<Ix8Hh7K6K6It4OH4R4R\`aK6JS$?IlEJOTNr   r   Nc                     t        |dz        }| j                         }|j                  ddddd|g      }|j                  |k(  sJ y)uC   --resume-from 값이 args.resume_from에 올바르게 저장된다.
summary.mdr   rN   r   	   테스트r   N)r   r   
parse_argsrP   rW   r   summary_pathr   argss        r   !test_resume_from_parsed_correctlyz6TestCliResumeParsing.test_resume_from_parsed_correctly+  sR    8l23!!#  (K;P_am!no<///r   c                 f    | j                         }|j                  g d      }|j                  J y)u4   --resume-from 미지정 시 기본값은 None이다.)r   rN   r   r   N)r   r   rP   )rW   r   r   s      r    test_resume_from_default_is_nonez5TestCliResumeParsing.test_resume_from_default_is_none2  s3    !!#  !OP'''r   c                     t        |dz        }| j                         }|j                  ddddd|g      }|j                  dk(  sJ |j                  |k(  sJ y)u6   --resume-from은 --task와 함께 사용 가능하다.r   r   rN   r   u   작업 내용r   N)r   r   r   taskrP   r   s        r   &test_resume_from_can_be_used_with_taskz;TestCliResumeParsing.test_resume_from_can_be_used_with_task8  sd    8l23!!#  (K?Tceq!rsyyO+++<///r   c                     t        |dz        }t        |dz        }| j                         }|j                  ddd|d|g      }|j                  |k(  sJ |j                  |k(  sJ y)u;   --resume-from은 --task-file과 함께 사용 가능하다.r   ztask.mdr   rN   r   r   N)r   r   r   	task_filerP   )rW   r   r   task_file_pathr   r   s         r   +test_resume_from_can_be_used_with_task_filez@TestCliResumeParsing.test_resume_from_can_be_used_with_task_file@  ss    8l23X	12!!#  (KXgiu!vw~~///<///r   c                 (   t         }t        |      t        j                  vr)t        j                  j	                  dt        |             t        t        j                  j                               D ]  }|dk(  s	t        j                  |=  ddl}t        |dz        }t        j                  }	 ddddd	d
|gt        _	        ddl
}|j                  |j                        }d|j                  v sJ d       	 |t        _	        y# |t        _	        w xY w)uK   실제 dispatch.main()의 argparse에 --resume-from 옵션이 존재한다.r   r
   Nr   zdispatch.pyr   rN   r   r   r   rP   u>   dispatch() 함수에 resume_from 파라미터가 없습니다.)r   r   r   r   r   r   r   r   r
   argvinspect	signature
parameters)	rW   r   r   r   r   r   original_argvr   sigs	            r   )test_dispatch_main_has_resume_from_optionz>TestCliResumeParsing.test_dispatch_main_has_resume_from_optionI  s    	y>)HHOOAs9~.S[[--/0 	*H:%KK)	* 	%8l23 	%CH ##I$6$67C CNN2t4tt2$CH}CHs   1AD D)r   N)r\   r]   r^   r_   r   r   r   r   r   r   r   r   r   rb   r   r   r   r     sh    RX44 00$ 04 0(0t 0 00D 0T 0#%$ #%4 #%r   r   )r_   r   r/   osr   r`   pathlibr   unittest.mockr   r   pytestenvirongetr   r   r   r   ra   r   fixturer"   r)   _MOCK_PATCHESr4   r6   rd   rt   r   rb   r   r   <module>r      s$  
   	 
   * "**..!13HIJ
z?#(("HHOOAs:'D U5E5E . 34 3E$4$4 3 3 4 D   y $; $;X[; [;F6 6B\% \%r   