B
    ê¹`]] ã               @   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mZmZmZmZ ddlmZmZ ddl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ƒZ0G d+d,„ d,eƒZ1G d-d.„ d.eƒZ2G d/d0„ d0eƒZ3G d1d2„ d2eƒZ4G d3d4„ d4eƒZ5G d5d6„ d6eƒZ6G d7d8„ d8eƒZ7G d9d:„ d:eƒZ8G d;d<„ d<eƒZ9G d=d>„ d>e!ƒZ:dS )?a8  Tests for Beautiful Soup's tree traversal methods.

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

Different parsers will build different Beautiful Soup trees given the
same markup, but all Beautiful Soup trees can be traversed with the
methods tested here.
é    )Ú	set_traceN)ÚBeautifulSoup)Úbuilder_registryÚHTMLParserTreeBuilder)ÚPY3KÚCDataÚCommentÚDeclarationÚDoctypeÚ	FormatterÚNavigableStringÚScriptÚSoupStrainerÚ
StylesheetÚTagÚTemplateString)ÚSoupTestÚskipIf)ÚSelectorSyntaxErrorÚxmlÚ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   ú[/home/kop/projects/devel/pgwui/test_venv/lib/python3.7/site-packages/bs4/tests/test_tree.pyú
<listcomp>6   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   ÚassertSelectsIDs8   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_tagI   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_findM   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_findQ   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_everythingW   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>r2   ÚaN)r+   r   r3   r4   )r   r+   r   r   r   Útest_find_everything_with_name\   s    
z'TestFind.test_find_everything_with_nameN)	r%   r&   r'   Ú__doc__r-   r.   r1   r5   r7   r   r   r   r   r(   B   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   )r0   ÚFooz.*õ   Â»TN)r+   r   r4   ÚreÚcompile)r   r+   r   r   r   Útest_find_all_text_nodesd   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>r6   é   )ÚlimitÚ1r*   Ú3é   é
   Ú4Ú5r   N)r+   r"   r4   )r   r+   r   r   r   Útest_find_all_limitt   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>r6   rD   )rA   rB   Úfoo)r#   rC   )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   r4   )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>r6   ÚsourceTrI   )r0   N)r+   r4   Ú
assertTrueÚhasattr)r   r+   Úresultr   r   r   Útest_find_all_resultset   s    


z#TestFindAll.test_find_all_resultsetN)	r%   r&   r'   r8   r?   rH   rJ   rM   rR   r   r   r   r   r9   a   s   
r9   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">rF   zmathml:msqrtr6   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'   rV   r   r   r   r   rS   œ   s   rS   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   rY   §   s    zTestFindAllByName.setUpc             C   s   |   | j d¡ddg¡ d S )Nr6   z
First tag.zNested tag.)r"   rZ   r4   )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 )Nr6   z
First tag.)r0   TzNested tag.r   )r"   rZ   r4   r=   r>   )r   r   r   r   Útest_find_all_by_name_and_text²   s    z0TestFindAllByName.test_find_all_by_name_and_textc             C   s   |   | jj d¡dg¡ d S )Nr6   zNested tag.)r"   rZ   Úcr4   )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 )Nr6   z
First tag.zNested tag.)r"   rZ   )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 )Nr6   z
First tag.zNested tag.)r"   rZ   r4   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 )Nr6   r)   z
First tag.zSecond tag.zNested tag.)r"   rZ   r4   )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)r6   r)   z
First tag.zSecond tag.zNested tag.)r"   rZ   r4   )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"   rZ   r4   r=   r>   )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#   )rU   Ú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"   r4   )r   rf   rZ   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 brC   rB   )r+   r,   r=   r>   r4   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'   r8   rY   r\   r]   r_   r`   ra   rb   rc   rd   rg   ri   Ú__classcell__r   r   )r[   r   rW   ¤   s   rW   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"   r4   )r   rZ   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   r6   r4   Ú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)rU   zA tag called 'name1'.rU   )rT   zName match.ÚclassZclass2zClass match.)r+   r"   r4   )r   rZ   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>
                         r6   rB   )Úclass_zClass 1.r^   rC   zClass 3 and 4.rF   )rT   )r+   r"   r4   )r   rZ   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)rv   zFound itr6   zo b)r+   r4   r=   r>   r"   )r   rZ   Úfr   r   r   Ú0test_find_by_class_when_multiple_classes_present1  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>r6   ÚbazFound itc             S   s   t | ƒdkS )Nr@   )r3   )Úvaluer   r   r   Úbig_attribute_valueD  s    znTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.big_attribute_valuec             S   s   t | ƒdkS )Nr@   )r3   )r|   r   r   r   Úsmall_attribute_valueI  s    zpTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.small_attribute_value)r+   r"   r4   r=   r>   )r   r+   r}   r~   r   r   r   Ú:test_find_all_with_non_dictionary_for_attrs_finds_by_class?  s    
zQTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_classc             C   sŒ   |   d¡}| d¡\}}|  ||g| 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>r6   rI   r:   zfoo bar)rv   zbar foo)r+   r4   r   )r   r+   r6   Za2r   r   r   Ú:test_find_all_with_string_for_attrs_finds_multiple_classesO  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#   rl   )rT   zMatch.)r+   r   r"   r4   )r   rZ   Ústrainerr   r   r   Ú'test_find_all_by_attribute_soupstrainer[  s    z>TestFindAllByAttribute.test_find_all_by_attribute_soupstrainerc             C   s&   |   d¡}|  |jdd ddg¡ d S )Nz<a id="1">ID present.</a>
                            <a>No ID present.</a>
                            <a id="">ID is empty.</a>r6   )r#   zNo ID present.)r+   r"   r4   )r   rZ   r   r   r   Ú$test_find_all_with_missing_attributec  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"   r4   )r   rZ   r   r   r   Ú$test_find_all_with_defined_attributek  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.rD   )r#   rB   )r+   r"   r4   )r   rZ   Úexpectedr   r   r   Ú$test_find_all_with_numeric_attributet  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>rB   rC   rF   )r#   )r+   r"   r4   )r   rZ   r   r   r   Ú(test_find_all_with_list_attribute_values}  s    z?TestFindAllByAttribute.test_find_all_with_list_attribute_valuesc             C   s,   |   d¡}|  |jt d¡dddg¡ d S )NzÞ<a id="a">One a.</a>
                            <a id="aa">Two as.</a>
                            <a id="ab">Mixed as and bs.</a>
                            <a id="b">One b.</a>
                            <a>No ID.</a>z^a+$)r#   zOne a.zTwo as.)r+   r"   r4   r=   r>   )r   rZ   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>r6   rI   )r0   r:   )r+   r6   r   r4   )r   r+   r6   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>r6   rI   )r0   )r+   r   r4   )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>r2   rI   )r#   r0   rD   r:   )r+   r6   r   r4   )r   r+   r6   r   r   r   Ú,test_find_by_attribute_and_containing_string   s    
