
    igE                        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 ddlmZmZmZ e	j"                  j%                  dd       d Zd0deded	efd
Zd1dedefdZd2dededefdZd Zd3defdZd Zd Zd4dZd5defdZ d Z!d Z"d Z#d Z$d Z%d Z&d  Z'd! Z(d" Z)d# Z*d$ Z+d% Z,e-d&k(  re!e"e#e$e%e&e'e(e)e*e+e,gZ.dZ/dZ0e.D ]  Z1	  e1        e/dz  Z/  e5d)d*         e5d+e/ d, e7e.       d-       e0r e5d'e0 d.        e	jp                  d       y e5d/        e	jp                  d       yy# e2$ r<Z3ddl4Z4 e5d'e1jZ                   d(e3         e4jl                          e0dz  Z0Y dZ3[3dZ3[3ww xY w)6u  
Tests for Story 3.06 (Track B): MVFLInterceptor — Wires MVFL Into Chain

BB1: Clean output → post_execute passes through unchanged (no mvfl_corrected key)
BB2: Triggered output → CorrectionLoop called, result has mvfl_corrected=True
BB3: MVFL decision recorded in events.jsonl
BB4: 3-strike escalation → result has mvfl_escalated=True
BB5: on_correction is pure passthrough (returns unchanged payload)

WB1: Priority=90 ensures MVFL runs after JIT hydration (10) and business logic
WB2: pre_execute truly returns unchanged payload (identity)
WB3: VoyagerDefense.score is called (synchronous)
WB4: metadata.name == "mvfl"
WB5: on_error calls trigger.evaluate on error dict
    N)Path)	AsyncMock	MagicMockpatchz/mnt/e/genesis-systemc                 H    t        j                         j                  |       S )z0Run a coroutine synchronously for test purposes.)asyncioget_event_looprun_until_complete)coros    6/mnt/e/genesis-system/tests/track_b/test_story_3_06.pyrunr      s    !!#66t<<    	triggeredtrigger_typedetailsc                 H    ddl m}  || | r|nd| rdnd| r|      S d      S )z)Build an MVFLTriggerResult for injection.r   )MVFLTriggerResultN   zClean output)r   r   severityr   )core.mvfl.mvfl_triggerr   )r   r   r   r   s       r   _make_trigger_resultr   $   s7    8%.\DQ$	  +9	 r   should_blockscorec                 $    ddl m}  ||g |       S )z#Build a VoyagerScore for injection.r   )VoyagerScore)r   matched_scarsr   )core.mvfl.voyager_defenser   )r   r   r   s      r   _make_voyager_scorer   /   s    6e2LQQr   r   successattempts	escalatedc                 B    ddl m} | rddddndddd	} || |||
      S )z'Build a CorrectionResult for injection.r   )CorrectionResultt1	completed	correctedtask_idstatusoutputerrorMVFL_ESCALATION_REQUIREDr(   r)   r+   )r   r*   r    r!   )core.mvfl.correction_loopr#   )r   r    r!   r#   r*   s        r   _make_correction_resultr/   5   s5    :PWL75O^F GFXYbccr   c                  N    t               } t        d      | j                  _        | S )z4Return a mock MVFLTrigger that reports clean output.Fr   r   evaluatereturn_valuemocks    r   _make_clean_trigger_mockr6   >   s    ;D!5e!<DMMKr   c                 R    t               }t        d| d      |j                  _        |S )z/Return a mock MVFLTrigger that always triggers.Tzdetected errorr1   )r   r5   s     r   _make_triggered_trigger_mockr8   E   s$    ;D!5dLJZ![DMMKr   c                  P    t               } t        d      | j                  _        | S )z/Return a mock VoyagerDefense that never blocks.F)r   r   r   r   r3   r4   s    r   _make_clean_voyager_mockr;   L   s    ;D1uEDJJKr   c                  R    t               } t        dd      | j                  _        | S )z0Return a mock VoyagerDefense that always blocks.Tgffffff?)r   r   r:   r4   s    r   _make_blocking_voyager_mockr=   S   s!    ;D1t4PDJJKr   c                 l    ddl m}  || xs
 t               |xs
 t               |xs
 t	                     S )zABuild an MVFLInterceptor with all dependencies mocked by default.r   MVFLInterceptortriggervoyagercorrection_loop)core.mvfl.mvfl_interceptorr@   r6   r;   r   )rB   rC   rD   r@   s       r   _make_interceptorrF   Z   s4    :535535'69; r   r(   c                     | ddS )NzDo the thing.)r(   prompt )r(   s    r   
