U
    Ñ~fh"×  ã                   @   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                   @   sP   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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-khbgcco8/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 )Nú"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_tagsc                 C   s<   |   d¡}d| dd„ ¡jks"t‚d | dd„ ¡ks8t‚d S )Nr/   r)   c                 S   s
   | j dkS )Nr)   ©r+   ©Útr   r   r   Ú<lambda>G   ó    zETestFind.test_find_with_function_can_only_find_tags.<locals>.<lambda>c                 S   s   | dkS )Nr   r   r2   r   r   r   r4   H   r5   )r   r   r+   r   r   r   r   r   Ú*test_find_with_function_can_only_find_tagsE   s    
z3TestFind.test_find_with_function_can_only_find_tagsN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r%   r'   r.   r0   r6   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_tagsM   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_nodesS   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
   rG   rI   Úfoor   rJ   )r   rO   r   r   r   r   r   Ú%test_calling_a_tag_is_calling_findallj   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_recursiono   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 ResultSetrS   r&   ÚsourceTrQ   r   N)r   r$   Úhasattrr   ©r   r   Úresultr   r   r   Útest_find_all_resultsetƒ   s    


z#TestFindAll.test_find_all_resultsetN)
r7   r8   r9   r:   r?   rE   rP   rR   r`   re   r   r   r   r   r;   J   s   
r;   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">rL   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)r7   r8   r9   ri   r   r   r   r   rf      s   rf   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.©rO   rn   r$   ro   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&   rr   r   Trs   Útag©rO   rn   r$   rC   rD   ro   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&   rs   )rO   rn   Úcr$   ro   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 rq   )rO   rn   ro   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 rq   )rO   rn   r$   r	   ro   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   rr   úSecond tag.rs   rt   ro   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   rr   r}   rs   rt   ro   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]$rr   r}   rs   rw   ro   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©rv   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.rN   )r   r„   rn   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 brJ   rI   )r   r   rC   rD   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)r7   r8   r9   r:   rp   ru   rx   rz   r{   r|   r~   r   r€   r…   r†   r   r   r   r   rj   —   s   rj   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.rN   ©r   rn   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name1r1   zA tag called 'name1'.r+   rg   zName match.ÚclassZclass2zClass match.rN   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&   rI   ©Úclass_zClass 1.ry   rJ   zClass 3 and 4.rL   rg   rN   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$   rC   rD   rO   )r   rn   Ú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 ©NrF   ©r#   ©Úvaluer   r   r   Úbig_attribute_value3  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_value8  s    zpTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.small_attribute_value©r   rO   r$   rC   rD   )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&   rQ   r@   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_classes=  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ˆ   rg   zMatch.)r   r	   rO   r$   )r   rn   Zstrainerr   r   r   Ú'test_find_all_by_attribute_soupstrainerI  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.rN   r‰   r   r   r   Ú$test_find_all_with_missing_attributeQ  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.rN   r‰   r   r   r   Ú$test_find_all_with_defined_attributeY  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   rI   rN   )r   rn   Úexpectedr   r   r   Ú$test_find_all_with_numeric_attributea  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>rI   rJ   rL   r   rN   r‰   r   r   r   Ú(test_find_all_with_list_attribute_valuesj  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_valuev  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&   rQ   r   r@   ©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&   rQ   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!   rQ   )r   r   r
   r@   r­   r®   r   r   r   Ú,test_find_by_attribute_and_containing_string  s    
zCTestFindAllByAttribute.test_find_by_attribute_and_containing_stringN)r7   r8   r9   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   ry   z	Comment 1z	Comment 2ÚdÚspanrI   r   é   é   Úabcr   Z12r
   r!   )r   r(   rV   r   Údefault_builderr   r´   r   r   r#   ÚcontentsZsmooth)r   r   r(   Úbuilderr´   r   r   r   Útest_smooth˜  s(    






zTestSmooth.test_smoothN)r7   r8   r9   r:   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   rn   r(   ÚiÚelementr   r   r   Ú
test_indexÄ  s    
	zTestIndex.test_indexN)r7   r8   r9   r:   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.Nrk   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   rn   r   Ústartro   r   r   r   rp   Ø  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   ro   r   r   r   Útest_parentâ  s    z TestParentOperations.test_parentc                 C   s    | j jd }|j| j kst‚d S )Nr   )rn   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)rn   rÊ   r   ro   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   ro   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   ro   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   )rn   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Ç   )rn   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 r   rg   ©Ú.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 r   rg   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)r7   r8   r9   r:   rp   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 )ÚProximityTestNrk   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>rm   ro   r   r   r   rp     s    ÿzProximityTest.setup_method©r7   r8   r9   rp   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 )ÚTestNextOperationsNrk   c                    s   t t| ƒ ¡  | jj| _d S rÍ   )Úsuperrâ   rp   rn   r   rÆ   ro   ©Ú	__class__r   r   rp     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   ro   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   )rn   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Í   )rn   rç   r   ro   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ê   rF   r   )rO   rÆ   Úfind_all_nextro   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   ro   r   r   r   Útest_find_next1  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ê   )rn   r   rñ   r   r   rO   rï   rÖ   r   r   r   Útest_find_next_for_text_element5  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Û   <  s     z;TestNextOperations.test_next_generators.<locals>.<listcomp>r   rJ   rê   c                 S   s   g | ]}|‘qS r   r   rô   r   r   r   rÛ   B  s     r
   r   )rn   r   Únext_elementsr   Zself_and_next_elements)r   rÆ   Ú
successorsrv   r¹   Zsuccessors2r   r   r   Útest_next_generators:  s    z'TestNextOperations.test_next_generators)r7   r8   r9   rp   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 )ÚTestPreviousOperationsNrk   c                    s"   t t| ƒ ¡  | jjdd| _d S ré   )rã   rú   rp   rn   r   Úendro   rä   r   r   rp   H  s    z#TestPreviousOperations.setup_methodc                 C   s*   | j jd dkst‚| j jjdks&t‚d S )Nr   rJ   rî   )rû   Úprevious_elementr   ro   r   r   r   Útest_previousL  s    z$TestPreviousOperations.test_previousc                 C   s   | j  d¡}|jd kst‚d S )NÚhtml)rn   r   rü   r   )r   rˆ   r   r   r   Ú#test_previous_of_first_item_is_noneP  s    z:TestPreviousOperations.test_previous_of_first_item_is_nonec                 C   s   | j jd kst‚d S rÍ   )rn   rü   r   ro   r   r   r   Útest_previous_of_root_is_noneT  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   )rO   rû   Úfind_all_previousro   r   r   r   Útest_find_all_previousX  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   rJ   ræ   r   )rû   Úfind_previousr   ro   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æ   )rn   r   r  r   r   rO   r  rÖ   r   r   r   Ú#test_find_previous_for_text_elementc  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Æ   rI   )rn   r   rÐ   Úprevious_elementsZself_and_previous_elements)r   rÆ   r   r   r   Útest_previous_generatorsh  s    z/TestPreviousOperations.test_previous_generators)r7   r8   r9   rp   rý   rÿ   r   r  r  r  r  rù   r   r   rä   r   rú   G  s   rú   c                   @   s   e Zd Zddœdd„ZdS )ÚSiblingTestNrk   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*Ú )rC   rD   Úsubr   rn   )r   Úmarkupr   r   r   rp   o  s    zSiblingTest.setup_methodrá   r   r   r   r   r  n  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 )ÚTestNextSiblingNrk   c                    s"   t t| ƒ ¡  | jjdd| _d S )NrI   r   )rã   r  rp   rn   r   rÆ   ro   rä   r   r   rp   ƒ  s    zTestNextSibling.setup_methodc                 C   s   | j jd kst‚d S rÍ   )rn   Únext_siblingr   ro   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   rJ   ú1.1)rÆ   r  r   rç   ro   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   rL   )rn   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   ro   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   rJ   rL   r   )rÐ   rÆ   r>   ro   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   rJ   rL   rI   )rÐ   rÆ   Únext_siblingsZself_and_next_siblingsro   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>bazrA   r   r   Úbazr@   Únonesuch)r   r   r  r+   r   rO   r>   r-   ©r   r   rÆ   r   r   r   Ú"test_next_sibling_for_text_element¦  s    
z2TestNextSibling.test_next_sibling_for_text_element)r7   r8   r9   rp   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 )ÚTestPreviousSiblingNrk   c                    s"   t t| ƒ ¡  | jjdd| _d S )NrL   r   )rã   r  rp   rn   r   rû   ro   rä   r   r   rp   ²  s    z TestPreviousSibling.setup_methodc                 C   s   | j jd kst‚d S rÍ   )rn   Úprevious_siblingr   ro   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   rJ   r   z3.1)rû   r  r   rü   ro   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   rI   )rn   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   rJ   )rû   r,   r   ro   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´   rJ   r   rI   r   )rÐ   rû   r=   ro   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 )NrJ   r   rI   rL   )rÐ   rû   Úprevious_siblingsZself_and_previous_siblingsro   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   rA   r@   r  )r   r   r  r+   r   rO   r=   r,   r  r   r   r   Ú&test_previous_sibling_for_text_element×  s    
z:TestPreviousSibling.test_previous_sibling_for_text_element)r7   r8   r9   rp   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>rS   rQ   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   r<   Ú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   rV   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Œ   rM   rJ   rL   Ú6Ú7Ú8Ú9Z3456789)r   r   rV   Únew_tagr+   r   r-  Úinsert_beforeÚinsert_afterÚextendZget_text)	r   r   rþ   r1  rŒ   Ztext5Ztext34Ztext67Ztext89r   r   r   Ú&test_insertion_returns_inserted_things
  s    


z;TestTreeModification.test_insertion_returns_inserted_thingsc                 C   s0   d}|   |¡}|j}| |j¡}||ks,t‚d S )Nz<a></a><b><c></c></b>)r   r&   Úreplace_withry   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   r<  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@  r;  ry   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   ry   r;  r   rŽ   r'  )r   r   r   ry   rd   r   r   r   Útest_replace_tag_with_itself5  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   r;  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   s8   d}|   |¡}t t¡ |j d|j¡ W 5 Q R X d S )NrF  r   )r   r¿   rÀ   rÁ   r&   r-  rG  r   r   r   Ú,test_insert_tag_into_itself_raises_exceptionC  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-  r6  r   r   ÚlistÚchildren)r   r   rK  rL  Úp1Úp4r   r   r   Útest_insert_multiple_elementsI  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.
        rJ  z<p>p2</p><p>p3</p>r
   rK  rL  rM  rN  N)	r   r-  r   r   ÚdescendantsÚ
isinstancer   rO  rP  )	r   r   r   Z	to_insertrK  rL  rÂ   rQ  rR  r   r   r   Ú1test_insert_beautifulsoup_object_inserts_childrenU  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¹   r;  r   r   r   )r   r   r&   ÚleftÚrightr   r   r   Ú3test_replace_with_maintains_next_element_throughoutj  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   r;  r   rü   r   rÊ   rç   )r   r   Únew_textr   r   r   r   Útest_replace_final_nodex  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
   r[  z!<a><b>Argh!Hooray!</b><c></c></a>r   rZ  )r   r   r-  rŽ   r'  r   r   rü   rç   r  r  ry   )r   r   r\  r   r   r   Útest_consecutive_text_nodes‚  s    
z0TestTreeModification.test_consecutive_text_nodesc                 C   sT   |   d¡}|j dd¡ |j dd¡ ddg|jjks:t‚|jjd jdksPt‚d S )NrS   r   r@   rQ   )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   rV   r   rŽ   rc   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ü   ry   rÊ   )r   rº   r   Z	magic_tagZb_tagr   Zc_tagra  r   r   r   Útest_insert_tag¤  s*    
ÿ
z$TestTreeModification.test_insert_tagc                 C   s2   d}|   |¡}|j d|j¡ || ¡ ks.t‚d S )Nz<a>b<c></c>d</a>r
   )r   r&   r-  ry   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 rE  )r   r&   rV   r   rŽ   r   rc  r   r   r   Ú*test_append_child_thats_already_at_the_endÇ  s    
z?TestTreeModification.test_append_child_thats_already_at_the_endc                 C   sJ   d}|   |¡}|j|j|j|j|j|jg}|j |¡ d| 	¡ k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³   ry   r   r&   r9  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 )NrS   r   ry   r³   rg  z<a>bcde</a>)r   r   r&   r9  rŽ   r   rh  r   r   r   Ú"test_extend_with_a_list_of_stringsÔ  s
    
z7TestTreeModification.test_extend_with_a_list_of_stringsÚget_tagsc                 C   s   | S rÍ   r   rƒ   r   r   r   r4   Û  r5   zTestTreeModification.<lambda>c                 C   s   | j S rÍ   )r¹   rƒ   r   r   r   r4   Û  r5   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   r9  rŽ   r   )r   rl  r   r   rm  rn  Ú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   r4   é  r5   z<a></a><b>1</b>c                 C   s   dS )NZabcder   rq  r   r   r   r4   ê  r5   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>TrT   zIA single non-Tag item was passed into Tag.extend. Use Tag.append instead.)r   rW   rX   r   r9  r(   Zdecode_contentsr   rY   rZ   r   r[   )	r   Zstring_sourcerd   r   r   r]   r   r^   r_   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   rc  r   r   r   Ú$test_move_tag_to_beginning_of_parentü  s    
z9TestTreeModification.test_move_tag_to_beginning_of_parentc                 C   s.   |   d¡}|j dd¡ t|jƒdks*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   r7  r&   rŽ   r'  r   r¿   rÀ   rÁ   rB  r6  ©r   r   r   r   r   r   Útest_insert_before  s    

z'TestTreeModification.test_insert_beforec                 C   sj   |   d¡}|j ddd¡ |j ddd¡ | ¡ |  d¡ks@t‚|j |jd¡ | ¡ |  d¡ksft‚d S )Nr    rv  ú rw  z$QUUX BAZ<a>foo</a>BAZ QUUX<b>bar</b>ZFOOz'QUUX BAZ<b>bar</b>FOO<a>foo</a>BAZ QUUX)r   r   r7  r&   rŽ   r'  r   r   r   r   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    rv  rw  z<a>foo</a>QUUX<b>bar</b>BAZrx  ry  rz  r&   )r   r   r8  r&   rŽ   r'  r   r¿   rÀ   rÁ   rB  r7  r6  r{  r   r   r   Útest_insert_after1  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    rv  r}  rw  z$<a>foo</a>QUUX BAZ<b>bar</b>BAZ QUUXzFOO z(QUUX BAZ<b>bar</b><a>foo</a>FOO BAZ QUUX)r   r   r8  r&   rŽ   r'  r   r   r   r   r   Útest_insert_multiple_afterI  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   r6  Ú
new_stringr¿   rÀ   rÁ   r8  ÚNotImplementedError©r   r   rv   r   r   r   r   Ú:test_insert_after_raises_exception_if_after_has_no_meaningU  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   r6  r‚  r¿   rÀ   rÁ   r7  rƒ  r„  r   r   r   ÚFtest_insert_before_raises_notimplementederror_if_before_has_no_meaning`  s    


