a
    Cg7                     @   s  d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
mZmZmZ ddlmZ ddlmZ G d	d
 d
eZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd  d eZG d!d" d"eZG d#d$ d$eZG d%d& d&eZ g d'Z!G d(d) d)eZ"G d*d+ d+eZ#dS ),a8  Tests for Beautiful Soup's tree traversal methods.

The tree traversal methods are the main advantage of using Beautiful
Soup over just using a parser.

Different parsers will build different Beautiful Soup trees given the
same markup, but all Beautiful Soup trees can be traversed with the
methods tested here.
    N)BeautifulSoup)builder_registry)!AttributeResemblesVariableWarningCDataCommentNavigableStringTag)SoupStrainer   )SoupTestc                   @   sH   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d Z
dS )TestFindz&Basic tests of the find() method.
    c                 C   s"   |  d}|djdksJ d S )Nz <a>1</a><b>2</b><a>3</a><b>4</b>b2)soupfindstringselfr    r   R/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/bs4/tests/test_tree.pytest_find_tag"   s    
zTestFind.test_find_tagc                 C   s"   |  d}|jdddksJ d S )Nu   <h1>Räksmörgås</h1>   Räksmörgåsr   )r   r   r   r   r   r   test_unicode_text_find&   s    
zTestFind.test_unicode_text_findc                 C   s,   |  d}t| d|jddjks(J d S )Nu&   <h1 id="Räksmörgås">here it is</h1>z
here it isr   id)r   strr   textr   r   r   r   test_unicode_attribute_find*   s    
z$TestFind.test_unicode_attribute_findc                 C   s"   |  d}dt| ksJ dS )z)Test an optimization that finds all tags.<a>foo</a><b>bar</b>   Nr   lenfind_allr   r   r   r   test_find_everything/   s    
zTestFind.test_find_everythingc                 C   s$   |  d}dt|dks J dS )z;Test an optimization that finds all tags with a given name.z<a>foo</a><b>bar</b><a>baz</a>r    aNr!   r   r   r   r   test_find_everything_with_name4   s    
z'TestFind.test_find_everything_with_namec                 C   sP   |  d}d| jksJ d|d jks4J d|d jksLJ d S )Nz<div></div><p></p>divpr   r   namefind_previous_siblingfind_next_siblingr   r   r   r   test_find_with_no_arguments9   s    
z$TestFind.test_find_with_no_argumentsc                 C   sP   |  d}d| jksJ d|d jks4J d|d jksLJ d S )Nz"text<div>text</div>text<p>text</p>r'   r(   r)   r   r   r   r   +test_find_with_no_arguments_only_finds_tags?   s    
z4TestFind.test_find_with_no_arguments_only_finds_tagsN)__name__
__module____qualname____doc__r   r   r   r$   r&   r-   r.   r   r   r   r   r      s   r   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 )TestFindAllz%Basic tests of the find_all() method.c                 C   sX   |  d}dt|j ks J dt|d ks:J dt|d ksTJ d S )Nz/<body>text<div>text</div>text<p>text</p></body>r    r
   r(   r'   )r   r"   bodyr#   r   find_previous_siblingsfind_next_siblingsr   r   r   r   /test_find_all_with_no_arguments_only_finds_tagsI   s    
z;TestFindAll.test_find_all_with_no_arguments_only_finds_tagsc                 C   sv   |  d}|jdddgks J |jddgdddgks<J |jtddg dksZJ |jddg dksrJ dS )	z'You can search the tree for text nodes.u   <html>Foo<b>bar</b>»</html>barr   Fooz.*)r9   r8      »TN)r   r#   recompiler   r   r   r   test_find_all_text_nodesO   s
    
z$TestFindAll.test_find_all_text_nodesc                 C   st   |  d}| |jdddg d | |jddddg | |jdddg d	 | |jdd
dg d	 dS )z7You can limit the number of items returned by find_all.z(<a>1</a><a>2</a><a>3</a><a>4</a><a>5</a>r%      limit)1r   3r
   rA   
   )rA   r   rB   45r   Nr   assert_selectsr#   r   r   r   r   test_find_all_limit\   s
    
zTestFindAll.test_find_all_limitc                 C   s:   |  d}| |ddddg | |jdddg d S )	Nz!<a>1</a><b>2<a id='foo'>3</a></b>r%   r
   r?   rA   foor   rB   )r   rG   r   r   r   r   r   %test_calling_a_tag_is_calling_findallf   s    
z1TestFindAll.test_calling_a_tag_is_calling_findallc                 C   s   |  d}g }|| tjddL}g ||ks8J |\}|jtksLJ t|j}|dksbJ W d    n1 sv0    Y  d S )N<a></a>TrecordzLIgnoring nested list [[...]] to avoid the possibility of infinite recursion.)	r   appendwarningscatch_warningsr#   filename__file__r   message)r   r   selfrefwwarningmsgr   r   r   Ttest_find_all_with_self_referential_data_structure_does_not_cause_infinite_recursionk   s    


