B
    j9C\°@ ã               @   s  d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
mZ ddlmZmZmZmZmZmZmZmZ ddlmZmZ e
 d¡dk	Ze
 d	¡dk	ZG d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZ G dd„ deƒZ!G dd„ deƒZ"G dd„ deƒZ#G dd„ de#ƒZ$G dd„ de#ƒZ%G d d!„ d!eƒZ&G d"d#„ d#e&ƒZ'G d$d%„ d%e&ƒZ(G d&d'„ d'eƒZ)G d(d)„ d)eƒZ*G d*d+„ d+eƒZ+G d,d-„ d-eƒZ,G d.d/„ d/eƒZ-G d0d1„ d1eƒZ.G d2d3„ d3eƒZ/G d4d5„ d5eƒZ0G d6d7„ d7eƒZ1dS )8a8  Tests for Beautiful Soup's tree traversal methods.

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

Different parsers will build different Beautiful Soup trees given the
same markup, but all Beautiful Soup trees can be traversed with the
methods tested here.
é    )Ú	set_traceN)ÚBeautifulSoup)Úbuilder_registryÚHTMLParserTreeBuilder)ÚPY3KÚCDataÚCommentÚDeclarationÚDoctypeÚNavigableStringÚSoupStrainerÚTag)ÚSoupTestÚskipIfZxmlZlxmlc               @   s   e Zd Zdd„ Zdd„ ZdS )ÚTreeTestc             C   s   |   dd„ |D ƒ|¡ dS )zÝMake sure that the given tags have the correct text.

        This is used in tests that define a bunch of tags, each
        containing a single string, and then select certain strings by
        some mechanism.
        c             S   s   g | ]
}|j ‘qS © )Ústring)Ú.0Útagr   r   ú2lib/python3.7/site-packages/bs4/tests/test_tree.pyú
<listcomp>1   s    z*TreeTest.assertSelects.<locals>.<listcomp>N)ÚassertEqual)ÚselfÚtagsÚshould_matchr   r   r   ÚassertSelects*   s    zTreeTest.assertSelectsc             C   s   |   dd„ |D ƒ|¡ dS )zÜMake sure that the given tags have the correct IDs.

        This is used in tests that define a bunch of tags, each
        containing a single string, and then select certain strings by
        some mechanism.
        c             S   s   g | ]}|d  ‘qS )Úidr   )r   r   r   r   r   r   :   s    z-TreeTest.assertSelectsIDs.<locals>.<listcomp>N)r   )r   r   r   r   r   r   ÚassertSelectsIDs3   s    zTreeTest.assertSelectsIDsN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   (   s   	r   c               @   s8   e Zd Z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.

    find() just calls find_all() with limit=1, so it's not tested all
    that thouroughly here.
    c             C   s"   |   d¡}|  | d¡jd¡ d S )Nz <a>1</a><b>2</b><a>3</a><b>4</b>ÚbÚ2)Úsoupr   Úfindr   )r   r$   r   r   r   Útest_find_tagD   s    
zTestFind.test_find_tagc             C   s"   |   d¡}|  |jddd¡ d S )Nu   <h1>RÃ¤ksmÃ¶rgÃ¥s</h1>u   RÃ¤ksmÃ¶rgÃ¥s)r   )r$   r   r%   )r   r$   r   r   r   Útest_unicode_text_findH   s    
zTestFind.test_unicode_text_findc             C   s,   |   d¡}t|ƒ |  d|jddj¡ d S )Nu&   <h1 id="RÃ¤ksmÃ¶rgÃ¥s">here it is</h1>z
here it isu   RÃ¤ksmÃ¶rgÃ¥s)r   )r$   Ústrr   r%   Útext)r   r$   r   r   r   Útest_unicode_attribute_findL   s    
z$TestFind.test_unicode_attribute_findc             C   s"   |   d¡}|  dt| ¡ ƒ¡ dS )z)Test an optimization that finds all tags.z<a>foo</a><b>bar</b>é   N)r$   r   ÚlenÚfind_all)r   r$   r   r   r   Útest_find_everythingR   s    
zTestFind.test_find_everythingc             C   s$   |   d¡}|  dt| d¡ƒ¡ 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+   ÚaN)r$   r   r,   r-   )r   r$   r   r   r   Útest_find_everything_with_nameW   s    
z'TestFind.test_find_everything_with_nameN)	r   r   r    Ú__doc__r&   r'   r*   r.   r0   r   r   r   r   r!   =   s   r!   c               @   s8   e Zd Z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   s   |   d¡}|  |jdddg¡ |  |jdddg¡ |  |jddgdddg¡ |  |jt d¡ddddg¡ |  |jdddddg¡ d	S )
z'You can search the tree for text nodes.u   <html>Foo<b>bar</b>Â»</html>Úbar)r   )r)   ÚFooz.*õ   Â»TN)r$   r   r-   ÚreÚcompile)r   r$   r   r   r   Útest_find_all_text_nodes_   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#   Ú3é   é
   Ú4Ú5r   N)r$   r   r-   )r   r$   r   r   r   Útest_find_all_limito   s    
zTestFindAll.test_find_all_limitc             C   s:   |   d¡}|  |ddddg¡ |  |jdddg¡ d S )	Nz!<a>1</a><b>2<a id='foo'>3</a></b>r/   r=   )r:   r;   Úfoo)r   r<   )r$   r   r"   )r   r$   r   r   r   Ú%test_calling_a_tag_is_calling_findall{   s    
z1TestFindAll.test_calling_a_tag_is_calling_findallc             C   s.   |   d¡}g }| |¡ |  g | |¡¡ d S )Nz<a></a>)r$   Úappendr   r-   )r   r$   Úlr   r   r   ÚTtest_find_all_with_self_referential_data_structure_does_not_cause_infinite_recursion€   s    

z`TestFindAll.test_find_all_with_self_referential_data_structure_does_not_cause_infinite_recursionc             C   s^   |   d¡}| d¡}|  t|dƒ¡ | d¡}|  t|dƒ¡ |jdd}|  t|dƒ¡ dS )z%All find_all calls return a ResultSetz<a></a>r/   ÚsourceTrB   )r)   N)r$   r-   Ú
assertTrueÚhasattr)r   r$   Úresultr   r   r   Útest_find_all_resultsetŠ   s    


z#TestFindAll.test_find_all_resultsetN)	r   r   r    r1   r8   rA   rC   rF   rK   r   r   r   r   r2   \   s   
r2   c               @   s   e Zd Zdd„ ZdS )ÚTestFindAllBasicNamespacesc             C   s<   |   d¡}|  d| d¡j¡ |  d|jddidj¡ d S )Nz0<mathml:msqrt>4</mathml:msqrt><a svg:fill="red">r?   zmathml:msqrtr/   zsvg:fillZred)Úattrs)r$   r   r%   r   Úname)r   r$   r   r   r   Útest_find_by_namespaced_name™   s    
z7TestFindAllBasicNamespaces.test_find_by_namespaced_nameN)r   r   r    rO   r   r   r   r   rL   —   s   rL   c                   sp   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )ÚTestFindAllByNamez&Test ways of finding tags by tag name.c                s   t t| ƒ ¡  |  d¡| _d S )Nz<a>First tag.</a>
                                  <b>Second tag.</b>
                                  <c>Third <a>Nested tag.</a> tag.</c>)Úsuperr   ÚsetUpr$   Útree)r   )Ú	__class__r   r   rR   ¢   s    zTestFindAllByName.setUpc             C   s   |   | j d¡ddg¡ d S )Nr/   z
First tag.zNested tag.)r   rS   r-   )r   r   r   r   Útest_find_all_by_tag_name¨   s    z+TestFindAllByName.test_find_all_by_tag_namec             C   s\   |   | jjddddg¡ |   | jjdddddg¡ |   | jjdt d¡dddg¡ d S )Nr/   z
First tag.)r)   TzNested tag.r   )r   rS   r-   r6   r7   )r   r   r   r   Útest_find_all_by_name_and_text­   s    z0TestFindAllByName.test_find_all_by_name_and_textc             C   s   |   | jj d¡dg¡ d S )Nr/   zNested tag.)r   rS   Úcr-   )r   r   r   r   Ú!test_find_all_on_non_root_element¹   s    z3TestFindAllByName.test_find_all_on_non_root_elementc             C   s   |   |  d¡ddg¡ d S )Nr/   z
First tag.zNested tag.)r   rS   )r   r   r   r   Ú%test_calling_element_invokes_find_all½   s    z7TestFindAllByName.test_calling_element_invokes_find_allc             C   s    |   | j tdƒ¡ddg¡ d S )Nr/   z
First tag.zNested tag.)r   rS   r-   r   )r   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"   z
First tag.zSecond tag.zNested tag.)r   rS   r-   )r   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"   z
First tag.zSecond tag.zNested tag.)r   rS   r-   )r   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]$z
First tag.zSecond tag.zNested tag.)r   rS   r-   r6   r7   )r   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   )rN   Úget)r   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.)r$   r   r-   )r   r_   rS   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¡ |  d|j¡ |  d|j¡ |  d|j¡ d S )NzH<div class='a b'>1</div><div class='a c'>2</div><div class='a d'>3</div>Údivza dza br<   r;   )r$   r%   r6   r7   r-   r   r   )r   r$   Zr1Zr2Zr3Zr4r   r   r   Ú%test_find_with_multi_valued_attributeá   s    z7TestFindAllByName.test_find_with_multi_valued_attribute)r   r   r    r1   rR   rU   rV   rX   rY   rZ   r[   r\   r]   r`   rb   Ú__classcell__r   r   )rT   r   rP   Ÿ   s   rP   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>Úfirst)r   zMatching a.zMatching b.)r$   r   r-   )r   rS   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¡ |  |jg|j| d¡d¡ |  |jg|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)rN   zA tag called 'name1'.rN   )rM   zName match.ÚclassZclass2zClass match.)r$   r   r-   )r   rS   r   r   r   Útest_find_all_by_attribute_dict  s    z6TestFindAllByAttribute.test_find_all_by_attribute_dictc             C   s°   |   d¡}|  |jddddg¡ |  |jddddg¡ |  |jdd	ddg¡ |  | dd¡dg¡ |  |jdd
ddg¡ |  | dd¡dg¡ |  | dd	¡dg¡ d S )Nzî
                         <a class="1">Class 1.</a>
                         <a class="2">Class 2.</a>
                         <b class="1">Class 1.</b>
                         <c class="3 4">Class 3 and 4.</c>
                         r/   r;   )Úclass_zClass 1.rW   r<   zClass 3 and 4.r?   )rM   )r$   r   r-   )r   rS   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Úo)ro   zFound itr/   zo b)r$   r-   r6   r7   r   )r   rS   Ú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/   ZbazFound itc             S   s   t | ƒdkS )Nr9   )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 )Nr9   )r,   )rt   r   r   r   Úsmall_attribute_valueD  s    zpTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.small_attribute_value)r$   r   r-   r6   r7   )r   r$   ru   rv   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| dd¡¡ |  |g| dd¡¡ |  |g|jddd¡ |  |g| dd¡¡ |  g | dd¡¡ d S )Nz*<a class="foo bar"></a><a class="foo"></a>r/   rB   r3   zfoo bar)ro   zbar foo)r$   r-   r   )r   r$   r/   Za2r   r   r   Ú:test_find_all_with_string_for_attrs_finds_multiple_classesJ  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   re   )rM   zMatch.)r$   r   r   r-   )r   rS   Ústrainerr   r   r   Ú'test_find_all_by_attribute_soupstrainerV  s    z>TestFindAllByAttribute.test_find_all_by_attribute_soupstrainerc             C   s&   |   d¡}|  |jdd ddg¡ d S )Nz<a id="1">ID present.</a>
                            <a>No ID present.</a>
                            <a id="">ID is empty.</a>r/   )r   zNo ID present.)r$   r   r-   )r   rS   r   r   r   Ú$test_find_all_with_missing_attribute^  s    z;TestFindAllByAttribute.test_find_all_with_missing_attributec             C   s&   |   d¡}|  |jddddg¡ d S )Nz<a id="1">ID present.</a>
                            <a>No ID present.</a>
                            <a id="">ID is empty.</a>T)r   zID present.zID is empty.)r$   r   r-   )r   rS   r   r   r   Ú$test_find_all_with_defined_attributef  s    z;TestFindAllByAttribute.test_find_all_with_defined_attributec             C   s>   |   d¡}ddg}|  |jdd|¡ |  |jdd|¡ d S )Nz[<a id=1>Unquoted attribute.</a>
                            <a id="1">Quoted attribute.</a>zUnquoted attribute.zQuoted attribute.r=   )r   r;   )r$   r   r-   )r   rS   Zexpectedr   r   r   Ú$test_find_all_with_numeric_attributeo  s
    z;TestFindAllByAttribute.test_find_all_with_numeric_attributec             C   s,   |   d¡}|  |jdddgdddg¡ d S )Nz‘<a id="1">1</a>
                            <a id="2">2</a>
                            <a id="3">3</a>
                            <a>No ID.</a>r;   r<   r?   )r   )r$   r   r-   )r   rS   r   r   r   Ú(test_find_all_with_list_attribute_valuesx  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-   r6   r7   )r   rS   r   r   r   Ú5test_find_all_with_regular_expression_attribute_value‚  s    zLTestFindAllByAttribute.test_find_all_with_regular_expression_attribute_valuec             C   sX   |   d¡}|j}|  |g|jddd¡ |  g |jddd¡ |  g |jddd¡ d S )Nz<b>foo</b><b>bar</b><a>foo</a>r/   rB   )r)   r3   )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¡ d S )Nz"<a>foo</a><a><b><c>foo</c></b></a>r/   rB   )r)   )r$   r   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¡ |  g |jddd¡ d S )Nz"<b id="1">foo</b><a id="2">foo</a>r+   rB   )r   r)   r=   r3   )r$   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)r   r   r    rf   rl   rn   rp   rs   rw   rx   rz   r{   r|   r}   r~   r   r€   r   r‚   r   r   r   r   rd   î   s    		
