
    AiH                     r   d Z ddlZddlmc m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mZm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)uw  
test_memory_check.py

utils/memory_check.py — Memory Check Confirmation Number System 단위 테스트
작성자: 아르고스 (개발1팀 테스트 전문가)

테스트 항목:
- parse_star_items(): MEMORY.md에서 ★ 포함 라인 추출
- find_feedback_files(): feedback_*.md 패턴 파일 목록 반환
- match_feedback_to_task(): task 키워드 기반 feedback 파일 매칭
- get_next_mc_id(): 로그 기반 다음 MC-XXXX ID 생성
- issue_mc(): MC 발급 + 로그 파일 기록
- get_unchecked_tasks(): running 태스크 중 MC 미발급 목록 반환

격리: pytest tmp_path fixture로 파일시스템 완전 격리
    N)Path)find_feedback_filesget_next_mc_idget_unchecked_tasksissue_mcmatch_feedback_to_taskparse_star_itemsc                   (    e Zd ZdZd Zd Zd Zd Zy)TestParseStarItemsu+   parse_star_items(memory_path) 동작 검증c                    |dz  }|j                  dd       t        |      }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
}t        |      }d}||k(  }|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                  |      dz  }	dd|	iz  }
t        t        j                  |
            d
x}x}}y
)u:   ★ 포함 라인 3개가 있는 MEMORY.md → 3개 반환	MEMORY.mdu   # 팀 메모리
- 일반 항목
★ [팀 라우팅 가이드](feedback_design_team_routing_v2.md)
★ [배포 체크리스트](deploy_checklist.md)
★ 코드 리뷰 필수 확인 사항
## 기타
- 참고 링크
utf-8encoding5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstanceresultlistpy0py1py2py4N   ==z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr   r   py3py6assert %(py8)spy8)
write_textr	   r   r   @py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanationr   _call_reprcompare)selftmp_path	memory_mdr   @py_assert3@py_format5@py_assert2@py_assert5@py_assert4@py_format7@py_format9s              ./home/jay/workspace/tests/test_memory_check.pytest_parse_star_items_normalz/TestParseStarItems.test_parse_star_items_normal0   sI   {*	   	 		
 "),&$''''''''z'''z''''''&'''&''''''$'''$''''''''''6{a{a{ass66{a    c                    |dz  }|j                  dd       t        |      }g }||k(  }|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  }t        t        j                  |            dx}}y)u#   빈 파일 → 빈 리스트 반환r    r   r   r   z%(py0)s == %(py3)sr   r   r    assert %(py5)spy5N)
r$   r	   r'   r,   r%   r&   r(   r)   r*   r+   )r-   r.   r/   r   r2   @py_assert1@py_format4@py_format6s           r7    test_parse_star_items_empty_filez3TestParseStarItems.test_parse_star_items_empty_fileC   s    {*	R'2!),v|vvvr9   c                 p   |dz  }t        |      }g }||k(  }|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  }t        t        j                  |            dx}}y)	u5   파일이 존재하지 않으면 빈 리스트 반환r   r   r<   r   r=   r>   r?   N)	r	   r'   r,   r%   r&   r(   r)   r*   r+   )r-   r.   non_existentr   r2   r@   rA   rB   s           r7   test_parse_star_items_no_filez0TestParseStarItems.test_parse_star_items_no_fileL   sn    +-!,/v|vvvr9   c                    |dz  }|j                  dd       t        |      }t        |      }d}||k(  }|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                  |      d
z  }dd|iz  }t        t        j                  |            dx}x}}|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  }t        j                  d|	      dz   d|iz  }t        t        j                  |            dx}
} y)uH   마크다운 서식(링크, 볼드 등)이 제거된 텍스트로 반환r   uf   ★ [팀 라우팅 가이드](feedback_design_team_routing_v2.md)
★ **코드 리뷰** 필수 확인
r   r      r   r   r   r   r   r"   r#   Nz](not inz%(py1)s not in %(py3)sitemr   r    u-   마크다운 링크 서식이 남아 있음: z
>assert %(py5)sr?   )r$   r	   r   r'   r,   r%   r&   r(   r)   r*   r+   _format_assertmsg)r-   r.   r/   r   r2   r3   r4   r5   r6   rL   @py_assert0rA   rB   s                r7   'test_parse_star_items_markdown_strippedz:TestParseStarItems.test_parse_star_items_markdown_strippedT   s>   {*	4 	 	
 "),6{a{a{ass66{a 	^D]4t#]]]4t]]]4]]]]]]t]]]t]]]]'TUYT\%]]]]]]]	^r9   N)__name__
__module____qualname____doc__r8   rC   rF   rP    r9   r7   r   r   -   s    5 &^r9   r   c                   "    e Zd ZdZd Zd Zd Zy)TestFindFeedbackFilesu/   find_feedback_files(feedback_dir) 동작 검증c                    |dz  }|j                          |dz  j                  dd       |dz  j                  dd       |dz  j                  d	d       |d
z  j                  dd       |dz  j                  dd       |dz  j                  dd       t        |      }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}t        |      }d}||k(  }|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                  |      dz  }	dd|	iz  }
t        t        j                  |
            dx}x}}|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}}|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)#u8   feedback_*.md 3개 + 다른 파일들 → 3개만 반환feedbackfeedback_design_team_routing.mdu   내용1r   r   zfeedback_deploy_checklist.mdu   내용2zfeedback_api_review_v2.mdu   내용3z
