
    SiH                     X   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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J t	        |      dk(  sJ y)u:   ★ 포함 라인 3개가 있는 MEMORY.md → 3개 반환	MEMORY.mdu   # 팀 메모리
- 일반 항목
★ [팀 라우팅 가이드](feedback_design_team_routing_v2.md)
★ [배포 체크리스트](deploy_checklist.md)
★ 코드 리뷰 필수 확인 사항
## 기타
- 참고 링크
utf-8encoding   N)
write_textr	   
isinstancelistlenselftmp_path	memory_mdresults       H/home/jay/workspace/.worktrees/task-2117-dev1/tests/test_memory_check.pytest_parse_star_items_normalz/TestParseStarItems.test_parse_star_items_normal0   sW    {*	   	 		
 "),&$'''6{a    c                 X    |dz  }|j                  dd       t        |      }|g k(  sJ y)u#   빈 파일 → 빈 리스트 반환r    r   r   N)r   r	   r   s       r    test_parse_star_items_empty_filez3TestParseStarItems.test_parse_star_items_empty_fileC   s5    {*	R'2!),||r   c                 2    |dz  }t        |      }|g k(  sJ y)u5   파일이 존재하지 않으면 빈 리스트 반환r   N)r	   )r   r   non_existentr   s       r   test_parse_star_items_no_filez0TestParseStarItems.test_parse_star_items_no_fileL   s"    +-!,/||r   c                     |dz  }|j                  dd       t        |      }t        |      dk(  sJ |D ]  }d|vrJ d|        y)	uH   마크다운 서식(링크, 볼드 등)이 제거된 텍스트로 반환r   uf   ★ [팀 라우팅 가이드](feedback_design_team_routing_v2.md)
★ **코드 리뷰** 필수 확인
r   r      z](u-   마크다운 링크 서식이 남아 있음: N)r   r	   r   )r   r   r   r   items        r   'test_parse_star_items_markdown_strippedz:TestParseStarItems.test_parse_star_items_markdown_strippedT   ss    {*	4 	 	
 "),6{a 	^Dt#]'TUYT\%]]#	^r   N)__name__
__module____qualname____doc__r   r    r#   r'    r   r   r   r   -   s    5 &^r   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J t        |      dk(  sJ |D ](  }|j                  d      sJ |j                  d      r(J  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   	feedback_z.mdN)mkdirr   r   r   r   r   
startswithendswith)r   r   feedback_dirr   names        r   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&$'''6{a 	(D??;///=='''	(r   c                 R    |dz  }|j                          t        |      }|g k(  sJ y)u)   빈 디렉토리 → 빈 리스트 반환r0   N)r3   r   )r   r   	empty_dirr   s       r   "test_find_feedback_files_empty_dirz8TestFindFeedbackFiles.test_find_feedback_files_empty_dir   s,    z)	$Y/||r   c                 2    |dz  }t        |      }|g k(  sJ y)u;   디렉토리가 존재하지 않으면 빈 리스트 반환no_such_feedback_dirN)r   r   r   non_existent_dirr   s       r   test_find_feedback_files_no_dirz5TestFindFeedbackFiles.test_find_feedback_files_no_dir   s%    #&<<$%56||r   N)r(   r)   r*   r+   r8   r;   r@   r,   r   r   r.   r.   j   s    9(.r   r.   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                     |dz  }|j                          |dz  j                  dd       |dz  j                  dd       t        d|      }t        |t              sJ d|v sJ d|vsJ y	)
u@   'design routing' task → feedback_design_team_routing.md 매칭r0   r1   u#   # 디자인 팀 라우팅 피드백r   r   zfeedback_api_gateway_setup.mdu   # API 게이트웨이 설정u   design routing 관련 작업Nr3   r   r   r   r   r   r   r6   r   s       r   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&$'''0F:::.f<<<r   c                     |dz  }|j                          |dz  j                  dd       t        d|      }t        |t              sJ d|vsJ y)u0   관련 없는 task_desc → 빈 리스트 반환r0   r1   u   # 디자인 팀 라우팅r   r   u9   데이터베이스 마이그레이션 스크립트 작성NrD   rE   s       r   $test_match_feedback_to_task_no_matchz<TestMatchFeedbackToTask.test_match_feedback_to_task_no_match   se    *,	9	9EE'' 	F 	
 ((ceqr&$'''0>>>r   c                     |dz  }|j                          |dz  j                  dd       t        d|      }t        |t              sJ d|v sJ y)u_   파일명 feedback_design_team_routing_v2.md → ["design", "team", "routing"] 키워드 추출r0   z"feedback_design_team_routing_v2.mdu   # 피드백 내용r   r   u   team routing 검토NrD   rE   s       r   .test_match_feedback_to_task_keyword_extractionzFTestMatchFeedbackToTask.test_match_feedback_to_task_keyword_extraction   sd    *,	<	<HH 7 	I 	

 ((=|L&$'''3v===r   c                 4    |dz  }t        d|      }|g k(  sJ y)u7   feedback 디렉토리가 없으면 빈 리스트 반환no_feedbackzdesign routingN)r   r>   s       r   %test_match_feedback_to_task_empty_dirz=TestMatchFeedbackToTask.test_match_feedback_to_task_empty_dir   s'    #m3'(8:JK||r   N)r(   r)   r*   r+   rF   rH   rJ   rM   r,   r   r   rB   rB      s    G=(?>r   rB   c                   (    e Zd ZdZd Zd Zd Zd Zy)TestGetNextMcIdu&   get_next_mc_id(log_path) 동작 검증c                 2    |dz  }t        |      }|dk(  sJ y)u+   로그 파일이 없으면 'MC-0001' 반환memory-check-log.jsonMC-0001N)r   r   r   log_pathr   s       r   test_get_next_mc_id_no_filez+TestGetNextMcId.test_get_next_mc_id_no_file   s%    55)"""r   c                     |dz  }|j                  t        j                  dg i      d       t        |      }|dk(  sJ y)u2   checks 배열이 비어 있으면 'MC-0001' 반환rQ   checksr   r   rR   Nr   jsondumpsr   rS   s       r    test_get_next_mc_id_empty_checksz0TestGetNextMcId.test_get_next_mc_id_empty_checks   sE    55DJJ"~6I)"""r   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(  sJ y)u<   마지막 MC-0005가 기록되어 있으면 'MC-0006' 반환rQ   rW   rR   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-0006NrX   r   r   rT   log_datar   s        r   test_get_next_mc_id_existingz,TestGetNextMcId.test_get_next_mc_id_existing   sz    55#
