
    ;+i&H                         d Z ddlZddlmc m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d Zd Z	 	 dde
ded	ed
ee   dz  de
f
dZde
dedede
fdZde
dede
fdZ G d d      Z G d d      Z G d d      Zy)ul  
test_signature_check.py — signature_check verifier + verify-done.py 테스트

작성자: 아르고스 (개발1팀 테스터)
task-1972: .done 자동 검증 게이트 구현 테스트 (TDD RED)

테스트 대상:
  - teams/shared/verifiers/signature_check.py :: verify(task_id, workspace_root)
  - scripts/verify-done.py :: verify_done(task_id, workspace_root)
    N)Path)patch	MagicMockc                  l    t         j                  j                  dd       dd l} | j	                  d      S )Nr   z*/home/jay/workspace/teams/shared/verifierssignature_check)syspathinsert	importlibimport_moduler   s    1/home/jay/workspace/tests/test_signature_check.py_import_signature_checkr      s*    HHOOACD""#455    c                      t         j                  j                  dd       dd l} | j	                  dj                  dd            S )Nr   z/home/jay/workspace/scriptszverify-done-_)r   r	   r
   r   r   replacer   s    r   _import_verify_doner      s6    HHOOA45""=#8#8c#BCCr   tmp_pathtask_idlevel
signaturesreturnc                 .   | dz  dz  }|j                  dd       d| dg}|r|j                  d| d       |-|j                  d	       |D ]  }|j                  d
| d        dj                  |      }|| dz  }|j                  |d       |S )u*   tmp_path/memory/tasks/{task_id}.md 생성.memorytasksTparentsexist_okz# u*   : 테스트용 task

## 목적
테스트.
u   
## 레벨
- 
u   
## 완료 시그니처
z-  z.mdutf-8encoding)mkdirappendjoin
write_text)	r   r   r   r   	tasks_dirlinessigcontent	task_files	            r   _make_task_filer/   '   s     8#g-IOOD4O0'HIJEugR0112 	'CLL2cU"&	' ggenGwisO+I73r   rel_pathr-   c                 p    | |z  }|j                   j                  dd       |j                  |d       |S )u(   tmp_path 하위에 코드 파일 생성.Tr   r#   r$   )parentr&   r)   )r   r0   r-   targets       r   _make_code_filer4   A   s;     F
MMt4
g0Mr   c                 z    | dz  dz  }|j                  dd       || dz  }|j                  d| dd	       |S )
u-   tmp_path/memory/events/{task_id}.done 생성.r   eventsTr   z.donezdone: r!   r#   r$   )r&   r)   )r   r   
events_dir	done_files       r   _make_done_filer9   I   sW    H$x/JTD1y..I6'"-@r   c                   p    e Zd ZdZdefdZdefdZdefdZdefdZdefdZ	defdZ
defd	Zdefd
Zy)TestSignatureCheckVerifyu*   signature_check.verify() 유닛 테스트.r   c                    t               }d}d}d}t        |||       t        ||dd| dg       |j                  |t	        |            }|d	   }d
}||k(  }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  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dz  }dd|iz  }t        t        j                  |            dx}}	y)u8   시나리오 1: grep 패턴이 파일에 존재 → PASSztask-test-passscripts/sample.pyz#def my_function():
    return True
