
    (<i	1                         d Z ddlZddlZddlmZ ddlZej                  j                  d e ee	      j                  j                  j                               ddlmZmZmZmZ  G d d      Z G d d      Z G d	 d
      Z G d d      Zy)u-   utils/checkpoint.py 테스트 스위트 (TDD)    N)Path)cleanup_oldlist_checkpointsrestoresnapshotc                       e Zd 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deddfdZdeddfdZy)TestSnapshotu   snapshot() 함수 테스트tmp_pathreturnNc                 z    |dz  }|j                  d       |dz  }t        |d|      }|j                         sJ y)u)   snapshot이 백업 파일을 생성한다
source.txtzoriginal contentcheckpointstestlabelcheckpoint_dirN
write_textr   existsselfr
   sourcer   backup_paths        L/home/jay/workspace/.worktrees/task-2057-dev2/utils/tests/test_checkpoint.py!test_snapshot_creates_backup_filez.TestSnapshot.test_snapshot_creates_backup_file   sE    L(,-!M1vVNS!!###    c                 x    |dz  }|j                  d       |dz  }t        ||      }t        |t              sJ y)u'   snapshot이 Path 객체를 반환한다r   contentr   r   N)r   r   
isinstancer   r   r
   r   r   results        r   test_snapshot_returns_pathz'TestSnapshot.test_snapshot_returns_path   s@    L()$!M1&@&$'''r   c                     |dz  }d}|j                  |       |dz  }t        ||      }|j                         |k(  sJ y)u.   백업 파일 내용이 원본과 동일하다r   zhello world
line 2r   r   N)r   r   	read_text)r   r
   r   originalr   r   s         r   test_snapshot_preserves_contentz,TestSnapshot.test_snapshot_preserves_content&   sL    L(((#!M1vnE$$&(222r   c                     |dz  }|j                  d       |dz  }t        ||      }ddl}|j                  d|j                        sJ y)uS   백업 파일명에 타임스탬프 형식이 포함된다 (YYYYMMDD_HHMMSS_ffffff)z
myfile.txtdatar   r   r   Nz\d{8}_\d{6}_\d{6})r   r   researchname)r   r
   r   r   r   r*   s         r   )test_snapshot_filename_contains_timestampz6TestSnapshot.test_snapshot_filename_contains_timestamp1   sP    L(&!!M1vnE 	yy-{/?/?@@@r   c                 t    |dz  }|j                  d       |dz  }t        ||      }d|j                  v sJ y)u4   백업 파일명에 원본 파일명이 포함된다zimportant.pycoder   r   Nr   r   r,   r   s        r   -test_snapshot_filename_contains_original_namez:TestSnapshot.test_snapshot_filename_contains_original_name>   sD    N*&!!M1vnE!1!1111r   c                 v    |dz  }|j                  d       |dz  }t        |d|      }d|j                  v sJ y)u"   label이 파일명에 포함된다zdata.txtr)   r   before_refactorr   Nr0   r   s        r   test_snapshot_with_labelz%TestSnapshot.test_snapshot_with_labelH   sG    J&&!!M1v->~^ K$4$4444r   c                 x    |dz  }|j                  d       |dz  }t        ||      }|j                         sJ y)u'   label 없이도 스냅샷 생성 가능file.txtr   r   r   Nr   r   s        r   test_snapshot_without_labelz(TestSnapshot.test_snapshot_without_labelR   sB    J&)$!M1vnE!!###r   c                     |dz  }|dz  }t        j                  t              5  t        ||       ddd       y# 1 sw Y   yxY w)u:   존재하지 않는 파일 스냅샷 시 FileNotFoundErrorznonexistent.txtr   r   N)pytestraisesFileNotFoundErrorr   r   r
   r   r   s       r   %test_snapshot_nonexistent_file_raisesz2TestSnapshot.test_snapshot_nonexistent_file_raises\   sC    --!M1]],- 	<VN;	< 	< 	<s	   ;Ac                     |dz  }|j                  d       |dz  dz  dz  }|j                         rJ t        ||       |j                         sJ y)u7   체크포인트 디렉토리가 없으면 자동 생성r6   r)   deepnestedr   r   N)r   r   r   r<   s       r   $test_snapshot_creates_checkpoint_dirz1TestSnapshot.test_snapshot_creates_checkpoint_dird   s\    J&&!!F*X5E!((***7$$&&&r   c                    |dz  }|j                  d       |dz  }t        |d|      }t        j                  d       |j                  d       t        |d|      }||k7  sJ |j	                         sJ |j	                         sJ y)uE   같은 파일을 여러 번 스냅샷 → 여러 백업 파일 생성r6   v1r   r   {Gz?v2N)r   r   timesleepr   )r   r
   r   r   path1path2s         r   -test_snapshot_multiple_creates_multiple_filesz:TestSnapshot.test_snapshot_multiple_creates_multiple_filesp   s    J&$!M1tNK

