
    i;                     `   d Z ddlZddlZddlZddlZddlZddlZdZej                  j                  de       ddl
mZmZmZmZ ddlm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 G d d      Z G d d      Z G d d      Z G d d      Zy)uF   test_qc_verify.py - qc_verify.py 자동 추론 + MANUAL_SKIP 테스트    Nz!/home/jay/workspace/teams/dev1/qc)_determine_overall_infer_test_files
_summarize	run_check)test_runnerc                   "    e Zd ZdZd Zd Zd Zy)TestInferTestFilesFoundub   _infer_test_files에 실제 존재하는 파일 경로를 넣으면 관련 테스트 파일 반환c                 >   |dz  }|j                          |dz  }|j                          |dz  }|j                  d       |dz  }|j                  d       |j                  dt        |             t	        t        |      g      }t        |      |v s
J d|        y	)
u]   임시 디렉토리에 tests/test_foo.py 생성 → foo.py 경로로 추론 → 발견 확인srctestsfoo.py# footest_foo.py
# test fooWORKSPACE_ROOTu4   test_foo.py가 추론 결과에 있어야 함, got: Nmkdir
write_textsetenvstrr   )selftmp_pathmonkeypatchsrc_dir	tests_dirfoo_pytest_foo_pyresults           E/home/jay/workspace/.worktrees/task-2116-dev1/tests/test_qc_verify.pytest_infer_test_files_foundz3TestInferTestFilesFound.test_infer_test_files_found   s     U"g%	8#'"-/|,+S];"CK=1;6)j-abhai+jj)    c                 N   |dz  dz  }|j                  d       |dz  dz  }|j                          |dz  }|j                  d       |dz  }|j                  d	       |j                  d
t        |             t	        t        |      g      }t        |      |v s
J d|        y)u2   부모 디렉토리의 tests/test_foo.py도 발견r   subT)parentsr   r   r   r   r   r   uA   부모 tests/test_foo.py가 추론 결과에 있어야 함, got: Nr   )r   r   r   sub_dirr   r   r   r   s           r   (test_infer_test_files_found_parent_testsz@TestInferTestFilesFound.test_infer_test_files_found_parent_tests2   s     U"U*d#u$w.	8#'"-/|,+S];"CK=1;6)w-nounv+ww)r!   c                 >   |j                  dt        |             |dz  }|j                          |dz  }|j                          |dz  }|j                  d       |dz  }|j                  d       t	        t        |      g      }t        |      |v s
J d|        y	)
u.   workspace_root/tests/test_foo.py 패턴 발견r   r   r   r   r   r   r   uD   workspace tests/test_foo.py가 추론 결과에 있어야 함, got: N)r   r   r   r   r   )r   r   r   workspace_tests_dirr   r   r   r   s           r   +test_infer_test_files_found_workspace_testszCTestInferTestFilesFound.test_infer_test_files_found_workspace_testsE   s    +S];&0!!#U"8#'")M9|,"CK=1;6)z-qrxqy+zz)r!   N)__name__
__module____qualname____doc__r    r&   r)    r!   r   r	   r	      s    lk&x&{r!   r	   c                       e Zd ZdZd Zd Zy)TestInferTestFilesNotFoundu9   관련 테스트 파일이 없으면 빈 리스트 반환c                     |j                  dt        |             t        |dz  dz        }t        |g      }|g k(  s
J d|        y)u:   존재하지 않는 파일 경로 전달 → 빈 리스트r   r   znonexistent.pyu/   테스트 파일 없으면 빈 리스트, got: Nr   r   r   )r   r   r   	fake_pathr   s        r   test_infer_test_files_not_foundz:TestInferTestFilesNotFound.test_infer_test_files_not_founda   sQ    +S];5(+;;<	"I;/|WNvhWW|r!   c                 ^    |j                  dt        |             t        g       }|g k(  sJ y)u&   빈 리스트 전달 → 빈 리스트r   Nr2   )r   r   r   r   s       r   test_infer_empty_listz0TestInferTestFilesNotFound.test_infer_empty_listi   s-    +S];"2&||r!   N)r*   r+   r,   r-   r4   r6   r.   r!   r   r0   r0   ^   s    CXr!   r0   c                       e Zd ZdZd Zy)TestInferTestFilesSkipTestFilesu#   test_ 접두사 파일은 건너뜀c                     |j                  dt        |             |dz  }|j                  d       t        t        |      g      }|g k(  s
J d|        y)u$   test_foo.py 전달 → 빈 리스트r   r   z# testu*   test_ 접두사 파일은 건너뜀, got: Nr   r   r   r   )r   r   r   	test_filer   s        r   %test_infer_test_files_skip_test_fileszETestInferTestFilesSkipTestFiles.test_infer_test_files_skip_test_filesx   sY    +S];},	X&"C	N#34|RI&RR|r!   N)r*   r+   r,   r-   r<   r.   r!   r   r8   r8   u   s    -Sr!   r8   c                       e Zd ZdZd Zy)TestInferTestFilesSkipNonPythonu!   .py가 아닌 파일은 건너뜀c                 .   |j                  dt        |             |dz  }|j                  d       |dz  }|j                  d       |dz  }|j                  d       t        t        |      t        |      t        |      g      }|g k(  s
J d|        y	)
u+   js, txt, md 파일 전달 → 빈 리스트r   zfoo.jsz// jszfoo.txttxtz	README.mdz# mdu%   .py 아닌 파일은 건너뜀, got: Nr:   )r   r   r   js_filetxt_filemd_filer   s          r   %test_infer_test_files_skip_non_pythonzETestInferTestFilesSkipNonPython.test_infer_test_files_skip_non_python   s    +S];X%7#i'E"[(6""CL#h-W#NO|MDVHMM|r!   N)r*   r+   r,   r-   rD   r.   r!   r   r>   r>      s    +Nr!   r>   c                       e Zd ZdZd Zd Zy) TestRunCheckTestRunnerManualSkipu0   --skip test_runner 시 MANUAL_SKIP 상태 반환c           	      N    t        ddgddg dg       }|d   dk(  s
J d|        y)	uT   run_check('test_runner', skip_list=['test_runner'], ...) → status == 'MANUAL_SKIP'r   	task-test name	skip_listtask_idapi_baseapi_endpointstest_dir
file_pathsstatusMANUAL_SKIPu   MANUAL_SKIP 기대, got: Nr   r   r   s     r   &test_run_check_test_runner_manual_skipzGTestRunCheckTestRunnerManualSkip.test_run_check_test_runner_manual_skip   sE    $o
 h=0V4MfX2VV0r!   c           	          t        ddgddg dg       }|d   dk(  sJ dj                  |d         }d|v sd	|v sd
|j                         v sJ yyy)u.   MANUAL_SKIP details에 경고 메시지 포함r   rH   rI   rJ   rR   rS   
detailsu   경고WARNN)r   joinupper)r   r   details_strs      r   )test_manual_skip_details_contains_warningzJTestRunCheckTestRunnerManualSkip.test_manual_skip_details_contains_warning   sz    $o
 h=000iiy 12+x;/F&T_TeTeTgJgggJg/F+r!   N)r*   r+   r,   r-   rV   r^   r.   r!   r   rF   rF      s    :Whr!   rF   c                       e Zd ZdZd Zd Zy)&TestRunCheckTestRunnerAutoInferNoFiles=   check_files로 추론했으나 테스트 파일 0개 → SKIPc                     |j                  dt        |             |dz  }|j                  d       t        dg ddg dt        |      g      }|d   d	k(  s
J d
|        y)ra   r   zbar.pyz# barr   rH   rI   rJ   rR   SKIPu,   테스트 파일 0개 → SKIP 기대, got: N)r   r   r   r   )r   r   r   src_filer   s        r   .test_run_check_test_runner_auto_infer_no_fileszUTestRunCheckTestRunnerAutoInferNoFiles.test_run_check_test_runner_auto_infer_no_files   sz    +S]; h&G$H
 h6)b-YZ`Ya+bb)r!   c           	      L    t        dg ddg dg       }|d   dk(  s
J d|        y)	u/   test_dir도 없고 file_paths도 없으면 SKIPr   rH   rI   rJ   rR   rc   u"   아무것도 없으면 SKIP, got: NrT   rU   s     r   /test_run_check_test_runner_no_dir_no_files_skipzVTestRunCheckTestRunnerAutoInferNoFiles.test_run_check_test_runner_no_dir_no_files_skip   sD    
 h6)X-OPVx+XX)r!   N)r*   r+   r,   r-   re   rg   r.   r!   r   r`   r`      s    Gc&Yr!   r`   c                       e Zd ZdZd Zy)&TestRunCheckTestRunnerWithTestDirWarnsu)   test_dir 사용 시 stderr에 WARN 출력c           
          |dz  }|j                          t        dg ddg t        |      g       }|j                         }d|j                  v s#d|j                  v sJ d|j                         y	y	)
u=   test_dir 사용 시 stderr에 --test-dir 관련 경고 출력r   r   rH   rI   rJ   z
--test-dirztest-diru0   stderr에 --test-dir 관련 경고 기대, got: N)r   r   r   
readouterrerr)r   r   capsysrP   r   captureds         r   .test_run_check_test_runner_with_test_dir_warnszUTestRunCheckTestRunnerWithTestDirWarns.test_run_check_test_runner_with_test_dir_warns   s     g%]
 $$&HLL(J(,,,F	O=hll=MN	OF,F(r!   N)r*   r+   r,   r-   ro   r.   r!   r   ri   ri      s    3Or!   ri   c                       e Zd ZdZd Zd Zy)TestSummarizeWithManualSkipu#   MANUAL_SKIP이 _summarize에 반영c                 j    dg ddg ddg dd}t        |      }d|v s
J d|       d|v sd|v sJ yy)u    MANUAL_SKIP이 summary에 포함rS   rR   rY   PASS)r   
file_checkdata_integrityu.   MANUAL_SKIP이 summary에 있어야 함, got: z2 PASSNr   r   checkssummarys      r   test_summarize_with_manual_skipz;TestSummarizeWithManualSkip.test_summarize_with_manual_skip  sg     '4C%+;)/B?

 V$'e+YZaYd)ee'7"f&777&7"r!   c                 <    dg ddg dd}t        |      }d|vsJ y)u*   MANUAL_SKIP 없으면 summary에 미포함rt   rs   rc   ru   rv   rS   Nrw   rx   s      r   &test_summarize_no_manual_skip_no_entryzBTestSummarizeWithManualSkip.test_summarize_no_manual_skip_no_entry  s5     &,;)/B?
 V$G+++r!   N)r*   r+   r,   r-   r{   r~   r.   r!   r   rq   rq   
  s    -	8,r!   rq   c                   "    e Zd ZdZd Zd Zd Zy)$TestDetermineOverallManualSkipIsWarnu,   MANUAL_SKIP 포함 시 전체 결과가 WARNc                 P    dg ddg dd}t        |g       }|dk(  s
J d|        y)u%   MANUAL_SKIP이 있으면 overall WARNrS   rs   rt   r   ru   rZ   u"   MANUAL_SKIP → WARN 기대, got: Nr   r   ry   overalls      r   *test_determine_overall_manual_skip_is_warnzOTestDetermineOverallManualSkipIsWarn.test_determine_overall_manual_skip_is_warn*  sD     '4C%+;
 %VR0& P$Fwi"PP r!   c                 P    dg ddg dd}t        |g       }|dk(  s
J d|        y)u"   FAIL + MANUAL_SKIP 혼재 시 FAILrS   rs   FAILr   u   FAIL이 있으면 FAIL, got: Nr   r   s      r   -test_determine_overall_fail_beats_manual_skipzRTestDetermineOverallManualSkipIsWarn.test_determine_overall_fail_beats_manual_skip3  sD     '4C%+;
 %VR0& K$A'"KK r!   c                 @    dg ddg dd}t        |g       }|dk(  sJ y)u   모두 PASS면 PASSrt   rs   r}   Nr   r   s      r   .test_determine_overall_all_pass_no_manual_skipzSTestDetermineOverallManualSkipIsWarn.test_determine_overall_all_pass_no_manual_skip<  s7     &,;)/B?
 %VR0&   r!   N)r*   r+   r,   r-   r   r   r   r.   r!   r   r   r   '  s    6QL!r!   r   c                   `    e Zd ZdZ ej
                  d      d        Zd Zd Zd Z	d Z
