
     Ij0              	      f   d Z ddlmZ ddlZddlmc mZ ddl	Z
ddlZddlZe
j                  j                  e
j                  j                  e
j                  j                  e
j                  j!                  e                        Zeej                  v rej                  j'                  e       ej                  j)                  de       ddlZ ej,                  d      ZeZ ej,                  dej2                        Zej6                  j9                  dg d      d	        Zej6                  j9                  dg d
      d        Z ej,                  d      Z ej,                  d      Z ej6                  j9                  dg d      d        Z!ej6                  j9                  dg d      d        Z" ej,                  d      Z#ej6                  j9                  dg d      d        Z$ ej,                  d      Z%ej6                  j9                  dg d      d        Z&d Z'd Z(d Z)d Z*d  Z+y)!u0  tests/regression/test_task_id_parser_v3.py — task-2547+1 회귀.

PR #95 Gemini fresh review (high 3 + medium 1) 회귀 박제:
  - 필수 fix 1: dashboard/helpers.py task-ID 제거 정규식 multi-dot 지원
  - 필수 fix 2: report_parser.py task-ID 추출 정규식 multi-dot 지원
  - 필수 fix 3: scripts/start_task_guard.py commit prefix 정규식 multi-dot 지원
  - 필수 fix 4: dispatch/__init__.py _is_design_task unused var 제거 (origin/main 기조 보존)

필수 회귀 7항목 (회장 §명시 1:1):
  - task-2523.9 실제 패턴 fixture
  - task-1234.5.6 multi-dot fixture
  - task-1234 기존 패턴 유지
  - task-1234+1 V2 retry 패턴 유지
  - task-1234.5 single-dot 패턴 유지
  - report_parser / dashboard helpers / commit prefix guard regression
  - 전체 관련 regression PASS
    )annotationsNuY   ^(?:task-\d+(?:\.\d+)*(?:_\d+\.\d+)?(?:_[a-z])?(?:\+\d+)?|Task\s+\d+[\.\d]*)\s*[:：]?\s*u^   ^(?:task-\d+(?:\.\d+)*(?:_\d+\.\d+)?(?:_[a-z])?(?:\+\d+)?|Task\s*-?\s*\d+[\.\d]*)\s*[:：]?\s*)flagszraw,expected_clean)
)u   task-1234.5: 본문 제목   본문 제목)u   task-1234.5 본문 제목r   )u   task-2523.9: 본문 제목r   )u   task-1234.5.6: 본문 제목r   )u   task-1234.5.6 본문 제목r   )u   task-1234: 본문 제목r   )u   task-1234+1: 본문 제목r   )u   task-2487+1: 본문 제목r   )u   task-2469_1.2: 본문 제목r   )u    task-2469_1.2_a+3: 본문 제목r   c                (   t         j                  d|       j                         }||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
z   d|iz  }t        t        j                  |            d}y)u;   task-timers description 첫 줄 prefix 제거 (priority 1). ==z%(py0)s == %(py2)scleanedexpected_cleanpy0py2u    → 	    (기대 )z
>assert %(py4)spy4N)DASHBOARD_PREFIX_RE_PRIORITY1substrip
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanationrawr   r   @py_assert1@py_format3@py_format5s         >/home/jay/workspace/tests/regression/test_task_id_parser_v3.py%test_dashboard_priority1_prefix_stripr%   0   s    . ,//C8>>@Gn$\\\7n\\\\\\7\\\7\\\\\\n\\\n\\\\uWKyHZZ[&\\\\\\\    ))u   task-2523.9: 보고서	   보고서)u   task-1234.5.6: 보고서r'   )u   Task 1234.5.6: 보고서r'   )u   Task-1234.5.6 보고서r'   )u   task-1234+1 보고서r'   c                   t         j                  d|       j                         }||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  }dd|iz  }t        t        j                  |            d	}y	)
u4   보고서 H1 prefix 제거 (priority 3, IGNORECASE).r   r   r
   r   r   r   zassert %(py4)sr   N)DASHBOARD_PREFIX_RE_PRIORITY3r   r   r   r   r   r   r   r   r   r   r   s         r$   6test_dashboard_priority3_prefix_strip_case_insensitiver*   K   s     ,//C8>>@Gn$$$$7n$$$$$$7$$$7$$$$$$n$$$n$$$$$$$r&   z5task-\d+(?:\.\d+)*(?:_\d+\.\d+)?(?:_[a-z])?(?:\+\d+)?z;#\s+(task-\d+(?:\.\d+)*(?:_\d+\.\d+)?(?:_[a-z])?(?:\+\d+)?)ztitle,expected_tid))u   # task-9.2 완료task-9.2)u   # task-1234.5.6 보고서task-1234.5.6)u   # task-2523.9 통합task-2523.9)u   # task-1234 단순	task-1234)u   # task-2487+1 회복task-2487+1)u   # task-2469_1.2_a+3 통합task-2469_1.2_a+3c                   t         j                  |       }d }||u}|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z   d|iz  }t        t        j                  |            d x}}|j                  }d} ||      }||k(  }	|	st        j                  d	|	fd