zCTestFindAllByAttribute.test_find_by_attribute_and_containing_stringN)r%   r&   r'   rm   rs   ru   rw   rz   r   r€   r‚   rƒ   r„   r†   r‡   rˆ   r‰   rŠ   r‹   r   r   r   r   rk   ó   s    		
rk   c               @   s   e Zd ZdZdd„ ZdS )Ú
TestSmoothzTest Tag.smooth.c             C   s  |   d¡}|j}| d¡ | d¡ | tdƒ¡ | tdƒ¡ | d¡ |  ¡ }t||dƒ}| d¡ | d	¡ | |¡ |  d |jj¡ |  d
t	|j
ƒ¡ | ¡  |  dt	|j
ƒ¡ |  d|j
d ¡ |  d|jj¡ |  d|j
d ¡ |  d|j
d ¡ d S )Nz<div>a</div>r)   r^   z	Comment 1z	Comment 2ÚdÚspanrB   r*   é   é   Úabcr   Z12rD   r2   )r+   rh   rK   r   Údefault_builderr   r   rŽ   r   r3   ÚcontentsZsmooth)r   r+   rh   ÚbuilderrŽ   r   r   r   Útest_smooth«  s(    






zTestSmooth.test_smoothN)r%   r&   r'   r8   r•   r   r   r   r   rŒ   ¨  s   rŒ   c               @   s   e Zd ZdZdd„ ZdS )Ú	TestIndexzTest Tag.indexc             C   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>rD   )r+   rh   Ú	enumerater“   r   ÚindexÚassertRaisesÚ
ValueError)r   rZ   rh   ÚiÚelementr   r   r   Ú
test_indexÖ  s    zTestIndex.test_indexN)r%   r&   r'   r8   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>)rX   rž   rY   r+   rZ   r)   Ústart)r   )r[   r   r   rY   é  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   )rZ   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   rZ   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)r0   r)   )rZ   r,   r   r£   rU   )r   r0   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)r0   r§   r#   r    )rZ   r,   r   r©   )r   r0   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#   )rT   )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'   r8   rY   r¤   r¥   r¦   r¨   rª   r«   r¬   r®   rj   r   r   )r[   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>)rX   r   rY   r+   rZ   )r   )r[   r   r   rY     s    zProximityTest.setUp)r%   r&   r'   rY   rj   r   r   )r[   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)rX   r°   rY   rZ   r)   rŸ   )r   )r[   r   r   rY   #  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)r0   )rZ   r,   r   r²   )r   Úlastr   r   r   Útest_next_of_last_item_is_none+  s    z1TestNextOperations.test_next_of_last_item_is_nonec             C   s   |   | jjd ¡ d S )N)r   rZ   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´   r@   )r#   )r"   rŸ   Úfind_all_next)r   r   r   r   Útest_find_all_next3  s    z%TestNextOperations.test_find_all_nextc             C   s2   |   | j d¡d d¡ |   | jjddd¡ d S )Nr)   r#   r*   r´   )r0   )r   rŸ   Ú	find_next)r   r   r   r   Útest_find_next8  s    z!TestNextOperations.test_find_nextc             C   s<   | j jdd}|  | d¡jd¡ |  | d¡ddg¡ d S )Nr±   )r0   r)   r¸   r´   )rZ   r,   r   r»   r   r"   r¹   )r   r0   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¸   )r0   c             S   s   g | ]}|‘qS r   r   )r   Únoder   r   r   r   C  s    z:TestNextOperations.test_next_generator.<locals>.<listcomp>r#   rC   r´   )rZ   r,   Znext_elementsr   )r   rŸ   Ú
successorsr   r“   r   r   r   Útest_next_generatorA  s
    z&TestNextOperations.test_next_generator)r%   r&   r'   rY   r³   r¶   r·   rº   r¼   r½   rÀ   rj   r   r   )r[   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´   )r0   )rX   rÁ   rY   rZ   r,   Úend)r   )r[   r   r   rY   K  s    zTestPreviousOperations.setUpc             C   s*   |   | jjd d¡ |   | jjjd¡ d S )Nr#   rC   r¸   )r   rÂ   Úprevious_element)r   r   r   r   Útest_previousO  s    z$TestPreviousOperations.test_previousc             C   s   | j  d¡}|  |jd ¡ d S )NÚhtml)rZ   r,   r   rÃ   )r   rl   r   r   r   Ú#test_previous_of_first_item_is_noneS  s    z:TestPreviousOperations.test_previous_of_first_item_is_nonec             C   s   d S )Nr   )r   r   r   r   Útest_previous_of_root_is_noneW  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±   rD   )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#   rC   r±   )r0   )r   rÂ   Úfind_previous)r   r   r   r   Útest_find_previouse  s    z)TestPreviousOperations.test_find_previousc             C   s>   | j jdd}|  | d¡jd¡ |  | d¡dddg¡ d S )Nr´   )r0   r)   r¸   r±   )rZ   r,   r   rÊ   r   r"   rÈ   )r   r0   r   r   r   Ú#test_find_previous_for_text_elementi  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±   )r0   c             S   s   g | ]}|‘qS r   r   )r   r¾   r   r   r   r   q  s    zBTestPreviousOperations.test_previous_generator.<locals>.<listcomp>r#   rB   ÚbodyÚheadrÅ   )rZ   r,   Zprevious_elementsr   rU   )r   rŸ   Zpredecessorsr)   rÍ   rÎ   rÅ   r   r   r   Útest_previous_generatoro  s    z.TestPreviousOperations.test_previous_generator)r%   r&   r'   rY   rÄ   rÆ   rÇ   rÉ   rË   rÌ   rÏ   rj   r   r   )r[   r   rÁ   I  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*Ú )rX   rÐ   rY   r=   r>   Úsubr+   rZ   )r   Úmarkup)r[   r   r   rY   ~  s    zSiblingTest.setUp)r%   r&   r'   rY   rj   r   r   )r[   r   rÐ   |  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 )NrB   )r#   )rX   rÔ   rY   rZ   r,   rŸ   )r   )r[   r   r   rY   ”  s    zTestNextSibling.setUpc             C   s   |   | jjd ¡ d S )N)r   rZ   Únext_sibling)r   r   r   r   Ú!test_next_sibling_of_root_is_none˜  s    z1TestNextSibling.test_next_sibling_of_root_is_nonec             C   sB   |   | jjd d¡ |   | jjjd d¡ |   | jjd d¡ d S )Nr#   r*   rC   z1.1)r   rŸ   rÕ   r²   )r   r   r   r   Útest_next_sibling›  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#   rF   )r   rZ   rÅ   rÕ   r,   )r   Únested_spanZ	last_spanr   r   r   Útest_next_sibling_may_not_exist¢  s
    z/TestNextSibling.test_next_sibling_may_not_existc             C   s   |   | j d¡d d¡ d S )NrŽ   r#   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*   rC   rF   )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>bazr;   )r0   r)   Úbazr:   Únonesuch)r+   r,   r   rÕ   rU   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'   rY   rÖ   r×   rÙ   rÛ   rÝ   rà   rj   r   r   )r[   r   rÔ   ’  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 )NrF   )r#   )rX   rá   rY   rZ   r,   rÂ   )r   )r[   r   r   rY   Á  s    zTestPreviousSibling.setUpc             C   s   |   | jjd ¡ d S )N)r   rZ   Ú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#   rC   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#   rB   )r   rZ   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#   rC   )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Ž   rC   r*   rB   )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Þ   )r0   r)   r;   r:   rß   )r+   r,   r   râ   rU   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'   rY   rã   rä   rå   rç   ré   rê   rj   r   r   )r[   r   rá   ¿  s   	rá   c               @   s   e Zd Zdd„ ZdS )ÚTestTagc             C   st   |   d¡ d¡}d |_|  d| d¡¡ dg|_|  d| d¡¡ |  d| d ¡¡ ddg|_|  d| d¡¡ d S )NrÑ   Za_tagTr   Zsome_other_tagrD   F)r+   Únew_tagZ_preserve_whitespace_tagsr   Z_should_pretty_printÚpreserve_whitespace_tags)r   r   r   r   r   Útest__should_pretty_printð  s    
