
    )\i;                        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
Z
ddlZddlmZ ddlZ ee      j                   j                   dz  Ze
j$                  j'                  d ee             ddlZej.                  j1                  dedz        Zej.                  j5                  e      Zej8                  j;                  e       ddlZej@                  dedefd	       Z!ej@                  d
ede"f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* G d d      Z+ G d d      Z, G d d      Z-y) u   todo-manager.py 테스트 (task-864.1)

모든 서브커맨드 정상 동작, 에러 케이스, JSON 무결성 검증 테스트.
    N)Pathmemorytodo_managerztodo-manager.pytmp_pathreturnc              #   
  K   t         j                  }t         j                  }t         j                  }| dz  t         _        | dz  t         _        | dz  t         _        |  |t         _        |t         _        |t         _        yw)u]   임시 디렉토리에서 테스트 (todo_utils의 파일 경로를 임시 경로로 패치).z	todo.jsonztodo.json.bakztodo-removed.jsonN)tu	TODO_FILEBACKUP_FILEREMOVED_FILE)r   	orig_todoorig_backuporig_removeds       ./home/jay/workspace/tests/test_todo_manager.pytemp_todo_dirr      sb      I..K??Lk)BL/BN!44BO
NBL BN"BOs   BBr   c                     ddddddddd	g d
dd	dddddgd
dddddddd	dgg d
gd	d}t         j                  |       |S )u   샘플 todo.json 생성.1.0	issue-001TestProj   테스트 이슈 1u   설명highpendingz2026-01-01T00:00:00N   서브1F)titledonetask_idu   서브2Tztask-001)
idprojectr   descriptionprioritystatus
created_atcompleted_atlinked_tasks	sub_items	issue-002	OtherProju   테스트 이슈 2 mediumin_progressz2026-01-02T00:00:00task-002)versionissueslast_synced)tm	save_todo)r   datas     r   sample_todor2   0   s      "%-'"#3 $ "'4H'*M  "&-!$'3 $!+!
: ? DB LLK    c                       e Zd ZdZdeddfdZdededdfdZdeddfdZdededdfd	Z	dededdfd
Z
dededdfdZy)TestLoadSaveu   로드/저장 테스트.r   r   Nc                 ,   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	   }g }||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)
u   빈 파일 로드.r,   r   ==z%(py1)s == %(py4)spy1py4assert %(py6)spy6Nr-   )r/   	load_todo
@pytest_ar_call_reprcompare	_safereprAssertionError_format_explanation)selfr   r1   @py_assert0@py_assert3@py_assert2@py_format5@py_format7s           r   test_load_emptyzTestLoadSave.test_load_empty[   s    ||~I'%'%''''%''''''%'''''''H~##~####~###~##########r3   r2   c                    t         j                         }|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}}|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}}y	)u   기존 파일 로드.r-      r7   z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)slenpy0py2r<   py7assert %(py9)spy9Nr   r   r   r9   r:   r=   r>   )r/   r?   rO   r@   rA   @py_builtinslocals_should_repr_global_namerB   rC   rD   )rE   r   r2   r1   @py_assert1rG   @py_assert6@py_assert5@py_format8@py_format10rF   rH   rI   rJ   s                 r   test_load_existingzTestLoadSave.test_load_existinga   s    ||~>'s>"'a'"a''''"a''''''s'''s'''>'''"'''a'''''''H~a &5+5&+5555&+555&555+5555555r3   c                    dg d}t         j                  |       t        j                  }|j                  } |       }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            dx}x}}y)u   저장 시 파일 생성.r   )r,   r-   z`assert %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.TODO_FILE
}.exists
}()
}r	   rQ   rR   r<   r>   N)r/   r0   r	   r
   existsrV   rW   r@   rX   rB   rC   rD   )rE   r   r1   rY   rG   r[   rJ   s          r   test_save_creates_filez#TestLoadSave.test_save_creates_fileg   s     B/
T||$|""$"$$$$$$$$r$$$r$$$|$$$"$$$$$$$$$$r3   c                    t         j                         }d|d   d   d<   t         j                  |       t        j                  }|j
                  } |       }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            dx}x}}y)	u   저장 시 백업 생성.u	   수정됨r-   r   r   zbassert %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.BACKUP_FILE
}.exists
}()
}r	   r`   N)r/   r?   r0   r	   r   ra   rV   rW   r@   rX   rB   rC   rD   )rE   r   r2   r1   rY   rG   r[   rJ   s           r   test_save_creates_backupz%TestLoadSave.test_save_creates_backupm   s    ||~%0Xq'"
T~~&~$$&$&&&&&&&&r&&&r&&&~&&&$&&&&&&&&&&r3   c                    t         j                         }|d   j                  dddd       t         j                  |       t         j                         }|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)u   atomic write 검증.r-   z	issue-003XY)r   r   r      r7   rN   rO   rP   rT   rU   N)r/   r?   appendr0   rO   r@   rA   rV   rW   rX   rB   rC   rD   )rE   r   r2   r1   reloadedrY   rG   rZ   r[   r\   r]   s              r   test_atomic_writezTestLoadSave.test_atomic_writet   s    ||~X[S3OP 	T <<>H%+s%&+!+&!++++&!++++++s+++s+++%+++&+++!+++++++r3   c                 ~   t         j                         }t         j                  |       t        t        j
                  d      5 }t        j                  |      }ddd       |k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      nddz  }d	d
|iz  }t        t        j                  |            d}y# 1 sw Y   xY w)u(   JSON 검증 (깨진 JSON 저장 방지).utf-8encodingNr7   )z%(py0)s == %(py2)srj   r1   )rQ   rR   zassert %(py4)sr<   )r/   r?   r0   openr	   r
   jsonloadr@   rA   rV   rW   rX   rB   rC   rD   )	rE   r   r2   r1   frj   rY   @py_format3rI   s	            r   test_json_validationz!TestLoadSave.test_json_validation   s    ||~
T ",,1 	$Qyy|H	$4x4xx44	$ 	$s   D33D<)__name__
__module____qualname____doc__r   rK   dictr^   rb   rd   rk   ru    r3   r   r5   r5   X   s    "$T $d $6 64 6D 6%D %T %'d ' 'RV '
,t 
,$ 
,4 
,	 $ 	 T 	 d 	 r3   r5   c                   L    e Zd ZdZdededdfdZdededdfdZdededdfdZy)	TestListu   list 서브커맨드 테스트.r   r2   r   Nc                    ddl }|j                  ddd      }t        j                  |       |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}	}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)u   전체 목록.r   NFr   r!   rq   r   inz+%(py1)s in %(py5)s
{%(py5)s = %(py3)s.out
}capturedr;   py3py5assert %(py7)srS   r&   argparse	Namespacer/   cmd_list
readouterroutr@   rA   rB   rV   rW   rX   rC   rD   rE   r   r2   capsysr   argsr   rF   @py_assert4rH   @py_format6r\   s               r   test_list_allzTestList.test_list_all   s   !!$t%!H
D$$&*hll*{l****{l***{******h***h***l********hll*{l****{l***{******h***h***l*******r3   c                    ddl }|j                  ddd      }t        j                  |       |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}	}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)u   프로젝트 필터.r   Nr   Fr   r   r   r   r   r   r   rS   r&   not inz/%(py1)s not in %(py5)s
{%(py5)s = %(py3)s.out
}r   r   s               r   test_list_filter_projectz!TestList.test_list_filter_project   s    	!!*T!N
D$$&*hll*{l****{l***{******h***h***l*******.(,,.{,....{,...{......(...(...,.......r3   c                    ddl }|j                  ddd      }t        j                  |       |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}	}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)u   상태 필터.r   Nr*   Fr   r   r   r   r   r   r   rS   r&   r   r   r   r   s               r   test_list_filter_statusz TestList.test_list_filter_status   s    	!!$}5!Q
D$$&.(,,.{,....{,...{......(...(...,.......*hll*{l****{l***{******h***h***l*******r3   )	rv   rw   rx   ry   r   rz   r   r   r   r{   r3   r   r}   r}      sY    )+4 +d +t +
/!
/04
/	
/
+!
+04
+	
+r3   r}   c                   8    e Zd ZdZdededdfdZdededdfdZy)TestShowu   show 서브커맨드 테스트.r   r2   r   Nc                 
   ddl }|j                  dd      }t        j                  |       |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)u   존재하는 이슈 조회.r   Nr   Fissue_idrq   r   r   r   r   r   r   rS   )r   r   r/   cmd_showr   r   r@   rA   rB   rV   rW   rX   rC   rD   r   s               r   test_show_existingzTestShow.test_show_existing   s     	!!;U!C
D$$&#3x||3#|3333#|333#333333x333x333|3333333r3   c                    ddl }|j                  dd      }t        j                  t              5 }t
        j                  |       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)   존재하지 않는 이슈.r   N	issue-999Fr      r7   )zG%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.value
}.code
} == %(py7)sexcrP   rT   rU   )r   r   pytestraises
SystemExitr/   r   valuecoder@   rA   rV   rW   rX   rB   rC   rD   )rE   r   r2   r   r   r   rY   rG   rZ   r[   r\   r]   s               r   test_show_not_foundzTestShow.test_show_not_found   s    !!;U!C]]:& 	#KK	yy"y~~""~""""~""""""s"""s"""y"""~""""""""""	 	s   D::E)rv   rw   rx   ry   r   rz   r   r   r{   r3   r   r   r      s<    )	4!	404	4		4# #D #T #r3   r   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y)TestAddu   add 서브커맨드 테스트.r   r   Nc                    ddl }|j                  dddddd      }t        j                  |       |j	                         }g }d}|j
                  }|j                  }	 |	       }
||
v }|}|s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                  |      t        j                  |	      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}}t        j#                         }|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}}|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}}y)"u   최소 필드로 추가.r   NNewProju
   새 이슈Fr   r   r    r!   r   rq   successz"id"r   )z_%(py3)s in %(py11)s
{%(py11)s = %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s.out
}.lower
}()
}r   )r   r   rS   rU   py11z%(py13)spy13)z/%(py16)s in %(py20)s
{%(py20)s = %(py18)s.out
})py16py18py20z%(py22)spy22r   zassert %(py25)spy25r-   r7   rN   rO   rP   rT   rU   r   r9   r:   r=   r>   )r   r   r/   cmd_addr   r   lowerr@   rA   rB   rV   rW   rX   ri   _format_booloprC   rD   r?   rO   )rE   r   r   r   r   r   rY   rH   rZ   @py_assert8@py_assert10r   rF   @py_assert15@py_assert19@py_assert17@py_format12@py_format14@py_format21@py_format23@py_format24@py_format26r1   rG   r[   r\   r]   rI   rJ   s                                r   test_add_minimalzTestAdd.test_add_minimal   sQ   !! " 
 	

4$$&JyJHLLJL..J.0Jy00JFJhllJFl4JJJJJy0JJJyJJJJJJHJJJHJJJLJJJ.JJJ0JJJJJJJFlJJJFJJJJJJhJJJhJJJlJJJJJJJJJJJJJJJ||~>'s>"'a'"a''''"a''''''s'''s'''>'''"'''a'''''''H~a +8y8+y8888+y888+888y8888888r3   c                    ddl }|j                  dddddd	      }t        j                  |       t        j	                         }|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   }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   }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)u   모든 필드로 추가.r   NFullProju   전체 이슈r   r*   u   상세 설명Fr   r-   r    r7   r9   r:   r=   r>   r!   r   )
r   r   r/   r   r?   r@   rA   rB   rC   rD   )rE   r   r   r   r1   issuerF   rG   rH   rI   rJ   s              r   test_add_fullzTestAdd.test_add_full   sE   !!! ' " 
 	

4||~Xq!Z *F* F**** F*** ***F*******X/-/-////-//////-///////]#66#6666#666#6666666666r3   c           	         ddl }|j                  dddddd      }t        j                  |       |j                  dddddd      }t        j                  |       t        j	                         }|d   D cg c]  }|d	   	 }}t        |      }t        |      }	d
}
|	|
k(  }|sSt        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                  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  }t        t        j                  |            dx}x}	x}}
yc c}w )u   ID 자동 생성.r   NPT1Fr   T2r-   r   rM   r7   )zN%(py6)s
{%(py6)s = %(py0)s(%(py4)s
{%(py4)s = %(py1)s(%(py2)s)
})
} == %(py9)srO   setids)rQ   r;   rR   r<   r>   rU   zassert %(py11)sr   )r   r   r/   r   r?   r   rO   r@   rA   rV   rW   rX   rB   rC   rD   )rE   r   r   args1args2r1   ir   rG   r[   r   @py_assert7r]   r   s                 r   test_auto_id_generationzTestAdd.test_auto_id_generation   sU    ""td4TX] # 
 	

5 ""td4TX] # 
 	

5||~ $X/1qw//s8!s8}!!}!!!!}!!!!!!s!!!s!!!!!!3!!!3!!!!!!s!!!s!!!8!!!}!!!!!!!!!! 0s   8H)rv   rw   rx   ry   r   r   r   r   r{   r3   r   r   r      s>    (9d 9t 9(74 7D 7("T "d "r3   r   c                   L    e Zd ZdZdededdfdZdededdfdZdededdfdZy)	
TestUpdateu!   update 서브커맨드 테스트.r   r2   r   Nc                    ddl }|j                  ddddd      }t        j                  |       t        j	                         }t        j                  |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   }d}||u}	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      d
z  }
dd|
iz  }t        t        j                  |            dx}x}	}y)u   상태 수정.r   Nr   r   Fr   r!   r    r   rq   r!   r7   r9   r:   r=   r>   r#   )is not)z%(py1)s is not %(py4)sr   r   r/   
cmd_updater?   
find_issuer@   rA   rB   rC   rD   rE   r   r2   r   r   r1   r   rF   rG   rH   rI   rJ   s               r   test_update_statuszTestUpdate.test_update_status  s    !! $dQV " 
 	d||~dK0X(&(&((((&((((((&(((((((^$0D0$D0000$D000$000D0000000r3   c                    ddl }|j                  ddddd      }t        j                  |       t        j	                         }t        j                  |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}
}	y)u   우선순위 수정.r   Nr   lowFr   r    r7   r9   r:   r=   r>   r   )rE   r   r2   r   r   r   r1   r   rF   rG   rH   rI   rJ   s                r   test_update_priorityzTestUpdate.test_update_priority  s     	!! TPU " 
 	d||~dK0Z )E) E)))) E))) )))E)))))))r3   c                     ddl }|j                  ddddd      }t        j                  t              5  t
        j                  |       ddd       y# 1 sw Y   yxY w)r   r   Nr   r   Fr   )r   r   r   r   r   r/   r   rE   r   r2   r   r   s        r   test_update_not_foundz TestUpdate.test_update_not_found*  sU    !! $dQV " 
 ]]:& 	 MM$	  	  	    AA)	rv   rw   rx   ry   r   rz   r   r   r   r{   r3   r   r   r   
  sV    +1 14 1D 1*!*04*	* 4  d  t  r3   r   c                   L    e Zd ZdZdededdfdZdededdfdZdededdfdZy)	
TestRemoveu!   remove 서브커맨드 테스트.r   r2   r   Nc                    ddl }|j                  dd        |j                  ddd      }t        j	                  |       t        j                         }|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}
}	|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}}y)u   확인 후 삭제.r   Nzbuiltins.inputc                      y)Nyr{   )_s    r   <lambda>z5TestRemove.test_remove_with_confirm.<locals>.<lambda>>  s    r3   r   Fr   forcerq   r-   r   r7   rN   rO   rP   rT   rU   r   r&   r9   r:   r=   r>   )r   setattrr   r/   
cmd_remover?   rO   r@   rA   rV   rW   rX   rB   rC   rD   )rE   r   r2   monkeypatchr   r   r1   rY   rG   rZ   r[   r\   r]   rF   rH   rI   rJ   s                    r   test_remove_with_confirmz#TestRemove.test_remove_with_confirm8  s&    	,m<!!;e%!P
d||~>'s>"'a'"a''''"a''''''s'''s'''>'''"'''a'''''''H~a &5+5&+5555&+555&555+5555555r3   c                 Z   ddl }|j                  ddd      }t        j                  |       t        j	                         }|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)u   강제 삭제.r   Nr   TFr   r-   r   r7   rN   rO   rP   rT   rU   )r   r   r/   r   r?   rO   r@   rA   rV   rW   rX   rB   rC   rD   )rE   r   r2   r   r   r1   rY   rG   rZ   r[   r\   r]   s               r   test_remove_forcezTestRemove.test_remove_forceF  s    !!;d!O
d||~>'s>"'a'"a''''"a''''''s'''s'''>'''"'''a'''''''r3   c                 r   ddl }|j                  ddd      }t        j                  |       t        j
                  }|j                  } |       }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      t        j                  |      d	z  }t        t        j                  |            dx}x}}t        t        j
                  d
      5 }	t        j                   |	      }
ddd       
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}}|
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}}y# 1 sw Y   {xY w)u   삭제된 이슈 백업.r   Nr   TFr   zcassert %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.REMOVED_FILE
}.exists
}()
}r	   r`   rm   rn   removedr   r7   rN   rO   rP   rT   rU   r   r9   r:   r=   r>   )r   r   r/   r   r	   r   ra   rV   rW   r@   rX   rB   rC   rD   rp   rq   rr   rO   rA   )rE   r   r2   r   r   rY   rG   r[   rJ   rs   r   rZ   r\   r]   rF   rH   rI   s                    r   test_remove_creates_backupz%TestRemove.test_remove_creates_backupP  s    	!!;d!O
d'%%'%''''''''r'''r''''''%''''''''''"//G4 	#iilG	#9%+s%&+!+&!++++&!++++++s+++s+++%+++&+++!+++++++y!!$T*9k9*k9999*k999*999k9999999	# 	#s   J,,J6)	rv   rw   rx   ry   r   rz   r   r   r   r{   r3   r   r   r   5  sY    +6!6046	6(t ($ (4 (:!:04:	:r3   r   c                   $    e Zd ZdZdededdfdZy)
TestSubAddu"   sub-add 서브커맨드 테스트.r   r2   r   Nc                    ddl }|j                  ddd      }t        j                  |       t        j	                         }t        j                  |d      }|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}
}	|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   d   d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)u   sub_item 추가.r   Nr   u
   새 서브F)r   r   rq   r%   rh   r7   rN   rO   rP   rT   rU   rM   r   r9   r:   r=   r>   r   isz%(py1)s is %(py4)s)r   r   r/   cmd_sub_addr?   r   rO   r@   rA   rV   rW   rX   rB   rC   rD   )rE   r   r2   r   r   r1   r   rY   rG   rZ   r[   r\   r]   rF   rH   rI   rJ   s                    r   test_sub_addzTestSubAdd.test_sub_addc  s   !!;lQV!W
