
    iC              
      .   U d Z ddl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Zddl	Z	ddl
Z
ddlmZ ddlZ eej                  j                  d e ee      j%                         j&                  d                     Zedz  Z ee      ej,                  vr"ej,                  j/                  d ee             edz  d	z  Zed
z  Zedz  dz  dz  Zedz  dz  dz  dz  Z ed      Zi Zded<   ddZd Z ddZ!d dZ"d!d"dZ#d Z$d Z%d Z&d Z'd Z(d Z)d Z*y)#u;  task-2403 — IDS 후속 정리 통합 회귀 테스트 (벨레스 작성).

커버 항목:
1. task-2391/2392/2394 .done 발급 확인
2. task-2392 28장 PNG 한글 OCR 100% (계층 표본 + rapidocr)
3. task-2393 5 mp4 첫·중·끝 OCR 100%
4. task-2394 router 5 자연어 케이스 라우팅 정확도 ≥ 80%
5. silent pass 게이트 회귀 (더미 PNG → OCR 키워드 0건 → FAIL 판정)

★ silent pass 금지: 파일 존재만으로 PASS 판정하지 않는다.
★ rapidocr 미설치 환경: 명확한 FAIL 메시지로 신호 (silent fallback PASS 금지).
    )annotationsN)PathWORKSPACE_ROOT   scriptsmemoryeventsarchiveskillszmobile-prototype-kooutputszvalidate_korean_ocr.pyz/tmp/task-2403-motiondict_OCR_ENGINE_CACHEc                     	 t        j                  d       y# t        $ r) 	 t        j                  d       Y y# t        $ r Y Y yw xY ww xY w)u  사용 가능한 OCR 엔진 종류 반환.

    Returns:
        "easyocr" — easyocr 사용 (한국어 정확도 높음)
        "rapidocr" — rapidocr fallback (중국어 PPOCR 모델, 한국어 미지원)
        "none" — OCR 미설치 (silent pass 금지: 명시 FAIL)
    easyocrrapidocr_onnxruntimerapidocrnone)	importlibimport_moduleImportError     ;/home/jay/workspace/tests/dev6/test_ids_followup_cleanup.py_ocr_engine_kindr   7   sP    	* 	##$:; 			s$    	A
9	AA
AA
c                     t               } | dk(  ry| t        v rt        |    | fS | dk(  rddl}|j                  ddgdd	      }ndd
lm}  |       }|t        | <   || fS )uJ   OCR 엔진 인스턴스 반환. 캐시 사용 (모델 init 비용 절감).r   )Nr   r   r   NkoenF)gpuverbose)RapidOCR)r   r   r   Readerr   r    )kindr   enginer    s       r   	_load_ocrr$   J   so    Dv~   &,,yt%G1$d4<r   c                    |dk(  r| j                  t        |      d      S |dk(  r= | t        |            \  }}|sg S |D cg c]  }|st        |      dkD  s|d    c}S g S c c}w )u1   OCR 실행 → 인식된 텍스트 목록 반환.r   r   )detailr      )readtextstrlen)r#   r"   png_pathresult_items         r   _run_ocrr/   [   so    ys8}Q77z3x=)	I$*EDds4y1}QEEI Fs   A&A&A&c                     t         j                  j                  dt              } t         j                  j	                  |       }| j
                  j                  |       |j                  S )Nvalidate_korean_ocr)r   utilspec_from_file_locationVALIDATE_OCR_SCRIPTmodule_from_specloaderexec_moduleSCENARIO_KEYWORDS)specmods     r   _load_scenario_keywordsr;   l   sP    >>112D ..
)
)$
/CKKC    r   c           
        dd}d}t        j                  d||ddddd      } |d|      }d}t        |      D ]  }d	d
|z  z   }	||	z  } t        j                  |      }
 |d|
      } |dd      }| j                  ||z   |z   |z          y)u:   흰색 10×10 PNG 파일 생성 (한글 텍스트 없음).c                    | |z   }t        j                  dt        |            |z   t        j                  dt        j                  |      dz        z   S )Nz>Il    )structpackr*   zlibcrc32)
