
    ei$,              	       T   d Z ddlZddlmc m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    4/home/jay/workspace/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                  :   ddl m} m} dg} | |      } ||      }dg}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d	|       d
z   d|iz  }t        t        j                  |            dx}}dg}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       d
z   d|iz  }t        t        j                  |            dx}}y)uY   extension/foo.js 만 변경 → scopes=["extension"], test_paths=["extension/__tests__/"]r   classify_scopesscope_test_matrixzextension/foo.js	extension==z%(py0)s == %(py3)sscopespy0py3zexpected ['extension'] but got 
>assert %(py5)spy5Nextension/__tests__/
test_pathsz*expected ['extension/__tests__/'] but got 
task_scoper4   r5   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanation	r4   r5   pathsr:   rA   @py_assert2@py_assert1@py_format4@py_format6s	            r   test_extension_onlyrS   R   sh   = EU#F"6*J!] 6]"  6]              #    *&2     11 :11  :1              2    5ZLA    r   c                  6   ddl m} m} dg} | |      } ||      }dg}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d	|       d
z   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  }t        j                  d|       d
z   d|iz  }t        t        j                  |            dx}	}y)u.   server/api.py 만 변경 → scopes=["server"]r   r3   zserver/api.pyserverr7   r9   r:   r;   zexpected ['server'] but got r>   r?   Nzserver/tests/inz%(py1)s in %(py3)srA   py1r=   z server/tests/ not in test_paths=rB   )
r4   r5   rN   r:   rA   rO   rP   rQ   rR   @py_assert0s
             r   test_server_onlyr\   f   sc   =EU#F"6*JZ 6Z  6Z                   'vh/      ?j(  ?j          )    )    +:,7    r   c                  P   ddl m}  ddg} | |      }ddg}||k(  }|st        j                  d|fd||f      d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      d
z  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}}t        |      }||k(  }|s<t        j                  d|fd||f      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d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}}y)uO   extension/x + skills/y 동시 변경 → scopes=["extension","skills"] (sorted)r   )r4   zextension/background.jszskills/summarizer.pyr6   skillsr7   r9   r:   r;   z)expected ['extension', 'skills'] but got r>   r?   N)z0%(py0)s == %(py5)s
{%(py5)s = %(py2)s(%(py3)s)
}sorted)r<   py2r=   r?   zscopes must be sorted, got 
>assert %(py7)spy7)rC   r4   rD   rE   rF   rG   rH   rI   rJ   rK   rL   r_   )	r4   rN   r:   rO   rP   rQ   rR   @py_assert4@py_format8s	            r   test_extension_and_skillsre   z   sm   *&(>?EU#F!8, 6,,  6,              -    4F8<     F^K6^#KKK6^KKKKKK6KKK6KKKKKKVKKKVKKKKKKFKKKFKKK^KKK'B6(%KKKKKKKr   c                  8   ddl m} m} dg} | |      } ||      }dg}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d	|       d
z   d|iz  }t        t        j                  |            dx}}g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       d
z   d|iz  }t        t        j                  |            dx}}y)uD   README.md 만 변경 → scopes=["docs"], test_paths=[] (smoke only)r   r3   r   docsr7   r9   r:   r;   zexpected ['docs'] but got r>   r?   NrA   z3docs scope should have no dedicated test path, got rB   rM   s	            r   test_docs_onlyrh      s*   =MEU#F"6*JXD6XDDD6XDDDDDD6DDD6DDDXDDD!;F8DDDDDDD :  :                  >j\J    r   c                  :   ddl m} m} ddg} | |      } ||      }dg}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      d	z  }t        j                  d
|       dz   d|iz  }t        t        j                  |            dx}}g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      d	z  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}}y)u=   매칭 안 되는 path → scopes=["unscoped"], test_paths=[]r   r3   zsome/random/file.txtzanother.xyzunscopedr7   r9   r:   r;   zexpected ['unscoped'] but got r>   r?   NrA   z1unscoped should have no dedicated test path, got rB   rM   s	            r   test_unscopedrk      s-   =#]3EU#F"6*J \L6\!LLL6\LLLLLL6LLL6LLL\LLL%CF8#LLLLL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        |            \  }}d}	||	u }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  |      rt        j                   |      ndt        j                   |	      dz  }t        j"                  d|       dz   d|iz  }t%        t        j&                  |            dx}
}	d}|d   }||v }	|	st        j                  d|	fd||f      t        j                   |      t        j                   |      dz  }t        j"                  d|d          d z   d!|iz  }t%        t        j&                  |            dx}x}	}d}|d   }||v}	|	st        j                  d"|	fd#||f      t        j                   |      t        j                   |      dz  }t        j"                  d$|d          d z   d!|iz  }t%        t        j&                  |            dx}x}	}d}|d%   }||v }	|	st        j                  d|	fd||f      t        j                   |      t        j                   |      dz  }t        j"                  d&|d%          d z   d!|iz  }t%        t        j&                  |            dx}x}	}d}|d'   }||v }	|	st        j                  d|	fd||f      t        j                   |      t        j                   |      dz  }t        j"                  d(|d'          d z   d!|iz  }t%        t        j&                  |            dx}x}	}d}|d)   }||v }	|	st        j                  d|	fd||f      t        j                   |      t        j                   |      dz  }t        j"                  d*|d)          d z   d!|iz  }t%        t        j&                  |            dx}x}	}d+D ]  }||v }
|
st        j                  d|
fd,||f      d-t        j                         v st        j                  |      rt        j                   |      nd-d.t        j                         v st        j                  |      rt        j                   |      nd.d/z  }t        j"                  d0| d1      d2z   d3|iz  }t%        t        j&                  |            d}
 y)4uP  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
