
    i+c                       d Z ddlmZ ddlZddlZddlmZ ddlZddl	Z	ddl
mZmZ ej                  j                  d e ed                   ddlmZmZmZmZmZmZmZ dZd	Zd
ZdZefd%dZefd%dZefd%dZefd%dZefd%dZ efd%dZ!efd%dZ"efd%dZ#efd%dZ$efd%dZ%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)'ug  
test_quality_evaluator.py — task-2421 IDS Phase 1 단위 테스트
silent corruption (단조 그라데이션+박스+텍스트 1종 패턴) 영구 차단 검증

작성자: 카구야 (단위 테스트 담당)
관련 태스크: task-2421 (task-2389 한글 깨짐, task-2401 단조 그라데이션 silent pass 재발 방지)
             task-2421-G2 (로키 G2 적대적 평가 4건 약점 회귀 차단)

구현 의존: quality_evaluator.py (벤자이텐 작성)
  - check_visual_diversity: STD_THRESHOLD=25.0, UNIQUE_THRESHOLD=1000,
                             SPATIAL_COHERENCE_DIFF_MAX=25.0 (TV-static 차단)
  - check_brand_color_match: design_md["primary"] 키, Delta-E < 30,
                              BRAND_AREA_RATIO_MIN=0.10 (면적 비율 검증)
  - check_hybrid_pattern: 각 패턴별 알고리즘 (Sobel 기반)
  - check_font_size: pytesseract 미설치/예외 시 BLOCKED 통일 (passed=True, blocked=True, score=0)
  - check_ocr_confidence: pytesseract 없으면 BLOCKED, OCR_KOREAN_RATIO_MIN=0.5 (한글 비율 검증)
  - evaluate_image: 5개 check 통합, retry_hints = 각 check의 retry_hint 병합
    )annotationsN)Path)Image	ImageDrawz*/home/jay/workspace/skills/satori-cardnews)
EvalResultcheck_brand_color_matchcheck_font_sizecheck_hybrid_patterncheck_ocr_confidencecheck_visual_diversityevaluate_imagez0/home/jay/.local/share/fonts/Pretendard-Bold.otfz3/home/jay/.local/share/fonts/Pretendard-Regular.otfz./home/jay/.local/share/fonts/NotoSansCJKKR.otf)8  r   c                    t        j                  | d   | d   dft         j                        }t        | d         D ]%  }t	        dd|z  | d   z  z         }||dd|ddf<   ' t        j                  |      S )uX   단조 수직 회색 그라데이션 — silent corruption 대표 케이스 (task-2401).   r      dtype`   @   N)npzerosuint8rangeintr   	fromarray)sizearrxvs       A/home/jay/workspace/tests/skills/satori/test_quality_evaluator.py_make_monotone_gradientr!   :   sy    
((DGT!Wa(
9C47^ q(47223Aq!G ??3    c                0    t        j                  d| d      S )u8   단색 분홍 이미지 — std_mean 0, unique_colors 1.RGBz#FF69B4r   newr   s    r    _make_solid_pinkr(   C       99UD),,r"   c                    t        j                  d| d      }t        j                  |      }|j	                  g dddd       |j	                  g dd	       |S )
uA   흰색 배경 + 밝은 회색 박스만 — unique_colors 극소.r$   #FFFFFF)d   r,     r-   z#EEEEEEz#CCCCCC   )filloutlinewidth)   r2   p  r3   )r/   )r   r&   r   Draw	rectangle)r   imgdraws      r    _make_box_text_onlyr8   H   sN    
))E4
+C>>#DNN'iRSNTNN'iN8Jr"   c                    t         j                  j                  dd| d   | d   dft         j                        }t	        j
                  |      S )uF   랜덤 픽셀 노이즈 — Sobel edge density 0.9+ → h1_photo_card.r      r   r   r   )r   randomrandintr   r   r   )r   r   s     r    _make_random_noiser=   Q   sA    
))

AsT!Wd1gq$9

