§
    U¤½j¢  ã                   óR   — d Z ddlZddlmc m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.
é    N)ÚPathc                   ó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¦  «        }|j        } |¦   «         }|s t          j        d¦  «        dz   dt	          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          t          j	        |¦  «        ¦  «        ‚dx}}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 existzC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}Útelemetry_file)Úpy0Úpy2Úpy4N)
r   ÚexistsÚ
@pytest_arÚ_format_assertmsgÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanation)Úselfr	   Ú@py_assert1Ú@py_assert3Ú@py_format5s        úCC:\Projects\FreeExile\tests\unit\test_target_dummy_and_telemetry.pyÚ'test_target_dummy_telemetry_file_existszMTestMilestone2TargetDummyAndTelemetry.test_target_dummy_telemetry_file_exists   sÔ   € åÐQÑRÔRˆØÔ$ÐNÐ$Ð$Ñ&Ô&ÐNÐ&ÐNÕNÔNÐ(NÑNÔNÐNÑNÐNÕNÔNÑNÔNÐNÐNÕNÔNˆ~ÑNÔNÐNÕNÔNˆ~ÑNÔNÐNÐNÕNÔNÐ$ÑNÔNÕNÔNÐ&ÑNÔNÐNÐNÑNÐNÕNÕNÔNÐNÑNÔNÑNÔNÐNÐNÐNÐNÐNÐNÐNó    c                 óÌ  — t          d¦  «                             d¬¦  «        }d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d	¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}dS )zHtarget_dummy_telemetry.js must implement PROJECT.md interface contracts.r   úutf-8©Úencodingz
recordHit(©Úin©z%(py1)s in %(py3)sÚcontent©Úpy1Úpy3z3Must implement recordHit(damage, isCrit, timestamp)ú
>assert %(py5)sÚpy5Nz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 totalDamage©r   Ú	read_textr   Ú_call_reprcomparer   r   r   r   r   r   r   ©r   r$   Ú@py_assert0Ú@py_assert2Ú@py_format4Ú@py_format6s         r   Ú.test_target_dummy_telemetry_interface_contractzTTestMilestone2TargetDummyAndTelemetry.test_target_dummy_telemetry_interface_contract   sÈ  € åÐJÑKÔK×UÒUÐ_fÐUÑgÔgˆØÐ]ˆ|˜wÐ&Ð]Ð]Ð]Õ]Ô]Ð]Ð]Ð]Ð]ˆ|˜wÐ]Ñ]Ô]Õ]Ô]ˆ|Ñ]Ô]Ð]Õ]Ô]Ñ]Ô]Ð]Ð]Õ]Ô]˜wÑ]Ô]Ð]Õ]Ô]˜wÑ]Ô]Ð]Ð]Ð]Ð]Ñ]Ð]Õ]Ô]Ð(]Ñ]Ô]Ð]Ñ]Ð]Ð]Ð]Ñ]Ð]Õ]Õ]Ô]Ð]Ñ]Ô]Ñ]Ô]Ð]Ð]Ð]Ð]Ð]ØÐJˆ 'Ð)ÐJÐJÐJÕJÔJÐJÐJÐJÐJˆ 'ÐJÑJÔJÕJÔJˆÑJÔJÐJÕJÔJÑJÔJÐJÐJÕJÔJ 'ÑJÔJÐJÕJÔJ 'ÑJÔJÐJÐJÐJÐJÑJÐJÕJÔJÐ+JÑJÔJÐJÑJÐJÐJÐJÑJÐJÕJÕJÔJÐJÑJÔJÑJÔJÐJÐJÐJÐJÐJØÐ<ˆx˜7Ð"Ð<Ð<Ð<Õ<Ô<Ð<Ð<Ð<Ð<ˆx˜7Ð<Ñ<Ô<Õ<Ô<ˆxÑ<Ô<Ð<Õ<Ô<Ñ<Ô<Ð<Ð<Õ<Ô<˜7Ñ<Ô<Ð<Õ<Ô<˜7Ñ<Ô<Ð<Ð<Ð<Ð<Ñ<Ð<Õ<Ô<Ð$<Ñ<Ô<Ð<Ñ<Ð<Ð<Ð<Ñ<Ð<Õ<Õ<Ô<Ð<Ñ<Ô<Ñ<Ô<Ð<Ð<Ð<Ð<Ð<ØÐAˆ|˜wÐ&ÐAÐAÐAÕAÔAÐAÐAÐAÐAˆ|˜wÐAÑAÔAÕAÔAˆ|ÑAÔAÐAÕAÔAÑAÔAÐAÐAÕAÔA˜wÑAÔAÐAÕAÔA˜wÑAÔAÐAÐAÐAÐAÑAÐAÕAÔAÐ(AÑAÔAÐAÑAÐAÐAÐAÑAÐAÕAÕAÔAÐAÑAÔAÑAÔAÐAÐAÐAÐAÐAØÐ9ˆy˜GÐ#Ð9Ð9Ð9Õ9Ô9Ð9Ð9Ð9Ð9ˆy˜GÐ9Ñ9Ô9Õ9Ô9ˆyÑ9Ô9Ð9Õ9Ô9Ñ9Ô9Ð9Ð9Õ9Ô9˜GÑ9Ô9Ð9Õ9Ô9˜GÑ9Ô9Ð9Ð9Ð9Ð9Ñ9Ð9Õ9Ô9Ð%9Ñ9Ô9Ð9Ñ9Ð9Ð9Ð9Ñ9Ð9Õ9Õ9Ô9Ð9Ñ9Ô9Ñ9Ô9Ð9Ð9Ð9Ð9Ð9ØÐ?ˆ|˜wÐ&Ð?Ð?Ð?Õ?Ô?Ð?Ð?Ð?Ð?ˆ|˜wÐ?Ñ?Ô?Õ?Ô?ˆ|Ñ?Ô?Ð?Õ?Ô?Ñ?Ô?Ð?Ð?Õ?Ô?˜wÑ?Ô?Ð?Õ?Ô?˜wÑ?Ô?Ð?Ð?Ð?Ð?Ñ?Ð?Õ?Ô?Ð(?Ñ?Ô?Ð?Ñ?Ð?Ð?Ð?Ñ?Ð?Õ?Õ?Ô?Ð?Ñ?Ô?Ñ?Ô?Ð?Ð?Ð?Ð?Ð?ØÐ7ˆx˜7Ð"Ð7Ð7Ð7Õ7Ô7Ð7Ð7Ð7Ð7ˆx˜7Ð7Ñ7Ô7Õ7Ô7ˆxÑ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Ð7Ð7Ñ7Ð7Õ7Õ7Ô7Ð7Ñ7Ô7Ñ7Ô7Ð7Ð7Ð7Ð7Ð7ØÐAˆ} Ð'ÐAÐAÐAÕAÔAÐAÐAÐAÐAˆ} ÐAÑAÔAÕAÔAˆ}ÑAÔAÐAÕAÔAÑAÔAÐAÐAÕAÔA ÑAÔAÐAÕAÔA ÑAÔAÐAÐAÐAÐAÑAÐAÕAÔAÐ)AÑAÔAÐAÑAÐAÐAÐAÑAÐAÕAÕAÔAÐAÑAÔAÑAÔAÐAÐAÐAÐAÐAÐAÐAr   c                 óÞ  — t          d¦  «                             d¬¦  «                             ¦   «         }t          |¦  «        }d}||k    }|�st	          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  }t	          j
        d
