
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3
6]Í8 ã               @   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
jdƒdk	Ze
j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   | j 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   ú/usr/lib/python3.6/test_tree.pyú
<listcomp>2   s    z*TreeTest.assertSelects.<locals>.<listcomp>N)ÚassertEqual)ÚselfÚtagsÚshould_matchr   r   r   ÚassertSelects+   s    zTreeTest.assertSelectsc             C   s   | j 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   ÚassertSelectsIDs4   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"   | j dƒ}| j|j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_tagE   s    
zTestFind.test_find_tagc             C   s"   | j dƒ}| j|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_findI   s    
zTestFind.test_unicode_text_findc             C   s,   | j dƒ}t|ƒ | j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_findM   s    
z$TestFind.test_unicode_attribute_findc             C   s"   | j dƒ}| jdt|jƒ ƒƒ 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_everythingS   s    
zTestFind.test_find_everythingc             C   s$   | j dƒ}| jdt|j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_nameX   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�   | j dƒ}| j|jdd�dgƒ | j|jdd�dgƒ | j|jddgd�ddgƒ | j|jtjdƒd�dddgƒ | j|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‚   | j dƒ}| j|jddd�dddgƒ | j|jddd�dgƒ | j|jdd	d�dddd
dgƒ | j|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_limitp   s    
zTestFindAll.test_find_all_limitc             C   s:   | j dƒ}| j|ddd�dgƒ | j|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.   | j dƒ}g }|j|ƒ | jg |j|ƒƒ 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^   | j dƒ}|jdƒ}| jt|dƒƒ |jdƒ}| jt|dƒƒ |jdd�}| j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<   | j dƒ}| jd|jdƒjƒ | 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| ƒjƒ  | j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 | j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jddd�dgƒ | j | jjddd�ddgƒ | j | jjdtj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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   | j | j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 | j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 | j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 | j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 | jjtj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„ }| j dƒ}| j|j|ƒddgƒ d S )Nc             S   s   | j | 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   | j dƒ}|jddƒ}|jdtjdƒƒ}|jdddgƒ\}}| jd|jƒ | jd|jƒ | jd|jƒ | 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&   | j dƒ}| j|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j dƒ}dj dƒ}| j|ƒ}| j|jg|j|d�ƒ | j|jg|j|jdƒd�ƒ | j|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   | j dƒ}| j|jdd�dgƒ | j|jddid�dgƒ | j|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°   | j dƒ}| j|jddd�dgƒ | j|jddd�dgƒ | j|jdd	d�dgƒ | j|jddƒdgƒ | j|jdd
�ddgƒ | j|jddƒdgƒ | j|j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   | j dƒ}|jdtjdƒd�}| j|dgƒ |jdtjdƒd�}| j|dgƒ |jdtjdƒd�}| j|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   | j dƒ}| j|jdtjdƒƒdgƒ dd„ }| j|jd|ƒg ƒ dd„ }| j|j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_valueE  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Œ   | j dƒ}|jdƒ\}}| j||g|jddƒƒ | j|g|jddƒƒ | j|g|jddd�ƒ | j|g|jddƒƒ | jg |j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_classesK  s    
zQTestFindAllByAttribute.test_find_all_with_string_for_attrs_finds_multiple_classesc             C   s0   | j dƒ}tddid�}| j|j|ƒ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_soupstrainerW  s    z>TestFindAllByAttribute.test_find_all_by_attribute_soupstrainerc             C   s&   | j dƒ}| j|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&   | j dƒ}| j|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_attributeg  s    z;TestFindAllByAttribute.test_find_all_with_defined_attributec             C   s>   | j dƒ}ddg}| j|jdd�|ƒ | j|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_attributep  s
    z;TestFindAllByAttribute.test_find_all_with_numeric_attributec             C   s,   | j dƒ}| j|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_valuesy  s    z?TestFindAllByAttribute.test_find_all_with_list_attribute_valuesc             C   s,   | j dƒ}| j|jtj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   | j dƒ}|j}| j|g|jddd�ƒ | jg |jddd�ƒ | j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*   | j dƒ}| j|j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   | j dƒ}|j}| j|g|jddd�ƒ | j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   | j dƒ}|j}x(t|jƒD ]\}}| j||j|ƒƒ qW | j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| ƒjƒ  | j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jd dƒ | j | jjjd dƒ | j | 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| 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   | j 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 | jjdƒdddgƒ | j | 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 | jjdƒd dƒ | j | 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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�}| j|j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 ƒ}| j|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| ƒjƒ  | j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j| _d S )N)rQ   rž   rR   rS   r"   r�   )r   )rT   r   r   rR   õ  s    zTestNextOperations.setUpc             C   s*   | j | jjdƒ | j | 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|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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 | jjdƒddgƒ | jjdd� | j | 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 | jjdƒd dƒ | j | 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�}| j|jdƒjdƒ | j|j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 ƒ}|\}}| j|d dƒ | j|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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jd dƒ | j | 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 jdƒ}| j|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 | jjdƒdddgƒ | j | 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 | jjdƒd dƒ | j | jjdd�dƒ d S )Nr"   r   r<   rŸ   )r)   )r   r®   Úfind_previous)r   r   r   r   Útest_find_previous7  s    z)TestPreviousOperations.test_find_previousc             C   s>   | j jdd�}| j|jdƒjdƒ | j|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_previous_for_text_element;  s    z:TestPreviousOperations.test_find_previous_for_text_elementc             C   sh   | j jdd�}dd„ |jD ƒ}|\}}}}| j|d dƒ | j|jdƒ | j|jdƒ | j|jd	ƒ d S )
