
    i%                     x   d 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  ee      j                         j                  d   Zej"                  j%                  dedz  dz        Zg ZdZeeuZeZerej0                  ZdZeeuZeZesB ej8                  defd	eef      d
 ej:                         v s ej<                  e      r ej>                  e      nd
 ej>                  e      dz  Z dde iz  Z!ejE                  e!       er ej8                  defdeef      d
 ej:                         v s ej<                  e      r ej>                  e      nd
 ej>                  e       ej>                  e      dz  Z#dde#iz  Z$ejE                  e$        ejJ                  ed      i z  Z&dde&iz  Z' e( ejR                  e'            dxZxZxZxZxZxZZej"                  jU                  e      Z+e+e
jX                  d<   ej0                  j[                  e+       dede.e/   ddfdZ0d Z1d Z2d Z3d Z4d Z5y)u   단위 테스트: token-tracker.py enrich() / parse_session() 토큰 기록 로직

task-2338 | 작성자: 카마소츠 (dev7 테스터)
    N)Path   token_trackerscriptsztoken-tracker.py)is not)z%(py2)s is not %(py5)sspec)py2py5z%(py7)spy7)z5%(py11)s
{%(py11)s = %(py9)s.loader
} is not %(py14)s)py9py11py14z%(py16)spy16zassert %(py19)spy19pathlinesreturnc                 V    | j                  dj                  d |D              d       y )N
c              3   F   K   | ]  }t        j                  |        y w)N)jsondumps).0ls     3/home/jay/workspace/tests/test_task_timer_tokens.py	<genexpr>z_write_jsonl.<locals>.<genexpr>   s     ;djjm;s   !utf-8encoding)
write_textjoin)r   r   s     r   _write_jsonlr"      s!    OODII;U;;gON    c           	         | dz  }t        |dddddddd	d
dddid
g       t        j                  t        |            }|d   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|d   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|d   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|d   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|d   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}|d   }d}||k(  }|slt	        j
                  d|fd||f      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}}y)u   assistant usage 블록에서 input/output/cache_read/cache_creation 4종 토큰을
    모두 수집하고 total_tokens = 합산, task_id 파싱을 검증한다.session.jsonl	assistantd      i,  i  input_tokensoutput_tokenscache_read_input_tokenscache_creation_input_tokensclaude-sonnet-4-6)usagemodeltypemessageusercontentz	task-9999r*   ==z%(py1)s == %(py4)spy1py4assert %(py6)spy6Nr+   cache_read_tokenscache_creation_tokenstotal_tokensi  task_id)	r"   r   parse_sessionstr
@pytest_ar_call_reprcompare	_safereprAssertionError_format_explanation)tmp_pathjsonlr@py_assert0@py_assert3@py_assert2@py_format5@py_format7s           r   )test_parse_session_collects_4_token_typesrQ   "   sT    &E %(%(/236	 -	
 !;/	
 & 	##CJ/A^###################_$$$$$$$$$$$$$$$$$$$ !(S(!S((((!S(((!(((S((((((($%,,%,,,,%,,,%,,,,,,,,,,^$$$$$$$$$$$$$$$$$$$Y<&;&<;&&&&<;&&&<&&&;&&&&&&&r#   c                 j   | dz  }t        |dddidg       t        j                  t        |            }|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  }dd|iz  }	t        t        j                  |	            dx}x}x}x}}y)u   user 메시지 내 경로에서 cwd_project 'InsuRo'를 추출하는지 확인한다.

    NOTE: parse_session()에 cwd_project 감지 로직이 현재 미구현 상태임.
    쿠쿨칸 패치 병합 후 통과 예정.
    r%   r4   r5   u@   task-9000 작업, 경로: /home/jay/projects/InsuRo/src/main.tsxr1   cwd_projectInsuRor6   zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)srK   py0r	   r;   r=   r   assert %(py11)sr   Nr"   r   rB   rC   getrD   rE   @py_builtinslocals_should_repr_global_namerF   rG   rH   
rI   rJ   rK   @py_assert1rM   @py_assert5@py_assert8@py_assert7@py_format10@py_format12s
             r   -test_parse_session_detects_cwd_project_insurore   G   s     &E]	
  	##CJ/A55++5+8+8++++8++++++1+++1+++5+++++++++8++++++++r#   c           
         | dz  }t        |dddi dgddddd	d
dddddidg       t        j                  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                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}x}x}}y)u   assistant tool 호출에 'mcp__' 접두사가 있을 때 mcp_used == True 인지 확인한다.

    NOTE: parse_session()에 mcp_used 감지 로직이 현재 미구현 상태임.
    쿠쿨칸 패치 병합 후 통과 예정.
    r%   r&   tool_usez"mcp__code-review-graph__get_review)r2   nameinput
      r   r)   r.   )r5   r/   r0   r1   r4   r5   z	task-8888mcp_usedTiszI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} is %(py9)srK   rV   rX   r   NrY   r^   s
             r   #test_parse_session_detects_mcp_usedrp   `   s    &E !+ D!# %'%&/034	 -	