t          |¦  «        › �¦  «        dz   d|iz  }t          t	          j        |¦  «        ¦  «        ‚dx}x}}dS )z8target_dummy_telemetry.js must strictly be <= 250 lines.r   r   r   éú   ©ú<=©z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} <= %(py6)sÚlenÚlines©r
   r&   r'   Úpy6z4target_dummy_telemetry.js must be <= 250 lines, got ú
>assert %(py8)sÚpy8N)r   r0   Ú
splitlinesr=   r   r1   r   r   r   r   r   r   r   )r   r>   r4   Ú@py_assert5Ú@py_assert4Ú@py_format7Ú@py_format9s          r   Ú,test_target_dummy_telemetry_hygiene_line_capzRTestMilestone2TargetDummyAndTelemetry.test_target_dummy_telemetry_hygiene_line_cap   ss  € åÐHÑIÔI×SÒSÐ]dÐSÑeÔe×pÒpÑrÔrˆÝ�5‰zŒzÐe˜SÐeˆz˜SÒ ÐeÐeÑeÕeÔeÐeÐeÐeÐeˆz˜SÐeÑeÔeÐeÕeÔeÑeÔeÐeÐeÕeÔe�sÑeÔeÐeÕeÔe�sÑeÔeÐeÐeÐeÕeÔeÑeÔeÐeÐeÕeÔe�5ÑeÔeÐeÕeÔe�5ÑeÔeÐeÐeÕeÔeˆzÑeÔeÕeÔe˜SÑeÔeÐeÐeÑeÐeÕeÔeÐ"eÕY\Ð]bÑYcÔYcÐ"eÐ"eÑeÔeÐeÑeÐeÐeÐeÑeÐeÕeÕeÔeÐeÑeÔeÑeÔeÐeÐeÐeÐeÐeÐeÐeÐeÐer   c                 óâ  — t          d¦  «                             d¬¦  «        }d}||v }|s—t          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 }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j
        d¦  «        dz   d
