
    (<i#                        d Z ddlZddlZddlmZ ddlmZ ddlZej                  j                  d e
 ee      j                               ddlmZmZmZmZmZ  G d d      Z G d d	      Z G d
 d      Z G d d      Z G d d      Zy)uA   generate_ai_image.py의 순수 함수에 대한 단위 테스트.    N)Path)Any)
COST_TABLE	SCENARIOSload_env_keysload_resultssave_resultsc                       e Zd ZdeddfdZdeddfdZdeddfdZdeddfdZdeddfdZdeddfd	Z	deddfd
Z
deddfdZy)TestLoadEnvKeystmp_pathreturnNc                 ^    |dz  }|j                  dd       t        |      }|dddk(  sJ y)	u.   KEY=VALUE 형식을 올바르게 파싱한다.	.env.keyszFOO=bar
BAZ=qux
utf-8encodingbarqux)FOOBAZN
write_textr   selfr   env_fileresults       Z/home/jay/workspace/.worktrees/task-2057-dev2/tools/ai-image-gen/test_generate_ai_image.pytest_parse_key_valuez$TestLoadEnvKeys.test_parse_key_value   s=    k)07Cx(u5555    c                 \    |dz  }|j                  dd       t        |      }|ddik(  sJ y)u5   export KEY=VALUE 형식을 올바르게 파싱한다.r   zexport MY_KEY=my_value
r   r   MY_KEYmy_valueNr   r   s       r   test_parse_export_prefixz(TestLoadEnvKeys.test_parse_export_prefix#   s=    k)6Ix((J////r   c                 \    |dz  }|j                  dd       t        |      }|ddik(  sJ y)u>   큰따옴표로 감싸진 값에서 따옴표를 제거한다.r   zAPI_KEY="secret123"
r   r   API_KEY	secret123Nr   r   s       r   test_strip_double_quotesz(TestLoadEnvKeys.test_strip_double_quotes,   =    k)3gFx()[1111r   c                 \    |dz  }|j                  dd       t        |      }|ddik(  sJ y)uA   작은따옴표로 감싸진 값에서 따옴표를 제거한다.r   zAPI_KEY='secret456'
r   r   r%   	secret456Nr   r   s       r   test_strip_single_quotesz(TestLoadEnvKeys.test_strip_single_quotes5   r(   r   c                 \    |dz  }|j                  dd       t        |      }|ddik(  sJ y)u   빈 줄을 무시한다.r   z

FOO=bar