rd   c               @   s   e Zd ZdZdd„ ZdS )Ú	TestIndexzTest Tag.indexc             C   sN   |   d¡}|j}x(t|jƒD ]\}}|  || |¡¡ qW |  t|jd¡ 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$   ra   Ú	enumerateÚcontentsr   ÚindexÚassertRaisesÚ
ValueError)r   rS   ra   ÚiÚelementr   r   r   Ú
test_index§  s    zTestIndex.test_indexN)r   r   r    r1   r‹   r   r   r   r   rƒ   ¥  s   rƒ   c                   s`   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Z‡  ZS )ÚTestParentOperationsz;Test navigation and searching through an element's parents.c                s(   t t| ƒ ¡  |  d¡| _| jj| _d S )Na1  <ul id="empty"></ul>
                                 <ul id="top">
                                  <ul id="middle">
                                   <ul id="bottom">
                                    <b>Start here</b>
                                   </ul>
                                  </ul>)rQ   rŒ   rR   r$   rS   r"   Ústart)r   )rT   r   r   rR   º  s    zTestParentOperations.setUpc             C   sF   |   | jjd d¡ |   | jjjd d¡ |   | jjjjd d¡ d S )Nr   ÚbottomÚmiddleÚtop)r   r   Úparent)r   r   r   r   Útest_parentÆ  s    z TestParentOperations.test_parentc             C   s    | j jd }|  |j| j ¡ d S )Nr   )rS   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¡ d S )N)r   rS   r‘   )r   r   r   r   Útest_soup_object_has_no_parentÏ  s    z3TestParentOperations.test_soup_object_has_no_parentc             C   s8   |   | j d¡dddg¡ |   | jjddddg¡ d S )NÚulrŽ   r   r   )r   )r   r   Zfind_parents)r   r   r   r   Útest_find_parentsÒ  s    z&TestParentOperations.test_find_parentsc             C   s8   |   | j d¡d d¡ |   | jjdddd d¡ d S )Nr•   r   rŽ   r   )r   )r   r   Úfind_parent)r   r   r   r   Útest_find_parentØ  s    z%TestParentOperations.test_find_parentc             C   s"   | j jdd}|  |jjd¡ d S )Nz
Start here)r)   r"   )rS   r%   r   r‘   rN   )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¡ d S )Nz
Start here)r)   r•   r   rŽ   )rS   r%   r   r—   )r   r)   r   r   r   Útest_text_element_find_parentà  s    z2TestParentOperations.test_text_element_find_parentc             C   s(   dd„ | j jD ƒ}|  |dddg¡ d S )Nc             S   s&   g | ]}|d k	rd|j kr|d ‘qS )Nr   )rM   )r   r‘   r   r   r   r   å  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_generator)r   r   r    r1   rR   r’   r“   r”   r–   r˜   r™   rš   rœ   rc   r   r   )rT   r   rŒ   ·  s   rŒ   c                   s   e Zd Z‡ fdd„Z‡  ZS )ÚProximityTestc                s   t t| ƒ ¡  |  d¡| _d S )Nzg<html id="start"><head></head><body><b id="1">One</b><b id="2">Two</b><b id="3">Three</b></body></html>)rQ   r   rR   r$   rS   )r   )rT   r   r   rR   ì  s    zProximityTest.setUp)r   r   r    rR   rc   r   r   )rT   r   r   ê  s   r   c                   sT   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
‡  ZS )ÚTestNextOperationsc                s   t t| ƒ ¡  | jj| _d S )N)rQ   rž   rR   rS   r"   r   )r   )rT   r   r   rR   ô  s    zTestNextOperations.setUpc             C   s*   |   | jjd¡ |   | jjjd d¡ d S )NÚOner   r#   )r   r   Únext_element)r   r   r   r   Ú	test_nextø  s    zTestNextOperations.test_nextc             C   s    | j jdd}|  |jd ¡ d S )NÚThree)r)   )rS   r%   r   r    )r   Zlastr   r   r   Útest_next_of_last_item_is_noneü  s    z1TestNextOperations.test_next_of_last_item_is_nonec             C   s   |   | jjd ¡ d S )N)r   rS   r    )r   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¢   r9   )r   )r   r   Úfind_all_next)r   r   r   r   Útest_find_all_next  s    z%TestNextOperations.test_find_all_nextc             C   s2   |   | j d¡d d¡ |   | jjddd¡ d S )Nr"   r   r#   r¢   )r)   )r   r   Ú	find_next)r   r   r   r   Útest_find_next	  s    z!TestNextOperations.test_find_nextc             C   s<   | j jdd}|  | d¡jd¡ |  | d¡ddg¡ d S )NrŸ   )r)   r"   r¥   r¢   )rS   r%   r   r¨   r   r   r¦   )r   r)   r   r   r   Útest_find_next_for_text_element  s    z2TestNextOperations.test_find_next_for_text_elementc             C   sF   | j jdd}dd„ |jD ƒ}|\}}|  |d d¡ |  |d¡ d S )Nr¥   )r)   c             S   s   g | ]}|‘qS r   r   )r   Únoder   r   r   r     s    z:TestNextOperations.test_next_generator.<locals>.<listcomp>r   r<   r¢   )rS   r%   Znext_elementsr   )r   r   Z
successorsr   r…   r   r   r   Útest_next_generator  s
    z&TestNextOperations.test_next_generator)r   r   r    rR   r¡   r£   r¤   r§   r©   rª   r¬   rc   r   r   )rT   r   rž   ò  s   rž   c                   sT   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
‡  ZS )ÚTestPreviousOperationsc                s"   t t| ƒ ¡  | jjdd| _d S )Nr¢   )r)   )rQ   r­   rR   rS   r%   Úend)r   )rT   r   r   rR     s    zTestPreviousOperations.setUpc             C   s*   |   | jjd d¡ |   | jjjd¡ d S )Nr   r<   r¥   )r   r®   Úprevious_element)r   r   r   r   Útest_previous   s    z$TestPreviousOperations.test_previousc             C   s   | j  d¡}|  |jd ¡ d S )NÚhtml)rS   r%   r   r¯   )r   re   r   r   r   Ú#test_previous_of_first_item_is_none$  s    z:TestPreviousOperations.test_previous_of_first_item_is_nonec             C   s   d S )Nr   )r   r   r   r   Útest_previous_of_root_is_none(  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   )r   r®   Úfind_all_previous)r   r   r   r   Útest_find_all_previous.  s    z-TestPreviousOperations.test_find_all_previousc             C   s2   |   | j d¡d d¡ |   | jjddd¡ d S )Nr"   r   r<   rŸ   )r)   )r   r®   Úfind_previous)r   r   r   r   Útest_find_previous6  s    z)TestPreviousOperations.test_find_previousc             C   s>   | j jdd}|  | d¡jd¡ |  | d¡dddg¡ d S )Nr¢   )r)   r"   r¥   rŸ   )rS   r%   r   r¶   r   r   r´   )r   r)   r   r   r   Ú#test_find_previous_for_text_element:  s    z:TestPreviousOperations.test_find_previous_for_text_elementc             C   sh   | j jdd}dd„ |jD ƒ}|\}}}}|  |d d¡ |  |jd¡ |  |jd¡ |  |jd	¡ d S )
NrŸ   )r)   c             S   s   g | ]}|‘qS r   r   )r   r«   r   r   r   r   B  s    zBTestPreviousOperations.test_previous_generator.<locals>.<listcomp>r   r;   ÚbodyÚheadr±   )rS   r%   Zprevious_elementsr   rN   )r   r   Zpredecessorsr"   r¹   rº   r±   r   r   r   Útest_previous_generator@  s    z.TestPreviousOperations.test_previous_generator)r   r   r    rR   r°   r²   r³   rµ   r·   r¸   r»   rc   r   r   )rT   r   r­     s   r­   c                   s   e Zd Z‡ fdd„Z‡  ZS )ÚSiblingTestc                s4   t t| ƒ ¡  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*Ú )rQ   r¼   rR   r6   r7   Úsubr$   rS   )r   Úmarkup)rT   r   r   rR   O  s    zSiblingTest.setUp)r   r   r    rR   rc   r   r   )rT   r   r¼   M  s   r¼   c                   sL   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	‡  Z
S )ÚTestNextSiblingc                s"   t t| ƒ ¡  | jjdd| _d S )Nr;   )r   )rQ   rÀ   rR   rS   r%   r   )r   )rT   r   r   rR   e  s    zTestNextSibling.setUpc             C   s   |   | jjd ¡ d S )N)r   rS   Únext_sibling)r   r   r   r   Ú!test_next_sibling_of_root_is_nonei  s    z1TestNextSibling.test_next_sibling_of_root_is_nonec             C   sB   |   | jjd d¡ |   | jjjd d¡ |   | jjd d¡ d S )Nr   r#   r<   z1.1)r   r   rÁ   r    )r   r   r   r   Útest_next_siblingl  s    z!TestNextSibling.test_next_siblingc             C   sN   |   | jjjd ¡ | jjdd}|   |jd ¡ | jjdd}|   |jd ¡ d S )Nz1.1)r   r?   )r   rS   r±   rÁ   r%   )r   Únested_spanZ	last_spanr   r   r   Útest_next_sibling_may_not_exists  s
    z/TestNextSibling.test_next_sibling_may_not_existc             C   s   |   | j d¡d d¡ d S )NÚspanr   r#   )r   r   Úfind_next_sibling)r   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#   r<   r?   )r   )r   r   Úfind_next_siblings)r   r   r   r   Útest_next_siblings  s    z"TestNextSibling.test_next_siblingsc             C   sv   |   d¡}|jdd}|  |jjd¡ |  |jjd¡ |  | d¡dg¡ |  |jddd¡ |  |jddd ¡ d S )NzFoo<b>bar</b>bazr4   )r)   r"   Úbazr3   Únonesuch)r$   r%   r   rÁ   rN   r   rÉ   rÇ   )r   r$   r   r   r   r   Ú"test_next_sibling_for_text_element…  s    
z2TestNextSibling.test_next_sibling_for_text_element)r   r   r    rR   rÂ   rÃ   rÅ   rÈ   rÊ   rÍ   rc   r   r   )rT   r   rÀ   c  s   	rÀ   c                   sL   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	‡  Z
S )ÚTestPreviousSiblingc                s"   t t| ƒ ¡  | jjdd| _d S )Nr?   )r   )rQ   rÎ   rR   rS   r%   r®   )r   )rT   r   r   rR   ’  s    zTestPreviousSibling.setUpc             C   s   |   | jjd ¡ d S )N)r   rS   Úprevious_sibling)r   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¡ |   | jjjd d¡ |   | jjd d¡ d S )Nr   r<   r#   z3.1)r   r®   rÏ   r¯   )r   r   r   r   Útest_previous_sibling™  s    z)TestPreviousSibling.test_previous_siblingc             C   sN   |   | jjjd ¡ | jjdd}|   |jd ¡ | jjdd}|   |jd ¡ d S )Nz1.1)r   r;   )r   rS   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¡ d S )NrÆ   r   r<   )r   r®   Úfind_previous_sibling)r   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Æ   r<   r#   r;   )r   )r   r®   Úfind_previous_siblings)r   r   r   r   Útest_previous_siblings¬  s    z*TestPreviousSibling.test_previous_siblingsc             C   sv   |   d¡}|jdd}|  |jjd¡ |  |jjd¡ |  | d¡dg¡ |  |jddd¡ |  |jddd ¡ d S )NzFoo<b>bar</b>bazrË   )r)   r"   r4   r3   rÌ   )r$   r%   r   rÏ   rN   r   rÕ   rÓ   )r   r$   r   r   r   r   Ú&test_previous_sibling_for_text_element²  s    
z:TestPreviousSibling.test_previous_sibling_for_text_element)r   r   r    rR   rÐ   rÑ   rÒ   rÔ   rÖ   r×   rc   r   r   )rT   r   rÎ     s   	rÎ   c               @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚTestTagCreationz$Test the ability to create new tags.c             C   sd   |   d¡}|jddddid}|  t|tƒ¡ |  d|j¡ |  tddd|j¡ |  d |j	¡ d S )Nr½   rB   rË   rN   za name)r3   rM   )r3   rN   )
r$   Únew_tagrH   Ú
isinstancer   r   rN   ÚdictrM   r‘   )r   r$   rÙ   r   r   r   Útest_new_tag¿  s    
zTestTagCreation.test_new_tagc             C   s„   t rBtddƒ}| d¡}| d¡}|  d| ¡ ¡ |  d| ¡ ¡ tddƒ}| d¡}| d¡}|  d| ¡ ¡ |  d| ¡ ¡ d S )	Nr½   zlxml-xmlÚbrÚps   <br/>s   <p/>zhtml.parsers   <p></p>)ÚXML_BUILDER_PRESENTr   rÙ   r   ri   )r   Zxml_soupZxml_brZxml_pZ	html_soupZhtml_brZhtml_pr   r   r   Ú1test_tag_inherits_self_closing_rules_from_builderÇ  s    





zATestTagCreation.test_tag_inherits_self_closing_rules_from_builderc             C   s4   |   d¡}| d¡}|  d|¡ |  t|tƒ¡ d S )Nr½   rB   )r$   Ú
new_stringr   rH   rÚ   r   )r   r$   Úsr   r   r   Ú'test_new_string_creates_navigablestringÛ  s    

z7TestTagCreation.test_new_string_creates_navigablestringc             C   s6   |   d¡}| dt¡}|  d|¡ |  t|tƒ¡ d S )Nr½   rB   )r$   rá   r   r   rH   rÚ   )r   r$   râ   r   r   r   Ú3test_new_string_can_create_navigablestring_subclassá  s    
zCTestTagCreation.test_new_string_can_create_navigablestring_subclassN)r   r   r    r1   rÜ   rà   rã   rä   r   r   r   r   rØ   ½  s
   rØ   c               @   sT  e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Zd5d6„ Zd7d8„ Zd9d:„ Zd;d<„ Z d=d>„ Z!d?d@„ Z"dAdB„ Z#dCdD„ Z$dEdF„ Z%dGdH„ Z&dIdJ„ Z'dKdL„ Z(dMdN„ Z)dOdP„ Z*dQdR„ Z+dSS )TÚTestTreeModificationc             C   sl   |   d¡}d|jd< |  | ¡ |  d¡¡ |jd= |  | ¡ |  d¡¡ d|jd< |  | ¡ |  d¡¡ d S )	Nz<a id="1"></a>r+   r   z<a id="2"></a>z<a></a>rB   Zid2z<a id2="foo"></a>)r$   r/   r   rj   Údocument_for)r   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
¡ d S )Nr±   z<body></body>)Úbuilderr/   Úolzhttp://foo.com/Zhrefr   r=   s4   <body><a href="http://foo.com/"></a><ol></ol></body>)r   Úlookupr$   r   r¹   Úinsertr   ri   )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|¡ |  | ¡ |  d¡¡ 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"   rD   r   r‘   rj   ræ   )r   Údocr$   Zsecond_paraZboldr   r   r   Ú!test_append_to_contents_moves_tagþ  s    

z6TestTreeModification.test_append_to_contents_moves_tagc             C   s0   d}|   |¡}|j}| |j¡}|  ||¡ d S )Nz<a></a><b><c></c></b>)r$   r/   Úreplace_withrW   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}| ¡ }|  ||¡ d S )Nz<a><b></b><c></c></a>)r$   r/   Úunwrapr   )r   r)   r$   r/   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¡ |  t|j¡ |  t|j|j	¡ d S )Nz<a><b>Foo</b></a><c>Bar</c>)
r$   r/   Úextractr   r‘   r‡   rˆ   rò   rï   rW   )r   r$   r/   r   r   r   ÚItest_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parent  s    
z^TestTreeModification.test_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parentc             C   s:   d}|   |¡}|j}|j |¡ |  | ¡ |  |¡¡ d S )Nz-<a><b></b><c>Foo<d></d></c></a><a><e></e></a>)r$   rW   rï   r   rj   ræ   )r   r)   r$   rW   r   r   r   Útest_replace_tag_with_itself&  s
    
z1TestTreeModification.test_replace_tag_with_itselfc             C   s&   d}|   |¡}|  t|jj|j¡ d S )Nz<a><b></b></a>)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   s(   d}|   |¡}|  t|jjd|j¡ d S )Nz<a><b></b></a>r   )r$   r‡   rˆ   r/   rë   )r   r)   r$   r   r   r   Ú,test_insert_tag_into_itself_raises_exception2  s    
zATestTreeModification.test_insert_tag_into_itself_raises_exceptionc       	      C   s   |   d¡}d}|   |¡}| d|¡ x|jD ]}t|tƒr,t‚q,W t|jƒ\}}}}|  d|j	¡ |  d|j	¡ |  d|j	¡ |  d|j	¡ dS )	z”Inserting one BeautifulSoup object into another actually inserts all
        of its children -- you'll never combine BeautifulSoup objects.
        z-<p>And now, a word:</p><p>And we're back.</p>z<p>p2</p><p>p3</p>r=   zAnd now, a word:Úp2Úp3zAnd we're back.N)
r$   rë   ZdescendantsrÚ   r   ÚAssertionErrorÚlistZchildrenr   r   )	r   r$   r)   Z	to_insertr‰   Úp1rù   rú   Zp4r   r   r   Ú1test_insert_beautifulsoup_object_inserts_children7  s    

zFTestTreeModification.test_insert_beautifulsoup_object_inserts_childrenc             C   sX   |   d¡}|j}|jd }| dd¡ |j\}}| d¡ | d¡ |  d|jj¡ d S )Nz<p><a>one</a><b>three</b></p>r   r=   Ztwor½   Zthree)r$   r/   r…   rë   ZreplaceWithr   r"   r   )r   r$   r/   r"   ÚleftÚrightr   r   r   Ú3test_replace_with_maintains_next_element_throughoutK  s    




zHTestTreeModification.test_replace_with_maintains_next_element_throughoutc             C   sl   |   d¡}|jdd d¡ |jdd}|j}|  |j|¡ |  |j|¡ |  |jj|¡ |  |jd ¡ d S )Nz<b>Argh!</b>zArgh!)r)   zHooray!)r$   r%   rï   r"   r   r¯   r‘   r    )r   r$   Únew_textr"   r   r   r   Útest_replace_final_nodeZ  s    
z,TestTreeModification.test_replace_final_nodec             C   s˜   |   d¡}|j dd¡ |  | ¡ |  d¡¡ |jdd}|  |jd¡ |  |jj|¡ |  |j	d¡ |  |j	j
|¡ |  |j
d ¡ |  |j|j¡ d S )Nz<a><b>Argh!</b><c></c></a>r=   zHooray!z!<a><b>Argh!Hooray!</b><c></c></a>)r)   zArgh!)r$   r"   rë   r   rj   ræ   r%   r¯   r    rÏ   rÁ   rW   )r   r$   r  r   r   r   Útest_consecutive_text_nodesd  s    

z0TestTreeModification.test_consecutive_text_nodesc             C   sT   |   d¡}|j dd¡ |j dd¡ |  ddg|jj¡ |  |jjd jd¡ d S )Nz<a></a>r   r3   rB   )r$   r/   rë   r   r…   r    )r   r$   r   r   r   Útest_insert_stringy  s
    
z'TestTreeModification.test_insert_stringc             C   sö   | j }| jd|d}t||dƒ}| dd¡ |j d|¡ |  | ¡ |  d¡¡ |j}|  |j	|¡ |  |j
|¡ |jdd	}|  |j|¡ |  |j|¡ |j}|  |j	|¡ |  |j
|¡ |jdd	}|  |j|¡ |  |j|¡ |  |j|¡ 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Find)r)   )Zdefault_builderr$   r   rë   r/   r   rj   ræ   r"   rÁ   rÏ   r%   r    r¯   rW   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   s0   d}|   |¡}|j |j¡ |  || ¡ ¡ d S )Nz<a><b></b></a>)r$   r/   rD   r"   r   rj   )r   rk   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| 
¡ ¡ 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$   Úgrr   ÚeÚdrW   r"   r/   Úextendr   rj   )r   rk   r$   rE   r   r   r   Útest_extend¦  s
    
z TestTreeModification.test_extendc             C   s2   d}|   |¡}|j d|j¡ |  d| ¡ ¡ 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   rj   )r   rk   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¡ d S )Nz<br/>r=   ZContentsz<br>Contents</br>)r$   rÝ   rë   r   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¡¡ |j |j¡ |  | ¡ |  d¡¡ |j}|  t|j|¡ | 	¡  |  t|jd¡ |   d¡}|j | 
d¡¡ d S )	Nz<a>foo</a><b>bar</b>ÚBAZÚQUUXzQUUX<a>foo</a>BAZ<b>bar</b>zQUUX<b>bar</b><a>foo</a>BAZÚnopez<a>r/   )r$   r"   Úinsert_beforer/   r   rj   ræ   r‡   rˆ   rô   rÙ   )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¡¡ |j |jd¡ |  | ¡ |  d¡¡ d S )Nz<a>foo</a><b>bar</b>r  ú r  z$QUUX BAZ<a>foo</a>BAZ QUUX<b>bar</b>ÚFOOz'QUUX BAZ<b>bar</b>FOO<a>foo</a>BAZ QUUX)r$   r"   r  r/   r   rj   ræ   )r   r$   r   r   r   Útest_insert_multiple_beforeÓ  s    
z0TestTreeModification.test_insert_multiple_beforec             C   sª   |   d¡}|j d¡ |j d¡ |  | ¡ |  d¡¡ |j |j¡ |  | ¡ |  d¡¡ |j}|  t|j|¡ | 	¡  |  t|jd¡ |   d¡}|j 
| d¡¡ d S )	Nz<a>foo</a><b>bar</b>r  r  z<a>foo</a>QUUX<b>bar</b>BAZzQUUX<b>bar</b><a>foo</a>BAZr  z<a>r/   )r$   r"   Úinsert_afterr/   r   rj   ræ   r‡   rˆ   rô   r  rÙ   )r   r$   r"   r   r   r   Útest_insert_afterÞ  s    

z&TestTreeModification.test_insert_afterc             C   sj   |   d¡}|j ddd¡ |j ddd¡ |  | ¡ |  d¡¡ |j |jd¡ |  | ¡ |  d¡¡ d S )Nz<a>foo</a><b>bar</b>r  r  r  z$<a>foo</a>QUUX BAZ<b>bar</b>BAZ QUUXzFOO z(QUUX BAZ<b>bar</b><a>foo</a>FOO BAZ QUUX)r$   r"   r  r/   r   rj   ræ   )r   r$   r   r   r   Útest_insert_multiple_afterô  s    
z/TestTreeModification.test_insert_multiple_afterc             C   sR   |   d¡}| d¡}| d¡}|  t|j|¡ |  t|j|¡ |  t|j|¡ d S )Nr½   r/   )r$   rÙ   rá   r‡   rˆ   r  ÚNotImplementedError)r   r$   r   r   r   r   r   Ú:test_insert_after_raises_exception_if_after_has_no_meaningþ  s    


zOTestTreeModification.test_insert_after_raises_exception_if_after_has_no_meaningc             C   sR   |   d¡}| d¡}| d¡}|  t|j|¡ |  t|j|¡ |  t|j|¡ d S )Nr½   r/   )r$   rÙ   rá   r‡   rˆ   r  r  )r   r$   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¡¡ |  |jd ¡ |  |j|j¡ |  |jd¡ |  |j	d¡ 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   rj   ræ   r‘   rÞ   r    rÁ   )r   r$   r  Zshowr   r   r   Útest_replace_with  s    
z&TestTreeModification.test_replace_withc             C   s0   d}|   |¡}|j |j¡ |  d| ¡ ¡ d S )Nz<a><b></b><c></c></a>z<a><c></c></a>)r$   r"   rï   rW   r   rj   )r   rk   r$   r   r   r   Útest_replace_first_child  s    
z-TestTreeModification.test_replace_first_childc             C   s0   d}|   |¡}|j |j¡ |  d| ¡ ¡ d S )Nz<a><b></b><c></c></a>z<a><b></b></a>)r$   rW   rï   r"   r   rj   )r   rk   r$   r   r   r   Útest_replace_last_child#  s    
z,TestTreeModification.test_replace_last_childc             C   s  |   d¡}|j}|j}| |¡ |  | ¡ |  d¡¡ |  |jd ¡ |  |jddj	d ¡ |  |j
d ¡ |  |jd ¡ |  |jd ¡ |  |j|j¡ |  |j
d¡ |  |j	j	|j¡ |  |jd ¡ |jdd}|j}|  |j	|¡ |  |j|¡ |  |j
|¡ |  |j|¡ d S )NzQ<a>We<b>reserve<c>the</c><d>right</d></b></a><e>to<f>refuse</f><g>service</g></e>z-<a>We<f>refuse</f></a><e>to<g>service</g></e>r   )r)   ZWeÚto)r$   r"   rr   rï   r   rj   ræ   r‘   r%   r    r¯   rÁ   rÏ   r/   r
  r	  )r   r$   Z
remove_tagZmove_tagZto_textZg_tagr   r   r   Útest_nested_tag_replace_with)  s.    

z1TestTreeModification.test_nested_tag_replace_withc             C   s6   |   d¡}|j ¡  |  |jd ¡ |  |jjd¡ d S )NzI
            <p>Unneeded <em>formatting</em> is unneeded</p>
            zUnneeded formatting is unneeded)r$   Úemrò   r   rÞ   r)   )r   rS   r   r   r   Útest_unwrapM  s
    
z TestTreeModification.test_unwrapc             C   sF   |   d¡}|j | d¡¡}|  | ¡ d¡ |  | ¡ |  d¡¡ d S )NzI wish I was bold.r"   z<b>I wish I was bold.</b>)r$   r   ÚwraprÙ   r   rj   ræ   )r   r$   rt   r   r   r   Ú	test_wrapU  s
    
zTestTreeModification.test_wrapc             C   s4   |   d¡}|jj |j¡ |  | ¡ |  d¡¡ d S )Nz<b></b>I wish I was bold.z<b>I wish I was bold.</b>)r$   r"   rÁ   r&  r   rj   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ƒ¡ |  | ¡ |  d¡¡ 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…   rj   ræ   )r   r$   r   r   r   Ú&test_wrap_puts_new_contents_at_the_endb  s    

z;TestTreeModification.test_wrap_puts_new_contents_at_the_endc             C   sâ   |   d¡}|  t|jjƒd¡ |jdd ¡ }|  | ¡ d¡ |  | ¡ d¡ |  t|jjƒd¡ |  |jd ¡ |  |j	d ¡ |  |j
j
d ¡ |jdd	}|jd
d	}|  |j
|¡ |  |j|¡ |  |j	|¡ |  |j|¡ d S )NzR<html><body>Some content. <div id="nav">Nav crap</div> More content.</body></html>r9   Znav)r   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%   rô   rj   r‘   r¯   r    rÁ   rÏ   )r   r$   Z	extractedZ	content_1Z	content_2r   r   r   Útest_extractj  s"    z!TestTreeModification.test_extractc             C   sz   |   d¡}|jj}|jj}| d¡}| d¡}|j |¡ |j |¡ | ¡  | ¡  |  ||jj¡ |  ||jj¡ d S )Nz<a>foo</a><b>bar</b>rB   r3   )r$   r/   r   r"   rá   rD   rô   r   )r   r$   Zfoo_1Zbar_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ƒ¡ 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‰   )r$   r   r   r      s    zKTestTreeModification.test_extract_multiples_of_same_tag.<locals>.<listcomp>r,  z<body>

<a></a>
</body>)r$   r-   r   r(   r¹   )r   r   )r$   r   Ú"test_extract_multiples_of_same_tag”  s    
z7TestTreeModification.test_extract_multiples_of_same_tagc             C   s.   |   d¡}| d¡ ¡  |  d | d¡¡ d S )Nz<html>
<body>hi</body>
</html>r¹   )r$   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   sf   |   d¡}|j}|j ¡  |  t|jjƒd¡ |  t|dƒ¡ |j	}|jdd |  dt|jƒ¡ dS )zTag.clear()z4<p><a>String <em>Italicized</em></a> and another</p>r   r…   T)Z	decomposeN)
r$   r/   rÞ   Úclearr   r,   r…   rH   rI   r$  )r   r$   r/   r$  r   r   r   Ú
test_clear­  s    

zTestTreeModification.test_clearc             C   sB   |   d¡}d|j_|  |jjdg¡ d|j_|  |jjdg¡ dS )zTag.string = 'string'z<a></a> <b><c></c></b>rB   r3   N)r$   r/   r   r   r…   r"   )r   r$   r   r   r   Útest_string_set»  s
    
z$TestTreeModification.test_string_setc             C   s,   |   d¡}|jj|j_|  |j ¡ d¡ d S )Nz<a><b>foo</b><c>bar</c>s   <a><b>bar</b><c>bar</c></a>)r$   rW   r   r"   r   r/   ri   )r   r$   r   r   r   Ú/test_string_set_does_not_affect_original_stringÃ  s    
zDTestTreeModification.test_string_set_does_not_affect_original_stringc             C   s2   |   d¡}tdƒ}||j_|  t|jjtƒ¡ d S )Nz<a></a>rB   )r$   r   r/   r   rH   rÚ   )r   r$   Úcdatar   r   r   Ú)test_set_string_preserves_class_of_stringÈ  s    
z>TestTreeModification.test_set_string_preserves_class_of_stringN),r   r   r    rç   rì   rî   rñ   ró   rõ   rö   r÷   rø   rþ   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r!  r#  r%  r'  r(  r)  r*  r+  r-  r.  r0  r1  r2  r4  r   r   r   r   rå   ç  sR   	
		
$	rå   c               @   sx   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚTestElementObjectsz)Test various features of element objects.c             C   sV   |   d¡}|  t|jƒd¡ |  t|ƒd¡ |  t|jƒd¡ |  t|jjƒd¡ dS )z3The length of an element is its number of children.z<top>1<b>2</b>3</top>r=   r9   N)r$   r   r,   r…   r   )r   r$   r   r   r   Útest_lenÑ  s
    
zTestElementObjects.test_lenc             C   sL   |   d¡}|  |j| d¡¡ |  |jj| d¡ d¡¡ |  |jd¡ dS )z2Accessing a Python member .foo invokes find('foo')z<b><i></i></b>r"   r‰   N)r$   r   r"   r%   r‰   r/   )r   r$   r   r   r   Útest_member_access_invokes_findß  s    
z2TestElementObjects.test_member_access_invokes_findc          	   C   sP   |   d¡}tjdd}|j}W d Q R X |  |j|¡ |  dt|d jƒ¡ d S )Nz<b><i></i></b>T)Úrecordzp.bTag is deprecated, use .find("b") instead. If you really were looking for a tag called bTag, use .find("bTag")r   )r$   ÚwarningsÚcatch_warningsZbTagr   r"   r(   Úmessage)r   r$   Úwr   r   r   r   Útest_deprecated_member_accessæ  s    
z0TestElementObjects.test_deprecated_member_accessc             C   s2   |   d¡}|  |j d¡¡ |  |j d¡¡ dS )zÙhas_attr() checks for the presence of an attribute.

        Please note note: has_attr() is different from
        __in__. has_attr() checks the tag's attributes and __in__
        checks the tag's chidlren.
        z<foo attr='bar'>ÚattrZattr2N)r$   rH   rB   Úhas_attrÚassertFalse)r   r$   r   r   r   Útest_has_attrï  s    
z TestElementObjects.test_has_attrc             C   s   d}|   |d¡ d S )Nz%<b a="1" z="5" m="3" f="2" y="4"></b>z%<b a="1" f="2" m="3" y="4" z="5"></b>)ZassertSoupEquals)r   r¿   r   r   r   Ú.test_attributes_come_out_in_alphabetical_orderû  s    zATestElementObjects.test_attributes_come_out_in_alphabetical_orderc             C   s   |   d¡}|  |jjd¡ d S )Nz
<b>foo</b>rB   )r$   r   r"   r   )r   r$   r   r   r   Útest_stringÿ  s    
zTestElementObjects.test_stringc             C   s   |   d¡}|  |jjd ¡ d S )Nz<b></b>)r$   r   r"   r   )r   r$   r   r   r   Útest_empty_tag_has_no_string  s    
z/TestElementObjects.test_empty_tag_has_no_stringc             C   s`   |   d¡}|  |jjd ¡ |   d¡}|  |jjd ¡ |   d¡}|j dd¡ |  |jjd ¡ d S )Nz<a>foo<b></b><b></b></b>z<a>foo<b></b>bar</b>z
<a>foo</b>r=   r3   )r$   r   r"   r   r/   rë   )r   r$   r   r   r   Ú-test_tag_with_multiple_children_has_no_string
  s    


