
    [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
mZ ddlZddlmZ ej                  d        Zdedefd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 G d d      Zy)u%   utils.feature_flags 단위 테스트.    N)PathFeatureFlagLoaderc           	          | dz  }dddddddddd}|j                  t        j                  |dd      d	
       t        |      S )uJ   기본 6개 플래그가 모두 False인 임시 feature_flags.json 반환.zfeature_flags.jsonz1.02026-04-04T00:00:00+09:00Fprogressive_disclosure_enabledrw_isolation_enabledhooks_enforcement_enabledtrust5_tagging_enabledmodel_map_enabledhaiku_ab_enabled)schema_version
updated_atflags   )indentensure_asciiutf-8encoding)
write_textjsondumpsstr)tmp_path
flags_filedatas      //home/jay/workspace/tests/test_feature_flags.pytmp_flags_filer       s`     00J1.3$)).&+!& %
D $**T!%HSZ[z?    pathreturnc                     t        |       S )u>   절대 경로를 받아 FeatureFlagLoader 인스턴스 생성.r"   r   r%   s    r   make_loaderr&   %   s    $''r!   c                       e Zd Zd Zd Zy)TestBasicLoadingc           	         t        |      }g d}|D ]C  }|j                  } ||      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }	t        j                  | d      d	z   d
|	iz  }
t        t        j                  |
            d x}x}x}}F y )Nr   Fis)zP%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.is_enabled
}(%(py3)s)
} is %(py8)sloaderflag)py0py2py3py5py8z should be Falsez
>assert %(py10)spy10)r&   
is_enabled
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanation)selfr    r,   expected_flagsr-   @py_assert1@py_assert4@py_assert7@py_assert6@py_format9@py_format11s              r   test_all_six_flags_are_falsez-TestBasicLoading.test_all_six_flags_are_false0   s    ^,
 # 	OD$$N$T*NeN*e3NNN*eNNNNNN6NNN6NNN$NNNNNNTNNNTNNN*NNNeNNNv=M5NNNNNNNN	Or!   c                    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	 |j                         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 )N   ==)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slen	all_flags)r.   py1r0   py6zassert %(py8)sr2   c              3   $   K   | ]  }|d u  
 yw)FN ).0vs     r   	<genexpr>zJTestBasicLoading.test_get_all_flags_returns_six_entries.<locals>.<genexpr>A   s     :!1::s   z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}all)r.   r/   py4)r&   get_all_flagsrK   r5   r6   r7   r8   r9   r:   r<   r=   valuesrT   )r>   r    r,   rL   @py_assert2@py_assert5rA   @py_format7rD   r@   @py_assert3@py_format5s               r   &test_get_all_flags_returns_six_entriesz7TestBasicLoading.test_get_all_flags_returns_six_entries=   s   ^,((*	9~""~""""~""""""s"""s""""""9"""9"""~"""""""""":y'7'7'9::s:::::::::s:::s::::::::::::::r!   N)__name__
__module____qualname__rF   r]   rP   r!   r   r(   r(   /   s    O;r!   r(   c                       e Zd Zd Zd Zy)TestMtimeCachec                   	
 t        |      }ddi	|j                  
	
fd}||_        |j                          |j                          |j                          	d   }d}||k(  }|st        j                  d|fd||f      t        j
                  |      t        j
                  |      dz  }t        j                  d      dz   d	|iz  }t        t        j                  |            d x}x}}y )
Ncountr   c                  .     dxx   dz  cc<            y )Nrd      rP   )load_call_countoriginal_loads   r   counting_loadzITestMtimeCache.test_no_reload_when_mtime_unchanged.<locals>.counting_loadP   s    G$)$Or!   rI   )z%(py1)s == %(py4)srM   rU   u1   mtime 미변경 시 _load가 호출되면 안 됨z
>assert %(py6)srN   )	r&   _loadreloadr5   r6   r:   r;   r<   r=   )r>   r    r,   ri   @py_assert0r[   rX   r\   rZ   rg   rh   s            @@r   #test_no_reload_when_mtime_unchangedz2TestMtimeCache.test_no_reload_when_mtime_unchangedJ   s    ^,"A,	 % 	w'a1a'1,aaa'1aaa'aaa1aaa.aaaaaaaar!   c                 ,   t        |      }t        j                  d       t        j                  t        |      j                  d            }d|d   d<   t        |      j                  t        j                  |d      d       |j                          |j                  }d} ||      }d}||u }|st        j                  d	|fd
||f      dt        j                         v st        j                  |      rt        j                   |      ndt        j                   |      t        j                   |      t        j                   |      t        j                   |      dz  }	dd|	iz  }
t#        t        j$                  |
            d x}x}x}x}}y )N{Gz?r   r   Tr   r	   r   )r   r*   zP%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.is_enabled
}(%(py4)s)
} is %(py9)sr,   r.   r/   rU   rN   py9assert %(py11)spy11)r&   timesleepr   loadsr   	read_textr   r   rl   r4   r5   r6   r7   r8   r9   r:   r<   r=   )r>   r    r,   r   r@   r[   rY   @py_assert8rB   @py_format10@py_format12s              r   (test_reload_triggered_when_mtime_changesz7TestMtimeCache.test_reload_triggered_when_mtime_changes]   s   ^, 	

4zz$~.88'8JK:>W67^''

4(BW'U 	  J!AJ !ABJdJBdJJJJBdJJJJJJvJJJvJJJ JJJ!AJJJBJJJdJJJJJJJJr!   N)r^   r_   r`   rn   r}   rP   r!   r   rb   rb   I   s    b&Kr!   rb   c                   $    e Zd Zd Zd Zd Zd Zy)TestAtomicWritec                    t        |      }|j                  dd       t        j                  t	        |      j                  d            }|d   d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            d x}x}}y )Nr
   Tr   r   r   r*   )z%(py1)s is %(py4)srj   assert %(py6)srN   )r&   set_flagr   rx   r   ry   r5   r6   r:   r<   r=   )	r>   r    r,   on_diskrm   r[   rX   r\   rZ   s	            r   test_set_flag_persists_to_filez.TestAtomicWrite.test_set_flag_persists_to_fileq   s    ^,.5 **T.1;;W;MNw 67?4?74????74???7???4???????r!   c                 8   t        |      }|j                  dd       |j                  }d} ||      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}x}x}}y )	Nr   Tr*   rq   r,   rr   rt   ru   )r&   r   r4   r5   r6   r7   r8   r9   r:   r<   r=   
r>   r    r,   r@   r[   rY   rz   rB   r{   r|   s
             r   test_set_flag_updates_in_memoryz/TestAtomicWrite.test_set_flag_updates_in_memoryy   s    ^,3T:  E!<E !<=EE=EEEE=EEEEEEvEEEvEEE EEE!<EEE=EEEEEEEEEEEr!   c                    t        |      }|j                  dd       t        j                  t	        |      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   }d}||k7  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}y )Nr   Tr   r   r   )in)z%(py1)s in %(py3)sr   )rM   r0   assert %(py5)sr1   r   )!=)z%(py1)s != %(py4)srj   r   rN   )r&   r   r   rx   r   ry   r5   r6   r:   r7   r8   r9   r<   r=   )r>   r    r,   r   rm   rX   @py_format4@py_format6r[   r\   rZ   s              r    test_set_flag_updates_updated_atz0TestAtomicWrite.test_set_flag_updates_updated_at~   s    ^,+T2**T.1;;W;MN&|w&&&&|w&&&|&&&&&&w&&&w&&&&&&&|$C(CC$(CCCCC$(CCCC$CCC(CCCCCCCCr!   c                 l   t        |      }t        j                  j                  |      }|j	                  dd       t        j
                  |      D cg c]  }|j                  d      s| }}g }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       d	z   d
|iz  }	t        t        j                  |	            d x}}y c c}w )Nr   Tz.tmprI   )z%(py0)s == %(py3)s	tmp_filesr.   r0   u   .tmp 파일이 남아있음: z
>assert %(py5)sr1   )r&   osr"   dirnamer   listdirendswithr5   r6   r7   r8   r9   r:   r;   r<   r=   )
r>   r    r,   dir_pathfr   rX   r@   r   r   s
             r   test_set_flag_no_tmp_files_leftz/TestAtomicWrite.test_set_flag_no_tmp_files_left   s    ^,77??>2*D1 "

8 4K1

68JQK	KKyBKKKyBKKKKKKyKKKyKKKBKKK"?	{ KKKKKKK Ls   D1+D1N)r^   r_   r`   r   r   r   r   rP   r!   r   r   r   p   s    @F
DLr!   r   c                       e Zd Zd Zy)TestJSONDecodeErrorRecoveryc                    t        |      }|j                  dd       |j                  }d} ||      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}x}x}}t        j                  d	       t        |      j                  d
d       |j                          |j                  }d} ||      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }t        j                   d      dz   d|iz  }	t        t        j                  |	            d x}x}x}x}}y )Nr   Tr*   rq   r,   rr   rt   ru   rp   z{ invalid json !!!r   r   u5   JSONDecodeError 후 이전 캐시를 유지해야 함z
>assert %(py11)s)r&   r   r4   r5   r6   r7   r8   r9   r:   r<   r=   rv   rw   r   r   rl   r;   r   s
             r   &test_invalid_json_keeps_previous_cachezBTestJSONDecodeErrorRecovery.test_invalid_json_keeps_previous_cache   s   ^,0$7  B!9B !9:BdB:dBBBB:dBBBBBBvBBBvBBB BBB!9BBB:BBBdBBBBBBB 	

4^''(<w'O 	  {!9{ !9:{d{:dB{{{:d{{{{{{v{{{v{{{ {{{!9{{{:{{{d{{{D{{{{{{{{r!   N)r^   r_   r`   r   rP   r!   r   r   r      s    |r!   r   c                       e Zd Zd Zd Zy)TestUnknownFlagc                    t        |      }|j                  d      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y )	Nnonexistent_flag_xyzFr*   z%(py0)s is %(py3)sresultr   r   r1   )
r&   r4   r5   r6   r7   r8   r9   r:   r<   r=   )r>   r    r,   r   rX   r@   r   r   s           r   test_unknown_flag_returns_falsez/TestUnknownFlag.test_unknown_flag_returns_false   su    ^,""#9:vvvvr!   c                    t        |      }	 |j                  d      }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y # t        $ r"}t        j                  d	|        Y d }~y d }~ww xY w)
Ntotally_made_up_flagFr*   r   r   r   r   r1   u8   존재하지 않는 플래그 조회 시 예외 발생: )r&   r4   r5   r6   r7   r8   r9   r:   r<   r=   	Exceptionpytestfail)	r>   r    r,   r   rX   r@   r   r   es	            r    test_unknown_flag_does_not_raisez0TestUnknownFlag.test_unknown_flag_does_not_raise   s    ^,	X&&'=>F""6U?"""6U""""""6"""6"""U""""""" 	XKKRSTRUVWW	Xs   B6C 	C/C**C/N)r^   r_   r`   r   r   rP   r!   r   r   r      s    
Xr!   r   c                       e Zd Zd Zd Zy)TestFileNotFoundHandlingc                 0   t        |dz        }t        |      }|j                  }d} ||      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }	dd	|	iz  }
t        t        j                  |
            d x}x}x}x}}y )
