
    BThJW                     R   d dl Z d dlmZ d dlmZmZ d dlmZ d dlmZm	Z	 d dl
mZ d dlmZmZmZmZmZmZmZmZmZmZmZ d dlmZ d	d
lmZ d	dlmZmZmZm Z  d	dl!m"Z" d	dl#m$Z$m%Z%m&Z&m'Z'm(Z( erd dl)Z)d dl*Z*d	dl+m,Z, d	dl-m.Z. e G d d             Z/ ed       G d d             Z0y)    N)defaultdict)	dataclassfield)cached_property)gettextngettext)Path)TYPE_CHECKINGAnyCallableDefaultDictDict	FrozenSet	GeneratorIteratorListSetTuple)xfailed_key   )PYTEST_NODE_SEP)SnapshotSnapshotCollectionSnapshotCollectionsSnapshotUnknownCollection)PyTestLocation)bolderror_stylegreensuccess_stylewarning_style)SnapshotAssertion)
ItemStatusc            	          e Zd ZU dZeed<   ed   ed<   eedf   ed<   ded<   e	d	   ed
<    e
e      Zded<    e
e      Zded<    e
e      Zded<    e
e      Zded<    e
e      Zded<    e
e      Zded<    e
e      Zeee	e   f   ed<    e
e      Zed   ed<    e
d      Zeed<   edefd       Zedefd       Zedefd       Zedeedf   fd       ZdddefdZd>d!Z d>d"Z!edefd#       Z"edefd$       Z#edefd%       Z$edefd&       Z%edefd'       Z&edefd(       Z'ede(d   fd)       Z)ede(d   fd*       Z*ed?d+       Z+ede(e   fd,       Z,d-dde-e.e-ed d f   ef   e/d f   fd.Z0	 	 	 	 	 	 d@d/Z1d0ddefd1Z2d2ed3edefd4Z3d2ede	e	e      fd5Z4d2ed6ed7e	e	e      defd8Z5d6edefd9Z6d2ed6edefd:Z7d2ed6edefd;Z8d2ed6edefd<Z9d2edefd=Z:y )ASnapshotReportz
    This class is responsible for determining the test summary and post execution
    results. It will provide the lines of the report to be printed as well as the
    information used for removal of unused or orphaned snapshots and collections.
    base_dirzpytest.Itemcollected_itemsr#   selected_itemszargparse.Namespaceoptionsr"   
