
    xi{Q                        d Z ddlZddlmc mZ ddlZddl	Z	ddl
Z
ddlmZ ddlmZmZ ddlZ ee      j$                  j$                  Ze
j(                  j+                  d ee             edz  Zej0                  j3                  de      ZdZeeuZes ej:                  defdeef      d	 ej<                         v s ej>                  e      r ej@                  e      nd	 ej@                  e      d
z  Z!dde!iz  Z" e# ejH                  e"            dxZZej0                  jK                  e      Z&ejN                  ZdZ(ee(uZ)e)s ej:                  de)fdee(f      d	 ej<                         v s ej>                  e      r ej@                  e      nd	 ej@                  e       ej@                  e(      dz  Z"dde"iz  Z* e# ejH                  e*            dxZxZ)Z(e&e
jV                  d<   ejN                  jY                  e&        G d d      Z- G d d      Z. G d d      Z/ G d d      Z0 G d d      Z1 G d d      Z2 G d d      Z3 G d d       Z4y)!ue  
test_youtube_transcribe.py

scripts/youtube-transcribe.py 단위 테스트 (TDD)

테스트 항목:
1. argparse: 필수/선택 인자 파싱 정상 동작
2. download_audio: yt-dlp 호출 및 WAV 파일 반환
3. transcribe_audio: HTTP multipart/form-data 전송 정상 처리
4. transcribe_audio: 연결 실패 시 fallback 경고 반환
5. transcribe_audio: 타임아웃 시 fallback 경고 반환
6. format_output: text/json/srt 형식 변환
7. main: 정상 흐름 통합 (mock)
8. main: 로컬 서비스 불가 시 fallback 메시지
9. main: exit code 성공 0
10. main: exit code 실패 1 (yt-dlp 에러)
    N)Path)	MagicMockpatchzyoutube-transcribe.pyyoutube_transcribeis not)z%(py0)s is not %(py3)sspec)py0py3assert %(py5)spy5)z2%(py2)s
{%(py2)s = %(py0)s.loader
} is not %(py5)sr
   py2r   assert %(py7)spy7c                   *    e Zd Zd Zd Zd Zd Zd Zy)TestParseArgsc                     t        j                  t              5  t        j	                  g        ddd       y# 1 sw Y   yxY w)u)   --url 없이 실행 시 SystemExit 발생Npytestraises