z`TestFindAll.test_find_all_with_self_referential_data_structure_does_not_cause_infinite_recursionc                 C   sX   |  d}|d}t|ds"J |d}t|ds:J |jdd}t|dsTJ dS )z%All find_all calls return a ResultSetrK   r%   sourceTrI   r   N)r   r#   hasattrr   r   resultr   r   r   test_find_all_resultset   s    


z#TestFindAll.test_find_all_resultsetN)
r/   r0   r1   r2   r7   r=   rH   rJ   rX   r]   r   r   r   r   r3   F   s   
r3   c                   @   s   e Zd Zdd ZdS )TestFindAllBasicNamespacesc                 C   s<   |  d}d|djksJ d|jddidjks8J d S )Nz0<mathml:msqrt>4</mathml:msqrt><a svg:fill="red">rD   zmathml:msqrtr%   zsvg:fillZredattrs)r   r   r   r*   r   r   r   r   test_find_by_namespaced_name   s    
z7TestFindAllBasicNamespaces.test_find_by_namespaced_nameN)r/   r0   r1   ra   r   r   r   r   r^      s   r^   c                   @   sn   e Zd ZdZddddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd ZdS )TestFindAllByNamez&Test ways of finding tags by tag name.Nreturnc                 C   s   |  d| _d S )Nz<a>First tag.</a>
                                  <b>Second tag.</b>
                                  <c>Third <a>Nested tag.</a> tag.</c>r   treer   r   r   r   setup_method   s    zTestFindAllByName.setup_methodc                 C   s   |  | jdddg d S Nr%   
First tag.Nested tag.rG   rf   r#   rg   r   r   r   test_find_all_by_tag_name   s    z+TestFindAllByName.test_find_all_by_tag_namec                 C   s\   |  | jjddddg |  | jjdddddg |  | jjdtddddg d S )Nr%   rj   r   Trk   tagrG   rf   r#   r;   r<   rg   r   r   r   test_find_all_by_name_and_text   s    z0TestFindAllByName.test_find_all_by_name_and_textc                 C   s   |  | jjddg d S )Nr%   rk   )rG   rf   cr#   rg   r   r   r   !test_find_all_on_non_root_element   s    z3TestFindAllByName.test_find_all_on_non_root_elementc                 C   s   |  | dddg d S ri   )rG   rf   rg   r   r   r   %test_calling_element_invokes_find_all   s    z7TestFindAllByName.test_calling_element_invokes_find_allc                 C   s    |  | jtdddg d S ri   )rG   rf   r#   r	   rg   r   r   r   test_find_all_by_tag_strainer   s    z/TestFindAllByName.test_find_all_by_tag_strainerc                 C   s    |  | jddgg d d S )Nr%   r   rj   zSecond tag.rk   rl   rg   r   r   r   test_find_all_by_tag_names   s    z,TestFindAllByName.test_find_all_by_tag_namesc                 C   s"   |  | jdddg d d S )NT)r%   r   ru   rl   rg   r   r   r   test_find_all_by_tag_dict   s    z+TestFindAllByName.test_find_all_by_tag_dictc                 C   s"   |  | jtdg d d S )Nz^[ab]$ru   ro   rg   r   r   r   test_find_all_by_tag_re   s    z)TestFindAllByName.test_find_all_by_tag_rec                 C   s,   dd }|  d}| ||ddg d S )Nc                 S   s   | j | dkS Nr   )r*   getrn   r   r   r   id_matches_name   s    zRTestFindAllByName.test_find_all_with_tags_matching_method.<locals>.id_matches_namez<a id="a">Match 1.</a>
                            <a id="1">Does not match.</a>
                            <b id="b">Match 2.</a>zMatch 1.zMatch 2.rF   )r   r|   rf   r   r   r   'test_find_all_with_tags_matching_method   s    
z9TestFindAllByName.test_find_all_with_tags_matching_methodc                 C   sx   |  d}|dd}|dtd}|dddg\}}d|jksJJ d|jksXJ d|jksfJ d|jkstJ d S )NzH<div class='a b'>1</div><div class='a c'>2</div><div class='a d'>3</div>r'   za dza brB   rA   )r   r   r;   r<   r#   r   )r   r   Zr1Zr2Zr3Zr4r   r   r   %test_find_with_multi_valued_attribute   s    z7TestFindAllByName.test_find_with_multi_valued_attribute)r/   r0   r1   r2   rh   rm   rp   rr   rs   rt   rv   rw   rx   r}   r~   r   r   r   r   rb      s   rb   c                   @   s   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!S )"TestFindAllByAttributec                 C   s&   |  d}| |jddddg d S )Nz
                         <a id="first">Matching a.</a>
                         <a id="second">
                          Non-matching <b id="first">Matching b.</b>a.
                         </a>firstr   zMatching a.zMatching b.rF   r   rf   r   r   r   test_find_all_by_attribute_name   s    
z6TestFindAllByAttribute.test_find_all_by_attribute_namec                 C   st   d d}d d}| |}|jg|j|dks6J |jg|j|ddksTJ |jgspJ |j|dgdd S )Nu   םולשutf8u   <a title="םולש"></a>)titlezsomething else)encoder   r%   r#   decode)r   Zpeacedatar   r   r   r   %test_find_all_by_utf8_attribute_value   s    


z<TestFindAllByAttribute.test_find_all_by_utf8_attribute_valuec                 C   sX   |  d}| |jdddg | |jddiddg | |jdd	idd
g d S )Na0  
                         <a name="name1" class="class1">Name match.</a>
                         <a name="name2" class="class2">Class match.</a>
                         <a name="name3" class="class3">Non-match.</a>
                         <name1>A tag called 'name1'.</name1>
                         Zname1r*   zA tag called 'name1'.r*   r_   zName match.classZclass2zClass match.rF   r   r   r   r   test_find_all_by_attribute_dict   s    
z6TestFindAllByAttribute.test_find_all_by_attribute_dictc                 C   s   |  d}| |jddddg | |jddddg | |jdd	ddg | |dddg | |jdd
ddg | |dddg | |dd	dg d S )Nz
                         <a class="1">Class 1.</a>
                         <a class="2">Class 2.</a>
                         <b class="1">Class 1.</b>
                         <c class="3 4">Class 3 and 4.</c>
                         r%   rA   class_zClass 1.rq   rB   zClass 3 and 4.rD   r_   rF   r   r   r   r   test_find_all_by_class  s    
	z-TestFindAllByAttribute.test_find_all_by_classc                 C   st   |  d}|jdtdd}| |dg |jdtdd}| |dg |jdtdd}| |dg d S )Nz#<gar class='foo bar'>Found it</gar>Zgaror   Found itr%   zo b)r   r#   r;   r<   rG   )r   rf   fr   r   r   0test_find_by_class_when_multiple_classes_present  s    
zGTestFindAllByAttribute.test_find_by_class_when_multiple_classes_presentc                 C   sd   |  d}| |dtddg dd }| |d|g  dd }| |d|dg d S )	Nz<a class='bar'>Found it</a>r%   bar   c                 S   s   t | dkS Nr>   r"   valuer   r   r   big_attribute_value/  s    znTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.big_attribute_valuec                 S   s   t | dkS r   r   r   r   r   r   small_attribute_value4  s    zpTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.small_attribute_valuer   rG   r#   r;   r<   )r   r   r   r   r   r   r   :test_find_all_with_non_dictionary_for_attrs_finds_by_class*  s    
zQTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_classc                 C   s   |  d}|d\}}||gs0J |dd|gsFJ |dd|g|jdddks^J |g|ddkstJ g |ddksJ d S )Nz*<a class="foo bar"></a><a class="foo"></a>r%   rI   r8   zfoo barr   zbar foor   r#   )r   r   r%   Za2r   r   r   :test_find_all_with_string_for_attrs_finds_multiple_classes9  s    
zQTestFindAllByAttribute.test_find_all_with_string_for_attrs_finds_multiple_classesc                 C   s0   |  d}tddid}| ||dg d S )Nzi
                         <a id="first">Match.</a>
                         <a id="second">Non-match.</a>r   r   r_   zMatch.)r   r	   rG   r#   )r   rf   Zstrainerr   r   r   'test_find_all_by_attribute_soupstrainerE  s    
z>TestFindAllByAttribute.test_find_all_by_attribute_soupstrainerc                 C   s&   |  d}| |jdd ddg d S )N<a id="1">ID present.</a>
                            <a>No ID present.</a>
                            <a id="">ID is empty.</a>r%   r   zNo ID present.rF   r   r   r   r   $test_find_all_with_missing_attributeM  s    
z;TestFindAllByAttribute.test_find_all_with_missing_attributec                 C   s&   |  d}| |jddddg d S )Nr   Tr   zID present.zID is empty.rF   r   r   r   r   $test_find_all_with_defined_attributeU  s    
z;TestFindAllByAttribute.test_find_all_with_defined_attributec                 C   s>   |  d}ddg}| |jdd| | |jdd| d S )Nz[<a id=1>Unquoted attribute.</a>
                            <a id="1">Quoted attribute.</a>zUnquoted attribute.zQuoted attribute.r
   r   rA   rF   )r   rf   expectedr   r   r   $test_find_all_with_numeric_attribute]  s    
z;TestFindAllByAttribute.test_find_all_with_numeric_attributec                 C   s>   |  d}| |jg ddddg | |jg dg  d S )Nz<a id="1">1</a>
                            <a id="2">2</a>
                            <a id="3">3</a>
                            <a>No ID.</a>)rA   rB   rD   r   rA   rB   rF   r   r   r   r   (test_find_all_with_list_attribute_valuesf  s    
z?TestFindAllByAttribute.test_find_all_with_list_attribute_valuesc                 C   s,   |  d}| |jtddddg d S )Nz<a id="a">One a.</a>
                            <a id="aa">Two as.</a>
                            <a id="ab">Mixed as and bs.</a>
                            <a id="b">One b.</a>
                            <a>No ID.</a>z^a+$r   zOne a.zTwo as.r   r   r   r   r   5test_find_all_with_regular_expression_attribute_valuer  s    
zLTestFindAllByAttribute.test_find_all_with_regular_expression_attribute_valuec                 C   sB   |  d}|j}|g|jdddks(J g |jdddks>J d S )Nz<b>foo</b><b>bar</b><a>foo</a>r%   rI   r   r8   r   r%   r#   r   r   r%   r   r   r   'test_find_by_name_and_containing_string~  s    
z>TestFindAllByAttribute.test_find_by_name_and_containing_stringc                 C   s*   |  d}|d|jdddks&J d S )Nz"<a>foo</a><a><b><c>foo</c></b></a>r%   rI   r   r   r   r   r   r   =test_find_by_name_and_containing_string_when_string_is_buried  s    
zTTestFindAllByAttribute.test_find_by_name_and_containing_string_when_string_is_buriedc                 C   sB   |  d}|j}|g|jdddks(J g |jdddks>J d S )Nz"<b id="1">foo</b><a id="2">foo</a>r    rI   )r   r   r
   r8   r   r   r   r   r   ,test_find_by_attribute_and_containing_string  s    
zCTestFindAllByAttribute.test_find_by_attribute_and_containing_stringN)r/   r0   r1   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s    
	r   c                   @   s   e Zd ZdZdd ZdS )
TestSmoothzTest Tag.smooth.c                 C   s  |  d}|j}|d |d |td |td |d |  }t||d}|d |d	 || d |jju sJ d
t|j	ksJ |
  dt|j	ksJ d|j	d ksJ d|jjksJ d|j	d ksJ d|j	d ksJ d S )Nz<div>a</div>r   rq   z	Comment 1z	Comment 2dspanrA   r         abcr   Z12r
   r    )r   r'   rN   r   default_builderr   r   r   r"   contentsZsmooth)r   r   r'   builderr   r   r   r   test_smooth  s(    






zTestSmooth.test_smoothN)r/   r0   r1   r2   r   r   r   r   r   r     s   r   c                   @   s   e Zd ZdZdd ZdS )	TestIndexzTest Tag.indexc                 C   sn   |  d}|j}t|jD ]\}}|||ksJ qtt |d W d    n1 s`0    Y  d S )Nah  <div>
                            <a>Identical</a>
                            <b>Not identical</b>
                            <a>Identical</a>

                            <c><d>Identical with child</d></c>
                            <b>Also not identical</b>
                            <c><d>Identical with child</d></c>
                            </div>r
   )r   r'   	enumerater   indexpytestraises
