o
    _"<fŹ                     @   s  d Z ddlmZ ddlZddlZddlZ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mZ ddlmZ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'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.
    )	set_traceN)BeautifulSoup)builder_registryHTMLParserTreeBuilder)CDataCommentDeclarationDoctype	FormatterNavigableStringScriptSoupStrainer
StylesheetTagTemplateString   )SoupTestskipIfc                   @   8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )TestFindzBasic tests of the find() method.

    find() just calls find_all() with limit=1, so it's not tested all
    that thouroughly here.
    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   J/var/www/html/kck/venv/lib/python3.10/site-packages/bs4/tests/test_tree.pytest_find_tag.      
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_find2   r    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_find6   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_nameA   s   
z'TestFind.test_find_everything_with_nameN)	__name__
__module____qualname____doc__r   r#   r(   r.   r0   r   r   r   r   r   '   s    r   c                   @   r   )TestFindAllz%Basic tests of the find_all() method.c                 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s-J |jddg dks9J dS )	z'You can search the tree for text nodes.u   <html>Foo<b>bar</b>»</html>barr"   Fooz.*)r7   r6      »TN)r   r-   recompiler   r   r   r   test_find_all_text_nodesI   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   r?   
   )r?   r   r@   45r   Nr   assert_selectsr-   r   r   r   r   test_find_all_limitW   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=   r?   foor$   r@   )r   rE   r   r   r   r   r   %test_calling_a_tag_is_calling_findallc   s   
z1TestFindAll.test_calling_a_tag_is_calling_findallc                 C   s.   |  d}g }|| g ||ksJ d S )N<a></a>)r   appendr-   )r   r   lr   r   r   Ttest_find_all_with_self_referential_data_structure_does_not_cause_infinite_recursionh   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s*J dS )z%All find_all calls return a ResultSetrI   r/   sourceTrG   r"   N)r   r-   hasattr)r   r   resultr   r   r   test_find_all_resultsetr   s   


z#TestFindAll.test_find_all_resultsetN)	r1   r2   r3   r4   r;   rF   rH   rL   rP   r   r   r   r   r5   F   s    
r5   c                   @      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sJ d S )Nz0<mathml:msqrt>4</mathml:msqrt><a svg:fill="red">rB   zmathml:msqrtr/   zsvg:fillredattrs)r   r   r   namer   r   r   r   test_find_by_namespaced_name   s   
z7TestFindAllBasicNamespaces.test_find_by_namespaced_nameN)r1   r2   r3   rW   r   r   r   r   rR          rR   c                   @   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d Zdd Zdd Zdd ZdS )TestFindAllByNamez&Test ways of finding tags by tag name.c                 C      |  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      zTestFindAllByName.setup_methodc                 C   s   |  | jdddg d S Nr/   
First tag.Nested tag.rE   r\   r-   r]   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/   ra   r"   Trb   tagrE   r\   r-   r9   r:   r]   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/   rb   )rE   r\   cr-   r]   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 r`   )rE   r\   r]   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 r`   )rE   r\   r-   r   r]   r   r   r   test_find_all_by_tag_strainer      z/TestFindAllByName.test_find_all_by_tag_strainerc                 C   s    |  | jddgg d d S )Nr/   r   ra   zSecond tag.rb   rc   r]   r   r   r   test_find_all_by_tag_names   rl   z,TestFindAllByName.test_find_all_by_tag_namesc                 C   s"   |  | jdddg d d S )NT)r/   r   rm   rc   r]   r   r   r   test_find_all_by_tag_dict      z+TestFindAllByName.test_find_all_by_tag_dictc                 C   s"   |  | jtdg d d S )Nz^[ab]$rm   rf   r]   r   r   r   test_find_all_by_tag_re   rp   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%   )rV   get)re   r   r   r   id_matches_name   r_   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.rD   )r   rt   r\   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s%J d|jks,J d|jks3J d|jks:J d S )NzH<div class='a b'>1</div><div class='a c'>2</div><div class='a d'>3</div>divza dza br@   r?   )r   r   r9   r:   r-   r   )r   r   r1r2r3r4r   r   r   %test_find_with_multi_valued_attribute   s   z7TestFindAllByName.test_find_with_multi_valued_attributeN)r1   r2   r3   r4   r^   rd   rg   ri   rj   rk   rn   ro   rq   ru   r{   r   r   r   r   rY      s    rY   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   &   |  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.rD   r   r\   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sJ |jg|j|ddks*J |jgs8J |j|dgdd S )Nu   םולשutf8u   <a title="םולש"></a>)titlezsomething else)encoder   r/   r-   decode)r   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>
                         name1rV   zA tag called 'name1'.rV   rT   zName match.classclass2zClass match.rD   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/   r?   class_zClass 1.rh   r@   zClass 3 and 4.rB   rT   rD   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>garor   Found itr/   zo b)r   r-   r9   r:   rE   )r   r\   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&     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_value+  r   zpTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.small_attribute_valuer   rE   r-   r9   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sJ |dd|gs#J |dd|g|jdddks/J |g|ddks:J g |ddksDJ d S )Nz*<a class="foo bar"></a><a class="foo"></a>r/   rG   r6   zfoo barr   zbar foor   r-   )r   r   r/   a2r   r   r   :test_find_all_with_string_for_attrs_finds_multiple_classes1  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~   rT   zMatch.)r   r   rE   r-   )r   r\   strainerr   r   r   'test_find_all_by_attribute_soupstrainer=  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.rD   r   r   r   r   $test_find_all_with_missing_attributeE  s   