SystemExitr   
parse_argsselfs    </home/jay/workspace/scripts/tests/test_youtube_transcribe.pytest_url_requiredzTestParseArgs.test_url_required0   s1    ]]:& 	.))"-	. 	. 	.s	   9Ac                 p   t         j                  ddg      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|j                  }d
}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|j                  }d	}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}y	)u3   --url만 주면 기본값으로 나머지 채워짐--urlhttps://youtube.com/watch?v=abc==z+%(py2)s
{%(py2)s = %(py0)s.url
} == %(py5)sargsr   r   r   Ntextz.%(py2)s
{%(py2)s = %(py0)s.format
} == %(py5)sis)z.%(py2)s
{%(py2)s = %(py0)s.output
} is %(py5)skoz0%(py2)s
{%(py2)s = %(py0)s.language
} == %(py5)sr   r   url
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationformatoutputlanguager   r$   @py_assert1@py_assert4@py_assert3@py_format6@py_format8s          r   test_url_onlyzTestParseArgs.test_url_only5   s   !,,g7X-YZxx<<<x<<<<<x<<<<<<<t<<<t<<<x<<<<<<<<<<<{{$f${f$$$${f$$$$$$t$$$t$$${$$$f$$$$$$${{"d"{d""""{d""""""t"""t"""{"""d"""""""}}$$}$$$$}$$$$$$t$$$t$$$}$$$$$$$$$$    c                 r   t         j                  g d      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|j                  }d
}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}y	)u,   모든 인자 지정 시 올바르게 파싱)r   r    --formatjson--output/tmp/out.json
--languageenr    r!   r#   r$   r   r   r   NrB   r&   rD   )z.%(py2)s
{%(py2)s = %(py0)s.output
} == %(py5)srF   r*   r+   r8   s          r   test_all_argszTestParseArgs.test_all_args=   s   !,,	
 xx<<<x<<<<<x<<<<<<<t<<<t<<<x<<<<<<<<<<<{{$f${f$$$${f$$$$$$t$$$t$$${$$$f$$$$$$${{-o-{o----{o------t---t---{---o-------}}$$}$$$$}$$$$$$t$$$t$$$}$$$$$$$$$$r?   c                     t        j                  t              5  t        j	                  g d       ddd       y# 1 sw Y   yxY w)u!   format은 text|json|srt만 허용)r   r    rA   xmlNr   r   s    r   test_format_choicesz!TestParseArgs.test_format_choicesP   s6    ]]:& 	k))*ij	k 	k 	ks	   ;Ac                    t         j                  g d      }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}y	)
u   srt 포맷 파싱)r   r    rA   srtrL   r!   r&   r$   r   r   r   N)r   r   r5   r-   r.   r/   r0   r1   r2   r3   r4   r8   s          r   test_format_srtzTestParseArgs.test_format_srtU   s    !,,K
 {{#e#{e####{e######t###t###{###e#######r?   N)__name__
__module____qualname__r   r>   rG   rJ   rM    r?   r   r   r   /   s    .
%%&k
$r?   r   c                       e Zd Zd Zd Zd Zy)TestDownloadAudioc                    |dz  }|j                  d       t        d      5 }t               }t        |      |j                  _        t        d      |j                  _        t        |dz        |j                  _        t        j                  dt        |            }ddd       t        t              }|sd	d
t        j                         v st        j                  t              rt        j                  t              nd
dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t!        t        j"                  |            d}y# 1 sw Y   +xY w)u4   yt-dlp YoutubeDL 호출 및 WAV 파일 경로 반환	audio.wav   RIFF#youtube_transcribe.yt_dlp.YoutubeDLreturn_valueFz
audio.webmr    N5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstanceresultstrr
   py1r   py4)write_bytesr   r   rY   	__enter____exit__r]   prepare_filenamer   download_audior[   r/   r0   r-   r1   r2   r3   r4   )r   tmp_pathfake_wavmock_ydl_clsmock_ydlr\   r;   @py_format5s           r   test_calls_yt_dlpz#TestDownloadAudio.test_calls_yt_dlpc   s&   k)W%89 	\ {H2;2RL%%/1:1NL%%. 69L9P5QH%%2 (6613x=F	 &#&&&&&&&&z&&&z&&&&&&&&&&&&&&&&&#&&&#&&&&&&&&&&	 	s   A=GGc                    |dz  }|j                  d       t        d      5 }t               }|j                  }t        |      |_        t        d      |_        t        |dz        |j                  _        t        j                  dt        |            }ddd       j                  }d	} ||      }	|	sd
dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |	      dz  }
t!        t        j"                  |
            dx}x}}	y# 1 sw Y   xY w)u*   download_audio 반환값이 .wav 확장자zvideo_title.wavrV   rW   rX   Fzvideo_title.webmr    Nz.wavzJassert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.endswith
}(%(py4)s)
}r\   )r
   r   r`   py6)ra   r   r   rY   rb   rc   r]   rd   r   re   endswithr/   r0   r-   r1   r2   r3   r4   )r   rf   rg   rh   ri   ctx_mgrr\   r9   r;   @py_assert5@py_format7s              r   test_returns_wav_pathz'TestDownloadAudio.test_returns_wav_pathy   s   //W%89 		\ {H"//G )x @G(e<G58DV9V5WH%%2'6613x=F		 &v&v&&&&&&&&v&&&v&&&&&&v&&&&&&&&&&		 		s   A5EE(c                    t        d      5 }t               }|j                  }t        |      |_        t        d      |_        t        d      |j                  _        t        j                  t
        d      5  t        j                  dt        |             ddd       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)u,   yt-dlp 다운로드 실패 시 예외 발생rW   rX   Fzyt-dlp error)matchr    N)r   r   rY   rb   rc   	Exceptiondownloadside_effectr   r   r   re   r]   )r   rf   rh   ri   ro   s        r   test_raises_on_yt_dlp_errorz-TestDownloadAudio.test_raises_on_yt_dlp_error   s    89 
	\ {H"//G )x @G(e<G,5n,EH)y? "115s8}
	 
	 
	 
	s$   A.B7: B+B7+B4	0B77C N)rN   rO   rP   rk   rr   rx   rQ   r?   r   rS   rS   b   s    ','$r?   rS   c                   $    e Zd Zd Zd Zd Zd Zy)TestTranscribeAudioSuccessc                 T   |dz  }|j                  d       t               }d|_        dddddgd|j                  _        t        d	|
      5  t        j                  t        |      d      }ddd       d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                   |      rt        j                  |      nddz  }
dd|
iz  }t        t        j                  |            dx}}y# 1 sw Y   0xY w)u   정상 응답 시 dict 반환rU   rV         안녕하세요              ?startendr%   r%   segments youtube_transcribe.requests.postrX   r)   r7   Nr%   r!   z%(py1)s == %(py4)sr_   r`   assert %(py6)srm   r   inz%(py1)s in %(py3)sr\   r_   r   r   r   )ra   r   status_coderB   rY   r   r   transcribe_audior]   r-   r.   r2   r3   r4   r/   r0   r1   )r   rf   rg   mock_responser\   @py_assert0r;   @py_assert2rj   rq   @py_format4r<   s               r   !test_returns_transcription_resultz<TestTranscribeAudioSuccess.test_returns_transcription_result   s7   k)W%!$'!%#&s<MNO+
'
 5MR 	W'88XQU8VF	W f~2!22~!22222~!2222~222!22222222#zV####zV###z######V###V#######		W 	Ws   !FF'c           	         |dz  }|j                  d       t               }d|_        ddi|j                  _        t        d|      5 }t        j                  t        |      d	       d