ValueError)r   rf   r'   ielementr   r   r   
test_index  s    
	zTestIndex.test_indexN)r/   r0   r1   r2   r   r   r   r   r   r     s   r   c                   @   sf   e Zd ZdZddddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd ZdS )TestParentOperationsz;Test navigation and searching through an element's parents.Nrc   c                 C   s   |  d| _| jj| _d S )Na<  <ul id="empty"></ul>
                                 <ul id="top">
                                  <ul id="middle">
                                   <ul id="bottom">
                                    <b id="start">Start here</b>
                                   </ul>
                                  </ul>)r   rf   r   startrg   r   r   r   rh     s    z!TestParentOperations.setup_methodc                 C   sF   | j jd dksJ | j jjd dks*J | j jjjd dksBJ d S )Nr   bottommiddletop)r   parentrg   r   r   r   test_parent  s    z TestParentOperations.test_parentc                 C   s    | j jd }|j| j ksJ d S )Nr   )rf   r   r   )r   Ztop_tagr   r   r   %test_parent_of_top_tag_is_soup_object  s    z:TestParentOperations.test_parent_of_top_tag_is_soup_objectc                 C   s   d | j ju sJ d S N)rf   r   rg   r   r   r   test_soup_object_has_no_parent  s    z3TestParentOperations.test_soup_object_has_no_parentc                 C   sL   |  | jdg d |  | jjddddg | jjddg ksHJ d S )Nulr   r   r   r   r   r   )assert_selects_idsr   find_parentsrg   r   r   r   test_find_parents  s
    z&TestParentOperations.test_find_parentsc                 C   s6   | j jdddd dksJ | j jddd u s2J d S )Nr   r   r   r   r   )r   find_parentrg   r   r   r   test_find_parent  s    z%TestParentOperations.test_find_parentc                 C   s"   | j jdd}|jjdksJ d S )N
