
    <j(                     f   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ZddlmZ ddl	Z	 ee
      j                         j                  d   Zedz  dz  ZdefdZdefd	Zd
edededdfdZd
edefdZ e	j*                         d        Zd Zdee   dededz  fdZd Zd Zd Zd Zd Zd Zd Z d Z!y)un  
test_stash_lifecycle_classification.py
task: task-2571 TODO-7 T-1

검증 목표:
- spec §2 분류 매트릭스 기준 6 카테고리 stash 메시지 분류 정확성
- 임시 git repo 에서 각 source 1건씩 stash 메시지 시드 후 stash_audit.py --json 호출
- entries[].source 가 기대값과 일치하는지 검증

작성자: 하누만 (개발4팀 QA)
    N)Path   scriptszstash_audit.pyreturnc                     t        j                  d      } t               }t        j                  g d| d|       t        j                  g d| d|       t        j                  g d| d|       t        |       dz  j                  d	       t        j                  g d
| d|       t        j                  g d| d|       | S )u$   격리된 임시 git repo 초기화.zstash-lifecycle-test-)prefix)gitinit-qz-bmainTcwdcheckenv)r	   configz
user.emailtest@example.com)r	   r   z	user.nametesta.txthello)r	   addr   )r	   commitr   -mr
   )tempfilemkdtemp_git_env
subprocessrunr   
write_text)dr   s     7tests/regression/test_stash_lifecycle_classification.py_init_temp_repor!       s     78A
*CNN6ATsSNNFAUY_bcNN9qRUV	!Ww""7+NN*3GNN8atQTUH    c                  j    t         j                  j                         } d| d<   d| d<   d| d<   d| d<   | S )u"   git 명령 실행용 환경변수.r   GIT_AUTHOR_NAMEr   GIT_AUTHOR_EMAILGIT_COMMITTER_NAMEGIT_COMMITTER_EMAIL)osenvironcopy)r   s    r    r   r   -   sC    
**//
C#C0C &C!3CJr"   repo_dirmessagefilenamec                     t               }t        |       |z  }|j                  d| d       t        j                  dd|g| d|       t        j                  dddd	|g| d|       y
)u3   파일 하나 dirty 상태로 만들고 stash push.zdirty: 
r	   r   Tr   stashpushr   N)r   r   r   r   r   )r+   r,   r-   r   fpaths        r    _stash_pushr3   7   sf    
*CNX%E	wwir*+NNE5(+3ONNE7FD':PTZ]^r"   c                    t        j                  t        j                  t	        t
              dd| gdd      }|j                  dk(  s!J d|j                   d|j                          t        j                  |j                        S )u7   stash_audit.py --json 실행 후 파싱된 dict 반환.z--jsonz--workspaceT)capture_outputtextr   u#   stash_audit.py 실행 실패 (exit=z
)
stderr: )r   r   sys
executablestrSTASH_AUDIT_PY
returncodestderrjsonloadsstdout)r+   results     r    _run_audit_jsonrA   @   s    ^^	^,hxPF
 ! 
-f.?.?-@ A==/	#! ::fmm$$r"   c               #      K   t               } g d}|D ]  \  }}}t        | ||        | |f t        j                  | d       yw)u   
    spec §2 6 카테고리 stash 메시지 각 1건씩 시드.
    각 stash 는 별도 파일을 dirty 상태로 만들어 push.
    ))pre-taskzf1.txtzWIP: pre-task-2571 stash sample)
quarantinezf2.txtzB[task-2566][source=quarantine][reason=test] finish-task-quarantine)other-fileszf3.txtzE[task-2564][source=other-files][reason=test] other-files-stash sample)finish-taskzf4.txtzH[task-2569][source=finish-task][reason=test] finish-task GIT-GATE sample)wipzf5.txt!WIP on main: 9a651f37 some change)unknownzf6.txt'random unknown stash message no patternT)ignore_errorsN)r!   r3   shutilrmtree)r+   seeds_fnamemsgs        r    six_category_reporR   R   sT       HE  *5#Hc5)* E/
MM($/s   AAc           	          | \  }}t        |      }|j                  dg       }t        |      dk(  s,J dt        |       dt        j                  |dd              y)	u-   6 카테고리 모두 감지되어야 한다.entries   u   6건 stash 시드 후 u   건만 감지됨
entries: Fr   )ensure_asciiindentN)rA   getlenr=   dumps)rR   r+   rO   datarT   s        r    ,test_classification_all_six_sources_detectedr\   p   sg    #KHa8$Dhhy"%Gw<1 
 W /JJwU1EF	Hr"   rT   fragmentc                 B    | D ]  }||j                  dd      v s|c S  y)u   
    raw_message 에 fragment 가 포함된 entry 를 반환.
    git stash list 는 "On main: <msg>" 형식으로 prefix 를 붙이므로
    exact match 대신 substring search 를 사용.
    raw_message N)rX   )rT   r]   es      r    _find_entry_by_msg_fragmentrb   {   s0      quu]B//H r"   c           
          | \  }}t        |      }|j                  dg       }d}t        ||      }|*J d| d|D cg c]  }|j                  d       c}        |d   dk(  sJ d	|d    d
|d           yc c}w )uQ   'WIP: pre-task-2571 stash sample' 은 source=pre-task 로 분류되어야 한다.rT   zpre-task-2571 stash sampleN'u'   ' 포함 entry 미발견
raw_messages: r_   sourcerC   u   기대: pre-task, 실제: 
raw_message: rA   rX   rb   )rR   r+   rO   r[   rT   r]   entryra   s           r    "test_classification_pretask_sourceri      s    #KHa8$Dhhy"%G+H':E 
H: 8?@1!%%.@A	C ?j( 
$U8_$5_U=EYDZ[( As   A9c                     | \  }}t        |      }|j                  dg       }d}t        ||      }|J d| d       |d   dk(  sJ d|d    d	|d
           y)uU   finish-task-quarantine 패턴 stash 는 source=quarantine 로 분류되어야 한다.rT   zfinish-task-quarantineNrd      ' 포함 entry 미발견re   rD   u   기대: quarantine, 실제: rf   r_   rg   rR   r+   rO   r[   rT   r]   rh   s          r    %test_classification_quarantine_sourcerm      s    #KHa8$Dhhy"%G'H':E 
