
    'i6                         d dl mZ d dlmZ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 d dlmZmZ d dlmZ  G d de      Z G d d	e      Z G d
 de      Z G d de      Z G d de      Z G d de      Zy)    )TestCase)
ParseErrorIncompleteParseError)
LiteralRegexSequenceOneOfNot
QuantifierOptional
ZeroOrMore	OneOrMore
Expression)Grammarrule_grammar)Nodec                   @    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)LengthTestszTests for returning the right lengths

    I wrote these before parse tree generation was implemented. They're
    partially redundant with TreeTests.

    c                 L    |dn|j                   |j                  z
  }||k(  sJ y)zReturn whether the match lengths of 2 nodes are equal.

        Makes tests shorter and lets them omit positional stuff they don't care
        about.

        N)endstart)selfnodelengthnode_lengths       T/var/www/br/venv/lib/python3.12/site-packages/parsimonious/tests/test_expressions.pylen_eqzLengthTests.len_eq   s*     #ld4::0Ef$$$    c                 Z   | j                  t        d      j                  dd      d       | j                  t        d      j                  d      d       | j	                  t
        t        d      j                  d       | j                  t        dd	
      j                  d      d       y )Nhelloehello      zhello*hellooo   goodbyeT)ignore_caseHELLO)r   r   matchr   assertRaisesr   r   s    r   
test_regexzLengthTests.test_regex   s{    GG$**8Q7;E(O)))4a8*eHo&;&;YGE't4::7CQGr   c           
         | j                  t        t        d      t        d      t        d            j	                  d      d       | j                  t        t        t        d      t        d      t        d            j                  d       | j                  t        t        d            j	                  dd      d	       y )
Nzhi*loz.ingohiiiilobingo1234   hiiiilobingz>hiiiir"   r#   )r   r   r   r   r)   r*   r   r+   s    r   test_sequencezLengthTests.test_sequence#   s    HU5\74=%.IOOPbcegh*huU|WT]/4W~'??Dum	UHU5\*001=qAr   c           	      r   | j                  t        t        d      t        d            j                  d      d       | j                  t        t        d      t        d            j                  d      d       | j	                  t
        t        t        d      t        d            j                  d       y )Naaabb   bbaaa   aa)r   r	   r   r)   r*   r   r+   s    r   test_one_ofzLengthTests.test_one_of)   sz    E'%.'$-8>>uEqIE'%.'$-8>>wGK*eGENGDM&J&P&PRVWr   c                     | j                  t        t        d            j                  d      d       | j	                  t
        t        t        d            j                  d       y )N. r   Hi)r   r
   r   r)   r*   r   r+   s    r   test_notzLengthTests.test_not.   sC    Cc
O))"-q1*c%*o&;&;TBr   c           	         | j                  t        t        t        d            t        d            j	                  d      d       | j                  t        t        t        d            t        d            j	                  d      d       | j                  t        t        d            j	                  d      d       | j                  t        t        d            j	                  d      d       y )	Nabr"   abr8   r9   r5   r   )r   r   r   r   r)   r+   s    r   test_optionalzLengthTests.test_optional2   s    HXgcl3WS\BHHMqQHXgcl3WS\BHHNPQRHWS\*006:HWS\*006:r   c                    | j                  t        t        d            j                  d      d       | j                  t        t        d            j                  d      d       | j                  t	        d      j                  d      d       | j                  t        t	        d            j                  d      d       y )NrB   r=   r   bbbr6   ^)r   r   r   r)   r   r+   s    r   test_zero_or_morezLengthTests.test_zero_or_more8   s    Jws|,2226:Jws|,22591=E#J$$R(!, 	JuSz*004a8r   c                 N   | j                  t        t        d            j                  d      d       | j                  t        t        d            j                  d      d       | j                  t        t        d      d      j                  d      d       | j                  t	        t        d      dd      j                  d      d	       | j                  t	        t        d      dd      j                  d
      d       | j                  t        t        t        d      d      j                  d       | j                  t        t	        t        d      dd      j                  d       | j                  t        t        d            j                  d      d       y )NrB   r"   rF   r6   )minr#   )rJ   maxbbbb   bbbbbbr5   rG   r   )r   r   r   r)   r   r*   r   r   r+   s    r   test_one_or_morezLengthTests.test_one_or_moreA   s!   Igcl+11#6:Igcl+11%8!<Igcl288?CJws|:@@H!LJws|:@@JAN*i!&D&J&JDQ*j1!&L&R&RTXYIeCj)//5q9r   N)__name__