_make_taskrJ   d   s    /::r   c                     t        t               t                     } dddd}t        |j	                               }t        | j                  |t                            d}||v}|st        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}|st        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   }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}}t#        d       y)zKBB1: When trigger is clean and voyager does not block, result is unchanged.)rB   rC   task-001r%   okr'   mvfl_corrected)not in)z%(py1)s not in %(py3)sresultpy1py3z+Unexpected mvfl_corrected in clean result: 
>assert %(py5)spy5Nmvfl_escalatedz+Unexpected mvfl_escalated in clean result: r)   ==z%(py1)s == %(py4)srR   py4zassert %(py6)spy6r*   u5   BB1 PASSED — clean output untouched by post_execute)rF   r6   r;   setkeysr   post_executerJ   
@pytest_ar_call_reprcompare	_saferepr@py_builtinslocals_should_repr_global_name_format_assertmsgAssertionError_format_explanationprint)
interceptorrP   original_keys@py_assert0@py_assert2@py_format4@py_format6@py_assert3@py_format5@py_format7s
             r   .test_bb1_clean_output_passes_through_unchangedrs   l   s   #(*(*K
 ${dKF&M  67 a6)aaa6aaaaaaaaa6aaa6aaaa-XY_X`+aaaaaaaa6)aaa6aaaaaaaaa6aaa6aaaa-XY_X`+aaaaaaa(*{*{****{******{*******(#t#t####t######t#######	
ABr   c                     ddl m}  t               }t        t	        dd            |_         | t        d      t               |      }d	d
dd}t        |j                  |t        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  }	t        j"                  d|       dz   d|	iz  }
t%        t        j&                  |
            dx}x}x}x}}|j                  }d} ||      }d}||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                   |      t        j                   |      dz  }	t        j"                  d|       dz   d|	iz  }
t%        t        j&                  |
            dx}x}x}x}}|j
                  j)                          t+        d       y)zQBB2: When trigger fires and correction succeeds, result gets mvfl_corrected=True.r   r?   Tr   r   r    r3   syntaxrA   ztask-002r+   z
bad formatr-   rN   iszI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} is %(py9)srP   py0py2r[   r\   py9z#Expected mvfl_corrected=True, got: 
>assert %(py11)spy11Nmvfl_attemptsrW   zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)szExpected mvfl_attempts=1, got: uH   BB2 PASSED — triggered output corrected, mvfl_corrected=True in resultrE   r@   r   r   r/   r   r8   r;   r_   rJ   getr`   ra   rc   rd   re   rb   rf   rg   rh   assert_awaited_onceri   r@   correction_mockrj   rP   @py_assert1rp   @py_assert5@py_assert8@py_assert7@py_format10@py_format12s              r   )test_bb2_triggered_output_corrects_resultr      s   :kO#1HQU`a1bcO!,X6(*'K $wNF  J)?@A::_&_:&'_4_'4/___'4______6___6___:___&___'___4___3VW]V^1________::WoW:o&W!W&!+WWW&!WWWWWW6WWW6WWW:WWWoWWW&WWW!WWW/Nvh-WWWWWWWW++-	
TUr   c            	      *   ddl m}  ddl mc m} t	        j
                         5 }t        |      }|j                  }||_        	  | t               t               t                     }dddd}t        |j                  |t        d                   |d	z  }|j                  } |       }	|	st        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}}	|j/                         j1                         j3                         }t5        |      }d}||k\  }|st        j6                  d|fd||f      dt#        j$                         v st        j&                  t4              rt        j(                  t4              nd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}}t9        j:                  |d         }|d   }d}	||	k(  }|st        j6                  d|fd||	f      t        j(                  |      t        j(                  |	      dz  }