NrŸ   )r)   c             S   s   g | ]}|‘qS r   r   )r   r«   r   r   r   r   C  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_generatorA  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| ƒjƒ  d}tjdƒjd|ƒ}| j|ƒ| _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   P  s    zSiblingTest.setUp)r   r   r    rR   rc   r   r   )rT   r   r¼   N  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jdd�| _d S )Nr;   )r   )rQ   rÀ   rR   rS   r%   r�   )r   )rT   r   r   rR   f  s    zTestNextSibling.setUpc             C   s   | j | jjd ƒ d S )N)r   rS   Únext_sibling)r   r   r   r   Ú!test_next_sibling_of_root_is_nonej  s    z1TestNextSibling.test_next_sibling_of_root_is_nonec             C   sB   | j | jjd dƒ | j | jjjd dƒ | j | jjd dƒ d S )Nr   r#   r<   z1.1)r   r�   rÁ   r    )r   r   r   r   Útest_next_siblingm  s    z!TestNextSibling.test_next_siblingc             C   sN   | j | jjjd ƒ | jjdd�}| j |jd ƒ | jjdd�}| j |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_existt  s
    z/TestNextSibling.test_next_sibling_may_not_existc             C   s   | j | j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 | jjdƒdddgƒ | j | 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   | j dƒ}|jdd�}| j|jjdƒ | j|jjdƒ | j|jdƒdgƒ | j|jdd�dƒ | j|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À   d  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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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jd dƒ | j | jjjd dƒ | j | 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jd ƒ | jjdd�}| j |jd ƒ | jjdd�}| j |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 | j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 | jjdƒdddgƒ | j | 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   | j dƒ}|jdd�}| j|jjdƒ | j|jjdƒ | j|jdƒdgƒ | j|jdd�dƒ | j|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   | j dƒ}|jddddid�}| jt|tƒƒ | jd|jƒ | jtddd�|jƒ | 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ƒ}|jdƒ}|jdƒ}| jd|jƒ ƒ | jd|jƒ ƒ tddƒ}|jdƒ}|jdƒ}| jd|jƒ ƒ | jd|jƒ ƒ 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   | j dƒ}|jdƒ}| jd|ƒ | j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   | j dƒ}|jdtƒ}| jd|ƒ | j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               @   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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(dMS )NÚTestTreeModificationc             C   sl   | j dƒ}d|jd< | j|jƒ | jdƒƒ |jd= | j|jƒ | jdƒƒ d|jd< | j|jƒ | j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 jdƒƒ }| jd|d�}t||dƒ}t||dƒ}d|d< |jjd|ƒ |jjd	|ƒ | j|j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 |ƒ}|jdd�}|j}|jdd�j|jƒ | j|j|ƒ | j|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}|j|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 |ƒ}|j}|jƒ }| 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   | j dƒ}|j}|jƒ  | jd |jƒ | jt|jƒ | 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}|jj|ƒ | j|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}| j |ƒ}| j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}| j |ƒ}| j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_exception3  s    
zATestTreeModification.test_insert_tag_into_itself_raises_exceptionc       	      C   s’   | j dƒ}d}| j |ƒ}|jd|ƒ x|jD ]}t|tƒ s,t‚q,W t|jƒ\}}}}| jd|j	ƒ | jd|j	ƒ | jd|j	ƒ | 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_children8  s    