H:-. ?l* 
&uX&7u]G[F\]*r"   c                     | \  }}t        |      }|j                  dg       }d}t        ||      }|J d| d       |d   dk(  sJ d|d    d	|d
           y)uQ   other-files-stash 패턴 stash 는 source=other-files 로 분류되어야 한다.rT   zother-files-stash sampleNrd   rk   re   rE   u   기대: other-files, 실제: rf   r_   rg   rl   s          r    &test_classification_other_files_sourcero      s    #KHa8$Dhhy"%G)H':E 
H:-. ?m+ 
'h'8mH\G]^+r"   c                     | \  }}t        |      }|j                  dg       }d}t        ||      }|J d| d       |d   dk(  sJ d|d    d	|d
           y)uK   finish-task 패턴 stash 는 source=finish-task 로 분류되어야 한다.rT   zfinish-task GIT-GATE sampleNrd   rk   re   rF   u   기대: finish-task, 실제: rf   r_   rg   rl   s          r    &test_classification_finish_task_sourcerq      s    #KHa8$Dhhy"%G,H':E 
H:-. ?m+ 
'h'8mH\G]^+r"   c                     | \  }}t        |      }|j                  dg       }d}t        ||      }|J d| d       |d   dv sJ d|d    d	|d
           y)uc  
    'WIP on main: 9a651f37 some change' 패턴 stash 는 source=wip 로 분류되어야 한다.
    주의: git stash push -m "WIP on main: ..." 시 stash list 는 "On main: WIP on main: ..."
    로 표시될 수 있음. raw_message 기반 패턴 매칭(^WIP on \w) 은 stash_audit.py
    SOURCE_PATTERNS 5번 패턴. "On main: WIP on main: ..." 처럼 prefix 붙은 경우
    ^WIP 매칭이 안 될 수 있어 unknown 으로 분류될 수 있음.
    이 경우 "WIP on main:" 포함 여부로 source 를 검증하되,
    wip 또는 unknown 둘 다 허용 (stash_audit.py 현행 패턴 제약 반영).
    rT   rH   Nrd   rk   re   )rG   rI   u$   기대: wip 또는 unknown, 실제: rf   r_   rg   rl   s          r    test_classification_wip_sourcers      s     $KHa8$Dhhy"%G2H':E 
H:-. ?00 
.uX.?uUbOcNde0r"   c                     | \  }}t        |      }|j                  dg       }d}t        ||      }|J d| d       |d   dk(  sJ d|d    d	|d
           y)uI   패턴 매칭 없는 stash 는 source=unknown 로 분류되어야 한다.rT   rJ   Nrd   rk   re   rI   u   기대: unknown, 실제: rf   r_   rg   rl   s          r    "test_classification_unknown_sourceru      s    #KHa8$Dhhy"%G8H':E 
H:-. ?i' 
#E(O#4OE-DXCYZ'r"   c                     | \  }}t        |      }|j                  dg       }|D ]  }dD ]  }||v rJ d| d|          y)uO   모든 entry 가 필수 필드(index, source, raw_message)를 가져야 한다.rT   )indexre   r_   u   entry 에 'u   ' 필드 없음
entry: N)rA   rX   )rR   r+   rO   r[   rT   ra   fields          r    4test_classification_all_entries_have_required_fieldsry      sg    #KHa8$Dhhy"%G 7 	EA: eW$<QC@:	r"   c                     | \  }}t        |      }|j                  di       }|j                  di       }t        |j                               }|dk(  sJ d| d|        y)u4   summary.count_by_source 합계가 6이어야 한다.summarycount_by_sourcerU   u'   count_by_source 합계가 6이 아님: z
count_by_source: N)rA   rX   sumvalues)rR   r+   rO   r[   r{   r|   totals          r    2test_classification_count_by_source_matches_matrixr      ss    #KHa8$Dhhy"%Gkk"3R8O&&()EA: 
1% 9+,	.:r"   )"__doc__r=   r(   rL   r   r7   r   pathlibr   pytest__file__resolveparentsWORKTREE_ROOTr:   r9   r!   dictr   r3   rA   fixturerR   r\   listrb   ri   rm   ro   rq   rs   ru   ry   r    r"   r    <module>r      s  
  	   
   X&&(003*-==
 
$ _# _ _s _t _%c %d %$ 0 0:	d 	s 	td{ 	"   6 	
r"   