
    Ái2                         d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
mZ ddlZ ed      Z ed      Zdedee   ddfd	Zd
edee   ddfdZdee   fdZdee   fdZd ZdedefdZd Zd Zd Zy)u  
닌기르수(Ningirsu) - dev5팀 테스터
task: organization-structure.json 멤버 ID와 parse-member-id.sh 매핑 완전성 검증

검증 항목:
- org-structure의 모든 멤버가 parse-member-id.sh에 매핑되어 있는지
- parse_member_id() bash 함수의 기본 동작 (한국어/영어 이름 → ID)
- substring 충돌 방지 (긴 패턴이 짧은 패턴보다 우선 매칭되어야 함)
- 관계없는 텍스트에서 false positive 없음
    N)Pathz6/home/jay/workspace/memory/organization-structure.jsonz./home/jay/.claude/hooks/lib/parse-member-id.shnode	collectedreturnc                     t        | t              sy| j                  d      }|r(t        |t              r|dvr|j	                  |       yyyy)u7   dict 노드에서 'id' 필드를 재귀적으로 수집Nid)zconsulting-leadzvenus-delegate)
isinstancedictgetstradd)r   r   raw_ids      >/home/jay/workspace/teams/dev5/tests/test_member_id_mapping.py_extract_ids_from_noder      sI    dD!XXd^F*VS)>>MM&! ? *v    teamc                     dD ]0  }| j                  |      }t        |t              s%t        ||       2 | j                  dg       D ]  }t        ||        | j                  dg       D ]  }t	        ||        y)u;   팀(또는 센터) 한 개에서 모든 멤버 ID를 수집)leadoffice_leaddirect_workermembers	sub_teamsN)r   r	   r
   r   _collect_team_ids)r   r   keyr   membersubs         r   r   r   $   s     8 4xx}dD!"434 ((9b) 2vy12 xxR( *#y)*r   c                     t         j                  d      5 } t        j                  |       }ddd       j	                  di       }t               }|j	                  di       j	                  dg       D ]  }t        ||        |j	                  di       j	                  dg       D ]  }t        ||        |S # 1 sw Y   xY w)	uL   organization-structure.json에서 유효한 에이전트 ID 전체를 반환utf-8encodingN	structurecolumnsteamsrowscenters)ORG_STRUCTURE_PATHopenjsonloadr   setr   )forgr!   r   r   centers         r   get_org_member_idsr.   5   s    		 	 '	 	2 aiil R(I%I i,00"= +$	*+ --+//	2> -&),-  s   B99Cc                     t               } t        t        j                  dz  fD ]J  }|j                         s|j	                  d      }| j                  t        j                  d|             L | j                  d       | S )uD   parse-member-id.sh 또는 동적 캐시에서 매핑된 ID를 반환z.member-map-cache.shr   r   zecho "(\w+)" )	r*   PARSE_MEMBER_ID_PATHparentexists	read_textupdaterefindalldiscard)idspathcontents      r   get_mapped_idsr<   H   sr    EC 	##&<< = ;;=nngn6GJJrzz/7;<= KKOJr   c                     t         j                         st        j                  dt                 t        j                         st        j                  dt                t               } t               }| |z
  }|r`t        |      }t        d       |D ]  }t        d|         t        j                  dt        |       ddj                  |      z          yy)	uc   organization-structure.json의 모든 멤버가 parse-member-id.sh에 매핑되어 있는지 검증u   org-structure 파일 없음: "   parse-member-id.sh 파일 없음: uF   
[MISSING] org-structure에 있지만 parse-member-id.sh에 없는 ID:z  - u   총 u%   개 에이전트가 매핑 누락:
  z
  N)r&   r3   pytestskipr1   r.   r<   sortedprintfaillenjoin)org_ids
mapped_idsmissingmissing_sortedm_ids        r   test_all_org_members_mappedrK   Z   s    $$&34F3GHI&&(89M8NOP "G!J
"GWX" 	!DD- 	!3w<. FGkk.)*	
 r   textc                     t        t              }t        j                  ddd| dd| gddd      }|j                  j                         S )	u?   bash에서 parse_member_id 함수를 호출하고 결과 반환bashz-czsource "z" && parse_member_id "$1"_T   )capture_outputrL   timeout)r   r1   
subprocessrunstdoutstrip)rL   scriptresults      r   _call_parse_member_idrY   r   sQ    %&F^^	&)BCS$O	F ==  r   c            
      x   t         j                         st        j                  dt                 g d} | D ]   \  }}t	        |      }||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  }t        j                  d| d	| d
| d      dz   d|iz  }t        t        j                  |            d} y)uB   parse_member_id() 기본 동작 검증 - subprocess로 bash 호출r>   ))u,   헤르메스가 작업을 시작했습니다hermes)u*   오딘 팀장님 확인 부탁드립니다odin)u   마르둑 보고marduk)zHermes has started the taskr[   )zReport from Odinr\   )zMarduk completedr]   ==z%(py0)s == %(py2)sactualexpected_idpy0py2u   입력 '   ' → 기대 '   ', 실제 ''
>assert %(py4)spy4Nr1   r3   r?   r@   rY   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanation)casesrL   rb   ra   @py_assert1@py_format3@py_format5s          r   test_parse_member_id_basicry   ~   s5   &&(89M8NOP	E # Lk&t,k!	L:K:K	Lk	L 	LEKV	L 	L3K3K 	L 	LBK) 	L 	LEKV	L 	L3K3K "	L 	LBK) "	L 	L:K:KXdV>+k&K	L 	L 	L8K8K	L 	LLr   c            
      x   t         j                         st        j                  dt                 ddg} | D ]   \  }}t	        |      }||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  }t        j                  d	| d
| d| d      dz   d|iz  }t        t        j                  |            d} y)uK   substring 충돌 테스트 - '아누비스'가 '아누'보다 우선 매칭r>   )u/   아누비스가 데이터를 처리했습니다anubis)u    아누 실장님 지시입니다anur^   r`   ra   rb   rc   u   [substring 충돌] 입력 'rf   rg   rh   ri   rj   Nrk   )collision_casesrL   rb   ra   rv   rw   rx   s          r   (test_parse_member_id_substring_collisionr~      sF   &&(89M8NOP 	F3O
 - _k&t,k!	_M^M^	_k	_ 	_X^X^	_ 	_F^F^ 	_ 	_U^U^ 	_ 	_X^X^	_ 	_F^F^ "	_ 	_U^U^ "	_ 	_M^M^(n[MU[T\\]^	_ 	_ 	_K^K^	_ 	__r   c                     t         j                         st        j                  dt                 g d} | 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  }t        j                  d| d	| d
      dz   d|iz  }t        t        j                  |            dx}} y)u2   관계없는 텍스트에서 false positive 없음r>   )u   오늘 날씨가 맑습니다u   배포 완료 알림u   테스트 결과 보고서z'unknown random text with no agent namesr0   r^   )z%(py0)s == %(py3)sra   )rd   py3u#   [false positive] 무관 텍스트 'u)   ' → 예상 '' (빈 문자열), 실제 'rh   z
>assert %(py5)spy5Nrk   )unrelated_textsrL   ra   @py_assert2rv   @py_format4@py_format6s          r   test_no_false_positiver      s   &&(89M8NOPO   j&t,	jbL	jXiXi	jb	j 	jcici	j 	jQiQi 	j 	j`i`i 	j 	j`i`i 	j 	jXiXi06_`f_gghi	j 	j 	jViVi	j 	jjr   )__doc__builtinsrn   _pytest.assertion.rewrite	assertionrewriterl   r(   r6   rS   pathlibr   r?   r&   r1   objectr*   r   r   r
   r   r.   r<   rK   rY   ry   r~   r    r   r   <module>r      s   	   	   RS LM 
" "CH " "*D *SX *$ *"CH &C $
0	! 	! 	!L0_$jr   