z!TestTag.test__should_pretty_printN)r%   r&   r'   rî   r   r   r   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Ñ   rI   rÞ   rU   za name)r:   rT   )r:   rU   )
r+   rì   rO   Ú
isinstancer   r   rU   ÚdictrT   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   rp   )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Ñ   rI   )r+   Ú
new_stringr   rO   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Ñ   rI   )r+   r÷   r   r   rO   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'   r8   rò   rö   rù   rú   r   r   r   r   rï     s
   rï   c               @   sd  e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Zd5d6„ Zd7d8„ Zd9d:„ Zd;d<„ Z d=d>„ Z!d?d@„ Z"dAdB„ Z#dCdD„ Z$dEdF„ Z%dGdH„ Z&dIdJ„ Z'dKdL„ Z(dMdN„ Z)dOdP„ Z*dQdR„ Z+dSdT„ Z,dUdV„ Z-dWS )XÚTestTreeModificationc             C   sl   |   d¡}d|jd< |  | ¡ |  d¡¡ |jd= |  | ¡ |  d¡¡ d|jd< |  | ¡ |  d¡¡ d S )	Nz<a id="1"></a>r2   r#   z<a id="2"></a>z<a></a>rI   Zid2z<a id2="foo"></a>)r+   r6   r   rq   Údocument_for)r   r+   r   r   r   Útest_attribute_modification0  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>)r”   r6   Úolzhttp://foo.com/Úhrefr   rD   s4   <body><a href="http://foo.com/"></a><ol></ol></body>)r   Úlookupr+   r   rÍ   Úinsertr   rp   )r   r”   r+   r6   rþ   r   r   r   Útest_new_tag_creation9  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)   rK   r   r£   rq   rü   )r   Údocr+   Zsecond_paraZboldr   r   r   Ú!test_append_to_contents_moves_tagE  s    

z6TestTreeModification.test_append_to_contents_moves_tagc             C   s0   d}|   |¡}|j}| |j¡}|  ||¡ d S )Nz<a></a><b><c></c></b>)r+   r6   Úreplace_withr^   r   )r   r0   r+   r6   Únew_ar   r   r   Ú1test_replace_with_returns_thing_that_was_replacedW  s
    
zFTestTreeModification.test_replace_with_returns_thing_that_was_replacedc             C   s,   d}|   |¡}|j}| ¡ }|  ||¡ d S )Nz<a><b></b><c></c></a>)r+   r6   Úunwrapr   )r   r0   r+   r6   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+   r6   Úextractr   r£   r™   rš   r  r  r^   )r   r+   r6   r   r   r   ÚItest_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parente  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+   r^   r  r   rq   rü   )r   r0   r+   r^   r   r   r   Útest_replace_tag_with_itselfm  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  r6   )r   r0   r+   r   r   r   Ú1test_replace_tag_with_its_parent_raises_exceptiont  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š   r6   r  )r   r0   r+   r   r   r   Ú,test_insert_tag_into_itself_raises_exceptiony  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>rD   zAnd now, a word:Úp2Úp3zAnd we're back.N)
r+   r  Zdescendantsrð   r   ÚAssertionErrorÚlistÚchildrenr   r   )	r   r+   r0   Z	to_insertr›   Úp1r  r  Zp4r   r   r   Ú1test_insert_beautifulsoup_object_inserts_children~  s    

zFTestTreeModification.test_insert_beautifulsoup_object_inserts_childrenc             C   sX   |   d¡}|j}|jd }| dd¡ |j\}}| d¡ | d¡ |  d|jj¡ d S )Nz<p><a>one</a><b>three</b></p>r   rD   ZtworÑ   Zthree)r+   r6   r“   r  ÚreplaceWithr   r)   r   )r   r+   r6   r)   ÚleftÚrightr   r   r   Ú3test_replace_with_maintains_next_element_throughout’  s    




zHTestTreeModification.test_replace_with_maintains_next_element_throughoutc             C   sl   |   d¡}|jdd d¡ |jdd}|j}|  |j|¡ |  |j|¡ |  |jj|¡ |  |jd ¡ d S )Nz<b>Argh!</b>zArgh!)r0   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˜   |   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>rD   zHooray!z!<a><b>Argh!Hooray!</b><c></c></a>)r0   zArgh!)r+   r)   r  r   rq   rü   r,   rÃ   r²   râ   rÕ   r^   )r   r+   r  r   r   r   Útest_consecutive_text_nodes«  s    

z0TestTreeModification.test_consecutive_text_nodesc             C   sT   |   d¡}|j dd¡ |j dd¡ |  ddg|jj¡ |  |jjd jd¡ d S )Nz<a></a>r   r:   rI   )r+   r6   r  r   r“   r²   )r   r+   r   r   r   Útest_insert_stringÀ  s
    
z'TestTreeModification.test_insert_stringc             C   sø   |   ¡ }| jd|d}t||dƒ}| dd¡ |j d|¡ |  | ¡ |  d¡¡ |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   ÚtherD   z=<a><b>Find</b><magictag>the</magictag><c>lady!</c><d></d></a>ZFind)r0   )r’   r+   r   r  r6   r   rq   rü   r)   rÕ   râ   r,   r²   rÃ   r^   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+   r6   rK   r)   r   rq   )r   rr   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+   Úgry   Úer   r^   r)   r6   Úextendr   rq   )r   rr   r+   rL   r   r   r   Útest_extendí  s
    
