U
    }Äú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 d'd(d)d*d+d,d-d.d/d0d1d2gZ!G d3d4„ d4eƒZ"G d5d6„ d6eƒZ#dS )7a8  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t‚d S )Nz <a>1</a><b>2</b><a>3</a><b>4</b>ÚbÚ2)ÚsoupÚfindÚstringÚAssertionError©Úselfr   © r   ú7/tmp/pip-unpacked-wheel-kgiupv3k/bs4/tests/test_tree.pyÚtest_find_tag"   s    
zTestFind.test_find_tagc                 C   s"   |   d¡}|jdddkst‚d S )Nu   <h1>RÃ¤ksmÃ¶rgÃ¥s</h1>õ   RÃ¤ksmÃ¶rgÃ¥s©r   )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(t‚d S )Nu&   <h1 id="RÃ¤ksmÃ¶rgÃ¥s">here it is</h1>z
here it isr   ©Úid)r   Ústrr   Útextr   r   r   r   r   Útest_unicode_attribute_find*   s    
z$TestFind.test_unicode_attribute_findc                 C   s"   |   d¡}dt| ¡ ƒkst‚dS )z)Test an optimization that finds all tags.ú<a>foo</a><b>bar</b>é   N©r   ÚlenÚfind_allr   r   r   r   r   Útest_find_everything/   s    
zTestFind.test_find_everythingc                 C   s$   |   d¡}dt| d¡ƒks t‚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t‚d| d¡ ¡ jks4t‚d| d¡ ¡ jksLt‚d S )Nz<div></div><p></p>ÚdivÚp©r   r   Únamer   Ú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t‚d| d¡ ¡ jks4t‚d| d¡ ¡ jksLt‚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 t‚dt| d¡ ¡ ƒks:t‚dt| d¡ ¡ ƒksTt‚d S )Nz/<body>text<div>text</div>text<p>text</p></body>r!   r
   r)   r(   )r   r#   Úbodyr$   r   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   sz   |   d¡}|jdddgks t‚|jddgdddgks<t‚|jt d¡ddddgks\t‚|jdddddgksvt‚dS )	z'You can search the tree for text nodes.u   <html>Foo<b>bar</b>Â»</html>Úbarr   ÚFooz.*õ   Â»TN)r   r$   r   ÚreÚcompiler   r   r   r   Útest_find_all_text_nodesO   s
    
 z$TestFindAll.test_find_all_text_nodesc                 C   s‚   |   d¡}|  |jddddddg¡ |  |jddddg¡ |  |jdd	ddddd
dg¡ |  |jddddddd
dg¡ 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
   é
   Ú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@   rB   Úfoor   rC   )r   rH   r   r   r   r   r   Ú%test_calling_a_tag_is_calling_findallf   s    
z1TestFindAll.test_calling_a_tag_is_calling_findallc              	   C   sp   |   d¡}g }| |¡ tjddB}g | |¡ks8t‚|\}|jtksLt‚t|j	ƒ}|dksbt‚W 5 Q R X d S )Nú<a></a>T©ÚrecordzLIgnoring nested list [[...]] to avoid the possibility of infinite recursion.)
r   ÚappendÚwarningsÚcatch_warningsr$   r   Ú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"t‚| d¡}t|dƒs:t‚|jdd}t|dƒsTt‚dS )z%All find_all calls return a ResultSetrL   r&   ÚsourceTrJ   r   N)r   r$   Úhasattrr   ©r   r   Úresultr   r   r   Útest_find_all_resultset   s    


