
    i&                    .   d Z ddlm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	Z	 ee
      j                         j                  d   Zedz  dz  ZddZdd	Zddd
Zdd	 	 	 	 	 	 	 	 	 ddZe	j&                  dd       Zd Zd Zd Zd Zd Zd Zd Zd Zy)u  tests/mixed_commit/test_detector.py — mixed_commit_detector 시나리오 테스트.

task-2459 Phase 2-C / dev5팀 닌기르수 (테스터).

scripts/mixed_commit_detector.py 의 5단계 알고리즘과 freeze/evidence 부수효과를
임시 git repo + subprocess 호출로 검증.

원칙:
  - 모듈 코드 read-only.
  - subprocess 로만 호출 (import 하지 않음 — CLI 동작 검증).
  - 각 시나리오는 독립 fixture 사용.
    )annotationsN)Path   scriptszmixed_commit_detector.pyc                N    t        j                  dg|t        |       ddd      S )NgitTFcwdcapture_outputtextcheck)
subprocessrunstr)r
   argss     Q/home/jay/workspace/.worktrees/task-2459-dev5/tests/mixed_commit/test_detector.py_gitr       s(    >>	CHTE     c                f   | dz  }|j                          t        dddd|       t        ddd	|       t        dd
d|       t        ddd|       |dz  j                  dd       t        dd|       t        dddd|       t        dd|      }|j                  j	                         }||fS )u   임시 git repo 초기화. 초기 commit 1개 생성하여 base ref 로 사용.

    Returns:
        (repo_path, base_sha): repo 경로와 base commit sha (origin/main 대용).
    repoinit-qz-bmainr
   configz
user.emailztest@example.comz	user.nametesterzcommit.gpgsignfalsez	README.mdzbase
utf-8encodingaddcommit-mzbase: initial	rev-parseHEAD)mkdirr   
write_textstdoutstrip)tmp_pathr   resbase_shas       r   	make_repor-   &   s     fDJJLtV.<!3>;d3#W$7 
K##Hw#?&4D9
{F
-Czz!H>r   c                |   |xs3 dt        |       dt        j                  d      j                          d}| |z  j	                  |dz   d       t        d|| 	       t        d
dd|| 	      }|j                  dk7  rt        d|j                         t        dd| 	      }|j                  j                         S )uF   repo 에 commit 추가. file 내용은 매 commit 다르도록 보장.f__   z.txt
r   r   r!   r   r"   r   r#   r   zcommit failed: r$   r%   )lenosurandomhexr'   r   
returncodeRuntimeErrorstderrr(   r)   )r   message	file_namefnamer+   sha_ress         r   
add_commitr>   <   s    F2c'l^1RZZ]->->-@,AFE	E\gnw?4 
xtW$
7C
~~_SZZL9::;D1G>>!!r   )	workspacec                   |xs |}t         j                  t        t              | dt        |      g|}t	        j
                  |t        |      ddd      S )u?   detector subprocess 실행. workspace 미지정 시 cwd 사용.z--workspaceTFr	   )sys
executabler   DETECTORr   r   )task_idr
   r?   