JC??3r"   c                   t        j                  | d   | d   dft         j                        }t        | d         D ]  }t        d| d   d      D ]  }|| d   z  || d   z  dz  z   dz  }dd	||z   d
z  z  dz  z   }t	        j
                  ||d      \  }}}t        |dz        ||||dz   df<   t        |dz        ||||dz   df<   t        |dz        ||||dz   df<     t        j                  |      S )u   
    HSV 전 색상 + 채도 변화 그라디언트 — unique_colors > 5000, 평균 채도 > 0.4.
    → h2_illustration_card.
    r   r   r   r      g      ?      ?g333333?g?
   g      $@g?r:   	r   r   r   r   colorsys
hsv_to_rgbr   r   r   )	r   r   yr   huesatrgbs	            r    _make_hsv_illustrationrK   W   s%   
 ((DGT!Wa(
9C47^ ,q$q'1% 	,AtAw;T!Ws!22c9CA|,t33C))#sC8GAq!"1s7|C1QqS5!"1s7|C1QqS5!"1s7|C1QqS5!	,, ??3r"   c                   d}t        j                  | d   | d   dft         j                        }d}t        d| d   |      D ]  }t        d| d   |      D ]  }|dz  dk(  r~|dz  dz  }t	        j
                  |d	d	      \  }}}	t        |d
z        ||||z   |||z   df<   t        |d
z        ||||z   |||z   df<   t        |	d
z        ||||z   |||z   df<   nd||||z   |||z   f<   |dz  }  t        j                  |      S )uw   
    100px 컬러 블록 + 흰 블록 교번 — edge_density 0.03~0.08, sat_std > 0.1.
    → h3_gpt_style_card.
    r,   r   r   r   r   r?   333333?r@   gffffff?r:      rB   )
r   blockr   idxrE   r   rF   rH   rI   rJ   s
             r    _make_gpt_style_blocksrQ   h   sP   
 E
((DGT!Wa(
9C
C1d1gu% 
q$q'5) 		AQw!|TzS("--c4>1a/21s7|AagIq5y!+,/21s7|AagIq5y!+,/21s7|AagIq5y!+,,/AagIq5y()1HC		
 ??3r"   c                   | \  }}t        j                  |      j                  dd      }t        j                  |      j                  dd      }t        j                  ||dft         j                        }d|z  |dz
  z  j                  t         j                        |dddddf<   d|z  |dz
  z  j                  t         j                        |dddddf<   d|ddddd	f<   t        j                  |      S )
u   
    2D RG 그라디언트 (R: x축, G: y축) — smoothness < 5 AND unique_colors >= 1000.
    → h4_gradient_card PASS, visual_diversity도 PASS (2D이므로 샘플링 다양성 확보).
    r   r   r   r:   Nr      r?   )r   arangereshaper   r   astyper   r   )r   why_idxx_idxr   s         r     _make_smooth_multicolor_gradientr\   ~   s    
 DAqIIaL  Q'EIIaL  B'E
((Aq!9BHH
-C%K1q5)11"((;C1aL%K1q5)11"((;C1aLC1aL??3r"   c                   t         j                  j                  dd| d   | d   dft         j                        j	                  t         j
                        }t         j                  j                  dd| d   | d   df      }t        j                  ||z   dd	      j	                  t         j                        }t        j                  |      S )
ut   
    JPEG-like 자연 노이즈 (1~15 범위 픽셀 차이) — noise_ratio > 0.15.
    → h5_user_photo_card.
    P      r   r   r   r   i(   r:   )	r   r;   r<   r   rW   int16clipr   r   )r   basenoiser   s       r    _make_jpeg_noisere      s    
 99RtAwQ&;288LSSTVT\T\]DIIc2Qa!'<=E
''$,3
'
.
.rxx
8C??3r"   c                   t        j                  | d   | d   dfg dt         j                        j                  t         j                        }t         j
                  j                  dd| d   | d   df      }t        j                  ||z   dd      j                  t         j                        }t        j                  |      S )	u6   Supabase primary #3ECF8E 청록색 dominant 이미지.r   r   r   >         r   i   r:   )