||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }
dd|
iz  }t        t        j                  |            d x}x}x}}	y )Nis notz%(py0)s is not %(py3)smr   py3u    에서 task_id 추출 실패
>assert %(py5)spy5   r   zK%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.group
}(%(py4)s)
} == %(py8)sexpected_tidr   r   r   py6py8assert %(py10)spy10)REPORT_PARSER_H1searchr   r   r   r   r   r   r   r   r   group)titler<   r5   @py_assert2r!   @py_format4@py_format6@py_assert3@py_assert5@py_assert7@py_format9@py_format11s               r$   )test_report_parser_h1_extraction_multidotrN   g   s    	&AC1D=CCC1DCCCCCC1CCC1CCCDCCCUI%BCCCCCCC77%1%71:%:%%%%:%%%%%%1%%%1%%%7%%%1%%%:%%%%%%%%%%%%%%%%%r&   basename)r+   r.   task-1234.5r,   r-   r/   ztask-2469_1.2r0   c                j   t         j                  } ||       }d}||u}|s
t        j                  d|fd||f      dt	        j
                         v st        j                  t               rt        j                  t               ndt        j                  |      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}x}}y)	uC   파일명에서 task-ID 1:1 매치 (origin/main `re.match` 호환).Nr2   )zO%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.match
}(%(py3)s)
} is not %(py8)sREPORT_PARSER_TID_BODYrO   )r   r   r7   r9   r?   r@   rA   )
rR   matchr   r   r   r   r   r   r   r   )rO   r!   @py_assert4rK   @py_assert6rL   rM   s          r$   !test_report_parser_basename_matchrV   x   s     "''='1==1====1======!===!==='============1==========r&   zC(task/task-\d+(?:\.\d+)*(?:_\d+\.\d+)?(?:_[a-z])?(?:\+\d+)?-dev\d+)zbranch_text,expected))task/task-9.1-dev2rW   )task/task-1234.5.6-dev1rX   )task/task-2523.9-dev2rY   )task/task-2487+1-dev2rZ   )task/task-2469_1.2_a-dev3r[   c                   t         j                  |       }d }||u}|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z   d|iz  }t        t        j                  |            d x}}|j                  }d} ||      }||k(  }	|	st        j                  d	|	fd
||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }
dd|
iz  }t        t        j                  |            d x}x}x}}	y )Nr2   r4   r5   r6   u    매치 실패r8   r9   r:   r   r;   expectedr=   r@   rA   )REPORT_PARSER_MERGE_BRANCHrC   r   r   r   r   r   r   r   r   r   rD   )branch_textr]   r5   rF   r!   rG   rH   rI   rJ   rK   rL   rM   s               r$   (test_report_parser_merge_branch_multidotr`      s    	#))+6A:1D=:::1D::::::1:::1:::D:::[O>:::::::77!1!71:!:!!!!:!!!!!!1!!!1!!!7!!!1!!!:!!!!!!!!!!!!!!!!!r&   z<^\[(task-\d+(?:\.\d+)*(?:_\d+\.\d+)?(?:_[a-z])?(?:\+\d+)?)\]zcommit_msg,expected_prefix))u   [task-1234] 단순 prefixr.   )z[task-1234.5] legacy single-dotrP   )u'   [task-1234.5.6] legacy multi-dot 회귀r,   )u/   [task-2523.9] legacy multi-dot 실제 사용례r-   )z[task-2487+1] V2 retryr/   )z+[task-2469_1.2_a+3] V2 phase+parallel+retryr0   c                V   t         j                  |       }d }||u}|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z   d|iz  }t        t        j                  |            d x}}|j                  }d} ||      }||k(  }	|	s0t        j                  d	|	fd
||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }
t        j                  | d|j                  d      d|d      dz   d|
iz  }t        t        j                  |            d x}x}x}}	y )Nr2   r4   r5   r6   u    prefix 매치 실패r8   r9   r:   r   r;   expected_prefixr=   u    → 캡처 r   r   z
>assert %(py10)srA   )START_TASK_GUARD_COMMIT_PREFIXrS   r   r   r   r   r   r   r   r   r   rD   )
commit_msgrb   r5   rF   r!   rG   rH   rI   rJ   rK   rL   rM   s               r$   ,test_start_task_guard_commit_prefix_multidotre      s    	',,Z8A@1D=@@@1D@@@@@@1@@@1@@@D@@@ZN*?@@@@@@@77 1 71: :(   :                            )    )    .QWWQZN)O;NaP     r&   c                    t         j                  d      } d}| |u}|st        j                  d|fd| |f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}| j                  }d	} ||      }d
}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }	t        j                  d      dz   d|	iz  }
t        t        j                  |
            dx}x}x}x}}y)ui   기존 `task-\w+` 회귀: `task-1234.5.6` 을 `task-1234` 로 잘라 mixed 오판정하던 버그 박제.z#[task-1234.5.6] should not truncateNr2   r4   r5   r6   zassert %(py5)sr9   r:   r,   r   )zK%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.group
}(%(py4)s)
} == %(py9)sr   r   r   r>   py9u+   multi-dot 캡처가 잘리지 않아야 함
>assert %(py11)spy11)rc   rS   r   r   r   r   r   r   r   r   rD   r   )r5   rF   r!   rG   rH   rI   rJ   @py_assert8rK   @py_format10@py_format12s              r$   4test_start_task_guard_no_partial_truncation_multidotrn      s   &,,-RSA1D=1D11D77W1W71:WW:(WWW:WWWWWW1WWW1WWW7WWW1WWW:WWWWWW*WWWWWWWWr&   c                 (   t         j                  j                  t        dd      } t	        | d      5 }|j                         }ddd       d}|v }|st        j                  d|fd||f      t        j                  |      d	t        j                         v st        j                  |      rt        j                  |      nd	d
z  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}}y# 1 sw Y   xY w)u  dashboard/helpers.py 가 실제로 multi-dot 을 strip 하는지 SUT 단위 회귀.

    helpers 모듈은 함수 단위가 아니라 inline regex 이므로 source 텍스트에서
    task-2547+1 multi-dot 패턴 (`(?:\.\d+)*`) 존재를 회귀 박제로 검증한다.
    import 가능성 자체는 별도 조립 테스트가 책임지므로 여기서는 source 1:1 만 본다.
    	dashboardz
helpers.pyutf-8encodingN
(?:\.\d+)*inz%(py1)s in %(py3)ssrcpy1r7   u3   dashboard/helpers.py 에 multi-dot 패턴 미존재r8   r9   _ospathjoin_WROOTopenreadr   r   r   r   r   r   r   r   r   src_pathfhrx   @py_assert0rF   rG   rH   s          r$   7test_dashboard_helpers_module_pattern_supports_multidotr      s     xx}}V[,?H	h	) RggiW>S WWW>SWWW>WWWWWWSWWWSWWWW"WWWWWWW    DDc                 &   t         j                  j                  t        d      } t	        | d      5 }|j                         }ddd       d}|v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndd	z  }t        j                  d
      dz   d|iz  }t        t        j                  |            dx}}y# 1 sw Y   xY w)uO   report_parser.py 가 실제로 multi-dot 을 추출하는지 SUT 단위 회귀.zreport_parser.pyrq   rr   Nrt   ru   rw   rx   ry   u/   report_parser.py 에 multi-dot 패턴 미존재r8   r9   r{   r   s          r$   3test_report_parser_module_pattern_supports_multidotr      s    xx}}V%78H	h	) RggiS>S SSS>SSSS>SSSSSSSSSSSSSSS"SSSSSSS s   DDc                 (   t         j                  j                  t        dd      } t	        | d      5 }|j                         }ddd       d}|v }|st        j                  d|fd||f      t        j                  |      d	t        j                         v st        j                  |      rt        j                  |      nd	d
z  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}}y# 1 sw Y   xY w)u^   scripts/start_task_guard.py 가 multi-dot prefix 를 잘라먹지 않는지 SUT 단위 회귀.scriptszstart_task_guard.pyrq   rr   Nrt   ru   rw   rx   ry   u:   scripts/start_task_guard.py 에 multi-dot 패턴 미존재r8   r9   r{   r   s          r$   6test_start_task_guard_module_pattern_supports_multidotr      s    xx}}VY0EFH	h	) Rggi^>S ^^^>S^^^>^^^^^^S^^^S^^^^"^^^^^^^ r   c                 |   t         j                  j                  t        dd      } t	        | d      5 }|j                         }ddd       t        j                  d      }d}||u}|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z   d|iz  }t        t        j                   |            dx}}|j"                  }d} ||      }	d}
|	|
u }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      t        j                  |	      t        j                  |
      dz  }t        j                  d      dz   d|iz  }t        t        j                   |            dx}x}x}	x}}
y# 1 sw Y   xY w)uN  `_is_design_task = False` 초기 dead 초기화가 없는지 SUT 회귀.

    PR #95 head 에서 line 4523 에 추가되었던 `_is_design_task = False` 가 모든
    경로에서 재할당되어 dead code 였음. origin/main 은 이미 정리되어 있으며
    본 task-2547+1 는 그 상태를 회귀 박제로 보존한다.
    dispatchz__init__.pyrq   rr   Nz_if args\.workflow is None:\s*\n(?:[ \t]*#[^\n]*\n)*([ \t]+_is_design_task\s*=\s*False[^\n]*\n)?r2   r4   block_matchr6   u7   workflow None 블록 시작 위치를 찾을 수 없음r8   r9   r:   )is)zK%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.group
}(%(py4)s)
} is %(py9)srg   uT   _is_design_task = False dead 초기화가 다시 들어왔습니다 (PR #95 회귀).ri   rj   )r|   r}   r~   r   r   r   rerC   r   r   r   r   r   r   r   r   r   rD   )r   r   rx   r   rF   r!   rG   rH   rI   rJ   rk   rK   rl   rm   s                 r$   8test_dispatch_init_is_design_task_no_dead_initializationr      s    xx}}VZ?H	h	) Rggi ))jK #];d"]]];d]]]]]];]]];]]]d]]]$]]]]]]] Q Q 4 4'  4                           $(    	_      s   H11H;),__doc__
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   osr|   r   sys_sysr}   dirnameabspath__file__r   removeinsertpytestcompiler   DASHBOARD_PREFIX_RE_PRIORITY2
IGNORECASEr)   markparametrizer%   r*   rR   rB   rN   rV   r^   r`   rc   re   rn   r   r   r   r    r&   r$   <module>r      sG  $ #     	  
		#((**388+;+;CHH<L<LX<V+WX	Y	TYYIIV 		  F   !+

`!  !>  *

e
--!  *]+*] 	%	% $<  2::B 
 
&
& 	>> (RZZJ 
 	"	" ",C" 
  

X
XT_r&   