
    iK              
          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mZ d dlZ ee      j                   j                   Ze	j$                  j'                  d  ee             edz  Zej,                  j/                  de      ZdZeeuZes ej6                  defdeef      d ej8                         v s ej:                  e      r ej<                  e      nd ej<                  e      d	z  Zd
deiz  Z  e! ejD                  e             dxZZej,                  jG                  e      Z$ejJ                  ZdZ&ee&uZ'e's ej6                  de'fdee&f      d ej8                         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! ejD                  e(            dxZxZ'Z&ejJ                  jS                  e$       dede*e+   defdZ,d*dede*e   dz  de*e   dz  defdZ-d+dede.de/defdZ0d,dede*e   dede*e+   fdZ1 G d d      Z2 G d  d!      Z3 G d" d#      Z4 G d$ d%      Z5 G d& d'      Z6 G d( d)      Z7y)-    N)date)Pathzlearning-analyzer.pylearning_analyzeris notz%(py0)s is not %(py3)sspecpy0py3assert %(py5)spy5)z2%(py2)s
{%(py2)s = %(py0)s.loader
} is not %(py5)s)r   py2r   assert %(py7)spy7tmp_pathrecordsreturnc                     | dz  }|D cg c]  }t        j                  |       }}|j                  dj                  |      d       |S c c}w )Nzaudit-trail.jsonl
utf-8encoding)jsondumps
write_textjoin)r   r   frliness        ;/home/jay/workspace/scripts/tests/test_learning_analyzer.pymake_audit_trailr"      sK    &&A$+,qTZZ],E,LL5!GL4H -s   Afilespatternsc                     d}|r|dz  }|D ]  }|d| dz  } |r|dz  }|D ]  }|d| dz  } | dz  }|j                  |d       |S )	N zfiles:
z  - "z"
z
patterns:
zwhitelist.yamlr   r   r   )r   r#   r$   contentr   ps         r!   make_whitelistr*       s    G: 	&Aqc~%G	&=  	&Aqc~%G	&##ALL7L+H    min_task_countmin_task_ratioc                 H    d| d| d}| dz  }|j                  |d       |S )Nzmin_task_count: z
min_task_ratio: r   zthresholds.yamlr   r   r'   )r   r,   r-   r(   r   s        r!   make_thresholdsr/   /   s:      00B>BRRTUG$$ALL7L+Hr+   	file_pathtask_idsts_basec           
      z    g }t        |      D ]*  \  }}|j                  | dd|z   ddddd|  |dd	       , |S )
NT
   02dz:00:00Zdev1Editz/home/jay/workspace/   tsbottoolfiletask_idschema_version)	enumerateappend)r0   r1   r2   r   itids         r!   make_sample_recordsrE   6   sc    GH% 

