
    i<                         d Z ddlZddlZddlmZ ddlZ ed      Z ed      Z ed      Z ed      Z	de
d	e
fd
Zd	ee
   fdZdee
   fdZ G d d      Z G d d      Zedk(  r ej$                  edg       yy)u  
하누만(Hanuman), dev4팀 테스터
동적 멤버 매핑 검증 테스트 스위트

이 테스트 스위트는 parse-member-id.sh가 organization-structure.json에서
동적으로 매핑을 로드하고 정확하게 에이전트 ID를 추출하는지 검증합니다.
    N)Pathz6/home/jay/workspace/memory/organization-structure.jsonz./home/jay/.claude/hooks/lib/parse-member-id.shz2/home/jay/.claude/hooks/lib/generate-member-map.pyz0/home/jay/.claude/hooks/lib/.member-map-cache.shtextreturnc                     t         j                         st        j                  dt                 t	        j
                  dddt          dd| gddd	      }|j                  j                         S )
u   
    bash에서 parse_member_id 함수를 호출하고 결과 반환.

    Args:
        text: 에이전트 이름을 포함한 텍스트

    Returns:
        추출된 에이전트 ID (없으면 빈 문자열)
    zparse-member-id.sh not found: bash-csource "z" && parse_member_id "$1"_T
   capture_outputr   timeout)PARSE_MEMBER_ID_PATHexistspytestskip
subprocessrunstdoutstrip)r   results     ]/home/jay/workspace/.worktrees/task-2116-dev1/teams/dev4/tests/test_dynamic_member_mapping.py_call_parse_member_idr      st      &&(45I4JKL^^+,,EF	
 F ==      c                  .   t         j                         st        j                  dt                 t         j	                         5 } t        j                  |       }ddd       t               }t        j                  di       |       |S # 1 sw Y   1xY w)u   
    organization-structure.json에서 유효한 에이전트 ID 추출.

    consulting-lead와 venus-delegate는 제외합니다.

    Returns:
        추출된 ID들의 집합
    z"Organization structure not found: N	structure)
ORG_STRUCTURE_PATHr   r   r   openjsonloadset_collect_idsget)forgidss      r   _extract_ids_from_orgr'   :   sy     $$&89K8LMN		 	 	" aiil %Cb)3/J s   BB	collectedc                     t        | t              rZ| j                  d      }|r%t        |t              r|dvr|j	                  |       | j                         D ]  }t        ||        yt        | t              r| D ]  }t        ||        yy)u   
    재귀적으로 JSON 구조에서 id 필드를 수집합니다.

    consulting-lead와 venus-delegate는 필터링됩니다.

    Args:
        node: JSON 노드 (dict, list, 또는 기타)
        collected: ID를 수집할 set
    id)zconsulting-leadzvenus-delegateN)
isinstancedictr#   straddvaluesr"   list)noder(   raw_idvitems        r   r"   r"   N   s     $$j-BBf% 	'AI&	'	D$	 	*Dy)	* 
 r   c                   R    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zy)TestDynamicMemberMappingu(   동적 멤버 매핑 테스트 클래스c                    t         j                         st        j                  dt                 t        j                         r0t        j                         j                  dkD  sJ dt                yt        j                  dt        t               gddd      }t        j                         sJ dt         d	|j                          t        j                         j                  dkD  sJ d
t                y)u   
        generate-member-map.py 실행 시 캐시 파일이 생성되는지 검증.

        캐시 파일이 존재하고 크기가 0보다 커야 합니다.
        z"generate-member-map.py not found: r   z Cache file exists but is empty: python3T   r   zCache file was not created: 
