3
h5                 @   sJ   d dl mZ d dlZd dlZddlmZmZmZmZm	Z	 G dd dZ
dS )    )contextmanagerN   )ParserElementParseExceptionKeyword__diag__
__compat__c               @   sf   e Zd ZdZG dd dZG dd dZedeej	e
 ej	e
 eeej	e ej	e ed	d
dZdS )pyparsing_testzB
    namespace class for classes useful in writing unit tests
    c               @   s@   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S )z&pyparsing_test.reset_pyparsing_contexta  
        Context manager to be used when writing unit tests that modify pyparsing config values:
        - packrat parsing
        - bounded recursion parsing
        - default whitespace characters.
        - default keyword characters
        - literal string auto-conversion class
        - __diag__ settings

        Example::

            with reset_pyparsing_context():
                # test that literals used to construct a grammar are automatically suppressed
                ParserElement.inlineLiteralsUsing(Suppress)

                term = Word(alphas) | Word(nums)
                group = Group('(' + term[...] + ')')

                # assert that the '()' characters are not included in the parsed tokens
                self.assertParseAndCheckList(group, "(abc 123 def)", ['abc', '123', 'def'])

            # after exiting context manager, literals are converted to Literal expressions again
        c             C   s
   i | _ d S )N)_save_context)self r   6/tmp/pip-build-fibhr3ey/pyparsing/pyparsing/testing.py__init__/   s    z/pyparsing_test.reset_pyparsing_context.__init__c             C   s   t j| jd< tj| jd< t j| jd< t j| jd< t j| jd< t jrRt jj	| jd< n
d | jd< t j
| jd< t j| jd< d	d
 tjD | jd< dtji| jd< | S )Ndefault_whitespacedefault_keyword_charsliteral_string_classverbose_stacktracepackrat_enabledpackrat_cache_sizepackrat_parserecursion_enabledc             S   s   i | ]}t t||qS r   )getattrr   ).0namer   r   r   
<dictcomp>H   s   z?pyparsing_test.reset_pyparsing_context.save.<locals>.<dictcomp>r   collect_all_And_tokensr   )r   DEFAULT_WHITE_CHARSr
   r   DEFAULT_KEYWORD_CHARS_literalStringClassr   _packratEnabledpackrat_cachesize_parse_left_recursion_enabledr   Z
_all_namesr   r   )r   r   r   r   save2   s    
z+pyparsing_test.reset_pyparsing_context.savec             C   s   t j| jd kr t j| jd  | jd t _| jd t_t j| jd  x.| jd j D ]\}}|rjt	j
nt	j| qXW dt _| jd rt j| jd  n| jd	 t _| jd
 t _| jd t_| S )Nr   r   r   r   r   Fr   r   r   r   r   )r   r   r
   Zset_default_whitespace_charsr   r   r   inlineLiteralsUsingitemsr   enabledisabler   Zenable_packratr"   r#   r   r   )r   r   valuer   r   r   restoreR   s$    
z.pyparsing_test.reset_pyparsing_context.restorec             C   s   t |  }|jj| j |S )N)typer
   update)r   retr   r   r   copys   s    