z;TestFindAllByAttribute.test_find_all_with_missing_attributec                 C   r}   )Nr   Tr$   zID present.zID is empty.rD   r   r   r   r   $test_find_all_with_defined_attributeM  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$   r?   rD   )r   r\   expectedr   r   r   $test_find_all_with_numeric_attributeV  s   
z;TestFindAllByAttribute.test_find_all_with_numeric_attributec                 C   s*   |  d}| |jg ddddg d S )Nz<a id="1">1</a>
                            <a id="2">2</a>
                            <a id="3">3</a>
                            <a>No ID.</a>)r?   r@   rB   r$   r?   r@   rD   r   r   r   r   (test_find_all_with_list_attribute_values_  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_valuei  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/   rG   r"   r6   r   r/   r-   r   r   r/   r   r   r   'test_find_by_name_and_containing_stringv     
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/   rG   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*   rG   )r%   r   r   r6   r   r   r   r   r   ,test_find_by_attribute_and_containing_string  r   zCTestFindAllByAttribute.test_find_by_attribute_and_containing_stringN)r1   r2   r3   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r|      s"    		
r|   c                   @      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ksFJ d
t|j	ksOJ |
  dt|j	ks\J d|j	d kseJ d|jjksmJ d|j	d ksvJ d|j	d ksJ d S )Nz<div>a</div>r   rh   z	Comment 1z	Comment 2dspanr?   r         abcr   12r   r*   )r   rv   rJ   r   default_builderr   r   r   r,   contentssmooth)r   r   rv   builderr   r   r   r   test_smooth  s(   






zTestSmooth.test_smoothN)r1   r2   r3   r4   r   r   r   r   r   r     s    r   c                   @   r   )	TestIndexzTest Tag.indexc                 C   sp   |  d}|j}t|jD ]\}}|||ksJ qtt |d W d    d S 1 s1w   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   rv   	enumerater   indexpytestraises
ValueError)r   r\   rv   ielementr   r   r   
test_index  s   
	"zTestIndex.test_indexN)r1   r2   r3   r4   r   r   r   r   r   r     s    r   c                   @   sX   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d Zdd ZdS )TestParentOperationsz;Test navigation and searching through an element's parents.c                 C   s   |  d| _| jj| _d S )Na1  <ul id="empty"></ul>
                                 <ul id="top">
                                  <ul id="middle">
                                   <ul id="bottom">
                                    <b>Start here</b>
                                   </ul>
                                  </ul>)r   r\   r   startr]   r   r   r   r^     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s!J d S )Nr%   bottommiddletop)r   parentr]   r   r   r   test_parent  s   z TestParentOperations.test_parentc                 C   s    | j jd }|j| j ksJ d S )Nr   )r\   r   r   )r   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ksJ d S N)r\   r   r]   r   r   r   test_soup_object_has_no_parent     z3TestParentOperations.test_soup_object_has_no_parentc                 C   s6   |  | jdg d |  | jjddddg d S )Nul)r   r   r   r   r$   )assert_selects_idsr   find_parentsr]   r   r   r   test_find_parents  s   z&TestParentOperations.test_find_parentsc                 C   s8   | j dd dksJ | j jdddd dksJ d S )Nr   r%   r   r   r$   )r   find_parentr]   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   )r\   r   r   rV   r   r'   r   r   r   test_parent_of_text_element     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   )r\   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 }|sJ dddkgd S )Nc                 S   s&   g | ]}|d urd|j v r|d qS rr   rT   ).0r   r   r   r   