z#TestFindAll.test_find_all_resultsetN)
r0   r1   r2   r3   r8   r>   rI   rK   rY   r^   r   r   r   r   r4   F   s   
r4   c                   @   s   e Zd Zdd„ ZdS )ÚTestFindAllBasicNamespacesc                 C   s<   |   d¡}d| d¡jkst‚d|jddidjks8t‚d S )Nz0<mathml:msqrt>4</mathml:msqrt><a svg:fill="red">rE   zmathml:msqrtr&   zsvg:fillZred©Úattrs)r   r   r   r   r+   r   r   r   r   Útest_find_by_namespaced_name   s    
z7TestFindAllBasicNamespaces.test_find_by_namespaced_nameN)r0   r1   r2   rb   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.©rH   rg   r$   rh   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&   rk   r   Trl   Útag©rH   rg   r$   r<   r=   rh   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&   rl   )rH   rg   Úcr$   rh   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 rj   )rH   rg   rh   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 rj   )rH   rg   r$   r	   rh   r   r   r   Útest_find_all_by_tag_strainer´   s     ÿz/TestFindAllByName.test_find_all_by_tag_strainerc                 C   s"   |   | j ddg¡dddg¡ d S )Nr&   r   rk   úSecond tag.rl   rm   rh   r   r   r   Útest_find_all_by_tag_names¹   s     ÿz,TestFindAllByName.test_find_all_by_tag_namesc                 C   s$   |   | j dddœ¡dddg¡ d S )NT)r&   r   rk   rv   rl   rm   rh   r   r   r   Útest_find_all_by_tag_dict¾   s    þz+TestFindAllByName.test_find_all_by_tag_dictc                 C   s$   |   | j t d¡¡dddg¡ d S )Nz^[ab]$rk   rv   rl   rp   rh   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©ro   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.rG   )r   r}   rg   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sJt‚d|jksXt‚d|jksft‚d|jkstt‚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 brC   rB   )r   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)r0   r1   r2   r3   ri   rn   rq   rs   rt   ru   rw   rx   ry   r~   r   r   r   r   r   rc   “   s   rc   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.rG   ©r   rg   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s6t‚|jg|j| d¡dksTt‚|jgspt|j|dgdƒ‚d S )Nu   ××•×œ×©Úutf8u   <a title="××•×œ×©"></a>)Útitlezsomething else)Úencoder   r&   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.rG   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&   rB   ©Úclass_zClass 1.rr   rC   zClass 3 and 4.rE   r`   rG   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=   rH   )r   rg   Ú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   rH   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s0t| dd¡ƒ‚|gsFt| dd¡ƒ‚|g|jdddks^t‚|g| dd¡kstt‚g | dd¡ksˆt‚d S )Nz*<a class="foo bar"></a><a class="foo"></a>r&   rJ   r9   zfoo barr   zbar foo©r   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	   rH   r$   )r   rg   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.rG   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.rG   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   rB   rG   )r   rg   Úexpectedr   r   r   Ú$test_find_all_with_numeric_attribute]  s    
z;TestFindAllByAttribute.test_find_all_with_numeric_attributec                 C   s@   |   d¡}|  |jdddg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>rB   rC   rE   r   rG   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(t‚g |jdddks>t‚d S )Nz<b>foo</b><b>bar</b><a>foo</a>r&   rJ   r   r9   ©r   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&t‚d S )Nz"<a>foo</a><a><b><c>foo</c></b></a>r&   rJ   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(t‚g |jdddks>t‚d S )Nz"<b id="1">foo</b><a id="2">foo</a>r!   rJ   )r   r   r
   r9   r§   r¨   r   r   r   Ú,test_find_by_attribute_and_containing_string‰  s    
zCTestFindAllByAttribute.test_find_by_attribute_and_containing_stringN)r0   r1   r2   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ksŒt‚d
t	|j
ƒksžt‚| ¡  dt	|j
ƒks¸t‚d|j
d ksÊt‚d|jjksÚt‚d|j
d ksìt‚d|j
d ksþt‚d S )Nz<div>a</div>r   rr   z	Comment 1z	Comment 2ÚdÚspanrB   r   é   é   Úabcr   Z12r
   r!   )r   r(   rO   r   Údefault_builderr   r®   r   r   r#   ÚcontentsZsmooth)r   r   r(   Úbuilderr®   r   r   r   Útest_smooth”  s(    






zTestSmooth.test_smoothN)r0   r1   r2   r3   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   sZ   |   d¡}|j}t|jƒD ]\}}|| |¡kst‚qt t¡ | d¡ W 5 Q R X 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³   Úindexr   ÚpytestÚraisesÚ
ValueError)r   rg   r(   ÚiÚelementr   r   r   Ú
test_indexÀ  s    
	zTestIndex.test_indexN)r0   r1   r2   r3   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.Nrd   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   rg   r   Ústartrh   r   r   r   ri   Ô  s    z!TestParentOperations.setup_methodc                 C   sF   | j jd dkst‚| j jjd dks*t‚| j jjjd dksBt‚d S )Nr   ÚbottomÚmiddleÚtop)rÀ   Úparentr   rh   r   r   r   Útest_parentÞ  s    z TestParentOperations.test_parentc                 C   s    | j jd }|j| j kst‚d S )Nr   )rg   r³   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kst‚d S ©N)rg   rÄ   r   rh   r   r   r   Útest_soup_object_has_no_parentç  s    z3TestParentOperations.test_soup_object_has_no_parentc                 C   sN   |   | j d¡dddg¡ |   | jjddddg¡ | jjddg ksJt‚d S )NÚulrÁ   rÂ   rÃ   r   rÀ   )Úassert_selects_idsrÀ   Úfind_parentsr   rh   r   r   r   Útest_find_parentsê  s    
 ÿz&TestParentOperations.test_find_parentsc                 C   s6   | j jdddd dkst‚| j jddd ks2t‚d S )NrÉ   rÃ   r   r   rÀ   )rÀ   Úfind_parentr   rh   r   r   r   Útest_find_parentñ  s    z%TestParentOperations.test_find_parentc                 C   s"   | j jdd}|jjdkst‚d S )Nú