zFTestTreeModification.test_insert_beautifulsoup_object_inserts_childrenc             C   sX   | j dƒ}|j}|jd }|jddƒ |j\}}|jdƒ |jdƒ | j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_throughoutL  s    




zHTestTreeModification.test_replace_with_maintains_next_element_throughoutc             C   sl   | j dƒ}|jdd�jdƒ |jdd�}|j}| j|j|ƒ | j|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_node[  s    
z,TestTreeModification.test_replace_final_nodec             C   s˜   | j dƒ}|jjddƒ | j|jƒ | jdƒƒ |jdd�}| j|jdƒ | j|jj|ƒ | j|j	dƒ | j|j	j
|ƒ | j|j
d ƒ | j|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_nodese  s    

z0TestTreeModification.test_consecutive_text_nodesc             C   sT   | j dƒ}|jjddƒ |jjddƒ | jddg|j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_stringz  s
    
z'TestTreeModification.test_insert_stringc             C   sö   | j }| jd|d�}t||dƒ}|jddƒ |jjd|ƒ | j|jƒ | jdƒƒ |j}| j|j	|ƒ | j|j
|ƒ |jdd	�}| j|j|ƒ | j|j|ƒ |j}| j|j	|ƒ | j|j
|ƒ |jdd	�}| j|j|ƒ | j|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j|jƒ | 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   s2   d}| j |ƒ}|jjd|jƒ | jd|jƒ ƒ d S )Nz<a><b></b><c></c><d></d></a>r   z<a><d></d><b></b><c></c></a>)r$   r/   rë   Údr   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.   | j dƒ}|jjddƒ | j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`   | j dƒ}|jjdƒ |jjdƒ | j|jƒ | jdƒƒ |jj|jƒ | j|jƒ | 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)r$   r"   Úinsert_beforer/   r   rj   ræ   )r   r$   r   r   r   Útest_insert_before¶  s    
z'TestTreeModification.test_insert_beforec             C   s`   | j dƒ}|jjdƒ |jjdƒ | j|jƒ | jdƒƒ |jj|jƒ | j|jƒ | 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>BAZ)r$   r"   Úinsert_afterr/   r   rj   ræ   )r   r$   r   r   r   Útest_insert_afterÁ  s    
z&TestTreeModification.test_insert_afterc             C   sR   | j dƒ}|jdƒ}|jdƒ}| jt|j|ƒ | jt|j|ƒ | 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   | j dƒ}|jdƒ}|jdƒ}| jt|j|ƒ | jt|j|ƒ | 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   | j dƒ}|jdƒ\}}|j|ƒ | j|jƒ | jdƒƒ | j|jd ƒ | j|j|jƒ | j|jdƒ | j|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j|jƒ | jd|jƒ ƒ 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j|jƒ | jd|jƒ ƒ 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  | j dƒ}|j}|j}|j|ƒ | j|jƒ | jdƒƒ | j|jd ƒ | j|jdd�j	d ƒ | j|j
d ƒ | j|jd ƒ | j|jd ƒ | j|j|jƒ | j|j
dƒ | j|j	j	|jƒ | j|jd ƒ |jdd�}|j}| j|j	|ƒ | j|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WeZto)r$   r"   rr   rï   r   rj   ræ   r‘   r%   r    r¯   rÁ   rÏ   r/   ÚeÚg)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   | j dƒ}|jjƒ  | j|jd ƒ | j|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_unwrap  s
    
z TestTreeModification.test_unwrapc             C   sF   | j dƒ}|jj|jdƒƒ}| j|jƒ dƒ | j|jƒ | j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_wrap"  s
    
zTestTreeModification.test_wrapc             C   s4   | j dƒ}|jjj|jƒ | 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   | j dƒ}|jjj|jƒ | jdt|jjƒƒ | j|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_end/  s    

z;TestTreeModification.test_wrap_puts_new_contents_at_the_endc             C   sâ   | j dƒ}| jt|jjƒdƒ |jdd�jƒ }| j|jƒ dƒ | j|jƒ dƒ | jt|jjƒdƒ | j|jd ƒ | j|j	d ƒ | j|j
j
d ƒ |jdd	�}|jd
d	�}| j|j
|ƒ | j|j|ƒ | 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_extract7  s"    z!TestTreeModification.test_extractc             C   sz   | j dƒ}|jj}|jj}|jdƒ}|jdƒ}|jj|ƒ |jj|ƒ |jƒ  |jƒ  | 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_stringsP  s    