d
d
       j                  }g }|j                  }|j                  }d}	 ||	      }
d
}|
|u}|}|s9g }|j                  }t        |      }d}||kD  }|}|rd}t        |      }||v }|}|}|s6t        j                  d|fd|
|f      dt!        j"                         v st        j$                  |      rt        j&                  |      ndt        j&                  |      t        j&                  |      t        j&                  |	      t        j&                  |
      t        j&                  |      dz  }dd|iz  }|j)                  |       |st        j                  dfdf      dt!        j"                         v st        j$                  t              rt        j&                  t              nddt!        j"                         v st        j$                  |      rt        j&                  |      ndt        j&                        t        j&                  |      t        j&                  |      dz  }dd|iz  }j)                  |       |rt        j                  dfdf      t        j&                  |      dt!        j"                         v st        j$                  t              rt        j&                  t              nddt!        j"                         v st        j$                  |      rt        j&                  |      ndt        j&                  |      dz  }dd|iz  }|j)                  |       t        j*                  |d      i z  }d d!|iz  }|j)                  |       t        j*                  |d      i z  }d"d#|iz  } t-        t        j.                  |             d
x}x}x}x}x}	x}
x}x}x}x}x}x}x}x}x}x}}y
# 1 sw Y   xY w)$u6   requests.post에 files 인자(multipart) 전달 확인rU   rV   r|   r%   testr   rX   r)   r   Nfiles   r   )zl%(py10)s
{%(py10)s = %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s.kwargs
}.get
}(%(py8)s)
} is not %(py13)scall_kwargsr   r`   rm   py8py10py13%(py15)spy15>zP%(py24)s
{%(py24)s = %(py19)s(%(py22)s
{%(py22)s = %(py20)s.args
})
} > %(py27)slenpy19py20py22py24py27%(py29)spy29r   )z5%(py32)s in %(py37)s
{%(py37)s = %(py34)s(%(py35)s)
}r]   )py32py34py35py37z%(py39)spy39r   z%(py42)spy42zassert %(py45)spy45)ra   r   r   rB   rY   r   r   r   r]   	call_argskwargsgetr$   r   r-   r.   r/   r0   r1   r2   append_format_boolopr3   r4   )!r   rf   rg   r   	mock_postr   r9   r;   rp   @py_assert7@py_assert9@py_assert12@py_assert11r   @py_assert18@py_assert21@py_assert23@py_assert26@py_assert25@py_assert17@py_assert31@py_assert36@py_assert33@py_format14@py_format16@py_format28@py_format30@py_format38@py_format40@py_format41@py_format43@py_format44@py_format46s!                                    r   test_sends_multipart_form_dataz9TestTranscribeAudioSuccess.test_sends_multipart_form_data   s   k)W%!$'!+16*:'5MR 	NV_//H/M	N  ))	
{!! 	
!%% 	
g 	
%g. 	
d 	
.d: 	
  	
 !	
$%	
!A%	
*1	
585E	
*15E*E	
 	
 	
.d 	
 	
	6	
 	
   	
 	
 		  	
 	
 		 " 	
 	
 		 & 	
 	
 		 '. 	
 	
 		 / 	
 	
 		 7; 	
 	
 	
	6	
		
 	
!A	
 	
	6	
 	
  	
 	
 		 	
 	
	6	
 	
  	
 	
 		 	
 	
 		 !	
 	
 		 "	
 	
 		 %&	
 	
 	
	6	
		
 	
*15E	
 	
 		 +2	
 	
	6	
 	
  69	
 	
 		 69	
 	
	6	
 	
  :E	
 	
 		 :E	
 	
 		 6F	
 	
 	
	6	
		
 	
 	
 	
	6	
		
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
	N 	Ns   !Q  Q
c                    |dz  }|j                  d       t               }d|_        ddi|j                  _        t        d|      5 }t        j                  t        |      d	       d
d
d
       j                  }|j                  r|j                  d   n|j                  j                  dd      }d}||v }|st        j                  d|fd||f      t        j                  |      dt!        j"                         v st        j$                  |      rt        j                  |      nddz  }	dd|	iz  }
t'        t        j(                  |
            d
x}}d}||v }|st        j                  d|fd||f      t        j                  |      dt!        j"                         v st        j$                  |      rt        j                  |      nddz  }	dd|	iz  }
t'        t        j(                  |
            d
x}}y
# 1 sw Y   xY w)u/   로컬 Whisper GPU 서비스 URL로 POST 전송rU   rV   r|   r%   r   r   rX   r)   r   Nr   r,    zlocalhost:8200r   r   url_argr   r   r   z/v1/transcribe)ra   r   r   rB   rY   r   r   r   r]   r   r$   r   r   r-   r.   r2   r/   r0   r1   r3   r4   )r   rf   rg   r   r   r   r   r   r   r   r<   s              r   test_sends_correct_urlz1TestTranscribeAudioSuccess.test_sends_correct_url   sj   k)W%!$'!+16*:'5MR 	NV_//H/M	N ''	'0~~)..#9;K;K;O;OPUWY;Z*7****7*********7***7********7****7*********7***7*******	N 	Ns   !G??H	c                 &   |dz  }|j                  d       t               }d|_        ddi|j                  _        t        d|      5 }t        j                  t        |      d	       d
d
d
       j                  j                  }|j                  }d} ||      }d}	||	k(  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      t        j"                  |      t        j"                  |      t        j"                  |	      dz  }dd|iz  }t%        t        j&                  |            d
x}x}x}x}
}	y
# 1 sw Y   xY w)u   timeout=600 으로 POST 전송rU   rV   r|   r%   r   r   rX   r)   r   NtimeoutiX  r!   )zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)sr   )r
   r   r`   rm   py9zassert %(py11)spy11)ra   r   r   rB   rY   r   r   r   r]   r   r   r   r-   r.   r/   r0   r1   r2   r3   r4   )r   rf   rg   r   r   r   r9   r;   rp   @py_assert8r   @py_format10@py_format12s                r   test_timeout_600_secondsz3TestTranscribeAudioSuccess.test_timeout_600_seconds   s%   k)W%!$'!+16*:'5MR 	NV_//H/M	N  ))000y0y)0S0)S0000)S000000{000{000000y000)000S00000000		N 	Ns   !FFN)rN   rO   rP   r   r   r   r   rQ   r?   r   rz   rz      s    $$