assertionsdefault_factoryr   
discoveredcreatedfailedmatchedupdatedused_provided_test_paths
Expression_keyword_expressionsr   )default_num_xfailsreturnc                 @    t        | j                  j                        S N)boolr)   update_snapshotsselfs    _/var/www/catia.catastroantioquia-mas.com/valormas/lib/python3.12/site-packages/syrupy/report.pyr<   zSnapshotReport.update_snapshotsP   s    DLL1122    c                 @    t        | j                  j                        S r:   )r;   r)   warn_unused_snapshotsr=   s    r?   rB   z$SnapshotReport.warn_unused_snapshotsT   s    DLL6677r@   c                 @    t        | j                  j                        S r:   )r;   r)   include_snapshot_detailsr=   s    r?   rD   z'SnapshotReport.include_snapshot_detailsX   s    DLL99::r@   c                 V    | j                   D ci c]  }|j                  | c}S c c}w r:   )r'   nodeid)r>   items     r?   _collected_items_by_nodeidz)SnapshotReport._collected_items_by_nodeid\   s%    .2.B.BCdT!CCCs   &rG   c                 j    t         |j                  v r!|j                  t            }|r|j                  S y)NF)r   stashrun)r>   rG   results      r?   
_has_xfailzSnapshotReport._has_xfail`   s,    $**$ZZ,Fzz!r@   Nc                 B   | j                          t        t              }| j                  D ]  }|j                  j
                  }|j                  j                  }|||   vrh||   j                  |       | j                  j                  |j                  j                  |j                  |j                  j                               |j                  j                         D ]4  }t!        |j"                        }|j                  t%        |j&                  |j(                               | j*                  j-                  |       |j.                  r| j.                  j-                  |       |j0                  r| j0                  j-                  |       |j2                  r| j4                  j-                  |       | j7                  |j                  j8                        }|r| xj:                  dz  c_        | j<                  j-                  |       7  y )N)test_locationignore_extensionslocation)namedata)rG   r   )&_SnapshotReport__parse_invocation_argsr   setr*   rO   filepath	extension	__class__addr-   mergediscover_snapshotssessionignore_file_extensions
executionsvaluesr   snapshot_locationr   snapshot_name
final_datar2   updater.   r1   successr0   rM   rG   r7   r/   )r>   locations_discovered	assertionrO   extension_classrL   snapshot_collection	has_xfails           r?   __post_init__zSnapshotReport.__post_init__h   s   $$& <Gs;K 	<I%33<<M'11;;O&:=&II$]377H%%''::&/&=&=*3*;*;*R*R ;  $..557 <&8#55'# $''&"6"6V=N=NO 		  !45>>LL''(;<^^LL''(;<^^LL''(;< $V5I5I5N5N OI ((A-(KK&&':;'<	<r@   c                    | j                   j                  rB| j                  j                  t        j                  | j                   j                               | j                   j                  D ]  }|j                  t              }|d   j                         }t        |      }| j                   j                  r7	 t        j                  |      }|j                  t        |j                        }t!        |j#                         r|n|j%                               }|dd | j&                  |<    y# t        $ r Y Kw xY w)a  
        Parse the invocation arguments to extract some information for test selection
        This compiles and saves values from `-k`, `--pyargs` and test dir path

        https://docs.pytest.org/en/stable/reference.html#command-line-flags
        https://docs.pytest.org/en/stable/reference.html#config

        Summary
        -k: is evaluated and used to match against snapshot names when present
        -m: is ignored for now as markers are not matched to snapshot names
        --pyargs: arguments are imported to get their file locations
        [args]: a path provided e.g. tests/test_file.py::TestClass::test_method
        would result in `"tests/test_file.py"` being stored as the location in a
        dictionary with `["TestClass", "test_method"]` being the test node path
        r   Nr   )r)   keywordr5   rZ   r4   composefile_or_dirsplitr   stripr	   pyargs	importlibimport_module__file__	Exceptionstris_absoluteabsoluter3   )r>   ro   partspackage_or_filepathrW   modfilepath_abss          r?   __parse_invocation_argsz&SnapshotReport.__parse_invocation_args   s   " <<%%))**<*<T\\=Q=Q*RS<<33 	@K%%o6E"'(.."2/0H||""#112EFC||/#'#5 $0028I8I8KL 7<ABiD%%l3	@ ! s   <6D22	D>=D>c                 8    | j                  | j                        S r:   )_count_snapshotsr.   r=   s    r?   num_createdzSnapshotReport.num_created       $$T\\22r@   c                 8    | j                  | j                        S r:   )r   r/   r=   s    r?   
num_failedzSnapshotReport.num_failed       $$T[[11r@   c                 8    | j                  | j                        S r:   )r   r0   r=   s    r?   num_matchedzSnapshotReport.num_matched   r   r@   c                 8    | j                  | j                        S r:   )r   r1   r=   s    r?   num_updatedzSnapshotReport.num_updated   r   r@   c                 8    | j                  | j                        S r:   )r   unusedr=   s    r?   
num_unusedzSnapshotReport.num_unused   r   r@   c                 l    | j                   j                         | j                  j                         k(  S r:   )rH   keysr(   r=   s    r?   selected_all_collected_itemsz+SnapshotReport.selected_all_collected_items   s+    ..3359L9L9Q9Q9SSSr@   c                 .      fd j                   D        S )Nc              3   t   K   | ]/  }j                   |   j                  d k(  rj                  |    1 yw)skippedN)r(   valuerH   .0rF   r>   s     r?   	<genexpr>z/SnapshotReport.skipped_items.<locals>.<genexpr>   s=      
""6*00I= ++F3
s   58r(   r=   s   `r?   skipped_itemszSnapshotReport.skipped_items       
--
 	