z[TestTreeModification.test_insert_before_raises_notimplementederror_if_before_has_no_meaningc                 C   sv   |   d¡}| d¡\}}| |¡ | ¡ |  d¡k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$   r;  rŽ   r'  r   rÊ   r)   rç   r  )r   r   r‡  Úshowr   r   r   Útest_replace_withk  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&   r1   z
won't workrF  Zstring1Zstring2)r   r¿   rÀ   rÁ   r;  r   r&   r   )r   Za_tagr   r   r   Útest_replace_with_errorsx  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 )Nr?  r³   zText In D Tagrg  r˜   zRandom Textz;<a><b></b><d>Text In D Tag</d><e></e>Random Text<f></f></a>)	r   r6  r   ry   r;  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 )Nr?  z<a><c></c></a>)r   r   r;  ry   rŽ   r   rc  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 )Nr?  rF  )r   ry   r;  r   rŽ   r   rc  r   r   r   Útest_replace_last_childŸ  s    
z,TestTreeModification.test_replace_last_childc                 C   s  |   d¡}|j}|j}| |¡ | ¡ |  d¡k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>rX  r   ZWeÚto)r   r   r˜   r;  rŽ   r'  r   rÊ   r   rç   rü   r  r  r&   rg  rf  )r   r   Z
remove_tagZmove_tagZto_textZg_tagr   r   r   Útest_nested_tag_replace_with¥  s0    ÿ

