
    еhq                     h    S SK r S SKrS SKrS SKrS SKr " S S5      rSrS rS rS r	S r
S	 rS
 rg)    Nc                   $    \ rS rSrSrSrSrSrSrg)TColors   z3Class to hold ANSI color codes for terminal output.z[92mz[91mz[0m N)	__name__
__module____qualname____firstlineno____doc__GREENREDRESET__static_attributes__r       H/Users/wehrwes/Documents/2540/141/repo/lectures/L10/code/Exam1/iotest.pyr   r      s    =E
CEr   r      c                 j   [         R                  R                  U 5      (       d;  [        [        R
                   SU  S[        R                   35        [        S5        g [        U S5       n[        UR                  5       U S5        SSS5        g! , (       d  f       g= f! [         aE    [        [        R
                   S	[        R                   35        [        S
5        [        S5         g[         a8  n[        [        R
                   SU [        R                   35         SnAgSnAff = f)zp
Performs a pre-flight syntax check on the student's script.
Returns True if syntax is valid, False if invalid.
u   ❌ Error: The script 'z' was not found.zOPlease make sure your script has the correct name and is in the same directory.FrexecNTz Your program has a syntax error!zHPython could not understand your code. Please review your file for typoszHor other syntax mistakes and run the test again. The tests were not run.z2An unexpected error occurred during syntax check: )ospathexistsprintr   r   r   opencompilereadSyntaxError	Exception)script_pathfes      r   check_syntaxr"      s    
 77>>+&&4[MAQRYR_R_Q`ab_`+s#qAFFHk62 $ $# =gmm_MNXYXY OPQsSZS`S`Rabcs=   !B# -B	B# 
B B#  B# #AD21	D2:.D--D2c                     U (       a/  [        [        R                   SU [        R                   35        g[        [        R                   SU [        R                   35        g)z
Prints a formatted test result line with arguments.

Args:
    passed (bool): Whether the test passed or failed
    args_str (str): String representation of the test arguments
u   [PASS] ✅ Arguments: u   [FAIL] ❌ Arguments: N)r   r   r   r   r   )passedargs_strs     r   print_test_resultr&   -   sG     5hZOP3H:gmm_MNr   c                    U R                  S5       Vs/ s H  o"R                  5       PM     nnUR                  S5       Vs/ s H  o"R                  5       PM     nnX4:H  nU(       a  g[        R                  " X45      n/ nU H  nUR	                  S5      (       a5  UR                  [        R                   U [        R                   35        MN  UR	                  S5      (       a5  UR                  [        R                   U [        R                   35        M  UR	                  S5      (       d  M  UR                  U5        M     SSR                  S U 5       5      4$ s  snf s  snf )z
Default comparator: compares expected and actual output line by line, stripping trailing whitespace.
Returns (passed: bool, message: str). If not passed, message contains ndiff output.

T z- z+ z? Fc              3   ,   #    U  H
  nS U 3v   M     g7f)z    Nr   ).0ls     r   	<genexpr>%default_comparator.<locals>.<genexpr>O   s     BMq$qc
Ms   )splitrstripdifflibndiff
startswithappendr   r   r   r   join)expected_outputactual_outputlineexpected_linesactual_linesr$   diffmessage_liness           r   default_comparatorr>   ;   s    
 1@0E0Ed0KL0Kkkm0KNL.;.A.A$.GH.GdKKM.GLH+F}}^:Dt$$$$}TF7==/%JK&&$$tfW]]O%LM&&$$T*  diiBMBBBB MHs   E#E(c                 (    X;   a  gSU SU  S3nSU4$ )z
Comparator that checks if expected_output appears anywhere in actual_output.
No whitespace stripping or line splitting.
Returns (passed: bool, message: str).
r)   zN    Expected output not found in observed output.
    --- Observed output ---
z4
    --- was expected to contain the following: ---
r(   Fr   )r7   r8   msgs      r   contains_comparatorrA   R   s;     ',o Cr	# 	 czr   c           
         Sn[        U5      n[        U5       GH  u  pEUS   nUS   R                  5       nUR                  S5      nUR                  S[        5      n	[
        R                  U /U-   n
SR                  U5      nU(       a	  USU S3-  n S	nU(       a  S
R                  U5      S
-   n[        R                  " U
SSU[        SS9nUR                  R                  5       nU	" X~5      u  nnU(       a  US-  n[        SU5        M  [        SU5        [        S5        [        U5        GM     X#4$ ! [        R                   a/    [        SU5        [        S[         S35        [        S5         GMa  [        R                   a'    [        SU5        [        S5        [        S5         GM  [          a3    [        ["        R$                   SU  S["        R&                   35           g	f = f)z<
Runs the full suite of tests against the student's script.
r   argsr7   stdin
comparator z (with stdin: )Nr(   T)capture_outputtextinputtimeoutcheck   Fz  Differences:z   Your program took longer than z  seconds to run and was stopped.z8  This might be caused by an infinite loop in your code.zK  Your program crashed during this test (it returned a non-zero exit code).z:  This is often caused by an unhandled error or exception.z"Error: Could not find the script 'z	' to run.)len	enumeratestripgetr>   sys
executabler6   
subprocessrunTIMEOUT_SECONDSstdoutr&   r   TimeoutExpiredCalledProcessErrorFileNotFoundErrorr   r   r   )script_nametestspassed_counttotal_countitestrC   r7   stdin_inputrE   commandr%   
stdin_dataresultr8   r$   messages                    r   	run_testsrf   e   s    Le*KU#F|01779hhw'XXl,>?
>>;/$688D> .Q77H(	J!YY{3d:
  ^^# 'F #MM//1M )HOFG!!$1!%2&'gK $l $$ (( 	NeX.4_4EEefgLMM,, 	PeX._`NOO  	W[[M!CK=PYZaZgZgYhij	s%   A7D8"D88>G/:5G/38G/.G/c                 $   [        S5        [        U 5      (       d  S[        U5      p2O[        X5      u  p#[        S5        [        SU SU S35        [        S5        X#:X  a,  [        [        R
                   S[        R                   35        X#4$ )	z
Main function to run tests for an assignment.

Args:
    student_script_name (str): Name of the student's Python script
    test_cases (list): List of test case dictionaries with "args", "expected_output", and optionally "stdin"
z--- Starting Test Runner ---r   z
----------------------------zTotal: z / z Tests Passedz----------------------------u"   All tests passed - nice work! 🎉)r   r"   rN   rf   r   r   r   )student_script_name
test_casesr$   totals       r   run_assignment_testsrk      s     

() +,,3z?!"5B 
/	GF83ug]
34	(OA'--QR=r   )rT   rR   r   shutilr2   r   rV   r"   r&   r>   rA   rf   rk   r   r   r   <module>rm      sH     
 	    0OC.&=%@r   