z TestTreeModification.test_extendc             C   sX   d}|   |¡}|jddd}|jddd}| |¡ |  d| ¡ ¡ |  d| ¡ ¡ d S )NzS<body><div id="d1"><a>1</a><a>2</a><a>3</a><a>4</a></div><div id="d2"></div></body>rh   Úd1)r#   Úd2z<div id="d1"></div>z3<div id="d2"><a>1</a><a>2</a><a>3</a><a>4</a></div>)r+   r,   r#  r   rq   )r   rr   r+   r%  r&  r   r   r   Ú&test_extend_with_another_tags_contentsô  s    

z;TestTreeModification.test_extend_with_another_tags_contentsc             C   s2   d}|   |¡}|j d|j¡ |  d| ¡ ¡ d S )Nz<a><b></b><c></c><d></d></a>r   z<a><d></d><b></b><c></c></a>)r+   r6   r  r   r   rq   )r   rr   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/>rD   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>r6   )r+   r)   Úinsert_beforer6   r   rq   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-  r6   r   rq   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>r6   )r+   r)   Úinsert_afterr6   r   rq   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)   r2  r6   r   rq   rü   )r   r+   r   r   r   Útest_insert_multiple_afterD  s    
z/TestTreeModification.test_insert_multiple_afterc             C   sR   |   d¡}| d¡}| d¡}|  t|j|¡ |  t|j|¡ |  t|j|¡ d S )NrÑ   r6   )r+   rì   r÷   r™   rš   r2  ÚNotImplementedError)r   r+   r   r   r   r   r   Ú:test_insert_after_raises_exception_if_after_has_no_meaningN  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Ñ   r6   )r+   rì   r÷   r™   rš   r-  r5  )r   r+   r   r   r   r   r   ÚFtest_insert_before_raises_notimplementederror_if_before_has_no_meaningV  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+   r4   r  r   rq   rü   r£   rô   r²   rÕ   )r   r+   r8  Ú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  r^   r   rq   )r   rr   r+   r   r   r   Útest_replace_first_childm  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+   r^   r  r)   r   rq   )r   rr   r+   r   r   r   Útest_replace_last_childs  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  )r0   ZWeÚto)r+   r)   ry   r  r   rq   rü   r£   r,   r²   rÃ   rÕ   râ   r6   r"  r!  )r   r+   Z
remove_tagZmove_tagZto_textZg_tagr   r   r   Útest_nested_tag_replace_withy  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ô   r0   )r   rZ   r   r   r   Útest_unwrap  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   rq   rü   )r   r+   r|   r   r   r   Ú	test_wrap¥  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Õ   rA  r   rq   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.r2   z+<b>I like being bold.I wish I was bold.</b>)	r+   r)   rÕ   rA  r   r3   r“   rq   rü   )r   r+   r   r   r   Ú&test_wrap_puts_new_contents_at_the_end²  s    

z;TestTreeModification.test_wrap_puts_new_contents_at_the_endc             C   sâ   |   d¡}|  t|jjƒd¡ |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>r@   Únav)r#   z6<html><body>Some content.  More content.</body></html>z<div id="nav">Nav crap</div>r2   zSome content. )r0   z More content.)r+   r   r3   rÍ   r“   r,   r
  rq   r£   rÃ   r²   rÕ   râ   )r   r+   Z	extractedZ	content_1Z	content_2r   r   r   Útest_extractº  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>rI   r:   )r+   r6   r   r)   r÷   rK   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>rH  z<body>

<a></a>
</body>)r+   r4   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)Ú	decomposeN)
r+   r6   rô   Úclearr   r3   r“   rO   rP   r?  )r   r+   r6   r?  r   r   r   Ú
test_clearý  s    

zTestTreeModification.test_clearc             C   s†   |   d¡}| d¡\}}|j}|jj}x"||||gD ]}|  d|j¡ q4W | ¡  x |||gD ]}|  d|j¡ q^W |  d|j¡ d S )Nz;<p><a>String <em>Italicized</em></a></p><p>Another para</p>rô   FT)r+   r4   r6   r?  r   r   Z
decomposedrK  )r   r+   r  r  r6   r0   r›   r   r   r   Útest_decompose  s    
z#TestTreeModification.test_decomposec             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>rI   r:   N)r+   r6   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+   r^   r   r)   r   r6   rp   )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>rI   )r+   r   r6   r   rO   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.  r1  r3  r4  r6  r7  r:  r;  r<  r>  r@  rB  rC  rD  rF  rG  rI  rJ  rM  rN  rO  rP  rR  r   r   r   r   rû   .  sV   	
			
$	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>rD   r@   N)r+   r   r3   r“   r¢   )r   r+   r   r   r   Útest_len2  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›   r6   )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_accessG  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+   rO   rI   Úhas_attrÚassertFalse)r   r+   r   r   r   Útest_has_attrP  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>rI   )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_stringf  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>rD   r:   )r+   r   r)   r   r6   r  )r   r+   r   r   r   Ú-test_tag_with_multiple_children_has_no_stringk  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>rI   )r+   r   r6   r   )r   r+   r   r   r   Ú)test_tag_with_recursive_string_has_stringy  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   r6   r0   Úget_text)r   r+   r   r   r   Útest_all_textˆ  s
    