__module____qualname____doc__r   r,   r2   r:   r?   rD   rH   rO    r   r   r   r      s3    %HBX
C;9:r   r   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)		TreeTestszTests for building the right trees

    We have only to test successes here; failures (None-returning cases) are
    covered above.

    c           	      x    t        dd      }| j                  |j                  d      t        |ddd             y)zATest that leaf expressions like ``Literal`` make the right nodes.r    greetingnamer   r#   N)r   assertEqualr)   r   )r   hs     r   test_simple_nodezTreeTests.test_simple_nodeT   s2    G*-)47Aq+ABr   c                    t        t        dd      t        dd      d      }d}| j                  |j                  |      t	        ||dd	t	        |j
                  d   |dd
      t	        |j
                  d   |d
d	      g             y)z@Assert that ``Sequence`` produces nodes with the right children.heigh	greeting1rY   ho	greeting2dwarfheighhor   r%   r#   r"   childrenN)r   r   r[   r)   r   members)r   stexts      r   test_sequence_nodeszTreeTests.test_sequence_nodesY   s    WW;7T;7gGQad199UV<Y]_`bcFdFJ199UV<Y]_`bcFdFf )g 	hr   c                     t        t        dd      d      }d}| j                  |j                  |      t	        ||ddt	        |j
                  d   |dd      g             y	)
zG``OneOf`` should return its own node, wrapping the child that succeeds.rA   litrY   one_ofr9   r   r"   re   N)r	   r   r[   r)   r   rg   )r   ori   s      r   r:   zTreeTests.test_one_ofa   s]    '#E*:Qa1tQ*F, )- 	.r   c                 (   t        t        dd      d      }d}| j                  |j                  |      t	        ||ddt	        |j
                  d   |dd      g             d}| j                  |j                  |      t	        ||dd             y	)
zE``Optional`` should return its own node wrapping the succeeded child.rA   rl   rY   optr   r"   re   r=   N)r   r   r[   r)   r   rg   r   exprri   s      r   rD   zTreeTests.test_optionalh   s    %0u=D)4dAqa$1-L/ ,0 	1
 D)4dAq+ABr   c           	          t        t        d      d      }d}| j                  |j                  |      t	        ||dd             y)zATest the 0 case of ``ZeroOrMore``; it should still return a node.rA   zerorY   r=   r   N)r   r   r[   r)   r   rq   s      r   test_zero_or_more_zeroz TreeTests.test_zero_or_more_zerou   s;    '#,V4D)4dAq+ABr   c                     t        t        dd      d      }d}| j                  |j                  |      t	        ||ddt	        |j
                  d   |dd      g             y)	zGTest the 1 case of ``OneOrMore``; it should return a node with a child.rA   rl   rY   oner   r"   re   N)r   r   r[   r)   r   rg   rq   s      r   test_one_or_more_onezTreeTests.test_one_or_more_one{   s^    51>D)4dAqa$1-L/ ,0 	1r   N)