r   fullr   rW   ra   r;   r<   rb   r   r   )r   r   rd   s      r    _make_supabase_tealrm      s    
''47DGQ');288
L
S
STVT\T\
]CIIb!d1gtAw%:;E
''#+q#
&
-
-bhh
7C??3r"   c                0    t        j                  d| d      S )u+   완전 회색 — brand color 불일치용.r$   #888888r%   r'   s    r    _make_solid_grayrp      r)   r"   c                2    ||z  }| j                  |       |S )N)save)r6   tmp_pathnameps       r    _saverv      s    4AHHQKHr"   c                  "    e Zd ZdZd Zd Zd Zy)TestSilentCorruptionDetectionu?   A. silent corruption 검출 — task-2401 재발 방지 핵심.c                z    t               }t        |      }|d   du sJ d|d    d|d           |d   J d	       y)
uo   
        A-1: 단조 회색 그라데이션 PNG → passed=False, reason에 'visual_diversity' 포함.
        passedFuG   단조 그라데이션은 visual_diversity FAIL이어야 함. std_mean=std_meanz, unique_colors=unique_colorsreasonNu'   FAIL 시 reason 필드가 있어야 함)r!   r   selfr6   results      r    2test_silent_corruption_monotone_gradient_box_failszPTestSilentCorruptionDetection.test_silent_corruption_monotone_gradient_box_fails   sl     &'',h5( 	
z*++;F?<S;TV	
( h+V-VV+r"   c                    t               }t        |      }|d   du sJ d|d           |d   dk  sJ d|d           y)uK   
        A-2: 단색 분홍 PNG → passed=False, std_mean 낮음.
        rz   Fu>   단색 분홍은 visual_diversity FAIL이어야 함. std_mean=r{         9@uQ   단색 이미지의 std_mean은 STD_THRESHOLD(25.0) 미만이어야 함. 실제: N)r(   r   r~   s      r    (test_silent_corruption_solid_color_failszFTestSilentCorruptionDetection.test_silent_corruption_solid_color_fails   so      ',h5( 	
LVT^M_L`a	
( j!D( 	
_`fgq`r_st	
(r"   c                t    t               }t        |      }|d   dk  sJ d|d           |d   du sJ d       y)u]   
        A-3: 단색 박스+텍스트만 PNG → unique_colors < 1000, passed=False.
        r|     uS   박스+텍스트만 있는 이미지는 unique_colors < 1000이어야 함. 실제: rz   FuD   unique_colors < 1000 이미지는 visual_diversity FAIL이어야 함N)r8   r   r~   s      r    .test_silent_corruption_low_unique_colors_failszLTestSilentCorruptionDetection.test_silent_corruption_low_unique_colors_fails   sd     "#',o&- 	
o./1	
- h5( 	
R	
(r"   N)__name__
__module____qualname____doc__r   r   r    r"   r    rx   rx      s    IW

r"   rx   c                  .    e Zd ZdZd Zd Zd Zd Zd Zy)TestHybridPatternDiversityub   B. 5 hybrid 패턴 분화 — 5가지 패턴이 각각 고유한 특징으로 구분됨을 검증.c                    t               }t        |d      }|d   du sJ d|d           |d   dkD  sJ d|d           y)	u   
        B-4: 랜덤 노이즈 PNG → Sobel edge density > 0.05 → h1_photo_card PASS.
        (실제 임계값: magnitude > 30 픽셀 비율 > 0.05)
        h1_photo_cardrz   Tu?   랜덤 노이즈는 h1_photo_card PASS여야 함. edge_density=feature_valueg?u3   h1_photo_card: edge_density > 0.05 필요. 실제: N)r=   r
   r~   s      r    test_h1_photo_card_pattern_passz:TestHybridPatternDiversity.test_h1_photo_card_pattern_pass   ss    
 !"%c?;h4' 	
"?346	
' o&- 	
A&BYAZ[	
-r"   c                    t               }t        |d      }|d   du sJ d|d    d|d           |d   dkD  sJ d	|d           y
)u   
        B-5: HSV 전색상+채도변화 PNG → unique_colors > 5000, 평균채도 > 0.4
             → h2_illustration_card PASS.
        h2_illustration_cardrz   TuV   HSV 일러스트는 h2_illustration_card PASS여야 함. unique_colors(feature_value)=r   	, reason=r}   i  u;   h2_illustration_card: unique_colors > 5000 필요. 실제: N)rK   r
   r~   s      r    !test_h2_illustration_pattern_passz<TestHybridPatternDiversity.test_h2_illustration_pattern_pass   s    
 %&%c+ABh4' 	
,,2?,C+DIfU]N^M_a	
' o&- 	
I&Q`JaIbc	
-r"   c                    t               }t        |d      }|d   du sJ d|d    d|d           d|d   cxk  rd	k  sn J d
|d           y)u   
        B-6: 100px 컬러+흰 블록 교번 PNG → edge_density 0.03~0.08, sat_std > 0.1
             → h3_gpt_style_card PASS.
        h3_gpt_style_cardrz   TuD   컬러+흰 블록은 h3_gpt_style_card PASS여야 함. edge_density=r   r   r}   gQ?g{Gz?u+   h3: edge_density 0.03~0.08 필요. 실제: N)rQ   r
   r~   s      r    test_h3_gpt_style_pattern_passz9TestHybridPatternDiversity.test_h3_gpt_style_pattern_pass  s    
 %&%c+>?h4' 	
"?34IfX>N=OQ	
' vo.6$6 	
9&:Q9RS	
6r"   c                    t               }t        |d      }t        |      }|d   du sJ d|d    d|d           |d   d	k\  sJ d
|d           y)u   
        B-7: 부드러운 다색 선형 그라디언트 PNG → smoothness < 5
             → h4_gradient_card PASS.
        visual_diversity 와 별도 검사: multi-color 이므로 unique_colors >= 1000.
        h4_gradient_cardrz   TuS   부드러운 다색 그라디언트는 h4_gradient_card PASS여야 함. smoothness=r   r   r}   r|   r   u@   다색 그라디언트는 unique_colors >= 1000 필요. 실제: N)r\   r
   r   )r   r6   	hp_result	vd_results       r    test_h4_gradient_pattern_passz8TestHybridPatternDiversity.test_h4_gradient_pattern_pass  s     /0(.@A	*3/	"d* 	
#O45Yy?R>SU	
*
 )T1 	
