§
    V¿jE  ã                  óX  — d Z ddlmZ ddlZddlZddlZddlZddlZej         	                    ej         
                    ej                             e¦  «        dd¦  «        ¦  «        Zej         
                    eddd¦  «        Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS )z7Unit tests for Full-Stack Blast Radius Impact Analyzer.é    )ÚannotationsNz..ÚtoolsÚanalysiszblast_radius.pyÚtargetÚstrÚ
extra_argsÚreturnÚdictc                óÜ   — t           j        t          d| ddg|¢}t          j        |ddt
          d¬¦  «        }|j        dk    sJ d|j        › �¦   «         ‚t          j	        |j
        ¦  «        S )	z4Helper to run blast_radius.py and parse JSON output.z--targetz--formatÚjsonTzutf-8)Úcapture_outputÚtextÚcwdÚencodingr   zScript failed with stderr: )ÚsysÚ
executableÚSCRIPT_PATHÚ
subprocessÚrunÚPROJECT_ROOTÚ
returncodeÚstderrr   ÚloadsÚstdout)r   r   ÚcmdÚresults       ú5C:\Projects\FreeExile\tests\unit\test_blast_radius.pyÚrun_blast_radiusr      sp   € åŒ>�;¨
°F¸JÈÐ
\ÐQ[Ð
\€CÝŒ^˜C°¸4Å\Ð\cÐdÑdÔd€FØÔ Ò!Ð!Ð!Ð#PÀÄÐ#PÐ#PÑ!Ô!Ð!ÝŒ:�f”mÑ$Ô$Ð$ó    ÚNonec                 ót   — t          d¦  «        } | d         dk    sJ ‚| d         du sJ ‚| d         dk    sJ ‚dS )zCTest files or isolated leaf files should be LOW risk and unblocked.ztests/unit/test_movement.pyÚ
risk_levelÚLOWÚblockedFr   N©r   )Úress    r   Ú'test_blast_radius_test_file_is_low_riskr'      sW   € å
Ð8Ñ
9Ô
9€CØˆ|Ô Ò%Ð%Ð%Ð%ØˆyŒ>˜UÐ"Ð"Ð"Ð"ØˆxŒ=Ð9Ò9Ð9Ð9Ð9Ð9Ð9r   c                 óÚ   — t          d¦  «        } | d         dv sJ ‚t          | d         ¦  «        dk    sJ ‚t          d„ | d         D ¦   «         ¦  «        }|sJ d| d         › �¦   «         ‚dS )	zFCore engine files with many dependents should have HIGH/CRITICAL risk.z(server/world/game_design_matrix_types.pyr"   ©ÚHIGHÚCRITICALÚaffected_filesr   c              3  ó   K  — | ]}d |v V — Œ	dS )Úgame_design_matrix_serviceN© ©Ú.0Úfs     r   ú	<genexpr>z5test_blast_radius_core_engine_file.<locals>.<genexpr>#   s(   è è € ÐWÐW¸AÐ2°aÐ7ÐWÐWÐWÐWÐWÐWr   z'Expected game_design_matrix_service in N©r   ÚlenÚany)r&   Úany_services     r   Ú"test_blast_radius_core_engine_filer8      s�   € å
ÐEÑ
FÔ
F€CØˆ|ÔÐ 4Ð4Ð4Ð4Ð4ÝˆsÐ#Ô$Ñ%Ô%¨Ò)Ð)Ð)Ð)ÝÐWÐWÀÐEUÔAVÐWÑWÔWÑWÔW€KØÐYÐYÐYÀ#ÐFVÔBWÐYÐYÑYÔYˆ;ÐYÐYr   c                 óZ   — d} t          | d¦  «        }|d         du sJ ‚|d         du sJ ‚dS )z)Acknowledging a target should unblock it.zserver/world/combat_engine.pyz--ackÚacknowledgedTr$   FNr%   )r   Úres_acks     r   Ú%test_blast_radius_acknowledgment_flowr<   '   sH   € à,€FÝ˜v wÑ/Ô/€GØ�>Ô" dÐ*Ð*Ð*Ð*Ø�9Ô Ð&Ð&Ð&Ð&Ð&Ð&r   c                 óÆ   — d} t          | ¦  «        }t          |d         ¦  «        dk    sJ ‚t          d„ |d         D ¦   «         ¦  «        }|sJ d|d         › �¦   «         ‚dS )z7Modifying a JS module should detect dependent JS files.zclient/webapp/js/ui/tooltips.jsr,   r   c              3  ó   K  — | ]}d |v V — Œ	dS )zmain.jsNr/   r0   s     r   r3   z;test_blast_radius_js_client_dependencies.<locals>.<genexpr>5   s&   è è € ÐAÐA a�9 �>ÐAÐAÐAÐAÐAÐAr   z-Expected main.js to import tooltips.js, got: Nr4   )r   r&   Úany_mains      r   Ú(test_blast_radius_js_client_dependenciesr@   /   s}   € à.€FÝ
˜6Ñ
"Ô
"€CÝˆsÐ#Ô$Ñ%Ô%¨Ò)Ð)Ð)Ð)åÐAÐA¨3Ð/?Ô+@ÐAÑAÔAÑAÔA€HØÐ\Ð\Ð\ÀSÐIYÔEZÐ\Ð\Ñ\Ô\ˆ8Ð\Ð\r   c                 ó�   — d} t          | ¦  «        }t          d„ |d         D ¦   «         ¦  «        }|sJ d|d         › �¦   «         ‚dS )zLModifying server meridian_catalog.py should flag client meridian_catalog.js.z server/world/meridian_catalog.pyc              3  ó   K  — | ]}d |v V — Œ	dS )zmeridian_catalog.jsNr/   r0   s     r   r3   z7test_blast_radius_dual_stack_catalog.<locals>.<genexpr>=   s(   è è € ÐSÐS¸Ð.°!Ð3ÐSÐSÐSÐSÐSÐSr   r,   z3Expected client meridian_catalog.js counterpart in N©r   r6   )r   r&   Úany_client_cats      r   Ú$test_blast_radius_dual_stack_catalogrE   9   s_   € à/€FÝ
˜6Ñ
"Ô
"€CÝÐSÐS¸SÐAQÔ=RÐSÑSÔSÑSÔS€NØÐhÐhÐhÐQTÐUeÔQfÐhÐhÑhÔhˆ>ÐhÐhr   c                 ó¨   — d} t          | ¦  «        }|d         dv sJ ‚t          d„ |d         D ¦   «         ¦  «        }|sJ d|d         › �¦   «         ‚dS )zMModifying proto/meridian.proto should flag dependent server and client files.zproto/meridian.protor"   r)   c              3  ó   K  — | ]}d |v V — Œ	dS )ÚmeridianNr/   r0   s     r   r3   z1test_blast_radius_proto_schema.<locals>.<genexpr>F   s&   è è € ÐEÐE¨!�j A�oÐEÐEÐEÐEÐEÐEr   r,   zExpected meridian services in NrC   )r   r&   r7   s      r   Útest_blast_radius_proto_schemarI   A   su   € à#€FÝ
˜6Ñ
"Ô
"€CØˆ|ÔÐ 4Ð4Ð4Ð4Ð4ÝÐEÐE¨sÐ3CÔ/DÐEÑEÔEÑEÔE€KØÐPÐPÐP¸Ð=MÔ9NÐPÐPÑPÔPˆ;ÐPÐPr   c                 ó�   — d} t          | ¦  «        }t          d„ |d         D ¦   «         ¦  «        }|sJ d|d         › �¦   «         ‚dS )zAModifying server_cpp FFI should flag python native engine bridge.zserver_cpp/src/sim_core_ffi.cppc              3  ó   K  — | ]}d |v V — Œ	dS )znative_engine_bridge.pyNr/   r0   s     r   r3   z/test_blast_radius_cpp_engine.<locals>.<genexpr>N   s(   è è € ÐSÐS¸Ð.°!Ð3ÐSÐSÐSÐSÐSÐSr   r,   z$Expected native_engine_bridge.py in NrC   )r   r&   Ú
any_bridges      r   Útest_blast_radius_cpp_enginerM   J   s^   € à.€FÝ
˜6Ñ
"Ô
"€CÝÐSÐS¸SÐAQÔ=RÐSÑSÔSÑSÔS€JØÐUÐUÐU¸cÐBRÔ>SÐUÐUÑUÔUˆ:ÐUÐUr   c                 óÆ   — d} t          | ¦  «        }t          |d         ¦  «        dk    sJ ‚t          d„ |d         D ¦   «         ¦  «        }|sJ d|d         › �¦   «         ‚dS )zOQuerying an Act or Boss entity should retrieve cross_relationships from SQLite.ÚACT_I_HUNGERÚdomain_impactsr   c              3  ó&   K  — | ]}d |v pd|v V — ŒdS )ÚACT_CONTAINS_ZONEÚzone_Nr/   )r1   Úimps     r   r3   z3test_blast_radius_matrix_triples.<locals>.<genexpr>W   s1   è è € Ð`Ð`À3Ð%¨Ð,Ð>°¸3°Ð`Ð`Ð`Ð`Ð`Ð`r   zExpected relational triples in Nr4   )r   r&   Úany_rels      r   Ú test_blast_radius_matrix_triplesrV   R   s}   € à€FÝ
˜6Ñ
"Ô
"€CÝˆsÐ#Ô$Ñ%Ô%¨Ò)Ð)Ð)Ð)ÝÐ`Ð`È#ÐN^ÔJ_Ð`Ñ`Ô`Ñ`Ô`€GØÐMÐMÐM°cÐ:JÔ6KÐMÐMÑMÔMˆ7ÐMÐMr   )r   r   r   r   r	   r
   )r	   r    )Ú__doc__Ú
__future__r   r   Úosr   r   ÚpytestÚpathÚabspathÚjoinÚdirnameÚ__file__r   r   r   r'   r8   r<   r@   rE   rI   rM   rV   r/   r   r   ú<module>r`      sr  ðØ =Ð =Ø "Ð "Ð "Ð "Ð "Ð "à €€€Ø 	€	€	€	Ø Ð Ð Ð Ø 
€
€
€
Ø €€€àŒw�Š˜rœwŸ|š|¨B¬G¯OªO¸HÑ,EÔ,EÀtÈTÑRÔRÑSÔS€ØŒg�lŠl˜<¨°*Ð>OÑPÔP€ð%ð %ð %ð %ð:ð :ð :ð :ðZð Zð Zð Zð'ð 'ð 'ð 'ð]ð ]ð ]ð ]ðið ið ið iðQð Qð Qð QðVð Vð Vð VðNð Nð Nð Nð Nð Nr   