|iz  }t          t          j	        |¦  «        ¦  «        ‚dx}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j
        d¦  «        dz   d
|iz  }t          t          j	        |¦  «        ¦  «        ‚dx}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j
        d¦  «        dz   d
|iz  }t          t          j	        |¦  «        ¦  «        ‚dx}}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.isDummyr!   r#   r$   r%   úassert %(py5)sr)   Nzm.hp = m.maxHpzMust clamp dummy hp to maxHpr(   zm.wx = m.originWxz0Must anchor wx strictly to originWx (zero drift)zm.wy = m.originWyz0Must anchor wy strictly to originWy (zero drift))r   r0   r   r1   r   r   r   r   r   r   r   r2   s         r   Ú0test_monster_system_dummy_immortality_and_anchorzVTestMilestone2TargetDummyAndTelemetry.test_monster_system_dummy_immortality_and_anchor#   so  € åÐBÑCÔC×MÒMÐW^ÐMÑ_Ô_ˆØÐ%ˆ{˜gÐ%Ð%Ð%Ð%Õ%Ô%Ð%Ð%Ð%Ð%ˆ{˜gÐ%Ñ%Ô%Õ%Ô%ˆ{Ñ%Ô%Ð%Õ%Ô%Ñ%Ô%Ð%Ð%Õ%Ô%˜gÑ%Ô%Ð%Õ%Ô%˜gÑ%Ô%Ð%Ð%Ð%Ð%Ñ%Ð%Ð%Ð%Ð%Ð%Ñ%Ð%Õ%Õ%Ô%Ð%Ñ%Ô%Ñ%Ô%Ð%Ð%Ð%Ð%Ð%ØÐJÐ 7Ð*ÐJÐJÐJÕJÔJÐJÐJÐJÐJÐ 7ÐJÑJÔJÕJÔJÐÑJÔJÐJÕJÔJÑJÔJÐJÐJÕJÔJ 7ÑJÔJÐJÕJÔJ 7ÑJÔJÐJÐJÐJÐJÑJÐJÕJÔJÐ,JÑJÔJÐJÑJÐJÐJÐJÑJÐJÕJÕJÔJÐJÑJÔJÑJÔJÐJÐJÐJÐJÐJØ"ÐaÐ" gÐ-ÐaÐaÐaÕaÔaÐaÐaÐaÐaÐ" gÐaÑaÔaÕaÔaÐ"ÑaÔaÐaÕaÔaÑaÔaÐaÐaÕaÔa gÑaÔaÐaÕaÔa gÑaÔaÐaÐaÐaÐaÑaÐaÕaÔaÐ/aÑaÔaÐaÑaÐaÐaÐaÑaÐaÕaÕaÔaÐaÑaÔaÑaÔaÐaÐaÐaÐaÐaØ"ÐaÐ" gÐ-ÐaÐaÐaÕaÔaÐaÐaÐaÐaÐ" gÐaÑaÔaÕaÔaÐ"ÑaÔaÐaÕaÔaÑaÔaÐaÐaÕaÔa gÑaÔaÐaÕaÔa gÑaÔaÐaÐaÐaÐaÑaÐaÕaÔaÐ/aÑaÔaÐaÑaÐaÐaÐaÑaÐaÕaÕaÔaÐaÑaÔaÑaÔaÐaÐaÐaÐaÐaÐaÐar   c                 ó²  — t          d¦  «                             d¬¦  «        }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  }	|                     |	¦  «         |s‹t          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          j	        |d¦  «        i z  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}x}x}x}}d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚dx}}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.isDummyr!   ©z%(py3)s in %(py5)sr$   ©r'   r)   ú%(py7)sÚpy7©z%(py10)s in %(py12)s©Úpy10Úpy12ú%(py14)sÚpy14é   zassert %(py17)sÚpy17NÚTargetDummyTelemetryr#   r%   z8combat_skills.js must record hit on TargetDummyTelemetryr(   r)   )r   r0   r   r1   r   r   r   r   ÚappendÚ_format_boolopr   r   r   )r   r$   r   r4   rE   r3   Ú@py_assert9Ú@py_assert11r6   Ú@py_format8Ú@py_format13Ú@py_format15Ú@py_format16Ú@py_format18r5   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Ñ^Ô^ˆØJÐJÐ ÐJÐ  GÐ+ÐJÐJÐJÐJÐJÐ/?ÐJÐ/?À7Ð/JÐJÐJÐJÐJÑJÕJÔJÐJÐJÐJÐJÐ  GÐJÑJÔJÕJÔJÐ ÑJÔJÐJÕJÔJÑJÔJÐJÐJÕJÔJ GÑJÔJÐJÕJÔJ GÑJÔJÐJÐJÐJÐJÑJÐJÐJÐJÐJÐJÑJÐJÐJ×JÒJÐJÑJÔJÐJÐJÐJÕJÔJÐJÐJÐJÐJÐ/?À7ÐJÑJÔJÕJÔJÐ/?ÑJÔJÐJÕJÔJÑJÔJÐJÐJÕJÔJÀ7ÑJÔJÐJÕJÔJÀ7ÑJÔJÐJÐJÐJÐJÑJÐJÐJÐJÐJÐJÑJÐJÐJ×JÒJÐJÑJÔJÐJÕJÔJÐJÐJÑJÔJÐJÑJÐJÐJÐJÐJÐJÑJÐJÕJÕJÔJÐJÑJÔJÑJÔJÐJÐJÐJÐJÐJÐJÐJÐJÐJÐJÐJÐJÐJØ%ÐlÐ%¨Ð0ÐlÐlÐlÕlÔlÐlÐlÐlÐlÐ%¨ÐlÑlÔlÕlÔlÐ%ÑlÔlÐlÕlÔlÑlÔlÐlÐlÕlÔl¨ÑlÔlÐlÕlÔl¨ÑlÔlÐlÐlÐlÐlÑlÐlÕlÔlÐ2lÑlÔlÐlÑlÐlÐlÐlÑlÐlÕlÕlÔlÐlÑlÔlÑlÔlÐlÐlÐlÐlÐlÐlÐlr   c                 ó¼  — t          d¦  «                             d¬¦  «        }d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d	¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}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   ÚisDummyr!   r#   r$   r%   z2spawnMonsterLoot must guard against dummy entitiesr(   r)   Nr/   r2   s         r   Ú.test_monster_loot_dropper_guards_against_dummyzTTestMilestone2TargetDummyAndTelemetry.test_monster_loot_dropper_guards_against_dummy1   sü   € åÐHÑIÔI×SÒSÐ]dÐSÑeÔeˆØÐYˆy˜GÐ#ÐYÐYÐYÕYÔYÐYÐYÐYÐYˆy˜GÐYÑYÔYÕYÔYˆyÑYÔYÐYÕYÔYÑYÔYÐYÐYÕYÔY˜GÑYÔYÐYÕYÔY˜GÑYÔYÐYÐYÐYÐYÑYÐYÕYÔYÐ%YÑYÔYÐYÑYÐYÐYÐYÑYÐYÕYÕYÔYÐYÑYÔYÑYÔYÐYÐYÐYÐYÐYÐYÐYr   c                 óØ  — t          d¦  «                             d¬¦  «        }d}||v }|s—t          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 }|s—t          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S )zRspawnQAEnemy in monster_system.js must reject hostile mob spawning in safe havens.rJ   r   r   Úzone_player_hideoutr!   r#   r$   r%   rK   r)   NÚzone_boundless_sanctuary)
r   r0   r   r1   r   r   r   r   r   r   r2   s         r   Ú#test_client_spawner_safe_haven_gatezITestMilestone2TargetDummyAndTelemetry.test_client_spawner_safe_haven_gate6   s²  € åÐBÑCÔC×MÒMÐW^ÐMÑ_Ô_ˆØ$Ð/Ð$¨Ð/Ð/Ð/Ð/Õ/Ô/Ð/Ð/Ð/Ð/Ð$¨Ð/Ñ/Ô/Õ/Ô/Ð$Ñ/Ô/Ð/Õ/Ô/Ñ/Ô/Ð/Ð/Õ/Ô/¨Ñ/Ô/Ð/Õ/Ô/¨Ñ/Ô/Ð/Ð/Ð/Ð/Ñ/Ð/Ð/Ð/Ð/Ð/Ñ/Ð/Õ/Õ/Ô/Ð/Ñ/Ô/Ñ/Ô/Ð/Ð/Ð/Ð/Ð/Ø)Ð4Ð)¨WÐ4Ð4Ð4Ð4Õ4Ô4Ð4Ð4Ð4Ð4Ð)¨WÐ4Ñ4Ô4Õ4Ô4Ð)Ñ4Ô4Ð4Õ4Ô4Ñ4Ô4Ð4Ð4Õ4Ô4¨WÑ4Ô4Ð4Õ4Ô4¨WÑ4Ô4Ð4Ð4Ð4Ð4Ñ4Ð4Ð4Ð4Ð4Ð4Ñ4Ð4Õ4Õ4Ô4Ð4Ñ4Ô4Ñ4Ô4Ð4Ð4Ð4Ð4Ð4Ð4Ð4r   c                 ól  — t          d¦  «                             d¬¦  «        }g }d}||v }|}|sd}||v }|}|�smt          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  }	|                     |	¦  «         |s‹t          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          j	        |d¦  «        i z  }t          j
        d¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}x}x}x}}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ÚgroundDropsr!   rO   r$   rP   rQ   rR   rS   rT   rW   rX   rY   z)Must flush groundDrops on zone transitionz
