
    +i=                     ^   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
Z
ddlmZmZ ddlmZ ddlZe	j                   j#                  d e ee      j(                  j(                               ddlZ G d d      Z G d d      Z G d	 d
      Z G d d      Z G d d      Z G d d      Zy)z=Tests for memory-janitor.py - TDD approach (RED phase first).    N)datetime	timedelta)Pathc                   P    e Zd ZdZdeddfdZdeddfdZdeddfdZdeddfdZy)	TestMemoryMdCheckz(Tests for MEMORY.md line count checking.tmp_pathreturnNc           	         |dz  }|j                  dj                  t        d      D cg c]  }d| 	 c}             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   }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   }t        |      }
||
k(  }|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                  |
      dz  }	dd|	iz  }t        t        j                  |            dx}x}}
yc c}w )u;   180줄짜리 MEMORY.md는 OK 상태를 반환해야 한다.	MEMORY.md
   line 
line_count==z%(py1)s == %(py4)spy1py4assert %(py6)spy6Nlimit   statusOKfile)z0%(py1)s == %(py6)s
{%(py6)s = %(py3)s(%(py4)s)
}str	memory_md)r   py3r   r   assert %(py8)spy8)
write_textjoinrangemjcheck_memory_md
@pytest_ar_call_reprcompare	_safereprAssertionError_format_explanationr   @py_builtinslocals_should_repr_global_name)selfr   r   iresult@py_assert0@py_assert3@py_assert2@py_format5@py_format7@py_assert5@py_format9s               8/home/jay/workspace/scripts/tests/test_memory_janitor.py test_check_memory_md_under_limitz2TestMemoryMdCheck.test_check_memory_md_under_limit   s   {*	TYYU3Z'H%s'HIJ##I.l#*s*#s****#s***#***s*******g%#%#%%%%#%%%%%%#%%%%%%%h'4'4''''4''''''4'''''''f~/Y/~////~///~///////////////Y///Y////////// (Is   K)c           	         |dz  }|j                  dj                  t        d      D cg c]  }d| 	 c}             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   }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c c}w )u@   201줄짜리 MEMORY.md는 WARNING 상태를 반환해야 한다.r   r      r   r   r   r   r   r   r   Nr   r   r   WARNING
r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   
r/   r   r   r0   r1   r2   r3   r4   r5   r6   s
             r9   test_check_memory_md_over_limitz1TestMemoryMdCheck.test_check_memory_md_over_limit!   s@   {*	TYYU3Z'H%s'HIJ##I.l#*s*#s****#s***#***s*******g%#%#%%%%#%%%%%%#%%%%%%%h,9,9,,,,9,,,,,,9,,,,,,, (Is   Gc           	         |dz  }|j                  dj                  t        d      D cg c]  }d| 	 c}             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   }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 )uB   정확히 200줄인 MEMORY.md는 OK 상태를 반환해야 한다.r   r   r   r   r   r   r   r   r   r   Nr   r   r>   r?   s
             r9   %test_check_memory_md_exactly_at_limitz7TestMemoryMdCheck.test_check_memory_md_exactly_at_limit,   s    {*	TYYU3Z'H%s'HIJ##I.l#*s*#s****#s***#***s*******h'4'4''''4''''''4''''''' (Is   Ec                 8   |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
   }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?   MEMORY.md가 없으면 NOT_FOUND 상태를 반환해야 한다.r   r   	NOT_FOUNDr   r   r   r   r   Nr   r   )r%   r&   r'   r(   r)   r*   r+   	r/   r   missingr1   r2   r3   r4   r5   r6   s	            r9   test_check_memory_md_not_foundz0TestMemoryMdCheck.test_check_memory_md_not_found6   s    [(##G,h.;.;....;......;.......l#(q(#q((((#q(((#(((q(((((((    )	__name__
__module____qualname____doc__r   r:   r@   rB   rG    rH   r9   r   r      sQ    2
0 
0$ 
0	- 	- 	-(d (t ()t ) )rH   r   c                   `    e Zd ZdZdeddfdZdeddfdZdeddfdZdeddfdZdeddfd	Z	y)
TestMemoryFilesReportz0Tests for memory/ directory file size reporting.r   r	   Nc                 X   |dz  }|j                          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
   }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   }i }||k(  }|slt        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|d   }g }||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>   빈 memory 디렉토리를 graceful하게 처리해야 한다.memorytotal_filesr   r   r   r   r   r   Ntotal_size_bytesby_directorylargest_files)mkdirr%   aggregate_memory_filesr'   r(   r)   r*   r+   )	r/   r   
memory_dirr1   r2   r3   r4   r5   r6   s	            r9   test_aggregate_empty_directoryz4TestMemoryFilesReport.test_aggregate_empty_directoryC   sq   (
**:6m$))$))))$)))$))))))))))().Q.)Q....)Q...)...Q.......n%++%++++%+++%++++++++++o&,",&",,,,&",,,&,,,",,,,,,,rH   c                 X   |dz  }|j                          |dz  }|j                  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   }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        |
      }d}||k(  }|st	        j
                  d|fd||f      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}}y)u9   단일 파일의 크기를 정확히 집계해야 한다.rQ   test.mdzhello worldrR      r   r   r   r   r   NrS      rU   z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)slenpy0py2r   py7assert %(py9)spy9)rV   r"   r%   rW   r'   r(   r)   r*   r+   r_   r,   r-   r.   )r/   r   rX   fr1   r2   r3   r4   r5   r6   @py_assert1@py_assert6r7   @py_format8@py_format10s                  r9   test_aggregate_single_filez0TestMemoryFilesReport.test_aggregate_single_fileO   sk   (
"	]#**:6m$))$))))$)))$))))))))))()/R/)R////)R///)///R////////*0s*+0q0+q0000+q000000s000s000*000+000q0000000rH   c                    |dz  }|dz  }|dz  }|j                  d       |j                  d       |dz  j                  d       |dz  j                  d	       |d
z  j                  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   }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 |D        }t        |      }|sddt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }	t        t	        j                  |	            dx}}d |D        }t        |      }|sddt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }	t        t	        j                  |	            dx}}t        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}}y)!uO   여러 하위 디렉토리의 크기를 디렉토리별로 집계해야 한다.rQ   reportswhisperT)parentsz
report1.mddAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAz
report2.mdBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBznote.md2CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCrR      r   r   r   r   r   NrS   i^  rT   c              3   $   K   | ]  }d |v  
 ywrm   NrM   .0ks     r9   	<genexpr>zLTestMemoryFilesReport.test_aggregate_multiple_directories.<locals>.<genexpr>o        0a9>0   ,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyra   rb   r   c              3   $   K   | ]  }d |v  
 yw)rn   NrM   rv   s     r9   ry   zLTestMemoryFilesReport.test_aggregate_multiple_directories.<locals>.<genexpr>p   rz   r{   c              3   *   K   | ]  }d |v s|  ywru   rM   rv   s     r9   ry   zLTestMemoryFilesReport.test_aggregate_multiple_directories.<locals>.<genexpr>r   s     =i1n1=s   	files   
size_bytesi,  )rV   r"   r%   rW   r'   r(   r)   r*   r+   r}   r,   r-   r.   next)r/   r   rX   reports_dirwhisper_dirr1   r2   r3   r4   r5   r6   dirsrg   reports_keys                 r9   #test_aggregate_multiple_directoriesz9TestMemoryFilesReport.test_aggregate_multiple_directories\   s   (
 9, 9,$'$'	|	#//	:	|	#//	:	y	 ,,X6**:6m$))$))))$)))$))))))))))()0S0)S0000)S000)000S0000000 n%0400s000000000s000s000000000000000400s000000000s000s00000000000000=d==K ).Q.)Q....)Q...)...Q.......K .5#5.#5555.#555.555#5555555rH   c                 l   |dz  }|j                          t        d      D ]$  }|d|ddz  j                  d|dz   z  dz         & t        j                  |      }|d	   }t        |      }d}||k(  }|st        j                  d
|fd||f      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}}|d	   D cg c]  }|d   	 }}d}t        ||      }||k(  }|s7t        j                  d
|fd||f      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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c c}w )u+   상위 10개 파일만 반환해야 한다.rQ      r   02dz.mdXr\   
   rU   r   r^   r_   r`   rd   re   Nr   T)reverse)zA%(py0)s == %(py7)s
{%(py7)s = %(py2)s(%(py3)s, reverse=%(py5)s)
}sizessorted)ra   rb   r   py5rc   )rV   r$   r"   r%   rW   r_   r'   r(   r,   r-   r.   r)   r*   r+   r   )r/   r   rX   r0   r1   rg   r3   rh   r7   ri   rj   rf   r   @py_assert4s                 r9   test_largest_files_top_10z/TestMemoryFilesReport.test_largest_files_top_10v   s   (
r 	LAD3s++77q1u8JK	L **:6/*1s*+1r1+r1111+r111111s111s111*111+111r1111111*0*ABQ<BB.23ud33u33333u3333333u333u333333333333333u333u333d33333333333 Cs   J1c                 8   |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
   }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	)uG   존재하지 않는 디렉토리도 graceful하게 처리해야 한다.rQ   rR   r   r   r   r   r   r   NrS   )r%   rW   r'   r(   r)   r*   r+   rE   s	            r9   $test_aggregate_nonexistent_directoryz:TestMemoryFilesReport.test_aggregate_nonexistent_directory   s    X%**73m$))$))))$)))$))))))))))().Q.)Q....)Q...)...Q.......rH   )
rI   rJ   rK   rL   r   rY   rk   r   r   r   rM   rH   r9   rO   rO   @   sd    :
-t 
- 
-14 1D 16D 6T 644$ 44 4/T /d /rH   rO   c                   p    e Zd ZdZdeddfdZdeddfdZdeddfdZdeddfdZdeddfd	Z	deddfd
Z
y)TestStaleFilesDetectionz3Tests for detecting files not accessed in 30+ days.r   r	   Nc                    |dz  }|j                          |dz  }|j                  d       t        j                  |d      }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)u?   최근에 수정된 파일은 stale 목록에 없어야 한다.rQ   	recent.mdzrecent content   daysr   z%(py0)s == %(py3)sr1   ra   r   assert %(py5)sr   N)rV   r"   r%   detect_stale_filesr'   r(   r,   r-   r.   r)   r*   r+   )	r/   r   rX   rf   r1   r4   rg   @py_format4@py_format6s	            r9   test_no_stale_files_recentz2TestStaleFilesDetection.test_no_stale_files_recent   s    (
$	%& &&z;v|vvvrH   c                    |dz  }|j                          |dz  }|j                  d       t        j                         dz
  }t        j                  |||f       t        j                  |d      }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}}|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)uH   31일 이상 수정되지 않은 파일은 stale로 감지해야 한다.rQ   zold-note.mdzold contenti( r   r   r\   r   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr_   r1   ra   r   r   r   r    r!   Nr   pathinz%(py1)s in %(py4)sr   r   r   
days_stale   >=)z%(py1)s >= %(py4)srV   r"   timeosutimer%   r   r_   r'   r(   r,   r-   r.   r)   r*   r+   )r/   r   rX   old_fileold_timer1   r4   r7   r   r6   r8   r2   r3   r5   s                 r9   test_detects_old_filesz.TestStaleFilesDetection.test_detects_old_files   s   (
-M* 99;.1
Hh/0&&z;6{a{a{ass66{a1q	& 11} 11111} 1111}111 11111111ay&,",&",,,,&",,,&,,,",,,,,,,rH   c                 2   |dz  }|j                          |dz  }|j                  d       t        j                         dz
  }t        j                  |||f       t        j                  |d      }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)uI   정확히 30일 된 파일은 stale이 아니다 (30일 초과만 stale).rQ   z	border.mdzborder contenti ' r   r   r   r   r1   r   r   r   N)rV   r"   r   r   r   r%   r   r'   r(   r,   r-   r.   r)   r*   r+   )
r/   r   rX   border_fileborder_timer1   r4   rg   r   r   s
             r9   test_exactly_30_days_not_stalez6TestStaleFilesDetection.test_exactly_30_days_not_stale   s    (
 ;./0 iik^4
{K89&&z;v|vvvrH   c                 6   |dz  }|j                          |dz  }|j                  d       |dz  }|j                  d       t        j                         dz
  }t        j                  |||f       t        j                  |d      }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)u[   최근 파일과 오래된 파일이 섞여있을 때 오래된 것만 반환해야 한다.rQ   r   recentzstale.mdstalei O r   r   r\   r   r   r_   r1   r   r    r!   Nr   r   r   r   r   r   r   r   )r/   r   rX   r   oldr   r1   r4   r7   r   r6   r8   r2   r3   r5   s                  r9   test_mixed_filesz(TestStaleFilesDetection.test_mixed_files   sa   (
 k)(# :%w99;.1
x*+&&z;6{a{a{ass66{a.VAYv..z.....z....z...........rH   c                 >   |dz  }|j                          |dz  }|j                  d       t        j                         dz
  }t        j                  |||f       t        j                  |d      }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!        j"                  |d   d   d       y)u:   last_modified 필드가 YYYY-MM-DD 형식이어야 한다.rQ   zold.mdxi 4 r   r   r\   r   r   r_   r1   r   r    r!   Nr   last_modifiedz%Y-%m-%d)rV   r"   r   r   r   r%   r   r_   r'   r(   r,   r-   r.   r)   r*   r+   r   strptime)r/   r   rX   r   r   r1   r4   r7   r   r6   r8   s              r9   test_last_modified_formatz1TestStaleFilesDetection.test_last_modified_format   s   (
8#s99;.1
x*+&&z;6{a{a{ass66{a&)O4jArH   c                    |dz  }|j                          t        j                  |d      }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
)uP   빈 디렉토리에서 stale 파일 감지는 빈 목록을 반환해야 한다.rQ   r   r   r   r   r1   r   r   r   N)rV   r%   r   r'   r(   r,   r-   r.   r)   r*   r+   )r/   r   rX   r1   r4   rg   r   r   s           r9   test_stale_empty_directoryz2TestStaleFilesDetection.test_stale_empty_directory   s    (
&&z;v|vvvrH   )rI   rJ   rK   rL   r   r   r   r   r   r   r   rM   rH   r9   r   r      sz    =
4 
D 
-t - -"t  / /$ /(B$ B4 B4 D rH   r   c                   `    e Zd ZdZdeddfdZdeddfdZdeddfdZdeddfdZdeddfd	Z	y)
TestDuplicateDetectionz/Tests for detecting duplicate or similar files.r   r	   Nc                    |dz  }|j                          |dz  j                  d       |dz  j                  d       t        j                  |g      }|D cg c]  }|d   dk(  s| }}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 |D        }t        |      }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}d |D        }t        |      }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}yc c}w )uO   하이픈/언더스코어 차이로 유사한 파일명을 감지해야 한다.scriptshealth_score.pyversion1health-score.pyversion2reasonsimilar_namer\   r   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)sr_   similarr   r    r!   Nr   r   c              3   $   K   | ]  }d |v  
 yw)r   NrM   rw   rf   s     r9   ry   zKTestDuplicateDetection.test_hyphen_underscore_similarity.<locals>.<genexpr>        9a$)9r{   r|   r}   r~   c              3   $   K   | ]  }d |v  
 yw)r   NrM   r   s     r9   ry   zKTestDuplicateDetection.test_hyphen_underscore_similarity.<locals>.<genexpr>   r   r{   )rV   r"   r%   detect_duplicatesr_   r'   r(   r,   r-   r.   r)   r*   r+   r}   )r/   r   scripts_dirr1   dr   r4   r7   r   r6   r8   r   rg   r3   r5   s                  r9   !test_hyphen_underscore_similarityz8TestDuplicateDetection.test_hyphen_underscore_similarity   s   *	(	(44Z@	(	(44Z@%%{m4$F(~(E1FF7| q |q    |q      s   s      7   7   |   q       
7#9599s999999999s999s999999999999999599s999999999s999s99999999999999	 Gs   K#&K#c                    |dz  }|j                          |dz  j                  d       |dz  j                  d       t        j                  |g      }|D cg c]  }|d   dk(  s| }}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c c}w )uJ   같은 디렉토리 내 동일한 크기의 파일을 감지해야 한다.r   z	file_a.pyzexactly tenz	file_b.pyr   	same_sizer\   r   r   r_   	size_dupsr   r    r!   NrV   r"   r%   r   r_   r'   r(   r,   r-   r.   r)   r*   r+   )r/   r   r   r1   r   r   r4   r7   r   r6   r8   s              r9   test_same_size_same_directoryz4TestDuplicateDetection.test_same_size_same_directory   s    *	{	"..}=	{	"..}=%%{m4 &E1!H+*DQE	E9~""~""""~""""""s"""s""""""9"""9"""~"""""""""" Fs   E=&E=c                    |dz  }|j                          |dz  j                  d       |dz  j                  d       t        j                  |g      }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)u7   중복이 없을 때 빈 목록을 반환해야 한다.r   zunique_a.pyz	content azunique_b.pyzdifferent content herer   r   r1   r   r   r   N)rV   r"   r%   r   r'   r(   r,   r-   r.   r)   r*   r+   )r/   r   r   r1   r4   rg   r   r   s           r9   test_no_duplicatesz)TestDuplicateDetection.test_no_duplicates	  s    *	}	$00=	}	$001IJ%%{m4 v|vvvrH   c                 0   |dz  }|dz  }|j                          |j                          |dz  j                  d       |dz  j                  d       t        j                  ||g      }|D cg c]  }|d   dk(  s| }}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c c}w )uM   다른 디렉토리에 있는 유사한 이름 파일도 감지해야 한다.dir_adir_bzreport_gen.pyazreport-gen.pybr   r   r\   r   r   r_   r   r   r    r!   Nr   )r/   r   r   r   r1   r   r   r4   r7   r   r6   r8   s               r9    test_similar_name_different_dirsz7TestDuplicateDetection.test_similar_name_different_dirs  s   7"7"		 ,,S1		 ,,S1%%uen5$F(~(E1FF7| q |q    |q      s   s      7   7   |   q        Gs   .F<Fc                 z   t        j                  g       }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)u>   빈 디렉토리 목록도 graceful하게 처리해야 한다.r   r   r1   r   r   r   N)
r%   r   r'   r(   r,   r-   r.   r)   r*   r+   )r/   r   r1   r4   rg   r   r   s          r9   test_empty_directoriesz-TestDuplicateDetection.test_empty_directories#  sj    %%b)v|vvvrH   )
rI   rJ   rK   rL   r   r   r   r   r   r   rM   rH   r9   r   r      sd    9:$ :4 :
#d 
#t 
#
4 
D 
! !$ !t  rH   r   c                   8    e Zd ZdZddZddZddZddZddZy)	TestRecommendationsz$Tests for recommendation generation.Nc                    ddddd}g }g }t        j                  |||      }d |D        }t        |      }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      d	z  }t        t        j                  |            d
x}}y
)uH   MEMORY.md가 제한 이내이면 OK 권고사항을 생성해야 한다.r   r   r   r   r   r   r   r   c              3   0   K   | ]  }d |v xr d|v   yw)180200NrM   rw   rs     r9   ry   zGTestRecommendations.test_recommendation_memory_md_ok.<locals>.<genexpr>9  s      ;5A:,%1*,;   r|   r}   r~   N
r%   generate_recommendationsr}   r,   r-   r'   r.   r)   r*   r+   r/   memory_md_checkstale_files
duplicatesrecsrg   r3   r5   s           r9    test_recommendation_memory_md_okz4TestRecommendations.test_recommendation_memory_md_ok,  s      	
 
**?KT;d;;s;;;;;;;;;s;;;s;;;;;;;;;;;;;;rH   c                    ddddd}g }g }t        j                  |||      }d |D        }t        |      }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      d	z  }t        t        j                  |            d
x}}y
)uM   MEMORY.md가 제한 초과이면 WARNING 권고사항을 생성해야 한다.r      r   r=   r   c              3   <   K   | ]  }d |v xs
 d|v xs d|v   yw)u   초과r=   u   정리NrM   r   s     r9   ry   zLTestRecommendations.test_recommendation_memory_md_warning.<locals>.<genexpr>H  s)     R8q=CINCh!mCRs   r|   r}   r~   Nr   r   s           r9   %test_recommendation_memory_md_warningz9TestRecommendations.test_recommendation_memory_md_warning;  s      	
 
**?KTRTRRsRRRRRRRRRsRRRsRRRRRRRRRRRRRRrH   c                    ddddd}dddd	d
ddd	g}g }t        j                  |||      }d |D        }t        |      }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}y)uK   stale 파일이 있으면 아카이브 권고사항을 생성해야 한다.r   2   r    r   r   r   r   zold1.mdz
2026-01-01I   )r   r   r   zold2.md-   c              3   0   K   | ]  }d |v xr d|v   yw)2u   아카이브NrM   r   s     r9   ry   zFTestRecommendations.test_recommendation_stale_files.<locals>.<genexpr>U  s!     B3!83! 33Br   r|   r}   r~   Nr   r   s           r9   test_recommendation_stale_filesz3TestRecommendations.test_recommendation_stale_filesJ  s    %)cSUVRPRP
 
**?KTBTBBsBBBBBBBBBsBBBsBBBBBBBBBBBBBBrH   c                    ddddd}g }ddgdd	g}t        j                  |||      }d
 |D        }t        |      }|sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}y)uP   중복 파일이 있으면 해당 파일명 권고사항을 생성해야 한다.r   r  r   r  r  zscripts/health_score.pyzscripts/health-score.pyr   )r   r   c              3   0   K   | ]  }d |v xs d|v   yw)health_scorezhealth-scoreNrM   r   s     r9   ry   zETestRecommendations.test_recommendation_duplicates.<locals>.<genexpr>d  s"     L!>Q&=.A*==Lr   r|   r}   r~   Nr   r   s           r9   test_recommendation_duplicatesz2TestRecommendations.test_recommendation_duplicatesW  s    %)cSUV 45NO(

 **?KTLtLLsLLLLLLLLLsLLLsLLLLLLLLLLLLLLrH   c                 h   ddddd}g }g }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)uM   문제가 없을 때도 최소한 하나의 권고사항이 있어야 한다.r   r  r   r  r  r\   r   r   r_   r   r   r    r!   N)r%   r   r_   r'   r(   r,   r-   r.   r)   r*   r+   )
r/   r   r   r   r   r4   r7   r   r6   r8   s
             r9   test_recommendation_no_issuesz1TestRecommendations.test_recommendation_no_issuesf  s    %)cSUV
**?KT4yAyA~yAss44yArH   )r	   N)	rI   rJ   rK   rL   r   r   r  r  r  rM   rH   r9   r   r   )  s!    .<SCMrH   r   c                   @    e Zd ZdZdeddfdZdeddfdZdeddfdZy)TestFullReportz1Integration tests for the full report generation.r   r	   Nc           	         |dz  }|j                          |dz  j                  dj                  t        d      D cg c]  }d| 	 c}             |dz  j                  d       t	        j
                  ||dz  |g      }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}}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}}t        j                  |d	          yc c}w )uA   전체 리포트가 올바른 JSON 스키마를 갖춰야 한다.rQ   r   r   r  r   r[   ztest contentrX   memory_md_path	scan_dirs	timestampr   z%(py1)s in %(py3)sr1   r   r   r   r   Nmemory_filesr   r   r   recommendations)rV   r"   r#   r$   r%   generate_reportr'   r(   r)   r,   r-   r.   r*   r+   r   fromisoformat)	r/   r   rX   r0   r1   r2   r4   r   r   s	            r9   test_full_report_structurez)TestFullReport.test_full_report_structuret  s    (
	k	!--diieTVi8X58X.YZ	i	++N;##!%3!l
 ${f$$$${f$$${$$$$$$f$$$f$$$$$$$'~''''~'''~'''''''''''''''' * F**** F*** ******F***F*******&}&&&&}&&&}&&&&&&&&&&&&&&&&%|v%%%%|v%%%|%%%%%%v%%%v%%%%%%% * F**** F*** ******F***F******* 	vk23% 9Ys   Q:c                    |dz  }|j                          t        j                  ||dz  |g      }t        j                  |      }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}y)u7   전체 리포트가 JSON 직렬화 가능해야 한다.rQ   r   r  N)is not)z%(py0)s is not %(py3)sjson_strr   r   r   )rV   r%   r  jsondumpsr'   r(   r,   r-   r.   r)   r*   r+   )	r/   r   rX   r1   r  r4   rg   r   r   s	            r9   "test_full_report_json_serializablez1TestFullReport.test_full_report_json_serializable  s    (
##!#k1!l
 ::f%##xt####xt######x###x###t#######rH   c           	         |dz  }|j                          |dz  }|j                  dj                  t        d      D cg c]  }d| 	 c}             t	        j
                  ||g       }|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}}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 )u<   memory_md_check 섹션에 필수 필드가 있어야 한다.rQ   r   r   d   r   r  r   r   r   r  checkr  r   r   Nr   r   r   )rV   r"   r#   r$   r%   r  r'   r(   r)   r,   r-   r.   r*   r+   )r/   r   rX   r   r0   r1   r%  r2   r4   r   r   s              r9   'test_full_report_memory_md_check_fieldsz6TestFullReport.test_full_report_memory_md_check_fields  s   (
{*	TYYU3Z'H%s'HIJ##!$
 ()vvv$|u$$$$|u$$$|$$$$$$u$$$u$$$$$$$w%w%w%% x5    x5   x      5   5        (Is   L)rI   rJ   rK   rL   r   r  r"  r&  rM   rH   r9   r  r  q  s>    ;44 4D 42$4 $D $! ! !rH   r  )rL   builtinsr,   _pytest.assertion.rewrite	assertionrewriter'   r   r   sysr   r   r   pathlibr   pytestr   insertr   __file__parentmemory_janitorr%   r   rO   r   r   r   r  rM   rH   r9   <module>r2     s    C    	 
  (   3tH~,,334 5 +) +)\L/ L/^Y Yx; ;|E EP<! <!rH   