z TestElementObjects.test_all_textc             C   sd   |   d¡}|  | ¡ d¡ |  |jttfdd¡ |  |jd dd¡ |   d¡}|  | ¡ d¡ d S )Nzfoo<!--IGNORE-->barZfoobar)ÚtypesZfooIGNOREbarz3foo<style>CSS</style><script>Javascript</script>bar)r+   r   rh  r   r   )r   r+   r   r   r   Ú/test_get_text_ignores_special_string_containers  s    

zBTestElementObjects.test_get_text_ignores_special_string_containersc             C   sD   |   d¡}|  ddgt|jƒ¡ |   d¡}|  ddgt|jƒ¡ d S )Nzfoo<!--IGNORE-->barrI   r:   z3foo<style>CSS</style><script>Javascript</script>bar)r+   r   r  Ústrings)r   r+   r   r   r   Ú2test_all_strings_ignores_special_string_containersœ  s    

zETestElementObjects.test_all_strings_ignores_special_string_containersN)r%   r&   r'   r8   rT  rU  r[  r_  r`  ra  rb  rc  rd  re  ri  rk  rm  r   r   r   r   rS  /  s   	rS  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'>rI   rt   )r+   r   r6   )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'>rI   r:   rt   )r+   r   r6   )r   r+   r   r   r   Ú!test_multiple_values_becomes_list¬  s    
z9TestCDAtaListAttributes.test_multiple_values_becomes_listc             C   s&   |   d¡}|  dddg|jd ¡ d S )Nz<a class='foo	bar
baz'>rI   r:   rÞ   rt   )r+   r   r6   )r   r+   r   r   r   Ú2test_multiple_values_separated_by_weird_whitespace°  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   r6   rp   )r   r+   r   r   r   Ú,test_attributes_joined_into_string_on_output´  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   r6   Zget_attribute_list)r   r+   r   r   r   Útest_get_attribute_list¸  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   Úform)r   r+   r   r   r   Útest_accept_charset¼  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   r6   )r   rr   r+   r   r   r   Ú-test_cdata_attribute_applying_only_to_one_tagÀ  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 )NrI   )rU   r   )r   r   r   ÚtË  s    zJTestCDAtaListAttributes.test_string_has_immutable_name_property.<locals>.t)r+   r   r   rU   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'   r8   ro  rp  rq  rr  rs  ru  rv  ry  r   r   r   r   rn  ¤  s   rn  c                   sh   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‡  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>)rX   rz  rY   Úpager+   rZ   )r   )r[   r   r   rY   Ò  s    zTestPersistence.setUpc             C   s@   t  | jd¡}t  |¡}|  |jt¡ |  | ¡ | j ¡ ¡ d S )Nr2   )ÚpickleÚdumpsrZ   Úloadsr   r[   r   rq   )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ÚdeepcopyrZ   r   rq   )r   Ú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+   Úencodingr‚  r   r   r   Útest_copy_preserves_encodingó  s
    
z,TestPersistence.test_copy_preserves_encodingc             C   st   |   d¡j}d|_d|_| ¡ }|  |j|j¡ |  |j|j¡ |  |j|j¡ |  |j|j¡ |  |j|j¡ d S )Nz<p></p>rE   é!   )	r+   rô   Z
sourcelineZ	sourceposr†  r   Zcan_be_empty_elementZcdata_list_attributesrí   )r   r   r„  r   r   r   Ú'test_copy_preserves_builder_informationú  s    z7TestPersistence.test_copy_preserves_builder_informationc             C   s>   d}|   |¡}t |tj¡}t |¡}|  | ¡ | ¡ ¡ d S )Nu
   <b>â˜ƒ</b>)r+   r|  r}  ÚHIGHEST_PROTOCOLr~  r   rq   )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>r;   )r   )	r+   r,   r‚  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   r‚  r   rO   rð   r   )r   rÅ   r+   rŽ  r  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+   r‚  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>endÚBar)r   )r+   rh   r‚  r   r/   r^  r£   rÃ   r,   r²   r  )r   rÅ   r+   rh   Zdiv_copyr   r   r   Útest_copy_tag_copies_contents5  s    