>assert %(py17)srZ   N)r   r0   r   r1   r   r   r   r   r\   r]   r   r   r   )r   r$   r   r4   rE   r3   r^   r_   r6   r`   ra   rb   rc   rd   s                 r   Ú;test_worldmap_teleport_flushes_ground_drops_and_projectileszaTestMilestone2TargetDummyAndTelemetry.test_worldmap_teleport_flushes_ground_drops_and_projectiles<   s   € åÐAÑBÔB×LÒLÐV]ÐLÑ^Ô^ˆØ{Ð{Ð'Ð{Ð'¨7Ð2Ð{Ð{Ð{Ð{Ð{°mÐ{°mÀwÐ6NÐ{Ð{Ð{Ð{Ñ{Õ{Ô{Ð{Ð{Ð{Ð{Ð'¨7Ð{Ñ{Ô{Õ{Ô{Ð'Ñ{Ô{Ð{Õ{Ô{Ñ{Ô{Ð{Ð{Õ{Ô{¨7Ñ{Ô{Ð{Õ{Ô{¨7Ñ{Ô{Ð{Ð{Ð{Ð{Ñ{Ð{Ð{Ð{Ð{Ð{Ñ{Ð{Ð{×{Ò{Ð{Ñ{Ô{Ð{Ð{Ð{Õ{Ô{Ð{Ð{Ð{Ð{°mÀwÐ{Ñ{Ô{Õ{Ô{°mÑ{Ô{Ð{Õ{Ô{Ñ{Ô{Ð{Ð{Õ{Ô{ÀwÑ{Ô{Ð{Õ{Ô{ÀwÑ{Ô{Ð{Ð{Ð{Ð{Ñ{Ð{Ð{Ð{Ð{Ð{Ñ{Ð{Ð{×{Ò{Ð{Ñ{Ô{Ð{Õ{Ô{Ð{Ð{Ñ{Ô{Ð{Ñ{Ð{Õ{Ô{ÐP{Ñ{Ô{Ð{Ñ{Ð{Ð{Ð{Ñ{Ð{Õ{Õ{Ô{Ð{Ñ{Ô{Ñ{Ô{Ð{Ð{Ð{Ð{Ð{Ð{Ð{Ð{Ð{Ð{Ð{Ð{Ð{Ð{Ð{r   c                 ó¼  — t          d¦  «                             d¬¦  «        }d}||v }|s¬t          j        d|fd||f¦  «        t          j        |¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddœz  }t          j        d	¦  «        d
z   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}}dS )zTenterMapPortal in hideout_gates.js must dispatch teleportToZone on portal traversal.ú$client/webapp/js/ui/hideout_gates.jsr   r   ÚteleportToZoner!   r#   r$   r%   z'enterMapPortal must call teleportToZoner(   r)   Nr/   r2   s         r   Ú.test_hideout_map_portal_calls_teleport_to_zonezTTestMilestone2TargetDummyAndTelemetry.test_hideout_map_portal_calls_teleport_to_zoneA   sÿ   € åÐ=Ñ>Ô>×HÒHÐRYÐHÑZÔZˆØÐUÐ 7Ð*ÐUÐUÐUÕUÔUÐUÐUÐUÐUÐ 7ÐUÑUÔUÕUÔUÐÑUÔUÐUÕUÔUÑUÔUÐUÐUÕUÔU 7ÑUÔUÐUÕUÔU 7ÑUÔUÐUÐUÐUÐUÑUÐUÕUÔUÐ,UÑUÔUÐUÑUÐUÐUÐUÑUÐUÕUÕUÔUÐUÑUÔUÑUÔUÐUÐUÐUÐUÐUÐUÐUr   c                 ó(  — g d¢}|D �]‰}t          |¦  «        }|                     ¦   «         �rb|                     d¬¦  «                             ¦   «         }t	          |¦  «        }d}||k    }|�st          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  }t          j        |› d
t	          |¦  «        › d�¦  «        dz   d|iz  }	t          t          j        |	¦  «        ¦  «        ‚dx}x}}�Œ‹dS )zCAll modified files must strictly comply with the 500-line hard cap.)rJ   rN   rg   ro   rs   r   r   iô  r:   r<   r=   r>   r?   z exceeded 500 lines hard cap (z lines)rA   rB   N)r   r   r0   rC   r=   r   r1   r   r   r   r   r   r   r   )
r   Úfiles_to_checkÚrel_pathÚpr>   r4   rD   rE   rF   rG   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Ðh SÐh�z SÒ(ÐhÐhÑhÕhÔhÐhÐhÐhÐh�z SÐhÑhÔhÐhÕhÔhÑhÔhÐhÐhÕhÔh•sÑhÔhÐhÕhÔh•sÑhÔhÐhÐhÐhÕhÔhÑhÔhÐhÐhÕhÔh˜5ÑhÔhÐhÕhÔh˜5ÑhÔhÐhÐhÕhÔh�zÑhÔhÕhÔh SÑhÔhÐhÐhÑhÐhÕhÔh¨XÐ*hÐ*hÕUXÐY^ÑU_ÔU_Ð*hÐ*hÐ*hÑhÔhÐhÑhÐhÐhÐhÑhÐhÕhÕhÔhÐhÑhÔhÑhÔhÐhÐhÐhÐhÐhÐhÐhùð		ið 	ir   )r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r7   rH   rL   re   ri   rm   rq   ru   rz   © 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   )r~   Úbuiltinsr   Ú_pytest.assertion.rewriteÚ	assertionÚrewriter   Úpathlibr   Úpytestr   r   r   r   ú<module>r†      s�   ððð ð
 € € € € € € € € € € € € Ð Ð Ð Ð Ð Ð Ø €€€ðIið Iið Iið Iið Iiñ Iiô Iið Iið Iið Iir   