
    i !                    &   d Z ddlmZ ddlZddlZddlZddlmZ ddl	Z	 ee
      j                         j                  d   Zedz  Zedz  Z e	j                   d	      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d Zd Zd Z y)u"  tests/lifecycle_guards/test_pre_push_guard.py — task-2471 회귀 테스트.

토르가 commit 0750481e 에서 ``scripts/pre_push_guard.py`` 에 적용한 4결함
수정을 영구 차단한다.

1. ``_parse_allowed_resources_yaml`` 의 numbered heading 인식
   (``## 7. allowed_resources`` 형식 + 기존 ``## allowed_resources`` 모두 OK)
2. ``_strip_yaml_inline_comment`` 헬퍼 (inline ``# 주석`` 제거)
3. ``extract_task_id_from_branch`` 헬퍼 (+N suffix 보존)
4. ``_resolve_allowed_resources`` capability snapshot + task 파일 모두 부재 시
   ``(None, error_msg)`` 반환 (실제 sys.exit 는 main 에서)

본 테스트는 ``tests/scripts/test_pre_push_guard.py`` (기존 7건 시나리오) 와
별도. 정적 단위 테스트만 수행.

헤임달(개발2팀 테스터) 작성.
    )annotationsN)Path   scriptszpre_push_guard.pymodule)scopec                    t         j                         sJ dt                 t        t              t        t              fD ]5  } | t
        j                  vst
        j                  j                  d|        7 t        j                  j                  dt        t                     }||j                  J t        j                  j                  |      }|t
        j                  |j                  <   |j                  j                  |       |S )u2  ``scripts/pre_push_guard.py`` 를 절대 경로 로드.

    ``pre_push_guard`` 자체가 ``sys.path`` 에 scripts/ 와 workspace root 를
    추가하므로 외부 setup 불필요. 단, qc_report_guard / task_scope 가 같은
    scripts 디렉토리에 있어야 함 (worktree 안에서 보장됨).
    z	missing: r   pre_push_guard_test_alias)PRE_PUSH_GUARD_PATHexistsstr	WORKSPACESCRIPTS_DIRsyspathinsert	importlibutilspec_from_file_locationloadermodule_from_specmodulesnameexec_module)pspecmods      A/home/jay/workspace/tests/lifecycle_guards/test_pre_push_guard.pyppgr       s     %%'J95H4I)JJ' )nc+./ "CHHHHOOAq!" >>11#S)<%=D  777
..
)
)$
/C CKK		KKC J    c                r    d}| j                  |      }|J d       d|d   v sJ d|d   v sJ d|d   v sJ y)	u=   ``## 7. allowed_resources`` 형식 YAML 블록 정상 파싱.uz   # 헤더