z@TestElementObjects.test_tag_with_multiple_children_has_no_stringc             C   s,   |   d¡}|  |jjd¡ |  |jd¡ d S )Nz<a><b>foo</b></a>rB   )r$   r   r/   r   )r   r$   r   r   r   Ú)test_tag_with_recursive_string_has_string  s    
z<TestElementObjects.test_tag_with_recursive_string_has_stringc             C   s4   |   d¡}|  |jj¡ |   d¡}|  |jj¡ dS )z7Only a tag containing a single text node has a .string.z<b>f<i>e</i>o</b>z<b></b>N)r$   r@  r"   r   )r   r$   r   r   r   Útest_lack_of_string  s    

z&TestElementObjects.test_lack_of_stringc             C   s`   |   d¡}|  |jjd¡ |  |jjddd¡ |  |j d¡d¡ |  |jjdddd¡ d	S )
zBTag.text and Tag.get_text(sep=u"") -> all child text, concatenatedz<a>a<b>r</b>   <r> t </r></a>zar  t T)ÚstripZartú,z	a,r, , t za,r,tN)r$   r   r/   r)   Úget_text)r   r$   r   r   r   Útest_all_text'  s
    
z TestElementObjects.test_all_textc             C   sJ   |   d¡}|  | ¡ d¡ |  |jttfdd¡ |  |jd dd¡ d S )Nzfoo<!--IGNORE-->barZfoobar)ÚtypesZfooIGNOREbar)r$   r   rJ  r   r   )r   r$   r   r   r   Útest_get_text_ignores_comments/  s    
z1TestElementObjects.test_get_text_ignores_commentsc             C   s$   |   d¡}|  ddgt|jƒ¡ d S )Nzfoo<!--IGNORE-->barrB   r3   )r$   r   rü   Zstrings)r   r$   r   r   r   Ú!test_all_strings_ignores_comments8  s    
z4TestElementObjects.test_all_strings_ignores_commentsN)r   r   r    r1   r6  r7  r=  rA  rB  rC  rD  rE  rF  rG  rK  rM  rN  r   r   r   r   r5  Î  s   		r5  c               @   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 )ÚTestCDAtaListAttributesz0Testing cdata-list attributes like 'class'.
    c             C   s"   |   d¡}|  dg|jd ¡ d S )Nz<a class='foo'>rB   rm   )r$   r   r/   )r   r$   r   r   r   Útest_single_value_becomes_list@  s    
z6TestCDAtaListAttributes.test_single_value_becomes_listc             C   s$   |   d¡}|  ddg|jd ¡ d S )Nz<a class='foo bar'>rB   r3   rm   )r$   r   r/   )r   r$   r   r   r   Ú!test_multiple_values_becomes_listD  s    
z9TestCDAtaListAttributes.test_multiple_values_becomes_listc             C   s&   |   d¡}|  dddg|jd ¡ d S )Nz<a class='foo	bar
baz'>rB   r3   rË   rm   )r$   r   r/   )r   r$   r   r   r   Ú2test_multiple_values_separated_by_weird_whitespaceH  s    
zJTestCDAtaListAttributes.test_multiple_values_separated_by_weird_whitespacec             C   s    |   d¡}|  d|j ¡ ¡ d S )Nz<a class='foo	bar'>s   <a class="foo bar"></a>)r$   r   r/   ri   )r   r$   r   r   r   Ú,test_attributes_joined_into_string_on_outputL  s    
zDTestCDAtaListAttributes.test_attributes_joined_into_string_on_outputc             C   s$   |   d¡}|  dg|j d¡¡ d S )Nz<a id='abc def'>zabc defr   )r$   r   r/   Zget_attribute_list)r   r$   r   r   r   Útest_get_attribute_listP  s    
z/TestCDAtaListAttributes.test_get_attribute_listc             C   s$   |   d¡}|  ddg|jd ¡ d S )Nz(<form accept-charset="ISO-8859-1 UTF-8">z
ISO-8859-1zUTF-8zaccept-charset)r$   r   Zform)r   r$   r   r   r   Útest_accept_charsetT  s    
z+TestCDAtaListAttributes.test_accept_charsetc             C   s$   d}|   |¡}|  d|jd ¡ d S )Nz)<a accept-charset="ISO-8859-1 UTF-8"></a>zISO-8859-1 UTF-8zaccept-charset)r$   r   r/   )r   rk   r$   r   r   r   Ú-test_cdata_attribute_applying_only_to_one_tagX  s    
zETestCDAtaListAttributes.test_cdata_attribute_applying_only_to_one_tagc                s6   |   d¡j‰ |  d ˆ j¡ ‡ fdd„}|  t|¡ d S )Nrâ   c                  s
   dˆ _ d S )NrB   )rN   r   )r   r   r   Útc  s    zJTestCDAtaListAttributes.test_string_has_immutable_name_property.<locals>.t)r$   r   r   rN   r‡   ÚAttributeError)r   rW  r   )r   r   Ú'test_string_has_immutable_name_property`  s    z?TestCDAtaListAttributes.test_string_has_immutable_name_propertyN)r   r   r    r1   rP  rQ  rR  rS  rT  rU  rV  rY  r   r   r   r   rO  <  s   rO  c                   s`   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Z‡  ZS )ÚTestPersistencez*Testing features like pickle and deepcopy.c                s&   t t| ƒ ¡  d| _|  | j¡| _d S )Nay  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Beautiful Soup: We called him Tortoise because he taught us.</title>
<link rev="made" href="mailto:leonardr@segfault.org">
<meta name="Description" content="Beautiful Soup: an HTML parser optimized for screen-scraping.">
<meta name="generator" content="Markov Approximation 1.4 (module: leonardr)">
<meta name="author" content="Leonard Richardson">
</head>
<body>
<a href="foo">foo</a>
<a href="foo"><b>bar</b></a>
</body>
</html>)rQ   rZ  rR   Zpager$   rS   )r   )rT   r   r   rR   j  s    zTestPersistence.setUpc             C   s@   t  | jd¡}t  |¡}|  |jt¡ |  | ¡ | j ¡ ¡ d S )Nr+   )ÚpickleÚdumpsrS   Úloadsr   rT   r   rj   )r   ÚdumpedÚloadedr   r   r   Ú!test_pickle_and_unpickle_identity~  s    
z1TestPersistence.test_pickle_and_unpickle_identityc             C   s&   t  | j¡}|  | ¡ | j ¡ ¡ d S )N)ÚcopyÚdeepcopyrS   r   rj   )r   Zcopiedr   r   r   Útest_deepcopy_identity†  s    z&TestPersistence.test_deepcopy_identityc             C   s:   t ddƒ}|j}| ¡ }|  dt|ƒ¡ |  ||j¡ d S )Ns   <p>&nbsp;</p>zhtml.parseru	   <p>Â </p>)r   Zoriginal_encodingÚ__copy__r   r(   )r   r$   Úencodingra  r   r   r   Útest_copy_preserves_encoding‹  s
    
z,TestPersistence.test_copy_preserves_encodingc             C   s>   d}|   |¡}t |tj¡}t |¡}|  | ¡ | ¡ ¡ d S )Nu
   <b>â˜ƒ</b>)r$   r[  r\  ZHIGHEST_PROTOCOLr]  r   rj   )r   r±   r$   r^  r_  r   r   r   Útest_unicode_pickle’  s
    

z#TestPersistence.test_unicode_picklec             C   sz   d}|   |¡}|jdd}t |¡}|  ||¡ |  d |j¡ |  d |j¡ |  d |j¡ |  d |j¡ |  d |j¡ d S )Nz<b>Foo<a></a></b><b>Bar</b>r4   )r   )	r$   r%   ra  r   r‘   r    ÚassertNotEqualrÁ   r¯   )r   r±   r$   Ús1Ús2r   r   r   Ú1test_copy_navigablestring_is_not_attached_to_treeš  s    

zATestPersistence.test_copy_navigablestring_is_not_attached_to_treec             C   s>   d}|   |¡}|j}t |¡}|  ||¡ |  t|tƒ¡ d S )Nz<b><!--Foo--></b>)r$   r   ra  r   rH   rÚ   r   )r   r±   r$   ri  rj  r   r   r   Ú0test_copy_navigablestring_subclass_has_same_type¦  s    

z@TestPersistence.test_copy_navigablestring_subclass_has_same_typec             C   s(   d}|   |¡}t |¡}|  ||¡ d S )Nz)<div><b>Foo<a></a></b><b>Bar</b></div>end)r$   ra  r   )r   r±   r$   Z	soup_copyr   r   r   Útest_copy_entire_soup®  s    

z%TestPersistence.test_copy_entire_soupc             C   s˜   d}|   |¡}|j}t |¡}|  t|ƒt|ƒ¡ |  ||¡ |  ||k¡ |  d |j¡ |  d |j¡ |  d |jddj	¡ |  
d |jddj	¡ d S )Nz)<div><b>Foo<a></a></b><b>Bar</b></div>endZBar)r   )r$   ra   ra  r   r(   r@  r‘   r¯   r%   r    rh  )r   r±   r$   ra   Zdiv_copyr   r   r   Útest_copy_tag_copies_contents´  s    

z-TestPersistence.test_copy_tag_copies_contents)r   r   r    r1   rR   r`  rc  rf  rg  rk  rl  rm  rn  rc   r   r   )rT   r   rZ  g  s   rZ  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 )"ÚTestSubstitutionsc             C   s0   d}|   |¡}|jdd}|  ||  d¡¡ d S )Nu#   <b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>Úminimal)Ú	formatter)r$   rj   r   ræ   )r   r¿   r$   Údecodedr   r   r   Ú!test_default_formatter_is_minimalÊ  s    
z3TestSubstitutions.test_default_formatter_is_minimalc             C   s0   d}|   |¡}|jdd}|  ||  d¡¡ d S )Nu'   <br><b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>r±   )rq  z.<br/><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>)r$   rj   r   ræ   )r   r¿   r$   rr  r   r   r   Útest_formatter_htmlÔ  s    
z%TestSubstitutions.test_formatter_htmlc             C   s0   d}|   |¡}|jdd}|  ||  d¡¡ d S )Nu'   <br><b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>Zhtml5)rq  z-<br><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>)r$   rj   r   ræ   )r   r¿   r$   rr  r   r   r   Útest_formatter_html5Ü  s    
z&TestSubstitutions.test_formatter_html5c             C   s0   d}|   |¡}|jdd}|  ||  d¡¡ d S )Nu#   <b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>rp  )rq  )r$   rj   r   ræ   )r   r¿   r$   rr  r   r   r   Útest_formatter_minimalä  s    
z(TestSubstitutions.test_formatter_minimalc             C   s0   d}|   |¡}|jd d}|  ||  d¡¡ d S )Nu#   <b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>)rq  u   <b><<SacrÃ© bleu!>></b>)r$   rj   r   ræ   )r   r¿   r$   rr  r   r   r   Útest_formatter_nullî  s
    