<listcomp>  s    z>TestParentOperations.test_parent_generator.<locals>.<listcomp>r   r   r   )r   parents)r   r   r   r   r   test_parent_generator  s   z*TestParentOperations.test_parent_generatorN)r1   r2   r3   r4   r^   r   r   r   r   r   r   r   r   r   r   r   r   r     s    r   c                   @   rQ   )ProximityTestc                 C   rZ   )Nzg<html id="start"><head></head><body><b id="1">One</b><b id="2">Two</b><b id="3">Three</b></body></html>r[   r]   r   r   r   r^     s   
zProximityTest.setup_methodNr1   r2   r3   r^   r   r   r   r   r     rX   r   c                       T   e Zd Z 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 )TestNextOperationsc                    s   t t|   | jj| _d S r   )superr   r^   r\   r   r   r]   	__class__r   r   r^     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_elementr]   r   r   r   	test_next  s   zTestNextOperations.test_nextc                 C   s    | j jdd}|jd ksJ d S NThreer"   )r\   r   r   )r   lastr   r   r   test_next_of_last_item_is_none  s   z1TestNextOperations.test_next_of_last_item_is_nonec                 C      | j jd ksJ d S r   )r\   r   r]   r   r   r   test_next_of_root_is_none     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$   )rE   r   find_all_nextr]   r   r   r   test_find_all_next  s   z%TestNextOperations.test_find_all_nextc                 C   2   | j dd dksJ | j jdddksJ d S )Nr   r%   r   r   r"   )r   	find_nextr]   r   r   r   test_find_next     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   )r\   r   r   r   rE   r   r   r   r   r   test_find_next_for_text_element  s   z2TestNextOperations.test_find_next_for_text_elementc                 C   sF   | j jdd}dd |jD }|\}}|d dksJ |dks!J d S )Nr   r"   c                 S      g | ]}|qS r   r   r   noder   r   r   r   #      z:TestNextOperations.test_next_generator.<locals>.<listcomp>r%   r@   r   )r\   r   next_elements)r   r   
successorsre   r   r   r   r   test_next_generator!  s
   z&TestNextOperations.test_next_generator)r1   r2   r3   r^   r   r   r   r   r   r   r  __classcell__r   r   r   r   r     s    r   c                       r   )TestPreviousOperationsc                    "   t t|   | jjdd| _d S r   )r   r  r^   r\   r   endr]   r   r   r   r^   +  r   z#TestPreviousOperations.setup_methodc                 C   s*   | j jd dks