t        j                   d|d          dz   d|
iz  }t+        t        j,                  |            dx}x}}	|d    }d}	||	k(  }|st        j6                  d|fd||	f      t        j(                  |      t        j(                  |	      dz  }
t        j                   d!|d           dz   d|
iz  }t+        t        j,                  |            dx}x}}	d"}||v }|st        j6                  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 }|st        j6                  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 }|st        j6                  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 }|st        j6                  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dd       t=        d0       y# ||_        w xY w# 1 sw Y   !xY w)1zKBB3: Every post_execute call writes an mvfl_decision event to events.jsonl.r   r?   NrA   ztask-003r%   rM   r'   zevents.jsonlzevents.jsonl was not createdzC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}log_path)r|   r}   r[   r   )>=)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} >= %(py6)slenlines)r|   rR   rS   r\   z!No events written to events.jsonlz
>assert %(py8)spy8
event_typemvfl_decisionrW   rY   rZ   z*Expected event_type='mvfl_decision', got: 
>assert %(py6)sr\   r(   zWrong task_id in event: 	timestampinz%(py1)s in %(py3)seventrQ   zMissing timestamp in eventrT   rU   r   zMissing triggered in eventblockedzMissing blocked in eventvoyager_scorezMissing voyager_score in eventu:   BB3 PASSED — mvfl_decision event written to events.jsonl)rE   r@   mvflmvfl_interceptortempfileTemporaryDirectoryr   
EVENTS_DIRr6   r;   r   r   r_   rJ   existsr`   rf   rc   rd   re   rb   rg   rh   	read_textstrip
splitlinesr   ra   jsonloadsri   )r@   interceptor_modtmpdirlog_diroriginal_events_dirrj   rP   r   r   rp   rq   r   rm   r   @py_assert4rr   @py_format9r   rl   rn   ro   s                        r   *test_bb3_decision_recorded_in_events_jsonlr      s   :88		$	$	& =&v,-88%,"	=)0202 )K ",{dSF((J1GHI/H??D?$D$DD&DDDDDDD8DDD8DDD?DDD$DDDDDD&&(..0;;=Eu:GG:?GGG:GGGGGG3GGG3GGGGGGuGGGuGGG:GGGGGG$GGGGGGGGJJuRy)E& / &/9  &/  I '  I +:    =U<=P<QR     #`z`#z1```#z```#```z```5MeT]N^M_3````````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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A9%AAA9AAA9AAAAAAAAAAAAA'AAAAAAA"M?e+MMM?eMMM?MMMMMMeMMMeMMMM-MMMMMMM)<O&?=B 

FG *=O&?= =s$   \	Z[=!\	=	\\		\c                     ddl m}  t               }t        t	        ddd            |_         | t        d      t               |	      }d
ddd}t        |j                  |t        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  }	t        j"                  d|       dz   d|	iz  }
t%        t        j&                  |
            dx}x}x}x}}|j                  }d} ||      }d}||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                   |      t        j                   |      dz  }	t        j"                  d|j                  d             dz   d|	iz  }