z-TestPersistence.test_copy_tag_copies_contents)r%   r&   r'   r8   rY   r  r…  rˆ  rŠ  rŒ  r  r‘  r’  r”  rj   r   r   )r[   r   rz  Ï  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+   rq   r   rü   )r   rÓ   r+   Údecodedr   r   r   Ú!test_default_formatter_is_minimalK  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Å   )r—  z.<br/><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>)r+   rq   r   rü   )r   rÓ   r+   r˜  r   r   r   Útest_formatter_htmlU  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>Úhtml5)r—  z-<br><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>)r+   rq   r   rü   )r   rÓ   r+   r˜  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>r–  )r—  )r+   rq   r   rü   )r   rÓ   r+   r˜  r   r   r   Útest_formatter_minimale  s    
z(TestSubstitutions.test_formatter_minimalc             C   s0   d}|   |¡}|jd d}|  ||  d¡¡ d S )Nu#   <b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>)r—  u   <b><<SacrÃ© bleu!>></b>)r+   rq   r   rü   )r   rÓ   r+   r˜  r   r   r   Útest_formatter_nullo  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>{  ó    z9TestSubstitutions.test_formatter_custom.<locals>.<lambda>)r—  z<b><FOO></b><b>BAR</b><br/>)r+   rq   r   rü   )r   rÓ   r+   r˜  r   r   r   Útest_formatter_customx  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>r–  )r—  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)rŸ  )r   r   r   r   r¡  ‘  r¢  zMTestSubstitutions.test_formatter_is_run_on_attribute_values.<locals>.<lambda>)r+   r6   r   rq   )r   rÓ   r+   r6   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   rp   rO   )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   rp   rO   )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 )NzN<div>  foo  <pre>  	bar
  
  </pre>  baz  <textarea> eee
fff	</textarea></div>zO<div>
 foo
 <pre>  	bar
  
  </pre>
 baz
 <textarea> eee
fff	</textarea>
</div>)r+   r   rh   Ú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)rŸ  )r   r   r   r   r¡  ¯  r¢  zLTestSubstitutions.test_prettify_accepts_formatter_function.<locals>.<lambda>)r—  r0  )r   r¨  rO   )r   r+   Ú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_default²  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_data¶  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)   rp   r   )r   rÓ   r+   r¥  r   r   r   Ú,test_html_entity_substitution_off_by_defaultº  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"/>Ú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   Úmetarp   rO   rq   )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>Úpre)Z
parse_onlyr   )r   r+   r   r“   rU   )r   rÓ   r   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'   r™  rš  rœ  r  rž  r£  r¤  r¦  r§  r©  r«  r­  r¯  r°  r¶  r¸  r   r   r   r   r•  I  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 )Ú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   rp   )r   rÅ   r+   r   r   r   Ú"test_unicode_string_can_be_encodedæ  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)   rp   )r   rÅ   r+   r   r   r   Ú1test_tag_containing_unicode_string_can_be_encodedì  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)   rp   )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t|jddd d S )Nu
   <b>â˜ƒ</b>r¼  Ústrict)Úerrors)r+   r™   ÚUnicodeEncodeErrorrp   )r   rÅ   r+   r   r   r   Ú test_encoding_can_be_made_strict÷  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   â˜ƒrn   )r‡  )r+   r   rp   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   â˜ƒrn   )r+   r   rp   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'   r8   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S )ÚTestFormatterc             C   sR   t ƒ }tdd}d|d< d|d< |  ddg| |¡¡ d |_|  g | |¡¡ d S )	Nr   )rU   rD   r)   r2   r6   )r6   r2   )r)   rD   )r   r   r   Ú
attributesrT   )r   r—  r   r   r   r   Útest_default_attributes  s    
z%TestFormatter.test_default_attributesc             C   sL   G dd„ dt ƒ}|  d¡}|ƒ }|j|d}|  |j|j¡ |  d|¡ d S )Nc               @   s   e Zd Zdd„ ZdS )z=TestFormatter.test_sort_attributes.<locals>.UnsortedFormatterc             s   s:   || _ x.t|j ¡ ƒD ]\}}|dkr(q||fV  qW d S )NÚignore)Úcalled_withÚsortedrT   Úitems)r   r   ÚkÚvr   r   r   rÈ  .  s
    zHTestFormatter.test_sort_attributes.<locals>.UnsortedFormatter.attributesN)r%   r&   r'   rÈ  r   r   r   r   ÚUnsortedFormatter-  s   rÐ  z*<p cval="1" aval="2" ignore="ignored"></p>)r—  z<p aval="2" cval="1"></p>)r   r+   rq   r   rË  rô   )r   rÐ  r+   r—  r˜  r   r   r   Útest_sort_attributes*  s    
z"TestFormatter.test_sort_attributesN)r%   r&   r'   rÉ  rÑ  r   r   r   r   rÇ    s   rÇ  c               @   s4   e Zd Zd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Ñ   rI   rD   z<![CDATA[foo]]>)r0   r   )r+   r   r  r   r/   r,   r“   )r   r+   rQ  r   r   r   Ú
test_cdataA  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 )NrD   zBITTER FAILURE)Úcount)Úargs)r   r   r   Ú	incrementR  s    zNTestNavigableStringSubclasses.test_cdata_is_never_formatted.<locals>.incrementrÑ   z<><><>rD   s   <![CDATA[<><><>]]>)r—  N)rÔ  r+   r   r  r   rp   )r   rÖ  r+   rQ  r   )r   r   Útest_cdata_is_never_formattedK  s    
z;TestNavigableStringSubclasses.test_cdata_is_never_formattedc             C   s2   t dƒ}|  d¡}| d|¡ |  | ¡ d¡ d S )NrI   rÑ   rD   s   <!DOCTYPE foo>
)r
   r+   r  r   rp   )r   Údoctyper+   r   r   r   Útest_doctype_ends_in_newline]  s    
