
    =i                        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ddlmZ ddlZ e ee      j#                         j$                  j$                        Zee
j(                  vre
j(                  j+                  de       ddlmZmZmZmZmZ  ee      j$                  dz  Z ee      j$                  j$                  dz  Z G d d      Z G d	 d
      Z G d d      Z  G d d      Z! G d d      Z" G d d      Z#y)z
Tests for impact_analyzer.py
    N)Path)analyzebuild_dependency_chainextract_endpointsextract_functionsextract_importsfixtureszimpact_analyzer.pyc                   .    e Zd ZdZd Zd Zd Zd Zd Zy)TestScenariosu   5개 핵심 시나리오 검증c                    t        t        dz        }t        |gt        t                    }d}|d   }||v }|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)uI   시나리오 1: sample_server.py 분석 시 /api/wiki/refine/start 포함sample_server.py	workspace/api/wiki/refine/startaffected_endpointsinz%(py1)s in %(py4)spy1py4z<Expected /api/wiki/refine/start in affected_endpoints, got: 
>assert %(py6)spy6N	strFIXTURES_DIRr   
@pytest_ar_call_reprcompare	_saferepr_format_assertmsgAssertionError_format_explanation)selfserver_fileresult@py_assert0@py_assert3@py_assert2@py_format5@py_format7s           A/home/jay/workspace/teams/shared/qc/tests/test_impact_analyzer.py#test_server_file_extracts_endpointsz1TestScenarios.test_server_file_extracts_endpoints'   s    ,);;<+#l2CD %	i(./C(D	i$(DD	iWhWh	i$(D	i 	i_h_h %	i 	i_h_h )E	i 	iWhWhI&QeJfIgh	i 	i 	iUhUh	i 	i 	i    c                    t        t        dz        }t        |gt        t                    }d}|d   }||v }|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)u?   시나리오 2: sample_module.py 분석 시 extract_data 포함sample_module.pyr   extract_dataaffected_functionsr   r   r   z2Expected extract_data in affected_functions, got: r   r   Nr   )r#   module_filer%   r&   r'   r(   r)   r*   s           r+   #test_module_file_extracts_functionsz1TestScenarios.test_module_file_extracts_functions0   s    ,);;<+#l2CD 	_$%9:	_::	_M^M^	_:	_ 	_U^U^ 	_ 	_U^U^ ;	_ 	_M^M^?G[@\?]^	_ 	_ 	_K^K^	_ 	_ 	_r-   c                 8   t        g t        t                    }|d   }g }||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d	   }g }||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d
   }g }||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d   }g }||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d   }i }||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)uG   시나리오 3: 빈 파일 목록 → 빈 결과 반환 (에러 없음)r   changed_files==)z%(py1)s == %(py4)sr   assert %(py6)sr   Nr1   r   affected_importsdependency_chain)r   r   r   r   r   r   r!   r"   )r#   r%   r&   r'   r(   r)   r*   s          r+   test_empty_files_gracefulz'TestScenarios.test_empty_files_graceful9   s   s<'89o&,",&",,,,&",,,&,,,",,,,,,,*+1r1+r1111+r111+111r1111111*+1r1+r1111+r111+111r1111111()/R/)R////)R///)///R///////()/R/)R////)R///)///R///////r-   c                    t        dgt        t                    }t        |t              }|s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dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            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  }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  }dd|iz  }t        t        j                  |            dx}}y)uC   시나리오 4: 존재하지 않는 파일 → 에러 없이 무시z/nonexistent/path/fake_file.pyr   5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancer%   dictpy0r   py2r   Nr1   r   z%(py1)s in %(py3)sr   py3assert %(py5)spy5r   )r   r   r   r>   r?   @py_builtinslocalsr   _should_repr_global_namer   r!   r"   r   )r#   r%   r'   r)   r&   r(   @py_format4@py_format6s           r+   test_nonexistent_file_ignoredz+TestScenarios.test_nonexistent_file_ignoredC   s\   -.,'

 &$''''''''z'''z''''''&'''&''''''$'''$''''''''''#-#v----#v---#------v---v-------#-#v----#v---#------v---v-------r-   c                 z   t        t        dz        t        t        dz        t        t        dz        g}t        j                         }t        |t        t                     t        j                         |z
  }d}||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d      dz   d|iz  }t        t	        j                  |            dx}}y)u#   시나리오 5: 30초 이내 완료r   r/   sample_utils.pyr      )<)z%(py0)s < %(py3)selapsedrA   rE   zExecution took z.2fzs, expected < 30sz