Start herer   r   )rg   r   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$t‚d S )NrÏ   r   rÉ   r   rÁ   )rg   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 ƒ}|dddgks$t‚d S )Nc                 S   s&   g | ]}|d k	rd|j kr|d ‘qS rz   r`   ©Ú.0rÄ   r   r   r   Ú
<listcomp>   s    
þz>TestParentOperations.test_parent_generator.<locals>.<listcomp>rÁ   rÂ   rÃ   )rÀ   Úparentsr   )r   rÖ   r   r   r   Útest_parent_generatorÿ  s    þz*TestParentOperations.test_parent_generatorc                 C   s*   dd„ | j jD ƒ}|ddddgks&t‚d S )Nc                 S   s&   g | ]}|d k	rd|j kr|d ‘qS rz   r`   rÓ   r   r   r   rÕ     s    
þzGTestParentOperations.test_self_and_parent_generator.<locals>.<listcomp>rÀ   rÁ   rÂ   rÃ   )rÀ   Zself_and_parentsr   )r   Úresultsr   r   r   Útest_self_and_parent_generator  s    þz3TestParentOperations.test_self_and_parent_generator)r0   r1   r2   r3   ri   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 )ÚProximityTestNrd   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>rf   rh   r   r   r   ri     s    ÿzProximityTest.setup_method©r0   r1   r2   ri   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 )ÚTestNextOperationsNrd   c                    s   t t| ƒ ¡  | jj| _d S rÇ   )ÚsuperrÜ   ri   rg   r   rÀ   rh   ©Ú	__class__r   r   ri     s    zTestNextOperations.setup_methodc                 C   s*   | j jdkst‚| j jjd dks&t‚d S )NÚOner   r   )rÀ   Únext_elementr   rh   r   r   r   Ú	test_next  s    zTestNextOperations.test_nextc                 C   s    | j jdd}|jd kst‚d S ©NÚThreer   )rg   r   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 kst‚d S rÇ   )rg   rá   r   rh   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   )rH   rÀ   Úfind_all_nextrh   r   r   r   Útest_find_all_next(  s    z%TestNextOperations.test_find_all_nextc                 C   s2   | j  d¡d dkst‚| j jdddks.t‚d S )Nr   r   r   rä   r   )rÀ   Ú	find_nextr   rh   r   r   r   Útest_find_next-  s    z!TestNextOperations.test_find_nextc                 C   s<   | j jdd}| d¡jdks"t‚|  | d¡ddg¡ d S )Nrà   r   r   rè   rä   )rg   r   rë   r   r   rH   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s6t‚|dksBt‚dd„ |jD ƒ}|d	d … |ksft‚|d
 |ksvt‚d S )Nrè   r   c                 S   s   g | ]}|‘qS r   r   ©rÔ   Únoder   r   r   rÕ   8  s     z;TestNextOperations.test_next_generators.<locals>.<listcomp>r   rC   rä   c                 S   s   g | ]}|‘qS r   r   rî   r   r   r   rÕ   >  s     r
   r   )rg   r   Únext_elementsr   Zself_and_next_elements)r   rÀ   Ú