t%        t        j&                  |
            dx}x}x}x}}|j
                  j)                          t+        d       y)zOBB4: When CorrectionLoop exhausts all attempts, result has mvfl_escalated=True.r   r?   F   T)r   r    r!   rv   external_rejectionrA   ztask-004r+   zAPI timeoutr-   rV   rx   rz   rP   r{   z2Expected mvfl_escalated=True after 3-strike, got: r   r   Nr   rW   r   zExpected mvfl_attempts=3, got: u;   BB4 PASSED — 3-strike escalation sets mvfl_escalated=Truer   r   s              r   4test_bb4_three_strike_escalation_sets_mvfl_escalatedr      s   :kO#,UQRVWO ",-AB(*'K $wOF  J)?@A:: & :&' 4 '4/  '4                  '    (    ,0    =VHE      :: o :o& ! &!+  &!                  &    '    +,    *&**_*E)FG      ++-	
GHr   c                     t               } dddd}t        | j                  |            }||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      nd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}dddd}||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}}t        d       y)z?BB5: on_correction must return the exact same dict it receives.ztask-005zCORRECTION: fix this   )r(   rH   attemptrx   z%(py0)s is %(py2)sreturnedpayloadr|   r}   z9on_correction must return the same dict object (identity)
>assert %(py4)sr[   NrW   z%(py0)s == %(py3)sr|   rS   assert %(py5)srU   u2   BB5 PASSED — on_correction is a pure passthrough)rF   r   on_correctionr`   ra   rc   rd   re   rb   rf   rg   rh   ri   	rj   r   r   r   @py_format3rq   rm   rn   ro   s	            r   %test_bb5_on_correction_is_passthroughr      s   #%K$0FSTUG;,,W56Hw[[[8w[[[[[[8[[[8[[[[[[w[[[w[[[[ [[[[[[[#-9O\]^^8^^^^^8^^^^^^^8^^^8^^^^^^^^^^^	
>?r   c                  \   t               } | j                  }|j                  }d}||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  }t        j                  d| j                  j                         dz   d|iz  }t        t        j                  |            d	x}x}x}}t        d
       y	)z2WB1: MVFLInterceptor.metadata.priority must be 90.Z   rW   )zN%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.metadata
}.priority
} == %(py7)srj   r|   r}   r[   py7zExpected priority=90, got: 
>assert %(py9)sr~   NuA   WB1 PASSED — priority=90 (runs after priority 10 JIT hydration))rF   metadatapriorityr`   ra   rc   rd   re   rb   rf   rg   rh   ri   rj   r   rp   @py_assert6r   @py_format8r   s          r   test_wb1_priority_is_90r      s	   #%K (( B (B.  (B                   )    -/    &k&:&:&C&C%DE      

MNr   c                     t               } dddd}t        | j                  |            }||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      nd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}dddd}||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}}t        d       y)z=WB2: pre_execute must return the exact same dict, unmodified.ztask-wb2Hello*   )r(   rH   
custom_keyrx   r   r   r   r   z,pre_execute must return the same dict objectr   r[   NrW   r   r   r   rU   u?   WB2 PASSED — pre_execute returns identity (unchanged payload))rF   r   pre_executer`   ra   rc   rd   re   rb   rf   rg   rh   ri   r   s	            r    test_wb2_pre_execute_is_identityr     s   #%K$rJG;**734HwNNN8wNNNNNN8NNN8NNNNNNwNNNwNNNN NNNNNNN#-PRSS8SSSSS8SSSSSSS8SSS8SSSSSSSSSSS	
KLr   c                      ddl m}  t               } | t               |t	                     }ddd}t        |j                  |t        d                   |j                  j                  |       t        d       y)	z7WB3: post_execute must call voyager.score exactly once.r   r?   rA   ztask-wb3r%   )r(   r)   u<   WB3 PASSED — voyager.score called once during post_executeN)rE   r@   r;   r6   r   r   r_   rJ   r   assert_called_once_withri   )r@   voyager_mockrj   rP   s       r    test_wb3_voyager_score_is_calledr     sh    :+-L!(*!K ${;F  J)?@A..v6	
HIr   c                  \   t               } | j                  }|j                  }d}||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  }t        j                  d| j                  j                        dz   d|iz  }t        t        j                  |            d	x}x}x}}t        d
       y	)z2WB4: MVFLInterceptor.metadata.name must be 'mvfl'.r   rW   zJ%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.metadata
}.name
} == %(py7)srj   r   z$Expected metadata.name='mvfl', got: r   r~   Nu&   WB4 PASSED — metadata.name == 'mvfl')rF   r   namer`   ra   rc   rd   re   rb   rf   rg   rh   ri   r   s          r   test_wb4_metadata_name_is_mvflr   1  s	   #%K $$  $.  $                   %    )/    /{/C/C/H/H.KL      

23r   c                     ddl m}  t               } | |t               t	                     }t        d      }t        d      }t        |j                  ||            }|j                  }|j                  }d}||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  }
t        j"                  d|j                  j                         dz   d|
iz  }t%        t        j&                  |            dx}x}x}	}|j                  j(                  }|d   d   }|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}}d}|d   }||v }|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}}d}||v }|st        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}}t+        d       y) zEWB5: on_error must call trigger.evaluate with the error dict context.r   r?   rA   ztask-wb5zSomething explodedr   rW   )zP%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.evaluate
}.call_count
} == %(py7)strigger_mockr   z*Expected 1 call to trigger.evaluate, got: r   r~   Nr)   r+   rY   rZ   z,Error output must have status='error', got: r   r\   r   )z%(py1)s in %(py4)sz5Error message must be in error_output['error'], got: r   r   rQ   z&Return dict must contain 'error' key: rT   rU   u>   WB5 PASSED — on_error calls trigger.evaluate with error dict)rE   r@   r6   r;   r   rJ   
ValueErrorr   on_errorr2   
call_countr`   ra   rc   rd   re   rb   rf   rg   rh   	call_argsri   )r@   r   rj   taskerrr   r   rp   r   r   r   r   r   error_outputrl   rm   rq   rr   rn   ro   s                       r   (test_wb5_on_error_calls_trigger_evaluater   >  s   :+-L!(*!K j!D
)
*C;''T23H     ++ q +q0  +q              !    ,    01    5\5J5J5U5U4VW     
 %%//IQ<?L! W !W,  !W    "    &-    7|nE       <#8 #88  #8         $9    @~N    
 S7hSSS7hSSS7SSSSSShSSShSSSS"H
 SSSSSSS	
JKr   c                  \   ddl m}  t               }t        t	        dd            |_         | t               t               |      }dd	d
d}t        |j                  |t        d                   |j
                  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}}t+        d       y)zGExtra: VoyagerDefense block (without trigger) also runs CorrectionLoop.r   r?   Tr   ru   rv   rA   z
task-extrar%   
suspiciousr'   rN   rx   rz   rP   r{   z2Expected mvfl_corrected after voyager block, got: r   r   Nu;   BB6 PASSED — voyager block alone triggers correction loop)rE   r@   r   r   r/   r   r6   r=   r_   rJ   r   r   r`   ra   rc   rd   re   rb   rf   rg   rh   ri   r   s              r   0test_bb6_voyager_block_alone_triggers_correctionr   e  s   :kO#1HQU`a1bcO!(*+-'K &UF  L)ABC++-:: & :&' 4 '4/  '4                  '    (    ,0    =VHE      