4$tNK~~||~~||~~r   )__name__
__module____qualname____doc__r   r   r#   r'   r-   r1   r4   r7   r=   rA   rJ    r   r   r	   r	      s    %$$ $4 $(4 (D (	3 	3 	3A$ A4 A2d 2t 25 5$ 5$D $T $<d <t <
'T 
'd 
'd t r   r	   c                   P    e Zd 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y)	TestRestoreu   restore() 함수 테스트r
   r   Nc                     |dz  }|j                  d       |dz  }t        ||      }|j                  d       |j                         dk(  sJ t        ||       |j                         dk(  sJ y)u(   restore가 파일 내용을 복원한다
target.txtr&   r   r   modifiedN)r   r   r%   r   r   s        r   test_restore_recovers_contentz)TestRestore.test_restore_recovers_content   sz    L(*%!M1vnE 	*%!Z/// 	V$!Z///r   c                     |dz  }|j                  d       |dz  }t        ||      }|dz  }t        ||       |j                         dk(  sJ y)u   다른 경로로 복원 가능r   r)   r   r   restored.txtN)r   r   r   r%   r   r
   r   r   r   targets         r   test_restore_to_new_pathz$TestRestore.test_restore_to_new_path   s[    L(&!!M1vnEN*V$!V+++r   c                     |dz  }|dz  }t        j                  t              5  t        ||       ddd       y# 1 sw Y   yxY w)u@   존재하지 않는 체크포인트 복원 시 FileNotFoundErrorznonexistent_checkpoint.txtrS   N)r9   r:   r;   r   )r   r
   fake_checkpointrY   s       r   *test_restore_nonexistent_checkpoint_raisesz6TestRestore.test_restore_nonexistent_checkpoint_raises   sC    "%AAL(]],- 	-OV,	- 	- 	-s	   :Ac                     |dz  }|j                  d       |dz  }t        ||      }|dz  }t        t        |      t        |             |j	                         dk(  sJ y)u   str 타입 경로도 허용r6   r   r   r   rW   N)r   r   r   strr%   rX   s         r   !test_restore_accepts_string_pathsz-TestRestore.test_restore_accepts_string_paths   sd    J&)$!M1vnEN*K #f+.!Y...r   )	rK   rL   rM   rN   r   rU   rZ   r]   r`   rO   r   r   rQ   rQ      sQ    $0d 0t 0 , ,$ ,-4 -D -/$ /4 /r   rQ   c                   p    e Zd 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
y)TestListCheckpointsu#   list_checkpoints() 함수 테스트r
   r   Nc                     |dz  }|j                  d       |dz  }t        ||       t        ||      }t        |t              sJ t        |      dkD  sJ t        |d   t              sJ y)u2   list_checkpoints가 dict 리스트를 반환한다r6   r)   r   r   r   N)r   r   r   r    listlendictr!   s        r   test_list_returns_list_of_dictsz3TestListCheckpoints.test_list_returns_list_of_dicts   sn    J&&!!M17!&H&$'''6{Q&)T***r   c                     |dz  }|j                  d       |dz  }t        |d|       t        ||      }t        |      dk(  sJ |d   }d	|v sJ d
|v sJ d|v sJ d|v sJ y)uJ   반환 dict에 필수 키가 있다: path, label, timestamp, original_pathr6   r)   r   mylabelr   r      r   pathr   	timestamporiginal_pathNr   r   r   re   )r   r
   r   r   r"   entrys         r    test_list_dict_has_required_keysz4TestListCheckpoints.test_list_dict_has_required_keys   s    J&&!!M1yH!&H6{aq	%e###%'''r   c                 ,   |dz  }|j                  d       |dz  }t        |d|       t        j                  d       |j                  d       t        |d|       t	        ||	      }t        |      d