zITestTreeModification.test_extract_distinguishes_between_identical_stringsc                s8   | j dƒ‰ ‡ fdd„ˆ jdƒD ƒ | j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 jƒ ‘qS r   )Úscriptrô   )r   r‰   )r$   r   r   r   m  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_taga  s    
z7TestTreeModification.test_extract_multiples_of_same_tagc             C   s.   | j dƒ}|jdƒjƒ  | jd |j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_stringsq  s    zWTestTreeModification.test_extract_works_when_element_is_surrounded_by_identical_stringsc             C   sf   | j dƒ}|j}|jjƒ  | jt|jjƒdƒ | jt|dƒƒ |j	}|jdd� | j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_clearz  s    

zTestTreeModification.test_clearc             C   sB   | j dƒ}d|j_| j|jjdgƒ d|j_| 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,   | j dƒ}|jj|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   | j dƒ}tdƒ}||j_| 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*  r,  r   r   r   r   rå   è  sL   	
		
$	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   | j dƒ}| jt|jƒdƒ | jt|ƒdƒ | jt|jƒdƒ | j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   | j dƒ}| j|j|jdƒƒ | j|jj|jdƒjdƒƒ | j|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   | j dƒ}tjdd��}|j}W d Q R X | j|j|ƒ | 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   | j dƒ}| j|jjdƒƒ | j|j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}| j |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   | j dƒ}| j|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   | j dƒ}| j|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`   | j dƒ}| j|jjd ƒ | j dƒ}| j|jjd ƒ | j dƒ}|jjddƒ | j|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,   | j dƒ}| j|jjdƒ | j|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   | j dƒ}| j|jjƒ | j dƒ}| j|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$   r8  r"   r   )r   r$   r   r   r   Útest_lack_of_stringì  s    

z&TestElementObjects.test_lack_of_stringc             C   s`   | j dƒ}| j|jjdƒ | j|jjdd�dƒ | j|jjdƒdƒ | j|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   | j dƒ}| j|jƒ dƒ | j|jttfd�dƒ | j|jd d�dƒ d S )Nzfoo<!--IGNORE-->barZfoobar)ÚtypesZfooIGNOREbar)r$   r   rB  r   r   )r   r$   r   r   r   Útest_get_text_ignores_commentsü  s    
z1TestElementObjects.test_get_text_ignores_commentsc             C   s$   | j dƒ}| j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_comments  s    
z4TestElementObjects.test_all_strings_ignores_commentsN)r   r   r    r1   r.  r/  r5  r9  r:  r;  r<  r=  r>  r?  rC  rE  rF  r   r   r   r   r-  ›  s   		r-  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"   | j dƒ}| j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$   | j dƒ}| j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_list  s    
z9TestCDAtaListAttributes.test_multiple_values_becomes_listc             C   s&   | j dƒ}| j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_whitespace  s    
zJTestCDAtaListAttributes.test_multiple_values_separated_by_weird_whitespacec             C   s    | j dƒ}| jd|j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_output  s    
zDTestCDAtaListAttributes.test_attributes_joined_into_string_on_outputc             C   s$   | j dƒ}| jdg|j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_list  s    
z/TestCDAtaListAttributes.test_get_attribute_listc             C   s$   | j dƒ}| j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_charset!  s    
z+TestCDAtaListAttributes.test_accept_charsetc             C   s$   d}| j |ƒ}| j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_tag%  s    
zETestCDAtaListAttributes.test_cdata_attribute_applying_only_to_one_tagc                s6   | j dƒj‰ | jd ˆ jƒ ‡ fdd„}| jt|ƒ d S )Nrâ   c                  s
   dˆ _ d S )NrB   )rN   r   )r   r   r   Út0  s    zJTestCDAtaListAttributes.test_string_has_immutable_name_property.<locals>.t)r$   r   r   rN   r‡   ÚAttributeError)r   rO  r   )r   r   Ú'test_string_has_immutable_name_property-  s    z?TestCDAtaListAttributes.test_string_has_immutable_name_propertyN)r   r   r    r1   rH  rI  rJ  rK  rL  rM  rN  rQ  r   r   r   r   rG  	  s   rG  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| ƒjƒ  d| _| j| 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   rR  rR   Zpager$   rS   )r   )rT   r   r   rR   7  s    zTestPersistence.setUpc             C   s@   t j| jdƒ}t j|ƒ}| j|jtƒ | j|jƒ | jjƒ ƒ d S )Nr+   )ÚpickleÚdumpsrS   Úloadsr   rT   r   rj   )r   ÚdumpedÚloadedr   r   r   Ú!test_pickle_and_unpickle_identityK  s    