Start herer   r   )rf   r   r   r*   r   r   r   r   r   test_parent_of_text_element  s    z0TestParentOperations.test_parent_of_text_elementc                 C   s(   | j jdd}|dd dks$J d S )Nr   r   r   r   r   )rf   r   r   r   r   r   r   test_text_element_find_parent  s    z2TestParentOperations.test_text_element_find_parentc                 C   s&   dd | j jD }|g dks"J d S )Nc                 S   s&   g | ]}|d urd|j v r|d qS ry   r_   .0r   r   r   r   
<listcomp>   s   z>TestParentOperations.test_parent_generator.<locals>.<listcomp>r   )r   parents)r   r   r   r   r   test_parent_generator  s    z*TestParentOperations.test_parent_generatorc                 C   s&   dd | j jD }|g dks"J d S )Nc                 S   s&   g | ]}|d urd|j v r|d qS ry   r_   r   r   r   r   r     s   zGTestParentOperations.test_self_and_parent_generator.<locals>.<listcomp>)r   r   r   r   )r   Zself_and_parents)r   resultsr   r   r   test_self_and_parent_generator  s    z3TestParentOperations.test_self_and_parent_generator)r/   r0   r1   r2   rh   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s   
r   c                   @   s   e Zd ZddddZdS )ProximityTestNrc   c                 C   s   |  d| _d S )Nz<html id="start"><head id="headtag"></head><body id="bodytag"><b id="1">One</b><b id="2">Two</b><b id="3">Three</b></body></html>re   rg   r   r   r   rh     s    zProximityTest.setup_methodr/   r0   r1   rh   r   r   r   r   r     s   r   c                       sZ   e Zd Zdd fddZdd Zdd Zd	d
 Zdd Zdd Zdd Z	dd Z
  ZS )TestNextOperationsNrc   c                    s   t t|   | jj| _d S r   )superr   rh   rf   r   r   rg   	__class__r   r   rh     s    zTestNextOperations.setup_methodc                 C   s*   | j jdksJ | j jjd dks&J d S )NOner   r   )r   next_elementrg   r   r   r   	test_next  s    zTestNextOperations.test_nextc                 C   s    | j jdd}|jd u sJ d S NThreer   )rf   r   r   )r   lastr   r   r   test_next_of_last_item_is_none   s    z1TestNextOperations.test_next_of_last_item_is_nonec                 C   s   | j jd u sJ d S r   )rf   r   rg   r   r   r   test_next_of_root_is_none$  s    z,TestNextOperations.test_next_of_root_is_nonec                 C   sB   |  | jdddg | jjdd |  | jjdddg d S )Nr   Twor   r>   r   )rG   r   find_all_nextrg   r   r   r   test_find_all_next(  s    z%TestNextOperations.test_find_all_nextc                 C   s2   | j dd dksJ | j jdddks.J d S )Nr   r   r   r   r   )r   	find_nextrg   r   r   r   test_find_next-  s    z!TestNextOperations.test_find_nextc                 C   s<   | j jdd}|djdks"J | |dddg d S )Nr   r   r   r   r   )rf   r   r   r   rG   r   r   r   r   r   test_find_next_for_text_element1  s    z2TestNextOperations.test_find_next_for_text_elementc                 C   sz   | j jdd}dd |jD }|\}}|d dks6J |dksBJ dd |jD }|d	d  |ksfJ |d
 |ksvJ d S )Nr   r   c                 S   s   g | ]}|qS r   r   r   noder   r   r   r   8      z;TestNextOperations.test_next_generators.<locals>.<listcomp>r   rB   r   c                 S   s   g | ]}|qS r   r   r   r   r   r   r   >  r   r
   r   )rf   r   next_elementsZself_and_next_elements)r   r   
successorsrn   r   Zsuccessors2r   r   r   test_next_generators6  s    z'TestNextOperations.test_next_generators)r/   r0   r1   rh   r   r   r   r   r   r   r   __classcell__r   r   r   r   r     s   r   c                       sZ   e Zd Zdd fddZdd Zdd Zd	d
 Zdd Zdd Zdd Z	dd Z
  ZS )TestPreviousOperationsNrc   c                    s"   t t|   | jjdd| _d S r   )r   r   rh   rf   r   endrg   r   r   r   rh   D  s    z#TestPreviousOperations.setup_methodc                 C   s*   | j jd dksJ | j jjdks&J d S )Nr   rB   r   )r   previous_elementrg   r   r   r   test_previousH  s    z$TestPreviousOperations.test_previousc                 C   s   | j d}|jd u sJ d S )Nhtml)rf   r   r   )r   r   r   r   r   #test_previous_of_first_item_is_noneL  s    z:TestPreviousOperations.test_previous_of_first_item_is_nonec                 C   s   | j jd u sJ d S r   )rf   r   rg   r   r   r   test_previous_of_root_is_noneP  s    z4TestPreviousOperations.test_previous_of_root_is_nonec                 C   s4   |  | jdg d |  | jjdddg d S )Nr   r   r   r   r
   r   r   )rG   r   find_all_previousrg   r   r   r   test_find_all_previousT  s    z-TestPreviousOperations.test_find_all_previousc                 C   s2   | j dd dksJ | j jdddks.J d S )Nr   r   rB   r   r   )r   find_previousrg   r   r   r   test_find_previous[  s    z)TestPreviousOperations.test_find_previousc                 C   s<   | j jdd}|djdks"J | |dg d d S )Nr   r   r   r   )rf   r   r   r   rG   r   r   r   r   r   #test_find_previous_for_text_element_  s    z:TestPreviousOperations.test_find_previous_for_text_elementc                 C   s8   | j jddd}| |jg d | |jg d d S )Nr   r   r   )bodytagheadtagr   )rA   r  r  r   )rf   r   r   previous_elementsZself_and_previous_elements)r   r   r   r   r   test_previous_generatorsd  s    z/TestPreviousOperations.test_previous_generators)r/   r0   r1   rh   r   r   r   r   r   r  r  r   r   r   r   r   r   C  s   r   c                   @   s   e Zd ZddddZdS )SiblingTestNrc   c                 C   s&   d}t dd|}| || _d S )Na  <html>
                    <span id="1">
                     <span id="1.1"></span>
                    </span>
                    <span id="2">
                     <span id="2.1"></span>
                    </span>
                    <span id="3">
                     <span id="3.1"></span>
                    </span>
                    <span id="4"></span>
                    </html>z\n\s* )r;   r<   subr   rf   )r   markupr   r   r   rh   k  s    zSiblingTest.setup_methodr   r   r   r   r   r  j  s   r  c                       sZ   e Zd Zdd fddZdd Zdd Zd	d
 Zdd Zdd Zdd Z	dd Z
  ZS )TestNextSiblingNrc   c                    s"   t t|   | jjdd| _d S )NrA   r   )r   r
  rh   rf   r   r   rg   r   r   r   rh     s    zTestNextSibling.setup_methodc                 C   s   | j jd u sJ d S r   )rf   next_siblingrg   r   r   r   !test_next_sibling_of_root_is_none  s    z1TestNextSibling.test_next_sibling_of_root_is_nonec                 C   sB   | j jd dksJ | j jjd dks*J | j jd dks>J d S )Nr   r   rB   1.1)r   r  r   rg   r   r   r   test_next_sibling  s    z!TestNextSibling.test_next_siblingc                 C   sN   | j jjd u sJ | j jdd}|jd u s.J | j jdd}|jd u sJJ d S )Nr  r   rD   )rf   r   r  r   )r   nested_spanZ	last_spanr   r   r   test_next_sibling_may_not_exist  s
    z/TestNextSibling.test_next_sibling_may_not_existc                 C   s   | j dd dksJ d S )Nr   r   r   )r   r,   rg   r   r   r   test_find_next_sibling  s    z&TestNextSibling.test_find_next_siblingc                 C   s4   |  | jdg d |  | jjdddg d S )Nr   r   rB   rD   rB   r   )r   r   r6   rg   r   r   r   test_next_siblings  s    z"TestNextSibling.test_next_siblingsc                 C   s,   |  | jjg d |  | jjg d d S )Nr  )rA   r   rB   rD   )r   r   next_siblingsZself_and_next_siblingsrg   r   r   r   test_next_siblings_generators  s    z-TestNextSibling.test_next_siblings_generatorsc                 C   sv   |  d}|jdd}|jjdks&J |jjdks6J | |ddg |jdddks^J |jddd u srJ d S )NFoo<b>bar</b>bazr9   r   r   bazr8   nonesuch)r   r   r  r*   rG   r6   r,   r   r   r   r   r   r   "test_next_sibling_for_text_element  s    