$+"1r?   rz   c                       e Zd Zd Zd Zd Zy)TestTranscribeAudioFallbackc                    ddl }|dz  }|j                  d       t        d|j                  j	                  d            5  t
        j                  t        |      d	      }ddd       d
   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}}|j                         }g }d}|j                  }||v }|}|s*d}|j                  }||v }|}|sd}|j                  }||v }|}|s#t        j                  d|fd||f      t        j                  |      dt        j                          v st        j"                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }|j%                  |       |sBt        j                  dfdf      t        j                  |      dt        j                          v st        j"                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }|j%                  |       |st        j                  dfdf      t        j                  |      dt        j                          v st        j"                  |      rt        j                  |      ndt        j                  |      dz  }d d!|iz  }|j%                  |       t        j&                  |d"      i z  }d#d$|iz  }t        t        j                  |            dx}x}x}x}x}x}x}x}x}x}}y# 1 sw Y   xY w)%u8   ConnectionError 시 fallback dict 반환 + 경고 로그r   NrU   rV   r   refusedrw   r)   r   r%   5   로컬 Whisper 서비스가 응답하지 않습니다r!   r   r   r   rm      경고WARNINGWhisperr   z+%(py3)s in %(py7)s
{%(py7)s = %(py5)s.err
}capturedr   r   r   %(py9)sr   z/%(py12)s in %(py16)s
{%(py16)s = %(py14)s.err
}py12py14py16%(py18)spy18z/%(py21)s in %(py25)s
{%(py25)s = %(py23)s.err
}py21py23py25%(py27)sr   r   assert %(py30)spy30)requestsra   r   
exceptionsConnectionErrorr   r   r]   r-   r.   r2   r3   r4   
readouterrerrr/   r0   r1   r   r   r   rf   capsys
req_modulerg   r\   r   r;   r   rj   rq   r   r9   @py_assert6r:   r   @py_assert15@py_assert13@py_assert20@py_assert24@py_assert22r=   r   @py_format17@py_format19@py_format26r   @py_format29@py_format31s                                r   &test_connection_error_returns_fallbackzBTestTranscribeAudioFallback.test_connection_error_returns_fallback   s1   %k)W%."--==iH
 	W (88XQU8VF		W f~X!XX~!XXXXX~!XXXX~XXX!XXXXXXXX$$&axa8<<ax<'a9aa9+Da	aU]UaUaa	UaHaaaaax<aaaxaaaaaa8aaa8aaa<aaaaaaa9aaa9aaaaaaaaaaaaaaaaaaa	Uaaaa	aaaaaaU]aaaU]aaaUaaaaaaaaaaaaaaaa	W 	W   !M99Nc                    ddl }|dz  }|j                  d       t        d|j                  j	                  d            5  t
        j                  t        |      d	      }ddd       d
   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}}|j                         }g }d}|j                  }||v }|}|s*d}|j                  }||v }|}|sd}|j                  }||v }|}|s#t        j                  d|fd||f      t        j                  |      dt        j                          v st        j"                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }|j%                  |       |sBt        j                  dfdf      t        j                  |      dt        j                          v st        j"                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }|j%                  |       |st        j                  dfdf      t        j                  |      dt        j                          v st        j"                  |      rt        j                  |      ndt        j                  |      dz  }d d!|iz  }|j%                  |       t        j&                  |d"      i z  }d#d$|iz  }t        t        j                  |            dx}x}x}x}x}x}x}x}x}x}}y# 1 sw Y   xY w)%u0   Timeout 시 fallback dict 반환 + 경고 로그r   NrU   rV   r   r   r   r)   r   r%   r   r!   r   r   r   rm   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   ra   r   r   Timeoutr   r   r]   r-   r.   r2   r3   r4   r   r   r/   r0   r1   r   r   r   s                                r   #test_timeout_error_returns_fallbackz?TestTranscribeAudioFallback.test_timeout_error_returns_fallback   s1   %k)W%."--55i@
 	W (88XQU8VF		W f~X!XX~!XXXXX~!XXXX~XXX!XXXXXXXX$$&axa8<<ax<'a9aa9+Da	aU]UaUaa	UaHaaaaax<aaaxaaaaaa8aaa8aaa<aaaaaaa9aaa9aaaaaaaaaaaaaaaaaaa	Uaaaa	aaaaaaU]aaaU]aaaUaaaaaaaaaaaaaaaa	W 	Wr  c                    ddl }|dz  }|j                  d       t        d|j                  j	                  d            5  t
        j                  t        |      d	      }ddd       j                  d