rP   rQ   rR   rS   r]   rj   r:   rD   ru   rx   rT   r   r   rV   rV   L   s)    C
h.CC1r   rV   c                       e Zd ZdZd Zy)
ParseTestsz Tests for the ``parse()`` methodc                     t        t        dd      d      }d}| j                  |j                  |      t	        ||ddt	        |j
                  d   |dd      t	        |j
                  d   |dd      g	             y
)zMake sure ``parse()`` returns the tree on success.

        There's not much more than that to test that we haven't already vetted
        above.

        rA   rl   rY   morer9   r   r8   r"   re   N)r   r   r[   parser   rg   rq   s      r   test_parse_successzParseTests.test_parse_success   sv     51?D)4dAqa$1-a$1-L/ ,0 	1r   N)rP   rQ   rR   rS   r~   rT   r   r   rz   rz      s
    *1r   rz   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	ErrorReportingTestsz Tests for reporting parse errorsc                 R   t        d      }d}	 |j                  |       y# t        $ r|}| j                  |j                  d       | j                  |j
                  |d          | j                  |j                  |       | j                  t        |      d       Y d}~yd}~ww xY w)zMake sure ``parse()`` fails and blames the
        rightward-progressing-most named Expression when an Expression isn't
        satisfied.

        Make sure ParseErrors have nice Unicode representations.

        z
            bold_text = open_parens text close_parens
            open_parens = "(("
            text = ~"[a-zA-Z]+"
            close_parens = "))"
            ((fred!!   close_parensz<Rule 'close_parens' didn't match at '!!' (line 1, column 7).N)r   r}   r   r[   posrr   ri   strr   grammarri   errors       r   test_inner_rule_succeedingz.ErrorReportingTests.test_inner_rule_succeeding   s        	iMM$ 	iUYY*UZZ)@AUZZ.SZ)ghh		is   ! 	B&A2B!!B&c                    t        d      }d}	 |j                  |       y# t        $ ra}| j                  |j                  d       | j                  |j
                  |d          | j                  |j                  |       Y d}~yd}~ww xY w)a]  Make sure rewinding the stack and trying an alternative (which
        progresses farther) from a higher-level rule can blame an expression
        within the alternative on failure.

        There's no particular reason I suspect this wouldn't work, but it's a
        more real-world example than the no-alternative cases already tested.

        a$  
            formatted_text = bold_text / weird_text
            bold_text = open_parens text close_parens
            weird_text = open_parens text "!!" bork
            bork = "bork"
            open_parens = "(("
            text = ~"[a-zA-Z]+"
            close_parens = "))"
            r      borkNr   r}   r   r[   r   rr   ri   r   s       r   test_rewindingz"ErrorReportingTests.test_rewinding   s~        	/MM$ 	/UYY*UZZ9UZZ..	/s   ! 	BABBc                    t        d      }	 |j                  d       y# t        $ ra}| j                  |j                  d       | j                  |j
                  |d          | j                  |j                  d       Y d}~yd}~ww xY w)zMake sure ParseErrors have sane printable representations even if we
        never succeeded in matching any named expressions.zbork = "bork"snorkr   r   Nr   r   r   r   s      r   test_no_named_rule_succeedingz1ErrorReportingTests.test_no_named_rule_succeeding   ss     -.	2MM'" 	2UYY*UZZ9UZZ11	2s    	B	ABB	c                     t        d      }	 |j                  d       y# t        $ r%}| j                  t	        |      d       Y d}~yd}~ww xY w)zpMake sure ``parse()`` reports where we started failing to match,
        even if a partial match was successful.z!sequence = "chitty" (" " "bang")+zchitty bangbangzRule 'sequence' matched in its entirety, but it didn't consume all the text. The non-matching portion of the text begins with 'bang' (line 1, column 12).N)r   r}   r   r[   r   r   s      r   test_parse_with_leftoversz-ErrorReportingTests.test_parse_with_leftovers   sY     BC	uMM+,# 	uS tu u	u    	AAAc                     t        d      }	 |j                  d       y# t        $ r%}| j                  t	        |      d       Y d}~yd}~ww xY w)zNamed rules should be used in error messages in favor of anonymous
        ones, even if those are rightward-progressing-more, and even if the
        failure starts at position 0.zstarts_with_a = &"a" ~"[a-z]+"burpz?Rule 'starts_with_a' didn't match at 'burp' (line 1, column 1).N)r   r}   r   r[   r   r   s      r   test_favoring_named_rulesz-ErrorReportingTests.test_favoring_named_rules   sK     ?@	lMM&! 	lSZ)jkk	lr   c                     t        d      }	 |j                  d       y# t        $ r3}| j                  t	        |      j                  d             Y d}~yd}~ww xY w)z7Make sure we got the line and column computation right.zi
            whee_lah = whee "\n" lah "\n"
            whee = "whee"
            lah = "lah"
            zwhee
lahGOOz)didn't match at 'GOO' (line 2, column 4).N)r   r}   r   
assertTruer   endswithr   s      r   test_line_and_columnz(ErrorReportingTests.test_line_and_column   sV      
	cMM.) 	c OOCJ//0`abb	cs    	A)AAN)