z%TestSubstitutions.test_formatter_nullc             C   s4   d}|   |¡}|jdd„ d}|  ||  d¡¡ d S )Nz!<b>&lt;foo&gt;</b><b>bar</b><br/>c             S   s   |   ¡ S )N)Úupper)Úxr   r   r   Ú<lambda>ú  s    z9TestSubstitutions.test_formatter_custom.<locals>.<lambda>)rq  z<b><FOO></b><b>BAR</b><br>)r$   rj   r   ræ   )r   r¿   r$   rr  r   r   r   Útest_formatter_custom÷  s    
z'TestSubstitutions.test_formatter_customc             C   sˆ   d}|   |¡}|j}d}|  || ¡ ¡ |  ||jdd¡ d}|  ||jdd¡ |  ||jd d¡ d}|  ||jdd	„ d¡ d S )
Nu%   <a href="http://a.com?a=b&c=Ã©">e</a>u)   <a href="http://a.com?a=b&amp;c=Ã©">e</a>rp  )rq  z/<a href="http://a.com?a=b&amp;c=&eacute;">e</a>r±   u%   <a href="HTTP://A.COM?A=B&C=Ã‰">E</a>c             S   s   |   ¡ S )N)rx  )ry  r   r   r   rz    s    zMTestSubstitutions.test_formatter_is_run_on_attribute_values.<locals>.<lambda>)r$   r/   r   rj   )r   r¿   r$   r/   Zexpect_minimalZexpect_htmlZexpect_upperr   r   r   Ú)test_formatter_is_run_on_attribute_values  s    
z;TestSubstitutions.test_formatter_is_run_on_attribute_valuesc             C   s$   d}t |dƒ ¡ }|  d|k¡ d S )NzO
  <script type="text/javascript">
   console.log("< < hey > > ");
  </script>