r   r   r   r   Nr   r   s       r   test_ignore_empty_linesz'TestLoadEnvKeys.test_ignore_empty_lines>   s<    k)-@x(%'''r   c                 \    |dz  }|j                  dd       t        |      }|ddik(  sJ y)u.   # 로 시작하는 주석 줄을 무시한다.r   u8   # 이것은 주석입니다
FOO=bar
# 또 다른 주석
r   r   r   r   Nr   r   s       r   test_ignore_comment_linesz)TestLoadEnvKeys.test_ignore_comment_linesG   sC    k)I 	 	

 x(%'''r   c                 2    |dz  }t        |      }|i k(  sJ y)u>   존재하지 않는 파일에 대해 빈 dict를 반환한다.zdoes_not_exist.keysN)r   r   r   missing_filer   s       r   &test_file_not_found_returns_empty_dictz6TestLoadEnvKeys.test_file_not_found_returns_empty_dictS   s#    "77|,||r   c                 h    d}|dz  }|j                  |d       t        |      }|ddddd	d
k(  sJ y)uB   다양한 형식이 혼합된 파일을 올바르게 파싱한다.zm# comment

PLAIN=value1
QUOTED="value2"
SINGLE='value3'
export EXPORTED=value4
export EXPORT_QUOTED="value5"
r   r   r   value1value2value3value4value5)PLAINQUOTEDSINGLEEXPORTEDEXPORT_QUOTEDNr   )r   r   contentr   r   s        r   test_mixed_formatsz"TestLoadEnvKeys.test_mixed_formats[   s[    . 	 k)Gg6x( %
 
 	
 
r   )__name__
__module____qualname__r   r   r#   r'   r+   r-   r/   r3   r@    r   r   r   r      s    6T 6d 60 0$ 02 2$ 22 2$ 2( ( (
($ 
(4 
(t  
4 
D 
r   r   c                   <    e Zd ZdeddfdZdeddfdZdeddfdZy)TestLoadResultsr   r   Nc                     ddddddddg}|dz  }|j                  t        j                  |      d	
       t        |      }||k(  sJ y)u&   올바른 JSON 파일을 로드한다.gptAmedium)apiscenarioqualitygeminiBlowresults.jsonr   r   N)r   jsondumpsr   )r   r   dataresults_filer   s        r   test_load_valid_jsonz$TestLoadResults.test_load_valid_jsonz   s]     sx@#%@&
  .0

4 07Cl+~~r   c                 2    |dz  }t        |      }|g k(  sJ y)u>   존재하지 않는 파일에 대해 빈 list를 반환한다.rQ   N)r   r1   s       r   &test_file_not_found_returns_empty_listz6TestLoadResults.test_file_not_found_returns_empty_list   s"    .0l+||r   c                 X    |dz  }|j                  dd       t        |      }|g k(  sJ y)u    빈 배열 JSON을 로드한다.rQ   z[]r   r   N)r   r   )r   r   rU   r   s       r   test_load_empty_listz$TestLoadResults.test_load_empty_list   s5    .0w7l+||r   )rA   rB   rC   r   rV   rX   rZ   rD   r   r   rF   rF   y   s;    T d t  T d r   rF   c                   \    e Zd ZdeddfdZdeddfdZdeddfdZdeddfdZdeddfdZy)	TestSaveResultsr   r   Nc                 \    ddddddg}|dz  }t        ||       t        |      }||k(  sJ y)uI   저장한 데이터를 다시 읽으면 동일한 내용이어야 한다.rH   rI   highK7A`?N)rK   rL   rM   cost_usderrorrQ   r	   r   r   r   rT   rU   reloadeds        r   test_save_and_reloadz$TestSaveResults.test_save_and_reload   sM     !!&
  .0\4(-4r   c                 J    |dz  }t        |g        |j                         sJ y)u/   save_results 호출 후 파일이 생성된다.rQ   N)r	   exists)r   r   rU   s      r   test_save_creates_filez&TestSaveResults.test_save_creates_file   s(    .0\2&""$$$r   c                 `    ddig}|dz  }t        ||       t        |      }|d   d   dk(  sJ y)uF   한글 텍스트를 포함한 데이터를 손상 없이 저장한다.messageu   한글 텍스트 테스트rQ   r   Nrb   rc   s        r   test_save_korean_textz%TestSaveResults.test_save_korean_text   sF    '02N&O%P.0\4(-{9%)EEEEr   c                 `    ddig}|dz  }t        ||       |j                  d      }d|v sJ y)uB   저장된 파일에 한글이 이스케이프 없이 저장된다.keyu   한글rQ   r   r   N)r	   	read_text)r   r   rT   rU   raw_contents        r   !test_save_uses_ensure_ascii_falsez1TestSaveResults.test_save_uses_ensure_ascii_false   sD    ',h&7%8.0\4(",,g,>;&&&r   c                 v    |dz  }ddig}ddig}t        ||       t        ||       t        |      }||k(  sJ y)u   기존 파일을 덮어쓴다.rQ   oldTnewNrb   )r   r   rU   old_datanew_datard   s         r   test_overwrite_existing_filez,TestSaveResults.test_overwrite_existing_file   sN    .0+0$-+0$-\8,\8,-8###r   )	rA   rB   rC   r   re   rh   rk   rp   rv   rD   r   r   r\   r\      sd     T  d  $%t % %Fd Ft F'$ '4 '
$T 
$d 
$r   r\   c                   $    e Zd ZddZddZddZy)TestScenariosNc                 ,    t        t              dk(  sJ y)u7   SCENARIOS dict에 3개의 시나리오가 존재한다.   N)lenr   r   s    r   test_has_three_scenariosz&TestScenarios.test_has_three_scenarios   s    9~"""r   c                 L    t        t        j                               h dk(  sJ y)u#   SCENARIOS의 키는 A, B, C 이다.>   rI   rO   CN)setr   keysr|   s    r   test_scenario_keys_are_a_b_cz*TestScenarios.test_scenario_keys_are_a_b_c   s    9>>#$777r   c                     t        j                         D ]9  \  }}t        |t              sJ d| d       t	        |      dkD  r0J d| d        y)u@   모든 시나리오 값은 비어 있지 않은 문자열이다.u   시나리오 u   의 값이 str이 아닙니다.r   u   의 값이 비어 있습니다.N)r   items
isinstancestrr{   )r   rm   values      r   %test_all_values_are_non_empty_stringsz3TestScenarios.test_all_values_are_non_empty_strings   s\    #//+ 	XJCeS)_]3%?^+__)u:>W]3%7V#WW>	Xr   r   N)rA   rB   rC   r}   r   r   rD   r   r   rx   rx      s    #8Xr   rx   c                   4    e Zd ZddZddZddZddZddZy)TestCostTableNc                 L    t        t        j                               h dk(  sJ y)u4   COST_TABLE에 low, medium, high 키가 존재한다.>   rP   r^   rJ   N)r   r   r   r|   s    r   test_has_low_medium_highz&TestCostTable.test_has_low_medium_high   s    :??$%)BBBBr   c                 F    t         d   t        j                  d      k(  sJ y)u   low 비용은 0.011이다.rP   gI+?Nr   pytestapproxr|   s    r   test_low_costzTestCostTable.test_low_cost   s    % FMM%$8888r   c                 F    t         d   t        j                  d      k(  sJ y)u   medium 비용은 0.042이다.rJ   g/$?Nr   r|   s    r   test_medium_costzTestCostTable.test_medium_cost   s    (#v}}U';;;;r   c                 F    t         d   t        j                  d      k(  sJ y)u   high 비용은 0.167이다.r^   r_   Nr   r|   s    r   test_high_costzTestCostTable.test_high_cost  s    &!V]]5%9999r   c                     t        j                         D ].  \  }}t        |t              s
J | d       |dkD  r&J | d        y)u(   모든 비용 값은 양수 float이다.u!    비용이 float이 아닙니다.r   u    비용이 0 이하입니다.N)r   r   r   float)r   rM   costs      r   "test_all_costs_are_positive_floatsz0TestCostTable.test_all_costs_are_positive_floats  sV    '--/ 	GMGTdE*Ywi7X,YY*!8Fy(EFF8	Gr   r   )rA   rB   rC   r   r   r   r   r   rD   r   r   r   r      s    C9<:Gr   r   )__doc__rR   syspathlibr   typingr   r   pathinsertr   __file__parentgenerate_ai_imager   r   r   r   r	   r   rF   r\   rx   r   rD   r   r   <module>r      s}    G  
    3tH~,,- . X
 X
@ J9$ 9$BX X*G Gr   