
    @ j$,              	       :   d Z ddlZddlZddlZddlmZ  ed      Z ed      Z ee      ej                  vr"ej                  j                  d ee             deddfdZdded	ed
edefdZdedefdZddZddZddZddZddZdeddfdZdeddfdZy)u  
test_task_scope.py — task_scope.py 회귀 테스트 (Guard MVP Phase 1, task-2434)

시나리오 (7개):
    1. test_extension_only             — extension/foo.js → scopes=["extension"]
    2. test_server_only                — server/api.py → scopes=["server"]
    3. test_extension_and_skills       — extension/x + skills/y → scopes=["extension","skills"]
    4. test_docs_only                  — README.md → scopes=["docs"], test_paths=[]
    5. test_unscoped                   — 미분류 path → scopes=["unscoped"], test_paths=[]
    6. test_diff_sets_separation       — head_diff/index_staged/working_tree/untracked 4집합 분리
    7. test_output_files_written       — --output-dir 시 JSON 2개 파일 생성
    N)Pathz/home/jay/workspace/scriptsz/home/jay/workspacepathreturnc                      dt         ddf fd} |d        |ddd        |dd	d
        dz  }|j                  d        |dd        |ddd       y)u3   tmp_path 하위에 최소 git repo를 생성한다.argsr   Nc                  f    t        j                  ddt              gt        |       z   dd       y )Ngit-CTcheckcapture_output)
subprocessrunstrlist)r   r   s    N/home/jay/workspace/.worktrees/task-2542-dev1/tests/scripts/test_task_scope.py_gitzinit_git_repo.<locals>._git#   s,    D#d)$tDz1	
    initconfigz