z:TestNavigableStringSubclasses.test_doctype_ends_in_newlinec             C   s   t dƒ}|  d| ¡ ¡ d S )NrI   z<?foo?>)r	   r   Zoutput_ready)r   r   r   r   r   Útest_declaratione  s    z.TestNavigableStringSubclasses.test_declarationc             C   sz   |   d¡}|  tttgdd„ |jddD ƒ¡ |   d¡}tdd„ |jjD ƒƒsRt	‚|jj
}t|tƒsht	‚t|tƒrvt	‚d S )	Nz7<div>text</div><script>text</script><style>text</style>c             S   s   g | ]
}|j ‘qS r   )r[   )r   r   r   r   r   r   q  s    zPTestNavigableStringSubclasses.test_default_string_containers.<locals>.<listcomp>T)r0   z><template>Some text<p>In a tag</p></template>Some text outsidec             s   s   | ]}t |tƒV  qd S )N)rð   r   )r   r   r   r   r   ú	<genexpr>z  s    zOTestNavigableStringSubclasses.test_default_string_containers.<locals>.<genexpr>)r+   r   r   r   r   r4   ÚallÚtemplaterl  r  rÕ   rð   r   )r   r+   Zoutsider   r   r   Útest_default_string_containersi  s    z<TestNavigableStringSubclasses.test_default_string_containersN)r%   r&   r'   rÓ  r×  rÙ  rÚ  rÞ  r   r   r   r   rÒ  ?  s
   
rÒ  c               @   sÜ  e Zd ZdZdd„ Zd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   rY   µ  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   Ú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 )Nro   rD   r   z	The title)r+   râ  r   r3   rU   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 )Nrh   é   Úmainr#   )r+   râ  r   r3   rU   Ú
select_one)r   rë  rh   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î  rD   )rA   zhtml body divró  r2   zbody divrô  rö  rE   )r"   )r   r   r   r   Ú
test_limitå  s    zTestSoupSelector.test_limitc             C   s   |   t| j d¡ƒd¡ d S )NÚdelr   )r   r3   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™   r   r+   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   rU   )r   Zdashedr   r   r   Útest_select_dashed_by_idô  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â  r0   )r   r   r   r   Útest_dashed_tag_textù  s    z%TestSoupSelector.test_dashed_tag_textc             C   s    |   | j d¡| j d¡¡ d S )Nzcustom-dashed-tag)r   r+   râ  r4   )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 )NÚh1Úheader1Ú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.oneprD   r   rô   rt   Úonep)r+   râ  r   r3   rU   )r   rå  rë  r   r   r   Útest_class_one  s
    
zTestSoupSelector.test_class_onec             C   s    | j  d¡}|  t|ƒd¡ d S )Nzdiv.onepr   )r+   râ  r   r3   )r   rë  r   r   r   Útest_class_mismatched_tag  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_id  s    
zTestSoupSelector.test_one_idc             C   s    | j  d¡}|  t|ƒd¡ d S )Nz#doesnotexistr   )r+   râ  r   r3   )r   rë  r   r   r   Útest_bad_id  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 pr@   rô   rD   rt   r  r   )r+   râ  r   r3   rU   r^  r]  )r   rë  rá  r   r   r   Útest_items_in_id  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   r3   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_support$  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_selection)  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_selector.  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_id2  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_equals5  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_tildeG  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_startswithU  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_endswithf  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_containsp  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"]Ú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™   r5  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)rD   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   r3   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)rD   r   z	Some text)r+   râ  r   r3   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 )Nrh   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/  r0  )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/  r0  )r"   )r   r   r   r   Ú$test_multiple_select_with_more_spaceò  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_duplicatedõ  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_siblingø  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_descendantû  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/  r0  Úzidar6  Ú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/  r0  r8  r6  r9  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_select	  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_attrs	  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/  r6  r9  )r"   )r   r   r   r   Útest_multiple_select_ids	  s    z)TestSoupSelector.test_multiple_select_idsc             C   s   |   dddg¡ d S )Nzbody > div > x, y > zr/  r6  )r"   )r   r   r   r   Útest_multiple_select_nested	  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, .c2r@   Zc1Úc2)rv   )r   râ  r   r3   r4   r  )r   rÓ   r+   r(  rœ   r   r   r   Útest_select_duplicate_elements	  s    

z/TestSoupSelector.test_select_duplicate_elementsN)>r%   r&   r'   rà  rY   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.  r1  r2  r3  r4  r5  r7  r;  r<  r=  r>  r?  r@  rB  r   r   r   r   rß  ‚  sv   1
	
	rß  );r8   Úpdbr   r‚  r|  r=   rW  Zbs4r   Zbs4.builderr   r   Zbs4.elementr   r   r   r	   r
   r   r   r   r   r   r   r   Zbs4.testingr   r   Z	soupsiever   r   rõ   ZLXML_PRESENTr   r(   r9   rS   rW   rk   rŒ   r–   rž   r¯   r°   rÁ   rÐ   rÔ   rá   rë   rï   rû   rS  rn  rz  r•  r¹  rÇ  rÒ  rß  r   r   r   r   Ú<module>
   sX   8;O 6,3(3--*    u+z 4(C