J | j jjdksJ d S )Nr%   r@   r   )r  previous_elementr]   r   r   r   test_previous/  s   z$TestPreviousOperations.test_previousc                 C   s   | j d}|jd ksJ d S )Nhtml)r\   r   r  )r   r~   r   r   r   #test_previous_of_first_item_is_none3  s   z:TestPreviousOperations.test_previous_of_first_item_is_nonec                 C   r   r   )r\   r  r]   r   r   r   test_previous_of_root_is_none7  r   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   )rE   r  find_all_previousr]   r   r   r   test_find_all_previous;  s   z-TestPreviousOperations.test_find_all_previousc                 C   r   )Nr   r%   r@   r   r"   )r  find_previousr]   r   r   r   test_find_previousC  r   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  )r\   r   r  r   rE   r  r   r   r   r   #test_find_previous_for_text_elementG  s
   z:TestPreviousOperations.test_find_previous_for_text_elementc                 C   sh   | j jdd}dd |jD }|\}}}}|d dksJ |jdks$J |jdks+J |jd	ks2J d S )
Nr   r"   c                 S   r   r   r   r   r   r   r   r   O  r   zBTestPreviousOperations.test_previous_generator.<locals>.<listcomp>r%   r?   bodyheadr  )r\   r   previous_elementsrV   )r   r   predecessorsr   r  r  r  r   r   r   test_previous_generatorM  s   z.TestPreviousOperations.test_previous_generator)r1   r2   r3   r^   r  r	  r
  r  r  r  r  r  r   r   r   r   r  )  s    r  c                   @   rQ   )SiblingTestc                 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* )r9   r:   subr   r\   )r   markupr   r   r   r^   \  s   zSiblingTest.setup_methodNr   r   r   r   r   r  Z  rX   r  c                       L   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Zdd Z	  Z
S )TestNextSiblingc                    r  )Nr?   r$   )r   r  r^   r\   r   r   r]   r   r   r   r^   q  r   zTestNextSibling.setup_methodc                 C   r   r   )r\   next_siblingr]   r   r   r   !test_next_sibling_of_root_is_noneu  r   z1TestNextSibling.test_next_sibling_of_root_is_nonec                 C   B   | 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   r@   1.1)r   r  r   r]   r   r   r   test_next_siblingx     z!TestNextSibling.test_next_siblingc                 C   N   | j jjd ks	J | j jdd}|jd ksJ | j jdd}|jd ks%J d S )Nr  r$   rB   )r\   r  r  r   )r   nested_span	last_spanr   r   r   test_next_sibling_may_not_exist  
   z/TestNextSibling.test_next_sibling_may_not_existc                 C      | j dd dksJ d S )Nr   r%   r   )r   find_next_siblingr]   r   r   r   test_find_next_sibling     z&TestNextSibling.test_find_next_siblingc                 C   4   |  | jdg d |  | jjdddg d S )Nr   )r   r@   rB   r@   r$   )r   r   find_next_siblingsr]   r   r   r   test_next_siblings     z"TestNextSibling.test_next_siblingsc                 C   v   |  d}|jdd}|jjdksJ |jjdksJ | |ddg |jdddks/J |jddd ks9J d S )NFoo<b>bar</b>bazr7   r"   r   bazr6   nonesuch)r   r   r  rV   rE   r,  r(  r   r   r   r   r   r   "test_next_sibling_for_text_element     
z2TestNextSibling.test_next_sibling_for_text_element)r1   r2   r3   r^   r  r   r%  r)  r-  r4  r  r   r   r   r   r  o      	r  c                       r  )TestPreviousSiblingc                    r  )NrB   r$   )r   r7  r^   r\   r   r  r]   r   r   r   r^     r   z TestPreviousSibling.setup_methodc                 C   r   r   )r\   previous_siblingr]   r   r   r   %test_previous_sibling_of_root_is_none  r   z9TestPreviousSibling.test_previous_sibling_of_root_is_nonec                 C   r  )Nr%   r@   r   z3.1)r  r8  r  r]   r   r   r   test_previous_sibling  r!  z)TestPreviousSibling.test_previous_siblingc                 C   r"  )Nr  r$   r?   )r\   r  r8  r   )r   r#  
first_spanr   r   r   #test_previous_sibling_may_not_exist  r&  z7TestPreviousSibling.test_previous_sibling_may_not_existc                 C   r'  )Nr   r%   r@   )r  find_previous_siblingr]   r   r   r   test_find_previous_sibling  r*  z.TestPreviousSibling.test_find_previous_siblingc                 C   r+  )Nr   )r@   r   r?   r?   r$   )r   r  find_previous_siblingsr]   r   r   r   test_previous_siblings  r.  z*TestPreviousSibling.test_previous_siblingsc                 C   r/  )Nr0  r1  r"   r   r7   r6   r2  )r   r   r8  rV   rE   r?  r=  r3  r   r   r   &test_previous_sibling_for_text_element  r5  z:TestPreviousSibling.test_previous_sibling_for_text_element)r1   r2   r3   r^   r9  r:  r<  r>  r@  rA  r  r   r   r   r   r7    r6  r7  c                   @   st  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d-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dAdB Z#dCdD Z$dEdF Z%dGdH Z&dIdJ Z'dKdL Z(dMdN Z)dOdP Z*dQdR Z+dSdT Z,dUdV Z-dWdX Z.dYdZ Z/d[S )\TestTreeModificationc                 C   sl   |  d}d|jd< | | dksJ |jd= | | dks$J d|jd< | | dks4J d S )	Nz<a id="1"></a>r*   r%   z<a id="2"></a>rI   rG   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s4J 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   r  insertr   )r   r   r   r/   rG  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s!J | | dks,J 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   rJ   r   r   rD  )r   docr   second_paraboldr   r   r   !test_append_to_contents_moves_tag  s   