extra_argscmds        r   run_detectorrG   H   s\      SIHI 
C >>S$T r   c                    t        |       S )u-   초기 commit 1개를 가진 임시 git repo.)r-   )r*   s    r   repo_with_baserI   a   s     Xr   c                   | \  }}t        |d       t        dd||      }|j                  dk(  s!J d|j                   d|j                          |dz  d	z  d
z  }|j                         rJ d       |dz  dz  dz  }|j                         r)t        |j                  d            }|g k(  s
J d|        t        j                  |j                        }|d   dv sJ |d   dk(  sJ y)uX   S1 — clean: 단일 task 토큰만, alien 없음 → exit 0, freeze/evidence 미생성.z[task-2459] feat: A	task-2459--baser   r   zstderr=z
stdout=.taskslockstask-2459.frozenu$   clean 인데 freeze 마커 생성됨evidencemixed-commit-*.jsonu!   clean 인데 evidence 생성됨: status)cleanclean_with_untaggedrD   N)
r>   rG   r7   r9   r(   existslistglobjsonloads)rI   r   r,   r+   frozenev_direvspayloads           r   test_s1_clean_single_taskr^   k   s    #ND(t*+
{HhD
AC>>QK'#**Yszzl KKH_w&);;F}}F FFH_z)K7F}}6;;456byC=cUCCyjj$G8 @@@@9,,,r   c                   | \  }}t        |d       t        |d       t        dd||      }|j                  dk(  s!J d|j                   d|j                          |d	z  d
z  dz  }|j                         sJ d       t        j                  |j                               }d|d   v sJ d|d   v sJ |d   dgk(  sJ |d	z  dz  dz  }t        |j                  d            }t        |      dk\  sJ y)uA   S2 — mixed: 2 task 혼합 → exit 1, freeze + evidence 생성.[task-2459] A[task-9999] BrK   rL   r      stdout=
stderr=rM   rN   rO   u5   mixed 감지 시 freeze 마커가 생성되어야 함mixed_tasks	task-9999alien_tasksrP   rQ   N)r>   rG   r7   r(   r9   rU   rX   rY   	read_textrV   rW   r3   )rI   r   r,   r+   rZ   frozen_datar[   r\   s           r   test_s2_mixed_two_tasksrj      s   #ND(t_%t_%
{HhD
AC>>QK'#**Yszzl KKH_w&);;F==?SSS? **V--/0K+m4444+m4444}%+666 H_z)K7F
v{{01
2Cs8q==r   c                \   | \  }}t        |d       t        |d       t        dd||      }|j                  dk(  s!J d|j                   d|j                          |d	z  d
z  dz  }|j                         rJ t        j                  |j                        }|d   dk(  sJ |d   dk(  sJ y)uK   S3 — token 없는 commit 은 alien 으로 간주하지 않음 → exit 0.z#random commit message without tokenr`   rK   rL   r   r   rc   rd   rM   rN   rO   rR   rT   untagged_commit_countrb   N)r>   rG   r7   r(   r9   rU   rX   rY   )rI   r   r,   r+   rZ   r]   s         r   "test_s3_untagged_commits_not_alienrm      s    #ND(t:;t_%
{HhD
AC>>QK'#**Yszzl KKH_w&);;F}}jj$G8 5555*+q000r   c                   | \  }}t        |d       t        |d       t        dd||      }|j                  dk(  sJ |dz  dz  d	z  }t        j                  |j                               }d
D ]  }||v rJ d|         |j                  d      xs |j                  d      }|J d       |j                  d      rd|v sJ t        |d   t              r|d   sJ |d   D ]%  }d|v rd|v rd|v sJ t        |d   t              r%J  y)u*   S4 — freeze 마커 필수 필드 검증.r`   ra   rK   rL   r   rb   rM   rN   rO   )rD   re   rg   r,   head_shacommitsu   freeze marker 필드 누락: 	frozen_atverified_atNu5   타임스탬프 필드 부재 (frozen_at/verified_at)ZTrp   shasubjecttokens)
r>   rG   r7   rX   rY   rh   getendswith
isinstancerV   )	rI   r   r,   r+   rZ   datakeyts_fieldcs	            r   test_s4_freeze_marker_schemar      s@   #ND(t_%t_%
{HhD
AC>>QH_w&);;F::f&&()D B d{A;C5AA{B xx$?(?HX!XXS!cXo55 d9ot,i@@)_ -zi1nQ>>!H+t,,,-r   c                   | \  }}t        |d       t        |d       t        dd||      }|j                  dk(  sJ |dz  dz  dz  }t        |j	                  d	            }t        |      dk\  sJ t        j                  |d
   j                               }d|v sJ d       d|d   v sJ |j                  dd      j                  d      sJ y)u3   S5 — evidence JSON 에 escalation_message 존재.r`   z[task-9999] foreignrK   rL   r   rb   rM   rP   rQ   escalation_messageu&   evidence 에 escalation_message 누락rf   freeze_marker_path rO   N)r>   rG   r7   sortedrW   r3   rX   rY   rh   rx   ry   )rI   r   r,   r+   r[   r\   evs          r   #test_s5_evidence_escalation_messager      s    #ND(t_%t*+
{HhD
AC>>QH_z)K7F
23
4Cs8q==	CG%%'	(B2%O'OO%"1222266&+445GHHHr   c                   | \  }}t        |d       t        |d       t        dd|d|      }|j                  dk(  s!J d|j                   d	|j                          t        j                  |j                        }|d
   du sJ d|d   v sJ |dz  dz  dz  }|j                         rJ d       |dz  dz  dz  }|j                         r't        |j                  d            }|g k(  sJ d       yy)u?   S6 — `--json` dry-run: 감지하지만 파일 생성 안 함.r`   ra   rK   rL   z--jsonr   rb   rc   rd   mixedTrf   rg   rM   rN   rO   u)   dry-run 에서 freeze 마커가 생성됨rP   rQ   u%   dry-run 에서 evidence 가 생성됨N)
r>   rG   r7   r(   r9   rX   rY   rU   rV   rW   )rI   r   r,   r+   r]   rZ   r[   r\   s           r   $test_s6_json_dry_run_no_side_effectsr      s	   #ND(t_%t_%
{Hhd
KC>>QK'#**Yszzl KK jj$G7t###'-0000 H_w&);;F}}K KKH_z)K7F}}6;;456byAAAy r   c                N   | \  }}t        |d       t        |d       t        dd||      }|j                  dk(  s!J d|j                   d|j                          |d	z  d
z  dz  }|j                         sJ t        j                  |j                               }d|d   v sJ y)uR   S7 — subject 본문 안의 토큰도 alien 감지 (prefix anchor 금지 검증).z[task-2459] step1z,[task-2459] follow up to [task-9999] cleanuprK   rL   r   rb   uJ   본문 토큰이 감지되지 않음 (prefix anchor 사용 의심)
stdout=rd   rM   rN   rO   rf   rg   N)	r>   rG   r7   r(   r9   rU   rX   rY   rh   )rI   r   r,   r+   rZ   r{   s         r   %test_s7_inline_alien_token_in_subjectr      s    #ND(t()tCD
{HhD
AC>>Q **Yszzl	4 H_w&);;F==??::f&&()D$}----r   c                    | \  }}t        dd||      }|j                  dk(  sJ t        j                  |j                        }|d   dk(  sJ |d   dk(  sJ y)	u<   추가 — base..HEAD 비어 있으면 status=empty, exit 0.rK   rL   r   r   rR   empty	n_commitsN)rG   r7   rX   rY   r(   )rI   r   r,   r+   r]   s        r   &test_empty_branch_returns_status_emptyr   	  se    #ND(
{HhD
AC>>Qjj$G8''';1$$$r   )r   r   r
   r   returnsubprocess.CompletedProcess)r*   r   r   ztuple[Path, str])N)r   r   r:   r   r;   z
str | Noner   r   )
rD   r   rE   r   r
   r   r?   zPath | Noner   r   )__doc__
__future__r   rX   r4   r   rA   pathlibr   pytest__file__resolveparents	REPO_ROOTrC   r   r-   r>   rG   fixturerI   r^   rj   rm   r   r   r   r   r    r   r   <module>r      s    #  	  
   N""$,,Q/	y #==,	"  "	 
 	
 !2  -*01" -FI&B..&	%r   