t||~dK0%+s%&+!+&!++++&!++++++s+++s+++%+++&+++!+++++++[!!$W-==-====-===-==========[!!$V,55,5555,555,5555555555r3   )rv   rw   rx   ry   r   rz   r  r{   r3   r   r   r   `  s    ,6$ 6T 6d 6r3   r   c                   `    e Zd ZdZdededdfdZdededdfdZdededdfdZdededdfd	Z	y)
TestSubDoneu#   sub-done 서브커맨드 테스트.r   r2   r   Nc                    ddl }|j                  ddddd      }t        j                  |       t        j	                         }t        j                  |d      }|d   d   d   }d	}||u }	|	slt        j                  d
|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}	}|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}	}y)u   인덱스로 완료.r   Nr   ztask-123Fr   indexmatchr   rq   r%   r   Tr   r   r:   r=   r>   r   r7   r9   r   r   r/   cmd_sub_doner?   r   r@   rA   rB   rC   rD   r   s               r   test_sub_done_by_indexz"TestSubDone.test_sub_done_by_indext  s   !! zPU " 
 	||~dK0[!!$V,44,4444,444,4444444444[!!$Y/=:=/:====/:===/===:=======r3   c                    ddl }|j                  ddddd      }t        j                  |       t        j	                         }t        j                  |d      }|d   d   d	   }d
}||u }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }
dd|
iz  }t        t        j                  |            dx}x}	}y)u   매칭으로 완료.r   Nr   r   ztask-456Fr  r%   r   Tr   r   r:   r=   r>   r	  r   s               r   test_sub_done_by_matchz"TestSubDone.test_sub_done_by_match  s    !! IzX] " 
 	||~dK0[!!$V,44,4444,444,4444444444r3   c                     ddl }|j                  ddddd      }t        j                  t              5  t
        j                  |       ddd       y# 1 sw Y   yxY w)u   잘못된 인덱스.r   Nr   c   task-789Fr  r   r   r   r   r   r/   r
  r   s        r   test_sub_done_invalid_indexz'TestSubDone.test_sub_done_invalid_index  sW     	!! $