normalz[grep] `def my_function` @ ``r   r   workspace_rootstatusPASS==z%(py1)s == %(py4)spy1py4   PASS 기대, 실제: 
>assert %(py6)spy6Ndetailsinz%(py1)s in %(py3)sresultrI   py3assert %(py5)spy5r   r4   r/   verifystr
@pytest_ar_call_reprcompare	_saferepr_format_assertmsgAssertionError_format_explanation@py_builtinslocals_should_repr_global_name)selfr   scr   code_relcode_contentrR   @py_assert0@py_assert3@py_assert2@py_format5@py_format7@py_format4@py_format6s                 r   test_signature_pass_grep_existsz8TestSignatureCheckVerify.test_signature_pass_grep_existsY   s   $&"&>(L96xjBC		
 73x=AhK6K6)KKK6KKKKKK6KKK-B6(+KKKKKKKK"yF""""yF"""y""""""F"""F"""""""r   c                    t               }d}d}t        ||d       t        ||dd| dg       |j                  |t	        |            }|d	   }d
}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	t        j                  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dz  }dd|iz  }t        t        j                  |            dx}}y)u8   시나리오 2: grep 패턴이 파일에 없음 → FAILztask-test-failr=   zdef other_function():
    pass
r>   z![grep] `def missing_function` @ `r?   r@   rA   rC   FAILrE   rG   rH      FAIL 기대, 실제: rL   rM   NrN   rO   rQ   rR   rS   rU   rV   rW   )rc   r   rd   r   re   rR   rg   rh   ri   rj   rk   rl   rm   s                r    test_signature_fail_grep_missingz9TestSignatureCheckVerify.test_signature_fail_grep_missingn   s   $&"&(,OP;H:QGH		
 73x=AhK6K6)KKK6KKKKKK6KKK-B6(+KKKKKKKK"yF""""yF"""y""""""F"""F"""""""r   c                    t               }d}t        ||       |j                  |t        |            }|d   }d}||k(  }|st	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }t	        j                  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dz  }
dd|
iz  }t        t	        j                  |            dx}}y)uO   시나리오 3: 시그니처 섹션 없는 기존 task → SKIP (하위 호환)ztask-old-no-sigrA   rC   SKIPrE   rG   rH      SKIP 기대, 실제: rL   rM   NrN   rO   rQ   rR   rS   rU   rV   )r   r/   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   )rc   r   rd   r   rR   rg   rh   ri   rj   rk   rl   rm   s               r   test_signature_skip_no_sectionz7TestSignatureCheckVerify.test_signature_skip_no_section   s    $&#'*73x=AhK6K6)KKK6KKKKKK6KKK-B6(+KKKKKKKK"yF""""yF"""y""""""F"""F"""""""r   c                 8   t               }d}d}t        ||d       t        ||dd| ddg       t        d	      5 }t	        d
dd      |_        |j                  |t        |            }ddd       d   }d}||v }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  d|       dz   d|
iz  }t        t        j                  |            dx}x}	}j                  D cg c]>  }|j                  r0t!        |j                  d
   t"              rd|j                  d
   v r|@ }}t%        |      }	d
}|	|k(  }|st        j                  d|fd|	|f      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                  |	      t        j                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}	x}}y# 1 sw Y    xY wc c}w ) uX   시나리오 4: Lv.1-2 (normal) task → [pytest] 시그니처는 무시, grep만 검증ztask-lv1-normalzscripts/feature.pyzFEATURE_FLAG = True
r>   z[grep] `FEATURE_FLAG` @ `r?   z0[pytest] `tests/test_feature.py::test_something`r@   subprocess.runr   r"   
returncodestdoutstderrrA   NrC   )rD   rt   rO   z%(py1)s in %(py4)srH   u5   normal 레벨에서 PASS 또는 SKIP 기대, 실제: rL   rM   pytestrE   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenpytest_callspy0rI   rT   rM   u:   Lv.1-2 (normal)에서 pytest 호출이 있으면 안 됨: 
>assert %(py8)spy8)r   r4   r/   r   r   return_valuerX   rY   rZ   r[   r\   r]   r^   r_   call_args_listargs
isinstancelistr   r`   ra   rb   )rc   r   rd   r   re   mock_runrR   rg   rh   ri   rj   rk   callr   @py_assert5@py_assert4@py_format9s                    r   test_level_normal_grep_onlyz4TestSignatureCheckVerify.test_level_normal_grep_only   s   $&#'(,CD+H:Q7B			
 #$ 	F$-2b$QH!YYws8}YEF	F h 	
#3 	
#33 	
 	
#3 	
 	
 		   	
 	
 		 $4 	
 	
  DF8L	
 	
 	
 	
 	
 &44
yyZ		!d;DIIVWL@X 
 
 <  	
A 	
 A% 	
 	
 	
 A 	
 	
	6	
 	
   	
 	
 		  	
 	
	6	
 	
    	
 	
 		   	
 	
 		 ! 	
 	
 		 %& 	
 	
  IW	
 	
 	
 	
 	
 	
	F 	F
s   0J
AJ
Jc                 p   t               }d}d}t        ||d       t        ||dd| ddg       g fd	}t        d
|      5  |j	                  |t        |            }ddd       t              }d}||kD  }	|	st        j                  d|	fd||f      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                  |      t        j                  |      dz  }
t        j                  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z   d|iz  }
t        t        j                  |
            dx}x}}y# 1 sw Y   xY w)uD   시나리오 5: Lv.3+ (critical) → [grep] + [pytest] 모두 검증ztask-lv3-criticalzscripts/secure.pyzdef validate_token(): pass
criticalz[grep] `def validate_token` @ `r?   z.[pytest] `tests/test_secure.py::test_validate`r@   c                     t        |       }d|v rj                  |        t        ddd      S t        t        j
                  d      r#t	        j
                  j                  | g|i |S t        ddd      S )Nr~   r   1 passedr"   ry   __wrapped__match)rY   r'   r   hasattr
subprocessrunr   )cmdr   kwargscmd_strpytest_calleds       r   fake_runzBTestSignatureCheckVerify.test_level_critical_all.<locals>.fake_run   s    #hG7"$$S) AjLLGNz~~_lGm:>>--cCDCFC  fs|  IJ  SZ  ce  tf  fr   rx   side_effectrA   Nr   >z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)sr   r   r   u5   Lv.3+ (critical)에서 pytest 호출이 있어야 함r   r   rC   )rD   rp   rO   r}   rH   u7   critical 레벨에서 PASS 또는 FAIL 기대, 실제: rL   rM   r   r4   r/   r   rX   rY   r   rZ   r[   r`   ra   rb   r\   r]   r^   r_   )rc   r   rd   r   re   r   rR   ri   r   r   rk   r   rg   rh   rj   r   s                  @r   test_level_critical_allz0TestSignatureCheckVerify.test_level_critical_all   s$   $&%&(,JK1(1=@		
 	f #: 	FYYws8}YEF	F =! 	
A 	
!A% 	
 	
 	
!A 	
 	
	6	
 	
   	
 	
 		  	
 	
	6	
 	
  ! 	
 	
 		 ! 	
 	
 		 " 	
 	
 		 %& 	
 	
  D	
 	
 	
 	
 	
 h 	
#3 	
#33 	
 	
#3 	
 	
 		   	
 	
 		 $4 	
 	
  FfXN	
 	
 	
 	
 	
 	
	F 	Fs   H++H5c           	         t               }d}d}t        ||d       t        ||dd| dd| dg       |j                  |t	        |      	      }|d
   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	t        j                  d|       dz   d|	iz  }
t        t        j                  |
            dx}x}}y)u;   여러 grep 시그니처 중 하나라도 실패하면 FAILztask-multi-grepzscripts/multi.pyzdef present_func():
    pass
r>   z[grep] `def present_func` @ `r?   z[grep] `def absent_func` @ `r@   rA   rC   rp   rE   rG   rH   u,   일부 grep 실패 시 FAIL 기대, 실제: rL   rM   N)r   r4   r/   rX   rY   rZ   r[   r\   r]   r^   r_   )rc   r   rd   r   re   rR   rg   rh   ri   rj   rk   s              r   test_grep_signature_multiplez5TestSignatureCheckVerify.test_grep_signature_multiple   s    $&#%(,MN/z;.xj:		
 73x=Ah 	
6 	
6) 	
 	
6 	
 	
 		   	
 	
 		 $* 	
 	
  ;6(C	
 	
 	
 	
 	
 	
r   c                    t               }d}t        ||ddg       |j                  |t        |            }|d   }d}||k(  }|st	        j
                  d|fd	||f      t	        j                  |      t	        j                  |      d
z  }t	        j                  d|       dz   d|iz  }	t        t	        j                  |	            dx}x}}y)u1   grep 대상 파일이 존재하지 않으면 FAILztask-no-filer>   z0[grep] `some_pattern` @ `scripts/nonexistent.py`r@   rA   rC   rp   rE   rG   rH   u*   파일 미존재 시 FAIL 기대, 실제: rL   rM   N)
r   r/   rX   rY   rZ   r[   r\   r]   r^   r_   
rc   r   rd   r   rR   rg   rh   ri   rj   rk   s
             r   test_signature_file_not_foundz6TestSignatureCheckVerify.test_signature_file_not_found   s    $& JK		
 73x=Ah 	
6 	
6) 	
 	
6 	
 	
 		   	
 	
 		 $* 	
 	
  9A	
 	
 	
 	
 	
 	
r   c                    t               }d}|j                  |t        |            }|d   }d}||k(  }|st        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }t        j                  d|       d	z   d
|iz  }	t        t        j                  |	            dx}x}}y)u;   task 파일 자체가 없으면 SKIP (graceful degradation)z
task-ghostrA   rC   rt   rE   rG   rH   u,   task 파일 없을 때 SKIP 기대, 실제: rL   rM   N)	r   rX   rY   rZ   r[   r\   r]   r^   r_   r   s
             r   %test_task_file_not_found_returns_skipz>TestSignatureCheckVerify.test_task_file_not_found_returns_skip	  s    $& 73x=Ah 	
6 	
6) 	
 	
6 	
 	
 		   	
 	
 		 $* 	
 	
  ;6(C	
 	
 	
 	
 	
 	
r   N)__name__
__module____qualname____doc__r   rn   rr   rv   r   r   r   r   r    r   r   r;   r;   V   sg    4# #*# #(#t #%
D %
N%
 %
N
T 
2
d 
&
d 
r   r;   c                   L    e Zd ZdZdefdZdefdZdefdZdefdZdefdZ	y)	TestVerifyDoneu.   verify-done.py verify_done() 유닛 테스트.r   c                 ~   t               }d}d}t        ||d       t        ||dd| dg       t        ||      }|j	                  |t        |            }|d	   }d
}||k(  }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  d|       dz   d|
iz  }t        t        j                  |            dx}x}	}|d   }d}||k(  }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  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dz  }dd|i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}}|j                   | 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}x}}y)$uR   .done 파일 + 시그니처 검증 PASS → .done 유지, status=PASS, action=keepztask-vd-passzscripts/app.pyzdef main(): pass
r>   z[grep] `def main` @ `r?   r@   rA   rC   rD   rE   rG   rH   rK   rL   rM   Nactionkeepu   action=keep 기대, 실제: rN   rO   rQ   rR   rS   rU   rV   u#   .done 파일이 유지되어야 함C
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}r8   r   py2rJ   .done.rejectedu-   .done.rejected 파일이 생성되면 안 됨zG
>assert not %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}rejected_file)r   r4   r/   r9   verify_donerY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   existsr2   )rc   r   vdr   re   r8   rR   rg   rh   ri   rj   rk   rl   rm   @py_assert1r   r   s                    r   test_verify_done_passz$TestVerifyDone.test_verify_done_pass  s~    " #(,@A/z;<		
 $Hg6	HFhK6K6)KKK6KKKKKK6KKK-B6(+KKKKKKKKhR6R6)RRR6RRRRRR6RRR-I&+RRRRRRRR"yF""""yF"""y""""""F"""F""""""" H!H!HH#HHHHHHHyHHHyHHHHHH!HHHHHH!((gYn+EE ''Z')Z))Z)ZZ+ZZZZZZZ=ZZZ=ZZZ'ZZZ)ZZZZZZr   c                 z	   t               }d}d}t        ||d       t        ||dd| dg       t        ||      }|j	                  |t        |            }|d	   }d
}||k(  }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  d|       dz   d|
iz  }t        t        j                  |            dx}x}	}|d   }d}||k(  }	|	st        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
t        j                  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dz  }d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}}	|d   }t        |      }d}||kD  }|st        j                  d |fd!||f      d"t        j                         v st        j                  t              rt        j                  t              nd"t        j                  |      t        j                  |      t        j                  |      d#z  }t        j                  d$|       d%z   d&|iz  }t        t        j                  |            dx}x}x}}|d'z  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}}y).uP   .done 파일 + 시그니처 검증 FAIL → .done.rejected 생성, action=rejectztask-vd-failzscripts/broken.pyz# empty
r>   z"[grep] `def required_function` @ `r?   r@   rA   rC   rp   rE   rG   rH   rq   rL   rM   Nr   rejectu   action=reject 기대, 실제: rN   rO   rQ   rR   rS   rU   rV   failed_signaturesu*   FAIL 시 failed_signatures 포함 필요: 
>assert %(py5)sr   r   )z/%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} > %(py7)sr   )r   r   rJ   py7u4   실패한 시그니처가 1개 이상이어야 함: z
>assert %(py9)spy9r   r6   r   u,   .done.rejected 파일이 생성되어야 함r   r   r   )r   r4   r/   r9   r   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   r   r   )rc   r   r   r   re   r8   rR   rg   rh   ri   rj   rk   rl   rm   r   @py_assert6r   @py_format8@py_format10r7   r   s                        r   &test_verify_done_fail_creates_rejectedz5TestVerifyDone.test_verify_done_fail_creates_rejected:  s    " &(K8<XJaHI		
 $Hg6	HFhK6K6)KKK6KKKKKK6KKK-B6(+KKKKKKKKhV8V8+VVV8VVVVVV8VVV/MfX-VVVVVVVV"yF""""yF"""y""""""F"""F""""""" # 	
"f, 	
 	
"f 	
 	
 		 # 	
 	
	6	
 	
  '- 	
 	
 		 '- 	
 	
  9A	
 	
 	
 	
 	
 -. 	
s./ 	
! 	
/!3 	
 	
/! 	
 	
	6	
 	
   	
 	
 		  	
 	
 		 / 	
 	
 		 0 	
 	
 		 34 	
 	
  C6(K	
 	
 	
 	
 	
 	

 (83
"y%??##U#%U%UU'UUUUUUU}UUU}UUU#UUU%UUUUUUr   c                 2   t               }d}t        ||       t        ||       |j                  |t	        |            }|d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|       d	z   d
|iz  }	t        t        j                  |	            dx}x}}|d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  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dz  }
dd|
iz  }t        t        j                  |            dx}}y)uE   시그니처 섹션 없는 task → SKIP, action=skip (하위 호환)ztask-vd-skiprA   rC   rt   rE   rG   rH   ru   rL   rM   Nr   skipu   action=skip 기대, 실제: rN   rO   rQ   rR   rS   rU   rV   )r   r/   r9   r   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   )rc   r   r   r   rR   rg   rh   ri   rj   rk   rl   rm   s               r   "test_verify_done_skip_no_signaturez1TestVerifyDone.test_verify_done_skip_no_signature^  s\    " '*'*HFhK6K6)KKK6KKKKKK6KKK-B6(+KKKKKKKKhR6R6)RRR6RRRRRR6RRR-I&+RRRRRRRR"yF""""yF"""y""""""F"""F"""""""r   c                    t               }d}d}t        ||d       t        ||dd| dg       t        ||       |j	                  |t        |            }|d	z  d
z  }|| dz  }|j                         rm|j                  d      }g }	||v }
|
}|
sd}||v }|}|sd}||v }|}|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                  |      rt        j                  |      nddz  }dd|iz  }|	j                  |       |
st        j                  dfd|f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }|	j                  |       |st        j                  dfd|f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }|	j                  |       t        j                  |	d      i z  }t        j                   d |      d!z   d"|iz  }t#        t        j$                  |            d#x}x}	x}
x}x}x}}y#y#)$uH   .done.rejected 생성 시 거절 사유가 파일에 기록되어야 함ztask-vd-reasonzscripts/impl.pyz# no matching content
r>   z[grep] `class MyClass` @ `r?   r@   rA   r   r6   r   r#   r$   rp   zclass MyClassrO   )z%(py2)s in %(py4)sr   r-   )r   rJ   z%(py6)srM   )z%(py9)s in %(py11)s)r   py11z%(py13)spy13)z%(py16)s in %(py18)s)py16py18z%(py20)spy20   u7   .done.rejected 파일에 사유 기록 필요. 내용: z
>assert %(py23)spy23N)r   r4   r/   r9   r   rY   r   	read_textrZ   r[   r`   ra   rb   r\   r'   _format_boolopr]   r^   r_   )rc   r   r   r   re   rR   r7   r   r-   r   rh   rg   @py_assert8@py_assert10@py_assert15@py_assert17rj   rk   @py_format12@py_format14@py_format19@py_format21@py_format22@py_format24s                           r   0test_verify_done_rejected_contains_reject_reasonz?TestVerifyDone.test_verify_done_rejected_contains_reject_reasonm  s    ""$(,EF4XJa@A		
 	'*HF (83
"y%??!#--w-?G7g%  7): o oQX>X   7g  v     I   v   &  I &   v 7  I *0  v   4;  I 4;   v oQX  I ?N  v   RY  I RY   v    J'U       "r   c                    t               }d}d}t        ||d       t        ||dd| dg       t        ||       t	        d      5 }t        d	d
d
      |_        |j                  |t        |            }ddd       d   }d}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}	}|d   }d}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
d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dz  }t        j"                  d      dz   d|iz  }t        t        j                  |            dx}}	y# 1 sw Y   xY w)uO   .done.rejected 시 자동 재위임 메시지 관련 정보가 result에 포함ztask-vd-delegatezscripts/gate.pyz# placeholder
r   z[grep] `def gate_function` @ `r?   r@   rx   r   r"   ry   rA   NrC   rp   rE   rG   rH   zassert %(py6)srM   r   r   r   rO   rQ   rR   rS   u=   재위임 메시지 전송을 위해 failed_signatures 필요r   rV   )r   r4   r/   r9   r   r   r   r   rY   rZ   r[   r\   r^   r_   r`   ra   rb   r]   )rc   r   r   r   re   r   rR   rg   rh   ri   rj   rk   rl   rm   s                 r   1test_verify_done_autodelegate_message_on_rejectedz@TestVerifyDone.test_verify_done_autodelegate_message_on_rejected  s    "$$(,=>0
!<		
 	'* #$ 	K$-2b$QH!^^GCM^JF	K h)6)6))))6))))))6)))))))h+8+8++++8++++++8+++++++ # 	
"f, 	
 	
"f 	
 	
 		 # 	
 	
	6	
 	
  '- 	
 	
 		 '- 	
 	
  L	
 	
 	
 	
 	
	K 	Ks   0H;;IN)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     sF    8[d [8"Vt "VH#4 # :
$ 
r   r   c                   (    e Zd ZdZdefdZdefdZy)TestLevelDetectionu&   레벨 판별 관련 통합 테스트.r   c                 @   t               }d}d}t        ||d       t        ||dd| ddg       g fd	}t        d
|      5  |j	                  |t        |             ddd       t              }d}||kD  }|st        j                  d|fd||f      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                  |      t        j                  |      dz  }	t        j                  d      dz   d|	iz  }
t        t        j                  |
            dx}x}}y# 1 sw Y   2xY w)uB   security 레벨도 Lv.3+로 취급 → grep + pytest 모두 검증ztask-security-levelzscripts/auth.pyzdef authenticate(): pass
securityz[grep] `def authenticate` @ `r?   z0[pytest] `tests/test_auth.py::test_authenticate`r@   c                 x    dt        |       v rj                  |        t        ddd      S t        ddd      S )Nr~   r   r   r"   ry   r   )rY   r'   r   )r   r   r   r   s      r   r   zLTestLevelDetection.test_security_level_treated_as_critical.<locals>.fake_run  s;    3s8#$$S) AjLL'"EEr   rx   r   rA   Nr   r   r   r   r   r   uC   security 레벨에서 pytest 호출이 있어야 함 (Lv.3+ 취급)r   r   r   )rc   r   rd   r   re   r   ri   r   r   rk   r   r   s              @r   'test_security_level_treated_as_criticalz:TestLevelDetection.test_security_level_treated_as_critical  s   $&'$(,HI/z;B		
 	F #: 	=IIgc(mI<	= =! 	
A 	
!A% 	
 	
 	
!A 	
 	
	6	
 	
   	
 	
 		  	
 	
	6	
 	
  ! 	
 	
 		 ! 	
 	
 		 " 	
 	
 		 %& 	
 	
  R	
 	
 	
 	
 	
 	
	= 	=s   FFc                    t               }d}d}t        ||d       t        ||d| dg       t        d      5 }t	        dd	d
      |_        |j                  |t        |            }ddd       j                  D cg c]>  }|j                  r0t        |j                  d   t              rd|j                  d   v r|@ }}t        |      }	d}
|	|
k(  }|st        j                  d|fd|	|
f      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$                  |	      t        j$                  |
      dz  }t        j&                  d      dz   d|iz  }t)        t        j*                  |            dx}	x}}
y# 1 sw Y   xY wc c}w )u6   레벨 섹션 없으면 기본적으로 grep만 검증ztask-no-levelzscripts/default.pyzDEFAULT_VALUE = 42
z[grep] `DEFAULT_VALUE` @ `r?   )r   rx   r   r   r"   ry   rA   Nr~   rE   r   r   r   r   u0   레벨 미지정 시 pytest 호출 없어야 함r   r   )r   r4   r/   r   r   r   rX   rY   r   r   r   r   r   rZ   r[   r`   ra   rb   r\   r]   r^   r_   )rc   r   rd   r   re   r   rR   cr   ri   r   r   rk   r   s                 r   +test_no_level_section_defaults_to_grep_onlyz>TestLevelDetection.test_no_level_section_defaults_to_grep_only  s   $&!'(,BC 	4XJa@A	
 #$ 	F$-7SU$VH!YYws8}YEF	F
  ..
vv*QVVAY5(affQi:O 
 
 <  	
A 	
 A% 	
 	
 	
 A 	
 	
	6	
 	
   	
 	
 		  	
 	
	6	
 	
    	
 	
 		   	
 	
 		 ! 	
 	
 		 %& 	
 	
  ?	
 	
 	
 	
 	
 	
	F 	F
s   0G- AG:-G7N)r   r   r   r   r   r   r   r   r   r   r   r     s    0
 
B
D 
r   r   )r"   N)r   builtinsr`   _pytest.assertion.rewrite	assertionrewriterZ   r   r   pathlibr   unittest.mockr   r   r~   r   r   rY   r   r/   r4   r9   r;   r   r   r   r   r   <module>r      s   	  
   * 6D #'	  S	D 	
 
4d c C D d S T ~
 ~
JN
 N
j>
 >
r   