
     jK                       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ddlmZ ddlZ ee      j!                         j"                  j"                  j"                  Z ee      ej(                  v r!ej(                  j+                   ee             ej(                  j-                  d ee             ddlmZmZmZmZmZmZmZmZm Z  dZ!dZ"dZ#dd	Z$dd
Z%e#e!fddZ&d Z'd Z(d Z)d Z*d Z+d Z,d Z-d Z.d Z/d Z0d Z1d Z2d Z3d Z4y)u   
tests/regression/test_canonical_workspace_resolver_2517.py

헤임달 (QA 테스터) — task-2517 회귀 테스트 14건
canonical_workspace_resolver 4 ambiguity 구조적 제거 + 정상 흐름 + edge case + hook 통합
    )annotationsN)Path)	CanonicalWorkspaceassert_cwd_matches_workspaceassert_finish_task_contextassert_main_freshevaluate_scope_dirty	from_dictresolve_canonical_workspaceresolve_for_hooksto_json(a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2	task-2517ztask/task-2517-dev2c                     dd fd
}|S )zN
    responses key: tuple of args
    value: (returncode, stdout, stderr)
    Ncwdc                   t        |       }|vrt        d|d| d      |   \  }}}t        j                  | |||      S )NMock missing:  (cwd=)args
returncodestdoutstderr)tupleKeyError
subprocessCompletedProcess)r   r   keyrcouterr	responsess         N/home/jay/workspace/tests/regression/test_canonical_workspace_resolver_2517.pyrunnerz make_mock_runner.<locals>.runner0   sU    Dki^C7&Q?@@ ~C**CX[\\     )r$   r&   s   ` r%   make_mock_runnerr)   +   s    
 ! ] Mr'   c                &    d|  d| d| d| d| dS )N	worktree 
HEAD z"
branch refs/heads/main

worktree z
branch refs/heads/z

r(   )	main_rootworktree_pathbranchshas       r%   _porcelain_worktree_outputr1   9   sB    
I; u  "? #u #H %		r'   c                f    t        | |||      }d| ddfd|dfdd| ddfd| ddfd| ddfdS )u  공통으로 사용되는 mock runner 응답 맵을 반환한다.

    show-toplevel은 worktree_path를 반환한다 (git worktree 실제 동작).
    workspace_root는 git worktree list --porcelain의 첫 번째 entry(main_root)로 결정된다.
    is_main 판정은 cwd == workspace_root (== main_root) 비교이므로,
    worktree에서 호출하면 is_main=False가 된다.
    r   
 r   r4   r4   git	rev-parsez--show-toplevelr8   worktreelist--porcelainr8   fetchoriginmainz--quietr8   r9   zorigin/mainr8   r9   z--abbrev-refHEADr8   r9   rD   )r1   )r-   r.   r/   r0   	porcelains        r%   _make_standard_responsesrG   F   sl     +9mVSQI23b5I21N56	24F7B./C5R-@78VHB-6L'(SE*b&9 r'   c                (	   | dz  }|j                  d       d| dt         d}d| dd	fd|d	fd
dt         dd	fddt         dd	fd}t        |      }t        t        |d|      }|j
                  }|j                  } |       }||k(  }	|	st        j                  d|	fd||f      dt        j                         v st        j                  |      rt        j                  |      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}}|j                  }|j                  } |       }||k(  }	|	st        j                  d|	fd||f      dt        j                         v st        j                  |      rt        j                  |      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}}|j                   }d}||u }	|	st        j                  d|	fd||f      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}	}|j"                  }|t        k(  }	|	st        j                  d|	fd|t        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }dd |iz  }t        t        j                  |            dx}}	y)!u?   main repo에서 resolve → workspace_root == cwd, is_main=TruerA   Tparentsr+   r,   
branch refs/heads/main

r   r3   r4   r5   r   zmain
r4   r6   r   r?   r&   ==zj%(py2)s
{%(py2)s = %(py0)s.workspace_root
} == %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py4)s.resolve
}()
}wsr-   py0py2py4py6py8assert %(py10)spy10Nz_%(py2)s
{%(py2)s = %(py0)s.cwd
} == %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py4)s.resolve
}()
}isz/%(py2)s
{%(py2)s = %(py0)s.is_main
} is %(py5)srS   rT   py5assert %(py7)spy7)z/%(py2)s
{%(py2)s = %(py0)s.task_id
} == %(py4)sTASK_IDrS   rT   rU   assert %(py6)srV   )mkdirFAKE_SHAr)   r   rb   workspace_rootresolve
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationr   is_maintask_id)tmp_pathr-   rF   r$   r&   rQ   @py_assert1@py_assert5@py_assert7@py_assert3@py_format9@py_format11@py_assert4@py_format6@py_format8@py_format5@py_format7s                    r%   test_resolve_in_main_repor   ^   s   6!IOODO! I; z %	&  34	{"5Er1J56	24F7B./H:R"-E6G'(XJb/2&>I i(F	$W)4PV	WB3	 1 13 1 33 33333 333333323332333333333	333	333 1333 3333333366(Y&&(&((6(((((6(((((((2(((2(((6((((((Y(((Y(((&(((((((((((::::22::: :    :      2   2   :                r'   c                	   | dz  }| dz  dz  }|j                  d       |j                  d       t        t        |      t        |      t        t              }d| ddfd|dfd	dt         ddfdt         ddfdt         ddfd
}t        |      }t        t        |d|      }|j                  }|j                  } |       }	||	k(  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  |      rt        j                  |      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}}	|j$                  }|j                  } |       }	||	k(  }
|
st        j                  d|
fd||	f      dt        j                         v st        j                  |      rt        j                  |      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}}	|j&                  }d}||u }
|
st        j                  d|
fd||f      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}
}|j(                  }|t        k(  }
|
st        j                  d|
fd|t        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t!        t        j"                  |            dx}}
y) u   worktree에서 resolve → worktree_path == cwd, branch_name 매칭, is_main=False

    실제 git worktree에서 `git rev-parse --show-toplevel`은 main_root를 반환한다.
    따라서 workspace_root = main_root, cwd = worktree → is_main=False.
    rA   
.worktreestask-2517-dev2TrI   r   r3   r4   r5   r6   rM   rN   )zi%(py2)s
{%(py2)s = %(py0)s.worktree_path
} == %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py4)s.resolve
}()
}rQ   r;   rR   rX   rY   NrZ   Fr[   r]   r^   r`   ra   )z3%(py2)s
{%(py2)s = %(py0)s.branch_name
} == %(py4)sBRANCHrc   rd   rV   )re   r1   strr   rf   r)   r   rb   r.   rh   ri   rj   rk   rl   rm   rn   ro   rp   r   rq   branch_name)rs   r-   r;   rF   r$   r&   rQ   rt   ru   rv   rw   rx   ry   rz   r{   r|   r}   r~   s                     r%   test_resolve_in_worktreer   |   s    6!I,&)99HOODO!NN4N *3y>3x=&RZ[I 34	{"5Er1J56	24F7B./H:R"-E78VHB-6L'(XJb/2&>I i(F	$W($v	VB1x//1/1111111111111121112111111111x111x111/1111111111166'X%%'%''6'''''6'''''''2'''2'''6''''''X'''X'''%'''''''''''::::22:>>#>V####>V######2###2###>######V###V#######r'   c                   | dz  }| dz  dz  }|j                  d       |j                  d       d}t        t        |      t        |      |      }t        |      }t	        t
        |d|      }|j                  }||k(  }|st        j                  d	|fd