k(  sJ |d   d   dk(  sJ |d   d   dk(  sJ y)u'   최신 체크포인트가 먼저 온다r6   rC   r   firstr   g{Gz?rE   secondr      r   r   rj   N)r   r   rF   rG   r   re   r!   s        r   test_list_sorted_newest_firstz1TestListCheckpoints.test_list_sorted_newest_first   s    J&$!M1w~F

4$xG!&H6{aay!X---ay!W,,,r   c                     |dz  }|j                  d       |dz  }t        |d|       t        ||      }|d   d   dk(  sJ y	)
u   label이 결과에 포함된다r6   r)   r   my_labelr   r   r   r   N)r   r   r   r!   s        r   test_list_label_in_resultz-TestListCheckpoints.test_list_label_in_result   sS    J&&!!M1z.I!&Hay!Z///r   c                 @    |dz  }|dz  }t        ||      }|g k(  sJ y)u1   체크포인트가 없으면 빈 리스트 반환r6   r   r   N)r   r!   s        r   "test_list_empty_for_no_checkpointsz6TestListCheckpoints.test_list_empty_for_no_checkpoints   s.    J&!M1!&H||r   c                     |dz  }|dz  }|j                  d       |j                  d       |dz  }t        |d|       t        |d|       t        ||	      }t        |      d
k(  sJ |d   d   dk(  sJ y)u:   다른 파일의 체크포인트는 포함되지 않는다za.txtzb.txtz	a contentz	b contentr   snap_ar   snap_br   rj   r   r   Nrn   )r   r
   file_afile_br   result_as         r   "test_list_only_shows_matching_filez6TestListCheckpoints.test_list_only_shows_matching_file   s    G#G#+&+&!M1xGxG#F>J8}!!!{7#x///r   )rK   rL   rM   rN   r   rg   rp   ru   rx   rz   r   rO   r   r   rb   rb      sw    -+ + +( ($ ("-d -t -$	0$ 	04 	04 D 04 0D 0r   rb   c                   `    e Zd 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)
TestCleanupOldu   cleanup_old() 함수 테스트r
   r   Nc                 
   |dz  }|j                  d       |dz  }t        d      D ](  }t        j                  d       t	        |d| |       * t        |d|	      }|d
k(  sJ t        ||      }t        |      dk(  sJ y)u2   keep 개수 초과 체크포인트를 삭제한다r6   r)   r      rD   snap_r      keepr   rt   r   Nr   rangerF   rG   r   r   r   re   r   r
   r   r   ideleted	remainings          r   $test_cleanup_removes_old_checkpointsz3TestCleanupOld.test_cleanup_removes_old_checkpoints  s    J&&!!M1q 	OAJJtVU1#;~N	O f1^L!||$VNK	9~"""r   c                 0   |dz  }|j                  d       |dz  }t        d      D ](  }t        j                  d       t	        |d| |       * t        |d|	       t        ||
      }t        |      dk(  sJ |d   d   dk(  sJ |d   d   dk(  sJ y)u.   정리 후 최신 체크포인트가 남는다r6   r)   r      rD   r   r   rt   r   r   r   r   snap_3rj   snap_2Nr   )r   r
   r   r   r   r   s         r   test_cleanup_keeps_newestz(TestCleanupOld.test_cleanup_keeps_newest!  s    J&&!!M1q 	OAJJtVU1#;~N	O 	F>B$VNK	9~"""|G$000|G$000r   c                 ~    |dz  }|j                  d       |dz  }t        ||       t        |d|      }|dk(  sJ y)	u#   삭제할 것이 없으면 0 반환r6   r)   r   r   
   r   r   N)r   r   r   )r   r
   r   r   r   s        r   0test_cleanup_returns_zero_when_nothing_to_deletez?TestCleanupOld.test_cleanup_returns_zero_when_nothing_to_delete3  sH    J&&!!M17f2nM!||r   c                     |dz  }|j                  d       |dz  }t        d      D ](  }t        j                  d       t	        |d| |       * t        |d|	      }|d
k(  sJ y)u$   삭제된 파일 수를 반환한다r6   r)   r      rD   sr   rt   r   r   N)r   r   rF   rG   r   r   )r   r
   r   r   r   r   s         r   "test_cleanup_returns_deleted_countz1TestCleanupOld.test_cleanup_returns_deleted_count>  ss    J&&!!M1q 	KAJJtVQqc7>J	K f1^L!||r   c                    |dz  }|j                  d       |dz  }t        d      D ](  }t        j                  d       t	        |d| |       * t        ||      }|d	k(  sJ t        ||      }t        |      d
k(  sJ y)u   기본 keep=10r6   r)   r      rD   r   r   r   rt   r   Nr   r   s          r   test_cleanup_default_keep_is_10z.TestCleanupOld.test_cleanup_default_keep_is_10L  s    J&&!!M1r 	KAJJtVQqc7>J	K f^D!||$VNK	9~###r   )
rK   rL   rM   rN   r   r   r   r   r   r   rO   r   r   r   r     se    (#T #d #"1$ 14 1$	 	RV 	4 D $ $ $r   r   )rN   sysrF   pathlibr   r9   rk   insertr_   __file__parentutils.checkpointr   r   r   r   r	   rQ   rb   r   rO   r   r   <module>r      sx    3 
    3tH~,,33::; < M Mo od3/ 3/lS0 S0lM$ M$r   