## 7. allowed_resources
```yaml
paths:
  - "scripts/foo.py"
  - tests/bar.py
forbidden_paths:
  - secret/**
```
Nu   numbered heading 미인식scripts/foo.pypathsztests/bar.py	secret/**forbidden_paths_parse_allowed_resources_yamlr   textouts      r   %test_yaml_numbered_heading_recognizedr+   >   sf    	 	 
+
+D
1C?888?s7|+++S\)))#/0000r    c                H    d}| j                  |      }|J |d   dgk(  sJ y)uJ   기존 ``## allowed_resources`` heading 도 그대로 파싱 (regression).z7## allowed_resources
```yaml
paths:
  - utils/x.py
```
Nr#   
utils/x.pyr&   r(   s      r   #test_yaml_plain_heading_still_worksr.   R   s<    	 	 
+
+D
1C??w<L>)))r    c                H    d}| j                  |      }|J |d   dgk(  sJ y)u<   ``## 12. allowed_resources`` 처럼 두 자리 숫자도 OK.z5## 12. allowed_resources
```yaml
paths:
  - a.py
```
Nr#   za.pyr&   r(   s      r   $test_yaml_numbered_two_digit_headingr0   `   s<    	 	 
+
+D
1C??w<F8###r    c                4    | j                  d      }|dk(  sJ y)u/   ``path/to/file  # 주석`` -> ``path/to/file``.u   path/to/file  # 주석path/to/fileN_strip_yaml_inline_commentr   r*   s     r   test_strip_inline_comment_basicr6   s   s!    

(
()A
BC.   r    c                4    | j                  d      }|dk(  sJ y)u   quote 없는 단순 path.zpath  # commentr   Nr3   r5   s     r   "test_strip_inline_comment_no_quoter8   y   s    

(
():
;C&==r    c                4    | j                  d      }|dk(  sJ y)u"   주석 없으면 원본 그대로.r2   Nr3   r5   s     r   .test_strip_inline_comment_no_comment_unchangedr:      s     

(
(
8C.   r    c                    d}| j                  |      }|J d|d   v sJ d|d   v sJ |d   D ]  }d|vrJ d|        d|d	   v sJ y)
u<   전체 YAML 파싱 흐름에서 inline 주석 제거 확인.u   ## allowed_resources
```yaml
paths:
  - "scripts/foo.py"  # 본 task 핵심
  - utils/bar.py    # 헬퍼
forbidden_paths:
  - secret/**  # ABSOLUTE forbidden
```
Nr"   r#   zutils/bar.py#u"   inline 주석이 path 에 잔존: r$   r%   r&   )r   r)   r*   r   s       r   $test_yaml_block_with_inline_commentsr=      s    	 	 
+
+D
1C??s7|+++S\)))\ H!|GA!GG|H#/0000r    c                4    | j                  d      }|dk(  sJ y)z-``task/task-2467+3-dev6`` -> ``task-2467+3``.ztask/task-2467+3-dev6ztask-2467+3Nextract_task_id_from_branchr5   s     r   %test_branch_parsing_with_retry_suffixrA      s!    

)
)*A
BC-r    c                .    | j                  d      }|J y)u)   ``main`` 같은 일반 브랜치는 None.mainNr?   r5   s     r   %test_branch_parsing_main_returns_nonerD      s    

)
)&
1C;;r    c                4    | j                  d      }|dk(  sJ y)u'   phase + parallel + retry 모두 보존.ztask/task-2470_1.2_a+5-dev3ztask-2470_1.2_a+5Nr?   r5   s     r   -test_branch_parsing_full_phase_parallel_retryrF      s"    

)
)*G
HC%%%%r    c                *    | j                  d      J y )N r?   )r   s    r   test_branch_parsing_empty_inputrI      s    **2.666r    c                    | j                  dt        |            \  }}|J |sJ d|v sd|j                         v sJ yy)uQ   capability snapshot 부재 + task 파일 부재 → ``(None, error_msg)`` 반환.z	task-9999Nu   없음not)_resolve_allowed_resourcesr   lower)r   tmp_patharerrs       r   <test_resolve_allowed_resources_returns_none_when_both_absentrQ      sN     ,,[#h-HGB::J3s?esyy{2222?r    c                   |dz  dz  }|j                  d       ddgdgdi}|d	z  j                  t        j                  |             | j	                  d
t        |            \  }}|dk(  sJ |J d|d   v sJ d|d   v sJ y)uL   capability snapshot 이 있으면 그것을 사용 (task 파일 fallback X).memorycapabilitiesTparentsallowed_resourcesr"   r$   )r#   r%   ztask-2471.jsonz	task-2471rH   Nr#   r%   )mkdir
write_textjsondumpsrL   r   )r   rN   cap_dirsnaprO   rP   s         r   7test_resolve_allowed_resources_uses_capability_snapshotr^      s    !N2GMM$M&' +}
D ++DJJt,<=,,[#h-HGB"99>>r'{***".////r    c                    |dz  dz  }|j                  d       |dz  j                  d       | j                  dt        |            \  }}|dk(  sJ |J d
|d   v sJ y	)uD   capability snapshot 없으면 task .md 파일의 YAML 블록 사용.rS   tasksTrU   ztask-9000.mdzM# task-9000

## 5. allowed_resources
```yaml
paths:
  - utils/x.py  # OK
```
z	task-9000rH   Nr-   r#   rX   rY   rL   r   r   rN   	tasks_dirrO   rP   s        r   6test_resolve_allowed_resources_falls_back_to_task_filerd      s{    8#g-IOODO!++	 ,,[#h-HGB"99>>2g;&&&r    c                    |dz  dz  }|j                  d       |dz  j                  d       | j                  dt        |            \  }}|J |sJ y)	uW   task .md 파일은 있지만 ``## allowed_resources`` 블록 없으면 ``(None, msg)``.rS   r`   TrU   ztask-7777.mdu,   # task

본문만 있고 YAML 블록 없음
z	task-7777Nra   rb   s        r   ;test_resolve_allowed_resources_task_file_without_yaml_blockrf      s^    8#g-IOODO!++,]^,,[#h-HGB::J3r    )!__doc__
__future__r   importlib.utilr   rZ   r   pathlibr   pytest__file__resolverV   r   r   r   fixturer   r+   r.   r0   r6   r8   r:   r=   rA   rD   rF   rI   rQ   r^   rd   rf    r    r   <module>rp      s   " #   
  N""$,,Q/	)#!$77  h  :1(*$&!!16 &730&'&r    