zCache file is empty: N)GENERATOR_PATHr   r   r   
CACHE_PATHstatst_sizer   r   r-   stderrselfr   s     r   test_cache_generationz.TestDynamicMemberMapping.test_cache_generationm   s     $$&KK<^<LMN !))A-?1*>?-  ^^C/0#	F !!#L-j\FMM?KL#??$,,q0V4I*2VV0r   c                     t               }|st        j                  d       g d}g }|D ]-  \  }}t        |      }||k7  s|j	                  | d| d       / |rt        j
                  d|        yy)ut  
        organization-structure.json의 모든 에이전트가 parse-member-id에서 매핑 가능한지 검증.

        - org-structure.json에서 재귀적으로 모든 id 추출 (consulting-lead, venus-delegate 제외)
        - parse-member-id.sh가 major names를 포함하고 있는지 확인 (spot check)
        - 누락된 주요 멤버가 없어야 함
        z-No member IDs found in organization structure))	kartikeya	Kartikeya)vishnuVishnu)hanumanHanuman)hermesHermes)odinOdin)lokiLoki)	aphrodite	Aphroditez (from 'z')z0Following major agents are not properly mapped: N)r'   r   r   r   appendfail)rA   org_idsmajor_agentsunmapped	member_idnamer   s          r   'test_all_org_members_mapped_dynamicallyz@TestDynamicMemberMapping.test_all_org_members_mapped_dynamically   s     ()KKGH
 + 	@OIt*40F"9+XdV2 >?	@
 KKJ8*UV r   c           	      b    g d}|D ]&  \  }}t        |      }||k(  rJ d| d| d| d        y)u  
        bash에서 parse_member_id 함수 호출하여 기본 매핑 동작 검증.

        테스트 케이스:
        - 한국어: "카르티케야가 작업합니다" → "kartikeya"
        - 영어: "Vishnu is reviewing" → "vishnu"
        - 마케팅: "아프로디테 팀장님" → "aphrodite"
        - dev8: "아누비스 코드 리뷰" → "anubis" (dev8 팀장 ra)
        ))u"   카르티케야가 작업합니다rD   )zVishnu is reviewingrF   )u   아프로디테 팀장님rP   )u   아누비스 코드 리뷰anubisFailed for '': expected '', got ''Nr   rA   