user.emailztest@test.comz	user.nameTest	README.mdzinit
add.commit-m)r   
write_text)r   r   readmes   `  r   init_git_repor   !   sg    
C 
D 
 	L<1;( KF
h4 r   file_relcontentc           	         | |z  }|j                   j                  dd       |j                  |       t        j                  ddt        |       d|gdd       t        j                  ddt        |       ddd	| gdd       t        j                  ddt        |       d
dgddd      }|j                  j                         S )u+   파일 추가 + 커밋 후 HEAD SHA 반환.Tparentsexist_okr	   r
   r   r   r   r   zadd z	rev-parseHEADr   r   text)parentmkdirr   r   r   r   stdoutstrip)r   r    r!   targetresults        r   make_commitr/   5   s    H_F
MMt4
gNNE4TE8<d4NNE4THdd8*<MNd4^^	c$if54dF ==  r   c                     t        j                  ddt        |       dddgddd      }|j                  j	                         S )u+   초기 커밋 SHA(첫번째 커밋) 반환.r	   r
   zrev-listz--max-parents=0r&   Tr'   )r   r   r   r+   r,   )r   r.   s     r   get_base_shar1   E   sA    ^^	c$i->G4dF ==  r   c                  z    ddl m} m} dg} | |      } ||      }|dgk(  s
J d|        |dgk(  s
J d|        y)	uY   extension/foo.js 만 변경 → scopes=["extension"], test_paths=["extension/__tests__/"]r   classify_scopesscope_test_matrixzextension/foo.js	extensionzexpected ['extension'] but got extension/__tests__/z*expected ['extension/__tests__/'] but got N
task_scoper4   r5   r4   r5   pathsscopes
test_pathss        r   test_extension_onlyr>   R   sg    = EU#F"6*Jk]" 
)&2" 011 
4ZLA1r   c                  v    ddl m} m} dg} | |      } ||      }|dgk(  s
J d|        d|v s
J d|        y)	u.   server/api.py 만 변경 → scopes=["server"]r   r3   zserver/api.pyserverzexpected ['server'] but got zserver/tests/z server/tests/ not in test_paths=Nr8   r:   s        r   test_server_onlyrA   f   sc    =EU#F"6*JhZ 
&vh/ j( 
*:,7(r   c                  z    ddl m}  ddg} | |      }|ddgk(  s
J d|        |t        |      k(  s
J d|        y	)
uO   extension/x + skills/y 동시 변경 → scopes=["extension","skills"] (sorted)r   )r4   zextension/background.jszskills/summarizer.pyr6   skillsz)expected ['extension', 'skills'] but got zscopes must be sorted, got N)r9   r4   sorted)r4   r;   r<   s      r   test_extension_and_skillsrE   z   s_    *&(>?EU#Fk8,, 
3F8<, VF^#K'B6(%KK#r   c                  x    ddl m} m} dg} | |      } ||      }|dgk(  s
J d|        |g k(  s
J d|        y)uD   README.md 만 변경 → scopes=["docs"], test_paths=[] (smoke only)r   r3   r   docszexpected ['docs'] but got z3docs scope should have no dedicated test path, got Nr8   r:   s        r   test_docs_onlyrH      s\    =MEU#F"6*JfXD!;F8DD 
=j\Jr   c                  z    ddl m} m} ddg} | |      } ||      }|dgk(  s
J d|        |g k(  s
J d|        y)	u=   매칭 안 되는 path → scopes=["unscoped"], test_paths=[]r   r3   zsome/random/file.txtzanother.xyzunscopedzexpected ['unscoped'] but got z1unscoped should have no dedicated test path, got Nr8   r:   s        r   test_unscopedrK      s_    =#]3EU#F"6*Jj\!L%CF8#LL! 
;J<Hr   tmp_pathc                    ddl m} | dz  }|j                          t        |       t	        |      }t        |d       |dz  dz  }|j                  j                  dd       |j                  d	       t        j                  d
dt        |      ddgdd       |dz  }|j                  d       |dz  }|j                  d        ||t        |            \  }}|
J d|        d|d   v sJ d|d           d|d   vsJ d|d           d|d   v sJ d|d           d|d   v sJ d|d           d|d   v sJ d|d           dD ]  }	|	|v rJ d|	 d         y)!uP  head_diff / index_staged / working_tree_modified / untracked 4집합이 명시 분리됨.

    - base_sha = 초기 커밋
    - 이후 커밋 1개 → head_diff에만 포함
    - staged 파일 → index_staged에만 포함
    - modified (unstaged) 파일 → working_tree_modified에만
    - untracked 파일 → untracked에만
    r   )get_diff_setsrepozserver/committed.pyr6   z	staged.jsTr#   zstaged
r	   r
   r   zextension/staged.jsr   r   zmodified content
zuntracked_new.txtz
untracked
Nzget_diff_sets returned error: 	head_diffz!committed file not in head_diff: z-staged-only file should not be in head_diff: index_stagedz!staged file not in index_staged: working_tree_modifiedz,modified file not in working_tree_modified: 	untrackedz!untracked file not in untracked: )rP   rQ   rR   rS   key 'z' missing from diff_sets)r9   rN   r*   r   r1   r/   r)   r   r   r   r   )
rL   rN   rO   base_shastaged_filemodified_fileuntracked_file	diff_setserrkeys
             r   test_diff_sets_separationr\      s    )fDJJL$D!H +, ${2KTD9:&NNE4TE3HId4 ;&M12 //Nm,"8SY7NIs;>8>>; !Ik$:: 
+Ik,B+CD: !	+(>> 
7	+8N7OP>
 !In$== 
+In,E+FG=
 )$;<< 
6yAX7Y6Z[<
 )K"88 
+Ik,B+CD8
 S GiF5-E!FFGr   c                    | dz  }|j                          t        |       t        |      }t        |d       | dz  }t	        j
                  t        j                  t        t        dz        d|dt        |      dt        |      gddt        t              	      }|j                  d
k(  s.J d|j                   d|j                   d|j                          |dz  }|dz  }|j                         s
J d|        |j                         s
J d|        |j                         5 }t!        j"                  |      }ddd       |j                         5 }t!        j"                  |      }	ddd       dD ]  }
|
v rJ d|
 d        dd   v sJ d|d           d	v sJ d       d|	v sJ d       d|	d   v sJ d|	d           d|	d   v sJ d|	d           y# 1 sw Y   xY w# 1 sw Y   ~xY w) uM   --output-dir 인자 사용 시 changed_paths.json + scope_matrix.json 생성.rO   zextension/popup.jsoutputztask_scope.pyz
--base-shaz--output-dirz--cwdT)r   r(   cwdr   ztask_scope.py exited with rc=z
stdout=z
stderr=zchanged_paths.jsonzscope_matrix.jsonz"changed_paths.json not created in z!scope_matrix.json not created in N)rU   head_sharP   rQ   rR   rS   rT   z!' missing from changed_paths.jsonrP   z%extension/popup.js not in head_diff: r<   z+key 'scopes' missing from scope_matrix.jsonr=   z/key 'test_paths' missing from scope_matrix.jsonr6   zextension not in scopes: r7   z(extension/__tests__/ not in test_paths: )r*   r   r1   r/   r   r   sys
executabler   _SCRIPTS_DIR
_WORKSPACE
returncoder+   stderrexistsopenjsonload)rL   rO   rU   
output_dirr.   changed_paths_filescope_matrix_filefcpsmr[   s              r   test_output_files_writtenrq      sj   fDJJL$D!H *+H$J^^NN./(C
OSY	
 
OF ! 
'(9(9': ;--	&--	:!
 $&::#&99$$& 
,ZL9& ##% 
+J<8% 
	 	 	" aYYq\				! QYYq\6 IbyHE#&GHHyI
  2k?2 
/;/@A2
 r>HHH>2PPP"X,& 
#BxL>2& "R%55 
22l3C2DE5+  s   &GG'G$'G0)zchange
)r   N)__doc__ri   r   ra   pathlibr   rc   rd   r   r   insertr   r/   r1   r>   rA   rE   rH   rK   r\   rq    r   r   <module>rv      s      
 
 12)*
|CHH$HHOOAs<()! ! !(!d !c !C ! ! !t ! !((L$$$AG AG AGP? ? ?r   