g       }g }g }||k(  }|}	|sd}
||
u }|}	|	sXt        j                  d|fd||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      dz  }dd|iz  }|j                  |       |st        j                  dfd|
f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |
      dz  }dd|iz  }|j                  |       t        j                   |d      i z  }dd|iz  }t#        t        j$                  |            dx}	x}x}x}x}}
y# 1 sw Y   xY w)u7   fallback 결과에 segments 키 없거나 빈 리스트r   NrU   rV   r   r   r   r)   r   r   r!   )z%(py2)s == %(py5)s)r   r   z%(py7)sr   r'   )z%(py9)s is %(py12)s)r   r   z%(py14)sr   r   zassert %(py17)spy17)r   ra   r   r   r   r   r   r]   r   r-   r.   r/   r0   r1   r2   r   r   r3   r4   )r   rf   r   rg   r\   r   r9   r:   r;   r   r   @py_assert10r<   r=   @py_format13@py_format15r   @py_format18s                     r   test_fallback_has_no_segmentsz9TestTranscribeAudioFallback.test_fallback_has_no_segments  sG   %k)W%."--==iH
 	W (88XQU8VF		W ::j"-121x2~1T1T!11111x2111111x111x11121111111T111111111111T11111111111111	W 	Ws   !G99HN)rN   rO   rP   r  r  r  rQ   r?   r   r   r      s    b"b"2r?   r   c                   N    e Zd ZdddddddddgdZd	 Zd
 Zd Zd Zd Zd Z	y)TestFormatOutput   안녕하세요 반갑습니다r~   r   r}   r   g      @u   반갑습니다r   c                    t         j                  | j                  d      }d}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}t        |t              }|sd