ÿ
z1TestTreeModification.test_nested_tag_replace_withc                 C   s6   |   d¡}|j ¡  |jd 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   Úwrapr6  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>rF   Ú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   r   rB  rŽ   rÊ   rü   rç   r  r  )r   r   Z	extractedZ	content_1Z	content_2r   r   r   Útest_extractå  s"    ÿz!TestTreeModification.test_extractc                 C   sr   |   d¡}|jj}| d¡}| d¡}|j |¡ |j |¡ | ¡  | ¡  ||jjks^t‚||jjksnt‚d S )Nr    rQ   r@   )r   r&   r   r‚  rV   r   rB  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   )ÚscriptrB  )rÚ   rÂ   rq  r   r   rÛ     s     zKTestTreeModification.test_extract_multiples_of_same_tag.<locals>.<listcomp>rš  z<body>

<a></a>
</body>)r   r$   r   r<   r   ro   r   rq  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>r<   )r   r   rB  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   rb   r  )r   r   r&   r  r   r   r   Ú
test_clear"  s    

zTestTreeModification.test_clearzmethod_name,expected_result)rT  ú9<div><em>child1</em><p id="start"></p><p>child3</p></div>)r  zH<div><em>child1</em><p id="start"><a>Second <em>child</em></a></p></div>)rö   r   )rP  r   )r  r	  )r#  zF<div><p id="start"><a>Second <em>child</em></a></p><p>child3</p></div>)rÜ   r	  c                 C   s<   |   d¡}t|j|ƒ}|D ]}| ¡  q|| ¡ ks8t‚d S )NzU<div><em>child1</em><p id='start'><a>Second <em>child</em></a></p><p>child3</p></div>)r   Úgetattrr)   rB  rŽ   r   )r   Úmethod_nameZexpected_resultr   ÚiteratorrÂ   r   r   r   Útest_extract_during_iteration0  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   rQ  rK  r&   r   rÂ   r   r   r   Útest_decomposeU  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_stringe  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>rQ   r@   N)r   r&   r   r¹   r   r   r   r   r   r   Útest_string_setn  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   ry   r   r   r&   r   r   r   r   r   r   Ú/test_string_set_does_not_affect_original_stringv  s    
zDTestTreeModification.test_string_set_does_not_affect_original_stringc                 C   s0   |   d¡}tdƒ}||j_t|jjtƒs,t‚d S )NrS   rQ   )r   r   r&   r   rU  r   )r   r   Úcdatar   r   r   Ú)test_set_string_preserves_class_of_string{  s    
z>TestTreeModification.test_set_string_preserves_class_of_stringN);r7   r8   r9   r(  r.  r0  r:  r>  rA  rC  rD  rH  rI  rS  rV  rY  r]  r^  r_  r`  rb  rd  re  rj  rk  r¿   ÚmarkÚparametrizerp  rr  rs  ru  r|  r~  r  r€  r…  r†  r‰  rŠ  r‹  rŒ  r  r  r‘  r”  r•  r–  r˜  r™  r›  rœ  rŸ  r¤  r¦  r§  r¨  r©  r«  r   r   r   r   r&  â  sŽ   	

	



þþ
	%ìþ
	r&  r   r$   rÓ   rÑ   rñ   rï   r  r  r-   r>   r,   r=   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>TrT   r  )r   zOThe 'text' argument to find()-type methods is deprecated. Use 'string' instead.)
r   r¡  r   rW   rX   rY   rZ   r   r   r[   ©r   r¢  r   Úmethodr]   r^   r_   r   r   r   Útest_find_type_method_string“  s    


ÿÿz4TestDeprecatedArguments.test_find_type_method_stringN)r7   r8   r9   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¯  TrT   Úu)Ú_classzN'_class' is an unusual attribute name and is a common misspelling for 'class_')r   r¡  r   rW   rX   rY   rZ   r   rU  r[   r   r   r°  r   r   r   Útest_suspicious_syntax_warning£  s    


ÿÿz+TestWarnings.test_suspicious_syntax_warningN)r7   r8   r9   r¿   r¬  r­  r³  r·  r   r   r   r   r´  ¢  s   r´  )$r:   r¿   rC   rW   Zbs4r   Zbs4.builderr   Zbs4.elementr   r   r   r   r   Z
bs4.filterr	   r	  r   r   r;   rf   rj   r‡   r²   r¼   rÅ   rà   râ   rú   r  r  r  r&  r³  r®  r´  r   r   r   r   Ú<module>   sX   
,FP /,?,'/1     &ô