
    (<iAt                        d 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j                  j                  dd       ddl
ZdZdZdZded	ed
edefdZdeded
edef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 G d! d"      Z G d# d$      Zy)%u   
test_g3_verifier.py — g3_independent_verifier.py 유닛/통합 테스트
작성자: 닌기르수 (개발5팀 테스터)
태스크: task-1883
    N)Pathz/home/jay/workspace/scriptsz6/home/jay/workspace/scripts/g3_independent_verifier.pyu   # task-1883 작업 보고서

## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/sample.py | 핵심 기능 추가 | grep "MAGIC_KEYWORD" OK | verified |
u  # task-1883 작업 보고서 (Lv.2)

**S**: 현재 문서 체계가 정비되지 않아 가이드라인이 누락되어 있다.

**C**: 이로 인해 신규 팀원의 온보딩 시간이 증가하고 있다.

## 개요
이 작업은 문서 수정만 포함합니다. 추가 내용을 채워 분량을 확보합니다.
작업 범위는 README 및 가이드 문서 갱신이며 코드 변경은 없습니다.
관련 이슈 없음. 단순 문서화 작업으로 완료됩니다.
tmp_pathtask_idcontentreturnc                 r    | dz  dz  }|j                  dd       || dz  }|j                  |d       |S )uJ   보고서 파일을 tmp_path/memory/reports/{task_id}.md 에 생성한다.memoryreportsTparentsexist_okz.mdutf-8encoding)mkdir
write_text)r   r   r   reports_dirreport_files        G/home/jay/workspace/.worktrees/task-2057-dev2/tests/test_g3_verifier.pymake_reportr   1   sM    X%	1KdT27)3/K7W5    rel_pathc                 p    | |z  }|j                   j                  dd       |j                  |d       |S )uA   소스 파일을 tmp_path 하위 rel_path 위치에 생성한다.Tr   r   r   )parentr   r   )r   r   r   targets       r   make_source_filer   :   s;     F
MMt4
g0Mr   c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestParseVerificationTablec                 D    t        j                  t              }|g k(  sJ y)u,   테이블 없는 보고서 → 빈 리스트N)g3vparse_verification_tableREPORT_WITHOUT_TABLE)selfresults     r    test_returns_empty_when_no_tablez;TestParseVerificationTable.test_returns_empty_when_no_tableH   s    --.BC||r   c                     t        j                  t              }t        |      dk(  sJ |d   }|d   dk(  sJ |d   dk(  sJ |d   dk(  sJ y	)
u2   테이블이 있는 보고서 → 엔트리 파싱   r   	file_pathscripts/sample.pykeywordMAGIC_KEYWORDstatusverifiedN)r    r!   REPORT_WITH_TABLElen)r#   r$   entrys      r   test_parses_verified_entryz5TestParseVerificationTable.test_parses_verified_entryM   sg    --.?@6{aq	[!%8888Y?222X*,,,r   c                 z    d}t        j                  |      }t        d |D              sJ t        |      dk(  sJ y)u9   헤더 행이 엔트리로 포함되지 않아야 한다.u   ## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/a.py | 변경 | grep "FOO" OK | verified |
c              3   ,   K   | ]  }|d    dk7    yw)r(   u   파일N ).0es     r   	<genexpr>zCTestParseVerificationTable.test_skips_header_row.<locals>.<genexpr>a   s     >!1[>X->s   r'   N)r    r!   allr/   r#   reportr$   s      r   test_skips_header_rowz0TestParseVerificationTable.test_skips_header_rowV   sA     --f5>v>>>>6{ar   c                 f    d}t        j                  |      }t        |      dk(  sJ |d   d   J y)u@   grep 검증 컬럼에 키워드 패턴이 없으면 keyword=Noneu   ## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/b.py | 변경 | 없음 | verified |
r'   r   r*   Nr    r!   r/   r9   s      r   #test_no_keyword_when_grep_col_emptyz>TestParseVerificationTable.test_no_keyword_when_grep_col_emptyd   sB     --f56{aay#+++r   c                     d}t        j                  |      }t        |      dk(  sJ |d   d   dk(  sJ |d   d   dk(  sJ y)	u   여러 엔트리 파싱u   ## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/a.py | 변경A | grep "KEY_A" OK | verified |
| scripts/b.py | 변경B | grep "KEY_B" OK | verified |
   r   r*   KEY_Ar'   KEY_BNr=   r9   s      r   test_multiple_entriesz0TestParseVerificationTable.test_multiple_entriesq   s[     --f56{aay#w...ay#w...r   N)__name__
__module____qualname__r%   r1   r;   r>   rC   r4   r   r   r   r   G   s    
- ,/r   r   c                       e Zd Zd Zd Zd Zy)TestResolveFilePathc                 |    |j                  t        dd       t        j                  d      }t        |      dk(  sJ y)u!   절대 경로는 그대로 반환WORKSPACE_ROOTz/tmp/wsz/absolute/path/file.pyN)setattrr    resolve_file_pathstr)r#   monkeypatchr$   s      r   test_absolute_path_unchangedz0TestResolveFilePath.test_absolute_path_unchanged   s9    C!19=&&'?@6{6666r   c                     |j                  t        dt        |             t        j                  d      }||dz  dz  k(  sJ y)uA   상대 경로는 WORKSPACE_ROOT 기준으로 절대 경로 변환rJ   r)   scripts	sample.pyN)rK   r    rM   rL   r#   rN   r   r$   s       r   /test_relative_path_prefixed_with_workspace_rootzCTestResolveFilePath.test_relative_path_prefixed_with_workspace_root   sB    C!13x=A&&':;I-;;;;r   c                     |j                  t        dt        |             t        j                  d      }t        |      j	                  d      sJ dt        |      vsJ y)u4   경로:라인번호 형식에서 라인번호 제거rJ   zscripts/sample.py:42r)   z:42N)rK   r    rM   rL   endswithrS   s       r   test_strips_line_number_suffixz2TestResolveFilePath.test_strips_line_number_suffix   sU    C!13x=A&&'=>6{##$7888CK'''r   N)rD   rE   rF   rO   rT   rW   r4   r   r   rH   rH      s    7<(r   rH   c                       e Zd Zd Zd Zy)TestCheckFileExistencec                    |j                  t        dt        |             |dz  dz  }|j                  j	                  dd       |j                  d       ddig}t        j                  |      \  }}|d	k(  sJ |g k(  sJ y
)u"   모든 파일이 존재하면 PASSrJ   rQ   rR   Tr   z# existsr(   r)   PASSN)rK   r    rM   r   r   r   check_file_existence)r#   rN   r   r   entriesr,   missings          r   test_pass_when_all_files_existz5TestCheckFileExistence.test_pass_when_all_files_exist   s    C!13x=AI%3D48*%!456227;"}}r   c                     |j                  t        dt        |             ddig}t        j                  |      \  }}|dk(  sJ d|v sJ y)u+   파일이 없으면 FAIL + 파일명 반환rJ   r(   zscripts/nonexistent.pyFAILN)rK   r    rM   r\   )r#   rN   r   r]   r,   r^   s         r   test_fail_when_file_missingz2TestCheckFileExistence.test_fail_when_file_missing   sW    C!13x=A!9:;227;'7222r   N)rD   rE   rF   r_   rb   r4   r   r   rY   rY      s    
3r   rY   c                   $    e Zd Zd Zd Zd Zd Zy)TestRunGrepVerificationc                 
   |j                  t        dt        |             |dz  dz  }|j                  j	                  dd       |j                  d       ddd	d