successorsro   r³   Zsuccessors2r   r   r   Útest_next_generators6  s    z'TestNextOperations.test_next_generators)r0   r1   r2   ri   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 )ÚTestPreviousOperationsNrd   c                    s"   t t| ƒ ¡  | jjdd| _d S rã   )rÝ   rô   ri   rg   r   Úendrh   rÞ   r   r   ri   D  s    z#TestPreviousOperations.setup_methodc                 C   s*   | j jd dkst‚| j jjdks&t‚d S )Nr   rC   rè   )rõ   Úprevious_elementr   rh   r   r   r   Útest_previousH  s    z$TestPreviousOperations.test_previousc                 C   s   | j  d¡}|jd kst‚d S )NÚhtml)rg   r   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 kst‚d S rÇ   )rg   rö   r   rh   r   r   r   Útest_previous_of_root_is_noneP  s    z4TestPreviousOperations.test_previous_of_root_is_nonec                 C   s6   |   | j d¡dddg¡ |   | jjdddg¡ d S )Nr   rä   rè   rà   r
   r   )rH   rõ   Úfind_all_previousrh   r   r   r   Útest_find_all_previousT  s    z-TestPreviousOperations.test_find_all_previousc                 C   s2   | j  d¡d dkst‚| j jdddks.t‚d S )Nr   r   rC   rà   r   )rõ   Úfind_previousr   rh   r   r   r   Útest_find_previous[  s    z)TestPreviousOperations.test_find_previousc                 C   s>   | j jdd}| d¡jdks"t‚|  | d¡dddg¡ d S )Nrä   r   r   rè   rà   )rg   r   rý   r   r   rH   rû   rÐ   r   r   r   Ú#test_find_previous_for_text_element_  s    z:TestPreviousOperations.test_find_previous_for_text_elementc                 C   s>   | j jddd}|  |jdddg¡ |  |jddddg¡ d S )Nr   rà   r   ZbodytagZheadtagrÀ   rB   )rg   r   rÊ   Úprevious_elementsZself_and_previous_elements)r   rÀ   r   r   r   Útest_previous_generatorsd  s    z/TestPreviousOperations.test_previous_generators)r0   r1   r2   ri   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 )ÚSiblingTestNrd   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   rg   )r   Úmarkupr   r   r   ri   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 )ÚTestNextSiblingNrd   c                    s"   t t| ƒ ¡  | jjdd| _d S )NrB   r   )rÝ   r  ri   rg   r   rÀ   rh   rÞ   r   r   ri     s    zTestNextSibling.setup_methodc                 C   s   | j jd kst‚d S rÇ   )rg   Únext_siblingr   rh   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t‚| j jjd dks*t‚| j jd dks>t‚d S )Nr   r   rC   ú1.1)rÀ   r  r   rá   rh   r   r   r   Útest_next_sibling†  s    z!TestNextSibling.test_next_siblingc                 C   sN   | j jjd kst‚| j jdd}|jd ks.t‚| j jdd}|jd ksJt‚d S )Nr	  r   rE   )rg   rø   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t‚d S )Nr®   r   r   )rÀ   r-   r   rh   r   r   r   Útest_find_next_sibling–  s    z&TestNextSibling.test_find_next_siblingc                 C   s6   |   | j d¡dddg¡ |   | jjdddg¡ d S )Nr®   r   rC   rE   r   )rÊ   rÀ   r7   rh   r   r   r   Útest_next_siblings™  s    z"TestNextSibling.test_next_siblingsc                 C   s2   |   | jjdddg¡ |   | jjddddg¡ d S )Nr   rC   rE   rB   )rÊ   rÀ   Únext_siblingsZself_and_next_siblingsrh   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&t‚|jjdks6t‚|  | d¡dg¡ |jdddks^t‚|jddd ksrt‚d S )NúFoo<b>bar</b>bazr:   r   r   Úbazr9   Únonesuch)r   r   r  r+   r   rH   r7   r-   ©r   r   rÀ   r   r   r   Ú"test_next_sibling_for_text_element¢  s    