dt        j                         v st        j                  t              rt        j
                  t              nddt        j                         v st        j                  |      rt        j
                  |      nddt        j                         v st        j                  t              rt        j
                  t              ndt        j
                  |      dz  }t        t        j                  |            d	}y	)u&   text 포맷은 순수 텍스트 반환r%   r  r   r   r6   r   r   r   NrZ   r[   r]   r^   )r   format_outputSAMPLE_RESULTr-   r.   r2   r/   r0   r1   r3   r4   r[   r]   )r   r6   r   r   r   r<   r;   rj   s           r   test_text_formatz!TestFormatOutput.test_text_format,  s    #11$2D2DfM0:0F::::0F:::0::::::F:::F:::::::&#&&&&&&&&z&&&z&&&&&&&&&&&&&&&&&#&&&#&&&&&&&&&&r?   c                 B   t         j                  | j                  d      }t        j                  |      }|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|d
   }t        |      }d}	||	k(  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            d	x}x}x}
}	y	)u5   json 포맷은 파싱 가능한 JSON 문자열 반환rB   r%   r  r!   r   r   r   rm   Nr      )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sr   r
   r   r`   r   assert %(py9)sr   )r   r  r  rB   loadsr-   r.   r2   r3   r4   r   r/   r0   r1   )r   r6   parsedr   r;   r   rj   rq   r9   r  rp   r=   r   s                r   test_json_formatz!TestFormatOutput.test_json_format2  s   #11$2D2DfMF#f~B!BB~!BBBBB~!BBBB~BBB!BBBBBBBB*%+s%&+!+&!++++&!++++++s+++s+++%+++&+++!+++++++r?   c                 "   t         j                  | j                  d      }d}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}d
}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}d}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)u)   srt 포맷은 SRT 형식 문자열 반환rL   1r   r   r6   r   r   r   Nz-->r}   r   r  r  r-   r.   r2   r/   r0   r1   r3   r4   r   r6   r   r   r   r<   s         r   test_srt_formatz TestFormatOutput.test_srt_format9  s&   #11$2D2DeLsf}sfsffuuu * F**** F*** ******F***F*******r?   c                    t         j                  | j                  d      }d}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}d
}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)u8   srt 타임코드가 HH:MM:SS,mmm --> HH:MM:SS,mmm 형식rL   z00:00:00,000r   r   r6   r   r   r   Nz00:00:01,500r(  r)  s         r   test_srt_timecode_formatz)TestFormatOutput.test_srt_timecode_formatA  s    #11$2D2DeL'~''''~'''~'''''''''''''''''~''''~'''~''''''''''''''''r?   c                    ddi}t         j                  |d      }d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d	x}}y	)
u0   segments 없는 경우 text 포맷 정상 동작r%   u	   테스트r   r   r6   r   r   r   N)
r   r  r-   r.   r2   r/   r0   r1   r3   r4   )r   r\   r6   r   r   r   r<   s          r   !test_text_format_without_segmentsz2TestFormatOutput.test_text_format_without_segmentsH  sw    +&#11&&A${f$$$${f$$${$$$$$$f$$$f$$$$$$$r?   c                 b   dg d}t         j                  |d      }t        j                  |      }d}|d   }||v }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }d	d
|iz  }t        t	        j                  |            dx}x}}y)u1   fallback 메시지도 json으로 직렬화 가능r   r   rB   r   r%   r   )z%(py1)s in %(py4)sr   r   rm   N)	r   r  rB   r#  r-   r.   r2   r3   r4   )	r   r\   r6   r$  r   r;   r   rj   rq   s	            r   !test_json_format_fallback_messagez2TestFormatOutput.test_json_format_fallback_messageN  s{    Q_ab#11&&AF#*F6N*yN****yN***y***N*******r?   N)
rN   rO   rP   r  r  r%  r*  r,  r.  r0  rQ   r?   r   r  r  #  sE    1#/@A#/@A
M',+(%+r?   r  c                   0    e Zd Zd Zd Zd Zd Zd Zd Zy)TestMainSuccessc                     dddddgdS )N   테스트 전사 결과r~   g       @r   r   rQ   r   s    r   _make_mock_resultz!TestMainSuccess._make_mock_result\  s    -#&s<UVW
 	
r?   c           	         t        dd      5  t        d| j                               5  t        dd      5  t        d      5  t        j                  g d       d	d	d	       d	d	d	       d	d	d	       d	d	d	       |j	                         }d
}|j
                  }||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}y	# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)u.   정상 흐름: text 포맷으로 stdout 출력!youtube_transcribe.download_audio/tmp/audio.wavrX   #youtube_transcribe.transcribe_audio#youtube_transcribe.tempfile.mkdtemp/tmp/yt_test youtube_transcribe.shutil.rmtreer   r    rA   r%   Nr4  r   z+%(py1)s in %(py5)s
{%(py5)s = %(py3)s.out
}r   r_   r   r   r   r   )r   r5  r   mainr   outr-   r.   r2   r/   r0   r1   r3   r4   )r   r   r   r   r:   r   r<   r=   s           r   test_main_text_to_stdoutz(TestMainSuccess.test_main_text_to_stdoutb  s#   6EUV 	X]1@V@V@XY
 	6^T	V[.W
	
 ##P	 	 	 	 $$&(8HLL8(L8888(L888(888888H888H888L8888888	 	 	 	 	 	 	 	sQ   E9E,E E	E $E,,E9EE  E)%E,,E6	1E99Fc           	         t        dd      5  t        d| j                               5  t        dd      5  t        d      5  t        j                  g d       d	d	d	       d	d	d	       d	d	d	       d	d	d	       |j	                         }t        j                  |j                        }|d
   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}y	# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)u   json 포맷으로 stdout 출력r7  r8  rX   r9  r:  r;  r<  )r   r    rA   rB   Nr%   r4  r!   r   r   r   rm   )r   r5  r   r@  r   rB   r#  rA  r-   r.   r2   r3   r4   )	r   r   r   r$  r   r;   r   rj   rq   s	            r   test_main_json_to_stdoutz(TestMainSuccess.test_main_json_to_stdoutp  s   6EUV 	X]1@V@V@XY
 	6^T	V[.W
	
 ##P	 	 	 	 $$&HLL)f~:!::~!:::::~!::::~:::!::::::::	 	 	 	 	 	 	 	sQ   EED8D,	D8$E,E,D51D88E=EE		EEc                 @   |dz  }t        dd      5  t        d| j                               5  t        dd      5  t        d      5  t        j                  d	d
dddt	        |      g       ddd       ddd       ddd       ddd       |j
                  } |       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}|j                  d      }d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }	dd|	iz  }
t        t        j                  |
            dx}}y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)u$   --output 지정 시 파일에 저장z
result.txtr7  r8  rX   r9  r:  r;  r<  r   r    rA   r%   rC   NzAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}out_file)r
   r   r`   zutf-8)encodingr4  r   r   contentr   r   r   )r   r5  r   r@  r]   existsr/   r0   r-   r1   r2   r3   r4   	read_textr.   )r   rf   rF  r9   r;   rj   rH  r   r   r   r<   s              r   test_main_output_to_filez(TestMainSuccess.test_main_output_to_file  s   l*6EUV 	X]1@V@V@XY
 	6^T	V[.W
	
 ##5M		 	 	 	           x   x             $$g$6(3(G3333(G333(333333G333G3333333%	 	 	 	 	 	 	 	sQ   HHG9	%G,	.G96H>H,G61G99H>HH	HHc           	         t        dd      5  t        d| j                               5  t        dd      5  t        d      5 }t        j                  dd	g       d
d
d
       d
d
d
       d
d
d
       d
d
d
       j	                  dd       y
# 1 sw Y   5xY w# 1 sw Y   9xY w# 1 sw Y   =xY w# 1 sw Y   AxY w)u    임시 디렉토리가 정리됨r7  r8  rX   r9  r:  z/tmp/yt_test_cleanupr<  r   r    NTignore_errors)r   r5  r   r@  assert_called_once_withr   mock_rmtrees     r   test_main_cleans_temp_dirz)TestMainSuccess.test_main_cleans_temp_dir  s    6EUV 		X]1@V@V@XY
 		1@V
		 .
			 ##;<		 		 		 		 	++,BRV+W		 		 		 		 		 		 		 		sQ   B4B(BB	B$B(,B4BBB%!B((B1	-B44B=c           	         t        dd      5  t        d| j                               5 }t        dd      5  t        d      5  t        j                  g d       d	d	d	       d	d	d	       d	d	d	       d	d	d	       j	                          |j
                  }g }|j                  }|j                  }d
} ||      }d}||k(  }	|	}
|	s>g }|j                  }t        |      }d}||kD  }|}|r|j                  d   }d}||k(  }|}|}
|
st        j                  d|	fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }|j!                  |       |	st        j                  dfdf      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                        t        j                  |      t        j                  |      dz  }dd|iz  }j!                  |       |r_t        j                  dfdf      t        j                  |      t        j                  |      dz  }dd|iz  }|j!                  |       t        j"                  |d      i z  }dd|iz  }|j!                  |       t        j"                  |d      i z  }d d!|iz  }t%        t        j&                  |            d	x}
x}x}x}x}x}x}	x}x}x}x}x}x}x}x}x}}y	# 1 sw Y   }xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)"u2   --language 인자가 transcribe_audio에 전달됨r7  r8  rX   r9  r:  r;  r<  )r   r    rE   rF   Nr7   rF   r   r!   )zh%(py10)s
{%(py10)s = %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s.kwargs
}.get
}(%(py8)s)
} == %(py13)sr   r   r   r   r   r   r   r   r   r   )z%(py32)s == %(py35)s)r   r   z%(py37)sr   r   z%(py40)spy40zassert %(py43)spy43)r   r5  r   r@  assert_called_oncer   r   r   r$   r   r-   r.   r/   r0   r1   r2   r   r   r3   r4   )r   mock_transcriber   r9   r;   rp   r   r   r   r   r   r   r   r   r   r   r   r   @py_assert34r   r   r   r   r   @py_format36r   @py_format39r   @py_format42r   s                                 r   'test_main_passes_language_to_transcribez7TestMainSuccess.test_main_passes_language_to_transcribe  s   6EUV 		X]1@V@V@XY
 		e1
		 .
			 ##P		 		 		 		 	**,%//	
{!! 	
!%% 	
j 	
%j1 	
T 	
1T9 	
  	
 !	
$%	
!A%	
*5*:*:1*=	
AE	
*=*E	
 	
 	
1T 	
 	
	6	
 	
   	
 	
 		  	
 	
 		 " 	
 	
 		 & 	
 	
 		 '1 	
 	
 		 2 	
 	
 		 6: 	
 	
 	
	6	
		
 	
!A	
 	
	6	
 	
  	
 	
 		 	
 	
	6	
 	
  	
 	
 		 	
 	
 		 !	
 	
 		 "	
 	
 		 %&	
 	
 	
	6	
		
 	
*=	
 	
 		 +>	
 	
 		 BF	
 	
 	
	6	
		
 	
 	
 	
	6	
		
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
		 		 		 		 		 		 		 		sQ   O>O1O$O	O$$O1,O>O!O$$O.)O11O;	6O>>PN)	rN   rO   rP   r5  rB  rD  rK  rR  r\  rQ   r?   r   r2  r2  [  s!    
9;40X
r?   r2  c                       e Zd Zd Zy)TestMainFallbackc           	         dg d}t        dd      5  t        d|      5  t        dd      5  t        d	      5  t        j                  g d
       ddd       ddd       ddd       ddd       |j                         }d}|j                  }||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)u.   서비스 불가 시 fallback 메시지 출력r   r   r7  r8  rX   r9  r:  r;  r<  r=  Nr   r>  r   r?  r   r   )r   r   r@  r   rA  r-   r.   r2   r/   r0   r1   r3   r4   )	r   r   fallback_resultr   r   r:   r   r<   r=   s	            r   test_fallback_message_in_outputz0TestMainFallback.test_fallback_message_in_output  s,    L

 6EUV 	X]1Y
 	6^T	V[.W
	
 ##P	 	 	 	 $$&FV(,,VF,VVVVF,VVVFVVVVVV(VVV(VVV,VVVVVVV	 	 	 	 	 	 	 	sP   E0E#EE	EE##E0EEE E##E-	(E00E:N)rN   rO   rP   ra  rQ   r?   r   r^  r^    s    Wr?   r^  c                       e Zd Zd Zd Zd Zy)TestExitCodec                 T   dg d}t        dd      5  t        d|      5  t        dd      5  t        d	      5  	 t        j                  d
dg       ddd       ddd       ddd       ddd       y# t        $ r}|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d|j                         dz   d|iz  }t        t        j                  |            dx}x}}Y d}~d}~ww xY w# 1 sw Y   %xY w# 1 sw Y   *xY w# 1 sw Y   /xY w# 1 sw Y   yxY w)u8   성공 시 SystemExit 없이 정상 종료 (exit code 0)u   성공r   r7  r8  rX   r9  r:  r;  r<  r   r    r   r!   )z,%(py2)s
{%(py2)s = %(py0)s.code
} == %(py5)ser   zExpected exit code 0, got z
>assert %(py7)sr   N)r   r   r@  r   coder-   r.   r/   r0   r1   r2   _format_assertmsgr3   r4   )r   mock_resultre  r9   r:   r;   r<   r=   s           r   test_exit_code_0_on_successz(TestExitCode.test_exit_code_0_on_success  sX   'R86EUV 		JX]1Y
 		J6^T		JV[.W
		JJ"''2S(TU		J 		J 		J 		J 		J  JvvIIv{IIIvIIIIIIqIIIqIIIvIIIIII&@$IIIIIIIIJ		J 		J 		J 		J 		J 		J 		J 		Jst   FFFE7	A5FF$F5	E4>C+E/)E7	/E44E7	7F<FF	FF	FF'c           	      D   t        dt        d            5  t        dd      5  t        d      5  t        j                  t              5 }t
        j                  dd	g       d
d
d
       d
d
d
       d
d
d
       d
d
d
       j                  }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                   |            d
x}x}x}}y
# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)u   yt-dlp 실패 시 SystemExit(1)r7  zyt-dlp failedr   r:  r;  rX   r<  r   r    Nr   r!   )zG%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.value
}.code
} == %(py7)sexc_infor!  r"  r   )r   ru   r   r   r   r   r@  valuerf  r-   r.   r/   r0   r1   r2   r3   r4   )r   rk  r9   r;   r  rp   r=   r   s           r   "test_exit_code_1_on_download_errorz/TestExitCode.test_exit_code_1_on_download_error  s;   /Y=W
 	V6^T	VV[.W
	V
 z* Vh"''2S(TUV	V 	V 	V ~~'~""'a'"a''''"a''''''x'''x'''~'''"'''a'''''''V V	V 	V 	V 	V 	V 	VsQ   FFE;E.	#E;+F3F.E83E;;F FF	FFc           	         t        dt        d            5  t        dd      5  t        d      5 }t        j                  t              5  t
        j                  dd	g       d
d
d
       d
d
d
       d
d
d
       d
d
d
       j                  dd       y
# 1 sw Y   5xY w# 1 sw Y   9xY w# 1 sw Y   =xY w# 1 sw Y   AxY w)u2   에러 발생 시에도 임시 디렉토리 정리r7  zdownload errorr   r:  z/tmp/yt_test_errrX   r<  r   r    NTrM  )r   ru   r   r   r   r   r@  rO  rP  s     r   #test_temp_dir_cleaned_even_on_errorz0TestExitCode.test_temp_dir_cleaned_even_on_error  s    /YGW=X
 	V1@R
	V .
		V z* V"''2S(TUV	V 	V 	V 	++,>d+SV V	V 	V 	V 	V 	V 	VsQ   B;B/B#B	#B#+B/3B;B B##B,(B//B8	4B;;CN)rN   rO   rP   ri  rm  ro  rQ   r?   r   rc  rc    s    J
(Tr?   rc  )5__doc__builtinsr/   _pytest.assertion.rewrite	assertionrewriter-   importlib.util	importlibrB   syspathlibr   unittest.mockr   r   r   __file__parent_SCRIPTS_DIRpathinsertr]   _MODULE_PATHutilspec_from_file_locationr	   r   r9   r.   r0   r1   r2   r   r<   r3   r4   module_from_specr   loaderr:   r;   r=   modulesexec_moduler   rS   rz   r   r  r2  r^  rc  rQ   r?   r   <module>r     s  $     
  *  H~$$++ 3|$ % 55~~--.BLQ t4   t4     t   t   4      ^^44T: {{ $ {$   {$     t   t   {  $      $6  !   * ++$ +$f5 5zC1 C1V12 12r0+ 0+p\
 \
HW W4(T (Tr?   