test_casesr   expected_idr   s        r   test_parse_basic_namesz/TestDynamicMemberMapping.test_parse_basic_names   Z    

 ", 	PD+*40F+%PdV=XfXQOP%	Pr   c           	      b    g d}|D ]&  \  }}t        |      }||k(  rJ d| d| d| d        y)u  
        substring 충돌 방지 검증.

        테스트 케이스:
        - "아누비스가 코드 리뷰" → "anubis" (not "anu")
        - "아누 실장님" → "anu"
        - "라타토스크 보고" → "ratatoskr" (not "라" 매칭 아님)
        ))u   아누비스가 코드 리뷰r[   )u   아누 실장님anu)u   라타토스크 보고	ratatoskrr\   r]   r^   r_   Nr`   ra   s        r   #test_substring_collision_preventionz<TestDynamicMemberMapping.test_substring_collision_prevention   Z    

 ", 	PD+*40F+%PdV=XfXQOP%	Pr   c           	      b    g d}|D ]&  \  }}t        |      }||k(  rJ d| d| d| d        y)ug  
        짧은 이름의 PCRE 경계 검증.

        테스트 케이스:
        - "루 백엔드 작업" → "lugh" (독립 단어로 매칭)
        - "루비처럼" → "" (빈 문자열 — 다른 단어의 일부이므로 false positive 아님)
        - "에코 데이터 수집" → "echo"
        - "에코시스템" → "" (빈 문자열)
        ))u   루 백엔드 작업lugh)u   루비처럼 )u   에코 데이터 수집echo)u   에코시스템rm   r\   r]   r^   r_   Nr`   ra   s        r   test_short_name_pcre_boundariesz8TestDynamicMemberMapping.test_short_name_pcre_boundaries   re   r   c           	      b    g d}|D ]&  \  }}t        |      }||k(  rJ d| d| d| d        y)u   
        특수 영어 이름 매핑 검증.

        테스트 케이스:
        - "Ah Kin designed" → "ah_kin"
        - "Ma'at 검증" → "maat"
        - "Da Vinci 아이디어" → "davinci"
        ))zAh Kin designedah_kin)u   Ma'at 검증maat)u   Da Vinci 아이디어davincir\   r]   r^   r_   Nr`   ra   s        r   test_special_english_namesz3TestDynamicMemberMapping.test_special_english_names   rj   r   c                 \    g d}|D ]#  \  }}t        |      }||k(  rJ d| d| d        y)u   
        무관 텍스트에서 false positive 없음을 검증.

        테스트 케이스:
        - "오늘 날씨가 맑습니다" → ""
        - "서버 배포 완료" → ""
        - "random English text" → ""
        ))u   오늘 날씨가 맑습니다rm   )u   서버 배포 완료rm   )zrandom English textrm   r\   z': expected empty string, got 'r_   Nr`   ra   s        r   test_no_false_positivez/TestDynamicMemberMapping.test_no_false_positive  sU    

 ", 	MD+*40F+%MdV#B6(!LM%	Mr   c                 D   t         j                         st        j                  d       t         j	                         j
                  dkD  sJ d       t        j                  dddt         dgddd	
      }|j                  dk(  sJ d       d|j                  v sJ d       y)u   
        캐시 갱신 체크.

        캐시 파일의 mtime을 과거로 설정하고 parse-member-id.sh 소싱 시
        캐시가 적절히 관리되는지 확인합니다.
        z-Cache file not found, skipping staleness testr   zCache file is emptyr   r   r	   z" && echo "loaded"Tr   r   z"parse-member-id.sh sourcing failedloadedz'parse-member-id.sh not sourced properlyN)r<   r   r   r   r=   r>   r   r   r   
returncoder   r@   s     r   test_cache_staleness_detectionz7TestDynamicMemberMapping.test_cache_staleness_detection  s       "KKGH  ((1,C.CC, TX&:%;;MNO	
   A%K'KK%6==(S*SS(r   c           	      b    g d}|D ]&  \  }}t        |      }||k(  rJ d| d| d| d        y)u   
        한국어 이름 파싱 검증.

        모든 한국어 이름이 정상적으로 매핑되는지 확인합니다.
        )
)u   헤르메스 검토rJ   )u   불칸이 작업vulcan)u   이리스가 디자인iris)u   아테나를 호출athena)u   아르고스 확인argos)u   오딘 팀장rL   )u   토르가 개발thor)u   프레이야입니다freya)u   미미르 의견mimir)u   헤임달 점검heimdallr\   r]   r^   r_   Nr`   )rA   korean_test_casesr   rc   r   s        r   test_korean_name_parsingz1TestDynamicMemberMapping.test_korean_name_parsing1  s[    
 "3 	PD+*40F+%PdV=XfXQOP%	Pr   c           	      b    g d}|D ]&  \  }}t        |      }||k(  rJ d| d| d| d        y)u   
        영어 이름 파싱 검증.

        모든 영어 이름이 정상적으로 매핑되는지 확인합니다.
        )
)zHermes is hererJ   )zVulcan worksr|   )zIris designedr}   )zAthena talksr~   )zArgos checkingr   )z
Odin leadsrL   )zThor developsr   )zFreya is presentr   )zMimir suggestsr   )zHeimdall guardsr   r\   r]   r^   r_   Nr`   )rA   english_test_casesr   rc   r   s        r   test_english_name_parsingz2TestDynamicMemberMapping.test_english_name_parsingJ  s[    
 "4 	PD+*40F+%PdV=XfXQOP%	Pr   c           	      b    g d}|D ]&  \  }}t        |      }||k(  rJ d| d| d| d        y)u   
        한국어 + 영어 혼합 텍스트 파싱 검증.

        한국어와 영어가 혼합된 텍스트에서도 정상적으로 매핑되는지 확인합니다.
        ))u   헤르메스(Hermes) 리뷰rJ   )u   Vulcan 불칸이 작업r|   )u   아테나 Athena 의견r~   )u$   프로메테우스 Prometheus 전략
prometheus)u   마아트 Ma'at 검증rr   r\   r]   r^   r_   Nr`   )rA   mixed_test_casesr   rc   r   s        r   test_mixed_language_parsingz4TestDynamicMemberMapping.test_mixed_language_parsingc  s[    
 "2 	PD+*40F+%PdV=XfXQOP%	Pr   N)__name__
__module____qualname____doc__rB   rY   rd   ri   ro   rt   rv   rz   r   r   r    r   r   r6   r6   j   sH    2W:WBP.P*P.P*M*T2P2P2Pr   r6   c                       e Zd ZdZd Zy)TestCacheIntegrationu    캐시 통합 테스트 (선택)c                     t         j                         st        j                  d       t         j	                         5 }|j                         }ddd       dv sJ d       y# 1 sw Y   xY w)u   
        캐시 파일이 bash 함수를 포함하는지 검증.

        캐시 파일에 `echo "xxx"` 패턴의 매핑이 포함되어 있는지 확인합니다.
        zCache file not foundNrn   z+Cache file does not contain echo statements)r<   r   r   r   r   read)rA   r$   cache_contents      r   "test_cache_contains_bash_functionsz7TestCacheIntegration.test_cache_contains_bash_functions  s_       "KK./__ 	%!FFHM	% &U(UU&		% 	%s   A##A,N)r   r   r   r   r   r   r   r   r   r   }  s    *Vr   r   __main__z-v)r   r   r   pathlibr   r   r   r   r;   r<   r-   r   r!   r'   r"   r6   r   r   main__file__r   r   r   <module>r      s        RS LM JKDE
! ! !8s3x (*#c( *8KP KPfV V. zFKK4 ! r   