NyYhOiNjk	
1r"   c                    t               }t        |d      }|d   du sJ d|d           |d   dkD  sJ d|d           y)	ub   
        B-8: JPEG-like 노이즈 PNG → noise_ratio > 0.15 → h5_user_photo_card PASS.
        h5_user_photo_cardrz   TuG   JPEG noise 이미지는 h5_user_photo_card PASS여야 함. noise_ratio=r   rM   u7   h5_user_photo_card: noise_ratio > 0.15 필요. 실제: N)re   r
   r~   s      r    test_h5_user_photo_pattern_passz:TestHybridPatternDiversity.test_h5_user_photo_pattern_pass'  st      %c+?@h4' 	
!/235	
' o&- 	
Ef_F]E^_	
-r"   N)	r   r   r   r   r   r   r   r   r   r   r"   r    r   r      s    l
 
 
 
&
r"   r   c                      e Zd ZdZd Zd Zy)TestBrandColorMatchuM   C. 브랜드 색상 매칭 — design_md["primary"] 키 사용, Delta-E < 30.c                    t               }ddi}t        ||      }|d   du sJ d|d           |d   dk  sJ d|d           y	)
ug   
        C-9: Supabase primary #3ECF8E(청록) dominant PNG → passed=True, min_delta_e < 30.
        primary#3ECF8Erz   TuT   Supabase 청록 dominant 이미지는 brand_color_match PASS여야 함. min_delta_e=min_delta_e      >@u/   min_delta_e는 30 미만이어야 함. 실제: N)rm   r   r   r6   	design_mdr   s       r    )test_brand_color_match_supabase_teal_passz=TestBrandColorMatch.test_brand_color_match_supabase_teal_pass>  s}     "#	*	(i8h4' 	