chunk_typedatacs      r   _chunkz_make_dummy_png.<locals>._chunk}   sD    {{4T+a/&++dDJJqMT^D^2___r   s   PNG

z>IIBBBBB   r   r   s   IHDRr       s   s   IDATs   IENDN)rB   bytesrC   rH   returnrH   )r>   r?   ranger@   compresswrite_bytes)pathwidthheightrE   header	ihdr_dataihdrraw_rowsr-   row
compressedidatiends                r   _make_dummy_pngrX   z   s    ` "FJvq!Q1EI'9%DH6] %//C x(J':&D'3DVd]T)D01r   c                     g d} g }| D ]V  }t         | dz  t        | dz  t         | dz  t        | dz  g}t        d |D              }|rF|j                  |       X |rJ d| dt          dt         d       y	)
ua   task-2391, 2392, 2394 의 .done 파일이 events/ 또는 events/archive/ 에 존재해야 한다.)z	task-2391z	task-2392z	task-2394z.donez.done.ackedc              3  <   K   | ]  }|j                           y w)N)exists).0ps     r   	<genexpr>z<test_done_files_issued_for_2391_2392_2394.<locals>.<genexpr>   s     31AHHJ3s   u=   다음 task의 .done 파일이 발급되지 않았습니다: u   
  확인 경로: u    및 u3   
  finish-task.sh 실행 여부를 점검하세요.N)
EVENTS_DIREVENTS_ARCHIVE_DIRanyappend)task_idsmissingtid
candidatesfounds        r   )test_done_files_issued_for_2391_2392_2394rh      s     7HG 
  C5&C5.C5,,C5!44	

 3
33NN3
   
Gy Q&<u-?,@ A=	=;wr   c                    t        t        j                  d            } t        |       }|dk\  sJ d| dt         d       g d}|D ]v  }t	        t        j                  | d            }|sJ d| dt                |d	   }|j                         j                  d
z  }|dkD  r_J d|j                   d|dd        y)ui   outputs/ 디렉토리에 PNG가 28장 존재하고 표본 3장 크기가 각각 10KB 초과여야 한다.*.png   u   PNG 파일이 u5   장입니다 (기대: 28장 이상).
  디렉토리: u<   
  스바로그가 아직 렌더링 중일 수 있습니다.dashboard_iphone15pro_lightsignup_step1_pixel9pro_darkai_analysis_iphone15pro_darku   표본 PNG 'u/   ' 를 찾을 수 없습니다.
  디렉토리: r   i   
   'u   ' 크기가 z.1fuk   KB — 10KB 미만.
  한글이 그려지지 않았거나 렌더링이 실패한 것으로 의심됩니다.N)sortedOUTPUTS_DIRglobr*   liststatst_sizename)	png_filesactual_countsample_stemsstemmatchespngsize_kbs          r   !test_png_28_count_and_sample_sizer      s     {''01Iy>L2 
 '&- (F	FL
  
{''4&78 	
4& !*m-	
w aj((*$$t+| 	
zgc] 3f f	
|
r   c                    t               \  } }| t        j                  d       t               }dddd}t	        j
                  d      }g }|j                         D ]  \  }}t        t        j                  | d            }|s|j                  d	| d
       ?|d   }	t        | ||	      }
dj                  |
      }|j                  |g       }|D cg c]	  }||v s| }}t        |j                  |            }|r|j                  d|	j                    d| d| d|dd         |rJ ddj                  |      z   dz          yc c}w )u   표본 PNG 3장에 대해 rapidocr로 한글 키워드 존재를 검증한다.

    ★ rapidocr 미설치 환경: FAIL (silent pass 금지).
      - 파일 크기만으로 PASS 처리하지 않는다.
    Nu   [rapidocr 미설치] rapidocr_onnxruntime 패키지가 설치되어 있지 않습니다.
  한글 OCR 검증을 건너뛰면 silent pass가 됩니다 — 이는 허용되지 않습니다.
  pip install rapidocr-onnxruntime 후 재실행하세요.	dashboardsignup_step1ai_analysisrl   u	   [가-힣]rj   u     파일 없음: u    (outputs/에서 찾지 못함)r    z  u   : 시나리오='uB   ' 한글 OCR 0건 (시각 corruption 의심)
    matched_keywords=u$   
    OCR 텍스트 (처음 200자):    u3   PNG 한글 OCR 시각 corruption 게이트 실패:

u]   
  (정밀 키워드 매칭 정확도는 memory/reports/task-2403-easyocr-verify.json 참조))r$   pytestfailr;   recompileitemsru   rs   rt   rb   r/   joingetboolsearchrx   )ocrocr_kindscenario_keywords
sample_map	HANGUL_REfailuresr|   scenarior}   r+   textscombinedexpected_kwskwmatched_keywords
any_hanguls                   r   (test_png_sample_rapidocr_korean_keywordsr      s    KMC
{I	
 01 (3'5(5J 

<(IH$**, h{''4&78OO/v5TUV1:h188E? ),,Xr:)5H2xBHH )**845
OOX]]O#3H: >((8'9 :66>tn5GI%2  >8ATTh	i<x Is   	EEc                 R   t         j                         sJ dt          d       t        t         j                  d            } t        t         j                  d            }t	        |       dk\  }t	        |      dk\  }|s*|s'J dt	        |        dt	        |       d	t          d
       yy)u   /tmp/task-2403-motion/ 에 mp4 5건 또는 PNG 15장이 존재해야 한다.

    ★ 디렉토리 미존재 시 skip이 아닌 명확한 FAIL로 신호.
    u9   모션 출력 디렉토리가 존재하지 않습니다: u   
  task-2393 산출물이 아직 생성되지 않았거나 경로가 변경되었습니다.
  glob 패턴으로 /tmp/task-2403-motion/**/*.mp4 및 *.png 를 확인하세요.z**/*.mp4**/*.png      zmp4(u   건) 또는 PNG 프레임(u_   장) 모두 부족합니다.
  기대: mp4 5건 이상 또는 PNG 15장 이상
  디렉토리: u?   
  스바로그 mp4 렌더링 완료 여부를 확인하세요.N)
MOTION_DIRr[   rr   rt   r*   )	mp4_files
png_frameshas_mp4
has_framess       r   test_motion_mp4_or_frames_existr     s      
CJ< P\ 	\ zz23I

34J)n!GZB&Jj 
s9~8Z8I J%, 'I	I j7r   c            	     F   t         j                         st        j                  dt          d       t	               \  } }| t        j                  d       t        t         j                  d            t        t         j                  d            z   t        t         j                  d            z   }|sJ dt          d	       |d
   }t        | ||      }dj                  |      }g d}|D cg c]	  }||v s| }}|sJ d|j                   d| d|dd        yc c}w )u   모션 표본 1건에 대해 rapidocr로 한글 키워드 존재를 검증한다.

    ★ rapidocr 미설치 환경: FAIL (silent pass 금지).
    u&   모션 출력 디렉토리 미존재: uA   
  test_motion_mp4_or_frames_exist 먼저 통과해야 합니다.Nu   [rapidocr 미설치] rapidocr_onnxruntime 패키지가 설치되어 있지 않습니다.
  모션 OCR 검증을 건너뛰면 silent pass가 됩니다 — 허용되지 않습니다.
  pip install rapidocr-onnxruntime 후 재실행하세요.z**/*first*.pngz
**/*_0.pngr   u1   모션 PNG 프레임을 찾을 수 없습니다: z	/**/*.pngr   r   )u	   보험료u   비교u   안내AIu   분석u   점수u   카드뉴스u   발행u?   모션 표본 OCR 키워드 없음 (시각 corruption 의심): u:   
  기대 키워드 (모션 슬라이드 3장 합집합): u"   
  OCR 텍스트 (처음 200자): r   )
r   r[   r   r   r$   rr   rt   r/   r   rx   )	r   r   rf   
sample_pngr   r   candidate_kwsr   rg   s	            r   test_motion_sample_rapidocrr   0  s@    4ZL AO O	

 KMC
{I	
 	z/01
.
/	0
,
-	. 
  
;J<yQ: AJS(J/ExxH jM':B2>R:E: 
I*//IZ [DDQ? S,,4TcN+=	?5 ;s   .	D8Dc                    t        j                  d      } g d}d}g }|D ]m  \  }}| j                  |d      }|j                  |k(  r|dz  }.|j	                  d|d|d	|j                  d
|j
                  d|j                  dd       o |t        |      z  }|dk\  s-J d| dt        |       d|dddj                  |      z          y)u   5개 자연어 입력 → 각 라우팅 결과 정답률 ≥ 80% (5건 중 4건 이상).

    ids_natural_routing.route()를 importlib로 직접 호출.
    ids_natural_routing))u)   인스타그램 카드뉴스 만들어줘cardnews)u.   iPhone 15 Pro 모바일 프로토타입 시연mobile)u"   supabase 스타일 보험 PPT 5장ppt)u#   MP4 모션 카드뉴스 reels 30초motion)u%   광고 포토 이미지 한글 카피imager   design_team)callerr'   u     프롬프트=u   
    기대 intent=u   
    실제 intent=z (skill=z, conf=z.2f)g?u   라우팅 정확도 /z (z.0%u(   ) — 기대: ≥ 80%
미스 케이스:
r   N)	r   r   routeintentrb   skill
confidencer*   r   )
ids_router
test_casescorrectmissespromptexpected_intentdecisionaccuracys           r   $test_router_natural_language_5_casesr   c  s    (()>?JJ GF#- 	##F=#A??o-qLGMM!& ,%%4$7 8%%-__$7x?QQXYaYlYlmpXqqrt	 Z(Ht 
wiqZ(9HS> J 	 $		& 1	2r   c                    t               \  } }| t        j                  d       t               }|j	                  dg d      }t        j                         5 }t        |      dz  }t        |dd       |j                         j                  }|dk  sJ d	| d
       t        | ||      }dj                  |      }|D 	cg c]	  }	|	|v s|	 }
}	|
rJ d| d|
 d       	 ddd       yc c}	w # 1 sw Y   yxY w)uv  더미 PNG (한글 0) → rapidocr OCR → 키워드 0건 → FAIL이어야 한다.

    이 테스트 자체가 PASS 되어야 한다 (더미 PNG로 FAIL이 나는지 확인하는 메타 회귀).
    즉, OCR 키워드가 0건임을 assert 하여 "파일 존재만으로 PASS 되지 않음"을 보장.

    ★ rapidocr 미설치 환경: FAIL (silent fallback 불허).
    Nu!  [rapidocr 미설치] silent pass 게이트 회귀 테스트를 실행할 수 없습니다.
  rapidocr_onnxruntime 미설치 상태에서 더미 PNG 검증을 건너뛰면
  'silent pass 금지' 원칙이 보장되지 않습니다.
  pip install rapidocr-onnxruntime 후 재실행하세요.r   )u   보험u   월u   원u   추천zdummy_no_korean.pngrp   )rN   rO   i (  u    더미 PNG가 너무 큽니다: u   B — 테스트 설계 오류r   u%   게이트 회귀 오류: 더미 PNG (u$   B, 한글 없음)에서
  키워드 uz   가 발견되었습니다.
  OCR 엔진이 오탐(false positive)을 내거나 테스트 설계를 점검해야 합니다.)r$   r   r   r;   r   tempfileTemporaryDirectoryr   rX   rv   rw   r/   r   )r   r   r   r   tmpdir	dummy_png
size_bytesr   r   r   	found_kwss              r   .test_silent_pass_gate__dummy_png_must_fail_ocrr     s*    KMC
{I	
 01$((6XYL		$	$	& 
&L#88		B7 ^^%--
I% 	
.zl:WX	
% h	288E?".AB".RA	A  	
3J< @$+ &nn	
}9
 
 B
 
s%   A)C/ 	C*
C*C/*C//C8)rI   r)   )r"   r)   r+   r   rI   z	list[str])rI   r   )rp   rp   )rM   r   rN   intrO   r   rI   None)+__doc__
__future__r   r   importlib.utilosr   r>   sysr   r@   pathlibr   r   environr   r)   __file__resolveparentsr   SCRIPTSrM   insertr_   r`   rs   r4   r   r   __annotations__r   r$   r/   r;   rX   rh   r   r   r   r   r   r   r   r   r   <module>r      sB   #   	 	  
     JJNN#Sh)?)?)A)I)I!)L%MN 9
$w<sxxHHOOAs7|$h&1
)+ x'*??)KX 55	AD\\  )*
  4 &"	"!26<
@:D6+f#V(
r   