d	 Zy
)TestVerifyWithTestFilesu2   test_runner.verify(test_files=[...]) 동작 확인T)autousec                     ddl }t        t        j                  j	                               D ]J  }d|v st        t        j                  |   |j                  j                        s:t        j                  |= L y)uX   test_qc_gate.py의 sys.modules MagicMock 오염 방지를 위해 실제 모듈로 교체r   N	verifiers)unittest.mocklistsysmoduleskeys
isinstancemock	MagicMock)r   unittestmod_names      r   _ensure_real_test_runnerz0TestVerifyWithTestFiles._ensure_real_test_runnerN  sZ     	 S[[--/0 	*Hh&:ckk(6KX]]MdMd+eKK)	*r!   c                 X    ddl m} |j                  g       }|d   dk(  s
J d|        y)u   빈 test_files → SKIPr   N
test_filesrR   rc   u%   빈 test_files → SKIP 기대, got: verifiers.test_runnerr   verifyr   trr   s      r   +test_verify_with_test_files_empty_list_skipzCTestVerifyWithTestFiles.test_verify_with_test_files_empty_list_skipX  s7    *b)h6)[-RSYRZ+[[)r!   c                     ddl m} |j                  dg      }|d   dk(  s
J d|        dj                  |d	         }d
|v sd|v sd|j	                         v sJ yyy)uB   존재하지 않는 test_files → SKIP (존재하는 파일 0개)r   Nz$/tmp/nonexistent_test_file_abc123.pyr   rR   rc   u1   존재하지 않는 파일 → SKIP 기대, got: rX   rY   u   존재하는u   없음)r   r   r   r[   r\   )r   r   r   r]   s       r   ,test_verify_with_nonexistent_test_files_skipzDTestVerifyWithTestFiles.test_verify_with_nonexistent_test_files_skip_  s}    *'M&NOh6)g-^_e^f+gg)iiy 12,K0G6U`UfUfUhKhhhKh0G,r!   c                     ddl m} |dz  }|j                  d       |j                  t	        |      g      }|d   dv s
J d|        y)	uB   존재하는 테스트 파일 → pytest 실행 (PASS 또는 FAIL)r   Nztest_sample.pyz*def test_always_pass():
    assert 1 == 1