!-013	
' m$t+ 	
=f]>S=TU	
+r"   c                    t               }ddi}t        ||      }|d   du sJ d|d           |d   dkD  sJ d|d           y	)
uo   
        C-10: design_md primary=#3ECF8E(청록), PNG는 회색만 → passed=False, min_delta_e > 30.
        r   r   rz   FuP   청록 primary + 회색 PNG는 brand_color_match FAIL이어야 함. min_delta_e=r   r   u,   min_delta_e는 30 초과여야 함. 실제: N)rp   r   r   s       r    (test_brand_color_match_wrong_color_failsz<TestBrandColorMatch.test_brand_color_match_wrong_color_failsO  s}      	*	(i8h5( 	
!-013	
( m$t+ 	
:6-;P:QR	
+r"   N)r   r   r   r   r   r   r   r"   r    r   r   ;  s    W
"
r"   r   c                      e Zd ZdZd Zd Zy)TestOcrConfidenceu<   D. OCR confidence — task-2389 한글 깨짐 회귀 차단.c                D   	 ddl }t	        j
                  dt        d      }t        j                  |      }	 ddl	m
} |j                  t        d      }|j!                  dd	d
|       |j!                  ddd
|       t#        |      }|d   dk\  sJ d|d           |d   du sJ d       y# t        $ r t        j                  d       Y w xY w# t        $ rF 	 ddl	m
} |j                  t        d      }n%# t        $ r ddl	m
} |j                         }Y nw xY wY w xY w)u   
        D-11: 한글 텍스트가 명확한 PNG → avg_confidence >= 70.
        pytesseract 없으면 skip (시스템 의존).
        r   Npytesseract not installedr$   r+   	ImageFontr^   )r,     u   안녕하세요 테스트#000000r/   font)r,   i  u   카드뉴스 품질 검사avg_confidenceF   uC   명확한 한글 텍스트는 avg_confidence >= 70 필요. 실제: rz   Tu   OCR passed 필드 True 필요)pytesseractImportErrorpytestskipr   r&   SIZEr   r4   PILr   truetype	FONT_BOLD	Exception	FONT_NOTOload_defaulttextr   )r   rs   _ptr6   r7   r   r   r   s           r    $test_ocr_korean_high_confidence_passz6TestOcrConfidence.test_ocr_korean_high_confidence_passh  s2   
	5% iitY/~~c"		0%%%i4D 			*9	PT	U		*:QU	V%c*&'2- 	
./02	
- h4'H)HH'1  	5KK34	5  	00) )))R8 0) --/0		0sF   B, C ,CC	DC76D7DDDDDc                v   	 ddl }t	        j
                  dt        d      }t        j                  |      }t        d      D ]%  }d|dz  z   }|j                  |d	|d
z   dgdd       ' t        |      }|d   d
k  }|d   dk(  }|s|sJ d|d           yy# t        $ r t        j                  d       Y w xY w)u   
        D-12: 깨진 문자(회색 사각형) PNG → avg_confidence < 70 또는 텍스트 미인식.
        pytesseract 없으면 skip.
        r   Nr   r$   r+   rk   r,   Z   r   r   i  z#AAAAAAro   )r/   r0   r           u`   깨진 문자 이미지는 avg_confidence < 70 또는 no text여야 함. 실제: avg_confidence=)r   r   r   r   r   r&   r   r   r4   r   r5   r   )	r   r   r6   r7   ir   r   is_low_confidence
is_no_texts	            r    *test_ocr_garbled_text_low_confidence_failsz<TestOcrConfidence.test_ocr_garbled_text_low_confidence_fails  s    
	5% iitY/~~c"q 	UAa"fANNAsAFC0y)NT	U &c*"#34r9,-4
 J 	
&&,-=&>%?A	
.J   	5KK34	5s   B B87B8N)r   r   r   r   r   r   r   r"   r    r   r   e  s    FIB
r"   r   c                      e Zd ZdZd Zy)TestEvaluateImageIntegrationuB   E. 통합 evaluate_image — 5개 check 통합, EvalResult 반환.c                `   t        j                  dd       t               }t        ||d      }ddi}t	        ||dt
              }t        |t              sJ d	       |j                  d
u s!J d|j                   d|j                          |j                  dk\  sJ d|j                          y)u   
        E-13: 정상 카드뉴스 (랜덤 노이즈 h1_photo_card + #888888 brand)
               → passed=True, score >= 70.
        pytesseract 없으면 skip.
        r   r   r}   znormal_card.pngr   z#808080r   png_pathr   hybrid_patterntarget_sizeu.   반환값은 EvalResult 인스턴스여야 함Tu;   정상 카드뉴스는 passed=True여야 함. fail_reasons=z, score=r   u9   정상 카드뉴스는 score >= 70이어야 함. 실제: N)r   importorskipr=   rv   r   r   
isinstancer   rz   fail_reasonsscore)r   rs   r6   r   r   r   s         r    0test_evaluate_image_integration_normal_card_passzMTestEvaluateImageIntegration.test_evaluate_image_integration_normal_card_pass  s     	M2MN "h(9:	*	*	
 &*-_/__-}}$ 	