z+pyparsing_test.reset_pyparsing_context.copyc             C   s   | j  S )N)r$   )r   r   r   r   	__enter__x   s    z0pyparsing_test.reset_pyparsing_context.__enter__c             G   s   | j   d S )N)r*   )r   argsr   r   r   __exit__{   s    z/pyparsing_test.reset_pyparsing_context.__exit__N)
__name__
__module____qualname____doc__r   r$   r*   r.   r/   r1   r   r   r   r   reset_pyparsing_context   s    !r6   c               @   sL   e Zd ZdZdddZdddZddd	Zdd
dZee	ddfddZ
dS )z&pyparsing_test.TestParseResultsAssertszk
        A mixin class to add parse results assertion methods to normal unittest.TestCase classes.
        Nc             C   s<   |dk	r| j ||j |d |dk	r8| j ||j |d dS )z
            Unit test assertion to compare a :class:`ParseResults` object with an optional ``expected_list``,
            and compare any defined results names with an optional ``expected_dict``.
            N)msg)ZassertEqualas_listZas_dict)r   resultexpected_listexpected_dictr7   r   r   r   assertParseResultsEquals   s    z?pyparsing_test.TestParseResultsAsserts.assertParseResultsEqualsTc             C   s@   |j |dd}|r t|j  nt|j  | j|||d dS )z
            Convenience wrapper assert to test a parser element and input string, and assert that
            the resulting ``ParseResults.asList()`` is equal to the ``expected_list``.
            T)Z	parse_all)r:   r7   N)parse_stringprintdumpr8   r<   )r   exprtest_stringr:   r7   verboser9   r   r   r   assertParseAndCheckList   s
    z>pyparsing_test.TestParseResultsAsserts.assertParseAndCheckListc             C   s@   |j |dd}|r t|j  nt|j  | j|||d dS )z
            Convenience wrapper assert to test a parser element and input string, and assert that
            the resulting ``ParseResults.asDict()`` is equal to the ``expected_dict``.
            T)parseAll)r;   r7   N)r=   r>   r?   r8   r<   )r   r@   rA   r;   r7   rB   r9   r   r   r   assertParseAndCheckDict   s
    z>pyparsing_test.TestParseResultsAsserts.assertParseAndCheckDictc             C   s0  |\}}|dkr.| j ||dk	r"|ndd dS dd t||D }x|D ]\}}}	tdd |	D d}
tdd |	D d}|dk	r| j||
p|d	 t|tr|W dQ R X qHtd
d |	D d}tdd |	D d}||fdk r| j||||
p|d qHtd| qHW | j ||dk	r$|ndd dS )ah  
            Unit test assertion to evaluate output of ``ParserElement.runTests()``. If a list of
            list-dict tuples is given as the ``expected_parse_results`` argument, then these are zipped
            with the report tuples returned by ``runTests`` and evaluated using ``assertParseResultsEquals``.
            Finally, asserts that the overall ``runTests()`` success value is ``True``.

            :param run_tests_report: tuple(bool, [tuple(str, ParseResults or Exception)]) returned from runTests
            :param expected_parse_results (optional): [tuple(str, list, dict, Exception)]
            Nzfailed runTests)r7   c             S   s   g | ]\}}||fqS r   r   )r   Zrptexpectedr   r   r   
<listcomp>   s   zOpyparsing_test.TestParseResultsAsserts.assertRunTestResults.<locals>.<listcomp>c             s   s   | ]}t |tr|V  qd S )N)
isinstancestr)r   expr   r   r   	<genexpr>   s    zNpyparsing_test.TestParseResultsAsserts.assertRunTestResults.<locals>.<genexpr>c             s   s&   | ]}t |trt|tr|V  qd S )N)rH   r+   
issubclass	Exception)r   rJ   r   r   r   rK      s   )expected_exceptionr7   c             s   s   | ]}t |tr|V  qd S )N)rH   list)r   rJ   r   r   r   rK      s    c             s   s   | ]}t |tr|V  qd S )N)rH   dict)r   rJ   r   r   r   rK      s    )r:   r;   r7   zno validation for )NN)Z
assertTruezipnextassertRaisesrH   rM   r<   r>   )r   Zrun_tests_reportZexpected_parse_resultsr7   Zrun_test_successZrun_test_resultsZmergedrA   r9   rF   Zfail_msgrN   r:   r;   r   r   r   assertRunTestResults   s>    
z;pyparsing_test.TestParseResultsAsserts.assertRunTestResultsc          	   c   sd   |d k	r@t |trtj|}| j|||d}|V  W d Q R X n | j||d}|V  W d Q R X d S )N)r7   )rH   rI   reescapeassertRaisesRegexrS   )r   exc_typeZexpected_msgr7   ctxr   r   r   assertRaisesParseException   s    