z2TestNextSibling.test_next_sibling_for_text_element)r/   r0   r1   rh   r  r  r  r  r  r  r  r   r   r   r   r   r
  ~  s   	r
  c                       sZ   e Zd Zdd fddZdd Zdd Zd	d
 Zdd Zdd Zdd Z	dd Z
  ZS )TestPreviousSiblingNrc   c                    s"   t t|   | jjdd| _d S )NrD   r   )r   r  rh   rf   r   r   rg   r   r   r   rh     s    z TestPreviousSibling.setup_methodc                 C   s   | j jd u sJ d S r   )rf   previous_siblingrg   r   r   r   %test_previous_sibling_of_root_is_none  s    z9TestPreviousSibling.test_previous_sibling_of_root_is_nonec                 C   sB   | j jd dksJ | j jjd dks*J | j jd dks>J d S )Nr   rB   r   z3.1)r   r  r   rg   r   r   r   test_previous_sibling  s    z)TestPreviousSibling.test_previous_siblingc                 C   sN   | j jjd u sJ | j jdd}|jd u s.J | j jdd}|jd u sJJ d S )Nr  r   rA   )rf   r   r  r   )r   r  Z
first_spanr   r   r   #test_previous_sibling_may_not_exist  s
    z7TestPreviousSibling.test_previous_sibling_may_not_existc                 C   s   | j dd dksJ d S )Nr   r   rB   )r   r+   rg   r   r   r   test_find_previous_sibling  s    z.TestPreviousSibling.test_find_previous_siblingc                 C   s4   |  | jdg d |  | jjdddg d S )Nr   rB   r   rA   rA   r   )r   r   r5   rg   r   r   r   test_previous_siblings  s    z*TestPreviousSibling.test_previous_siblingsc                 C   s,   |  | jjg d |  | jjg d d S )Nr!  )rD   rB   r   rA   )r   r   previous_siblingsZself_and_previous_siblingsrg   r   r   r   !test_previous_siblings_generators  s    z5TestPreviousSibling.test_previous_siblings_generatorsc                 C   sv   |  d}|jdd}|jjdks&J |jjdks6J | |ddg |jdddks^J |jddd u srJ d S )Nr  r  r   r   r9   r8   r  )r   r   r  r*   rG   r5   r+   r  r   r   r   &test_previous_sibling_for_text_element  s    
z:TestPreviousSibling.test_previous_sibling_for_text_element)r/   r0   r1   rh   r  r  r  r   r"  r$  r%  r   r   r   r   r   r    s   	r  c                   @   s  e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zejd-d.d/ d0d/ gd1d2 Zejd3d4d/ d5gd6d/ d7gfd8d9 Zd:d; Zd<d= Zd>d? Z d@dA Z!dBdC Z"dDdE Z#dFdG Z$dHdI Z%dJdK Z&dLdM Z'dNdO Z(dPdQ Z)dRdS Z*dTdU Z+dVdW Z,dXdY Z-dZd[ Z.d\d] Z/d^d_ Z0d`da Z1dbdc Z2ddde Z3dfdg Z4ejdhg didjdk Z5dldm Z6dndo Z7dpdq Z8drds Z9dtdu Z:dvS )wTestTreeModificationc                 C   sl   |  d}d|jd< | | dks*J |jd= | | dksHJ d|jd< | | dkshJ d S )	Nz<a id="1"></a>r    r   z<a id="2"></a>rK   rI   Zid2z<a id2="foo"></a>)r   r%   r   document_forr   r   r   r   test_attribute_modification  s    


z0TestTreeModification.test_attribute_modificationc                 C   sl   t d }| jd|d}t||d}t||d}d|d< |jd| |jd	| |j d
kshJ d S )Nr   z<body></body>r   r%   olzhttp://foo.com/hrefr   r
   s4   <body><a href="http://foo.com/"></a><ol></ol></body>)r   lookupr   r   r4   insertr   )r   r   r   r%   r*  r   r   r   test_new_tag_creation  s    z*TestTreeModification.test_new_tag_creationc                 C   s\   d}|  |}|jdd}|j}|jdd|j |j|ksBJ | | dksXJ d S )NzT<p id="1">Don't leave me <b>here</b>.</p>
                <p id="2">Don't leave!</p>r   r   zD<p id="1">Don't leave me .</p>
<p id="2">Don't leave!<b>here</b></p>)r   r   r   rN   r   r   r'  )r   docr   Zsecond_paraZboldr   r   r   !test_append_to_contents_moves_tag  s    

z6TestTreeModification.test_append_to_contents_moves_tagc           	      C   s   |  d}|d}||d}|jdks2J |d|d\}|jdksTJ |d}|dksjJ |dd}|ddgksJ |d	d
}|d	d
gksJ |ddg}|ddgksJ |	 dksJ d S )Nz<html></html>r   headr   r   rE   rB   rD   6789Z3456789)
r   r   rN   new_tagr*   r-  insert_beforeinsert_afterextendZget_text)	r   r   r   r1  r   Ztext5Ztext34Ztext67Ztext89r   r   r   &test_insertion_returns_inserted_things  s    


z;TestTreeModification.test_insertion_returns_inserted_thingsc                 C   s0   d}|  |}|j}||j}||ks,J d S )Nz<a></a><b><c></c></b>)r   r%   replace_withrq   r   r   r   r%   new_ar   r   r   1test_replace_with_returns_thing_that_was_replaced  s
    
zFTestTreeModification.test_replace_with_returns_thing_that_was_replacedc                 C   s,   d}|  |}|j}| }||ks(J d S )N<a><b></b><c></c></a>)r   r%   unwrapr<  r   r   r   +test_unwrap_returns_thing_that_was_replaced   s
    
z@TestTreeModification.test_unwrap_returns_thing_that_was_replacedc                 C   s   |  d}|j}|  d |ju s&J tt |  W d    n1 sN0    Y  tt ||j	 W d    n1 s0    Y  d S )Nz<a><b>Foo</b></a><c>Bar</c>)
r   r%   extractr   r   r   r   r@  r;  rq   r   r   r   r   Itest_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parent'  s    
&z^TestTreeModification.test_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parentc                 C   sF   d}|  |}|j}|j|}||ks,J | | |ksBJ d S )Nz-<a><b></b><c>Foo<d></d></c></a><a><e></e></a>)r   rq   r;  r   r'  )r   r   r   rq   r\   r   r   r   test_replace_tag_with_itself1  s    
z1TestTreeModification.test_replace_tag_with_itselfc                 C   sJ   d}|  |}tt |j|j W d    n1 s<0    Y  d S N<a><b></b></a>)r   r   r   r   r   r;  r%   r   r   r   r   r   r   1test_replace_tag_with_its_parent_raises_exception9  s    
zFTestTreeModification.test_replace_tag_with_its_parent_raises_exceptionc                 C   sL   d}|  |}tt  |jd|j W d    n1 s>0    Y  d S )NrF  r   )r   r   r   r   r%   r-  rG  r   r   r   ,test_insert_tag_into_itself_raises_exception?  s    
zATestTreeModification.test_insert_tag_into_itself_raises_exceptionc                 C   s   |  d}|d|jddd|jddd\}}d|jks>J d|jksLJ t|j\}}}}d|jkslJ d|jkszJ d|jksJ d|jksJ d S )	N-<p>And now, a word:</p><p>And we're back.</p>r
   r(   p2r   p3And now, a word:And we're back.)r   r-  r6  r   listchildren)r   r   rK  rL  p1p4r   r   r   test_insert_multiple_elementsE  s    
&z2TestTreeModification.test_insert_multiple_elementsc           	      C   s   |  d}d}|  |}|d|\}}d|jks6J d|jksDJ |jD ]}t|trJJ qJt|j\}}}}d|jks~J d|jksJ d|jksJ d|jksJ dS )	zInserting one BeautifulSoup object into another actually inserts all
        of its children -- you'll never combine BeautifulSoup objects.
        rJ  z<p>p2</p><p>p3</p>r
   rK  rL  rM  rN  N)r   r-  r   descendants