QV " 
 ]]:& 	"OOD!	" 	" 	"r   c                     ddl }|j                  ddddd      }t        j                  t              5  t
        j                  |       ddd       y# 1 sw Y   yxY w)u   매칭 없음.r   Nr   u	   없는거ztask-000Fr  r  r   s        r   test_sub_done_no_matchz"TestSubDone.test_sub_done_no_match  sX    !!  " 
 ]]:& 	"OOD!	" 	" 	"r   )
rv   rw   rx   ry   r   rz   r  r  r  r  r{   r3   r   r  r  q  ss    ->D >t >PT >5D 5t 5PT 5
"!
"04
"	
""D "t "PT "r3   r  c                   8    e Zd ZdZdededdfdZdededdfdZy)TestLinku   link 서브커맨드 테스트.r   r2   r   Nc                    ddl }|j                  ddd      }t        j                  |       t        j	                         }t        j                  |d      }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)u   새 링크 추가.r   Nr   r  Fr   r   rq   r$   r   )z%(py1)s in %(py4)sr:   r=   r>   )r   r   r/   cmd_linkr?   r   r@   rA   rB   rC   rD   r   s               r   test_link_newzTestLink.test_link_new  s    !!;
QV!W
D||~dK02U>22z22222z2222z22222222222r3   c                 b   ddl }|j                  ddd      }t        j                  |       t        j	                         }t        j                  |d      }|d   }|j                  }d}	 ||	      }
d}|
|k(  }|st        j                  d	|fd
|
|f      t        j                  |      t        j                  |      t        j                  |	      t        j                  |
      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}	x}