zhtml.parsers   < < hey > >)r   ri   rH   )r   rí   Úencodedr   r   r   Ú2test_formatter_skips_script_tag_for_html_documents  s    zDTestSubstitutions.test_formatter_skips_script_tag_for_html_documentsc             C   s$   d}t |dƒ ¡ }|  d|k¡ d S )NzF
  <style type="text/css">
   console.log("< < hey > > ");
  </style>
zhtml.parsers   < < hey > >)r   ri   rH   )r   rí   r}  r   r   r   Ú1test_formatter_skips_style_tag_for_html_documents  s    zCTestSubstitutions.test_formatter_skips_style_tag_for_html_documentsc             C   s    |   d¡}|  d|j ¡ ¡ d S )Nz*<div>  foo  <pre>  	bar
  
  </pre>  baz  z/<div>
 foo
 <pre>  	bar
  
  </pre>
 baz
</div>)r$   r   ra   Úprettify)r   r$   r   r   r   Ú,test_prettify_leaves_preformatted_text_alone$  s    
z>TestSubstitutions.test_prettify_leaves_preformatted_text_alonec             C   s,   t ddƒ}|jdd„ d}|  d|k¡ d S )Nz<html><body>foo</body></html>zhtml.parserc             S   s   |   ¡ S )N)rx  )ry  r   r   r   rz  .  s    zLTestSubstitutions.test_prettify_accepts_formatter_function.<locals>.<lambda>)rq  r  )r   r€  rH   )r   r$   Zprettyr   r   r   Ú(test_prettify_accepts_formatter_function,  s    
z:TestSubstitutions.test_prettify_accepts_formatter_functionc             C   s"   |   d¡}|  tt| ¡ ƒ¡ d S )Nz<a></a>)r$   r   r(   Útyper€  )r   r$   r   r   r   Ú(test_prettify_outputs_unicode_by_default1  s    
z:TestSubstitutions.test_prettify_outputs_unicode_by_defaultc             C   s$   |   d¡}|  tt| d¡ƒ¡ d S )Nz<a></a>zutf-8)r$   r   Úbytesrƒ  r€  )r   r$   r   r   r   Útest_prettify_can_encode_data5  s    
z/TestSubstitutions.test_prettify_can_encode_datac             C   s0   d}|   |¡}|j d¡}|  || d¡¡ d S )Nu   <b>SacrÃ© bleu!</b>zutf-8)r$   r"   ri   r   )r   r¿   r$   r}  r   r   r   Ú,test_html_entity_substitution_off_by_default9  s    
z>TestSubstitutions.test_html_entity_substitution_off_by_defaultc             C   sŠ   d}|   |¡}|  |jd d¡ | d¡}|  d|k¡ | d¡}|  d|k¡ | d¡}|  d	|k¡ | d
¡ d
¡}|  d|k¡ d S )NzE<meta content="text/html; charset=x-sjis" http-equiv="Content-type"/>Zcontentztext/html; charset=x-sjiszutf-8s   charset=utf-8Úeuc_jps   charset=euc_jpz	shift-jiss   charset=shift-jiszutf-16zcharset=utf-16)r$   r   Úmetari   rH   rj   )r   Zmeta_tagr$   Úutf_8rˆ  Ú	shift_jisZutf_16_ur   r   r   Útest_encoding_substitution?  s    