r@   c                 .      fd j                   D        S )Nc              3   Z   K   | ]"  }j                   |   rj                  |    $ y wr:   )r(   rH   r   s     r?   r   z+SnapshotReport.ran_items.<locals>.<genexpr>   s2      
""6* ++F3
s   (+r   r=   s   `r?   	ran_itemszSnapshotReport.ran_items   r   r@   c           	      $   t               }| j                  | j                  | j                        D ]Q  }|j                  }| j
                  r| j                  |      s.| j                  |      }| j                  rFt        |      s;|D ch c]!  }| j                  ||j                        s|# }}|| j                  v}ni|D ch c]\  }| j                  ||j                        r=| j                  ||j                  |      r| j                  ||j                        s|^ }}d}|r7t        |      }|D ]  }|j                  |        |j                  |       3|s7|j                  t!        |             T |S c c}w c c}w )a  
        Iterate over each snapshot that was discovered but never used and compute
        if the snapshot was unused because the test attached to it was never run,
        or if the snapshot is obsolete and therefore is a candidate for removal.

        Summary, if a snapshot was supposed to be run based on the invocation args
        and it was not, then it should be marked as unused otherwise ignored.
        ra   rb   )ra   rb   provided_nodesFrQ   )r   _diff_snapshot_collectionsr-   r2   rR   r3   _ran_items_match_location_get_matching_path_nodesr   any_skipped_items_match_namerS   _selected_items_match_name_provided_nodes_match_namer   rZ   r   )	r>   unused_collectionsunused_snapshot_collectionra   r   snapshotunused_snapshotsmark_for_removal!marked_unused_snapshot_collections	            r?   r   zSnapshotReport.unused   s    12*.*I*IOOTYY+
 3	& !; C C((1O1O!2
 !::;LMN00^9L
 %?$ 99*;8== :  $  $ $5DII#E  %?$ 66*;8== 7  77*;&.mm'5 8 
 !::*;8== ;  $  $ $) 4F.51 !1 DH599(CD"&&'HI!"&&-7HIc3	h "!K$$s   &FA!Fc           	   #   *	  K   g }| j                   r| j                  | j                   k  r|j                  t        dd| j                   | j                  z
        j	                  t        | j                   | j                  z
                     | j                  rH|j                  t        dd| j                        j	                  t        | j                                     | j                  rH|j                  t        dd| j                        j	                  t        | j                                     | j                  rH|j                  t        dd| j                        j	                  t        | j                                     | j                  rH|j                  t        d	d
| j                        j	                  t        | j                                     | j                  r| j                  rd}d}nd}d}| j                  s| j                  rt        | j                        }nt        | j                        }|j                  t        ||| j                        j	                  |             dj                  |       | j                  rd | j                  s| j                   r{| j                  rdnd}| j#                  | j$                        D ]M  \  }}dj                  t'        t(        t+        |                  }t        t-        |            d| d| dz    O | j                  s2t-        d      }	| j                  rt        |	       nt        |	       | j                  r| j                  r{| j                   rod | j#                  | j.                        D ]M  \  }}dj                  t'        t(        t+        |                  }
t        t-        d            d|
 d| dz    O | j                  r| j                  r}| j                   rpd | j#                  | j0                        D ]M  \  }}dj                  t'        t(        t+        |                  }t        t-        d            d| d| dz    O yyyyw)a   
        These are the lines printed at the end of a test run. Example:
        ```
        2 snapshots passed. 5 snapshots generated. 1 unused snapshot deleted.

        Re-run pytest with --snapshot-update to delete unused snapshots.
        ```
        z{} snapshot failed.z{} snapshots failed.z{} snapshot xfailed.z{} snapshots xfailed.z{} snapshot passed.z{} snapshots passed.z{} snapshot generated.z{} snapshots generated.z{} snapshot updated.z{} snapshots updated.z{} unused snapshot deleted.z{} unused snapshots deleted.z{} snapshot unused.z{} snapshots unused.  DeletedUnusedz, z ()z@Re-run pytest with --snapshot-update to delete unused snapshots.	GeneratedUpdatedN)r   r7   appendr   formatr   r!   r   r    r   r   r   r   r<   rB   joinrD   ,_SnapshotReport__iterate_snapshot_collectionr   mapr   sortedr   r.   r1   )r>   summary_linestext_singulartext_plural
text_countbase_message	snapshotspath_to_filer   messagecreated_snapshotsupdated_snapshotss               r?   lineszSnapshotReport.lines  s     $&??t//$//A  )*OOd&6&66 &T__t7G7G%GHI $$./(( f]4+;+;<=   )*$$ &t'7'789   ,-$$ &t//01   *+$$ &t//01 ??$$ =< 54$$(B(B*4??;
(9
  T__ELLZX hh}%%??H$$(E(E,0,A,Ayx/3/Q/QKK0 +I| (,yyT6);L1M'N$%gl&;<./r,qAB	 ((!V --'00%g.. 5 5$:W:WH+/+M+M, '	< %)IIc$y8I.J$K!!'+"67+,B|nA>?	  5 5$:W:WH+/+M+M, '	< %)IIc$y8I.J$K!!')"45+,B|nA>?	 ;X 5s   RR
collectionc              #      K   |D ]K  }|j                   }d |D        }	 t        t        |      j                  | j                              }||f M y # t
        $ r |}Y w xY ww)Nc              3   4   K   | ]  }|j                     y wr:   )rS   )r   r   s     r?   r   z?SnapshotReport.__iterate_snapshot_collection.<locals>.<genexpr>  s     K8Ks   )rR   rw   r	   relative_tor&   
ValueError)r>   r   ri   rW   r   r   s         r?   __iterate_snapshot_collectionz,SnapshotReport.__iterate_snapshot_collection  st      $. 	,*33HK7JKI("4>#=#=dmm#LM l++	,  (  ((s(   A%-A	A%A"A%!A""A%c                 D   t               }|D ]  }|j                  |j                        xs t        |j                        }t        |j                        }|D ]/  }|j                  |j                        r|j                  |       1 |j                  |        |S )a  
        Find the difference between two collections of snapshot collections. While
        preserving the location site to all collections in the first collections.
        That is a collection with collection sites {A{1,2}, B{3,4}, C{5,6}} with
        snapshot collections when diffed with another collection with snapshots
        {A{1,2}, B{3,4}, D{7,8}}  will result in a collection with the contents
        {A{}, B{}, C{5,6}}.
        rQ   )r   getrR   r   rS   rZ   )r>   snapshot_collections1snapshot_collections2diffed_snapshot_collectionssnapshot_collection1snapshot_collection2diffed_snapshot_collectionr   s           r?   r   z)SnapshotReport._diff_snapshot_collections  s     ':&;#$9 
	H #8#<#<$--$ $L#-A-J-JK ! *<-66*& 1 =+//>.228<= (++,FG
	H +*r@   snapshot_collectionsc                 &    t        d |D              S )zZ
        Count all the snapshots at all the locations in the snapshot collections
        c              3   2   K   | ]  }t        |        y wr:   )len)r   ri   s     r?   r   z2SnapshotReport._count_snapshots.<locals>.<genexpr>  s      
)<C#$
s   )sum)r>   r   s     r?   r   zSnapshotReport._count_snapshots  s      
@T
 
 	
r@   ra   provided_pathc                 v    t        |      }t        |j                         r|      |v S |j                        |v S )z
        Check if a snapshot location matches the path provided by checking that the
        provided path folder is in a parent position relative to the snapshot location
        )r	   rw   is_dirparent)r>   ra   r   paths       r?   _is_matching_pathz SnapshotReport._is_matching_path  s9    
 M"4;;=4:>OOOdkk:>OOOr@   c                 ~    | j                   D cg c]#  }| j                  ||      r| j                   |   % c}S c c}w )a  
        For the snapshot location provided, get the nodes of the test paths provided to
        pytest on invocation. If there were no paths provided then this list should be
        empty. If there are paths without nodes provided then this is a list of empties
        )r3   r   )r>   ra   r   s      r?   r   z'SnapshotReport._get_matching_path_nodes  sF     11
%%&7> %%d+
 	
 
s   (:rb   r   c                 B    |sy|D ]  }|dj                  |      v s y y)z
        Check that a snapshot name matches the node paths provided.
        If no nodes are filtered, provided_nodes is empty, which means
        all nodes should be matched.
        T.F)r   )r>   ra   rb   r   	node_paths        r?   r   z)SnapshotReport._provided_nodes_match_name  s2     ' 	I 33	 r@   c                 b    |j                  d      t        fd| j                  D              S )z
        Check that a snapshot name would have been included by the keyword
        expression parsed from the invocation arguments
        r   c              3   F   K   | ]  }|j                  fd         yw)c                 .     t         fdD              S )Nc              3   &   K   | ]  }|v  
 y wr:    )r   rS   subnames     r?   r   z[SnapshotReport._provided_keywords_match_name.<locals>.<genexpr>.<lambda>.<locals>.<genexpr>  s     -P$go-Ps   )r   )r   namess   `r?   <lambda>zHSnapshotReport._provided_keywords_match_name.<locals>.<genexpr>.<lambda>  s    #-P%-P*P r@   N)evaluate)r   exprr   s     r?   r   z?SnapshotReport._provided_keywords_match_name.<locals>.<genexpr>  s#      
 MMPQ
s   !)rp   r   r5   )r>   rb   r   s     @r?   _provided_keywords_match_namez,SnapshotReport._provided_keywords_match_name  s5    
 ##C( 