"//0H	
$ ||r! 	
G~V	
!r"   N)r   r   r   r   r   r   r"   r    r   r     s
    L
r"   r   c                      e Zd ZdZd Zy)TestRetryHintsu<   F. retry_hints 검증 — FAIL 시 retry_hint 병합 반환.c                d   t               }t        ||d      }ddi}t        ||dt              }|j                  du sJ d|j
                          t        |j                        dkD  sJ d	|j                          d
|j                  v xs d|j                  v }|sJ d|j                          y)u   
        F-14: 단조 그라데이션 PNG (visual_diversity FAIL)
               → retry_hints 비어있지 않음,
               force_pattern_diversity 또는 suggested_seed 포함.
        zmonotone_gradient.pngr   r   r   r   Fu?   단조 그라데이션은 passed=False여야 함. fail_reasons=r   uB   FAIL 케이스는 retry_hints가 비어있으면 안 됨. 실제: force_pattern_diversitysuggested_seeduM   retry_hints에 force_pattern_diversity 또는 suggested_seed 필요. 실제: N)r!   rv   r   r   rz   r   lenretry_hints)r   rs   r6   r   r   r   has_diversity_hints          r    test_fail_returns_retry_hintsz,TestRetryHints.test_fail_returns_retry_hints  s     &'h(?@	*	-	
 }}% 	
MfNaNaMbc	
% 6%%&* 	
PQWQcQcPde	
* &););; 66#5#55 	 " 	
))*,	
!r"   N)r   r   r   r   r   r   r"   r    r   r     s
    F
r"   r   c                  (    e Zd ZdZd Zd Zd Zd Zy)TestLokiG2RegressionBlocku8   G. 로키 G2 적대적 평가 4건 약점 회귀 차단.c                H   t         j                  j                  d       t        j                  ddt         j                        j                  t         j                        }|t         j                  j                  ddd      z  }t        j                  |dd      j                  t         j                        }t        j                  |      }t        |      }|d	   d
u sJ d|d    d|d           |d   dkD  sJ d|d           |d   d|d   v sJ d|d           y)u   
        G-15 (CRITICAL): TV-static 노이즈 PNG → spatial_diff > 25.0 → passed=False.
        '공간 일관성' reason 포함 확인.
        *   r   r   r   rT   r   i<   r   r:   rz   FuH   TV-static 노이즈는 visual_diversity FAIL이어야 함. spatial_diff=spatial_diffz, std_mean=r{   r   uX   TV-static의 spatial_diff는 SPATIAL_COHERENCE_DIFF_MAX(25.0) 초과여야 함. 실제: r}   Nu   공간 일관성u9   FAIL reason에 '공간 일관성' 포함 필요. 실제: )r   r;   seedrl   r   rW   ra   r<   rb   r   r   r   )r   r   r6   r   s       r    'test_visual_diversity_tv_static_blockedzATestLokiG2RegressionBlock.test_visual_diversity_tv_static_blocked  s6   
 			rggos"((;BB288Lryy  b/::ggc1c"))"((3ooc"',h5( 	