isinstancer   rO  rP  )	r   r   r   Z	to_insertrK  rL  r   rQ  rR  r   r   r   1test_insert_beautifulsoup_object_inserts_childrenQ  s    


zFTestTreeModification.test_insert_beautifulsoup_object_inserts_childrenc                 C   sN   |  d}|j}|dd |j\}}|d |d d|jjksJJ d S )Nz<p><a>one</a><b>three</b></p>r
   Ztwor  Zthree)r   r%   r-  r   r;  r   r   )r   r   r%   leftrightr   r   r   3test_replace_with_maintains_next_element_throughoutf  s    



zHTestTreeModification.test_replace_with_maintains_next_element_throughoutc                 C   sl   |  d}|jddd |jdd}|j}|j|ks<J |j|ksJJ |jj|ksZJ |jd u shJ d S )Nz<b>Argh!</b>Argh!r   Hooray!)r   r   r;  r   r   r   r   )r   r   new_textr   r   r   r   test_replace_final_nodet  s    
z,TestTreeModification.test_replace_final_nodec                 C   s   |  d}|jdd | | dks.J |jdd}|jdksHJ |jj|ksXJ |jdksfJ |jj	|ksvJ |j	d u sJ |j|j
ksJ d S )Nz<a><b>Argh!</b><c></c></a>r
   r[  z!<a><b>Argh!Hooray!</b><c></c></a>r   rZ  )r   r   r-  r   r'  r   r   r   r  r  rq   )r   r   r\  r   r   r   test_consecutive_text_nodes~  s    
z0TestTreeModification.test_consecutive_text_nodesc                 C   sT   |  d}|jdd |jdd ddg|jjks:J |jjd jdksPJ d S )NrK   r   r8   rI   )r   r%   r-  r   r   r   r   r   r   test_insert_string  s
    
z'TestTreeModification.test_insert_stringc                 C   s8   |  d}|jd}|dks"J |j dks4J d S )Nz<b>1</b>r   z	<b>12</b>)r   r   rN   r   r[   r   r   r   test_append  s    
z TestTreeModification.test_appendc                 C   s   |   }| jd|d}t||d}|dd |jd| | | dksRJ |j}|j|ksfJ |j	|kstJ |j
dd	}|j|ksJ |j|ksJ |j}|j|ksJ |j	|ksJ |j
dd	}|j|ksJ |j|ksJ |j|ksJ d S )
Nz%<a><b>Find</b><c>lady!</c><d></d></a>r)  Zmagictagr   ther
   z=<a><b>Find</b><magictag>the</magictag><c>lady!</c><d></d></a>ZFindr   )r   r   r   r-  r%   r   r'  r   r  r  r   r   r   rq   r   )r   r   r   Z	magic_tagZb_tagr   Zc_tagra  r   r   r   test_insert_tag  s*    

z$TestTreeModification.test_insert_tagc                 C   s2   d}|  |}|jd|j || ks.J d S )Nz<a>b<c></c>d</a>r
   )r   r%   r-  rq   r   r   r   r   r   r   r   %test_insert_into_the_current_location  s    
z:TestTreeModification.test_insert_into_the_current_locationc                 C   s0   d}|  |}|j|j || ks,J d S rE  )r   r%   rN   r   r   rc  r   r   r   *test_append_child_thats_already_at_the_end  s    
z?TestTreeModification.test_append_child_thats_already_at_the_endc                 C   sJ   d}|  |}|j|j|j|j|j|jg}|j| d|	 ksFJ d S )Nz1<a><b><c><d><e><f><g></g></f></e></d></c></b></a>z1<a><g></g><f></f><e></e><d></d><c></c><b></b></a>)
r   gr   er   rq   r   r%   r9  r   r   r   r   elementsr   r   r   #test_extend_with_a_list_of_elements  s
    
z8TestTreeModification.test_extend_with_a_list_of_elementsc                 C   s>   d}|  |}ddtddg}|j| d| ks:J d S )NrK   r   rq   r   rg  z<a>bcde</a>)r   r   r%   r9  r   rh  r   r   r   "test_extend_with_a_list_of_strings  s
    
z7TestTreeModification.test_extend_with_a_list_of_stringsget_tagsc                 C   s   | S r   r   r{   r   r   r   <lambda>  r   zTestTreeModification.<lambda>c                 C   s   | j S r   )r   r{   r   r   r   rm    r   c                 C   s`   d}|  |}|jddd}|jddd}||}|| d| ksLJ d| ks\J d S )NzS<body><div id="d1"><a>1</a><a>2</a><a>3</a><a>4</a></div><div id="d2"></div></body>r'   d1r   d2z<div id="d1"></div>z3<div id="d2"><a>1</a><a>2</a><a>3</a><a>4</a></div>)r   r   r9  r   )r   rl  r   r   rn  ro  tagsr   r   r   &test_extend_with_another_tags_contents  s    

z;TestTreeModification.test_extend_with_another_tags_contentszstring_source,resultc                 C   s   | j jS r   )r%   r   r   r   r   r   rm    r   z<a></a><b>1</b>c                 C   s   dS )NZabcder   rr  r   r   r   rm    r   z<a>1</a><b>abcde</b>c           	      C   s   d}|  |}tjdd`}||}|j| |j |ksBJ |\}|jtksVJ t	|j
}|dkslJ W d    n1 s0    Y  d S )Nz<div><a>1</a><b></b></div>TrL   zIA single non-Tag item was passed into Tag.extend. Use Tag.append instead.)r   rO   rP   r   r9  r'   Zdecode_contentsrQ   rR   r   rS   )	r   Zstring_sourcer\   r   r   rU   r   rV   rW   r   r   r   )test_extend_with_a_single_non_tag_element  s    

z>TestTreeModification.test_extend_with_a_single_non_tag_elementc                 C   s2   d}|  |}|jd|j d| ks.J d S )Nz<a><b></b><c></c><d></d></a>r   z<a><d></d><b></b><c></c></a>)r   r%   r-  r   r   rc  r   r   r   $test_move_tag_to_beginning_of_parent  s    
z9TestTreeModification.test_move_tag_to_beginning_of_parentc                 C   s.   |  d}|jdd t|jdks*J d S )Nz<br/>r
   ZContentsz<br>Contents</br>)r   brr-  r   r   r   r   r   &test_insert_works_on_empty_element_tag  s    