zApyparsing_test.TestParseResultsAsserts.assertRaisesParseException)NNN)NT)NT)NN)r2   r3   r4   r5   r<   rC   rE   rT   r   r   rZ   r   r   r   r   TestParseResultsAsserts~   s   



Ar[   NT|)s
start_lineend_lineexpand_tabseol_markmark_spacesmark_controlreturnc                s4  |r| j  } |dk	rtjt|}|dkr`dd ttddtddD }d	|d
< tj|}d n0t|tjfddttddd
g D }| j	|} |dk	r|dkr|dkrtjddd}| j	|} n| j
d|} |dkrd}|dkrt| }t|t| }ttd||}|dkr4| j |d | }	n dd | jd|d | D }	|	s^dS tt|tdd |	D }
dd  }|
dkr|djdd tt|
d dD  d }nd}|| djdd t|
 d  D  d }|d|
 d    d }|| dj fddt|	|d D  d S )!u	  
        Helpful method for debugging a parser - prints a string with line and column numbers.
        (Line and column numbers are 1-based.)

        :param s: tuple(bool, str - string to be printed with line and column numbers
        :param start_line: int - (optional) starting line number in s to print (default=1)
        :param end_line: int - (optional) ending line number in s to print (default=len(s))
        :param expand_tabs: bool - (optional) expand tabs to spaces, to match the pyparsing default
        :param eol_mark: str - (optional) string to mark the end of lines, helps visualize trailing spaces (default="|")
        :param mark_spaces: str - (optional) special character to display in place of spaces
        :param mark_control: str - (optional) convert non-printing control characters to a placeholding
                                 character; valid values:
                                 - "unicode" - replaces control chars with Unicode symbols, such as "␍" and "␊"
                                 - any single character string - replace control characters with given string
                                 - None (default) - string is displayed as-is

        :return: str - input string with leading line numbers and column number headers
        Nunicodec             S   s   i | ]\}}||qS r   r   )r   cur   r   r   r     s   z4pyparsing_test.with_line_numbers.<locals>.<dictcomp>r   !   i $  i3$  i!$      c                s   i | ]
} |qS r   r   )r   rf   )ord_mark_controlr   r   r   %  s         i	$  i#$  )	   rl   r   c             S   s   g | ]}|d  qS )u   ␊r   )r   liner   r   r   rG   8  s    z4pyparsing_test.with_line_numbers.<locals>.<listcomp>u   ␊c             s   s   | ]}t |V  qd S )N)len)r   ro   r   r   r   rK   =  s    z3pyparsing_test.with_line_numbers.<locals>.<genexpr>c   c             s   s&   | ]}d d  |d d  V  qdS )rm   rq   r   d   Nr   )r   ir   r   r   rK   C  s   rr   
c             s   s    | ]}d |d d  V  qdS )z	         r   
   Nr   )r   rs   r   r   r   rK   M  s    ru   Z
1234567890c             3   s,   | ]$\}}| d d|   V  qdS )d:Nr   )r   rs   ro   )ra   lineno_widthr   r   rK   U  s   )start)
expandtabstypingcastrI   rQ   range	maketransordrO   	translatereplacerp   minmax
splitlinessplitjoin	enumerate)r]   r^   r_   r`   ra   rb   rc   Ztranstable_mapZtblZs_linesZmax_line_lenZleadZheader0Zheader1Zheader2r   )ra   rx   rk   r   with_line_numbers   sN    
$

 
,,z pyparsing_test.with_line_numbers)NNTr\   NN)r2   r3   r4   r5   r6   r[   staticmethodrI   r{   Optionalintboolr   r   r   r   r   r	      s   h}     (r	   )
contextlibr   rU   r{   corer   r   r   r   r   r	   r   r   r   r   <module>   s   	