z2TestNextSibling.test_next_sibling_for_text_element)r0   r1   r2   ri   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 )ÚTestPreviousSiblingNrd   c                    s"   t t| ƒ ¡  | jjdd| _d S )NrE   r   )rÝ   r  ri   rg   r   rõ   rh   rÞ   r   r   ri   ®  s    z TestPreviousSibling.setup_methodc                 C   s   | j jd kst‚d S rÇ   )rg   Úprevious_siblingr   rh   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t‚| j jjd dks*t‚| j jd dks>t‚d S )Nr   rC   r   z3.1)rõ   r  r   rö   rh   r   r   r   Útest_previous_siblingµ  s    z)TestPreviousSibling.test_previous_siblingc                 C   sN   | j jjd kst‚| j jdd}|jd ks.t‚| j jdd}|jd ksJt‚d S )Nr	  r   rB   )rg   rø   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t‚d S )Nr®   r   rC   )rõ   r,   r   rh   r   r   r   Útest_find_previous_siblingÅ  s    z.TestPreviousSibling.test_find_previous_siblingc                 C   s6   |   | j d¡dddg¡ |   | jjdddg¡ d S )Nr®   rC   r   rB   r   )rÊ   rõ   r6   rh   r   r   r   Útest_previous_siblingsÈ  s
    
 ÿz*TestPreviousSibling.test_previous_siblingsc                 C   s2   |   | jjdddg¡ |   | jjddddg¡ d S )NrC   r   rB   rE   )rÊ   rõ   Úprevious_siblingsZself_and_previous_siblingsrh   r   r   r   Ú!test_previous_siblings_generatorsÏ  s    z5TestPreviousSibling.test_previous_siblings_generatorsc                 C   sv   |   d¡}|jdd}|jjdks&t‚|jjdks6t‚|  | d¡dg¡ |jdddks^t‚|jddd ksrt‚d S )Nr  r  r   r   r:   r9   r  )r   r   r  r+   r   rH   r6   r,   r  r   r   r   Ú&test_previous_sibling_for_text_elementÓ  s    
z:TestPreviousSibling.test_previous_sibling_for_text_element)r0   r1   r2   ri   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 dhdidjdkdldmdndog¡dpdq„ ƒZ5drds„ Z6dtdu„ Z7dvdw„ Z8dxdy„ Z9dzd{„ Z:d|S )}ÚTestTreeModificationc                 C   sl   |   d¡}d|jd< | ¡ |  d¡ks*t‚|jd= | ¡ |  d¡ksHt‚d|jd< | ¡ |  d¡ksht‚d S )	Nz<a id="1"></a>r!   r   z<a id="2"></a>rL   rJ   Zid2z<a id2="foo"></a>)r   r&   r‡   Údocument_forr   r   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sht‚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   r5   Úinsertr†   r   )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sBt‚| ¡ |  d¡ksXt‚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   rO   rÄ   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s2t‚| d| d¡¡\}|jdksTt‚| d¡}|dksjt‚| dd¡}|ddgks†t‚| d	d
¡}|d	d
gks¢t‚| 	ddg¡}|ddgksÀt‚| 
¡ dksÐt‚d S )Nz<html></html>rø   Úheadr   r…   rF   rC   rE   Ú6Ú7Ú8Ú9Z3456789)r   r   rO   Únew_tagr+   r   r'  Úinsert_beforeÚinsert_afterÚextendZget_text)	r   r   rø   r+  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,t‚d S )Nz<a></a><b><c></c></b>)r   r&   Úreplace_withrr   r   ©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(t‚d S )Nú<a><b></b><c></c></a>)r   r&   Úunwrapr   r6  r   r   r   Ú+test_unwrap_returns_thing_that_was_replaced   s
    
z@TestTreeModification.test_unwrap_returns_thing_that_was_replacedc              	   C   sj   |   d¡}|j}| ¡  d |jks&t‚t t¡ | ¡  W 5 Q R X t t¡ | 	|j
¡ W 5 Q R X d S )Nz<a><b>Foo</b></a><c>Bar</c>)r   r&   ÚextractrÄ   r   r¹   rº   r»   r:  r5  rr   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,t‚| ¡ |  |¡ksBt‚d S )Nz-<a><b></b><c>Foo<d></d></c></a><a><e></e></a>)r   rr   r5  r   r‡   r!  )r   r   r   rr   r]   r   r   r   Útest_replace_tag_with_itself1  s    
z1TestTreeModification.test_replace_tag_with_itselfc              	   C   s6   d}|   |¡}t t¡ |j |j¡ W 5 Q R X d S ©Nú<a><b></b></a>)r   r¹   rº   r»   r   r5  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   s8   d}|   |¡}t t¡ |j d|j¡ W 5 Q R X d S )Nr@  r   )r   r¹   rº   r»   r&   r'  rA  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>t‚d|jksLt‚t|jƒ\}}}}d|jkslt‚d|jkszt‚d|jksˆt‚d|jks–t‚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'  r0  r   r   ÚlistÚchildren)r   r   rE  rF  Úp1Úp4r   r   r   Útest_insert_multiple_elementsE  s    
&z2TestTreeModification.test_insert_multiple_elementsc           	      C   s¬   |   d¡}d}|   |¡}| d|¡\}}d|jks6t‚d|jksDt‚|jD ]}t|tƒrJt‚qJt|jƒ\}}}}d|jks~t‚d|jksŒt‚d|jksšt‚d|jks¨t‚dS )	z”Inserting one BeautifulSoup object into another actually inserts all
        of its children -- you'll never combine BeautifulSoup objects.
        rD  z<p>p2</p><p>p3</p>r
   rE  rF  rG  rH  N)	r   r'  r   r   ÚdescendantsÚ