z6TestTreeModification.test_append_to_contents_moves_tagc                 C   s0   d}|  |}|j}||j}||ksJ d S )Nz<a></a><b><c></c></b>)r   r/   replace_withrh   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/   unwraprQ  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ksJ tt |  W d    n1 s'w   Y  tt ||j	 W d    d S 1 sCw   Y  d S )Nz<a><b>Foo</b></a><c>Bar</c>)
r   r/   extractr   r   r   r   rU  rP  rh   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   s:   d}|  |}|j}|j| | | |ksJ d S )Nz-<a><b></b><c>Foo<d></d></c></a><a><e></e></a>)r   rh   rP  r   rD  )r   r'   r   rh   r   r   r   test_replace_tag_with_itself  s
   
z1TestTreeModification.test_replace_tag_with_itselfc                 C   sL   d}|  |}tt |j|j W d    d S 1 sw   Y  d S N<a><b></b></a>)r   r   r   r   r   rP  r/   r   r'   r   r   r   r   1test_replace_tag_with_its_parent_raises_exception  s
   
"zFTestTreeModification.test_replace_tag_with_its_parent_raises_exceptionc                 C   sN   d}|  |}tt |jd|j W d    d S 1 s w   Y  d S )Nr[  r   )r   r   r   r   r/   rJ  r\  r   r   r   ,test_insert_tag_into_itself_raises_exception  s
   
"zATestTreeModification.test_insert_tag_into_itself_raises_exceptionc           	      C   s   |  d}d}|  |}|d| |jD ]	}t|trJ qt|j\}}}}d|jks/J d|jks6J d|jks=J d|jksDJ dS )	zInserting one BeautifulSoup object into another actually inserts all
        of its children -- you'll never combine BeautifulSoup objects.
        z-<p>And now, a word:</p><p>And we're back.</p>z<p>p2</p><p>p3</p>r   zAnd now, a word:p2p3zAnd we're back.N)r   rJ  descendants
isinstancer   listchildrenr   )	r   r   r'   	to_insertr   p1r_  r`  p4r   r   r   1test_insert_beautifulsoup_object_inserts_children  s   