g}t        j                  |      \  }}|dk(  sJ |g k(  sJ y)u(   키워드가 파일에 존재하면 PASSrJ   rQ   rR   Tr   def MAGIC_KEYWORD(): pass
r)   r+   r-   r(   r*   r,   r[   NrK   r    rM   r   r   r   run_grep_verificationr#   rN   r   srcr]   r,   faileds          r   test_pass_when_keyword_foundz4TestRunGrepVerification.test_pass_when_keyword_found   s    C!13x=A"[0

545 1*$
 227;||r   c                 .   |j                  t        dt        |             |dz  dz  }|j                  j	                  dd       |j                  d       ddd	d
g}t        j                  |      \  }}|dk(  sJ t        |      dk(  sJ d|d   v sJ y)u%   키워드가 파일에 없으면 FAILrJ   rQ   rR   Tr   def other_function(): pass
r)   r+   r-   rg   ra   r'   r   N)rK   r    rM   r   r   r   ri   r/   rj   s          r   test_fail_when_keyword_missingz6TestRunGrepVerification.test_fail_when_keyword_missing   s    C!13x=A"[0

556 1*$
 227;6{a&)+++r   c                     |j                  t        dt        |             ddddg}t        j                  |      \  }}|dk(  sJ |g k(  sJ y)u9   status가 verified가 아닌 항목은 grep 검사 스킵rJ   r)   r+   pendingrg   r[   N)rK   r    rM   ri   )r#   rN   r   r]   r,   rl   s         r   test_skips_non_verified_entriesz7TestRunGrepVerification.test_skips_non_verified_entries   s`    C!13x=A 1*#
 227;||r   c                 
   |j                  t        dt        |             |dz  dz  }|j                  j	                  dd       |j                  d       ddd	d