isinstancer   rI  rJ  )	r   r   r   Z	to_insertrE  rF  r¼   rK  rL  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sJt‚d S )Nz<p><a>one</a><b>three</b></p>r
   Ztwor  Zthree)r   r&   r'  r³   r5  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<t‚|j|ksJt‚|jj|ksZt‚|jd ksht‚d S )Nz<b>Argh!</b>úArgh!r   úHooray!)r   r   r5  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.t‚|jdd}|jdksHt‚|jj|ksXt‚|j	dksft‚|j	j
|ksvt‚|j
d ks„t‚|j|jks”t‚d S )Nz<a><b>Argh!</b><c></c></a>r
   rU  z!<a><b>Argh!Hooray!</b><c></c></a>r   rT  )r   r   r'  r‡   r!  r   r   rö   rá   r  r  rr   )r   r   rV  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:t‚|jjd jdksPt‚d S )NrL   r   r9   rJ   )r   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"t‚|j ¡ dks4t‚d S )Nz<b>1</b>r   z	<b>12</b>)r   r   rO   r   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sRt‚|j}|j	|ksft‚|j
|kstt‚|jdd	}|j|ksŽt‚|j|ksœt‚|j}|j	|ks°t‚|j
|ks¾t‚|jdd	}|j|ksØt‚|j|ksæt‚|j|ksôt‚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á   rö   rr   rÄ   )r   r´   r   Z	magic_tagZb_tagr   Zc_tagr[  r   r   r   Útest_insert_tag   s*    
ÿ
z$TestTreeModification.test_insert_tagc                 C   s2   d}|   |¡}|j d|j¡ || ¡ ks.t‚d S )Nz<a>b<c></c>d</a>r
   )r   r&   r'  rr   r‡   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,t‚d S r?  )r   r&   rO   r   r‡   r   r]  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sFt