;#
;#
;#
;#
;
 	DJJx07C)"""r   c                     |dz  }ddddgi}|j                  t        j                  |      d       t        |      }|dk(  sJ |j	                  d	      sJ t        |      d
k(  sJ y)u8   MC ID는 항상 4자리 zero-padding 형식이어야 함rQ   rW   zMC-0009ztask-009r^   r   r   zMC-0010MC-   N)r   rY   rZ   r   r4   r   rd   s        r   test_get_next_mc_id_formatz*TestGetNextMcId.test_get_next_mc_id_format  s}    55zBC
 	DJJx07C)"""  '''6{ar   N)r(   r)   r*   r+   rU   r[   rf   rj   r,   r   r   rO   rO      s    0###$ r   rO   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         r   _make_memory_mdzTestIssueMc._make_memory_md  sc    ,$%z" 	9ALL-a!eWB78	9rwwu~@r   c                    |dz  }| j                  |d      }|dz  }|j                          t        dd|||      }t        |t              sJ d|v sJ |d   d	k(  sJ |d
   dk(  sJ d|v sJ |d   dk(  sJ d|v sJ t        |d   t
              sJ |j                         sJ t        j                  |j                  d            }d|v sJ t        |d         dk(  sJ |d   d   d   d	k(  sJ |d   d   d
   dk(  sJ y)uY   로그 파일이 없을 때 issue_mc() 호출 → 로그 파일 생성 + MC 기록 확인rQ   r%   rs   r0   r]   u   API 라우팅 설계 작업r`   	task_descrT   rt   r6   r_   rR   r`   star_items_checkedmemory_items_readr   r   rW   rn   r   N)rw   r3   r   r   dictr   existsrY   loads	read_textr   )r   r   rT   rt   r6   r   re   s          r   test_issue_mc_creates_logz%TestIssueMc.test_issue_mc_creates_log%  sj   55**8*B*,3#%
 &$'''&   g)+++i J...#v---*+q000"f,,,&!45t<<<    ::h00'0BC8###8H%&!+++!!$W-:::!!$Y/:===r   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(  sJ |d   dk(  sJ t        j                  |j                  d            }t        |d         dk(  sJ |d   D cg c]  }|d   	 }	}d|	v sJ d|	v sJ yc c}w )u`   기존 로그에 이미 MC가 있을 때 issue_mc() → 기존 항목 유지 + 새 항목 추가rQ   rn   ry   r0   rW   rR   z	task-prevr   u   항목A)r_   r`   r|   r}   r   r   rb   u   새 기능 배포 작업rz   r_   ra   r`   r%   N)	rw   r3   r   rY   rZ   r   r   r   r   )