g}t        j                  |      \  }}|dk(  sJ |g k(  sJ y)u!   keyword가 None이면 grep 스킵rJ   rQ   rR   Tr   zdef func(): pass
r)   Nr-   rg   r[   rh   rj   s          r    test_skips_entry_without_keywordz8TestRunGrepVerification.test_skips_entry_without_keyword   s    C!13x=A"[0

5+, 1$
 227;||r   N)rD   rE   rF   rm   rp   rs   ru   r4   r   r   rd   rd      s    $,&r   rd   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	TestG3VerifierIntegrationu   
    subprocess로 g3_independent_verifier.py를 직접 실행하거나,
    monkeypatch로 WORKSPACE_ROOT를 교체하여 main()을 호출하는 통합 테스트.
    c                 P   |j                  t        dt        |             |j                  t        ddd|g       t	        j
                  t              5 }t        j                          ddd       |j                  j                  S # 1 sw Y   j                  j                  S xY w)u   
        main()을 직접 호출하고 exit code를 캡처한다.
        sys.argv와 WORKSPACE_ROOT를 monkeypatch로 교체한다.
        rJ   argvg3_independent_verifier.py	--task-idN
rK   r    rM   syspytestraises
SystemExitmainvaluecoder#   rN   r   r   exc_infos        r   _run_main_with_argsz-TestG3VerifierIntegration._run_main_with_args  s}    
 	C!13x=AC*FU\)]^]]:& 	(HHJ	~~"""	~~"""   BB%c                 t    d}d}t        |||       t        |dd       | j                  |||      }|dk(  sJ y)uC   정상 보고서 + 키워드가 존재하는 파일 → exit code 0z	task-9001u   # task-9001 작업 보고서

## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/sample.py | 핵심 기능 추가 | grep "MAGIC_KEYWORD" OK | verified |
r)   rf   r   Nr   r   r   r#   r   rN   r   report_content	exit_codes         r   test_pass_with_valid_reportz5TestG3VerifierIntegration.test_pass_with_valid_report  sN     	Hg~6 	#68UV ,,[(GL	A~~r   c                 p   d}d}t        |||       t        |dd       | j                  |||      }|dk(  sJ |dz  dz  | dz  }|j                         sJ d	       t	        j
                  |j                  d
            }|d   |k(  sJ t        |d         dkD  sJ t        d |d   D              sJ y)ue   보고서에 verified 키워드가 있으나 실제 파일에 없음 → exit code 1 + g3-fail 생성z	task-9002u   # task-9002 작업 보고서

## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/sample.py | 핵심 기능 추가 | grep "MISSING_SYMBOL" OK | verified |
r)   ro   r'   r	   events.g3-failu(   g3-fail 파일이 생성되어야 한다r   r   r   fail_reasonsr   c              3   $   K   | ]  }d |v  
 yw)MISSING_SYMBOLNr4   r5   rs     r   r7   zFTestG3VerifierIntegration.test_fail_missing_keyword.<locals>.<genexpr>R  s     LQ#q(L   N)	r   r   r   existsjsonloads	read_textr/   anyr#   r   rN   r   r   r   	fail_file	fail_datas           r   test_fail_missing_keywordz3TestG3VerifierIntegration.test_fail_missing_keyword6  s     	Hg~6 	#68VW,,[(GL	A~~ x'(2y5II	!M#MM!JJy22G2DE	#w...9^,-111L)N2KLLLLr   c                   	 d}|dz  dz  j                  dd       |j                  t        dt        |             |j                  t        ddd	|g       d
dl}g 	|j                  	fd}|j                  |d|       t        j                  t              5 }t        j                          ddd       j                  j                  dk(  sJ dj                  	      }d|v sJ y# 1 sw Y   <xY w)uY   보고서 파일이 없으면 exit code 1 + 에러 메시지에 'report not found' 포함z	task-9003r	   r
   Tr   rJ   ry   rz   r{   r   Nc                  h    dj                  d | D              }j                  |        | i | y )N c              3   2   K   | ]  }t        |        y wNrM   r5   as     r   r7   zYTestG3VerifierIntegration.test_fail_no_report.<locals>.capturing_print.<locals>.<genexpr>f       1qCF1   joinappendargskwargslineoriginal_printoutput_liness      r   capturing_printzFTestG3VerifierIntegration.test_fail_no_report.<locals>.capturing_printe  2    881D11D%D+F+r   printr'   