z,TestSubstitutions.test_encoding_substitutionc             C   s2   d}t dƒ}| j||d}|  |jd jd¡ d S )Nz`<head><meta content="text/html; charset=x-sjis" http-equiv="Content-type"/></head><pre>foo</pre>Zpre)Z
parse_onlyr   )r   r$   r   r…   rN   )r   r¿   ry   r$   r   r   r   Ú;test_encoding_substitution_doesnt_happen_if_tag_is_strainedW  s    zMTestSubstitutions.test_encoding_substitution_doesnt_happen_if_tag_is_strainedN)r   r   r    rs  rt  ru  rv  rw  r{  r|  r~  r  r  r‚  r„  r†  r‡  rŒ  r  r   r   r   r   ro  È  s    

	
		ro  c               @   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 )ÚTestEncodingz0Test the ability to encode objects into strings.c             C   s.   d}|   |¡}|  |jj d¡d d¡¡ d S )Nu
   <b>â˜ƒ</b>zutf-8u   â˜ƒ)r$   r   r"   r   ri   )r   r±   r$   r   r   r   Ú"test_unicode_string_can_be_encodede  s    
z/TestEncoding.test_unicode_string_can_be_encodedc             C   s,   d}|   |¡}|  |j d¡| d¡¡ d S )Nu
   <b>â˜ƒ</b>zutf-8)r$   r   r"   ri   )r   r±   r$   r   r   r   Ú1test_tag_containing_unicode_string_can_be_encodedk  s    
z>TestEncoding.test_tag_containing_unicode_string_can_be_encodedc             C   s&   d}|   |¡}|  |j d¡d¡ d S )Nu
   <b>â˜ƒ</b>Úasciis   <b>&#9731;</b>)r$   r   r"   ri   )r   r±   r$   r   r   r   Ú<test_encoding_substitutes_unrecognized_characters_by_defaultq  s    
zITestEncoding.test_encoding_substitutes_unrecognized_characters_by_defaultc             C   s&   d}|   |¡}| jt|jddd d S )Nu
   <b>â˜ƒ</b>r‘  Ústrict)Úerrors)r$   r‡   ÚUnicodeEncodeErrorri   )r   r±   r$   r   r   r   Ú test_encoding_can_be_made_strictv  s    
z-TestEncoding.test_encoding_can_be_made_strictc             C   s$   d}|   |¡}|  d|j ¡ ¡ d S )Nu
   <b>â˜ƒ</b>u   â˜ƒ)r$   r   r"   Zdecode_contents)r   r±   r$   r   r   r   Útest_decode_contents|  s    
z!TestEncoding.test_decode_contentsc             C   s.   d}|   |¡}|  d d¡|jjdd¡ d S )Nu
   <b>â˜ƒ</b>u   â˜ƒrg   )re  )r$   r   ri   r"   Zencode_contents)r   r±   r$   r   r   r   Útest_encode_contents  s
    
z!TestEncoding.test_encode_contentsc             C   s*   d}|   |¡}|  d d¡|j ¡ ¡ d S )Nu
   <b>â˜ƒ</b>u   â˜ƒrg   )r$   r   ri   r"   ZrenderContents)r   r±   r$   r   r   r   Útest_deprecated_renderContentsˆ  s    
z+TestEncoding.test_deprecated_renderContentsc             C   s8   d}|   |¡}tr$|  |t|ƒ¡ n|  dt|ƒ¡ d S )Nu
   <b>â˜ƒ</b>s   <b>\u2603</b>)r$   r   r   Úrepr)r   r±   r$   r   r   r   Ú	test_reprŽ  s
    
zTestEncoding.test_reprN)r   r   r    r1   r  r  r’  r–  r—  r˜  r™  r›  r   r   r   r   rŽ  b  s   rŽ  c               @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚTestNavigableStringSubclassesc             C   sX   |   d¡}tdƒ}| d|¡ |  t|ƒd¡ |  |jddd¡ |  |jd d¡ d S )Nr½   rB   r=   z<![CDATA[foo]]>)r)   r   )r$   r   rë   r   r(   r%   r…   )r   r$   r3  r   r   r   Ú
test_cdata˜  s    
z(TestNavigableStringSubclasses.test_cdatac                sV   dˆ _ ‡ fdd„}ˆ  d¡}tdƒ}| d|¡ ˆ  d|j|d¡ ˆ  dˆ j ¡ d	S )
zkText inside a CData object is passed into the formatter.

        But the return value is ignored.
        r   c                 s   ˆ  j d7  _ dS )Nr=   zBITTER FAILURE)Úcount)Úargs)r   r   r   Ú	increment©  s    zNTestNavigableStringSubclasses.test_cdata_is_never_formatted.<locals>.incrementr½   z<><><>r=   s   <![CDATA[<><><>]]>)rq  N)rž  r$   r   rë   r   ri   )r   r   r$   r3  r   )r   r   Útest_cdata_is_never_formatted¢  s    
z;TestNavigableStringSubclasses.test_cdata_is_never_formattedc             C   s2   t dƒ}|  d¡}| d|¡ |  | ¡ d¡ d S )NrB   r½   r=   s   <!DOCTYPE foo>
)r
   r$   rë   r   ri   )r   Zdoctyper$   r   r   r   Útest_doctype_ends_in_newline´  s    
z:TestNavigableStringSubclasses.test_doctype_ends_in_newlinec             C   s   t dƒ}|  d| ¡ ¡ d S )NrB   z<?foo?>)r	   r   Zoutput_ready)r   r  r   r   r   Útest_declaration¼  s    z.TestNavigableStringSubclasses.test_declarationN)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e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d0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Z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„ Z0dZd[„ Z1d\d]„ Z2d^d_„ Z3d`da„ Z4dbdc„ Z5ddde„ Z6dfdg„ Z7dhdi„ Z8djdk„ Z9dldm„ Z:dndo„ Z;dpdq„ Z<drds„ Z=dtS )uÚTestSoupSelectoraþ  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>The title</title>
<link rel="stylesheet" href="blah.css" type="text/css" id="l1">
</head>
<body>
<custom-dashed-tag class="dashed" id="dash1">Hello there.</custom-dashed-tag>
<div id="main" class="fancy">
<div id="inner">
<h1 id="header1">An H1</h1>
<p>Some text</p>
<p class="onep" id="p1">Some more text</p>
<h2 id="header2">An H2</h2>
<p class="class1 class2 class3" id="pmulti">Another</p>
<a href="http://bob.example.org/" rel="friend met" id="bob">Bob</a>
<h2 id="header3">Another H2</h2>
<a id="me" href="http://simonwillison.net/" rel="me">me</a>
<span class="s1">
<a href="#" id="s1a1">span1a1</a>
<a href="#" id="s1a2">span1a2 <span id="s1a2s1">test</span></a>
<span class="span2">
<a href="#" id="s2a1">span2a1</a>
</span>
<span class="span3"></span>
<custom-dashed-tag class="dashed" id="dash2"/>
<div data-tag="dashedvalue" id="data1"/>
</span>
</div>
<x id="xid">
<z id="zida"/>
<z id="zidab"/>
<z id="zidac"/>
</x>
<y id="yid">
<z id="zidb"/>
</y>
<p lang="en" id="lang-en">English</p>
<p lang="en-gb" id="lang-en-gb">English UK</p>
<p lang="en-us" id="lang-en-us">English US</p>
<p lang="fr" id="lang-fr">French</p>
</div>