z1TestPersistence.test_pickle_and_unpickle_identityc             C   s&   t j| jƒ}| j|jƒ | jjƒ ƒ d S )N)ÚcopyÚdeepcopyrS   r   rj   )r   Zcopiedr   r   r   Útest_deepcopy_identityS  s    z&TestPersistence.test_deepcopy_identityc             C   s:   t ddƒ}|j}|jƒ }| jdt|ƒƒ | j||jƒ d S )Ns   <p>&nbsp;</p>zhtml.parseru	   <p>Â </p>)r   Zoriginal_encodingÚ__copy__r   r(   )r   r$   ÚencodingrY  r   r   r   Útest_copy_preserves_encodingX  s
    
z,TestPersistence.test_copy_preserves_encodingc             C   s>   d}| j |ƒ}tj|tjƒ}tj|ƒ}| j|jƒ |jƒ ƒ d S )Nu
   <b>â˜ƒ</b>)r$   rS  rT  ZHIGHEST_PROTOCOLrU  r   rj   )r   r±   r$   rV  rW  r   r   r   Útest_unicode_pickle_  s
    

z#TestPersistence.test_unicode_picklec             C   sz   d}| j |ƒ}|jdd�}tj|ƒ}| j||ƒ | jd |jƒ | jd |jƒ | jd |jƒ | jd |jƒ | jd |jƒ d S )Nz<b>Foo<a></a></b><b>Bar</b>r4   )r   )	r$   r%   rY  r   r‘   r    ÚassertNotEqualrÁ   r¯   )r   r±   r$   Ús1Ús2r   r   r   Ú1test_copy_navigablestring_is_not_attached_to_treeg  s    

zATestPersistence.test_copy_navigablestring_is_not_attached_to_treec             C   s>   d}| j |ƒ}|j}tj|ƒ}| j||ƒ | jt|tƒƒ d S )Nz<b><!--Foo--></b>)r$   r   rY  r   rH   rÚ   r   )r   r±   r$   ra  rb  r   r   r   Ú0test_copy_navigablestring_subclass_has_same_types  s    

