
    i_#                     0   d 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  G d d      Z G d d      Z G d	 d
      Z G d d      Z G d d      Zy)uq   utils/skill_parser.py 테스트 스위트

frontmatter 파싱 및 메타데이터 추출 함수를 검증한다.
    N)Path)extract_categoryextract_descriptionextract_requiresextract_triggersparse_frontmatterc                   P    e Zd ZdZddZddZddZddZddZddZ	dd	Z
dd
Zy)TestParseFrontmatteru8   parse_frontmatter(content) -> tuple[dict, str] 테스트Nc                 l    d}t        |      \  }}t        |t              sJ t        |t              sJ y)u   반환 타입은 (dict, str)u   ---
name: skill
---
본문Nr   
isinstancedictstrselfcontentfmbodys       N/home/jay/workspace/.worktrees/task-2116-dev1/utils/tests/test_skill_parser.py"test_returns_tuple_of_dict_and_strz7TestParseFrontmatter.test_returns_tuple_of_dict_and_str   s5    1$W-D"d###$$$$    c                 |    d}t        |      \  }}|j                  d      dk(  sJ |j                  d      dk(  sJ y)u   단순 key: value YAML 파싱u1   ---
name: my-skill
description: 설명
---
본문namemy-skilldescriptionu   설명N)r   getr   s       r   test_parses_simple_key_valuez1TestParseFrontmatter.test_parses_simple_key_value%   sB    I$W-Dvvf~+++vvm$000r   c                 H    d}t        |      \  }}d|vsJ d|v sJ d|v sJ y)u'   body에서 frontmatter 블록 제거됨u   ---
name: s
---
# 제목
본문z---u   # 제목u   본문Nr   r   s       r   test_body_excludes_frontmatterz3TestParseFrontmatter.test_body_excludes_frontmatter,   s?    7$W-DD   T!!!4r   c                 @    d}t        |      \  }}|i k(  sJ ||k(  sJ y)u%   frontmatter 없으면 빈 dict 반환u'   # 헤딩만 있는 파일
본문 내용Nr   r   s       r   &test_no_frontmatter_returns_empty_dictz;TestParseFrontmatter.test_no_frontmatter_returns_empty_dict4   s,    <$W-DRxxwr   c                 <    t        d      \  }}|i k(  sJ |dk(  sJ y)u(   빈 문자열 입력 시 빈 dict 반환 Nr   r   r   r   s      r   $test_empty_string_returns_empty_dictz9TestParseFrontmatter.test_empty_string_returns_empty_dict;   s'    $R(DRxxrzzr   c                     d}t        |      \  }}t        |j                  d      t              sJ d|d   v sJ d|d   v sJ y)u   YAML 리스트 값 파싱u,   ---
triggers:
  - ship
  - deploy
---
본문triggersshipdeployN)r   r   r   listr   s       r   test_parses_yaml_listz*TestParseFrontmatter.test_parses_yaml_listA   sR    E$W-D"&&,d333J'''2j>)))r   c                 l    d}t        |      \  }}t        |t              sJ t        |t              sJ y)u1   잘못된 YAML은 빈 dict 반환 (예외 없음)u#   ---
: invalid: [unclosed
---
본문Nr   r   s       r   $test_invalid_yaml_returns_empty_dictz9TestParseFrontmatter.test_invalid_yaml_returns_empty_dictI   s5    :$W-D"d###$$$$r   c                 z    d}t        |      \  }}|j                  d      dk(  sJ |j                         dk(  sJ y)u*   frontmatter만 있고 본문 없는 파일z---
name: only-fm
---
r   zonly-fmr$   N)r   r   stripr   s       r   test_frontmatter_only_filez/TestParseFrontmatter.test_frontmatter_only_fileP   s?    -$W-Dvvf~***zz|r!!!r   returnN)__name__
__module____qualname____doc__r   r   r    r"   r&   r,   r.   r1    r   r   r
   r
      s-    B%1 *%"r   r
   c                   8    e Zd ZdZddZddZddZddZddZy)	TestExtractDescriptionu.   extract_description(fm, body) -> str 테스트Nc                 2    ddi}d}t        ||      dk(  sJ y)u(   frontmatter의 description 우선 반환r   u	   fm 설명u   # 헤딩 제목
본문Nr   r%   s      r   $test_returns_frontmatter_descriptionz;TestExtractDescription.test_returns_frontmatter_description`   s&    [)("2t,;;;r   c                 .    i }d}t        ||      dk(  sJ y)u2   frontmatter description 없을 때 # 헤딩 사용u   # 헤딩 설명

본문 내용u   헤딩 설명Nr<   r%   s      r   test_falls_back_to_headingz1TestExtractDescription.test_falls_back_to_headingf   s!    1"2t,???r   c                 .    i }d}t        ||      dk(  sJ y)u0   description도 헤딩도 없으면 빈 문자열u&   그냥 본문만 있음
줄 두 번째r$   Nr<   r%   s      r   $test_returns_empty_if_no_descriptionz;TestExtractDescription.test_returns_empty_if_no_descriptionl   s!    8"2t,222r   c                 2    ddi}d}t        ||      dk(  sJ y)u   앞뒤 공백 제거r   u     공백 설명  r$   u   공백 설명Nr<   r%   s      r   test_strips_whitespacez-TestExtractDescription.test_strips_whitespacer   s'    01"2t,???r   c                 2    i }d}t        ||      }|dk(  sJ y)u&   여러 헤딩 중 첫 번째만 사용u.   # 첫 번째 헤딩
## 두 번째
# 세 번째u   첫 번째 헤딩Nr<   r   r   r   results       r   test_first_heading_onlyz.TestExtractDescription.test_first_heading_onlyx   s'    A$R.,,,,r   r2   )	r4   r5   r6   r7   r=   r?   rA   rC   rG   r8   r   r   r:   r:   ]   s     8<@3@-r   r:   c                   @    e Zd ZdZd	dZd	dZd	dZd	dZd	dZd	dZ	y)
TestExtractTriggersu1   extract_triggers(fm, body) -> list[str] 테스트Nc                 >    dg di}d}t        ||      }|g dk(  sJ y)u"   frontmatter triggers 배열 반환r(   )r)   r*   releaser$   Nr   rE   s       r   (test_returns_list_from_frontmatter_arrayz<TestExtractTriggers.test_returns_list_from_frontmatter_array   s-    78!"d+6666r   c                 8    ddi}d}t        ||      }|dgk(  sJ y)u:   frontmatter triggers 문자열 → 단일 항목 리스트triggerzship itr$   NrL   rE   s       r   )test_returns_list_from_frontmatter_stringz=TestExtractTriggers.test_returns_list_from_frontmatter_string   s-    #!"d+)$$$r   c                 D    i }d}t        ||      }t        |      dkD  sJ y)u(   본문에서 'trigger' 포함 줄 추출u.   ## Trigger
- Use when deploying

다른 내용r   N)r   lenrE   s       r   $test_extracts_from_body_trigger_linez8TestExtractTriggers.test_extracts_from_body_trigger_line   s(    B!"d+6{Qr   c                 L    i }d}t        ||      }t        d |D              sJ y)u"   본문의 'Use when' 패턴 추출u)   Use when you need to ship code
다른 줄c              3   $   K   | ]  }d |v  
 yw)r)   Nr8   ).0ts     r   	<genexpr>zGTestExtractTriggers.test_extracts_use_when_from_body.<locals>.<genexpr>   s     /16Q;/s   N)r   anyrE   s       r    test_extracts_use_when_from_bodyz4TestExtractTriggers.test_extracts_use_when_from_body   s,    ;!"d+/////r   c                 H    i }d}t        ||      }t        |t              sJ y)u0   frontmatter도 본문도 없으면 빈 리스트u(   그냥 평범한 본문
트리거 없음N)r   r   r+   rE   s       r   $test_empty_fm_and_body_returns_emptyz8TestExtractTriggers.test_empty_fm_and_body_returns_empty   s(    :!"d+&$'''r   c                 :    ddgi}d}t        ||      }|dgk(  sJ y)u/   frontmatter triggers가 있으면 본문 무시r(   z
fm-triggerzUse when something happensNrL   rE   s       r   )test_frontmatter_takes_priority_over_bodyz=TestExtractTriggers.test_frontmatter_takes_priority_over_body   s/    <.)+!"d+,'''r   r2   )
r4   r5   r6   r7   rM   rP   rS   rZ   r\   r^   r8   r   r   rI   rI      s#    ;7%0((r   rI   c                   8    e Zd ZdZddZddZddZddZddZy)	TestExtractRequiresu+   extract_requires(fm) -> list[str] 테스트Nc                 8    dddgi}t        |      }|ddgk(  sJ y)u   requires 배열 반환requireszdep-azdep-bNr   r   r   rF   s      r   %test_returns_list_from_requires_arrayz9TestExtractRequires.test_returns_list_from_requires_array   s.    7G,-!"%'7++++r   c                 2    ddi}t        |      }|dgk(  sJ y)u.   requires 문자열 → 단일 항목 리스트rb   z
single-depNrc   rd   s      r   test_returns_list_from_stringz1TestExtractRequires.test_returns_list_from_string   s&    ,'!"%,'''r   c                 4    ddgi}t        |      }|dgk(  sJ y)u   prerequisites 키도 지원prerequisiteszpre-aNrc   rd   s      r   !test_prerequisites_key_also_worksz5TestExtractRequires.test_prerequisites_key_also_works   s(    y)!"%'"""r   c                 ,    i }t        |      }|g k(  sJ y)u    requires 없으면 빈 리스트Nrc   rd   s      r    test_empty_fm_returns_empty_listz4TestExtractRequires.test_empty_fm_returns_empty_list   s    !"%||r   c                 0    ddi}t        |      }|g k(  sJ y)u(   requires 값이 None이면 빈 리스트rb   Nrc   rd   s      r   "test_none_value_returns_empty_listz6TestExtractRequires.test_none_value_returns_empty_list   s"    $!"%||r   r2   )	r4   r5   r6   r7   re   rg   rj   rl   rn   r8   r   r   r`   r`      s    5,(#r   r`   c                   0    e Zd ZdZddZddZddZddZy)TestExtractCategoryu7   extract_category(fm, body, skill_name) -> str 테스트Nc                 4    ddi}d}t        ||d      dk(  sJ y)u"   frontmatter category 우선 반환categorydevr$   r   Nr   r%   s      r   !test_returns_frontmatter_categoryz5TestExtractCategory.test_returns_frontmatter_category   s(    % D*5>>>r   c                 0    i }d}t        ||d      dk(  sJ y)u'   본문의 'category: xxx' 패턴 추출u   category: testing
다른 내용r   testingNrt   r%   s      r   test_extracts_from_body_patternz3TestExtractCategory.test_extracts_from_body_pattern   s#    1D*5BBBr   c                 0    i }d}t        ||d      dk(  sJ y)u#   category 없으면 'general' 반환u   그냥 본문r   generalNrt   r%   s      r   test_returns_general_as_defaultz3TestExtractCategory.test_returns_general_as_default   s#    D*5BBBr   c                 4    i }d}t        ||d      }|dk(  sJ y)u'   본문 category 값의 따옴표 제거zcategory: "quoted-cat"r   z
quoted-catNrt   rE   s       r   %test_strips_quotes_from_body_categoryz9TestExtractCategory.test_strips_quotes_from_body_category   s(    '!"dJ7%%%r   r2   )r4   r5   r6   r7   ru   rx   r{   r}   r8   r   r   rp   rp      s    A?CC&r   rp   )r7   syspathlibr   pytestpathinsertr   __file__parentutils.skill_parserr   r   r   r   r   r
   r:   rI   r`   rp   r8   r   r   <module>r      s   
    3tH~,,33::; < :" :"D -  -P+( +(f N& &r   