11
 
 	
r@   c                     | j                   D ]2  }t        |      }|j                  |      s |j                  |      s2 y y)z^
        Check that a snapshot name would match a test node using the Pytest location
        TF)r   r   matches_snapshot_locationmatches_snapshot_namer>   ra   rb   rG   rR   s        r?   _ran_items_match_namez$SnapshotReport._ran_items_match_name  sH     NN 	D%d+H11!00?	 r@   c                     | j                   D ]2  }t        |      }|j                  |      s |j                  |      s2 y y)z
        Check that a snapshot name should be treated as skipped by the current session
        This being true means that it will not be deleted even if the it is unused
        TF)r   r   r   r   r   s        r?   r   z(SnapshotReport._skipped_items_match_name  sJ     && 	D%d+H11!00?	 r@   c                 b    | j                   r| j                  |      S | j                  ||      S )z
        Check that a snapshot name should be treated as selected by the current session
        This being true means that if the snapshot was not used then it will be deleted
        r   )r5   r   r   )r>   ra   rb   s      r?   r   z)SnapshotReport._selected_items_match_name  s;     $$55mDD))/} * 
 	
r@   c                 @    t        fd| j                  D              S )z
        Check if any test run in the current session should match the snapshot location
        This being true means that if no snapshot in the collection was used then it
        should be discarded as obsolete
        c              3   R   K   | ]  }t        |      j                           y wr:   )r   r   )r   rG   ra   s     r?   r   z;SnapshotReport._ran_items_match_location.<locals>.<genexpr>  s*      
 4 ::;LM