||f      dt        j                         v st        j                  |      rt        j                  |      nd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}}|j                  }||k(  }|st        j                  d	|fd||f      dt        j                         v st        j                  |      rt        j                  |      nd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}}y)u(   fetch 후 origin/main HEAD 정확 매칭rA   r   r   TrI   (deadbeefdeadbeefdeadbeefdeadbeefdeadbeefr0   rM   rN   z5%(py2)s
{%(py2)s = %(py0)s.main_head_sha
} == %(py4)srQ   	fixed_sharc   rd   rV   N)z0%(py2)s
{%(py2)s = %(py0)s.base_sha
} == %(py4)s)re   rG   r   r)   r   rb   main_head_shari   rj   rk   rl   rm   rn   ro   rp   base_sha)rs   r-   r;   r   r$   r&   rQ   rt   rw   r}   r~   s              r%   test_main_head_sha_lockr      sj   6!I,&)99HOODO!NN4N I(YXIVIi(F	$W($v	VB(y((((y((((((2(((2(((((((((y(((y(((((((;;#;)####;)######2###2###;######)###)#######r'   c                    | dz  }| dz  dz  }|j                  d       |j                  d       d}|j                  d|       t        t        |      t        |            }t	        |      }t        t        |d|      }|j                  }t        |      }	|	|k7  }
|
s7t        j                  d	|
fd
|	|f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nd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}	}
|j                  }|j                   } |       }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      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)uS   환경변수 WORKSPACE_ROOT 우선순위 — git rev-parse와 충돌 시 git 우선rA   r   r   TrI   z/some/completely/wrong/pathWORKSPACE_ROOTrM   !=zT%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.workspace_root
})
} != %(py7)sr   rQ   stale_env_rootrS   py1py3r_   ra   assert %(py9)spy9NrN   rP   r-   rR   rX   rY   re   setenvrG   r   r)   r   rb   rg   ri   rj   rk   rl   rm   rn   ro   rp   rh   )rs   monkeypatchr-   r;   r   r$   r&   rQ   @py_assert2rz   @py_assert6r|   @py_format10rt   ru   rv   rw   rx   ry   s                      r%   test_env_var_priority_git_winsr      s   6!I,&)99HOODO!NN4N 2N'8(YXGIi(F	$W($v	VB   33 !3!^3333!^33333333333333333r333r333 333!333333^333^33333333	 1 13 1 33 33333 333333323332333333333	333	333 1333 33333333r'   c                f   | dz  }| dz  dz  }| dz  }|j                  d       |j                  d       |j                  d       t        t        |      t        |            }t        |      }t	        t
        |d|      }t        |j                  |j                  |j                  |j                  |j                  |j                  |j                         |j                  |j                  	      }t!        j"                  t$        d	
      5  t'        |       ddd       y# 1 sw Y   yxY w)uM   잘못된 cwd → assert_cwd_matches_workspace RuntimeError('WRONG_CWD: ...')rA   r   r   some_other_dirTrI   rM   )	rr   rg   r.   r   r   r   r   rq   is_clean	WRONG_CWDmatchN)re   rG   r   r)   r   rb   r   rr   rg   r.   r   r   r   rh   rq   r   pytestraisesRuntimeErrorr   )rs   r-   r;   	wrong_dirr$   r&   rQ   ws_wrongs           r%   test_wrong_cwd_raisesr      s   6!I,&)99H++IOODO!NN4N OODO!(YXGIi(F	$W($v	VB "

((&&NN&&


H 
|;	7 /$X./ / /s   D''D0c                b  	
 | dz  }| dz  dz  |j                  d       j                  d       d
dt        t        |      t              t        
      	dd	id
d	
fd
}t	        t
        d|      }|j                  }|
k(  }|st        j                  d|fd|
f      dt        j                         v st        j                  |      rt        j                  |      nd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}}t        j                   t"        d      5  t%        ||       d
d
d
       y
# 1 sw Y   y
xY w)uZ   fetch 후 origin/main 변경 시뮬레이션 → assert_main_fresh FAIL('STALE_MAIN: ...')rA   r   r   TrI   (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbnr   Nr   c               @   t        |       }|dk(  r5dxx   dz  cc<   d   dk(  r
n}t        j                  | d| dd      S d ddfd	dfddt         ddfd
 ddfd	}||vrt	        d
|d| d      ||   \  }}}t        j                  | |||      S )NrB   r      r   r3   r4   r   r5   )r7   r:   r>   rC   rE   r   r   r   )r   r   r   r   r   )r   r   r    r0   fixedr!   r"   r#   
call_countrF   sha1sha2r;   s           r%   stateful_runnerz/test_stale_main_raises.<locals>.stateful_runner   s    Dk55sOq O$S/Q.$DC..DQRUQVVXzbdee67H:R"5M9:Ir8J;F;<mR:P+,bk2*>
 e^C7&Q?@@SzC**CX[\\r'   rM   rN   r   rQ   r   rc   rd   rV   
STALE_MAINr   r&   )re   r1   r   r   r   rb   r   ri   rj   rk   rl   rm   rn   ro   rp   r   r   r   r   )rs   r-   r   rQ   rt   rw   r}   r~   r   rF   r   r   r;   s           @@@@@r%   test_stale_main_raisesr      s8   6!I,&)99HOODO!NN4N DD +3y>3x=&RVWIqJ%) ] ]$ 
%W($	_B#t####t######2###2#########t###t####### 
|<	8 6"_56 6 6s   F%%F.c                t   | dz  }| dz  dz  }|j                  d       |j                  d       dg}t        g d|z         }t        t        |      t        |            }d||<   t	        |      }t        t        |d|	      }t        |||
      }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}
}	y)uS   expected_files 외 파일이 dirty → evaluate_scope_dirty IS_CLEAN (False 반환)rA   r   r   TrI   z%utils/canonical_workspace_resolver.py)r8   statusr=   z--r5   rM   r   Fr[   )z%(py0)s is %(py3)sresult)rS   r   zassert %(py5)sr_   N)re   r   rG   r   r)   r   rb   r	   ri   rj   rk   rl   rm   rn   ro   rp   )rs   r-   r;   expected_filesclean_status_keyr$   r&   rQ   r   r   rt   @py_format4r{   s                r%   $test_dirty_workspace_false_detectionr     s    6!I,&)99HOODO!NN4N =>NCnTU(YXGI"-Ii(F	$W($v	VB ""nVDF6U?6U66Ur'   c                   | dz  }| dz  dz  }|j                  d       |j                  d       d}d}t        t        |      t        |      |      }d	| d
df|d<   t        |      }t	        t
        |d|      }||j                  t        |j                        d}t        j                  t        d      5  t        |||       ddd       y# 1 sw Y   yxY w)u|   HEAD SHA 변경 후 finish_target 불일치 → assert_finish_task_context RuntimeError('FINISH_TASK_CONTEXT_MISMATCH: ...')rA   r   r   TrI   (cccccccccccccccccccccccccccccccccccccccc(ddddddddddddddddddddddddddddddddddddddddr   r   r3   r4   rE   rM   head_shar   r.   FINISH_TASK_CONTEXT_MISMATCHr   r   N)re   rG   r   r)   r   rb   r   r.   r   r   r   r   )	rs   r-   r;   original_head_shachanged_head_shar$   r&   rQ   finish_targets	            r%   !test_finish_task_context_mismatchr   )  s    6!I,&)99HOODO!NN4N  (YXL]^I 015E4Fb2I2.NI*+i(F	$W($v	VB &~~R--.M 