<div id="footer">
</div>
c             C   s   t | jdƒ| _d S )Nzhtml.parser)r   ÚHTMLr$   )r   r   r   r   rR   ó  s    zTestSoupSelector.setUpc          
   K   sR   dd„ | j j|f|ŽD ƒ}| ¡  | ¡  |  ||d|d |¡d |¡f ¡ d S )Nc             S   s   g | ]}|d  ‘qS )r   r   )r   Úelr   r   r   r   ÷  s    z2TestSoupSelector.assertSelects.<locals>.<listcomp>z$Selector %s, expected [%s], got [%s]z, )r$   ÚselectÚsortr   Újoin)r   ÚselectorÚexpected_idsÚkwargsZel_idsr   r   r   r   ö  s    zTestSoupSelector.assertSelectsc             G   s"   x|D ]\}}|   ||¡ qW d S )N)ÚassertSelect)r   Ztestsrª  r«  r   r   r   ÚassertSelectMultiple  s    z%TestSoupSelector.assertSelectMultiplec             C   sF   | j  d¡}|  t|ƒd¡ |  |d jd¡ |  |d jdg¡ d S )Nrh   r=   r   z	The title)r$   r§  r   r,   rN   r…   )r   Úelsr   r   r   Útest_one_tag_one  s    z!TestSoupSelector.test_one_tag_onec             C   sX   | j  d¡}|  t|ƒd¡ x|D ]}|  |jd¡ q"W | j  d¡}|  d|d ¡ d S )Nra   é   Úmainr   )r$   r§  r   r,   rN   Ú
select_one)r   r¯  ra   r¦  r   r   r   Útest_one_tag_many  s    
z"TestSoupSelector.test_one_tag_manyc             C   s   | j  d¡}|  d |¡ d S )NZnonexistenttag)r$   r³  r   )r   Úmatchr   r   r   Ú(test_select_one_returns_none_if_no_match  s    z9TestSoupSelector.test_select_one_returns_none_if_no_matchc             C   s    | j  d¡}|  dddg¡ d S )Nzdiv divÚinnerÚdata1)r$   r§  r   )r   r¯  r   r   r   Útest_tag_in_tag_one  s    z$TestSoupSelector.test_tag_in_tag_onec             C   s&   x dD ]}|   |ddddg¡ qW d S )N)zhtml divzhtml body divzbody divr¸  r²  r·  Úfooter)r   )r   rª  r   r   r   Útest_tag_in_tag_many  s    
z%TestSoupSelector.test_tag_in_tag_manyc             C   sB   | j ddgdd | j dddgdd | j dd	ddd
gdd d S )Nzhtml divr²  r=   )r:   zhtml body divr·  r+   zbody divr¸  rº  r>   )r   )r   r   r   r   Ú
test_limit#  s    zTestSoupSelector.test_limitc             C   s   |   t| j d¡ƒd¡ d S )NÚdelr   )r   r,   r$   r§  )r   r   r   r   Útest_tag_no_match)  s    z"TestSoupSelector.test_tag_no_matchc             C   s   |   t| jjd¡ d S )Nztag%t)r‡   ÚSyntaxErrorr$   r§  )r   r   r   r   Útest_invalid_tag,  s    z!TestSoupSelector.test_invalid_tagc             C   s   |   dddg¡ d S )Nzcustom-dashed-tagÚdash1Údash2)r   )r   r   r   r   Útest_select_dashed_tag_ids/  s    z+TestSoupSelector.test_select_dashed_tag_idsc             C   s6   | j  d¡}|  |d jd¡ |  |d d d¡ d S )Nzcustom-dashed-tag[id="dash2"]r   zcustom-dashed-tagr   rÂ  )r$   r§  r   rN   )r   Zdashedr   r   r   Útest_select_dashed_by_id2  s    z)TestSoupSelector.test_select_dashed_by_idc             C   s   |   | j d¡d jd¡ d S )Nzbody > custom-dashed-tagr   zHello there.)r   r$   r§  r)   )r   r   r   r   Útest_dashed_tag_text7  s    z%TestSoupSelector.test_dashed_tag_textc             C   s    |   | j d¡| j d¡¡ d S )Nzcustom-dashed-tag)r   r$   r§  r-   )r   r   r   r   Ú#test_select_dashed_matches_find_all:  s    z4TestSoupSelector.test_select_dashed_matches_find_allc             C   s   |   ddgfdddgf¡ d S )NZh1Úheader1Zh2Úheader2Úheader3)r®  )r   r   r   r   Útest_header_tags=  s    z!TestSoupSelector.test_header_tagsc             C   sV   xPdD ]H}| j  |¡}|  t|ƒd¡ |  |d jd¡ |  |d d dg¡ qW d S )N)z.onepzp.onepzhtml p.onepr=   r   rÞ   rm   Úonep)r$   r§  r   r,   rN   )r   rª  r¯  r   r   r   Útest_class_oneC  s
    
zTestSoupSelector.test_class_onec             C   s    | j  d¡}|  t|ƒd¡ d S )Nzdiv.onepr   )r$   r§  r   r,   )r   r¯  r   r   r   Útest_class_mismatched_tagJ  s    z*TestSoupSelector.test_class_mismatched_tagc             C   s    xdD ]}|   |dg¡ qW d S )N)z	div#innerz#innerzdiv div#innerr·  )r   )r   rª  r   r   r   Útest_one_idN  s    
zTestSoupSelector.test_one_idc             C   s    | j  d¡}|  t|ƒd¡ d S )Nz#doesnotexistr   )r$   r§  r   r,   )r   r¯  r   r   r   Útest_bad_idR  s    zTestSoupSelector.test_bad_idc             C   sf   | j  d¡}|  t|ƒd¡ x|D ]}|  |jd¡ q"W |  |d d dg¡ |  |d  d¡¡ d S )Nzdiv#inner pr9   rÞ   r=   rm   rË  r   )r$   r§  r   r,   rN   r@  r?  )r   r¯  r¦  r   r   r   Útest_items_in_idV  s    
z!TestSoupSelector.test_items_in_idc             C   s*   x$dD ]}|   t| j |¡ƒd¡ qW d S )N)zdiv#main delzdiv#main div.oopszdiv div#mainr   )r   r,   r$   r§  )r   rª  r   r   r   Útest_a_bunch_of_emptys^  s    
z'TestSoupSelector.test_a_bunch_of_emptysc             C   s    xdD ]}|   |dg¡ qW d S )N)z.class1zp.class1z.class2zp.class2z.class3zp.class3zhtml p.class2zdiv#inner .class2Úpmulti)r   )r   rª  r   r   r   Útest_multi_class_supportb  s    
z)TestSoupSelector.test_multi_class_supportc             C   s    xdD ]}|   |dg¡ qW d S )N)z.class1.class3z.class3.class2z.class1.class2.class3rÒ  )r   )r   rª  r   r   r   Útest_multi_class_selectiong  s    
z+TestSoupSelector.test_multi_class_selectionc             C   s"   |   dddg¡ |   ddg¡ d S )Nz.s1 > aÚs1a1Ús1a2z.s1 > a spanÚs1a2s1)r   )r   r   r   r   Útest_child_selectorl  s    z$TestSoupSelector.test_child_selectorc             C   s   |   ddg¡ d S )Nz.s1 > a#s1a2 spanr×  )r   )r   r   r   r   Útest_child_selector_idp  s    z'TestSoupSelector.test_child_selector_idc             C   st   |   ddgfddgfddgfddgfddgfddgfd	dgfd
g fddgfddgfddgfdg fdg fdg f¡ d S )Nzp[class="onep"]rý   z
p[id="p1"]z[class="onep"]z	[id="p1"]zlink[rel="stylesheet"]Úl1zlink[type="text/css"]zlink[href="blah.css"]zlink[href="no-blah.css"]z[rel="stylesheet"]z[type="text/css"]z[href="blah.css"]z[href="no-blah.css"]zp[href="no-blah.css"])r®  )r   r   r   r   Útest_attribute_equalss  s    z&TestSoupSelector.test_attribute_equalsc             C   s\   |   ddgfddgfddgfddgfddgfddgfdd	gfd
d	gfdd	gfdd	gf¡
 d S )Nzp[class~="class1"]rÒ  zp[class~="class2"]zp[class~="class3"]z[class~="class1"]z[class~="class2"]z[class~="class3"]za[rel~="friend"]Úbobza[rel~="met"]z[rel~="friend"]z[rel~="met"])r®  )r   r   r   r   Útest_attribute_tilde…  s    z%TestSoupSelector.test_attribute_tildec             C   sv   |   ddgfddgfdg fdg fdg fddgfdd	d