report not found)r   rK   r    rM   r}   builtinsr   r~   r   r   r   r   r   r   )
r#   r   rN   r   r   r   r   
all_outputr   r   s
           @@r   test_fail_no_reportz-TestG3VerifierIntegration.test_fail_no_reportW  s    	H	y	(//t/LC!13x=AC*FU\)]^!	,
 	Hg?]]:& 	(HHJ	 ~~""a''' YY|,
!Z///	 	s   C,,C5c                 ^    d}t        ||t               | j                  |||      }|dk(  sJ y)u;   테이블 없는 보고서 → PASS with SKIP (exit code 0)z	task-9004r   N)r   r"   r   )r#   r   rN   r   r   s        r   test_skip_lv2_no_tablez0TestG3VerifierIntegration.test_skip_lv2_no_tablex  s4    Hg';<,,[(GL	A~~r   c                 2   t         j                  j                         }t        |      |d<   |dz  dz  j	                  dd       t        j                  dt        ddgdd|d	
      }|j                  dk(  sJ |j                  |j                  z   }d|v sJ y)uJ   subprocess로 스크립트를 실행 — 보고서 없음 → returncode 1rJ   r	   r
   Tr   python3r{   ztask-subprocess-test   )capture_outputtextenvtimeoutr'   r   N)osenvironcopyrM   r   
subprocessrunSCRIPT_PATH
returncodestdoutstderr)r#   r   r   r$   outputs        r   test_subprocess_no_reportz3TestG3VerifierIntegration.test_subprocess_no_report  s    jjoo #H	H	y	(//t/L[2HI
   A%%%.!V+++r   N)
rD   rE   rF   __doc__r   r   r   r   r   r   r4   r   r   rw   rw     s(    
	#4MB0B,r   rw   c                   $    e Zd Zd Zd Zd Zd Zy)TestCheckPlannedItemsc                     ddddddddd	dg}t        j                  |      \  }}|d
k(  sJ t        |      dk(  sJ d|d   v sJ d|d   v sJ y)u'   planned 상태 항목이 있으면 FAILscripts/a.py   변경ANplannedr(   descriptionr*   r,   scripts/b.py   변경BrB   r-   ra   r'   u   1건r   )r    check_planned_itemsr/   r#   r]   r,   detailss       r   "test_fail_when_planned_items_existz8TestCheckPlannedItems.test_fail_when_planned_items_exist  s     )t_hi(wblm
 11':7|q   ###+++r   c                 `    dddddg}t        j                  |      \  }}|dk(  sJ |g k(  sJ y)u    planned 항목이 없으면 PASSr   r   rA   r-   r   r[   Nr    r   r   s       r   test_pass_when_no_planned_itemsz5TestCheckPlannedItems.test_pass_when_no_planned_items  sH     )wblm
 11':"}}r   c                 l    ddddddddg}t        j                  |      \  }}|dk(  sJ d|d	   v sJ y
)u=   planned 항목 여러 개 → 모두 FAIL 메시지에 포함r   r   r   )r(   r   r,   r   r   ra   u   2건r   Nr   r   s       r   test_fail_with_multiple_plannedz5TestCheckPlannedItems.test_fail_with_multiple_planned  sU     )iX(iX
 11':###r   c                 P    t        j                  g       \  }}|dk(  sJ |g k(  sJ y)u   빈 entries → PASSr[   Nr   )r#   r,   r   s      r   test_pass_when_empty_entriesz2TestCheckPlannedItems.test_pass_when_empty_entries  s0    11"5"}}r   N)rD   rE   rF   r   r   r   r   r4   r   r   r   r     s    
,$r   r   c                       e Zd Zd Zd Zd Zy) TestG3VerifierPlannedIntegrationc                 P   |j                  t        dt        |             |j                  t        ddd|g       t	        j
                  t              5 }t        j                          d d d        |j                  j                  S # 1 sw Y   j                  j                  S xY wNrJ   ry   rz   r{   r|   r   s        r   r   z4TestG3VerifierPlannedIntegration._run_main_with_args  {    C!13x=AC*FU\)]^]]:& 	(HHJ	~~"""	~~"""r   c                 F   d}d}t        |||       t        |dd       t        |dd       | j                  |||      }|dk(  sJ |dz  d	z  | d
z  }|j                         sJ t	        j
                  |j                  d            }t        d |d   D              sJ y)u2   보고서에 planned 항목 포함 → exit code 1z	task-9010u  # task-9010 작업 보고서

## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/done.py | 완료된 변경 | grep "DONE_KEY" OK | verified |
| scripts/todo.py | 미완료 변경 | 없음 | planned |
zscripts/done.pyzDONE_KEY = True
zscripts/todo.pyz# not done yet
r'   r	   r   r   r   r   c              3   @   K   | ]  }d |j                         v   yw)r   N)lowerr   s     r   r7   zTTestG3VerifierPlannedIntegration.test_fail_with_planned_in_report.<locals>.<genexpr>  s     Ma9	)Ms   r   N)r   r   r   r   r   r   r   r   r   s           r    test_fail_with_planned_in_reportzATestG3VerifierPlannedIntegration.test_fail_with_planned_in_report  s    	 	Hg~6#46IJ#46HI,,[(GL	A~~ x'(2y5II	!!!JJy22G2DE	M9^3LMMMMr   c                     d}d}t        |||       t        |dd       t        |dd       | j                  |||      }|dk(  sJ y)	u)   모든 항목이 verified → exit code 0z	task-9011u  # task-9011 작업 보고서

## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/a.py | 변경 A | grep "KEY_A" OK | verified |
| scripts/b.py | 변경 B | grep "KEY_B" OK | verified |
r   zKEY_A = True
r   zKEY_B = True
r   Nr   r   s         r   test_pass_with_all_verifiedz<TestG3VerifierPlannedIntegration.test_pass_with_all_verified  sV    	 	Hg~6>3CD>3CD,,[(GL	A~~r   N)rD   rE   rF   r   r   r   r4   r   r   r   r     s    #N4r   r   c                   0    e Zd Zd Zd Zd Zd Zd Zd Zy)TestCheckReportQualityc                 f    d}t        j                  |      \  }}|dk(  sJ t        |      dk\  sJ y)u;   1줄짜리 보고서 → FAIL (SCQA 부족 + 분량 부족)u   # task-xxx
끝.ra   r'   N)r    check_report_qualityr/   r#   r:   r,   issuess       r   test_fail_minimal_reportz/TestCheckReportQuality.test_fail_minimal_report  s;    #11&96{ar   c                 n    d}t        j                  |      \  }}|dk(  sJ t        d |D              sJ y)u$   200자 미만 + SCQA 없음 → FAILu5   짧은 보고서입니다.
내용이 부족합니다.ra   c              3   0   K   | ]  }d |v xs d|v   yw)SCQA   분량Nr4   r5   is     r   r7   zATestCheckReportQuality.test_fail_short_no_scqa.<locals>.<genexpr>  s      @A6Q;/(a-/@s   Nr    r   r   r   s       r   test_fail_short_no_scqaz.TestCheckReportQuality.test_fail_short_no_scqa  s=    I11&9@@@@@r   c                 T    d}t        j                  |      \  }}|dk(  sJ |g k(  sJ y)u)   SCQA 2개 이상 + 200자 이상 → PASSu.  # 보고서

**S**: 현재 상황입니다. 시스템이 정상 동작 중입니다.

**C**: 문제가 발생했습니다. 특정 기능이 작동하지 않습니다.

추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 추가내용 r[   Nr    r   r   s       r   test_pass_scqa_with_lengthz1TestCheckReportQuality.test_pass_scqa_with_length  s8     Y11&9||r   c                 n    d}t        j                  |      \  }}|dk(  sJ t        d |D              sJ y)u:   SCQA 1개만 존재 + 200자 이상 → FAIL (SCQA 부족)u  # 보고서

**S**: 현재 상황입니다.

내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. 내용을 채우기 위한 텍스트입니다. ra   c              3   $   K   | ]  }d |v  
 yw)r   Nr4   r   s     r   r7   zATestCheckReportQuality.test_fail_scqa_only_one.<locals>.<genexpr>  s     /16Q;/r   Nr   r   s       r   test_fail_scqa_only_onez.TestCheckReportQuality.test_fail_scqa_only_one  s=    }11&9/////r   c                 T    d}t        j                  |      \  }}|dk(  sJ |g k(  sJ y)u*   '## S -', '## C -' 형식의 SCQA → PASSu  # 보고서

## S - 상황
현재 상황 설명입니다.

## C - 문제
문제 설명입니다.

내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 내용 r[   Nr   r   s       r    test_pass_with_header_style_scqaz7TestCheckReportQuality.test_pass_with_header_style_scqa   s8     O11&9||r   c                 n    d}t        j                  |      \  }}|dk(  sJ t        d |D              sJ y)u%   SCQA 있지만 200자 미만 → FAILu   **S**: 상황.
**C**: 문제.ra   c              3   $   K   | ]  }d |v  
 yw)r   Nr4   r   s     r   r7   zDTestCheckReportQuality.test_fail_length_under_200.<locals>.<genexpr>,  s     1Q8q=1r   Nr   r   s       r   test_fail_length_under_200z1TestCheckReportQuality.test_fail_length_under_200'  s=    111&91&1111r   N)	rD   rE   rF   r   r   r  r  r  r	  r4   r   r   r   r     s!     A02r   r   c                   $    e Zd Zd Zd Zd Zd Zy)TestParseVerificationTableV9c                 l    d}t        j                  |      }t        |      dk(  sJ |d   d   dk(  sJ y)u^   '수정 파일별 검증 상태' 섹션의 테이블만 파싱, 다른 섹션 테이블 무시u  ## 시나리오 목록

| 시나리오 | 설명 | 결과 | 비고 |
|----------|------|------|------|
| 로그인 테스트 | 로그인 동작 확인 | 성공 | 없음 |

## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/auth.py | 인증 로직 수정 | grep "validate_token" OK | verified |

## 결론

| 항목 | 상태 |
|------|------|
| 전체 | 완료 |
r'   r   r(   scripts/auth.pyNr=   r9   s      r   %test_only_parses_verification_sectionzBTestParseVerificationTableV9.test_only_parses_verification_section5  sE    & --f56{aay%)::::r   c                 l    d}t        j                  |      }t        |      dk(  sJ |d   d   dk(  sJ y)u,   파일 경로 패턴이 아닌 행은 무시u4  ## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/real.py | 실제 파일 | grep "KEY" OK | verified |
| 로그인 테스트 | 시나리오 설명 | 성공 | verified |
| 사용자 조회 | API 설명 | 통과 | verified |
r'   r   r(   zscripts/real.pyNr=   r9   s      r   test_ignores_non_file_rowsz7TestParseVerificationTableV9.test_ignores_non_file_rowsN  sE     --f56{aay%)::::r   c                 R    d}t        j                  |      }t        |      dk(  sJ y)u.   절대 경로(/로 시작)도 파일로 인식u   ## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| /home/jay/workspace/scripts/test.py | 수정 | grep "KEY" OK | verified |
r'   Nr=   r9   s      r   test_accepts_absolute_pathsz8TestParseVerificationTableV9.test_accepts_absolute_paths]  s-     --f56{ar   c                 R    d}t        j                  |      }t        |      dk(  sJ y)u!   다양한 확장자 파일 인식u  ## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| src/app.tsx | 컴포넌트 수정 | grep "Component" OK | verified |
| config/settings.yaml | 설정 변경 | grep "timeout" OK | verified |
r@   Nr=   r9   s      r   test_accepts_various_extensionsz<TestParseVerificationTableV9.test_accepts_various_extensionsi  s-     --f56{ar   N)rD   rE   rF   r  r  r  r  r4   r   r   r  r  4  s    ;2;
  r   r  c                   "    e Zd ZdZd Zd Zd Zy)TestG3VerifierV5Integrationu7   V-5 통합 테스트: 빈 보고서로 g3 통과 방지c                 P   |j                  t        dt        |             |j                  t        ddd|g       t	        j
                  t              5 }t        j                          d d d        |j                  j                  S # 1 sw Y   j                  j                  S xY wr   r|   r   s        r   r   z/TestG3VerifierV5Integration._run_main_with_args  r   r   c                     d}d}t        |||       | j                  |||      }|dk(  sJ |dz  dz  | dz  }|j                         sJ y)u7   검증 시나리오 1: 1줄짜리 보고서 → g3 FAILz	task-9020u   # task-9020
끝.r'   r	   r   r   N)r   r   r   )r#   r   rN   r   r   r   r   s          r   test_fail_one_line_reportz5TestG3VerifierV5Integration.test_fail_one_line_report  sg    ,Hg~6,,[(GL	A~~ x'(2y5II	!!!r   c                 Z    d}d}t        |||       | j                  |||      }|dk(  sJ y)uR   검증 시나리오 2: SCQA 포함 + 테이블 없는 조사 보고서 → g3 PASSz	task-9021u  # task-9021 조사 보고서

**S**: 현재 시스템은 정상 운영 중이며, 데이터 파이프라인이 안정적으로 동작하고 있다.

**C**: 그러나 최근 데이터 지연이 간헐적으로 발생하여 사용자 불만이 증가하고 있다.

**Q**: 데이터 지연의 근본 원인은 무엇이며 해결 가능한가?

**A**: 조사 결과 캐시 만료 정책이 원인으로 확인되었고, TTL 조정으로 해결 가능하다.

상세 내용입니다. 상세 내용입니다. 상세 내용입니다. 상세 내용입니다. 상세 내용입니다. 상세 내용입니다. 상세 내용입니다. 상세 내용입니다. 상세 내용입니다. 상세 내용입니다. r   N)r   r   r   s         r   test_pass_scqa_no_tablez3TestG3VerifierV5Integration.test_pass_scqa_no_table  s?    . 	 	Hg~6,,[(GL	A~~r   N)rD   rE   rF   r   r   r  r  r4   r   r   r  r  |  s    A#"r   r  c                       e Zd ZdZd Zd Zy)TestG3VerifierV9IntegrationuY   V-9 통합 테스트: 여러 테이블이 있는 보고서 → 검증 테이블만 파싱c                    |j                  t        dt        |             |j                  t        ddd|g       dd l}g |j
                  fd}|j                  |d|       t        j                  t              5 }t        j                          d d d        j                  j                  dj                        fS # 1 sw Y   0xY w)	NrJ   ry   rz   r{   r   c                  h    dj                  d | D              }j                  |        | i | y )Nr   c              3   2   K   | ]  }t        |        y wr   r   r   s     r   r7   z[TestG3VerifierV9Integration._run_main_with_args.<locals>.capturing_print.<locals>.<genexpr>  r   r   r   r   s      r   r   zHTestG3VerifierV9Integration._run_main_with_args.<locals>.capturing_print  r   r   r   r   )rK   r    rM   r}   r   r   r~   r   r   r   r   r   r   )	r#   rN   r   r   r   r   r   r   r   s	          @@r   r   z/TestG3VerifierV9Integration._run_main_with_args  s    C!13x=AC*FU\)]^!	, 	Hg?]]:& 	(HHJ	~~""DIIl$;;;	 	s   CCc                     d}d}t        |||       t        |dd       | j                  |||      \  }}|dk(  sJ t        j                  |      }|d   d   d   d	k(  sJ y
)u_   검증 시나리오 3: 여러 테이블 → 검증 테이블만 파싱, 정보 테이블 무시z	task-9030ug  # task-9030 작업 보고서

**S**: 현재 인증 모듈에 보안 취약점이 보고되었다.

**C**: 토큰 만료 검증 로직이 누락되어 만료된 토큰으로 접근이 가능하다.

**Q**: 토큰 검증 로직을 추가하여 보안 취약점을 해결할 수 있는가?

**A**: validate_token 함수에 만료 검증 추가로 해결 완료. pytest 5 passed, 0 failed.

## 시나리오 목록

| 시나리오 | 설명 | 결과 | 비고 |
|----------|------|------|------|
| 만료 토큰 | 만료된 토큰 거부 | 성공 | 핵심 시나리오 |
| 유효 토큰 | 정상 토큰 허용 | 성공 | 기본 동작 |

## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|------|-----------|-----------|------|
| scripts/auth.py | 토큰 검증 추가 | grep "validate_token" OK | verified |

## 결론

전체 작업 완료.
r  zdef validate_token(): pass
r   checksreport_parseentries_foundr'   N)r   r   r   r   r   )r#   r   rN   r   r   r   r   r$   s           r   test_multi_table_reportz3TestG3VerifierV9Integration.test_multi_table_report  s|    8 	Hg~6#46TU 44[(GT	6A~~ F#h/@AEEEr   N)rD   rE   rF   r   r   r%  r4   r   r   r  r    s    c<'Fr   r  )r   r   r   r   r}   pathlibr   r~   pathinsertg3_independent_verifierr    r   r.   r"   rM   r   r   r   rH   rY   rd   rw   r   r   r   r  r  r  r4   r   r   <module>r*     s    	  
   0 1 % G  $  s t t s S T 7/ 7/~( (43 36E EZK, K,f$ $X4 4x)2 )2b@  @ P% %Z9F 9Fr   