">23;vj?Q>RT	
( n%, 	
n-.0	
, h+0BfXFV0V 	
GxHXGYZ	
V0Vr"   c                   t        j                  ddt         j                        }g d|ddddf<   t        j                  |      }ddd	}t        ||      }|d
   du sJ d|d           |d   dk  sJ d|d           d|v sJ d       y)ul   
        G-16 (MEDIUM): 99% 회색 + 1% 청록 PNG → matching_area_ratio < 0.10 → passed=False.
        r   rT   r   rg   Nl   r   supabase)r   rt   rz   FuM   1% 청록 영역은 brand_color_match FAIL이어야 함. matching_area_ratio=matching_area_ratiog?uO   matching_area_ratio는 BRAND_AREA_RATIO_MIN(0.10) 미만이어야 함. 실제: u9   반환 dict에 'matching_area_ratio' 키가 있어야 함)r   rl   r   r   r   r   )r   r   r6   r   r   s        r    .test_brand_color_area_ratio_insufficient_failszHTestLokiG2RegressionBlock.test_brand_color_area_ratio_insufficient_fails  s     ggos"((;(DSD$3$Jooc" ):>	(i8h5( 	
##)*?#@"AC	
( +,t3 	
3457	
3 %. 	
G	
.r"   c                P   ddl m} t        j                  dt        d      }|snt        |t              }|d   du sJ d|d           |d   du sJ d	|j                  d              |d
   dk(  sJ d|d
           d|d   v sJ d|d           yt        j                  d       y)u   
        G-17 (HIGH): pytesseract 미설치 환경 → check_font_size가 BLOCKED 반환 확인.
        passed=True, blocked=True, score=0, reason에 'BLOCKED' 포함.
        r   )_TESSERACT_AVAILABLEr$   r+   rz   Tu4   BLOCKED 상태에서 passed=True여야 함. 실제: blockedu5   BLOCKED 상태에서 blocked=True여야 함. 실제: r   u3   BLOCKED 상태에서 score=0이어야 함. 실제: BLOCKEDr}   u=   BLOCKED reason에 'BLOCKED' 문자열 포함 필요. 실제: u?   pytesseract installed — exception path not tested in this envN)	scripts.quality_evaluatorr   r   r&   r   r	   getr   r   )r   r   r6   r   s       r    *test_check_font_size_ocr_exception_blockedzDTestLokiG2RegressionBlock.test_check_font_size_ocr_exception_blocked&  s    
 	CiitY/#$S$/F(#t+ FvhGWFXY+ )$, G

S\H]G^_, '?a' EfWoEVW' x 00 OPVW_P`Oab0 KKYZr"   c                4   t        j                  dd       t        j                  dt        d      }t        j                  |      }	 ddlm} |j                  dd	      }|j                  ddd|       |j                  ddd|       |j                  ddd|       t        |      }|j                  dd      dk(  s|j                  d      dk(  r|d   du sJ d       y|d   du s+J d|j                  d       d|j                  d              |j                  d      d|d   v sJ d|j                  d              y# t        $ rG 	 ddlm} |j                  t        d
      }n%# t        $ r ddlm} |j                         }Y nw xY wY 5w xY w) u   
        G-18 (LOW): pytesseract 설치 환경에서 영문 텍스트만 그린 PNG → 한글 비율 < 50% → passed=False.
        pytesseract 미설치 시 skip.
        r   u4   pytesseract not installed — skip korean_ratio testr   r$   r+   r   r   z4/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttfr^   r   )r,   i|  zENGLISH ONLY TEXTr   r   )r,   i  zNO KOREAN HERE)r,   iD  zABCDEFGHIJ 12345r   r   rS   rz   Fu7   텍스트 미감지 케이스도 passed=False여야 함u^   영문만 있는 이미지는 한글 비율 부족으로 passed=False여야 함. korean_ratio=korean_ratior   r}   Nu   한글u*   reason에 '한글' 포함 필요. 실제: )r   r   r   r&   r   r   r4   r   r   r   r   FONT_REGULARr   r   r   r   )r   r6   r7   r   r   r   s         r    (test_ocr_english_only_fails_korean_ratiozBTestLokiG2RegressionBlock.test_ocr_english_only_fails_korean_ratio@  s   
 	M2hiiitY/~~c"		0%%%&\^`aD 			*1		M		*.YT	J		*0yt	L%c* ::&*c1VZZ@P5QUW5W(#u, I, (#u,   &

> :;9VZZPXEYDZ\, ::h'3F8DT8T <VZZ=Q<RST8T7  	00) )),; 0) --/0		0s6   	E 	FE.-F.FFFFFN)r   r   r   r   r   r   r   r   r   r"   r    r   r     s    B
2
.[4)r"   r   )r   tuplereturnImage.Image)r6   r   rs   r   rt   strr   r   ).r   
__future__r   rC   syspathlibr   numpyr   r   r   r   r   pathinsertr  r   r   r   r	   r
   r   r   r   r   r   r   r   r!   r(   r8   r=   rK   rQ   r\   re   rm   rp   rv   rx   r   r   r   r   r   r   r   r"   r    <module>r     s  & #  
     
 3tHIJ K   ?	D<	 +/   $( -
 '+  &*   *.  " *.  , 48   $(   '+   $( -
+
 +
dS
 S
t#
 #
T;
 ;
D
 
H!
 !
Pv vr"   