gfdd	d
gfdddgfdd
dgfddgfdd
gfddgf¡ d S )Nz[rel^="style"]rÚ  zlink[rel^="style"]znotlink[rel^="notstyle"]z[rel^="notstyle"]zlink[rel^="notstyle"]zlink[href^="bla"]za[href^="http://"]rÜ  Úmez[href^="http://"]z	[id^="p"]rÒ  rý   z	[id^="m"]r²  zdiv[id^="m"]z
a[id^="m"]zdiv[data-tag^="dashed"]r¸  )r®  )r   r   r   r   Útest_attribute_startswith“  s    



z*TestSoupSelector.test_attribute_startswithc             C   sH   |   ddgfddgfddgfdddddd	d
ddgfddgfdg f¡ d S )Nz[href$=".css"]rÚ  zlink[href$=".css"]zlink[id$="1"]z	[id$="1"]r¸  rý   rÇ  rÕ  Ús2a1r×  rÁ  zdiv[id$="1"]z[id$="noending"])r®  )r   r   r   r   Útest_attribute_endswith¤  s    z(TestSoupSelector.test_attribute_endswithc             C   sÐ   |   ddgfddgfdg fdg fdg fddgfdd	d
gfdddgfddgfdd
gfddgfddgfddgfddddddddddg	fddgfdg fdd	d
dgfdd	d
gfd dgfd!dd"gfd#d"gfd$dgf¡ d S )%Nz[rel*="style"]rÚ  zlink[rel*="style"]znotlink[rel*="notstyle"]z[rel*="notstyle"]zlink[rel*="notstyle"]zlink[href*="bla"]z[href*="http://"]rÜ  rÞ  z	[id*="p"]rÒ  rý   zdiv[id*="m"]r²  z
a[id*="m"]z[href*=".css"]zlink[href*=".css"]zlink[id*="1"]z	[id*="1"]r¸  rÇ  rÕ  rÖ  rà  r×  rÁ  zdiv[id*="1"]z[id*="noending"]z[href*="."]za[href*="."]zlink[href*="."]zdiv[id*="n"]r·  zdiv[id*="nn"]zdiv[data-tag*="edval"])r®  )r   r   r   r   Útest_attribute_contains®  s.    



z(TestSoupSelector.test_attribute_containsc             C   s2   |   ddddgfddddgfddgfdg f¡ d S )	Nzp[lang|="en"]zlang-enz
lang-en-gbz
lang-en-usz[lang|="en"]zp[lang|="fr"]zlang-frzp[lang|="gb"])r®  )r   r   r   r   Útest_attribute_exact_or_hypenË  s
    z.TestSoupSelector.test_attribute_exact_or_hypenc             C   sV   |   ddddgfddgfdddgfddd	d
dgfdddgfdg fdg fddgf¡ d S )Nz[rel]rÚ  rÜ  rÞ  z	link[rel]za[rel]z[lang]zlang-enz
lang-en-gbz
lang-en-uszlang-frzp[class]rý   rÒ  z[blah]zp[blah]zdiv[data-tag]r¸  )r®  )r   r   r   r   Útest_attribute_existsÓ  s    

z&TestSoupSelector.test_attribute_existsc             C   s,   d}t |dƒ}| d¡\}|  d|j¡ d S )Nz]<div style="display: wrong">nope</div>
        <div style="display: right">yes</div>
        zhtml.parserzdiv[style="display: right"]Zyes)r   r§  r   r   )r   r±   r$   Zchosenr   r   r   Ú"test_quoted_space_in_selector_nameß  s    
z3TestSoupSelector.test_quoted_space_in_selector_namec             C   s(   |   t| jjd¡ |   t| jjd¡ d S )Nza:no-such-pseudoclassza:nth-of-type(a))r‡   r  r$   r§  r¿  )r   r   r   r   Útest_unsupported_pseudoclassç  s    z-TestSoupSelector.test_unsupported_pseudoclassc             C   s˜   | j  d¡}|  t|ƒd¡ |  |d jd¡ | j  d¡}|  t|ƒd¡ |  |d jd¡ | j  d¡}|  t|ƒd¡ | j  d¡}|  t|ƒd¡ d S )	Nzdiv#inner p:nth-of-type(1)r=   r   z	Some textzdiv#inner p:nth-of-type(3)ZAnotherzdiv#inner p:nth-of-type(4)zdiv p:nth-of-type(0))r$   r§  r   r,   r   )r   r¯  r   r   r   Útest_nth_of_typeî  s    z!TestSoupSelector.test_nth_of_typec             C   s2   | j  d¡}|  t|ƒd¡ |  |d jd¡ d S )Nzdiv#inner > p:nth-of-type(1)r=   r   z	Some text)r$   r§  r   r,   r   )r   r¯  r   r   r   Ú"test_nth_of_type_direct_descendant  s    z3TestSoupSelector.test_nth_of_type_direct_descendantc             C   s   |   ddg¡ d S )Nz#inner > p:nth-of-type(2)rý   )r   )r   r   r   r   Ú"test_id_child_selector_nth_of_type  s    z3TestSoupSelector.test_id_child_selector_nth_of_typec             C   s.   | j jddd}| d¡}|  |ddg¡ d S )Nra   r²  )r   r·  r¸  )r$   r%   r§  r   )r   r·  Úselectedr   r   r   Útest_select_on_element	  s    
z'TestSoupSelector.test_select_on_elementc             C   s   |   ddg¡ |   dg ¡ d S )Nz.fancy #innerr·  z.normal #inner)r   )r   r   r   r   Útest_overspecified_child_id  s    z,TestSoupSelector.test_overspecified_child_idc             C   sB   |   ddg¡ |   ddg¡ |   ddg¡ |  g | j d¡¡ d S )Nz#p1 + h2rÈ  z#p1 + h2 + prÒ  z#p1 + #header2 + .class1z#p1 + p)r   r   r$   r§  )r   r   r   r   Útest_adjacent_sibling_selector  s    z/TestSoupSelector.test_adjacent_sibling_selectorc             C   sR   |   dddg¡ |   ddg¡ |   ddg¡ |   ddg¡ |  g | j d¡¡ d S )	Nz#p1 ~ h2rÈ  rÉ  z#p1 ~ #header2z#p1 ~ h2 + arÞ  z#p1 ~ h2 + [rel="me"]z#inner ~ h2)r   r   r$   r§  )r   r   r   r   Útest_general_sibling_selector  s
    z.TestSoupSelector.test_general_sibling_selectorc             C   s   |   t| jjd¡ d S )Nzh1 >)r‡   r¿  r$   r§  )r   r   r   r   Útest_dangling_combinator#  s    z)TestSoupSelector.test_dangling_combinatorc             C   s   |   ddddg¡ d S )Nzp[lang] ~ pz
lang-en-gbz
lang-en-uszlang-fr)r   )r   r   r   r   Ú2test_sibling_combinator_wont_select_same_tag_twice&  s    zCTestSoupSelector.test_sibling_combinator_wont_select_same_tag_twicec             C   s   |   dddg¡ d S )Nzx, yÚxidÚyid)r   )r   r   r   r   Útest_multiple_select*  s    z%TestSoupSelector.test_multiple_selectc             C   s   |   dddg¡ d S )Nzx,yrñ  rò  )r   )r   r   r   r   Ú"test_multiple_select_with_no_space-  s    z3TestSoupSelector.test_multiple_select_with_no_spacec             C   s   |   dddg¡ d S )Nzx,    yrñ  rò  )r   )r   r   r   r   Ú$test_multiple_select_with_more_space0  s    z5TestSoupSelector.test_multiple_select_with_more_spacec             C   s   |   ddg¡ d S )Nzx, xrñ  )r   )r   r   r   r   Útest_multiple_select_duplicated3  s    z0TestSoupSelector.test_multiple_select_duplicatedc             C   s   |   dddg¡ d S )Nzx, y ~ p[lang=fr]rñ  zlang-fr)r   )r   r   r   r   Útest_multiple_select_sibling6  s    z-TestSoupSelector.test_multiple_select_siblingc             C   s   |   dddg¡ d S )Nzx, y > zrñ  Úzidb)r   )r   r   r   r   Ú.test_multiple_select_tag_and_direct_descendant9  s    z?TestSoupSelector.test_multiple_select_tag_and_direct_descendantc          	   C   s   |   dddddddg¡ d S )Nzdiv > x, y, zrñ  rò  Úzidarø  ÚzidabÚzidac)r   )r   r   r   r   Ú/test_multiple_select_direct_descendant_and_tags<  s    z@TestSoupSelector.test_multiple_select_direct_descendant_and_tagsc          	   C   s   |   dddddddg¡ d S )Nzdiv x,y,  zrñ  rò  rú  rø  rû  rü  )r   )r   r   r   r   Ú(test_multiple_select_indirect_descendant?  s    z9TestSoupSelector.test_multiple_select_indirect_descendantc             C   s(   |   t| jjd¡ |   t| jjd¡ d S )Nz,x, yzx,,y)r‡   r¿  r$   r§  )r   r   r   r   Útest_invalid_multiple_selectB  s    z-TestSoupSelector.test_invalid_multiple_selectc             C   s   |   dddg¡ d S )Nzp[lang=en], p[lang=en-gb]zlang-enz
lang-en-gb)r   )r   r   r   r   Útest_multiple_select_attrsF  s    z+TestSoupSelector.test_multiple_select_attrsc             C   s   |   ddddg¡ d S )Nz*x, y > z[id=zida], z[id=zidab], z[id=zidb]rñ  rø  rû  )r   )r   r   r   r   Útest_multiple_select_idsI  s    z)TestSoupSelector.test_multiple_select_idsc             C   s   |   dddg¡ d S )Nzbody > div > x, y > zrñ  rø  )r   )r   r   r   r   Útest_multiple_select_nestedL  s    z,TestSoupSelector.test_multiple_select_nestedc             C   sR   d}t |dƒ}| d¡}|  dt|ƒ¡ x$|jddgdD ]}||ks:t‚q:W d S )Nz3<div class="c1"/><div class="c2"/><div class="c1"/>zhtml.parserz.c1, .c2r9   Zc1Zc2)ro   )r   r§  r   r,   r-   rû   )r   r¿   r$   rê  rŠ   r   r   r   Útest_select_duplicate_elementsO  s    

z/TestSoupSelector.test_select_duplicate_elementsN)>r   r   r    r¥  rR   r   r­  r®  r°  r´  r¶  r¹  r»  r¼  r¾  rÀ  rÃ  rÄ  rÅ  rÆ  rÊ  rÌ  rÍ  rÎ  rÏ  rÐ  rÑ  rÓ  rÔ  rØ  rÙ  rÛ  rÝ  rß  rá  râ  rã  rä  rå  ræ  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¤  À  sv   1
	
	r¤  )2r1   Zpdbr   ra  r[  r6   r9  Zbs4r   Zbs4.builderr   r   Zbs4.elementr   r   r   r	   r
   r   r   r   Zbs4.testingr   r   rê   rß   ZLXML_PRESENTr   r!   r2   rL   rP   rd   rƒ   rŒ   r   rž   r­   r¼   rÀ   rÎ   rØ   rå   r5  rO  rZ  ro  rŽ  rœ  r¤  r   r   r   r   Ú<module>
   sN   (
;O 83(3--*   jn+a 4*