>assert %(py5)srG   N)r   r   timer   r   r   rH   rI   rJ   r   r    r!   r"   )r#   filesstartrR   r(   @py_assert1rK   rL   s           r+    test_execution_within_30_secondsz.TestScenarios.test_execution_within_30_secondsN   s     112112001
 		\!23))+%Mw|MMMwMMMMMMwMMMwMMMMMMwsm;LMMMMMMMr-   N)	__name__
__module____qualname____doc__r,   r3   r;   rM   rX    r-   r+   r   r   $   s!    )i_0	.Nr-   r   c                       e Zd Zd Zd Zd Zy)TestExtractFunctionsFromASTc                    t        t        t        dz              }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  }dd|iz  }t        t        j                  |            d x}}y )
NrO   helper_funcr   rC   r%   rD   rF   rG   format_outputr   r   r   r   r   r   rH   rI   rJ   r!   r"   r#   r%   r&   r(   rK   rL   s         r+   !test_extracts_top_level_functionsz=TestExtractFunctionsFromAST.test_extracts_top_level_functionsd   s    "3|6G'G#HI&}&&&&}&&&}&&&&&&&&&&&&&&&&(&((((&(((((((((&(((&(((((((r-   c                 b   t        t        t        dz              }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  }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  }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  }dd|iz  }t        t        j                  |            d x}}y )Nr/   r0   r   rC   r%   rD   rF   rG   process_dataDataProcessorzDataProcessor.runrc   rd   s         r+   test_extracts_class_methodsz7TestExtractFunctionsFromAST.test_extracts_class_methodsi   s~   "3|6H'H#IJ'~''''~'''~'''''''''''''''''~''''~'''~''''''''''''''''(&((((&(((((((((&(((&(((((((","f,,,,"f,,,",,,,,,f,,,f,,,,,,,r-   c                 f   t        d      }g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y N/nonexistent/file.pyr6   z%(py0)s == %(py3)sr%   rS   rF   rG   )	r   r   r   rH   rI   rJ   r   r!   r"   r#   r%   r(   rW   rK   rL   s         r+   #test_nonexistent_file_returns_emptyz?TestExtractFunctionsFromAST.test_nonexistent_file_returns_emptyp   e    "#9:v|vvvr-   N)rY   rZ   r[   re   ri   ro   r]   r-   r+   r_   r_   b   s    )
-r-   r_   c                       e Zd Zd Zd Zd Zy)TestExtractImportsFromASTc                    t        t        t        dz              }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 )	Nr/   sample_utilsr   rC   r%   rD   rF   rG   r   r   r   r   r   r   rH   rI   rJ   r!   r"   rd   s         r+   test_extracts_from_importsz4TestExtractImportsFromAST.test_extracts_from_importsw   sp     \4F%F!GH'~''''~'''~''''''''''''''''r-   c                    t        t        t        dz              }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  }dd|iz  }t        t        j                  |            d x}}y )
Nsample_importer.pysample_moduler   rC   r%   rD   rF   rG   rt   ru   rd   s         r+   test_extracts_plain_importsz5TestExtractImportsFromAST.test_extracts_plain_imports{   s     \4H%H!IJ(&((((&(((((((((&(((&((((((('~''''~'''~''''''''''''''''r-   c                 f   t        d      }g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y rk   )	r   r   r   rH   rI   rJ   r   r!   r"   rn   s         r+   ro   z=TestExtractImportsFromAST.test_nonexistent_file_returns_empty   se     !78v|vvvr-   N)rY   rZ   r[   rv   rz   ro   r]   r-   r+   rr   rr   u   s    ((
r-   rr   c                   $    e Zd Zd Zd Zd Zd Zy)TestExtractEndpointsc                    t        t        t        dz              }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  }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  }dd|iz  }t        t        j                  |            d x}}y )Nr   r   r   rC   r%   rD   rF   rG   z/api/wiki/refine/resumez/api/status)r   r   r   r   r   r   rH   rI   rJ   r!   r"   rd   s         r+   'test_extracts_path_comparison_endpointsz<TestExtractEndpoints.test_extracts_path_comparison_endpoints   s(   "3|6H'H#IJ'1'61111'6111'111111611161111111(2(F2222(F222(222222F222F2222222&}&&&&}&&&}&&&&&&&&&&&&&&&&r-   c                 Z   t        t        t        dz              }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 )
Nr      )>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)slenr%   )rA   r   rE   r   zassert %(py8)spy8)r   r   r   r   r   r   rH   rI   rJ   r   r!   r"   )r#   r%   r(   @py_assert5@py_assert4r*   @py_format9s          r+   !test_extracts_all_three_endpointsz6TestExtractEndpoints.test_extracts_all_three_endpoints   s    "3|6H'H#IJ6{a{a{ass66{ar-   c                 f   t        d      }g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y rk   )	r   r   r   rH   rI   rJ   r   r!   r"   rn   s         r+   ro   z8TestExtractEndpoints.test_nonexistent_file_returns_empty   rp   r-   c                    t        t        t        dz              }g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y )NrO   r6   rm   r%   rS   rF   rG   )r   r   r   r   r   rH   rI   rJ   r   r!   r"   rn   s         r+   )test_file_without_endpoints_returns_emptyz>TestExtractEndpoints.test_file_without_endpoints_returns_empty   so    "3|6G'G#HIv|vvvr-   N)rY   rZ   r[   r   r   ro   r   r]   r-   r+   r}   r}      s    ' r-   r}   c                       e Zd Zd Zd Zd Zy)TestBuildDependencyChainc                   	 t        t        dz        }t        |gt        t                    }||v }|st        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  }t        t        j                  |            d }||   }|D cg c]!  }t        j                  j                  |      # c}		f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 )Nr/   r   r   )z%(py0)s in %(py2)sr2   chain)rA   rB   zassert %(py4)sr   c              3   &   K   | ]  }|v  
 y w)Nr]   ).0nameimporter_namess     r+   	<genexpr>zMTestBuildDependencyChain.test_finds_files_importing_module.<locals>.<genexpr>   s      
'+DN"
s   )r   rx   z"Expected importers in chain, got: z.
>assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyrA   rB   r   )r   r   r   r   r   rH   rI   rJ   r   r!   r"   ospathbasenamer   r    )
r#   r2   r   rW   @py_format3r)   	importerspr'   r   s
            @r+   !test_finds_files_importing_modulez:TestBuildDependencyChain.test_finds_files_importing_module   s   ,);;<&}L@QRe####{e######{###{######e###e#######+&	7@A!"''**1-A
/Y
 	As 
 
 	A 
 	A/@/@//?@	A 	A:@&	A 	A(@(@  	A 	A7@y  	A 	A7@y
 	A 	A7@y
 	A 	A 	A-@-@	A 	A Bs   &G:c                    t        g t        t                    }i }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y )Nr   r6   rm   r   rS   rF   rG   )r   r   r   r   r   rH   rI   rJ   r   r!   r"   )r#   r   r(   rW   rK   rL   s         r+   $test_empty_files_returns_empty_chainz=TestBuildDependencyChain.test_empty_files_returns_empty_chain   sk    &rS5FGu{uuur-   c                 z   t        dgt        t                    }t        |t              }|s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dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d }y )Nrl   r   r=   r>   r   r?   r@   )r   r   r   r>   r?   rH   rI   r   rJ   r   r!   r"   )r#   r   r'   r)   s       r+   (test_nonexistent_file_returns_empty_listzATestBuildDependencyChain.test_nonexistent_file_returns_empty_list   s    &(>'?3|K\]%&&&&&&&&z&&&z&&&&&&%&&&%&&&&&&&&&&&&&&&&&&&r-   N)rY   rZ   r[   r   r   r   r]   r-   r+   r   r      s    	A'r-   r   c                   (    e Zd ZdZdefdZdefdZy)TestCLIOutputJSONu!   CLI 실행 시 JSON 파일 출력tmp_pathc                    |dz  }t        t        dz        }t        j                  t        j
                  t        t              d|dt        |      dt        t              gddd      }|j                  }d	}||k(  }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d|j                         dz   d|iz  }	t!        t        j"                  |	            d x}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}}t'        |      5 }t)        j*                  |      }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  }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  }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  }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  }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  }dd|iz  }t!        t        j"                  |            d x}}y # 1 sw Y   DxY w) Nimpact.jsonr   --files--output--workspaceTrP   capture_outputtexttimeoutr   r6   )z2%(py2)s
{%(py2)s = %(py0)s.returncode
} == %(py5)sr%   )rA   rB   rG   zCLI failed: z
>assert %(py7)spy7z Output JSON file was not createdzC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}output_filer   r5   r   rC   datarD   rF   rG   r1   r   r9   r:   )r   r   
subprocessrunsys
executableANALYZER_PATH
returncoder   r   rH   rI   rJ   r   r    stderrr!   r"   existsopenjsonload)r#   r   r   r$   r%   rW   r   r'   rL   @py_format8r)   fr   r&   r(   rK   s                   r+   test_cli_produces_json_outputz/TestCLIOutputJSON.test_cli_produces_json_output   sP   .,);;<M"K L!	  
    EAE A%EEE AEEEEEEvEEEvEEE EEEAEEEfmm_'EEEEEEEE!!G!#G#GG%GGGGGGG{GGG{GGG!GGG#GGGGGG+ 	 !99Q<D	  &$&&&&$&&&&&&&&&$&&&$&&&&&&&#+#t++++#t+++#++++++t+++t+++++++#+#t++++#t+++#++++++t+++t+++++++!)!T))))!T)))!))))))T)))T)))))))!)!T))))!T)))!))))))T)))T)))))))	  	 s   U44U>c                 >   |dz  }t        t        dz        }t        j                  t        j
                  t        t              d|dt        |      dt        t              gddd       t        |      5 }t        j                  |      }d d d        d	}d
   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}y # 1 sw Y   xY w)Nr   r   r   r   r   TrP   r   r   r   r   r   r   r8   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r"   )r#   r   r   r$   r   r   r&   r'   r(   r)   r*   s              r+    test_cli_json_contains_endpointsz2TestCLIOutputJSON.test_cli_json_contains_endpoints   s    .,);;<M"K L!	  	
  + 	 !99Q<D	  (E40D+EE'+EEEEE'+EEEE'EEE+EEEEEEEE	  	 s   5DDN)rY   rZ   r[   r\   r   r   r   r]   r-   r+   r   r      s     +*d *@F Fr-   r   )$r\   builtinsrH   _pytest.assertion.rewrite	assertionrewriter   r   r   r   r   rT   pathlibr   pytestr   __file__resolveparent_PARENTr   insertimpact_analyzerr   r   r   r   r   r   r   r   r_   rr   r}   r   r   r]   r-   r+   <module>r      s      	  
   
d8n$$&--44
5
#((HHOOAw  H~$$z1X%%,,/CC6N 6N| &   *' ',:F :Fr-   