zFTestTreeModification.test_insert_beautifulsoup_object_inserts_childrenc                 C   sX   |  d}|j}|jd }|dd |j\}}|d |d d|jjks*J d S )Nz<p><a>one</a><b>three</b></p>r   r   twor  three)r   r/   r   rJ  replaceWithr   r   )r   r   r/   r   leftrightr   r   r   3test_replace_with_maintains_next_element_throughout/  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s%J |jj|ks-J |jd ks4J d S )Nz<b>Argh!</b>Argh!r"   Hooray!)r   r   rP  r   r  r   r   )r   r   new_textr   r   r   r   test_replace_final_node>  s   
z,TestTreeModification.test_replace_final_nodec                 C   s   |  d}|jdd | | dksJ |jdd}|jdks$J |jj|ks,J |jdks3J |jj	|ks;J |j	d ksBJ |j|j
ksJJ d S )Nz<a><b>Argh!</b><c></c></a>r   rp  z!<a><b>Argh!Hooray!</b><c></c></a>r"   ro  )r   r   rJ  r   rD  r   r  r   r8  r  rh   )r   r   rq  r   r   r   test_consecutive_text_nodesH  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s(J d S )NrI   r   r6   rG   )r   r/   rJ  r   r   r   r   r   r   test_insert_string]  s
   
z'TestTreeModification.test_insert_stringc                 C   s   |   }| jd|d}t||d}|dd |jd| | | dks)J |j}|j|ks3J |j	|ks:J |j
dd	}|j|ksGJ |j|ksNJ |j}|j|ksXJ |j	|ks_J |j
dd	}|j|kslJ |j|kssJ |j|kszJ d S )
Nz%<a><b>Find</b><c>lady!</c><d></d></a>rF  magictagr   ther   z=<a><b>Find</b><magictag>the</magictag><c>lady!</c><d></d></a>Findr"   )r   r   r   rJ  r/   r   rD  r   r  r8  r   r   r  rh   r   )r   r   r   	magic_tagb_tagr   c_tagrv  r   r   r   test_insert_tagf  s.   

z$TestTreeModification.test_insert_tagc                 C   s0   d}|  |}|j|j || ksJ d S rZ  )r   r/   rJ   r   r   r   r   r   r   r   r   *test_append_child_thats_already_at_the_end     
z?TestTreeModification.test_append_child_thats_already_at_the_endc                 C   sJ   d}|  |}|j|j|j|j|j|jg}|j| d|	 ks#J 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   rh   r   r/   extendr   )r   r   r   rK   r   r   r   test_extend  s
   
z TestTreeModification.test_extendc                 C   sX   d}|  |}|jddd}|jddd}|| d| ks"J 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>rv   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   r  r   )r   r   r   r  r  r   r   r   &test_extend_with_another_tags_contents  s   

z;TestTreeModification.test_extend_with_another_tags_contentsc                 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/   rJ  r   r   r|  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   Contentsz<br>Contents</br>)r   brrJ  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sJ |j|j | | dks.J |j}tt || W d    n1 sFw   Y  |	  tt |d W d    n1 sdw   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   insert_beforer/   r   rD  r   r   r   rW  new_tag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s3J d S )Nr)   r   r  z$QUUX BAZ<a>foo</a>BAZ QUUX<b>bar</b>FOOz'QUUX BAZ<b>bar</b>FOO<a>foo</a>BAZ QUUX)r   r   r  r/   r   rD  r   r   r   r   test_insert_multiple_before  s   



z0TestTreeModification.test_insert_multiple_beforec                 C   s   |  d}|jd |jd | | dksJ |j|j | | dks.J |j}tt || W d    n1 sFw   Y  |	  tt |d W d    n1 sdw   Y  |  d}|j
|d d S )	Nr)   r  r  z<a>foo</a>QUUX<b>bar</b>BAZr  r  r  r/   )r   r   insert_afterr/   r   rD  r   r   r   rW  r  r  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s3J d S )Nr)   r  r  r  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   r  r/   r   rD  r   r   r   r   test_insert_multiple_after  s   