s   $')r   r   )r>   ra   s    `r?   r   z(SnapshotReport._ran_items_match_location  s#      

 
 	
r@   )r8   N)r8   r   )r   r   r   r   r8   r   );__name__
__module____qualname____doc__r	   __annotations__r   r   rw   r   r   r   r-   r.   r/   r0   r1   r2   dictr3   rV   r5   r7   intpropertyr;   r<   rB   rD   r   rH   rM   rk   rU   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r@   r?   r%   r%   6   s    N''l*++!!()) ).>Q(RJ%R%*;N%OG"O$):M$NF!N%*;N%OG"O%*;N%OG"O"'8K"LD
L16t1L$sDI~.L.3C.H#l+HQ'K'3$ 3 3 8t 8 8 ;$ ; ; DDm1C,D D D}  $<L!@F 3S 3 3 2C 2 2 3S 3 3 3S 3 3 2C 2 2 Td T T 
x6 
 
 
8M2 
 
 >" >"@ kx} k kZ,/,	53d?3S893D	E, +4+  5+ 
	+6
5J 
s 
P3 Ps Pt P

# 

$tCy/ 

  T#Y	
 
$	
3 	
4 	

s 
3 
SW 
!$58	
!$
58
	
	
3 	
4 	
r@   r%   T)frozenc                   j    e Zd ZU dZ ee      Zee   e	d<   de
egef   defdZededd fd       Zy	)
r4   aY  
    Dumbed down version of _pytest.mark.expression.Expression not available in < 6.0
    https://github.com/pytest-dev/pytest/blob/6.0.x/src/_pytest/mark/expression.py
    Added for pared down support on older pytest version and because the expression
    module is not public. This only supports inclusion based on simple string matching.
    r+   codematcherr8   c                 @    t        t        || j                              S r:   )r   r   r  )r>   r  s     r?   r   zExpression.evaluate+  s    3w		*++r@   r   c                     d}h d}|D ]  }| j                  d| d|      }  t        t        | j                  |                  S )Nr   >    or  and  not (r   )r  )replacer4   	frozensetrp   )r   delimreplace_strrs       r?   rn   zExpression.compose.  sL    : 	3AMMAaS(E2E	3yU);<==r@   N)r   r   r   r   r   r
  r  r   rw   r   r   r;   r   staticmethodrn   r   r@   r?   r4   r4      s\     !;D)C.;,# 5 ,$ , >s >| > >r@   r4   )1rs   collectionsr   dataclassesr   r   	functoolsr   r   r   pathlibr	   typingr
   r   r   r   r   r   r   r   r   r   r   _pytest.skippingr   	constantsr   rT   r   r   r   r   rR   r   terminalr   r   r   r    r!   argparsepytestrg   r"   r]   r#   r%   r4   r   r@   r?   <module>r     s     # &     ) &  %  ,# f
 f
 f
R $> > >r@   