
    9j9                     .   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
Z
ddlZ ej                  e      j                         j                  d   Zedz  dz  Z e	j$                  de	j&                        Zefdej                  defd	Zg d
Zd Zd Zd Zd Zej8                  j;                  de      defd       Zej>                  d        Z dej                  de!e   fdZ"dej                  de!e   fdZ#d Z$d Z%d Z&d Z'd Z(d Z)d Z*d Z+d Z,y)u  
test_ci_sh_worktree_exclude_2549.py — task-2549 / task-2549+1 회귀 테스트

scripts/ci.sh의 1단계 syntax check (`find $WORKSPACE -name "*.py"`)에
non-source 디렉토리 (.worktrees / .venv / venv / .codegraph-venv /
node_modules / .git) 가지치기 (prune) 가 적용되어 스캔 시간 폭증이
재발하지 않도록 박제한다.

task-2549+1 추가 박제:
- ci.sh find 명령에 `-type f` 가 적용되어 디렉토리 이름이 `*.py` 인 경우
  (예: `pkg.py/` 디렉토리) 잘못 수집되지 않는다.
- `_run_find_pruned` 헬퍼는 ci.sh 의 find 블록을 정적 텍스트 추출 후
  bash 로 실행한다. 따라서 ci.sh 가 변경되면 테스트 행동도 자동 반영된다
  (재정의 X — False Positive 방지).
    N   scriptszci.shzGdone\s*<\s*<\(\s*(?P<find_cmd>find\s+\"\$WORKSPACE\".*?-print0[^)]*?)\)
ci_sh_pathreturnc                     | j                         }t        j                  |      }|st        d      |j	                  d      j                         S )u   ci.sh 의 1단계 find 명령을 텍스트로 추출.

    ci.sh 의 `done < <(find "$WORKSPACE" ... -print0 ...)` 블록을 매칭해
    안의 find 명령을 반환한다. ci.sh 가 바뀌면 자동으로 새 명령을 반환.
    u   ci.sh 의 1단계 find 블록(`done < <(find "$WORKSPACE" ... -print0 ...)`)을 찾을 수 없음. ci.sh 구조 변경 시 본 헬퍼도 갱신 필요.find_cmd)	read_text_FIND_BLOCK_REsearchRuntimeErrorgroupstrip)r   contentmatchs      H/home/jay/workspace/tests/regression/test_ci_sh_worktree_exclude_2549.py_extract_find_commandr   (   sR     ""$G!!'*EZ
 	
 ;;z"((**    )
.worktrees.venvvenv.codegraph-venvnode_modules.gitc                     t         j                  }  |        }|st        j                  dt                dz   dt	        j
                         v st        j                  t               rt        j                  t               ndt        j                  |       t        j                  |      dz  }t        t        j                  |            dx} }y)u5   scripts/ci.sh가 워크트리 루트에 존재한다.zci.sh not found at zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}CI_SHpy0py2py4N)
r   exists
@pytest_ar_format_assertmsg@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation)@py_assert1@py_assert3@py_format5s      r   test_ci_sh_existsr,   G   sl    <<8<>8>880888888858885888<888>888888r   c                  t   t         j                         } t        j                  }d} |||       }|s t	        j
                  d      dz   dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dt        j                         v st	        j                  |       rt	        j                  |       ndt	        j                  |      dz  }t        t	        j                  |            dx}x}}y)uH   ci.sh가 여전히 *.py 패턴을 find한다 (regression 방향 검증).-name\s+[\"']\*\.py[\"']zfind pattern '*.py' missingS
>assert %(py7)s
{%(py7)s = %(py2)s
{%(py2)s = %(py0)s.search
}(%(py4)s, %(py5)s)
}rer   r   r   r   py5py7N)r   r	   r0   r   r!   r"   r#   r$   r%   r&   r'   r(   )r   r)   r*   @py_assert6@py_format8s        r   test_ci_sh_still_finds_py_filesr6   L   s   ooG99 0 90': :   	&                 1      3:    3:    ;      r   c                     t               } 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	)
uC   ci.sh find 블록이 -prune 가지치기 최적화를 사용한다.-pruneinz%(py1)s in %(py3)scmdpy1py3u[   ci.sh find 블록이 -prune 최적화를 사용하지 않음 — `-not -path` 회귀 위험
>assert %(py5)sr2   N)
r   r!   _call_reprcomparer&   r#   r$   r%   r"   r'   r(   )r<   @py_assert0@py_assert2@py_format4@py_format6s        r   "test_ci_sh_uses_prune_optimizationrF   T   s    