N)is)z%(py0)s is %(py3)serrr;   zget_diff_sets returned error: r>   r?   	head_diffrV   z%(py1)s in %(py4)srZ   py4z!committed file not in head_diff: 
>assert %(py6)spy6)not in)z%(py1)s not in %(py4)sz-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: )rr   ry   rz   r{   z%(py0)s in %(py2)skey	diff_setsr<   r`   key 'z' missing from diff_sets
>assert %(py4)sru   )rC   rn   r*   r   r1   r/   r)   r   r   r   r   rD   rE   rF   rG   rH   rI   rJ   rK   rL   )rl   rn   ro   base_shastaged_filemodified_fileuntracked_filer~   rq   rO   rP   rQ   rR   r[   @py_assert3@py_format5@py_format7r}   @py_format3s                      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>3$;>>>3$>>>>>>3>>>3>>>$>>>8>>>>>>> ! Ik$:  $::   $:    !    %;    ,Ik,B+CD     ! 	+(>  (>>   (>    !    )?    8	+8N7OP    
 ! In$=  $==   $=    !    %>    ,In,E+FG    
  )$;< ;<<  ;<        =    7yAX7Y6Z[    
  )K"8 "88  "8        #9    ,Ik,B+CD    
 S GiFFFsiFFFFFFsFFFsFFFFFFiFFFiFFFF5-E!FFFFF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(  }|st        j                  d|fd||f      dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      t        j"                  |      dz  }t        j$                  d|j                   d|j&                   d|j(                         dz   d|iz  }	t+        t        j,                  |	            dx}x}}|dz  }
|dz  }|
j.                  } |       }|st        j$                  d|       dz   dt        j                         v st        j                   |
      rt        j"                  |
      ndt        j"                  |      t        j"                  |      dz  }t+        t        j,                  |            dx}}|j.                  } |       }|st        j$                  d|       dz   dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      t        j"                  |      dz  }t+        t        j,                  |            dx}}|
j1                         5 }t3        j4                  |      }ddd       |j1                         5 }t3        j4                  |      }ddd       dD ]  }|v }|st        j                  d|fd||f      d t        j                         v st        j                   |      rt        j"                  |      nd d!t        j                         v st        j                   |      rt        j"                  |      nd!d"z  }t        j$                  d#| d$      d%z   d&|iz  }t+        t        j,                  |            d} d}d'   }||v }|st        j                  d|fd(||f      t        j"                  |      t        j"                  |      d)z  }t        j$                  d*|d'          d+z   d,|iz  }t+        t        j,                  |            dx}x}}d-}|v }|st        j                  d|fd.||f      t        j"                  |      d/t        j                         v st        j                   |      rt        j"                  |      nd/d0z  }t        j$                  d1      d2z   d3|iz  }t+        t        j,                  |            dx}}d4}||v }|st        j                  d|fd.||f      t        j"                  |      d/t        j                         v st        j                   |      rt        j"                  |      nd/d0z  }t        j$                  d5      d2z   d3|iz  }t+        t        j,                  |            dx}}d6}|d-   }||v }|st        j                  d|fd(||f      t        j"                  |      t        j"                  |      d)z  }t        j$                  d7|d-          d+z   d,|iz  }t+        t        j,                  |            dx}x}}d8}|d4   }||v }|st        j                  d|fd(||f      t        j"                  |      t        j"                  |      d)z  }t        j$                  d9|d4          d+z   d,|iz  }t+        t        j,                  |            dx}x}}y# 1 sw Y   oxY w# 1 sw Y   Nx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   r7   )z2%(py2)s
{%(py2)s = %(py0)s.returncode
} == %(py5)sr.   )r<   r`   r?   ztask_scope.py exited with rc=z
stdout=z
stderr=ra   rb   Nzchanged_paths.jsonzscope_matrix.jsonz"changed_paths.json not created in zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}changed_paths_file)r<   r`   ru   z!scope_matrix.json not created in scope_matrix_file)r   head_sharr   ry   rz   r{   rV   r|   r}   cpr   r   z!' missing from changed_paths.jsonr   ru   rr   rs   rt   z%extension/popup.js not in head_diff: rv   rw   r:   rX   smrY   z+key 'scopes' missing from scope_matrix.jsonr>   r?   rA   z/key 'test_paths' missing from scope_matrix.jsonr6   zextension not in scopes: r@   z(extension/__tests__/ not in test_paths: )r*   r   r1   r/   r   r   sys
executabler   _SCRIPTS_DIR
_WORKSPACE
returncoderD   rE   rF   rG   rH   rI   rJ   r+   stderrrK   rL   existsopenjsonload)rl   ro   r   
output_dirr.   rP   rc   r   rR   rd   r   r   r   fr   r   r}   r   r[   rO   r   rQ   s                         r   test_output_files_writtenr      sQ   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HHHsbHHHHHHsHHHsHHHHHHbHHHbHHHHE#&GHHHHHHHI
   2k? ?2  ?         $3    0;/@A    
 H8r>HHH8rHHH8HHHHHHrHHHrHHHHHHHHHHHP<2PPP<2PPP<PPPPPP2PPP2PPPPPPPPPPP "X, ;,&  ;,        '    $BxL>2     " R%5 !%55  !%5    "    &6    32l3C2DE     +  s   8^;&_;__)zchange
)r   N)__doc__builtinsrF   _pytest.assertion.rewrite	assertionrewriterD   r   r   r   pathlibr   r   r   r   r   insertr   r/   r1   rS   r\   re   rh   rk   r   r    r   r   <module>r      s       
 
 12)*
|CHH$HHOOAs<()! ! !(!d !c !C ! ! !t ! !((L$$$AG AG AGP? ? ?r   