§
    U¤½j¢  ã                   ó8   — d Z ddlmZ ddlZ G d„ d¦  «        ZdS )z‚
Unit test suite for Milestone 2: Target Dummy Immortality, Loot Prevention,
and Telemetry Engine in FreeExile PoE2 Architecture.
é    )ÚPathNc                   ób   — e Zd Z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d„ZdS )Ú%TestMilestone2TargetDummyAndTelemetryzGVerifies Milestone 2 implementation requirements across client modules.ÚreturnNc                 ó`   — t          d¦  «        }|                     ¦   «         s
J d¦   «         ‚dS )zAtarget_dummy_telemetry.js must exist in client/webapp/js/engine/.ú1client/webapp/js/engine/target_dummy_telemetry.jsz$target_dummy_telemetry.js must existN)r   Úexists)ÚselfÚtelemetry_files     úCC:\Projects\FreeExile\tests\unit\test_target_dummy_and_telemetry.pyÚ'test_target_dummy_telemetry_file_existszMTestMilestone2TargetDummyAndTelemetry.test_target_dummy_telemetry_file_exists   s7   € åÐQÑRÔRˆØ×$Ò$Ñ&Ô&ÐNÐNÐ(NÑNÔNÐ&ÐNÐNó    c                 ó,  — t          d¦  «                             d¬¦  «        }d|v s
J d¦   «         ‚d|v s
J d¦   «         ‚d|v s
J d	¦   «         ‚d
|v s
J d¦   «         ‚d|v s
J d¦   «         ‚d|v s
J d¦   «         ‚d|v s
J d¦   «         ‚d|v s
J d¦   «         ‚dS )zHtarget_dummy_telemetry.js must implement PROJECT.md interface contracts.r   úutf-8©Úencodingz
recordHit(z3Must implement recordHit(damage, isCrit, timestamp)zgetTelemetry(zMust implement getTelemetry()zreset(zMust implement reset()Ú
currentDpszMust compute currentDpsÚpeakDpszMust track peakDpsÚ
comboCountzMust track comboCountÚmaxHitzMust track maxHitÚtotalDamagezMust track totalDamageN©r   Ú	read_text©r
   Úcontents     r   Ú.test_target_dummy_telemetry_interface_contractzTTestMilestone2TargetDummyAndTelemetry.test_target_dummy_telemetry_interface_contract   sø   € åÐJÑKÔK×UÒUÐ_fÐUÑgÔgˆØ˜wÐ&Ð&Ð&Ð(]Ñ&Ô&Ð&Ø 'Ð)Ð)Ð)Ð+JÑ)Ô)Ð)Ø˜7Ð"Ð"Ð"Ð$<Ñ"Ô"Ð"Ø˜wÐ&Ð&Ð&Ð(AÑ&Ô&Ð&Ø˜GÐ#Ð#Ð#Ð%9Ñ#Ô#Ð#Ø˜wÐ&Ð&Ð&Ð(?Ñ&Ô&Ð&Ø˜7Ð"Ð"Ð"Ð$7Ñ"Ô"Ð"Ø Ð'Ð'Ð'Ð)AÑ'Ô'Ð'Ð'Ð'r   c                 óÊ   — t          d¦  «                             d¬¦  «                             ¦   «         }t          |¦  «        dk    sJ dt          |¦  «        › �¦   «         ‚dS )z8target_dummy_telemetry.js must strictly be <= 250 lines.r   r   r   éú   z4target_dummy_telemetry.js must be <= 250 lines, got N)r   r   Ú
splitlinesÚlen)r
   Úliness     r   Ú,test_target_dummy_telemetry_hygiene_line_capzRTestMilestone2TargetDummyAndTelemetry.test_target_dummy_telemetry_hygiene_line_cap   sf   € åÐHÑIÔI×SÒSÐ]dÐSÑeÔe×pÒpÑrÔrˆÝ�5‰zŒz˜SÒ Ð Ð Ð"eÕY\Ð]bÑYcÔYcÐ"eÐ"eÑ Ô Ð Ð Ð r   c                 ó¬   — t          d¦  «                             d¬¦  «        }d|v sJ ‚d|v s
J d¦   «         ‚d|v s
J d¦   «         ‚d	|v s
J d
¦   «         ‚dS )z\monster_system.js must clamp dummy HP and anchor coordinates strictly to originWx, originWy.ú)client/webapp/js/engine/monster_system.jsr   r   z	m.isDummyzm.hp = m.maxHpzMust clamp dummy hp to maxHpzm.wx = m.originWxz0Must anchor wx strictly to originWx (zero drift)zm.wy = m.originWyz0Must anchor wy strictly to originWy (zero drift)Nr   r   s     r   Ú0test_monster_system_dummy_immortality_and_anchorzVTestMilestone2TargetDummyAndTelemetry.test_monster_system_dummy_immortality_and_anchor#   s‡   € åÐBÑCÔC×MÒMÐW^ÐMÑ_Ô_ˆØ˜gÐ%Ð%Ð%Ð%Ø 7Ð*Ð*Ð*Ð,JÑ*Ô*Ð*Ø" gÐ-Ð-Ð-Ð/aÑ-Ô-Ð-Ø" gÐ-Ð-Ð-Ð/aÑ-Ô-Ð-Ð-Ð-r   c                 ó|   — t          d¦  «                             d¬¦  «        }d|v sd|v sJ ‚d|v s
J d¦   «         ‚dS )	z[combat_skills.js must prevent dummy destruction from dropping loot or counting quest kills.ú(client/webapp/js/engine/combat_skills.jsr   r   z!target.isDummyztarget.isDummyÚTargetDummyTelemetryz8combat_skills.js must record hit on TargetDummyTelemetryNr   r   s     r   Ú2test_combat_skills_dummy_loot_and_quest_preventionzXTestMilestone2TargetDummyAndTelemetry.test_combat_skills_dummy_loot_and_quest_prevention+   s^   € åÐAÑBÔB×LÒLÐV]ÐLÑ^Ô^ˆØ  GÐ+Ð+Ð/?À7Ð/JÐ/JÐ/JÐJØ%¨Ð0Ð0Ð0Ð2lÑ0Ô0Ð0Ð0Ð0r   c                 óh   — t          d¦  «                             d¬¦  «        }d|v s
J d¦   «         ‚dS )zWmonster_loot_dropper.js must immediately return empty array if monster.isDummy is true.ú/client/webapp/js/engine/monster_loot_dropper.jsr   r   ÚisDummyz2spawnMonsterLoot must guard against dummy entitiesNr   r   s     r   Ú.test_monster_loot_dropper_guards_against_dummyzTTestMilestone2TargetDummyAndTelemetry.test_monster_loot_dropper_guards_against_dummy1   sB   € åÐHÑIÔI×SÒSÐ]dÐSÑeÔeˆØ˜GÐ#Ð#Ð#Ð%YÑ#Ô#Ð#Ð#Ð#r   c                 ód   — t          d¦  «                             d¬¦  «        }d|v sJ ‚d|v sJ ‚dS )zRspawnQAEnemy in monster_system.js must reject hostile mob spawning in safe havens.r$   r   r   Úzone_player_hideoutÚzone_boundless_sanctuaryNr   r   s     r   Ú#test_client_spawner_safe_haven_gatezITestMilestone2TargetDummyAndTelemetry.test_client_spawner_safe_haven_gate6   sJ   € åÐBÑCÔC×MÒMÐW^ÐMÑ_Ô_ˆØ$¨Ð/Ð/Ð/Ð/Ø)¨WÐ4Ð4Ð4Ð4Ð4Ð4r   c                 ót   — t          d¦  «                             d¬¦  «        }d|v sd|v sJ d¦   «         ‚dS dS )zUteleportToZone in worldmap_dungeons.js must flush groundDrops and flying projectiles.ú(client/webapp/js/ui/worldmap_dungeons.jsr   r   zgroundDrops.length = 0ÚgroundDropsz)Must flush groundDrops on zone transitionNr   r   s     r   Ú;test_worldmap_teleport_flushes_ground_drops_and_projectileszaTestMilestone2TargetDummyAndTelemetry.test_worldmap_teleport_flushes_ground_drops_and_projectiles<   sR   € åÐAÑBÔB×LÒLÐV]ÐLÑ^Ô^ˆØ'¨7Ð2Ð2°mÀwÐ6NÐ6NÐ6NÐP{Ñ6NÔ6NÐNÐ2Ð2Ð6NÐ6Nr   c                 óh   — t          d¦  «                             d¬¦  «        }d|v s
J d¦   «         ‚dS )zTenterMapPortal in hideout_gates.js must dispatch teleportToZone on portal traversal.ú$client/webapp/js/ui/hideout_gates.jsr   r   ÚteleportToZonez'enterMapPortal must call teleportToZoneNr   r   s     r   Ú.test_hideout_map_portal_calls_teleport_to_zonezTTestMilestone2TargetDummyAndTelemetry.test_hideout_map_portal_calls_teleport_to_zoneA   sB   € åÐ=Ñ>Ô>×HÒHÐRYÐHÑZÔZˆØ 7Ð*Ð*Ð*Ð,UÑ*Ô*Ð*Ð*Ð*r   c                 ó  — g d¢}|D ]}}t          |¦  «        }|                     ¦   «         rX|                     d¬¦  «                             ¦   «         }t	          |¦  «        dk    sJ |› dt	          |¦  «        › d�¦   «         ‚Œ~dS )zCAll modified files must strictly comply with the 500-line hard cap.)r$   r'   r+   r3   r7   r   r   iô  z exceeded 500 lines hard cap (z lines)N)r   r	   r   r   r    )r
   Úfiles_to_checkÚrel_pathÚpr!   s        r   Ú,test_all_modified_files_comply_with_hard_capzRTestMilestone2TargetDummyAndTelemetry.test_all_modified_files_comply_with_hard_capF   s¨   € ð
ð 
ð 
ˆð 'ð 	ið 	iˆHÝ�X‘”ˆAØ�xŠx‰zŒzð iØŸš¨W˜Ñ5Ô5×@Ò@ÑBÔB�Ý˜5‘z”z SÒ(Ð(Ð(¨XÐ*hÐ*hÕUXÐY^ÑU_ÔU_Ð*hÐ*hÐ*hÑ(Ô(Ð(øð		ið 	ir   )r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r"   r%   r)   r-   r1   r5   r9   r>   © r   r   r   r   
   s  € € € € € ØQÐQðOð Oð Oð Oð

Bð 
Bð 
Bð 
Bðfð fð fð fð
bð bð bð bðmð mð mð mðZð Zð Zð Zð
5ð 5ð 5ð 5ð|ð |ð |ð |ð
Vð Vð Vð Vð
ið ið ið ið ið ir   r   )rB   Úpathlibr   Úpytestr   rC   r   r   ú<module>rF      sr   ððð ð
 Ð Ð Ð Ð Ð Ø €€€ðIið Iið Iið Iið Iiñ Iiô Iið Iið Iið Iir   