!C 8s?  8s                  	f    r   c                  `   t               } t        j                  }d} |||       }|s t        j                  d      dz   dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dt        j                         v st        j                  |       rt        j                  |       ndt        j                  |      dz  }t        t        j                  |            dx}x}}y)u/  ci.sh find 블록이 -type f 로 파일만 대상 (task-2549+1 박제).

    디렉토리 이름이 `*.py` 로 끝나는 경우 (예: 패키지 디렉토리 'pkg.py/')
    py_compile 단계에 디렉토리가 전달되어 실패하거나 무의미한 결과를
    만드는 회귀를 방지한다.
    	-type\s+fuv   ci.sh find 블록이 -type f 필터를 사용하지 않음 — 디렉토리명 *.py 매칭 회귀 위험 (task-2549+1)r/   r0   r<   r1   N)r   r0   r   r!   r"   r#   r$   r%   r&   r'   r(   )r<   r)   r*   r4   r5   s        r   test_ci_sh_uses_type_f_filterrI   \   s     
!C99 \ 9\3' '  	B                 "      $'    $'    (      r   dir_namec                 x   t               }t        j                  dt        j                  |       z   dz         }|j                  } ||      }|st        j                  d|  d      dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d	x}}y	)
uL   ci.sh가 vendor 디렉토리 6종 각각을 -path 패턴으로 매칭한다.z[\"']\*/z(?:/\*)?[\"']zvendor path '*/uh   ' 패턴이 ci.sh find 블록에 없음 — prune/exclude 누락 시 442,775 파일 스캔 회귀 위험zJ
>assert %(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.search
}(%(py3)s)
}patr<   r   r   r?   r2   N)r   r0   compileescaper   r!   r"   r#   r$   r%   r&   r'   r(   )rJ   r<   rL   r)   @py_assert4rE   s         r   test_ci_sh_prunes_vendor_dirrQ   j   s     
!C
**"))H--0DDC :: :c? ?   ( $G 	H                                r   c                    | dz  }|j                          |dz  j                          |dz  dz  j                  d       |dz  dz  j                  d       |dz  j                          |dz  dz  j                  d	       |d
z  dz  dz  j                  d       |d
z  dz  dz  dz  j                  d       |d
z  dz  dz  dz  j                  d       |d
z  dz  dz  dz  dz  j                  d       |dz  dz  j                  d       |dz  dz  dz  j                  d       |dz  dz  j                  d       |dz  dz  dz  dz  dz  j                  d       |dz  dz  dz  dz  dz  dz  j                  d       |dz  dz  dz  dz  dz  j                  d       |dz  dz  dz  j                  d       |dz  dz  dz  dz  j                  d       |d z  d!z  j                  d       |d z  d!z  d"z  j                  d       |d#z  d z  d$z  j                  d       |d#z  d z  d$z  d%z  j                  d       |d&z  d'z  j                  d       |d&z  d'z  d(z  j                  d       |S ))uH   가짜 workspace: 정상 .py 3개 + 6종 vendor 디렉토리 .py 다수.wssrcza.pyzprint('a')
zb.pyzprint('b')
testsz	test_x.pyzdef test_x(): pass
r   ztask-ATparentszx.pypass
ztask-Bdeepnestedzz.pyr   libzpkg.pyzsite.pytoolsappserverr   z	vendor.pyzboot.pyr   r   r   pkgz	bridge.pyfrontendxzy.pyr   hookszpre.py)mkdir
write_text)tmp_pathrS   s     r   fake_workspacerf   |   s    
DBHHJ %Z%Z&$$^4%Z&$$^4'\'\K++,BC ,!E)000>,!E)F2>>xH,!F*X5<<T<J,!F*X5>JJ
 '\E   .'\EH$00:'\I))(3 '\EH$v-5<<T<J'\EH$v-5COO '\EH$v-	9EEhO )^''%/66t6D)^''%/(:FFxP .5 '''5.5 ;.::8D*_~%+2242@*_~%+f4@@J &[7!!$!/&[7X%11(;Ir   	workspacec                 &   t               }t        j                  j                         }t	        |       |d<   t        j                  dd|gdd|      }|j                  j                  d      D cg c]  }|s|j                  d       c}S c c}w )uH  ci.sh 에서 추출한 find 명령을 그대로 bash 로 실행 — 재정의 X.

    ci.sh 의 `"$WORKSPACE"` 만 가짜 workspace 경로로 치환하고 나머지
    인자/순서는 ci.sh 와 동일하다. 따라서 ci.sh 가 -type f / prune /
    vendor 목록을 변경하면 본 헬퍼 행동도 자동 반영된다.
    	WORKSPACEbash-cTcapture_outputcheckenv    utf-8)
r   osenvironcopystr
subprocessrunstdoutsplitdecode)rg   cmd_templatero   resultps        r   _run_find_prunedr~      s{     )*L
**//
C9~C^^	|$	F (.}}':':5'AG!QAHHWGGGs   0B8Bc                     dt        |       dddg}t        j                  |dd      }|j                  j	                  d      D cg c]  }|s|j                  d       c}S c c}w )	uP   수정 前 동작 (prune 없음) — 비교 베이스라인용. ci.sh와 무관.findz-namez*.py-print0T)rm   rn   rp   rq   )ru   rv   rw   rx   ry   rz   )rg   r<   r|   r}   s       r   _run_find_unfilteredr      sV    3y>7FI
>C^^CDAF'-}}':':5'AG!QAHHWGGGs   A$A$c                  
   t               } | j                  }d} ||      }|st        j                  d|       dz   dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      t        j                  |      d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}}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}|| 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}}t        j                  }d} |||       }	|	s t        j                  d      dz   dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |	      dz  }
t        t        j                  |
            dx}x}}	t        j                  }d} |||       }	|	s t        j                  d      dz   dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |	      dz  }
t        t        j                  |
            dx}x}}	y)uQ   헬퍼가 ci.sh 의 실제 find 블록을 추출한다 — 재정의 X 어설션.r   u'   find 명령으로 시작하지 않음: zN
>assert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.startswith
}(%(py4)s)
}r<   r   r   r   py6Nz"$WORKSPACE"r9   r;   r=   u,   $WORKSPACE 변수가 추출 명령에 없음r@   r2   r   u   -print0 종단이 없음r8   u"   -prune 가 추출 명령에 없음rH   u#   -type f 가 추출 명령에 없음r/   r0   r1   r.   u   -name '*.py' 가 없음)r   
startswithr!   r"   r#   r$   r%   r&   r'   r(   rA   r0   r   )r<   r)   r*   @py_assert5@py_format7rB   rC   rD   rE   r4   r5   s              r   $test_find_block_extracted_from_ci_shr      s   

!C>>T&T>&!T!TT%LSG#TTTTTTT3TTT3TTT>TTT&TTT!TTTTTTRs"RRRsRRRRRRRRRsRRRsRRRR$RRRRRRR797779777977777777777777777777@8s?@@@8s@@@8@@@@@@s@@@s@@@@@@@@@@@99N\N9\3'N'NN)NNNNNNN2NNN2NNN9NNN\NNNNNN3NNN3NNN'NNNNNN99Q0Q90#6Q6QQ8QQQQQQQ2QQQ2QQQ9QQQ0QQQQQQ#QQQ#QQQ6QQQQQQr   c           	         t        |       }|D ]  }t        D ]  }d| 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:   prune 적용 시 6종 vendor 디렉토리 내부 .py 0건./not inz%(py1)s not in %(py3)sfr=   u    내부 파일 누설: r@   r2   N)r~   EXPECTED_PRUNE_NAMESr!   rA   r&   r#   r$   r%   r"   r'   r(   )rf   filesr   blockedrB   rC   rD   rE   s           r   2test_find_prunes_all_vendor_dirs_in_fake_workspacer      s    ^,E + 	Gwiq> >*  >  I "  v   *+  I *+    )21#6    	r   c                    t        |       }|D ch c]"  }t        j                  j                  ||       $ }}h d}|j                  } ||      }|st        j                  d| d|       dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            dx}}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t        |       d|       dz   d|
iz  }t        t        j                  |            dx}x}}	yc c}w )uW   prune 적용해도 정상 영역 .py 3개 (src/a, src/b, tests/test_x)는 수집된다.>   src/a.pysrc/b.pytests/test_x.pyu   정상 .py 누락 — 기대 u    ⊆ 실제 zL
>assert %(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.issubset
}(%(py3)s)
}expectedrelrM   N   ==z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr   r   r>   r?   r   u1   정상 .py 정확히 3개여야 하는데 실제 : 
>assert %(py8)spy8)r~   rr   pathrelpathissubsetr!   r"   r#   r$   r%   r&   r'   r(   r   rA   )rf   r   r   r   r   r)   rP   rE   rC   r   r   @py_format9s               r   "test_find_collects_normal_py_filesr      s"   ^,E7<
=!277??1n-
=C
=:H S! !   (zcUC                   !    !    "      u:  :?   :                                <CJ<r%Q      >s   'I8c                 	   t        |       }t        |       }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t        |       d      d	z   d
|iz  }t        t        j                  |            dx}x}}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t        |       d      d	z   d
|iz  }t        t        j                  |            dx}x}}t        |      }t        |      }d}	t        ||	      }
||
z  }d}||k\  }|s3t        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                  |      dt        j                         v st        j                  t              rt        j                  t              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                  |      t        j                  |	      t        j                  |
      t        j                  |      d
z  }t        j                  dt        |       dt        |             dz   d|iz  }t        t        j                  |            dx}x}x}	x}
x}x}}y)uB   prune 적용 후 카운트가 비적용 대비 4배 이상 감소.   )>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)sr   
unfilteredr   zunfiltered count too low: u    — fixture brokenr   r   Nr   )<=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} <= %(py6)sprunedzpruned count too high: u    — prune not effective      )z(%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} / %(py12)s
{%(py12)s = %(py4)s(%(py8)s
{%(py8)s = %(py5)s(%(py6)s)
}, %(py10)s)
}) >= %(py16)smax)
r   r>   r?   r   r2   r   r   py10py12py16zreduction ratio too low: u    → z
>assert %(py18)spy18)r~   r   r   r!   rA   r#   r$   r%   r&   r"   r'   r(   r   )rf   r   r   rC   r   rP   r   r   @py_assert7@py_assert9@py_assert11@py_assert13@py_assert15@py_assert14@py_format17@py_format19s                   r   &test_prune_significantly_reduces_countr      s(   n-F%n5Jz? b ?b    ?b                            !    %S_$55HI     v; ! ;!   ;!                                "#f+.FG     z? V a Sa0 ?00 A 0A5   0A                              !    !      "%    "%      &,    &,    "-    /0    1    56    $C
O#4E#f+G      r   c                    t        |       }|D ]  }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	)
uB   중첩된 venv (jaaz-app 사례) 도 확실히 가지치기된다.ztools/app/server/venv/r   r   r   r=   u   중첩 venv 파일 누설: r@   r2   N
r~   r!   rA   r&   r#   r$   r%   r"   r'   r(   rf   r   r   rB   rC   rD   rE   s          r   test_nested_venv_prunedr      s    ^,E 
' 	
'q0 	
 	
'q 	
 	
 		 ( 	
 	
	6	
 	
  01 	
 	
 		 01 	
 	
  *!-	
 	
 	
 	
 	

r   c                    t        |       }|D ]  }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:   중첩된 node_modules (frontend/) 도 가지치기된다.zfrontend/node_modules/r   r   r   r=   u#   중첩 node_modules 파일 누설: r@   r2   Nr   r   s          r   test_nested_node_modules_prunedr     s    ^,E 
' 	
'q0 	
 	
'q 	
 	
 		 ( 	
 	
	6	
 	
  01 	
 	
 		 01 	
 	
  2!5	
 	
 	
 	
 	

r   c                    | dz  }|j                          |dz  j                  d       d}||z  j                  d       t        |      }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t        |       d|       dz   d|iz  }t        t	        j                  |            dx}x}}|D 	ch c]!  }	t        j                  j                  |	      # }
}	d|h}|
|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c c}	w )uW   파일명에 줄바꿈이 있어도 null-delimited 파싱으로 정확히 분리된다.rS   z	normal.pyrX   zweird
name.pyr   r   r   r   r   r   u>   줄바꿈 포함 파일명 분리 실패: 기대 2개, 실제 r   r   r   N)z%(py0)s == %(py3)snames)r   r?   u   파일명 깨짐: r@   r2   )rc   rd   r~   r   r!   rA   r#   r$   r%   r&   r"   r'   r(   rr   r   basename)re   rS   
weird_namer   rC   r   rP   r   r   r   r   r)   rD   rE   s                 r    test_filenames_with_newline_safer     s   	DBHHJ+!!(+!J*_  *R Eu:  :?   :                                IUTVW\V]^     +00QRWWa 0E0 *- 5--  5-              .    UG$     1s   &I/c           
         | dz  }|j                          |dz  j                          |dz  dz  j                  d       |dz  j                          |dz  j                  d       t        |      }|D ]
  }t        j                  } ||      }|j
                  } |       }|st        j                  d|       d	z   d
t        j                         v st        j                  t              rt        j                  t              nd
t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            dx}x}x}}|j                  }d}	 ||	      }
|
 }|st        j                  d|       dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      t        j                  |
      dz  }t        t        j                  |            dx}x}	x}
}|j                  }d}	 ||	      }
|
 }|st        j                  d|       dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |	      t        j                  |
      dz  }t        t        j                  |            dx}x}	x}
} 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t        |       d|       dz   d|iz  }t        t        j                  |            dx}x}}
t        j                  }|d   }	 ||	      }
|
j"                  }d}||k(  }|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                  |
      t        j                  |      t        j                  |      dz  }dd |iz  }t        t        j                  |            dx}x}	x}
x}x}}y)!u\  디렉토리 이름이 `*.py` 인 경우 ci.sh find 가 수집하지 않는다.

    `-type f` 없이 `-name "*.py"` 만 사용하면 디렉토리 이름이 `pkg.py/` 같이
    `.py` 로 끝나는 경우도 매칭되어 py_compile 에 디렉토리가 전달된다.
    task-2549+1 박제: 디렉토리는 결코 수집되지 않아야 한다.
    rS   zfake_pkg.pyz
inside.txtznot python
zweird_dir.pyzreal_module.pyzprint('real')
u5   디렉토리가 수집됨 (`-type f` 누락 회귀): z|
>assert %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.Path
}(%(py3)s)
}.is_file
}()
}pathlibr   )r   r   r?   r2   r3   py9Nu*   디렉토리 'fake_pkg.py' 가 수집됨: zP
>assert not %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.endswith
}(%(py4)s)
}r   u+   디렉토리 'weird_dir.py' 가 수집됨: r   r   r   r   r   r   u8   실제 *.py 파일 1개 기대 (real_module.py), 실제 r   r   r   r   )ze%(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.Path
}(%(py4)s)
}.name
} == %(py11)s)r   r   r   r   r   py11zassert %(py13)spy13)rc   rd   r~   r   Pathis_filer!   r"   r#   r$   r%   r&   r'   r(   endswithr   rA   name)re   rS   r   r   r)   rP   r4   @py_assert8@py_format10r*   r   r   r5   rC   r   r   @py_assert10r   @py_format12@py_format14s                       r   ,test_directory_named_dot_py_is_not_collectedr   $  s    
DBHHJ - -,&22>B.!
&&'89R E  	
|| 	
|A 	
&& 	
&( 	
( 	
  DA3G	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 ' 	
 	
 		 ) 	
 	
 	
 	
 	
 	
 :: 	
m 	
:m, 	
,, 	
, 	
  9<	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 , 	
 	
 		 - 	
 	
 	
 	
 	
 	
 :: 	
n 	
:n- 	
-- 	
- 	
  :!=	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
 		 - 	
 	
 		 . 	
 	
 	
 	
 	
 	
	
 u:  :?   :                                C3u:,bQVPWX     <<:a:<!:!&&:*::&*:::::&*:::::::7:::7:::<::::::!:::&:::*:::::::::r   c                 4   | dz  }|j                  d       t        |      }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z  }|dz  dz  j                  d       |dz  dz  dz  j                  d       |dz  j                  d       t        j                  j                         }t        |      |d<   t!        j"                  dd|gdd|      }	|	j$                  j'                  d      D 
cg c]  }
|
s|
j)                  d       }}
d |D        }t+        |      }|st        j                  d      d z   d!t        j                         v st        j                  t*              rt        j                  t*              nd!t        j                  |      t        j                  |      d"z  }t        t        j                  |            d
x}}y
c c}
w )#u	  ci.sh find 블록이 바뀌면 헬퍼가 자동 반영한다 (재정의 X 박제).

    ci.sh 가 새 vendor 디렉토리를 prune 에 추가하거나 -type f 를 제거하면
    `_run_find_pruned` 의 출력도 자동으로 그 변경을 따라가야 한다.
    z
fake_ci.shz#!/usr/bin/env bash
PY_FILES=()
while IFS= read -r -d '' f; do
    PY_FILES+=("$f")
done < <(find "$WORKSPACE" -type f -name "*.py" -print0 2>/dev/null)
z-type fr9   r;   	extractedr=   zassert %(py5)sr2   Nr8   r   r   u^   가짜 ci.sh 에 -prune 없는데 추출 결과에 포함됨 — 추출이 정적이지 않음r@   rS   r   leakTrV   should_leak.pyrX   zreal.pyri   rj   rk   rl   rp   rq   c              3   $   K   | ]  }d |v  
 yw)r   N ).0r   s     r   	<genexpr>z6test_ci_sh_change_is_auto_reflected.<locals>.<genexpr>q  s     51$5s   u   가짜 ci.sh (prune 없음) 실행 결과에 누설 파일이 안 보임 — 추출/실행 경로가 ci.sh 와 분리되어 있음z.
>assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyr   )rd   r   r!   rA   r&   r#   r$   r%   r'   r(   r"   rc   rr   rs   rt   ru   rv   rw   rx   ry   rz   r   )re   fake_cir   rB   rC   rD   rE   rS   ro   r|   r}   leakedr)   r*   r+   s                  r   #test_ci_sh_change_is_auto_reflectedr   J  s    %G	Q &g.I!9	!!!!9	!!!9!!!!!!	!!!	!!!!!!! 89$  89          %    %    	i    
 
DB,&&t&4,"22>>xH)^)
**//
C2wC^^	y!	F *0)<)<U)CIAqahhwIFI5f5 355 5  	@             6    6      Js   2L:L)-__doc__builtinsr#   _pytest.assertion.rewrite	assertionrewriter!   rr   r   r0   rv   pytestr   __file__resolverW   ROOTr   rN   DOTALLr
   ru   r   r   r,   r6   rF   rI   markparametrizerQ   fixturerf   listr~   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      sY     	  	   w||H%%'//2y7" NII 6; +gll +s +  9
 %9:	3 	 ;	" . .bH Hc H(HGLL HT#Y H	R


.#;L*r   