|+I	J E"2}VDE E Es   =CCc                   | dz  }|j                  d       d| dt         d}d| dd	fd|d	fd
dt         dd	fddt         dd	fd}t        |      }t        t        |d|      }|j
                  }d}||u}|st        j                  d|fd||f      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}}g }d}|j
                  }t        |      }||v }|}|sd}|j
                  }t        |      }||v }|}|s:t        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }|j                  |       |st        j                  dfdf      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                        t        j                  |      dz  }dd |iz  }|j                  |       t        j                   |d!      i z  }d"d#|iz  }t        t        j                  |            dx}x}x}x}x}x}x}x}x}}y)$ud   worktree 없을 때 resolve — worktree_path만 산출, 생성 X (실제 디렉토리 없어도 OK)rA   TrI   r+   r,   rK   r   r3   r4   r5   rL   r6   rM   N)is not)z9%(py2)s
{%(py2)s = %(py0)s.worktree_path
} is not %(py5)srQ   r^   r`   ra   r   dev1)in)zU%(py3)s in %(py10)s
{%(py10)s = %(py5)s(%(py8)s
{%(py8)s = %(py6)s.worktree_path
})
}r   )r   r_   rV   rW   rY   z%(py12)spy12)zZ%(py15)s in %(py22)s
{%(py22)s = %(py17)s(%(py20)s
{%(py20)s = %(py18)s.worktree_path
})
})py15py17py18py20py22z%(py24)spy24r   zassert %(py27)spy27)re   rf   r)   r   rb   r.   ri   rj   rk   rl   rm   rn   ro   rp   r   append_format_boolop)rs   r-   rF   r$   r&   rQ   rt   rz   rw   r{   r|   r   rv   @py_assert9@py_assert0@py_assert14@py_assert19@py_assert21@py_assert16ry   @py_format13@py_format23@py_format25@py_format26@py_format28s                            r%   "test_resolve_when_worktree_missingr   L  s}   6!IOODO! I; z %	&  34	{"5Er1J56	24F7B./H:R"-E6G'(XJb/2&>I i(F	$W)4PV	WB '4'4''''4''''''2'''2''''''4'''''''R;Rb..R#./R;//R6RAQAQRSAQ=RR6=R3RRRRR;/RRR;RRRRRR#RRR#RRRRRRbRRRbRRR.RRR/RRRRRRR6=RRRR6RRRRRRSRRRSRRRRRRRRRRRRAQRRR=RRRRRRRRRRRRRRRRr'   c                    | dz  }| dz  dz  }|j                  d       |j                  d       d}|j                  d|       t        t        |      t        |            }t	        |      }t        t        |d|      }|j                  }t        |      }	|	|k7  }
|
s7t        j                  d	|
fd
|	|f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nd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}	}
|j                  }|j                   } |       }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      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)u8   PROJECT_PATH 환경변수 stale 시 git rev-parse 우선rA   r   r   TrI   z/old/stale/project/pathPROJECT_PATHrM   r   r   r   rQ   stale_project_pathr   r   r   NrN   rP   r-   rR   rX   rY   r   )rs   r   r-   r;   r   r$   r&   rQ   r   rz   r   r|   r   rt   ru   rv   rw   rx   ry   s                      r%   test_env_var_project_path_staler   l  s   6!I,&)99HOODO!NN4N 2~'9:(YXGIi(F	$W($v	VB   73 !7!%77777!%777777737773777777r777r777 777!777777%7777%777777773	 1 13 1 33 33333 333333323332333333333	333	333 1333 33333333r'   c                   | dz  }| dz  dz  }|j                  d       |j                  d       t        t        |      t        |            }t        |      }t	        t
        |d|      }t        |      }t        j                  |      }t        |      }|j                  }	|j                  }
|	|
k(  }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                   |      nd	t        j                   |	      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}	x}}
|j&                  }	|j&                  }
|	|
k(  }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                   |      nd	t        j                   |	      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}	x}}
|j(                  }	|j(                  }
|	|
k(  }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                   |      nd	t        j                   |	      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}	x}}
|j*                  }	|j*                  }
|	|
k(  }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                   |      nd	t        j                   |	      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}	x}}
|j,                  }	|j,                  }
|	|
k(  }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                   |      nd	t        j                   |	      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}	x}}
|j.                  }	|j.                  }
|	|
k(  }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                   |      nd	t        j                   |	      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}	x}}
|j0                  }	|j0                  }
|	|
k(  }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                   |      nd	t        j                   |	      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}	x}}
|j2                  }	|j2                  }
|	|
k(  }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                   |      nd	t        j                   |	      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}	x}}
|j4                  }	|j4                  }
|	|
k(  }|st        j                  d|fd|	|
f      d	t        j                         v st        j                  |      rt        j                   |      nd	t        j                   |	      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}	x}}
y)uF   to_json → from_dict 라운드트립 무결성 (모든 필드 동일)rA   r   r   TrI   rM   rN   )zL%(py2)s
{%(py2)s = %(py0)s.task_id
} == %(py6)s
{%(py6)s = %(py4)s.task_id
}ws_restoredws_originalrS   rT   rU   rV   assert %(py8)srW   NzZ%(py2)s
{%(py2)s = %(py0)s.workspace_root
} == %(py6)s
{%(py6)s = %(py4)s.workspace_root
}zX%(py2)s
{%(py2)s = %(py0)s.worktree_path
} == %(py6)s
{%(py6)s = %(py4)s.worktree_path
}zT%(py2)s
{%(py2)s = %(py0)s.branch_name
} == %(py6)s
{%(py6)s = %(py4)s.branch_name
}zX%(py2)s
{%(py2)s = %(py0)s.main_head_sha
} == %(py6)s
{%(py6)s = %(py4)s.main_head_sha
})zN%(py2)s
{%(py2)s = %(py0)s.base_sha
} == %(py6)s
{%(py6)s = %(py4)s.base_sha
})zD%(py2)s
{%(py2)s = %(py0)s.cwd
} == %(py6)s
{%(py6)s = %(py4)s.cwd
})zL%(py2)s
{%(py2)s = %(py0)s.is_main
} == %(py6)s
{%(py6)s = %(py4)s.is_main
})zN%(py2)s
{%(py2)s = %(py0)s.is_clean
} == %(py6)s
{%(py6)s = %(py4)s.is_clean
})re   rG   r   r)   r   rb   r   jsonloadsr
   rr   ri   rj   rk   rl   rm   rn   ro   rp   rg   r.   r   r   r   r   rq   r   )rs   r-   r;   r$   r&   r   json_strparsedr   rt   ru   rw   r~   rx   s                 r%   (test_canonical_workspace_json_round_tripr     s   6!I,&)99HOODO!NN4N (YXGIi(F-g84X^_K {#HZZ!FF#K 5+"5"55"55555"5555555;555;555555555+555+555"55555555%%C)C)CC%)CCCCC%)CCCCCCC;CCC;CCC%CCCCCCCCCCCC)CCCCCCCC$$A(A(AA$(AAAAA$(AAAAAAA;AAA;AAA$AAAAAAAAAAAA(AAAAAAAA""=k&=&=="&====="&=======;===;==="======k===k===&========$$A(A(AA$(AAAAA$(AAAAAAA;AAA;AAA$AAAAAAAAAAAA(AAAAAAAA7;#7#77#77777#7777777;777;777777777;777;777#77777777??-koo-?o----?o------;---;---?------k---k---o-------5+"5"55"55555"5555555;555;555555555+555+555"555555557;#7#77#77777#7777777;777;777777777;777;777#77777777r'   c                	   | dz  }| dz  dz  }|j                  d       |j                  d       t        t        |      t        |            }t        |      }t	        t
        d|d|      }t	        t
        d|d|      }|j                  }|j                  }||k(  }	|	st        j                  d|	fd	||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      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}x}	}|j                  }|j                  }||k(  }	|	st        j                  d|	fd||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      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}x}	}|j                   }|j                   }||k(  }	|	st        j                  d|	fd||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      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}x}	}|j"                  }|j"                  }||k(  }	|	st        j                  d|	fd||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      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}x}	}y)uW   resolve_for_hooks('scope-guard') 두 번 호출 시 동일 workspace fields (확정성)rA   r   r   TrI   zscope-guardrM   rN   r   ws1ws2r   r   rW   Nr   r   r   )re   rG   r   r)   r   rb   rg   ri   rj   rk   rl   rm   rn   ro   rp   r.   r   r   )rs   r-   r;   r$   r&   r   r   rt   ru   rw   r~   rx   s               r%   &test_hook_scope_guard_shares_workspacer     s   6!I,&)99HOODO!NN4N (YXGIi(F
G]U[
\C
G]U[
\C 3!3!33!33333!333333333333333333333333333!333333331 1 11 11111 111111131113111111111111111 11111111??-coo-?o----?o------3---3---?------c---c---o-------1 1 11 11111 111111131113111111111111111 11111111r'   c                J   | dz  }| dz  dz  }|j                  d       |j                  d       t        t        |      t        |            }t        |      }t	        t
        d|d|      }t        |j                  t        |j                        d}t        |||	       y
)uW   resolve_for_hooks('finish-task') 결과로 assert_finish_task_context PASS (mismatch 0)rA   r   r   TrI   zfinish-taskrM   r   r   N)
re   rG   r   r)   r   rb   rf   r   r.   r   )rs   r-   r;   r$   r&   rQ   r   s          r%   &test_hook_finish_task_shares_workspacer     s    6!I,&)99HOODO!NN4N (YXGIi(F	7MxtTZ	[B ~~R--.M r=@r'   c                0   | dz  }| dz  dz  }|j                  d       |j                  d       t        t        |      t        |            }t        |      }t	        t
        d|d|      }t	        t
        d|d|      }|j                  }|j                  }||k(  }	|	st        j                  d	|	fd
||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      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}x}	}|j                  }|t        k(  }	|	st        j                  d	|	fd|t        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }
t        t        j                  |
            dx}}	y)uM   resolve_for_hooks('smoke')와 resolve_for_hooks('qc')가 동일 main_head_sharA   r   r   TrI   smokerM   qcrN   r   ws_smokews_qcr   r   rW   Nr   rf   rc   rd   rV   )re   rG   r   r)   r   rb   r   ri   rj   rk   rl   rm   rn   ro   rp   rf   )rs   r-   r;   r$   r&   r  r  rt   ru   rw   r~   rx   r}   s                r%   test_hooks_share_main_head_shar    s   6!I,&)99HOODO!NN4N (YXGIi(F 'xtTZ[HgtfUE !!8U%8%88!%88888!%888888888888888!888888U888U888%88888888!!-!X----!X------8---8---!------X---X-------r'   )r$   dict)
r-   r   r.   r   r/   r   r0   r   returnr   )r-   r   r.   r   r/   r   r0   r   )5__doc__
__future__r   builtinsrk   _pytest.assertion.rewrite	assertionrewriteri   r   r   syspathlibr   r   __file__rh   parent_WORKTREE_ROOTr   pathremoveinsert"utils.canonical_workspace_resolverr   r   r   r   r	   r
   r   r   r   rf   rb   r   r)   r1   rG   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r(   r'   r%   <module>r     s   #     
   h'')0077>>~#(("HHOOC'( 3~& '
 
 
  6
	
 PVbj 0!<$@$$44/@%6R0EFS@4,8D2*A0.r'   