GHr   c                  R   ddl m}  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}} |        }|j                  }|j                  }d
}||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}}t        d       y)z?WB6: MVFLInterceptor must be importable from core.mvfl package.r   r?   N)is not)z%(py0)s is not %(py3)sr@   r   r   rU   r   rW   r   rj   r   zassert %(py9)sr~   u?   WB6 PASSED — MVFLInterceptor exported from core.mvfl.__init__)	core.mvflr@   r`   ra   rc   rd   re   rb   rg   rh   r   r   ri   )r@   rm   r   rn   ro   rj   rp   r   r   r   r   s              r   /test_wb6_mvfl_interceptor_exported_from_packager   |  s    )"&&?$&&&&?$&&&&&&?&&&?&&&$&&&&&&&!#K.$$..$....$......;...;......$..........	
KLr   __main__zFAILED: u    — 
z<============================================================zStory 3.06 Test Results: /z passedz test(s)zALL TESTS PASSED)rw   bad)Fg        )r   F)rw   )NNN)rL   )9__doc__builtinsrc   _pytest.assertion.rewrite	assertionrewriter`   r   r   sysr   pathlibr   unittest.mockr   r   r   pathinsertr   boolstrr   floatr   intr/   r6   r8   r;   r=   rF   rJ   rs   r   r   r   r   r   r   r   r   r   r   r   __name__testspassedfailedt	Exceptionexc	tracebackri   	print_excr   exitrI   r   r   <module>r     s      
   5 5 * +=
D  QT Rd R5 RdT dS d ds ; ;C2V6&HZIB	@ O	M J,4 LNI.M z612<-((&087E FF 	CaKF 
Bvh-	%fXQs5zl'
BC)* !G ,  	HQZZLcU34I!aKF		s   
D55E6:2E11E6