( !;/	
) 4 	##CJ/A55$$5$$$$$$$$$$$$1$$$1$$$5$$$$$$$$$$$$$$$$$r#   c                    | dz  }| dz  }ddddddd	d
dddd	ii}ddddiii}|j                  t        j                  |      d       |j                  t        j                  |      d       t        j	                  t        |      t        |             t        j                  |j                  d            }|d   d   }|d   }|d   }d}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	|d   }d}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	|d   }d}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	|d   }d}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	|d   }d	}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}x}
}	|d    }d
}	||	k(  }
|
slt        j                  d|
fd||	f      t        j                  |      t        j                  |	      dz  }dd|iz  }t        t        j                  |            dx}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  }d%d&|iz  }t        t        j                  |            dx}x}	x}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  }d%d&|iz  }t        t        j                  |            dx}x}	x}x}}y)*u   ledger → timers 로 token_usage 4종 + total + cost 복사,
    cwd_project/mcp_used 태스크 레벨 복사를 검증한다.

    NOTE: enrich()가 mcp_used를 아직 복사하지 않음 — 쿠쿨칸 패치 병합 후 통과 예정.
    token-ledger.jsontask-timers.jsontasksztask-Xr            rj   g      ?r.   rT   T)	r*   r+   r>   r?   r@   cost_estimate_usdr0   rS   rl   team_id	dev7-teamr   r   timers_pathledger_pathtoken_usager*   r6   r8   r9   r<   r=   Nr+   r>   r?   r@   rx   rS   rU   txrV   rX   r   rl   rm   ro   )r    r   r   r   enrichrC   loads	read_textrD   rE   rF   rG   rH   rZ   r[   r\   r]   )rI   r}   r|   ledger_datatimers_dataresultr   turL   rM   rN   rO   rP   r_   r`   ra   rb   rc   rd   s                      r   %test_enrich_writes_all_4_token_fieldsr      s    00K//K 	 !!"%&)* "%(,' 

K  	;
K 4::k2WE4::k2WES%53{CSTZZ--w-?@F		"B	M	B n"""""""""""""""""""o#!#!####!######!#######!"'a'"a''''"a'''"'''a'''''''%&+!+&!++++&!+++&+++!+++++++n###################!")c)"c))))"c)))")))c))))))) 66,-,6- ,H, H,,,, H,,,,,,2,,,2,,,6,,,-,,, ,,,H,,,,,,, 66%*%6*%%%%%%%%%%%%2%%%2%%%6%%%*%%%%%%%%%%%%%%r#   c           
         | dz  }| dz  }ddddddddd	d
ii}ddddiii}|j                  t        j                  |      d       |j                  t        j                  |      d       t        j	                  t        |      t        |             t        j                  |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  }	dd|	iz  }
t        t        j                  |
            dx}}y)ur   timers에 task-Y, ledger에 task-Z만 있을 때
    task-Y에 token_usage가 추가되지 않음을 확인한다.rr   rs   rt   ztask-Zi  r   i  g?r.   )r*   r+   r>   r?   r@   rx   r0   ztask-Yry   rz   r   r   r{   r~   )not in)z%(py1)s not in %(py3)sty)r:   py3zassert %(py5)sr
   N)r    r   r   r   r   rC   r   r   rD   rE   rF   r[   r\   r]   rG   rH   )rI   r}   r|   r   r   r   r   rL   rN   @py_format4@py_format6s              r   !test_enrich_skips_unmatched_tasksr      s@    00K//K 	 #!$%&)* $%(,

K 	;
K 4::k2WE4::k2WES%53{CSTZZ--w-?@F		"B"=""""="""=""""""""""""""""r#   )6__doc__builtinsr[   _pytest.assertion.rewrite	assertionrewriterD   importlib.util	importlibr   syspathlibr   __file__resolveparents	WORKSPACEutilspec_from_file_locationr   r_   @py_assert4rM   rL   loader@py_assert10@py_assert13@py_assert12rE   r\   r]   rF   r   @py_format8append@py_format15@py_format17_format_boolop@py_format18@py_format20rG   rH   module_from_specr   modulesexec_modulelistdictr"   rQ   re   rp   r   r    r#   r   <module>r      s  
     
  N""$,,Q/	~~--Y*-?? 44 3t4 3DKK 3t 3Kt3 3 3 3t4 3 3 3 3 3t 3 3 3t 3 3 34 3 3 3 3 3 3 3Kt 3 3 3 3 3D 3 3 3D 3 3 3K 3 3t 3 3 3 3 3 3 3 3 3 3 3 3 3//5,O     &Ot ODJ O4 O'J,2#%T5&x##r#   