z/TestTreeModification.test_insert_multiple_afterc                 C      |  d}|d}|d}tt || W d    n1 s$w   Y  tt || W d    n1 s>w   Y  tt || W d    d S 1 sYw   Y  d S Nr  r/   )r   r  
new_stringr   r   r   r  NotImplementedErrorr   r   re   r   r   r   r   :test_insert_after_raises_exception_if_after_has_no_meaning     


"zOTestTreeModification.test_insert_after_raises_exception_if_after_has_no_meaningc                 C   r  r  )r   r  r  r   r   r   r  r  r  r   r   r   Ftest_insert_before_raises_notimplementederror_if_before_has_no_meaning  r  z[TestTreeModification.test_insert_before_raises_notimplementederror_if_before_has_no_meaningc                 C   sv   |  d}|d\}}|| | | dksJ |jd ks#J |j|jks+J |jdks2J |jdks9J 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-   rP  r   rD  r   pr   r  )r   r   r  showr   r   r   test_replace_with  s   


z&TestTreeModification.test_replace_withc                 C   s   t dd}tt |d W d    n1 sw   Y  | dj}tt |j| W d    n1 s;w   Y  tt |jd|d W d    d S 1 sYw   Y  d S )Nr/   r   z
won't workr[  string1string2)r   r   r   r   rP  r   r/   r   )r   a_tagr   r   r   test_replace_with_errors  s   
"z-TestTreeModification.test_replace_with_errorsc                 C   s   d}|  |}|d}d|_|d}|d}d}|j|||| | dks,J |jj|ks4J |jj|ks<J |jj|ksDJ |jj|ksLJ d S )NrT  r   zText In D Tagr  r   zRandom Textz;<a><b></b><d>Text In D Tag</d><e></e>Random Text<f></f></a>)r   r  r   rh   rP  r   r   r   )r   r   r   d_tage_tagf_taga_stringr   r   r   test_replace_with_multiple*  s   



z/TestTreeModification.test_replace_with_multiplec                 C   0   d}|  |}|j|j d| ksJ d S )NrT  z<a><c></c></a>)r   r   rP  rh   r   r|  r   r   r   test_replace_first_child9  r~  z-TestTreeModification.test_replace_first_childc                 C   r  )NrT  r[  )r   rh   rP  r   r   r|  r   r   r   test_replace_last_child?  r~  z,TestTreeModification.test_replace_last_childc                 C   s  |  d}|j}|j}|| | | dksJ |jd ks"J |jddjd ks-J |j	d ks4J |j
d ks;J |jd ksBJ |j|jksJJ |j	dksQJ |jj|jksZJ |j
d ksaJ |jdd}|j}|j|ksqJ |j
|ksxJ |j	|ksJ |j|ksJ 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>rm  r"   Weto)r   r   r   rP  r   rD  r   r   r   r  r  r8  r/   r  r  )r   r   
remove_tagmove_tagto_textg_tagr   r   r   test_nested_tag_replace_withE  s0   


z1TestTreeModification.test_nested_tag_replace_withc                 C   s6   |  d}|j  |jd ksJ |jjdksJ d S )NzI
            <p>Unneeded <em>formatting</em> is unneeded</p>
            zUnneeded formatting is unneeded)r   emrU  r  r'   r   r   r   r   test_unwrapi  s   