z;TestTreeModification.test_insert_works_on_empty_element_tagc                 C   s   |  d}|jd |jd | | dks8J |j|j | | dks\J |j}tt || W d    n1 s0    Y  |	  tt |d W d    n1 s0    Y  |  d}|j|
d d S )	Nr   BAZQUUXzQUUX<a>foo</a>BAZ<b>bar</b>QUUX<b>bar</b><a>foo</a>BAZnope<a>r%   )r   r   r7  r%   r   r'  r   r   r   rB  r6  r   r   r   r   r   r   test_insert_before  s    
((
z'TestTreeModification.test_insert_beforec                 C   sj   |  d}|jddd |jddd | | dks@J |j|jd | | dksfJ d S )Nr   rw   rx  z$QUUX BAZ<a>foo</a>BAZ QUUX<b>bar</b>ZFOOz'QUUX BAZ<b>bar</b>FOO<a>foo</a>BAZ QUUX)r   r   r7  r%   r   r'  r   r   r   r   test_insert_multiple_before   s    



z0TestTreeModification.test_insert_multiple_beforec                 C   s   |  d}|jd |jd | | dks8J |j|j | | dks\J |j}tt || W d    n1 s0    Y  |	  tt |d W d    n1 s0    Y  |  d}|j
|d d S )	Nr   rw  rx  z<a>foo</a>QUUX<b>bar</b>BAZry  rz  r{  r%   )r   r   r8  r%   r   r'  r   r   r   rB  r7  r6  r|  r   r   r   test_insert_after-  s    
((
z&TestTreeModification.test_insert_afterc                 C   sj   |  d}|jddd |jddd | | dks@J |j|jd | | dksfJ d S )Nr   rw  r~  rx  z$<a>foo</a>QUUX BAZ<b>bar</b>BAZ QUUXzFOO z(QUUX BAZ<b>bar</b><a>foo</a>FOO BAZ QUUX)r   r   r8  r%   r   r'  r   r   r   r   test_insert_multiple_afterE  s    



z/TestTreeModification.test_insert_multiple_afterc                 C   s   |  d}|d}|d}tt || W d    n1 sH0    Y  tt || W d    n1 s|0    Y  tt || W d    n1 s0    Y  d S Nr  r%   )r   r6  
new_stringr   r   r   r8  NotImplementedErrorr   r   rn   r   r   r   r   :test_insert_after_raises_exception_if_after_has_no_meaningQ  s    


((zOTestTreeModification.test_insert_after_raises_exception_if_after_has_no_meaningc                 C   s   |  d}|d}|d}tt || W d    n1 sH0    Y  tt || W d    n1 s|0    Y  tt || W d    n1 s0    Y  d S r  )r   r6  r  r   r   r   r7  r  r  r   r   r   Ftest_insert_before_raises_notimplementederror_if_before_has_no_meaning\  s    


((z[TestTreeModification.test_insert_before_raises_notimplementederror_if_before_has_no_meaningc                 C   sv   |  d}|d\}}|| | | dks8J |jd u sFJ |j|jksVJ |jdksdJ |jdksrJ d S )Nz;<p>There's <b>no</b> business like <b>show</b> business</p>r   z0<p>There's  business like <b>no</b> business</p>noz	 business)	r   r#   r;  r   r'  r   r(   r   r  )r   r   r  showr   r   r   test_replace_withg  s    



z&TestTreeModification.test_replace_withc                 C   s   t dd}tt |d W d    n1 s40    Y  | dj}tt |j| W d    n1 sv0    Y  tt  |jd|d W d    n1 s0    Y  d S )Nr%   r   z
won't workrF  Zstring1Zstring2)r   r   r   r   r;  r   r%   r   )r   Za_tagr   r   r   test_replace_with_errorst  s    
(*z-TestTreeModification.test_replace_with_errorsc                 C   s   d}|  |}|d}d|_|d}|d}d}|j|||| | dksXJ |jj|kshJ |jj|ksxJ |jj|ksJ |jj|ksJ d S )Nr?  r   zText In D Tagrg  r   zRandom Textz;<a><b></b><d>Text In D Tag</d><e></e>Random Text<f></f></a>)r   r6  r   rq   r;  r   r   r   )r   r   r   Zd_tagZe_tagZf_tagZa_stringr   r   r   test_replace_with_multiple  s     



z/TestTreeModification.test_replace_with_multiplec                 C   s0   d}|  |}|j|j d| ks,J d S )Nr?  z<a><c></c></a>)r   r   r;  rq   r   rc  r   r   r   test_replace_first_child  s    
z-TestTreeModification.test_replace_first_childc                 C   s0   d}|  |}|j|j d| ks,J d S )Nr?  rF  )r   rq   r;  r   r   rc  r   r   r   test_replace_last_child  s    
z,TestTreeModification.test_replace_last_childc                 C   s  |  d}|j}|j}|| | | dks6J |jd u sDJ |jddjd u sZJ |j	d u shJ |j
d u svJ |jd u sJ |j|jksJ |j	dksJ |jj|jksJ |j
d u sJ |jdd}|j}|j|ksJ |j
|ksJ |j	|ksJ |j|ksJ d S )NzQ<a>We<b>reserve<c>the</c><d>right</d></b></a><e>to<f>refuse</f><g>service</g></e>z-<a>We<f>refuse</f></a><e>to<g>service</g></e>rX  r   ZWeto)r   r   r   r;  r   r'  r   r   r   r   r  r  r%   rg  rf  )r   r   Z
remove_tagZmove_tagZto_textZg_tagr   r   r   test_nested_tag_replace_with  s0    


z1TestTreeModification.test_nested_tag_replace_withc                 C   s6   |  d}|j  |jd u s"J |jjdks2J d S )NzI
            <p>Unneeded <em>formatting</em> is unneeded</p>
            zUnneeded formatting is unneeded)r   emr@  r(   r   r   r   r   r   test_unwrap  s    

z TestTreeModification.test_unwrapc                 C   sF   |  d}|j|d}| dks,J | | dksBJ d S )NzI wish I was bold.r   <b>I wish I was bold.</b>)r   r   wrapr6  r   r'  )r   r   r   r   r   r   	test_wrap  s    
zTestTreeModification.test_wrapc                 C   s4   |  d}|jj|j | | dks0J d S )Nz<b></b>I wish I was bold.r  )r   r   r  r  r   r'  r   r   r   r   %test_wrap_extracts_tag_from_elsewhere  s    
z:TestTreeModification.test_wrap_extracts_tag_from_elsewherec                 C   sH   |  d}|jj|j dt|jjks.J | | dksDJ d S )Nz+<b>I like being bold.</b>I wish I was bold.r    z+<b>I like being bold.I wish I was bold.</b>)r   r   r  r  r"   r   r   r'  r   r   r   r   &test_wrap_puts_new_contents_at_the_end  s    