3 	2a4*G4.yk:"#		


 Nr+   c                   0    e Zd ZdefdZdefdZdefdZy)TestLoadWhitelistr   c                 F   t        |dgddg      }t        j                  |      }g }d}||v }|}|sd}||v }	|	}|sXt        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  }|j                  |       |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  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            d x}x}x}x}x}}	y )Nz(/home/jay/workspace/config/settings.yamlconfig/*ztests/*r#   r$   r#   r$   in)z%(py3)s in %(py5)sresult)r   r   %(py7)sr   )z%(py10)s in %(py12)s)py10py12z%(py14)spy14   zassert %(py17)spy17)r*   r   load_whitelist
@pytest_ar_call_reprcompare	_saferepr@py_builtinslocals_should_repr_global_namerB   _format_boolopAssertionError_format_explanation)selfr   wl_pathrM   @py_assert1@py_assert2@py_assert4@py_assert0@py_assert9@py_assert11@py_format6@py_format8@py_format13@py_format15@py_format16@py_format18s                   r!   test_load_whitelist_normalz,TestLoadWhitelist.test_load_whitelist_normalL   s     => ),

 #11':8w8w& 8J8J&$88888w&888w888888&888&8888888J&888J888888&888&88888888888888r+   c                 $   |dz  }t         j                  |      }g }i }||k(  }|}|st        |t              }|}|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  }
|j                  |
       |sd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d
t        j                         v st	        j                  t              rt	        j                  t              nd
t	        j                        dz  }|j                  |       t	        j                  |d      i z  }dd|iz  }t        t	        j                  |            d x}x}x}x}}y )Nnonexistent.yaml==z%(py2)s == %(py5)srM   r   r   rN   r   2%(py13)s
{%(py13)s = %(py9)s(%(py10)s, %(py11)s)
}
isinstancedictpy9rO   py11py13rR   assert %(py16)spy16)r   rT   rt   ru   rU   rV   rX   rY   rZ   rW   rB   r[   r\   r]   )r^   r   missingrM   r`   rb   @py_assert3rc   @py_assert12rf   rg   @py_format14ri   @py_format17s                 r!   test_load_whitelist_missingz-TestLoadWhitelist.test_load_whitelist_missingU   s   //"11':77v|7z&$777777v777777v777v7777777777777z777z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                 J   |dz  }|j                  dd       t        j                  |      }g }i }||k(  }|}|st        |t              }|}|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  }
|j                  |
       |sd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dt        j                         v st        j                  t              rt        j                  t              ndt        j                        dz  }|j                  |       t        j                  |d      i z  }dd|iz  }t        t        j                  |            d x}x}x}x}}y )Nz
empty.yamlr&   r   r   ro   rq   rM   rr   rN   r   rs   rt   ru   rv   rR   rz   r{   )r   r   rT   rt   ru   rU   rV   rX   rY   rZ   rW   rB   r[   r\   r]   )r^   r   r   rM   r`   rb   r}   rc   r~   rf   rg   r   ri   r   s                 r!   test_load_whitelist_emptyz+TestLoadWhitelist.test_load_whitelist_emptyZ   s   |#	R'*"11!477v|7z&$777777v777777v777v7777777777777z777z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+   N)__name__
__module____qualname__r   rl   r   r    r+   r!   rG   rG   K   s&    94 98D 8
8$ 8r+   rG   c                   0    e Zd ZdefdZdefdZdefdZy)TestLoadThresholdsr   c                 d   t        |dd      }t        j                  |      }|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
   }t        j                  }	d}
 |	|
      }||k(  }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  t              rt        j
                  t              ndt        j
                  |	      t        j
                  |
      t        j
                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}	x}
}y )N   g?r,   r-   r,   ro   z%(py1)s == %(py4)spy1py4assert %(py6)spy6r-   zL%(py1)s == %(py9)s
{%(py9)s = %(py5)s
{%(py5)s = %(py3)s.approx
}(%(py7)s)
}pytestr   r   r   r   rw   assert %(py11)srx   )r/   r   load_thresholdsrU   rV   rW   r\   r]   r   approxrX   rY   rZ   )r^   r   th_pathrM   rc   r}   ra   @py_format5@py_format7rb   @py_assert6@py_assert8@py_format10@py_format12s                 r!   test_load_thresholds_normalz.TestLoadThresholds.test_load_thresholds_normalg   s   !(1SQ"227;&',1,'1,,,,'1,,,',,,1,,,,,,,&'=6=====+=='+====='+===='======6===6==========+=========r+   c                 R   |dz  }t         j                  |      }|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	   }t        j                  }	d
}
 |	|
      }||k(  }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |	      t        j                  |
      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}	x}
}y )Nrn   r,      ro   r   r   r   r   r-   333333?r   r   r   r   rx   )r   r   rU   rV   rW   r\   r]   r   r   rX   rY   rZ   )r^   r   r|   rM   rc   r}   ra   r   r   rb   r   r   r   r   s                 r!   test_load_thresholds_missingz/TestLoadThresholds.test_load_thresholds_missingm   s   //"227;&',1,'1,,,,'1,,,',,,1,,,,,,,&'=6=====+=='+====='+===='======6===6==========+=========r+   c                 x   |dz  }|j                  dd       t        j                  |      }|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   }t        j                  }	d}
 |	|
      }||k(  }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  t              rt        j
                  t              ndt        j
                  |	      t        j
                  |
      t        j
                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}	x}
}y )Nzpartial.yamlzmin_task_count: 5
r   r   r,   r   ro   r   r   r   r   r-   r   r   r   r   r   rx   )r   r   r   rU   rV   rW   r\   r]   r   r   rX   rY   rZ   )r^   r   r   rM   rc   r}   ra   r   r   rb   r   r   r   r   s                 r!   test_load_thresholds_partialz/TestLoadThresholds.test_load_thresholds_partials   s!   ~%	*W="2215&',1,'1,,,,'1,,,',,,1,,,,,,,&'=6=====+=='+====='+===='======6===6==========+=========r+   N)r   r   r   r   r   r   r   r   r+   r!   r   r   f   s&    >D >>T >>T >r+   r   c                   `    e Zd ZdefdZdefdZdefdZdefdZdefdZdefdZ	defdZ
y	)
TestParseAuditTrailr   c                    t        dddg      }t        ||      }t        ddd      }t        ddd      }t        j	                  |||      }t        |      }d}||k(  }	|	st        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z  }
dd|
iz  }t        t        j                  |            d x}x}	}y )N
src/app.pytask-1.1task-2.1           r9   ro   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenrM   r   r   r   r   assert %(py8)spy8rE   r"   r   r   parse_audit_trailr   rU   rV   rX   rY   rZ   rW   r\   r]   r^   r   r   
trail_path
week_startweek_endrM   ra   @py_assert5rb   r   @py_format9s               r!   test_parse_normalz%TestParseAuditTrail.test_parse_normal   s    %lZ4LM%h8
$1%
a$"44ZXV6{a{a{ass66{ar+   c                    t        ddgd      }t        ddgd      }t        |||z         }t        dd	d
      }t        dd	d      }t        j	                  |||      }t        |      }d}	||	k(  }
|
st        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z  }dd|iz  }t        t        j                  |            d x}x}
}	|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}}y )Nr   r   z
2026-04-08)r2   zsrc/other.pyr   z
2026-04-01r   r   r   r   rR   ro   r   r   rM   r   r   r   r   r?   r   r   r   r   r   )r^   r   insideoutsider   r   r   rM   ra   r   rb   r   r   rc   r}   r   s                   r!   !test_parse_excludes_outside_rangez5TestParseAuditTrail.test_parse_excludes_outside_range   sE   $\J<V%nzlLY%h0@A
$1%
a$"44ZXV6{a{a{ass66{aay#1z1#z1111#z111#111z1111111r+   c                    dddddddg}t        ||      }t        dd	d
      }t        dd	d      }t        j                  |||      }t	        |      }d}||k(  }	|	st        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z  }
dd|
iz  }t        t        j                  |            d x}x}	}y )N2026-04-08T10:00:00Zr7   r8   z/tmp/scratch.pyr   r9   r:   r   r   r   r   r   ro   r   r   rM   r   r   r   r"   r   r   r   r   rU   rV   rX   rY   rZ   rW   r\   r]   r   s               r!   test_parse_excludes_tmp_pathsz1TestParseAuditTrail.test_parse_excludes_tmp_paths   s     -)%"#	
 &h8
$1%
a$"44ZXV6{a{a{ass66{ar+   c                    dddddddg}t        ||      }t        dd	d
      }t        dd	d      }t        j                  |||      }t	        |      }d}||k(  }	|	st        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z  }
dd|
iz  }t        t        j                  |            d x}x}	}y )Nr   anur8   /home/jay/workspace/src/app.pyr   r9   r:   r   r   r   r   r   ro   r   r   rM   r   r   r   r   r   s               r!   test_parse_excludes_anuz+TestParseAuditTrail.test_parse_excludes_anu   s     -8%"#	
 &h8
$1%
a$"44ZXV6{a{a{ass66{ar+   c                    dddddddddddd	ddg}t        ||      }t        d
dd      }t        d
dd      }t        j                  |||      }t	        |      }d}||k(  }	|	st        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z  }
dd|
iz  }t        t        j                  |            d x}x}	}y )Nr   r7   r8   r   unknownr9   r:   z2026-04-08T11:00:00Zr&   r   r   r   r   r   ro   r   r   rM   r   r   r   r   r   s               r!   #test_parse_excludes_unknown_task_idz7TestParseAuditTrail.test_parse_excludes_unknown_task_id   s    -8$"# -8"#
$ &h8
$1%
a$"44ZXV6{a{a{ass66{ar+   c                    t        |g       }t        ddd      }t        ddd      }t        j                  |||      }g }||k(  }|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 )Nr   r   r   r   ro   z%(py0)s == %(py3)srM   r
   r   r   )r"   r   r   r   rU   rV   rX   rY   rZ   rW   r\   r]   )
r^   r   r   r   r   rM   ra   r`   @py_format4rf   s
             r!   test_parse_empty_filez)TestParseAuditTrail.test_parse_empty_file   s    %h3
$1%
a$"44ZXVv|vvvr+   c                    |dz  }t        ddd      }t        ddd      }t        j                  |||      }g }||k(  }|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 )Nnonexistent.jsonlr   r   r   r   ro   r   rM   r
   r   r   )r   r   r   rU   rV   rX   rY   rZ   rW   r\   r]   )
r^   r   r|   r   r   rM   ra   r`   r   rf   s
             r!   test_parse_missing_filez+TestParseAuditTrail.test_parse_missing_file   s    00$1%
a$"44Wj(Sv|vvvr+   N)r   r   r   r   r   r   r   r   r   r   r   r   r+   r!   r   r      sV     $  2$ 2 d  "   " D  2d  r+   r   c                   \    e Zd ZdddZg g dZd Zd Zd Zd Zd	 Z	d
 Z
d Zd Zd Zd Zy)TestComputeHotspotsr   r   r   rJ   c                    t        dg d      }ddd}t        j                  || j                  |      \  }}t	        |      }d}||k(  }|st        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z  }dd|iz  }	t        t        j                  |	            d x}x}}d}
|d   d   }|
|v }|slt        j                  d|fd|
|f      t        j                  |
      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}
x}}y )Nr   r   r   task-3.1task-4.1r   皙?r   rR   ro   r   r   hotspotsr   r   r   zapp.pyr   r>   rK   )z%(py1)s in %(py4)sr   r   r   )rE   r   compute_hotspots_WHITELIST_EMPTYr   rU   rV   rX   rY   rZ   rW   r\   r]   )r^   r   
thresholdsr   _ra   r   rb   r   r   rc   r}   r   s                r!   test_hotspot_above_thresholdz0TestComputeHotspots.test_hotspot_above_threshold   s   %l4de()SA
'88$BWBWYcd!8}!!}!!!!}!!!!!!s!!!s!!!!!!8!!!8!!!}!!!!!!!!!!.8A;v..x.....x....x...........r+   c                    t        dddg      }t        j                  || j                  | j                        \  }}t        |      }d}||k(  }|st        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	z  }d
d|iz  }t        t        j                  |            d x}x}}y )Nr   r   r   r   ro   r   r   r   r   r   r   )rE   r   r   r   _THRESHOLDS_DEFAULTr   rU   rV   rX   rY   rZ   rW   r\   r]   )	r^   r   r   r   ra   r   rb   r   r   s	            r!   test_hotspot_below_thresholdz0TestComputeHotspots.test_hotspot_below_threshold   s    %lZ4LM'88$BWBWY]YqYqr!8}!!}!!!!}!!!!!!s!!!s!!!!!!8!!!8!!!}!!!!!!!!!!r+   c           
         t        dg d      }d}g }t        d|dz         D ]"  }|j                  dddd	| d
d| ddd       $ ddd}t        j	                  ||z   | j
                  |      \  }}t        |      }d}	||	k(  }
|
st        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z  }dd|iz  }t        t        j                  |            d x}x}
}	y )Nr   r   r   r      r   rR   2026-04-07T10:00:00Zr7   r8   /home/jay/workspace/src/other_.pytask-.1r9   r:   r         ?r   r   ro   r   r   r   r   r   r   rE   rangerB   r   r   r   r   rU   rV   rX   rY   rZ   rW   r\   r]   )r^   records_apptotal_task_countextra_recordsrC   r   r   r   ra   r   rb   r   r   s                r!   test_hotspot_ratio_checkz,TestComputeHotspots.test_hotspot_ratio_check   s)   ),8\]q*Q./ 
	A  0!"<QCsC!&qc}&'	
	 )*SA
'88}9TVZVkVkmwx!8}!!}!!!!}!!!!!!s!!!s!!!!!!8!!!8!!!}!!!!!!!!!!r+   c           
         t        dg d      }g }t        dd      D ]"  }|j                  dddd| d	d
| ddd       $ ddd}t        j	                  ||z   | j
                  |      \  }}t        |      }d}||k(  }	|	st        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z  }
dd|
iz  }t        t        j                  |            d x}x}	}y )Nr   r   r      r   r7   r8   r   r   r   r   r9   r:   r   r   r   r   ro   r   r   r   r   r   r   r   )r^   r   extrarC   r   r   r   ra   r   rb   r   r   s               r!   test_hotspot_and_conditionz.TestComputeHotspots.test_hotspot_and_condition  s   %l4XYq" 
	ALL0!"<QCsC!&qc}&'	
	 )*SA
'885$J_J_akl!8}!!}!!!!}!!!!!!s!!!s!!!!!!8!!!8!!!}!!!!!!!!!!r+   c                    t        dg d      }dhg d}ddd}t        j                  |||      \  }}t        |      }d}||k(  }|st	        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z  }	dd|	iz  }
t        t	        j                  |
            d x}x}}t        |      }d}||k(  }|st	        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z  }	dd|	iz  }
t        t	        j                  |
            d x}x}}y )Nr   r   rJ   r   r   r   r   ro   r   r   r   r   r   r   rR   whitelistedrE   r   r   r   rU   rV   rX   rY   rZ   rW   r\   r]   r^   r   	whitelistr   r   r   ra   r   rb   r   r   s              r!   test_whitelist_exclusionz,TestComputeHotspots.test_whitelist_exclusion  s[   %l4de+n"=	()SA
 1 B B7IWa b+8}!!}!!!!}!!!!!!s!!!s!!!!!!8!!!8!!!}!!!!!!!!!!;$1$1$$$$1$$$$$$s$$$s$$$$$$;$$$;$$$$$$1$$$$$$$r+   c                    t        dg d      }g dgd}ddd}t        j                  |||      \  }}t        |      }d}||k(  }|st	        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z  }	dd|	iz  }
t        t	        j                  |
            d x}x}}t        |      }d}||k(  }|st	        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z  }	dd|	iz  }
t        t	        j                  |
            d x}x}}y )Nconfig/settings.yamlr   rI   rJ   r   r   r   r   ro   r   r   r   r   r   r   rR   r   r   r   s              r!   test_whitelist_pattern_matchingz3TestComputeHotspots.test_whitelist_pattern_matching  s\   %&<>no zl;	()SA
 1 B B7IWa b+8}!!}!!!!}!!!!!!s!!!s!!!!!!8!!!8!!!}!!!!!!!!!!;$1$1$$$$1$$$$$$s$$$s$$$$$$;$$$;$$$$$$1$$$$$$$r+   c                    t        dg d      }t        dg d      }ddd}t        j                  ||z   | j                  |      \  }}|D ci c]  }|d   |j	                  d       }}t        d	 |D        d       }t        d
 |D        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}}
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}}
||   }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}||k(  }
|
slt        j                  d|
fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}
}y c c}w )Nr   r   r   r   r   r   r>   typec              3   P   K   | ]  }|d    j                  d      s|d       yw)r>   r   Nendswith.0hs     r!   	<genexpr>zGTestComputeHotspots.test_hotspot_type_classification.<locals>.<genexpr>-  s%     Qaqy7I7I%7P&	Q   &
&c              3   P   K   | ]  }|d    j                  d      s|d       yw)r>   z.yamlNr  r  s     r!   r	  zGTestComputeHotspots.test_hotspot_type_classification.<locals>.<genexpr>.  s%     U69K9KG9T!F)Ur
  r   r   py_filer
   r   r   	yaml_filerefactor_candidatero   r   r   r   r   config_hotspotrE   r   r   r   getnextrU   rV   rX   rY   rZ   rW   r\   r]   )r^   
records_pyrecords_yamlr   r   r   r  typesr  r  ra   r`   r   rf   rc   r}   r   r   s                     r!    test_hotspot_type_classificationz4TestComputeHotspots.test_hotspot_type_classification'  s   (7gh
*+ACst()SA
'88l9RTXTiTikuv!3;<a6AEE&M)<<Q8QSWXUXUW[\	""wd""""wd""""""w"""w"""d""""""" $$y$$$$y$$$$$$y$$$y$$$$$$$$$$W~5!55~!55555~!5555~555!55555555Y3#33#33333#3333333#33333333 =   Kc                    t        dg d      }t        dg d      }ddd}t        j                  ||z   | j                  |      \  }}|D ci c]  }|d   |j	                  d	       }}t        d
 |D        d       }t        d |D        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}}
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}}
||   }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}||k(  }
|
slt        j                  d|
fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}
}y c c}w )Nzsrc/high.py)r   r   r   r   ztask-5.1zsrc/medium.pyr   r   r   r   r>   priorityc              3   6   K   | ]  }d |d   v s|d     yw)zhigh.pyr>   Nr   r  s     r!   r	  zKTestComputeHotspots.test_hotspot_priority_classification.<locals>.<genexpr><  s     Pai9O!F)P   
c              3   6   K   | ]  }d |d   v s|d     yw)z	medium.pyr>   Nr   r  s     r!   r	  zKTestComputeHotspots.test_hotspot_priority_classification.<locals>.<genexpr>=  s     T!;!F);SAfITr  r   r   	high_filer
   r   r   medium_filehighro   r   r   r   r   mediumr  )r^   records_highrecords_mediumr   r   r   r  priority_mapr  r  ra   r`   r   rf   rc   r}   r   r   s                     r!   $test_hotspot_priority_classificationz8TestComputeHotspots.test_hotspot_priority_classification4  s   *=:vw,_>bc()SA
'88>)4+@+@*
! ?GG&	155#44GGPXPRVW	TxTVZ[ $$y$$$$y$$$$$$y$$$y$$$$$$$$$$"&&{$&&&&{$&&&&&&{&&&{&&&$&&&&&&&I&0&0&&0000&&000&000&0000000K(4H4(H4444(H444(444H4444444 Hr  c                    g d}t        d|      }ddd}t        j                  || j                  |      \  }}t	        |      }d}||k(  }|st        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z  }	dd|	iz  }
t        t        j                  |
            d x}x}}g }d}|d   }||v }|}|sd}|d   }||v }|}|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
|j                  |
       |s_t        j                  dfdf      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}}|d   j                  d      xs |d   j                  d      }|D ]  }||v }|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 )!Nr   r   r   r   r   rR   ro   r   r   r   r   r   r   r1   r   tasksrK   )z%(py3)s in %(py6)s)r   r   z%(py8)s)z%(py11)s in %(py14)s)rx   rQ   z%(py16)sr{   zassert %(py19)spy19)z%(py0)s in %(py2)srD   	task_list)r   r   zassert %(py4)sr   )rE   r   r   r   r   rU   rV   rX   rY   rZ   rW   r\   r]   rB   r[   r  )r^   r1   r   r   r   r   ra   r   rb   r   r   r`   rc   @py_assert10@py_assert13r~   ri   r   rk   @py_format20r(  rD   @py_format3r   s                           r!   test_hotspot_includes_task_listz3TestComputeHotspots.test_hotspot_includes_task_listC  s   C%lH=()SA
'88$BWBWYcd!8}!!}!!!!}!!!!!!s!!!s!!!!!!8!!!8!!!}!!!!!!!!!!BzBXa[Bz[(BGBx{BG{,BBBBz[BBBzBBB[BBBBBBBG{BBBGBBB{BBBBBBBBBBBBBBQKOOJ/K8A;??73K	 	$C)####3)######3###3######)###)#######	$r+   c                    t         j                  g | j                  | j                        \  }}g }||k(  }|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}}g }||k(  }|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 )Nro   r   r   r
   r   r   r   )r   r   r   r   rU   rV   rX   rY   rZ   rW   r\   r]   )r^   r   r   ra   r`   r   rf   s          r!   test_empty_recordsz&TestComputeHotspots.test_empty_recordsN  s     1 B B2tG\G\^b^v^v w+x2~x2xx2  {b    {b      {   {   b       r+   N)r   r   r   r   r   r   r   r   r   r   r   r  r$  r-  r/  r   r+   r!   r   r      sJ    -.#F!#4/"
"&"$%%45	$!r+   r   c                       e Zd Z eddd      Z eddd      Zddedededed	ef
d
Z	de
fdZde
fdZde
fdZde
fdZde
fdZde
fdZy)TestGenerateReportr   r   r      r0   
task_countr  total_tasksr   c           	      l    |||r||z  ndt        d|dz         D cg c]  }d| d
 c}d||dS c c}w )Nr   rR   r   r   r  )r>   r3  
task_ratior1   r  r  r4  )r   )r^   r0   r3  r  r4  rC   s         r!   _make_hotspotz TestGenerateReport._make_hotspot]  sN    $6A*{2q05aa0HI152I( &
 	
 Js   1
r   c                    | j                  d      g}t        j                  |g | j                  | j                  d|      }|j
                  } |       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        t        j                  |            d x}}y )Nr   r5   Aassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}output_pathr   r   r   )r7  r   generate_report_WEEK_START	_WEEK_ENDexistsrX   rY   rU   rZ   rW   r\   r]   )r^   r   r   r:  r`   r}   r   s          r!   test_report_createdz&TestGenerateReport.test_report_createdh  s    &&'GHI'77"dFVFVX\XfXfhjltu!!#!########{###{###!##########r+   c                 <   | j                  d      g}t        j                  |g | j                  | j                  d|      }|j                  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}}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 )Nr   r5   r   r   
2026-04-07rK   z%(py1)s in %(py3)sr(   r   r   r   r   z
2026-04-13r7  r   r<  r=  r>  	read_textrU   rV   rW   rX   rY   rZ   r\   r]   	r^   r   r   r:  r(   rc   ra   r   rf   s	            r!   test_report_contains_headerz.TestGenerateReport.test_report_contains_headerm  s   &&'GHI'77"dFVFVX\XfXfhjltu'''9&|w&&&&|w&&&|&&&&&&w&&&w&&&&&&&&|w&&&&|w&&&|&&&&&&w&&&w&&&&&&&r+   c                 b   t         j                  g g | j                  | j                  d|      }|j	                  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}}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}}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 )Nr   r   r   u   학습 기능 v1rK   rC  r(   rD  r   r   u   에러 유사도 미지원u	   v2 예정)r   r<  r=  r>  rF  rU   rV   rW   rX   rY   rZ   r\   r]   )r^   r   r:  r(   rc   ra   r   rf   s           r!   "test_report_contains_v1_limitationz5TestGenerateReport.test_report_contains_v1_limitationt  sO   '77B@P@PRVR`R`bcemn'''9!,!W,,,,!W,,,!,,,,,,W,,,W,,,,,,,+6+w6666+w666+666666w666w6666666%{g%%%%{g%%%{%%%%%%g%%%g%%%%%%%r+   c                    | j                  d      g}t        j                  |g | j                  | j                  d|      }|j                  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 )Nr   r5   r   r   z**status**: pendingrK   rC  r(   rD  r   r   rE  rG  s	            r!   #test_report_contains_hotspot_statusz6TestGenerateReport.test_report_contains_hotspot_status{  s    &&'GHI'77"dFVFVX\XfXfhjltu'''9$/$////$///$////////////////r+   c                    | j                  d      g}t        j                  |g | j                  | j                  d|      }|j                  d      }g }d}|j                  } |       }||v }	|	}
|	sd}||v }|}
|
st        j                  d|	fd||f      t        j                  |      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                  |      rt        j                  |      nd	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}}y )Nr   r5   r   r   summaryu   요약rK   )zD%(py3)s in %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s.lower
}()
}r(   )r   r   r   rw   z%(py11)srx   )z%(py14)s in %(py16)s)rQ   r{   z%(py18)spy18rR   zassert %(py21)spy21)r7  r   r<  r=  r>  rF  lowerrU   rV   rW   rX   rY   rZ   rB   r[   r\   r]   )r^   r   r   r:  r(   r`   ra   r   r   rb   rc   r*  @py_assert15r   r   r   @py_format19r+  @py_format22s                      r!   test_report_contains_summaryz/TestGenerateReport.test_report_contains_summary  s@   &&'GHI'77"dFVFVX\XfXfhjltu'''9ByBGMMBMOByO+BxBx7/BBBBByOBBByBBBBBBGBBBGBBBMBBBOBBBBBBBx7BBBxBBBBBB7BBB7BBBBBBBBBBBBBBBr+   c                 r   t         j                  g g | j                  | j                  d|      }|j                  }|j
                  }d} ||      }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            d x}x}x}}|j                  }|j                  }d} ||      }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            d x}x}x}}d}|j                  }	||	v }
|
st        j                  d	|
fd
||	f      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 )Nr   zweekly-zfassert %(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.name
}.startswith
}(%(py6)s)
}r:  )r   r   r   r   r   z.mdzdassert %(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.name
}.endswith
}(%(py6)s)
}2026rK   )z,%(py1)s in %(py5)s
{%(py5)s = %(py3)s.name
})r   r   r   r   r   )r   r<  r=  r>  name
startswithrX   rY   rU   rZ   rW   r\   r]   r  rV   )r^   r   r:  r`   r}   r   @py_assert7r   rc   rb   ra   rf   rg   s                r!   test_report_filename_formatz.TestGenerateReport.test_report_filename_format  s   '77B@P@PRVR`R`bcemn5**595*955555555{555{555555*55595555555555/((//(////////{///{//////(/////////////))))v)))))v))))v))))))))))))))))))))r+   N)r   r  r5   )r   r   r   r   r=  r>  strintru   r7  r   r@  rH  rJ  rL  rU  r[  r   r+   r!   r1  r1  Y  s    tQ"KT1b!I	
s 	
 	
3 	
fi 	
sw 	
$D $
'D '&4 &0D 0CT C*D *r+   r1  c                   L    e Zd Z eddd      Z eddd      ZdefdZdefdZy)	TestCLIr   r   r   r2  r   c                    t        dg d      t        ddg      z   }t        ||      }t        |      }t        |      }|dz  }|j	                          t
        j                  || j                  | j                        }t
        j                  |      }t
        j                  |      }	t
        j                  |||	      \  }
}t        |D ch c]  }|d   	 c}      }t
        j                  |
|| j                  | j                  ||      }|j                  } |       }|sddt        j                          v st#        j$                  |      rt#        j&                  |      ndt#        j&                  |      t#        j&                  |      d	z  }t)        t#        j*                  |            d x}}|j-                  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 c c}w )Nz
src/hot.pyr   zsrc/normal.pyr   reportsr?   r9  report_pathr;  r   r   zhot.pyrK   rC  r(   rD  r   r   )rE   r"   r*   r/   mkdirr   r   r=  r>  rT   r   r   r   r<  r?  rX   rY   rU   rZ   rW   r\   r]   rF  rV   )r^   r   r   r   r_   r   
output_dirparsedr   r   r   r   r   r4  rb  r`   r}   r   r(   rc   ra   r   rf   s                          r!   test_cli_with_sample_dataz!TestCLI.test_cli_with_sample_data  s   %J
*>? &h8
 *!(+	)
"44ZAQAQSWSaSab%44W=	&66w?
 1 B B69V` a+8A1Y<89'77k4#3#3T^^[R\
 !!#!########{###{###!##########'''9"x7""""x7"""x""""""7"""7""""""" 9s   I+c                    |dz  }t        |      }t        |      }|dz  }|j                          	 t        j	                  || j
                  | j                        }g }||k(  }|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}}t        j                  |      }t        j!                  |      }t        j#                  |||      \  }}t        j%                  ||| j
                  | j                  d	|      }|j&                  } |       }|sd
dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        t        j                  |            d x}}y # t(        $ r Y y t*        $ r"}t-        j.                  d|        Y d }~y d }~ww xY w)Nr   ra  ro   r   re  r
   r   r   r   r9  rb  r;  u7   audit-trail 없을 때 예상치 못한 예외 발생: )r*   r/   rc  r   r   r=  r>  rU   rV   rX   rY   rZ   rW   r\   r]   rT   r   r   r<  r?  
SystemExit	Exceptionr   fail)r^   r   r|   r_   r   rd  re  ra   r`   r   rf   r   r   r   r   rb  r}   r   es                      r!   test_cli_missing_audit_trailz$TestCLI.test_cli_missing_audit_trail  s   00 *!(+	)
	W&88$BRBRTXTbTbcF6R<6R66R)88AI*::7CJ$5$F$FvyZd$e!Hk+;;+t'7'7JK %%'%'''''''';''';'''%'''''''''' 	 	WKKQRSQTUVV	Ws   G)H 	I'I/IIN)	r   r   r   r   r=  r>  r   rf  rl  r   r+   r!   r_  r_    s8    tQ"KT1b!I#$ #,WT Wr+   r_  )NN)r   r   )rB  )8builtinsrX   _pytest.assertion.rewrite	assertionrewriterU   importlib.util	importlibr   sysdatetimer   pathlibr   r   __file__parent_SCRIPTS_DIRpathinsertr\  _MODULE_PATHutilspec_from_file_locationr	   ra   r`   rV   rY   rZ   rW   r   rf   r\   r]   module_from_specr   loaderrb   r}   rg   exec_modulelistru   r"   r*   r]  floatr/   rE   rG   r   r   r   r1  r_  r   r+   r!   <module>r     s0        
   H~$$++ 3|$ %44~~--.A<P t4   t4     t   t   4      NN33D9 {{ $ {$   {$     t   t   {  $         ) *t d4j T T $s)d*: TRUYY]M] im d C U ]a 3 $s) c ]abf]g *8 86> >4Z ZDo! o!n2* 2*t.W .Wr+   