summary.mdu   요약z	notes.txtu   메모zfeedback_draft.txtu   드래프트r   r   r   r   r   Nr   r   r   r   r   r"   r#   	feedback_Lassert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.startswith
}(%(py4)s)
}namer   r   r   r!   z.mdzJassert %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.endswith
}(%(py4)s)
})mkdirr$   r   r   r   r%   r&   r'   r(   r)   r*   r+   r   r,   
startswithendswith)r-   r.   feedback_dirr   r0   r1   r2   r3   r4   r5   r6   r]   r@   s                r7   test_find_feedback_files_normalz5TestFindFeedbackFiles.test_find_feedback_files_normalm   s   *, 
9	9EEiZaEb	6	6BB9W^B_	3	3??	T[?\ 
	$00G0L		#//7/K	,	,88RY8Z$\2&$''''''''z'''z''''''&'''&''''''$'''$''''''''''6{a{a{ass66{a 	(D??/;/?;////////4///4///?///;//////////==''=''''''''4'''4'''='''''''''''''	(r9   c                    |dz  }|j                          t        |      }g }||k(  }|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  }t        t        j                  |            dx}}y)	u)   빈 디렉토리 → 빈 리스트 반환rY   r   r<   r   r=   r>   r?   N)
r_   r   r'   r,   r%   r&   r(   r)   r*   r+   )r-   r.   	empty_dirr   r2   r@   rA   rB   s           r7   "test_find_feedback_files_empty_dirz8TestFindFeedbackFiles.test_find_feedback_files_empty_dir   sx    z)	$Y/v|vvvr9   c                 p   |dz  }t        |      }g }||k(  }|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  }t        t        j                  |            dx}}y)	u;   디렉토리가 존재하지 않으면 빈 리스트 반환no_such_feedback_dirr   r<   r   r=   r>   r?   N)	r   r'   r,   r%   r&   r(   r)   r*   r+   r-   r.   non_existent_dirr   r2   r@   rA   rB   s           r7   test_find_feedback_files_no_dirz5TestFindFeedbackFiles.test_find_feedback_files_no_dir   sq    #&<<$%56v|vvvr9   N)rQ   rR   rS   rT   rc   rf   rk   rU   r9   r7   rW   rW   j   s    9(.r9   rW   c                   (    e Zd ZdZd Zd Zd Zd Zy)TestMatchFeedbackToTasku=   match_feedback_to_task(task_desc, feedback_dir) 동작 검증c                 r   |dz  }|j                          |dz  j                  dd       |dz  j                  dd       t        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}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@   'design routing' task → feedback_design_team_routing.md 매칭rY   rZ   u#   # 디자인 팀 라우팅 피드백r   r   zfeedback_api_gateway_setup.mdu   # API 게이트웨이 설정u   design routing 관련 작업r   r   r   r   r   Ninz%(py1)s in %(py3)srM   r>   r?   rI   rK   r_   r$   r   r   r   r%   r&   r'   r(   r)   r*   r+   r,   
r-   r.   rb   r   r0   r1   rO   r2   rA   rB   s
             r7   test_match_feedback_to_taskz3TestMatchFeedbackToTask.test_match_feedback_to_task   s   *, 
9	9EE1G 	F 	
 
7	7CC*W 	D 	
 ((FU&$''''''''z'''z''''''&'''&''''''$'''$''''''''''0:0F::::0F:::0::::::F:::F:::::::.<.f<<<<.f<<<.<<<<<<f<<<f<<<<<<<r9   c                    |dz  }|j                          |dz  j                  dd       t        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}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   관련 없는 task_desc → 빈 리스트 반환rY   rZ   u   # 디자인 팀 라우팅r   r   u9   데이터베이스 마이그레이션 스크립트 작성r   r   r   r   r   NrI   rK   rM   r>   r?   rr   rs   s
             r7   $test_match_feedback_to_task_no_matchz<TestMatchFeedbackToTask.test_match_feedback_to_task_no_match   s+   *,	9	9EE'' 	F 	
 ((ceqr&$''''''''z'''z''''''&'''&''''''$'''$''''''''''0>0>>>>0>>>0>>>>>>>>>>>>>>>>r9   c                    |dz  }|j                          |dz  j                  dd       t        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}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_   파일명 feedback_design_team_routing_v2.md → ["design", "team", "routing"] 키워드 추출rY   z"feedback_design_team_routing_v2.mdu   # 피드백 내용r   r   u   team routing 검토r   r   r   r   r   Nro   rq   rM   r>   r?   rr   rs   s
             r7   .test_match_feedback_to_task_keyword_extractionzFTestMatchFeedbackToTask.test_match_feedback_to_task_keyword_extraction   s*   *,	<	<HH 7 	I 	

 ((=|L&$''''''''z'''z''''''&'''&''''''$'''$''''''''''3=3v====3v===3======v===v=======r9   c                 r   |dz  }t        d|      }g }||k(  }|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  }t        t        j                  |            d	x}}y	)
u7   feedback 디렉토리가 없으면 빈 리스트 반환no_feedbackzdesign routingr   r<   r   r=   r>   r?   N)	r   r'   r,   r%   r&   r(   r)   r*   r+   ri   s           r7   %test_match_feedback_to_task_empty_dirz=TestMatchFeedbackToTask.test_match_feedback_to_task_empty_dir   ss    #m3'(8:JKv|vvvr9   N)rQ   rR   rS   rT   rt   rv   rx   r{   rU   r9   r7   rm   rm      s    G=(?>r9   rm   c                   (    e Zd ZdZd Zd Zd Zd Zy)TestGetNextMcIdu&   get_next_mc_id(log_path) 동작 검증c                 p   |dz  }t        |      }d}||k(  }|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  }t        t        j                  |            d	x}}y	)
u+   로그 파일이 없으면 'MC-0001' 반환memory-check-log.jsonMC-0001r   r<   r   r=   r>   r?   N)	r   r'   r,   r%   r&   r(   r)   r*   r+   r-   r.   log_pathr   r2   r@   rA   rB   s           r7   test_get_next_mc_id_no_filez+TestGetNextMcId.test_get_next_mc_id_no_file   sp    55)""v""""v""""""v"""v""""""""""r9   c                    |dz  }|j                  t        j                  dg i      d       t        |      }d}||k(  }|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  }t        t	        j                  |            dx}}y)u2   checks 배열이 비어 있으면 'MC-0001' 반환r   checksr   r   r   r   r<   r   r=   r>   r?   Nr$   jsondumpsr   r'   r,   r%   r&   r(   r)   r*   r+   r   s           r7    test_get_next_mc_id_empty_checksz0TestGetNextMcId.test_get_next_mc_id_empty_checks   s    55DJJ"~6I)""v""""v""""""v"""v""""""""""r9   c                    |dz  }ddddddddd	dd
dddddgi}|j                  t        j                  |      d       t        |      }d}||k(  }|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  }t        t	        j                  |            dx}}y)u<   마지막 MC-0005가 기록되어 있으면 'MC-0006' 반환r   r   r   task-001mc_idtask_idMC-0002task-002zMC-0003task-003zMC-0004ztask-004zMC-0005ztask-005r   r   zMC-0006r   r<   r   r=   r>   r?   Nr   )	r-   r.   r   log_datar   r2   r@   rA   rB   s	            r7   test_get_next_mc_id_existingz,TestGetNextMcId.test_get_next_mc_id_existing   s    55#
;#
;#
;#
;#
;
 	DJJx07C)""v""""v""""""v"""v""""""""""r9   c                 j   |dz  }ddddgi}|j                  t        j                  |      d       t        |      }d}||k(  }|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  }t        t	        j                  |            dx}}|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}	}
t        |      }d}
||
k(  }|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                  |
      dz  }dd|iz  }t        t	        j                  |            dx}x}}
y)u8   MC ID는 항상 4자리 zero-padding 형식이어야 함r   r   zMC-0009ztask-009r   r   r   zMC-0010r   r<   r   r=   r>   r?   NMC-r\   r^      r   r   r   r"   r#   )r$   r   r   r   r'   r,   r%   r&   r(   r)   r*   r+   r`   r   )r-   r.   r   r   r   r2   r@   rA   rB   r0   r3   r5   r4   r6   s                 r7   test_get_next_mc_id_formatz*TestGetNextMcId.test_get_next_mc_id_format  s   55zBC
 	DJJx07C)""v""""v""""""v"""v""""""""""  '' ''''''''v'''v''' '''''''''''''6{a{a{ass66{ar9   N)rQ   rR   rS   rT   r   r   r   r   rU   r9   r7   r}   r}      s    0###$ r9   r}   c                   *    e Zd ZdZddZd Zd Zd Zy)TestIssueMcu   issue_mc(...) 동작 검증c                     |dz  }dg}t        |      D ]  }|j                  d|dz    d        |j                  dj                  |      d       |S )	u   테스트용 MEMORY.md 생성r   u   # 팀 메모리
u   ★ 체크 항목    
r;   r   r   )rangeappendr$   join)r-   r.   
star_countmemory_pathlinesis         r7   _make_memory_mdzTestIssueMc._make_memory_md  sc    ,$%z" 	9ALL-a!eWB78	9rwwu~@r9   c                 Z   |dz  }| j                  |d      }|dz  }|j                          t        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}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   }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}||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   }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}}	|d   }t        |t              }|sdd	t        j                         v st        j                  t              rt        j                  t              nd	t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            dx}}|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}}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%   }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}||k(  }	|	slt        j                  d|	fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}	}y).uY   로그 파일이 없을 때 issue_mc() 호출 → 로그 파일 생성 + MC 기록 확인r   rH   r   rY   r   u   API 라우팅 설계 작업r   	task_descr   r   rb   r   r   r   dictr   Nr   ro   rq   rM   r>   r?   r   r   z%(py1)s == %(py4)sr   r   assert %(py6)sr!   r   star_items_checkedmemory_items_readz5assert %(py5)s
{%(py5)s = %(py0)s(%(py2)s, %(py3)s)
}r   )r   r   r    r?   zAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}r   )r   r   r   r   r   r   r   r   z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sr   r   r   r   py7assert %(py9)spy9r   )r   r_   r   r   r   r%   r&   r'   r(   r)   r*   r+   r,   r   existsr   loads	read_textr   )r-   r.   r   r   rb   r   r0   r1   rO   r2   rA   rB   r5   r@   r4   r   @py_assert6r3   @py_format8@py_format10s                       r7   test_issue_mc_creates_logz%TestIssueMc.test_issue_mc_creates_log%  sq   55**8*B*,3#%
 &$''''''''z'''z''''''&'''&''''''$'''$'''''''''' w&    w&   w      &   &       g+)+)++++)++++++)+++++++i .J. J.... J... ...J.......#-#v----#v---#------v---v-------*+0q0+q0000+q000+000q0000000","f,,,,"f,,,",,,,,,f,,,f,,,,,,, !45<z5t<<<<<<<<z<<<z<<<5<<<<<<t<<<t<<<<<<<<<<          x   x             ::h00'0BC#x8####x8###x######8###8#######H%+s%&+!+&!++++&!++++++s+++s+++%+++&+++!+++++++!!$W-::-::::-:::-::::::::::!!$Y/=:=/:====/:===/===:=======r9   c                    |dz  }| j                  |d      }|dz  }|j                          ddddd	gd
gi}|j                  t        j                  |      d       t        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}	}t        j                  |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 cg c]  }|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c c}w )%u`   기존 로그에 이미 MC가 있을 때 issue_mc() → 기존 항목 유지 + 새 항목 추가r   r   r   rY   r   r   z	task-prevr   u   항목A)r   r   r   r   r   r   r   u   새 기능 배포 작업r   r   r   r   r   r   r   r!   Nr   rH   r   r   r   r   r   ro   rq   mc_idsrM   r>   r?   )r   r_   r$   r   r   r   r'   r,   r)   r*   r+   r   r   r   r%   r&   r(   )r-   r.   r   r   rb   existing_logr   rO   r0   r2   r1   r5   r   r@   r   r3   r   r   cr   rA   rB   s                         r7   !test_issue_mc_appends_to_existingz-TestIssueMc.test_issue_mc_appends_to_existingF  s   55**8*B*, &**+*3		
 	DJJ|4wG0#%
 g+)+)++++)++++++)+++++++i .J. J.... J... ...J....... ::h00'0BCH%+s%&+!+&!++++&!++++++s+++s+++%+++&+++!+++++++&.x&89!G*99"yF""""yF"""y""""""F"""F""""""""yF""""yF"""y""""""F"""F""""""" :s   Oc           	      *   |dz  }| j                  |d      }|dz  }|j                          t        dd|||      }h d}|j                  }|j                  } |       }	 ||	      }
|
s t        j                  d	||j	                         z
         d
z   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      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}x}	}
y)u3   issue_mc() 반환 딕셔너리의 필수 키 검증r   r   r   rY   r   u   테스트 태스크r   >   r   r   	timestampr   r   u&   반환 딕셔너리에 누락된 키: z}
>assert %(py9)s
{%(py9)s = %(py2)s
{%(py2)s = %(py0)s.issubset
}(%(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.keys
}()
})
}required_keysr   )r   r   r    r?   r   r   N)r   r_   r   issubsetkeysr'   rN   r%   r&   r(   r)   r*   r+   )r-   r.   r   r   rb   r   r   r@   r4   r   @py_assert8r   s               r7   test_issue_mc_return_structurez*TestIssueMc.test_issue_mc_return_structurem  s   55**8*B*,+#%
 e%% 	
fkk 	
km 	
%m4 	
4 	
  5]V[[]5R4ST	
 	
	6	
 	
   	
 	
 		  	
 	
 		 & 	
 	
	6	
 	
  '- 	
 	
 		 '- 	
 	
 		 '2 	
 	
 		 '4 	
 	
 		 5 	
 	
 	
 	
 	
 	
r9   N)rH   )rQ   rR   rS   rT   r   r   r   r   rU   r9   r7   r   r     s    %>B%#N
r9   r   c                   Z    e Zd ZdZdee   defdZdee   defdZ	d Z
d Zd	 Zd
 Zd Zy)TestGetUncheckedTasksu8   get_unchecked_tasks(log_path, timers_path) 동작 검증running_tasksreturnc                     |dz  }i }|D ]4  }|d   }|j                         D ci c]  \  }}|dk7  s|| c}}||<   6 d|i}	|j                  t        j                  |	      d       |S c c}}w )uL   task-timers.json 생성 헬퍼. task-timers는 {task_id: entry} dict 형식.task-timers.jsonr   tasksr   r   )itemsr$   r   r   )
r-   r.   r   timers_path
tasks_dictttidkvdatas
             r7   _make_timersz"TestGetUncheckedTasks._make_timers  s    !33
 	MAI,C01	L1Q)^q!tLJsO	M $tzz$/'B Ms
   A-A-checked_task_idsc                     |dz  }t        |      D cg c]  \  }}d|dz   d|d }}}|j                  t        j                  d|i      d       |S c c}}w )	u#   memory-check-log.json 생성 헬퍼r   r   r   04dr   r   r   r   )	enumerater$   r   r   )r-   r.   r   r   r   r   r   s          r7   	_make_logzTestGetUncheckedTasks._make_log  su    55 $$45
3 AE#;'C8
 
 	DJJ&'9:WM
s   Ac                    ddddddddg}| j                  ||      }| j                  |ddg      }t        ||      }g }||k(  }|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  }	t        t        j                  |	            dx}}y)uG   running 태스크 2개 모두 MC 발급 완료 → 빈 리스트 반환r   dev1runningr   team_idstatusr   dev2r   r<   r   r=   r>   r?   N)r   r   r   r'   r,   r%   r&   r(   r)   r*   r+   )
r-   r.   r   r   r   r   r2   r@   rA   rB   s
             r7   $test_get_unchecked_tasks_all_checkedz:TestGetUncheckedTasks.test_get_unchecked_tasks_all_checked  s     #vK"vK
 ''-@>>(Z,DE$X{;v|vvvr9   c                    ddddddddg}| j                  ||      }| j                  |dg      }t        ||      }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}t        |      }d}	||	k(  }
|
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                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	|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}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)uC   running 태스크 2개 중 1개만 MC 없음 → 해당 1개 반환r   r   r   r   r   r   r   r   r   r   r   Nr   r   r   r   r   r"   r#   r   r   r   r   r   r!   r   )r   r   r   r   r   r%   r&   r'   r(   r)   r*   r+   r   r,   )r-   r.   r   r   r   r   r0   r1   r2   r3   r4   r5   r6   rO   s                 r7   %test_get_unchecked_tasks_some_missingz;TestGetUncheckedTasks.test_get_unchecked_tasks_some_missing  s    #vK"vK
 ''-@>>(ZL9$X{;&$''''''''z'''z''''''&'''&''''''$'''$''''''''''6{a{a{ass66{aay#1z1#z1111#z111#111z1111111ay#-v-#v----#v---#---v-------r9   c                    |dz  }| j                  |g       }t        ||      }g }||k(  }|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  }t        t        j                  |            dx}}y)	u2   task-timers.json이 없으면 빈 리스트 반환r   r   r<   r   r=   r>   r?   N)
r   r   r'   r,   r%   r&   r(   r)   r*   r+   )	r-   r.   non_existent_timersr   r   r2   r@   rA   rB   s	            r7   "test_get_unchecked_tasks_no_timersz8TestGetUncheckedTasks.test_get_unchecked_tasks_no_timers  s    &);;>>(B/$X/BCv|vvvr9   c                 @   ddddddddg}| j                  ||      }|dz  }t        ||      }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}t        |      }d}	||	k(  }
|
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                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	|D ch c]  }|d   	 }}ddh}||k(  }|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  }t        t        j                  |            dx}}yc c}w )uB   memory-check-log.json이 없으면 running 태스크 전부 반환r   r   r   r   r   r   r   r   r   r   r   r   NrH   r   r   r   r   r"   r#   r   r<   task_idsr=   r>   r?   )r   r   r   r   r%   r&   r'   r(   r)   r*   r+   r   r,   )r-   r.   r   r   non_existent_logr   r0   r1   r2   r3   r4   r5   r6   r   r   r@   rA   rB   s                     r7   test_get_unchecked_tasks_no_logz5TestGetUncheckedTasks.test_get_unchecked_tasks_no_log  s    #vK"vK
 ''-@#&==$%5{C&$''''''''z'''z''''''&'''&''''''$'''$''''''''''6{a{a{ass66{a*01QAiL11&
33x33333x3333333x333x33333333333 2s   $Lc                    dddddddddd	ddg}| j                  ||      }| j                  |g       }t        ||      }|D ch c]  }|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c c}w )uH   status가 running인 태스크만 대상이어야 함 (completed 제외)r   r   r   r   r   r   	completedr   dev3r   rI   rK   r   rM   r>   r?   Nro   rq   )r   r   r   r'   r,   r)   r%   r&   r(   r*   r+   )r-   r.   	all_tasksr   r   r   r   r   rO   r2   rA   rB   s               r7   .test_get_unchecked_tasks_only_running_includedzDTestGetUncheckedTasks.test_get_unchecked_tasks_only_running_included  s    #vK"vM"vK
	
 '')<>>(B/$X{; +11QAiL11)z))))z)))z))))))))))))))))%zX%%%%zX%%%z%%%%%%X%%%X%%%%%%%%zX%%%%zX%%%z%%%%%%X%%%X%%%%%%% 2s   IN)rQ   rR   rS   rT   r   r   r   r   strr   r   r   r   r   r   rU   r9   r7   r   r     sL    B	DJ 	4 	DI $ ."4 &r9   r   )rT   builtinsr%   _pytest.assertion.rewrite	assertionrewriter'   r   syspathlibr   pytestpathinsertr   __file__resolveparentutils.memory_checkr   r   r   r   r   r	   r   rW   rm   r}   r   r   rU   r9   r7   <module>r      s   "   
   3tH~--/66==> ? 5^ 5^z) )b; ;F3  3 vf
 f
\`& `&r9   