rP   rQ   rR   rS   r   r   r   r   r   r   rT   r   r   r   r      s'    *i./4	2ulcr   r   c                   (    e Zd ZdZd Zd Zd Zd Zy)RepresentationTestsz5Tests for str(), unicode(), and repr() of expressionsc                 N    t        d      }t        |j                  d             y)z:Make sure matched unicode strings don't crash ``__str__``.zstring = ~r"\S+"uu   中文N)r   r   r}   )r   r   s     r   test_unicode_crashz&RepresentationTests.test_unicode_crash   s    ./GMM(#$r   c                 "    t        t               y)zSmoke-test the conversion of expressions to bits of rules.

        A slightly more comprehensive test of the actual values is in
        ``GrammarTests.test_unicode``.

        N)r   r   r+   s    r   test_unicodez RepresentationTests.test_unicode  s     	Lr   c                    | j                  t        t        d            d       | j                  t        t        d            d       | j                  t        t        d            d       | j                  t        t        d            d       | j                  t        t        d	            d
       | j                  t        t        d            d       | j                  t        t        d            d       | j                  t        t        d            d       | j                  t        t        d            d       | j                  t        t        d            d       y)zZMake sure converting an expression to unicode doesn't strip
        parenthesis.

        z"foo = "bar" ("baz" "eggs")* "spam"z"foo = 'bar' ('baz' 'eggs')* 'spam'z&foo = "bar" ("baz" "eggs"){2,4} "spam"z&foo = 'bar' ('baz' 'eggs'){2,4} 'spam'z%foo = "bar" ("baz" "eggs"){2,} "spam"z%foo = 'bar' ('baz' 'eggs'){2,} 'spam'z%foo = "bar" ("baz" "eggs"){1,} "spam"z"foo = 'bar' ('baz' 'eggs')+ 'spam'z%foo = "bar" ("baz" "eggs"){,4} "spam"z%foo = 'bar' ('baz' 'eggs'){,4} 'spam'z&foo = "bar" ("baz" "eggs"){0,1} "spam"z"foo = 'bar' ('baz' 'eggs')? 'spam'z%foo = "bar" ("baz" "eggs"){0,} "spam"z#foo = "bar" ("baz" / "eggs") "spam"z#foo = 'bar' ('baz' / 'eggs') 'spam'z"foo = "bar" &("baz" "eggs") "spam"z"foo = 'bar' &('baz' 'eggs') 'spam'z$foo = ("bar" "baz") / ("baff" "bam")z$foo = ('bar' 'baz') / ('baff' 'bam')Nr[   r   r   r+   s    r   test_unicode_keep_parensz,RepresentationTests.test_unicode_keep_parens
  s=    	W%IJK=	? 	W%MNOA	CW%LMN@	BW%LMN=	?W%LMN@	BW%MNO=	?W%LMN=	? 	W%JKL>	@ 	W%IJK=	? 	W%KLM?	Ar   c                 L    | j                  t        t        d            d       y)z
        Make sure there are no surrounding parens around the entire
        right-hand side of an expression (as they're unnecessary).

        zfoo = ("foo" ("bar" "baz"))zfoo = 'foo' ('bar' 'baz')Nr   r+   s    r   test_unicode_surrounding_parensz3RepresentationTests.test_unicode_surrounding_parens-  s"     	W%BCD4	6r   N)rP   rQ   rR   rS   r   r   r   r   rT   r   r   r   r      s    ?%
!AF6r   r   c                       e Zd ZdZd Zy)
SlotsTestszTests to do with __slots__c                      G d dt               } |       }| j                  |j                  i        | j                  |j                  d       y)a  Make sure a subclass of a __slots__-less class can introduce new
        slots itself.

        This isn't supposed to work, according to the language docs:

            When inheriting from a class without __slots__, the __dict__
            attribute of that class will always be accessible, so a __slots__
            definition in the subclass is meaningless.

        But it does.

        c                       e Zd ZdgZd Zy))SlotsTests.test_subclassing.<locals>.Smoosmooc                     d| _         y )Nr   )r   r+   s    r   __init__z2SlotsTests.test_subclassing.<locals>.Smoo.__init__J  s	    "	r   N)rP   rQ   rR   	__slots__r   rT   r   r   Smoor   G  s    I#r   r   r   N)r   r[   __dict__r   )r   r   r   s      r   test_subclassingzSlotsTests.test_subclassing:  s?    	#: 	# v+F+r   N)rP   rQ   rR   rS   r   rT   r   r   r   r   7  s
    $,r   r   N)unittestr   parsimonious.exceptionsr   r   parsimonious.expressionsr   r   r   r	   r
   r   r   r   r   r   parsimonious.grammarr   r   parsimonious.nodesr   r   rV   rz   r   r   r   rT   r   r   <module>r      ss     D_ _ _ 6 #>:( >:B41 41t1 1"_c( _cD;6( ;6|, ,r   