z;TestTreeModification.test_wrap_puts_new_contents_at_the_endc                 C   s   |  d}t|jjdksJ |jdd }| dks>J | dksNJ t|jjdksbJ |jd u spJ |jd u s~J |j	j	d u sJ |jdd	}|jd
d	}|j	|ksJ |j
|ksJ |j|ksJ |j|ksJ d S )NzR<html><body>Some content. <div id="nav">Nav crap</div> More content.</body></html>r>   navr   z6<html><body>Some content.  More content.</body></html>z<div id="nav">Nav crap</div>r    zSome content. r   z More content.)r   r"   r4   r   r   rB  r   r   r   r   r  r  )r   r   Z	extractedZ	content_1Z	content_2r   r   r   test_extract  s"    z!TestTreeModification.test_extractc                 C   sr   |  d}|jj}|d}|d}|j| |j| |  |  ||jjks^J ||jjksnJ d S )Nr   rI   r8   )r   r%   r   r  rN   r   rB  )r   r   Zfoo_1Zfoo_2Zbar_2r   r   r   4test_extract_distinguishes_between_identical_strings  s    


zITestTreeModification.test_extract_distinguishes_between_identical_stringsc                    s8   |  d  fdd dD  dt jks4J d S )Nzv
<html>
<head>
<script>foo</script>
</head>
<body>
 <script>bar</script>
 <a></a>
</body>
<script>baz</script>
</html>c                    s   g | ]} j  qS r   )scriptrB  )r   r   rr  r   r   r     r   zKTestTreeModification.test_extract_multiples_of_same_tag.<locals>.<listcomp>r  z<body>

<a></a>
</body>)r   r#   r   r4   rg   r   rr  r   "test_extract_multiples_of_same_tag
  s    
z7TestTreeModification.test_extract_multiples_of_same_tagc                 C   s.   |  d}|d  d |du s*J d S )Nz<html>
<body>hi</body>
</html>r4   )r   r   rB  r   r   r   r   Btest_extract_works_when_element_is_surrounded_by_identical_strings  s    
zWTestTreeModification.test_extract_works_when_element_is_surrounded_by_identical_stringsc                 C   sd   |  d}|j}|j  t|jjdks.J t|ds<J |j}|jdd dt|jks`J dS )zTag.clear()z4<p><a>String <em>Italicized</em></a> and another</p>r   r   T)	decomposeN)r   r%   r(   clearr"   r   rZ   r  )r   r   r%   r  r   r   r   
test_clear  s    

zTestTreeModification.test_clearzmethod_name,expected_result))rT  9<div><em>child1</em><p id="start"></p><p>child3</p></div>)r  zH<div><em>child1</em><p id="start"><a>Second <em>child</em></a></p></div>)r   r  )rP  r  )r  r  )r#  zF<div><p id="start"><a>Second <em>child</em></a></p><p>child3</p></div>)r   r  c                 C   s<   |  d}t|j|}|D ]}|  q|| ks8J d S )NzU<div><em>child1</em><p id='start'><a>Second <em>child</em></a></p><p>child3</p></div>)r   getattrr(   rB  r   )r   method_nameZexpected_resultr   iteratorr   r   r   r   test_extract_during_iteration,  s    
z2TestTreeModification.test_extract_during_iterationc                 C   s~   |  d}|d\}}|j}|jj}||||fD ]}d|ju s2J q2|  |||fD ]}d|ju sXJ qXd|ju szJ d S )Nz;<p><a>String <em>Italicized</em></a></p><p>Another para</p>r(   FT)r   r#   r%   r  r   
decomposedr  )r   r   rQ  rK  r%   r   r   r   r   r   test_decomposeQ  s    
z#TestTreeModification.test_decomposec                 C   sP   |  d}|j}|jj}d|ju s&J |  d|ju s<J d| ksLJ d S )Nz'<div><p>String 1</p><p>String 2</p></p>FTz!<div><p></p><p>String 2</p></div>)r   r'   r(   r   r  r  r   )r   r   r'   r   r   r   r   test_decompose_stringa  s    
z*TestTreeModification.test_decompose_stringc                 C   sB   |  d}d|j_|jjdgks$J d|j_|jjdgks>J dS )zTag.string = 'string'z<a></a> <b><c></c></b>rI   r8   N)r   r%   r   r   r   r   r   r   r   test_string_setj  s
    
z$TestTreeModification.test_string_setc                 C   s,   |  d}|jj|j_|j dks(J d S )Nz<a><b>foo</b><c>bar</c>s   <a><b>bar</b><c>bar</c></a>)r   rq   r   r   r%   r   r   r   r   r   /test_string_set_does_not_affect_original_stringr  s    
zDTestTreeModification.test_string_set_does_not_affect_original_stringc                 C   s0   |  d}td}||j_t|jjts,J d S )NrK   rI   )r   r   r%   r   rU  )r   r   cdatar   r   r   )test_set_string_preserves_class_of_stringw  s    
z>TestTreeModification.test_set_string_preserves_class_of_stringN);r/   r0   r1   r(  r.  r0  r:  r>  rA  rC  rD  rH  rI  rS  rV  rY  r]  r^  r_  r`  rb  rd  re  rj  rk  r   markparametrizerq  rs  rt  rv  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   r   r&    s   	

	




	%
	r&  )r   r#   r   r   r   r   r   r   r,   r6   r+   r5   c                   @   s"   e Zd Zejdedd ZdS )TestDeprecatedArgumentsr  c                 C   sz   |  d}t|j|}tjddD}|dd |\}|jtksBJ t|j}|dksXJ W d    n1 sl0    Y  d S )N<a>some</a><b>markup</b>TrL   r	  )r   zOThe 'text' argument to find()-type methods is deprecated. Use 'string' instead.)	r   r  r   rO   rP   rQ   rR   r   rS   r   r  r   methodrU   rV   rW   r   r   r   test_find_type_method_string  s    


z4TestDeprecatedArguments.test_find_type_method_stringN)r/   r0   r1   r   r  r  all_find_type_methodsr  r   r   r   r   r    s   r  c                   @   s"   e Zd Zejdedd ZdS )TestWarningsr  c                 C   s   |  d}t|j|}tjddT}|dd |\}|jtksBJ t|jt	sRJ t
|j}d|v shJ W d    n1 s|0    Y  d S )Nr  TrL   u)_classzN'_class' is an unusual attribute name and is a common misspelling for 'class_')r   r  r   rO   rP   rQ   rR   rU  rS   r   r   r  r   r   r   test_suspicious_syntax_warning  s    


z+TestWarnings.test_suspicious_syntax_warningN)r/   r0   r1   r   r  r  r  r  r   r   r   r   r    s   r  )$r2   r   r;   rO   Zbs4r   Zbs4.builderr   Zbs4.elementr   r   r   r   r   Z
bs4.filterr	   r  r   r   r3   r^   rb   r   r   r   r   r   r   r   r  r
  r  r&  r  r  r  r   r   r   r   <module>   s@   
(FP /,?,'/1     %