‚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­   rr   r   r&   r3  r‡   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:t‚d S )NrL   r   rr   r­   ra  z<a>bcde</a>)r   r   r&   r3  r‡   r   rb  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>×  ó    zTestTreeModification.<lambda>c                 C   s   | j S rÇ   )r³   r|   r   r   r   rg  ×  rh  c                 C   s`   d}|   |¡}|jddd}|jddd}||ƒ}| |¡ d| ¡ ksLt‚d| ¡ ks\t‚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   r3  r‡   r   )r   rf  rˆ   r   ri  rj  Ú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   rg  å  rh  z<a></a><b>1</b>c                 C   s   dS )NZabcder   rm  r   r   r   rg  æ  rh  z<a>1</a><b>abcde</b>c           	   	   C   sz   d}|   |¡}tjddV}||ƒ}|j |¡ |j ¡ |ksBt‚|\}|jt	ksVt‚t
|jƒ}|dkslt‚W 5 Q R X d S )Nz<div><a>1</a><b></b></div>TrM   zIA single non-Tag item was passed into Tag.extend. Use Tag.append instead.)r   rP   rQ   r   r3  r(   Zdecode_contentsr   rR   rS   r   rT   )	r   Zstring_sourcer]   rˆ   r   rV   r   rW   rX   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.t‚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‡   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*t‚d S )Nz<br/>r
   ZContentsz<br>Contents</br>)r   Úbrr'  r   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s8t‚|j |j¡ | ¡ |  d¡ks\t‚|j}t t	¡ | |¡ W 5 Q R X | 
¡  t t	¡ | d¡ W 5 Q R X |   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   r1  r&   r‡   r!  r   r¹   rº   r»   r<  r0  ©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@t‚|j |jd¡ | ¡ |  d¡ksft‚d S )Nr    rr  ú rs  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   r1  r&   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s8t‚|j |j¡ | ¡ |  d¡ks\t‚|j}t t	¡ | |¡ W 5 Q R X | 
¡  t t	¡ | d¡ W 5 Q R X |   d¡}|j | d¡¡ d S )	Nr    rr  rs  z<a>foo</a>QUUX<b>bar</b>BAZrt  ru  rv  r&   )r   r   r2  r&   r‡   r!  r   r¹   rº   r»   r<  r1  r0  rw  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@t‚|j |jd¡ | ¡ |  d¡ksft‚d S )Nr    rr  ry  rs  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   r2  r&   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 5 Q R X t t¡ | |¡ W 5 Q R X t t¡ | |¡ W 5 Q R X d S ©Nr  r&   )r   r0  Ú
new_stringr¹   rº   r»   r2  ÚNotImplementedError©r   r   ro   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 5 Q R X t t¡ | |¡ W 5 Q R X t t¡ | |¡ W 5 Q R X d S r}  )r   r0  r~  r¹   rº   r»   r1  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s8t‚|jd ksFt‚|j|jksVt‚|jdksdt‚|j	dksrt‚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$   r5  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 5 Q R X |  d¡j}t t¡ |j |¡ W 5 Q R X t t¡ |j d|d¡ W 5 Q R X d S )Nr&   rŠ   z
won't workr@  Zstring1Zstring2)r   r¹   rº   r»   r5  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sXt‚|jj|ksht‚|jj|ksxt‚|jj|ksˆt‚|jj|ks˜t‚d S )Nr9  r­   zText In D Tagra  r’   zRandom Textz;<a><b></b><d>Text In D Tag</d><e></e>Random Text<f></f></a>)	r   r0  r   rr   r5  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,t‚d S )Nr9  z<a><c></c></a>)r   r   r5  rr   r‡   r   r]  r   r   r   Útest_replace_first_child•  s    
z-TestTreeModification.test_replace_first_childc                 C   s0   d}|   |¡}|j |j¡ d| ¡ ks,t‚d S )Nr9  r@  )r   rr   r5  r   r‡   r   r]  r   r   r   Útest_replace_last_child›  s    
z,TestTreeModification.test_replace_last_childc                 C   s  |   d¡}|j}|j}| |¡ | ¡ |  d¡ks6t‚|jd ksDt‚|jddj	d ksZt‚|j
d ksht‚|jd ksvt‚|jd ks„t‚|j|jks”t‚|j
dks¢t‚|j	j	|jks´t‚|jd ksÂt‚|jdd}|j}|j	|ksât‚|j|ksðt‚|j
|ksþt‚|j|kst‚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>rR  r   ZWeÚto)r   r   r’   r5  r‡   r!  r   rÄ   r   rá   rö   r  r  r&   ra  r`  )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 ks"t‚|jjdks2t‚d S )NzI
            <p>Unneeded <em>formatting</em> is unneeded</p>
            zUnneeded formatting is unneeded)r   Úemr:  r   r)   r   r‚   r   r   r   Útest_unwrapÆ  s    

z TestTreeModification.test_unwrapc                 C   sF   |   d¡}|j | d¡¡}| ¡ dks,t‚| ¡ |  d¡ksBt‚d S )NzI wish I was bold.r   ú<b>I wish I was bold.</b>)r   r   Úwrapr0  r‡   r   r!  )r   r   r˜   r   r   r   Ú	test_wrapÎ  s    
zTestTreeModification.test_wrapc                 C   s4   |   d¡}|jj |j¡ | ¡ |  d¡ks0t‚d S )Nz<b></b>I wish I was bold.rŽ  )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.t‚| ¡ |  d¡ksDt‚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   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t‚|jdd ¡ }| ¡ dks>t‚| ¡ dksNt‚t|jjƒdksbt‚|jd kspt‚|j	d ks~t‚|j
j
d ksŽt‚|jdd	}|jd
d	}|j
|ks´t‚|j|ksÂt‚|j	|ksÐt‚|j|ksÞt‚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#   r5   r³   r   r   r<  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^t‚||jjksnt‚d S )Nr    rJ   r9   )r   r&   r   r~  rO   r   r<  r   )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s4t‚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   )Úscriptr<  )rÔ   r¼   rm  r   r   rÕ     s     zKTestTreeModification.test_extract_multiples_of_same_tag.<locals>.<listcomp>r–  z<body>