r   rR   )rt   r   rc   u   유효한 상태 기대, got: )r   r   r   r   r   )r   r   r   r;   r   s        r   #test_verify_with_existing_test_filez;TestVerifyWithTestFiles.test_verify_with_existing_test_fileh  s[    * //	KLs9~&67h#;;f?]^d]e=ff;r!   c                 T    ddl m} |j                         }|d   dk(  s
J d|        y)u(   test_dir도 test_files도 없으면 SKIPr   NrR   rc   u#   인수 없으면 SKIP 기대, got: r   r   s      r   test_verify_with_no_args_skipz5TestVerifyWithTestFiles.test_verify_with_no_args_skipt  s2    *h6)Y-PQWPX+YY)r!   c                 x    ddl m} t        |dz        }|j                  |dg      }|d   dk(  s
J d|        y)	u   test_files가 주어지면 test_dir 무시하지 않고 test_files로만 실행
        (test_files가 None이 아니면 test_dir 경로보다 test_files 우선)r   Nnonexistent_dirz/tmp/nonexistent_test_xyz.py)rP   r   rR   rc   u(   test_files 우선 → SKIP 기대, got: )r   r   r   r   )r   r   r   r   r   s        r   )test_verify_test_files_overrides_test_dirzATestVerifyWithTestFiles.test_verify_test_files_overrides_test_dir{  sY     	+h)::; $67  

 h6)^-UV\U]+^^)r!   N)r*   r+   r,   r-   pytestfixturer   r   r   r   r   r   r.   r!   r   r   r   K  s@    <V^^D!* "*\i
gZ_r!   r   )r-   	importlibjsonosr   tempfiler   QC_DIRpathinsert	qc_verifyr   r   r   r   r   r   r	   r0   r8   r>   rF   r`   ri   rq   r   r   r.   r!   r   <module>r      s    L   	 
   
- 6   ":{ :{D .S S&N N.h hJ!Y !YRO O:, ,:! !H=_ =_r!   