z TestTreeModification.test_unwrapc                 C   sF   |  d}|j|d}| dksJ | | dks!J d S )NzI wish I was bold.r   <b>I wish I was bold.</b>)r   r   wrapr  r   rD  )r   r   r   r   r   r   	test_wrapq  s   
zTestTreeModification.test_wrapc                 C   s4   |  d}|jj|j | | dksJ d S )Nz<b></b>I wish I was bold.r  )r   r   r  r  r   rD  r   r   r   r   %test_wrap_extracts_tag_from_elsewherew  s   
z:TestTreeModification.test_wrap_extracts_tag_from_elsewherec                 C   sH   |  d}|jj|j dt|jjksJ | | dks"J 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   rD  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s'J t|jjdks1J |jd ks8J |jd ks?J |j	j	d ksGJ |jdd	}|jd
d	}|j	|ksZJ |j
|ksaJ |j|kshJ |j|ksoJ 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,   r  r   r   rW  r   r   r  r   r  r8  )r   r   	extracted	content_1	content_2r   r   r   test_extract  s"   z!TestTreeModification.test_extractc                 C   sz   |  d}|jj}|jj}|d}|d}|j| |j| |  |  ||jjks3J ||jjks;J d S )Nr)   rG   r6   )r   r/   r   r   r  rJ   rW  )r   r   foo_1bar_1foo_2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sJ 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   )scriptrW  )r   r   r   r   r   r     s    zKTestTreeModification.test_extract_multiples_of_same_tag.<locals>.<listcomp>r  z<body>

<a></a>
</body>)r   r-   r&   r  r]   r   r  r   "test_extract_multiples_of_same_tag  s   
z7TestTreeModification.test_extract_multiples_of_same_tagc                 C   s.   |  d}|d  d |dksJ d S )Nz<html>
<body>hi</body>
</html>r  )r   r   rW  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s0J 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   rN   r  )r   r   r/   r  r   r   r   
test_clear  s   

zTestTreeModification.test_clearc                 C   s~   |  d}|d\}}|j}|jj}||||fD ]	}d|jks"J q|  |||fD ]	}d|jks5J q,d|jks=J 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   rf  r_  r/   r'   r   r   r   r   test_decompose  s   
z#TestTreeModification.test_decomposec                 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>rG   r6   N)r   r/   r   r   r   r   r   r   r   test_string_set  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   rh   r   r   r/   r   r   r   r   r   /test_string_set_does_not_affect_original_string  s   
zDTestTreeModification.test_string_set_does_not_affect_original_stringc                 C   s0   |  d}td}||j_t|jjtsJ d S )NrI   rG   )r   r   r/   r   rb  )r   r   cdatar   r   r   )test_set_string_preserves_class_of_string  s   
z>TestTreeModification.test_set_string_preserves_class_of_stringN)0r1   r2   r3   rE  rK  rO  rS  rV  rX  rY  r]  r^  rh  rn  rr  rs  rt  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   r   r   r   rB    s\    	


			$	rB  c                   @   s   e Zd Zdd Zdd ZdS )TestDeprecatedArgumentsc                 C   s   |  d}tjdd+}|jdd\}|dksJ |jjdks!J t|d j}|dks.J W d    d S 1 s9w   Y  d S )	Nz<a>some</a><b>markup</b>Trecordr  r'   r   r   zOThe 'text' argument to find()-type methods is deprecated. Use 'string' instead.)r   warningscatch_warningsr-   r   rV   r&   message)r   r   wrO   msgr   r   r   test_find_type_method_string  s   
"z4TestDeprecatedArguments.test_find_type_method_stringc                 C   sd   t jdd"}tdd}|jdksJ t|d j}|dks J W d    d S 1 s+w   Y  d S )NTr  r'   r  r   zXThe 'text' argument to the SoupStrainer constructor is deprecated. Use 'string' instead.)r  r  r   r'   r&   r  )r   r  r   r  r   r   r   $test_soupstrainer_constructor_string  s   
"z<TestDeprecatedArguments.test_soupstrainer_constructor_stringN)r1   r2   r3   r  r  r   r   r   r   r    s    	r  )*r4   pdbr   r   r9   r  bs4r   bs4.builderr   r   bs4.elementr   r   r   r	   r
   r   r   r   r   r   r   r  r   r   r   r5   rR   rY   r|   r   r   r   r   r   r  r  r  r7  rB  r  r   r   r   r   <module>   s<   
49N 5,2(1--    4