<a></a>
</body>)r   r$   r   r5   r   rh   r   rm  r   Ú"test_extract_multiples_of_same_tag
  s    
z7TestTreeModification.test_extract_multiples_of_same_tagc                 C   s.   |   d¡}| d¡ ¡  d | d¡ks*t‚d S )Nz<html>
<body>hi</body>
</html>r5   )r   r   r<  r   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.t‚t|dƒs<t‚|j}|jdd dt|jƒks`t‚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³   r   r[   rŒ  )r   r   r&   rŒ  r   r   r   Ú
test_clear  s    

zTestTreeModification.test_clearzmethod_name,expected_result)rN  ú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œ  )rJ  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s8t‚d S )NzU<div><em>child1</em><p id='start'><a>Second <em>child</em></a></p><p>child3</p></div>)r   Úgetattrr)   r<  r‡   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ks2t‚q2| ¡  |||fD ]}d|jksXt‚qXd|jkszt‚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   r   rK  rE  r&   r   r¼   r   r   r   Útest_decomposeQ  s    
z#TestTreeModification.test_decomposec                 C   sP   |   d¡}|j}|jj}d|jks&t‚| ¡  d|jks<t‚d| ¡ ksLt‚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   r   Útest_decompose_stringa  s    
z*TestTreeModification.test_decompose_stringc                 C   sB   |   d¡}d|j_|jjdgks$t‚d|j_|jjdgks>t‚dS )zTag.string = 'string'z<a></a> <b><c></c></b>rJ   r9   N)r   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(t‚d S )Nz<a><b>foo</b><c>bar</c>s   <a><b>bar</b><c>bar</c></a>)r   rr   r   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,t‚d S )NrL   rJ   )r   r   r&   r   rO  r   )r   r   Úcdatar   r   r   Ú)test_set_string_preserves_class_of_stringw  s    
z>TestTreeModification.test_set_string_preserves_class_of_stringN);r0   r1   r2   r"  r(  r*  r4  r8  r;  r=  r>  rB  rC  rM  rP  rS  rW  rX  rY  rZ  r\  r^  r_  rd  re  r¹   ÚmarkÚparametrizerl  rn  ro  rq  rx  rz  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-   r7   r,   r6   c                   @   s"   e Zd Zej de¡dd„ ƒZdS )ÚTestDeprecatedArgumentsrž  c              	   C   sf   |   d¡}t|j|ƒ}tjdd:}|dd |\}|jtksBt‚t|j	ƒ}|dksXt‚W 5 Q R X d S )Nú<a>some</a><b>markup</b>TrM   r  )r   zOThe 'text' argument to find()-type methods is deprecated. Use 'string' instead.)
r   r  r   rP   rQ   rR   rS   r   r   rT   ©r   rž  r   ÚmethodrV   rW   rX   r   r   r   Útest_find_type_method_string  s    


ÿÿz4TestDeprecatedArguments.test_find_type_method_stringN)r0   r1   r2   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   sv   |   d¡}t|j|ƒ}tjddJ}|dd |\}|jtksBt‚t|j	t
ƒsRt‚t|j	ƒ}d|ksht‚W 5 Q R X d S )Nr«  TrM   Úu)Ú_classzN'_class' is an unusual attribute name and is a common misspelling for 'class_')r   r  r   rP   rQ   rR   rS   r   rO  rT   r   r   r¬  r   r   r   Útest_suspicious_syntax_warningŸ  s    


ÿÿz+TestWarnings.test_suspicious_syntax_warningN)r0   r1   r2   r¹   r¨  r©  r¯  r³  r   r   r   r   r°  ž  s   r°  )$r3   r¹   r<   rP   Zbs4r   Zbs4.builderr   Zbs4.elementr   r   r   r   r   Z
bs4.filterr	   r  r   r   r4   r_   rc   r€   r¬   r¶   r¿   rÚ   rÜ   rô   r  r  r  r   r¯  rª  r°  r   r   r   r   Ú<module>   sX   
(FP /,?,'/1     &ô