r   r   rT   rt   r6   existing_logr   re   cmc_idss
             r   !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... ::h00'0BC8H%&!+++&.x&89!G*99F"""F""" :s   Cc                     |dz  }| j                  |d      }|dz  }|j                          t        dd|||      }h d}|j                  |j	                               sJ d	||j	                         z
          y
)u3   issue_mc() 반환 딕셔너리의 필수 키 검증rQ   r   ry   r0   rc   u   테스트 태스크rz   >   r_   r`   	timestampr}   r|   u&   반환 딕셔너리에 누락된 키: N)rw   r3   r   issubsetkeys)r   r   rT   rt   r6   r   required_keyss          r   test_issue_mc_return_structurez*TestIssueMc.test_issue_mc_return_structurem  s    55**8*B*,+#%
 e%%fkkm4 	
4]V[[]5R4ST	
4r   N)r%   )r(   r)   r*   r+   rw   r   r   r   r,   r   r   rl   rl     s    %>B%#N
r   rl   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   rY   rZ   )
r   r   r   timers_path
tasks_dictttidkvdatas
             r   _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 생성 헬퍼rQ   rh   rn   04dr^   rW   r   r   )	enumerater   rY   rZ   )r   r   r   rT   rv   r   rW   s          r   	_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(  sJ y)uG   running 태스크 2개 모두 MC 발급 완료 → 빈 리스트 반환r]   dev1runningr`   team_idstatusrb   dev2Nr   r   r   r   r   r   r   rT   r   s         r   $test_get_unchecked_tasks_all_checkedz:TestGetUncheckedTasks.test_get_unchecked_tasks_all_checked  s`     #vK"vK
 ''-@>>(Z,DE$X{;||r   c                     ddddddddg}| j                  ||      }| j                  |dg      }t        ||      }t        |t              sJ t        |      dk(  sJ |d   d	   dk(  sJ |d   d
   dk(  sJ y)uC   running 태스크 2개 중 1개만 MC 없음 → 해당 1개 반환r]   r   r   r   rb   r   rn   r   r`   r   N)r   r   r   r   r   r   r   s         r   %test_get_unchecked_tasks_some_missingz;TestGetUncheckedTasks.test_get_unchecked_tasks_some_missing  s     #vK"vK
 ''-@>>(ZL9$X{;&$'''6{aay#z111ay#v---r   c                 X    |dz  }| j                  |g       }t        ||      }|g k(  sJ y)u2   task-timers.json이 없으면 빈 리스트 반환r   N)r   r   )r   r   non_existent_timersrT   r   s        r   "test_get_unchecked_tasks_no_timersz8TestGetUncheckedTasks.test_get_unchecked_tasks_no_timers  s7    &);;>>(B/$X/BC||r   c                     ddddddddg}| j                  ||      }|dz  }t        ||      }t        |t              sJ t	        |      dk(  sJ |D ch c]  }|d	   	 }}|ddhk(  sJ y
c c}w )uB   memory-check-log.json이 없으면 running 태스크 전부 반환r]   r   r   r   rb   r   rQ   r%   r`   N)r   r   r   r   r   )r   r   r   r   non_existent_logr   r   task_idss           r   test_get_unchecked_tasks_no_logz5TestGetUncheckedTasks.test_get_unchecked_tasks_no_log  s     #vK"vK
 ''-@#&==$%5{C&$'''6{a*01QAiL11J
3333 2s   A.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sJ d|v sJ d|v sJ yc c}w )uH   status가 running인 태스크만 대상이어야 함 (completed 제외)r]   r   r   r   rb   r   	completedrc   dev3r`   Nr   )r   r   	all_tasksr   rT   r   r   r   s           r   .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)))X%%%X%%% 2s   A'N)r(   r)   r*   r+   r   r~   r   r   strr   r   r   r   r   r   r,   r   r   r   r     sL    B	DJ 	4 	DI $ ."4 &r   r   )r+   rY   syspathlibr   pytestpathinsertr   __file__resolveparentutils.memory_checkr   r   r   r   r   r	   r   r.   rB   rO   rl   r   r,   r   r   <module>r      s   "  
   3tH~--/66==> ? 5^ 5^z) )b; ;F3  3 vf
 f
\`& `&r   