Ndoes_not_exist.jsonr	   Fr*   rq   r,   rr   rt   ru   )r   r&   r4   r5   r6   r7   r8   r9   r:   r<   r=   )r>   r   non_existentr,   r@   r[   rY   rz   rB   r{   r|   s              r   ,test_missing_file_returns_false_for_any_flagzETestFileNotFoundHandling.test_missing_file_returns_false_for_any_flag   s    8&;;<\*  K!AK !ABKeKBeKKKKBeKKKKKKvKKKvKKK KKK!AKKKBKKKeKKKKKKKKr!   c                     t        |dz        }t        |      }|j                  } |       }i }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            d x}x}x}}y )Nr   rI   )zL%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.get_all_flags
}()
} == %(py7)sr,   )r.   r/   rU   py7zassert %(py9)srs   )r   r&   rV   r5   r6   r7   r8   r9   r:   r<   r=   )
r>   r   r   r,   r@   r[   rC   rY   @py_format8r{   s
             r   -test_missing_file_get_all_flags_returns_emptyzFTestFileNotFoundHandling.test_missing_file_get_all_flags_returns_empty   s    8&;;<\*##+#%++%++++%++++++v+++v+++#+++%++++++++++r!   N)r^   r_   r`   r   r   rP   r!   r   r   r      s    L
,r!   r   c                       e Zd Zd Zy)TestRealWorkspaceFilec                    d}t         j                  j                  |      st        j                  d       t        |      }|j                  }d} ||      }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }	t        t        j                  |	            dx}x}x}x}}y)u0   실제 .claude/feature_flags.json 기준 검증.z./home/jay/workspace/.claude/feature_flags.jsonu*   실제 feature_flags.json 파일이 없음r	   Tr*   rq   r,   rr   rt   ru   N)r   r"   existsr   skipr&   r4   r5   r6   r7   r8   r9   r:   r<   r=   )
r>   	real_pathr,   r@   r[   rY   rz   rB   r{   r|   s
             r   1test_progressive_disclosure_is_false_in_real_filezGTestRealWorkspaceFile.test_progressive_disclosure_is_false_in_real_file   s    D	ww~~i(KKDEY'  J!AJ !ABJdJBdJJJJBdJJJJJJvJJJvJJJ JJJ!AJJJBJJJdJJJJJJJJr!   N)r^   r_   r`   r   rP   r!   r   r   r      s    Kr!   r   )__doc__builtinsr7   _pytest.assertion.rewrite	assertionrewriter5   r   r   rv   pathlibr   r   utils.feature_flagsr   fixturer    r   r&   r(   rb   r   r   r   r   r   rP   r!   r   <module>r      s    +    	    1  &(c (/ (; ;4K KNL LJ| |*X X*	, 	,"K Kr!   