z@TestPersistence.test_copy_navigablestring_subclass_has_same_typec             C   s(   d}| j |ƒ}tj|ƒ}| j||ƒ d S )Nz)<div><b>Foo<a></a></b><b>Bar</b></div>end)r$   rY  r   )r   r±   r$   Z	soup_copyr   r   r   Útest_copy_entire_soup{  s    

z%TestPersistence.test_copy_entire_soupc             C   s˜   d}| j |ƒ}|j}tj|ƒ}| jt|ƒt|ƒƒ | j||ƒ | j||kƒ | jd |jƒ | jd |jƒ | jd |jdd�j	ƒ | j
d |jdd�j	ƒ d S )Nz)<div><b>Foo<a></a></b><b>Bar</b></div>endZBar)r   )r$   ra   rY  r   r(   r8  r‘   r¯   r%   r    r`  )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   rX  r[  r^  r_  rc  rd  re  rf  rc   r   r   )rT   r   rR  4  s   rR  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 |ƒ}|jdd�}| j|| j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 |ƒ}|jdd�}| j|| jdƒƒ d S )Nu'   <br><b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>r±   )ri  z.<br/><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>)r$   rj   r   ræ   )r   r¿   r$   rj  r   r   r   Útest_formatter_html¡  s    
z%TestSubstitutions.test_formatter_htmlc             C   s0   d}| j |ƒ}|jdd�}| j|| jdƒƒ d S )Nu'   <br><b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>Zhtml5)ri  z-<br><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>)r$   rj   r   ræ   )r   r¿   r$   rj  r   r   r   Útest_formatter_html5©  s    
z&TestSubstitutions.test_formatter_html5c             C   s0   d}| j |ƒ}|jdd�}| j|| jdƒƒ d S )Nu#   <b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>rh  )ri  )r$   rj   r   ræ   )r   r¿   r$   rj  r   r   r   Útest_formatter_minimal±  s    
z(TestSubstitutions.test_formatter_minimalc             C   s0   d}| j |ƒ}|jd d�}| j|| jdƒƒ d S )Nu#   <b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>)ri  u   <b><<SacrÃ© bleu!>></b>)r$   rj   r   ræ   )r   r¿   r$   rj  r   r   r   Útest_formatter_null»  s
    
z%TestSubstitutions.test_formatter_nullc             C   s4   d}| j |ƒ}|jdd„ d�}| j|| jdƒƒ d S )Nz!<b>&lt;foo&gt;</b><b>bar</b><br/>c             S   s   | j ƒ S )N)Úupper)Úxr   r   r   Ú<lambda>Ç  s    z9TestSubstitutions.test_formatter_custom.<locals>.<lambda>)ri  z<b><FOO></b><b>BAR</b><br>)r$   rj   r   ræ   )r   r¿   r$   rj  r   r   r   Útest_formatter_customÄ  s    
z'TestSubstitutions.test_formatter_customc             C   sˆ   d}| j |ƒ}|j}d}| j||jƒ ƒ | j||jdd�ƒ d}| j||jdd�ƒ | j||jd d�ƒ d}| j||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>rh  )ri  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   | j ƒ S )N)rp  )rq  r   r   r   rr  Ý  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ƒjƒ }| j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ƒjƒ }| jd|kƒ d S )NzF
  <style type="text/css">
   console.log("< < hey > > ");
  </style>
zhtml.parsers   < < hey > >)r   ri   rH   )r   rí   ru  r   r   r   Ú1test_formatter_skips_style_tag_for_html_documentsè  s    zCTestSubstitutions.test_formatter_skips_style_tag_for_html_documentsc             C   s    | j dƒ}| jd|j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�}| jd|kƒ d S )Nz<html><body>foo</body></html>zhtml.parserc             S   s   | j ƒ S )N)rp  )rq  r   r   r   rr  û  s    zLTestSubstitutions.test_prettify_accepts_formatter_function.<locals>.<lambda>)ri  ZFOO)r   rx  rH   )r   r$   Zprettyr   r   r   Ú(test_prettify_accepts_formatter_functionù  s    
z:TestSubstitutions.test_prettify_accepts_formatter_functionc             C   s"   | j dƒ}| jtt|jƒ ƒƒ d S )Nz<a></a>)r$   r   r(   Útyperx  )r   r$   r   r   r   Ú(test_prettify_outputs_unicode_by_defaultþ  s    
z:TestSubstitutions.test_prettify_outputs_unicode_by_defaultc             C   s$   | j dƒ}| jtt|jdƒƒƒ d S )Nz<a></a>zutf-8)r$   r   Úbytesr{  rx  )r   r$   r   r   r   Útest_prettify_can_encode_data  s    
z/TestSubstitutions.test_prettify_can_encode_datac             C   s0   d}| j |ƒ}|jjdƒ}| j||jdƒƒ d S )Nu   <b>SacrÃ© bleu!</b>zutf-8)r$   r"   ri   r   )r   r¿   r$   ru  r   r   r   Ú,test_html_entity_substitution_off_by_default  s    
z>TestSubstitutions.test_html_entity_substitution_off_by_defaultc             C   sŠ   d}| j |ƒ}| j|jd dƒ |jdƒ}| jd|kƒ |jdƒ}| jd|kƒ |jdƒ}| jd	|kƒ |jd
ƒjd
ƒ}| j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|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_strained$  s    zMTestSubstitutions.test_encoding_substitution_doesnt_happen_if_tag_is_strainedN)r   r   r    rk  rl  rm  rn  ro  rs  rt  rv  rw  ry  rz  r|  r~  r  r„  r…  r   r   r   r   rg  •  s    

	
		rg  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|jjjdƒdj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_encoded2  s    
z/TestEncoding.test_unicode_string_can_be_encodedc             C   s,   d}| j |ƒ}| j|jjdƒ|j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_encoded8  s    
z>TestEncoding.test_tag_containing_unicode_string_can_be_encodedc             C   s&   d}| j |ƒ}| j|j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_default>  s    
zITestEncoding.test_encoding_substitutes_unrecognized_characters_by_defaultc             C   s&   d}| j |ƒ}| 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_strictC  s    
z-TestEncoding.test_encoding_can_be_made_strictc             C   s$   d}| j |ƒ}| jd|jjƒ ƒ d S )Nu
   <b>â˜ƒ</b>u   â˜ƒ)r$   r   r"   Zdecode_contents)r   r±   r$   r   r   r   Útest_decode_contentsI  s    
z!TestEncoding.test_decode_contentsc             C   s.   d}| j |ƒ}| jdjdƒ|jjdd�ƒ d S )Nu
   <b>â˜ƒ</b>u   â˜ƒrg   )r]  )r$   r   ri   r"   Zencode_contents)r   r±   r$   r   r   r   Útest_encode_contentsN  s
    
z!TestEncoding.test_encode_contentsc             C   s*   d}| j |ƒ}| jdjdƒ|jjƒ ƒ d S )Nu
   <b>â˜ƒ</b>u   â˜ƒrg   )r$   r   ri   r"   ZrenderContents)r   r±   r$   r   r   r   Útest_deprecated_renderContentsU  s    
z+TestEncoding.test_deprecated_renderContentsc             C   s8   d}| j |ƒ}tr$| j|t|ƒƒ n| j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†  /  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   | j dƒ}tdƒ}|jd|ƒ | jt|ƒdƒ | j|jdd�dƒ | j|jd dƒ d S )Nr½   rB   r=   z<![CDATA[foo]]>)r)   r   )r$   r   rë   r   r(   r%   r…   )r   r$   r+  r   r   r   Ú
test_cdatae  s    
z(TestNavigableStringSubclasses.test_cdatac                sV   dˆ _ ‡ fdd„}ˆ jdƒ}tdƒ}|jd|ƒ ˆ jd|j|d�ƒ ˆ j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   Ú	incrementv  s    zNTestNavigableStringSubclasses.test_cdata_is_never_formatted.<locals>.incrementr½   z<><><>r=   s   <![CDATA[<><><>]]>)ri  N)r–  r$   r   rë   r   ri   )r   r˜  r$   r+  r   )r   r   Útest_cdata_is_never_formattedo  s    
z;TestNavigableStringSubclasses.test_cdata_is_never_formattedc             C   s2   t dƒ}| jdƒ}|jd|ƒ | j|jƒ 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ƒ}| jd|jƒ ƒ 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”  c  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 ƒ}|jƒ  |jƒ  | j||d|dj|ƒdj|ƒ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 ]\}}| j ||ƒ qW d S )N)ÚassertSelect)r   Ztestsr¢  r£  r   r   r   ÚassertSelectMultipleÏ  s    z%TestSoupSelector.assertSelectMultiplec             C   sF   | j jdƒ}| jt|ƒdƒ | j|d jdƒ | j|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 jdƒ}| jt|ƒdƒ x|D ]}| j|jdƒ q"W | j jdƒ}| j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 jdƒ}| j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 jdƒ}| j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 ]}| j |ddddgƒ qW d S )	Núhtml divúhtml body divúbody divr°  rª  r¯  Úfooter)r²  r³  r´  )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   | j t| j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   | j t| jjdƒ d S )Nztag%t)r‡   rˆ   r$   rŸ  )r   r   r   r   Útest_invalid_tagù  s    z!TestSoupSelector.test_invalid_tagc             C   s   | j 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 jdƒ}| j|d jdƒ | j|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_idÿ  s    z)TestSoupSelector.test_select_dashed_by_idc             C   s   | j | j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_text  s    z%TestSoupSelector.test_dashed_tag_textc             C   s    | j | jjdƒ| j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   | j 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 j|ƒ}| jt|ƒdƒ | j|d jdƒ | j|d d dgƒ qW d S )
Nú.onepúp.onepúhtml p.onepr=   r   rÞ   rm   Úonep)rÅ  rÆ  rÇ  )r$   rŸ  r   r,   rN   )r   r¢  r§  r   r   r   Útest_class_one  s
    
zTestSoupSelector.test_class_onec             C   s    | j jdƒ}| jt|ƒdƒ d S )Nzdiv.onepr   )r$   rŸ  r   r,   )r   r§  r   r   r   Útest_class_mismatched_tag  s    z*TestSoupSelector.test_class_mismatched_tagc             C   s    xdD ]}| j |dgƒ qW d S )Nú	div#innerú#innerúdiv div#innerr¯  )rË  rÌ  rÍ  )r   )r   r¢  r   r   r   Útest_one_id  s    
zTestSoupSelector.test_one_idc             C   s    | j jdƒ}| jt|ƒdƒ d S )Nz#doesnotexistr   )r$   rŸ  r   r,   )r   r§  r   r   r   Útest_bad_id  s    zTestSoupSelector.test_bad_idc             C   sf   | j jdƒ}| jt|ƒdƒ x|D ]}| j|jdƒ q"W | j|d d dgƒ | j|d jdƒƒ d S )Nzdiv#inner pr9   rÞ   r=   rm   rÈ  r   )r$   rŸ  r   r,   rN   r8  r7  )r   r§  rž  r   r   r   Útest_items_in_id#  s    
z!TestSoupSelector.test_items_in_idc             C   s*   x$dD ]}| j t| jj|ƒƒdƒ qW d S )Núdiv#main delúdiv#main div.oopsúdiv div#mainr   )rÑ  rÒ  rÓ  )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 ]}| j |d	gƒ qW d S )Nú.class1úp.class1ú.class2úp.class2ú.class3úp.class3úhtml p.class2údiv#inner .class2Úpmulti)rÕ  rÖ  r×  rØ  rÙ  rÚ  rÛ  rÜ  )r   )r   r¢  r   r   r   Útest_multi_class_support/  s    z)TestSoupSelector.test_multi_class_supportc             C   s    xdD ]}| j |dgƒ qW d S )Nú.class1.class3ú.class3.class2ú.class1.class2.class3rÝ  )rß  rà  rá  )r   )r   r¢  r   r   r   Útest_multi_class_selection4  s    z+TestSoupSelector.test_multi_class_selectionc             C   s"   | j dddgƒ | j ddgƒ d S )Nz.s1 > aÚs1a1Ús1a2z.s1 > a spanÚs1a2s1)r   )r   r   r   r   Útest_child_selector9  s    z$TestSoupSelector.test_child_selectorc             C   s   | j ddgƒ d S )Nz.s1 > a#s1a2 spanrå  )r   )r   r   r   r   Útest_child_selector_id=  s    z'TestSoupSelector.test_child_selector_idc             C   st   | j 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_equals@  s    z&TestSoupSelector.test_attribute_equalsc             C   s\   | j 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_tildeR  s    z%TestSoupSelector.test_attribute_tildec             C   sv   | j 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   | j 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_endswithq  s    z(TestSoupSelector.test_attribute_endswithc             C   sÐ   | j 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   | j 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   | j 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ƒ}|jdƒ\}| jd|jƒ d S )Nz]<div style="display: wrong">nope</div>
        <div style="display: right">yes</div>
        zhtml.parserzdiv[style="display: right"]Ú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(   | j t| jjdƒ | j t| jjdƒ d S )Nza:no-such-pseudoclassza:nth-of-type(a))r‡   r  r$   rŸ  )r   r   r   r   Útest_unsupported_pseudoclass´  s    z-TestSoupSelector.test_unsupported_pseudoclassc             C   sŽ   | j jdƒ}| jt|ƒdƒ | j|d jdƒ | j jdƒ}| jt|ƒdƒ | j|d jdƒ | j jdƒ}| jt|ƒdƒ | jt| j j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   r   r   Útest_nth_of_type¼  s    z!TestSoupSelector.test_nth_of_typec             C   s2   | j jdƒ}| jt|ƒdƒ | j|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   | j 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�}|jdƒ}| j|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   | j ddgƒ | j 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   | j ddgƒ | j ddgƒ | j ddgƒ | jg | j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   | j dddgƒ | j ddgƒ | j ddgƒ | j ddgƒ | jg | j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   | j 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   | j 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   | j 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   | j 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   | j dddgƒ d S )Nzx,    yr   r  )r   )r   r   r   r   Ú$test_multiple_select_with_more_spaceþ  s    z5TestSoupSelector.test_multiple_select_with_more_spacec             C   s   | j ddgƒ d S )Nzx, xr   )r   )r   r   r   r   Útest_multiple_select_duplicated  s    z0TestSoupSelector.test_multiple_select_duplicatedc             C   s   | j dddgƒ d S )Nzx, y ~ p[lang=fr]r   zlang-fr)r   )r   r   r   r   Útest_multiple_select_sibling  s    z-TestSoupSelector.test_multiple_select_siblingc             C   s   | j dddgƒ d S )Nzx, y > zr   Úzidb)r   )r   r   r   r   Ú.test_multiple_select_tag_and_direct_descendant  s    z?TestSoupSelector.test_multiple_select_tag_and_direct_descendantc             C   s   | j 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   | j 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(   | j t| jjdƒ | j t| jjdƒ d S )Nz,x, yzx,,y)r‡   rˆ   r$   rŸ  )r   r   r   r   Útest_invalid_multiple_select  s    z-TestSoupSelector.test_invalid_multiple_selectc             C   s   | j 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_attrs  s    z+TestSoupSelector.test_multiple_select_attrsc             C   s   | j 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_ids  s    z)TestSoupSelector.test_multiple_select_idsc             C   s   | j dddgƒ d S )Nzbody > div > x, y > zr   r  )r   )r   r   r   r   Útest_multiple_select_nested  s    z,TestSoupSelector.test_multiple_select_nestedc             C   sR   d}t |dƒ}|jdƒ}| j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_elements  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   rY  rS  r6   r1  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å   r-  rG  rR  rg  r†  r”  rœ  r   r   r   r   Ú<module>   sN   (
;O 83(3--*   6n+a 4*