
    8i"                        d Z ddlZddlmc mZ ddlZddlm	Z	 ddl
Z
 e	d      Zej                  j                  d eedz               ddlZe
j"                  d        Ze
j"                  d        Zdde	d	efd
Zd Zd Zd Zd Zd Zd Zy)u=   ast_dependency_map.py 단위 테스트 (task-2337 Phase 1.4).    N)Pathz/home/jay/workspacescriptsc                 ^    |dz  }|j                          | j                  t        d|       |S )Ncache	CACHE_DIR)mkdirsetattradm)monkeypatchtmp_pathr   s      4/home/jay/workspace/tests/test_ast_dependency_map.pyisolated_cacher      s,    wE	KKM[%0L    c                 0    | dz  }|j                          |S )Nproj)r   )r   roots     r   tiny_projectr      s    fDJJLKr   pcontentc                 `    | j                   j                  dd       | j                  |       y )NT)parentsexist_ok)parentr   
write_text)r   r   s     r   _writer   "   s"    HHNN4$N/LLr   c                    | dz  }t        |dz  d       t        |dz  d       t        |dz  dz  dz  d	       t        |d
z  dz  d       t        |dz  dz  dz  d       t        |dz  dz  dz  d       t        |dz  dz  dz  d       t        |dz  dz  dz  d       t        j                  |      }|D ch c]  }|j                   }}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}}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}}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        |      }d-}	||	k(  }
|
st	        j
                  d.|
fd/||	f      d0t        j                         v st	        j                  t              rt	        j                  t              nd0d1t        j                         v st	        j                  |      rt	        j                  |      nd1t	        j                  |      t	        j                  |	      d2z  }t	        j                  d3t        |       d4|       d5z   d6|iz  }t        t	        j                  |            d#x}x}
}	y#c c}w )7u\   EXCLUDE_DIRS 목록의 디렉토리는 _iter_py_files() 결과에서 제외되어야 한다.r   main.pyz# mainzfoo.pyz# foo
.worktreessubzexcluded.pyz
# excluded__pycache__z	cached.pyz# cachedz.venvlibzsite.pyz# sitez.githookszpre-commit.pyz# pre-commitnode_modulespkgzindex.pyz# indexz.codegraph-venvzx.pyz# xin)z%(py1)s in %(py3)sresult_namespy1py3u   main.py 가 결과에 없음
>assert %(py5)spy5Nu   foo.py 가 결과에 없음not inz%(py1)s not in %(py3)su/   .worktrees 하위 파일이 결과에 포함됨u0   __pycache__ 하위 파일이 결과에 포함됨u*   .venv 하위 파일이 결과에 포함됨u)   .git 하위 파일이 결과에 포함됨u1   node_modules 하위 파일이 결과에 포함됨u4   .codegraph-venv 하위 파일이 결과에 포함됨   ==z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenresultpy0r)   r*   py6u   예상 2개, 실제 u   개: 
>assert %(py8)spy8)r   r
   _iter_py_filesname
@pytest_ar_call_reprcompare	_saferepr@py_builtinslocals_should_repr_global_name_format_assertmsgAssertionError_format_explanationr4   )r   r   r5   r   r'   @py_assert0@py_assert2@py_format4@py_format6@py_assert5@py_assert4@py_format7@py_format9s                r    test_iter_py_files_excludes_dirsrN   ,   s   fD 4)X&
4(?G$ 4,&6E
4-+-z:
4'>E!I-x8
4&=7"_4nE
4. 5(:5yA
4##e+f4e<%F$*+qAFF+L+ D9$DDD9DDD9DDDDDDDDDDDDD&DDDDDDDB8|#BBB8|BBB8BBBBBB|BBB|BBBB%BBBBBBB _=,___=___=_____________._______^;l*^^^;l^^^;^^^^^^l^^^l^^^^,^^^^^^^V9L(VVV9LVVV9VVVVVVLVVVLVVVV*VVVVVVV[?,.[[[?,[[[?[[[[[[,[[[,[[[[0[[[[[[[^:\)^^^:\^^^:^^^^^^\^^^\^^^^+^^^^^^^]6%]]]6]]]6]]]]]]]]]]]]]']]]]]]] v;N!N;!NNN;!NNNNNN3NNN3NNNNNNvNNNvNNN;NNN!NNN3CK=fXNNNNNNNN ,s   8_c                    |}t        |dz  d       t        |dz  d       t        j                  |      }t        | j	                  d            }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                  |      }
|j                  }|j                   } |       }t#        |      }|
j                  }|j                   } |       }t#        |      }||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                  |      t        j                  |      t        j                  |      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      dz   d|iz  }t        t        j                  |            dx}x}x}x}x}x}x}x}}|j                  D ]  }|j                  |   }|
j                  |   }||k(  }|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 |j$                  j!                         D        }t#        |      }d  |
j$                  j!                         D        }t#        |      }||k(  }|s<t        j                  d|fd!||f      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                  t"              rt        j                  t"              ndt        j                  |      t        j                  |      d"z  }t        j                  d#      d$z   d%|iz  }t        t        j                  |            dx}x}x}x}}|j$                  D ]  }|j$                  |   }|
j$                  |   }||k(  }|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}} |j&                  }|j                   } |       }t#        |      }|
j&                  }|j                   } |       }t#        |      }||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                  |      t        j                  |      t        j                  |      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(      dz   d|iz  }t        t        j                  |            dx}x}x}x}x}x}x}x}}|j&                  D ]  }|j&                  |   }|
j&                  |   }||k(  }|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}} y)*uK   캐시 miss → 저장 → hit 후 동일 그래프 반환을 검증한다.zalpha.pyzimport beta
zbeta.pyz# beta module
*.pkl   r1   r3   r4   cache_filesr6   u&   캐시 파일이 1개여야 하는데 u   개r9   r:   N)a  %(py9)s
{%(py9)s = %(py0)s(%(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.module_to_file
}.keys
}()
})
} == %(py20)s
{%(py20)s = %(py11)s(%(py18)s
{%(py18)s = %(py16)s
{%(py16)s = %(py14)s
{%(py14)s = %(py12)s.module_to_file
}.keys
}()
})
}setg1g2)r7   r)   r*   r,   py7py9py11py12py14py16py18py20u   module_to_file 키 불일치z
>assert %(py22)spy22)z%(py1)s == %(py4)s)r)   py4zmodule_to_file[u   ] 값 불일치z
>assert %(py6)sr8   c              3   2   K   | ]  }t        |        y wNstr.0ks     r   	<genexpr>z'test_cache_roundtrip.<locals>.<genexpr>n        6!s1v6   c              3   2   K   | ]  }t        |        y wra   rb   rd   s     r   rg   z'test_cache_roundtrip.<locals>.<genexpr>o   rh   ri   )zP%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py10)s
{%(py10)s = %(py6)s(%(py8)s)
})r7   py2r_   r8   r:   py10u   file_imports 키 불일치z
>assert %(py12)srY   zfile_imports[)a  %(py9)s
{%(py9)s = %(py0)s(%(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.module_importers
}.keys
}()
})
} == %(py20)s
{%(py20)s = %(py11)s(%(py18)s
{%(py18)s = %(py16)s
{%(py16)s = %(py14)s
{%(py14)s = %(py12)s.module_importers
}.keys
}()
})
}u   module_importers 키 불일치zmodule_importers[)r   r
   DependencyGraphlistglobr4   r=   r>   r@   rA   rB   r?   rC   rD   rE   module_to_filekeysrS   file_importsmodule_importers)r   r   r   rT   rR   rG   rJ   rK   rL   rM   rU   @py_assert6@py_assert8@py_assert13@py_assert15@py_assert17@py_assert19@py_assert10@py_format21@py_format23rf   rF   @py_assert3@py_format5@py_assert1@py_assert7@py_assert9@py_format11@py_format13s                                r   test_cache_roundtripr   T   sl	   D 4*o.
4)./ 
		T	"B ~**734K{`q`q ```q``````3```3``````{```{``````q```$J3{K[J\\_"```````` 
		T	"B    ' %% '%' '3'( '0A0A '0A0F0F '0F0H 'C0H,I '(,II ' '&&'(,I ' ' &' '&&  ' '&Y  ' ' &' '&&  ' '&Y  ' '&Y ! ' '&Y & ' '&Y ( ' '&Y ) ' ' &' '&& -0 ' '&Y -0 ' ' &' '&& 13 ' '&Y 13 ' '&Y 1B ' '&Y 1G ' '&Y 1I ' '&Y -J ' '&&&' ' '&&' ' ' ' 1  # 	1r'8'8'; 	1#';; 	100	1#'; 	1 	1'0y $ 	1 	1'0y (< 	1 	100oaS0	1 	1 	100	1 	1 	11
 7r3356 U366 U6r3356U66U667 U UCTCTU66U UNTfU U<T<T  U UKT9  U UKT9 7 U UKT9 7 U UNTfU U<T<T3U UKT93U UKT96U UKT96U UCTCT8TU U UATATU U U__ /q! 	/R__Q%7 	/!%77 	/..	/!%7 	/ 	/%.Y " 	/ 	/%.Y &8 	/ 	/..mA3o.	/ 	/ 	/..	/ 	/ 	//
 "" )"'' )') )3)* )"2E2E )2E2J2J )2J2L )c2L.M )*.MM ) )(()*.M ) )"(&) )((  ) )(y  ) )"(&) )((  ) )(y  ) )(y # ) )(y ( ) )(y * ) )(y + ) )"(&) )(( /2 ) )(y /2 ) )"(&) )(( 35 ) )(y 35 ) )(y 3F ) )(y 3K ) )(y 3M ) )(y /N ) )((() ) )(() ) ) )   3""1% 	3)<)<Q)? 	3%)?? 	3!2!2	3%)? 	3 	3)2 & 	3 	3)2 *@ 	3 	3!2!2s/2	3 	3 	322	3 	3 	33r   c                 (   |}t        |dz  d       t        j                  |      }d}|j                  }||v }|st	        j
                  d|fd||f      t	        j                  |      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}x}}d}|j                  }||v}|st	        j
                  d|fd||f      t	        j                  |      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}x}}t        | j                  d            }	t        |	      }d}
||
k(  }|st	        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  }dd|iz  }t        t	        j                  |            dx}x}}
t        |dz  d       t        j                  |      }d}|j                  }||v }|st	        j
                  d|fd||f      t	        j                  |      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}x}}d}|j                  }||v }|st	        j
                  d|fd||f      t	        j                  |      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}x}}t        | j                  d            }t        |      }d}
||
k\  }|st	        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  }dd|iz  }t        t	        j                  |            dx}x}}
y)!ui   새 파일 추가 후 mtime 변경 시 캐시가 무효화되고 새 그래프에 파일이 포함된다.za.pyz# module a
ar%   )z6%(py1)s in %(py5)s
{%(py5)s = %(py3)s.module_to_file
}rT   r)   r*   r,   u   a 모듈이 g1에 없음z
>assert %(py7)srV   Nbr-   )z:%(py1)s not in %(py5)s
{%(py5)s = %(py3)s.module_to_file
}u*   b 모듈이 이미 g1에 있으면 안 됨rP   rQ   r1   r3   r4   cache_files_beforer6   assert %(py8)sr:   zb.pyz# module b
rU   u   a 모듈이 g2에 없음u@   b 모듈이 g2에 포함되어야 함 (cache miss 후 재빌드))>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)scache_files_after)r   r
   rm   rp   r=   r>   r?   r@   rA   rB   rC   rD   rE   rn   ro   r4   )r   r   r   rT   rF   rK   rG   rI   @py_format8r   rJ   rL   rM   rU   r   s                  r   &test_cache_invalidates_on_mtime_changer      s   D 4&=.) 
		T	"B?"##?3##???3#???3??????"???"???#???%????????Ub''U3''UUU3'UUU3UUUUUUbUUUbUUU'UUU)UUUUUUUUn11':;!"'a'"a''''"a''''''3'''3''''''!'''!'''"'''a''''''' 4&=.) 
		T	"B?"##?3##???3#???3??????"???"???#???%????????g"##g3##ggg3#ggg3gggggg"ggg"ggg#ggg%gggggggg ^009: !&Q&!Q&&&&!Q&&&&&&3&&&3&&&&&& &&& &&&!&&&Q&&&&&&&r   c                 n   |}t        |dz  dz  d       t        |dz  dz  d       t        |dz  dz  dz  dz  d       t        j                  |dg      }t        |      }d}||k(  }|st	        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  }dd|iz  }t        t	        j                  |            dx}x}}|d   d   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)uX   .worktrees 하위 파일은 analyze() direct_importers에 포함되지 않아야 한다.r$   r   zimport data
zdata.pyz# data module
r   r   rQ   r1   r3   r4   resultsr6   r   r:   Nr   blast_radiusdirect_importersr-   r/   path_strr(   u4   .worktrees 경로가 direct_importers에 포함됨: r+   r,   )r   r
   analyzer4   r=   r>   r@   rA   rB   r?   rD   rE   rC   )r   r   r   r   rG   rJ   rK   rL   rM   r   r   rF   rH   rI   s                 r   test_analyze_excludes_worktreesr      s   D 4%<)#_5
4%<)#%67 4%<,&.:OLkk$,Gw<1<1<133ww<1qz.12DE % N 	N|8+ 	N<M<M	N|8 	N 	NDMI  	N 	NGMv	N 	N5M5M $, 	N 	NDMI $, 	N 	N<M<MB8*M	N 	N 	N:M:M	N 	NNr   c                 
   |}t        |dz  d       t        |dz  d       t        j                  |dgd      }t        |      }d}||k(  }|st	        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  }dd|iz  }t        t	        j                  |            dx}x}}|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 
cg c]  }
|
j                  d      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}}|	D ]  }
|
j                  dd      }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}}|d   }|j                   } |       }|syt	        j                  d |
       d!z   t	        j                  |      t	        j                  |      t	        j                  |      d"z  }t        t	        j                  |            dx}x}} yc c}
w )#uW   캐시 hit 후 lazy AST를 사용해 함수 호출자를 올바르게 찾아야 한다.zlib.pyzdef hello():
    pass
	caller.pyzfrom lib import hello
hello()
hello)function_namerQ   r1   r3   r4   r   r6   r   r:   Nr   r   callers)>)z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)su9   callers가 비어 있음 — hello() 호출 감지 실패r9   :c              3   $   K   | ]  }d |v  
 yw)r   N )re   fs     r   rg   z5test_get_function_callers_lazy_ast.<locals>.<genexpr>   s     6A{a6s   u!   caller.py 가 callers에 없음: z.
>assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}any)r7   rk   r_   r0   partsu    줄번호 없는 caller 항목: u   줄번호가 숫자가 아님: zD
>assert %(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.isdigit
}()
}r   )r   r
   r   r4   r=   r>   r@   rA   rB   r?   rD   rE   rC   splitr   rsplitisdigit)r   r   r   r   rG   rJ   rK   rL   rM   r   ccaller_filesr   r}   r~   r   rF   rI   s                     r   "test_get_function_callers_lazy_astr      so   D
4(?67
4+ABkk$
'BGw<1<1<133ww<1aj(3Gw<X!X<!XXX<!XXXXXX3XXX3XXXXXXwXXXwXXX<XXX!XXXXXXXXXXX .55AGGCLO5L566 6366 66 6$5$5
+G956 6/5v6 655  6 6,5I  6 6,5I 7 6 6,5I 7 6 6 6"5"56 6  Ia 5zFQFzQFFFzQFFFFFFsFFFsFFFFFF5FFF5FFFzFFFQFFF"B1# FFFFFFFFQxHxH!H!HH%DQC#HHHHxHHHHHH!HHHHHHI 6s    Uc                    |}t        |dz  d       t        j                  |g       }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   빈 affected_files 리스트로 analyze() 호출 시 빈 리스트 반환, 예외 없음.zsomething.pyz# placeholder
r1   )z%(py0)s == %(py3)sr   )r7   r*   u4   빈 입력 시 빈 리스트 반환 예상, 실제: r+   r,   N)r   r
   r   r=   r>   r@   rA   rB   r?   rC   rD   rE   )r   r   r   r   rG   r   rH   rI   s           r   test_analyze_empty_filesr      s    D
4. "34kk$#GZ7b=ZZZ7bZZZZZZ7ZZZ7ZZZbZZZPQXPYZZZZZZZr   ) )__doc__builtinsr@   _pytest.assertion.rewrite	assertionrewriter=   syspathlibr   pytest	WORKSPACEpathinsertrc   ast_dependency_mapr
   fixturer   r   r   rN   r   r   r   r   r   r   r   r   <module>r      s    C   
   &'	 3y9,- .      d S  OP%3Z'DN6I<[r   