x}}y)u   중복 링크 방지.r   Nr&   r+   Fr  r$   r   r7   )zL%(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.count
}(%(py5)s)
} == %(py10)s)r;   r   r   rS   py10zassert %(py12)spy12)r   r   r/   r  r?   r   countr@   rA   rB   rC   rD   )rE   r   r2   r   r   r1   r   rF   rH   r   rZ   @py_assert9r   @py_format11@py_format13s                  r   test_link_duplicatezTestLink.test_link_duplicate  s    !!;
QV!W
D||~dK0^$;$**;:;*:6;!;6!;;;;6!;;;$;;;*;;;:;;;6;;;!;;;;;;;;r3   )rv   rw   rx   ry   r   rz   r  r"  r{   r3   r   r  r    s9    )	34 	3d 	3t 	3	< 	<D 	<T 	<r3   r  c                   $    e Zd ZdZdededdfdZy)TestJsonIntegrityu   JSON 무결성 테스트.r   r2   r   Nc                    t         j                  dgfd}|j                  t         d|       t        j	                         }d|d   d   d<   t        j                  t         j                        5  t        j                  |       ddd       t        t        j                  d	      5 }t        j                  |      }d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}
}	y# 1 sw Y   xY w# 1 sw Y   xY w)u   저장 전 JSON 검증.r   c                 l    dxx   dz  cc<   d   dk(  rt        j                  ddd       |       S )Nr   r   rM   testr(   )rq   JSONDecodeError)fp
call_countoriginal_loads    r   tracked_loadz@TestJsonIntegrity.test_save_validates_json.<locals>.tracked_load  s=    qMQM!}!**62q99 $$r3   rr   u   수정r-   r   Nrm   rn   r   r7   r9   r:   r=   r>   )rq   rr   r   r/   r?   r   r   r(  r0   rp   r	   r
   r@   rA   rB   rC   rD   )rE   r   r2   r   r,  r1   rs   originalrF   rG   rH   rI   rJ   r*  r+  s                @@r   test_save_validates_jsonz*TestJsonIntegrity.test_save_validates_json  s    		S
	% 	D&,7||~%-Xq'"]]4//0 	LL	 ",,1 	$Qyy|H	$!!$W-E1EE-1EEEEE-1EEEE-EEE1EEEEEEEE	 		$ 	$s   5E.EEE()rv   rw   rx   ry   r   rz   r.  r{   r3   r   r$  r$    s&    #F!F04F	Fr3   r$  ).ry   builtinsrV   _pytest.assertion.rewrite	assertionrewriter@   rq   osshutilsystempfilepathlibr   r   __file__parent
MEMORY_DIRpathinsertstrimportlib.util	importlibutilspec_from_file_locationspecmodule_from_specr/   loaderexec_module
todo_utilsr	   fixturer   rz   r2   r5   r}   r   r   r   r   r   r  r  r$  r{   r3   r   <module>rH     s\  
   	  
    (^""))H4
 3z? # ~~--njK\>\]^^$$T*      #D #T # #" $t $ $ $N1  1 h#+ #+L# #0=" ="@(  ( V(: (:V6 6"6" 6"r< <4F Fr3   