o
    üeóP ã                   @   sH  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 ddlmZmZ e
 d¡duZe
 d	¡duZG d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZ G dd„ deƒZ!G dd„ deƒZ"G dd„ deƒZ#G dd„ deƒZ$G dd„ deƒZ%G dd„ de%ƒZ&G d d!„ d!e%ƒZ'G d"d#„ d#eƒZ(G d$d%„ d%e(ƒZ)G d&d'„ d'e(ƒZ*G d(d)„ d)eƒZ+G d*d+„ d+eƒZ,G d,d-„ d-eƒZ-G d.d/„ d/eƒZ.G d0d1„ d1eƒZ/G d2d3„ d3eƒZ0G d4d5„ d5eƒZ1G d6d7„ d7eƒZ2G d8d9„ d9eƒZ3G d:d;„ d;eƒZ4G d<d=„ d=eƒZ5d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ÚSoupStrainerÚTag)ÚSoupTestÚskipIfÚxmlZlxmlc                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚTreeTestc                 C   ó   |   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   úCD:\Projects\ConvertPro\env\Lib\site-packages\bs4/tests/test_tree.pyÚ
<listcomp>2   s    z*TreeTest.assertSelects.<locals>.<listcomp>N©ÚassertEqual©ÚselfÚtagsZshould_matchr   r   r   ÚassertSelects+   ó   zTreeTest.assertSelectsc                 C   r   )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   ó   g | ]}|d  ‘qS ©Úidr   r   r   r   r   r   ;   ó    z-TreeTest.assertSelectsIDs.<locals>.<listcomp>Nr   r   r   r   r   ÚassertSelectsIDs4   r"   zTreeTest.assertSelectsIDsN)Ú__name__Ú
__module__Ú__qualname__r!   r'   r   r   r   r   r   )   s    	r   c                   @   ó8   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_tagE   ó   
zTestFind.test_find_tagc                 C   s"   |   d¡}|  |jddd¡ d S )Nu   <h1>RÃ¤ksmÃ¶rgÃ¥s</h1>õ   RÃ¤ksmÃ¶rgÃ¥sr   )r/   r   r0   r1   r   r   r   Útest_unicode_text_findI   r3   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 isr4   r$   )r/   Ústrr   r0   Útextr1   r   r   r   Útest_unicode_attribute_findM   s   
z$TestFind.test_unicode_attribute_findc                 C   s"   |   d¡}|  dt| ¡ ƒ¡ dS )z)Test an optimization that finds all tags.ú<a>foo</a><b>bar</b>é   N©r/   r   ÚlenÚfind_allr1   r   r   r   Útest_find_everythingS   s   
zTestFind.test_find_everythingc                 C   s$   |   d¡}|  dt| d¡ƒ¡ dS )z;Test an optimization that finds all tags with a given name.z<a>foo</a><b>bar</b><a>baz</a>r:   ÚaNr;   r1   r   r   r   Útest_find_everything_with_nameX   s   
z'TestFind.test_find_everything_with_nameN)	r(   r)   r*   Ú__doc__r2   r5   r8   r>   r@   r   r   r   r   r,   >   s    r,   c                   @   r+   )Ú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g d¢¡ |  |jddg d¢¡ d	S )
z'You can search the tree for text nodes.u   <html>Foo<b>bar</b>Â»</html>Úbarr   ©r7   ÚFooz.*)rE   rC   õ   Â»TN)r/   r   r=   ÚreÚcompiler1   r   r   r   Útest_find_all_text_nodes`   s   
ÿÿÿz$TestFindAll.test_find_all_text_nodesc                 C   st   |   d¡}|  |jdddg d¢¡ |  |jddddg¡ |  |jdddg d	¢¡ |  |jdd
dg d	¢¡ dS )z7You can limit the number of items returned by find_all.z(<a>1</a><a>2</a><a>3</a><a>4</a><a>5</a>r?   é   ©Úlimit)Ú1r.   Ú3é   rM   é
   )rM   r.   rN   Ú4Ú5r   N©r/   r!   r=   r1   r   r   r   Útest_find_all_limitp   s   
ÿÿzTestFindAll.test_find_all_limitc                 C   s:   |   d¡}|  |ddddg¡ |  |jdddg¡ d S )	Nz!<a>1</a><b>2<a id='foo'>3</a></b>r?   rO   rK   rM   Úfoor$   rN   )r/   r!   r-   r1   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 ©Nú<a></a>)r/   Úappendr   r=   )r   r/   Úlr   r   r   ÚTtest_find_all_with_self_referential_data_structure_does_not_cause_infinite_recursion   s   

z`TestFindAll.test_find_all_with_self_referential_data_structure_does_not_cause_infinite_recursionc                 C   s^   |   d¡}| d¡}|  t|dƒ¡ | d¡}|  t|dƒ¡ |jdd}|  t|dƒ¡ dS )z%All find_all calls return a ResultSetrX   r?   ÚsourceTrU   rD   N)r/   r=   Ú
assertTrueÚhasattr)r   r/   Úresultr   r   r   Útest_find_all_resultset‹   s   


z#TestFindAll.test_find_all_resultsetN)	r(   r)   r*   rA   rI   rT   rV   r[   r`   r   r   r   r   rB   ]   s    
rB   c                   @   ó   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">rQ   zmathml:msqrtr?   zsvg:fillÚred©Úattrs)r/   r   r0   r   Únamer1   r   r   r   Útest_find_by_namespaced_nameš   s   
z7TestFindAllBasicNamespaces.test_find_by_namespaced_nameN)r(   r)   r*   rg   r   r   r   r   rb   ˜   ó    rb   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                    ó   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   rm   £   ó   zTestFindAllByName.setUpc                 C   s   |   | j d¡ddg¡ d S ©Nr?   ú
First tag.úNested tag.©r!   rn   r=   ro   r   r   r   Útest_find_all_by_tag_name©   s   ÿz+TestFindAllByName.test_find_all_by_tag_namec                 C   s\   |   | jjddddg¡ |   | jjdddddg¡ |   | jjdt d¡dddg¡ d S )Nr?   rt   rD   Tru   r   ©r!   rn   r=   rG   rH   ro   r   r   r   Útest_find_all_by_name_and_text®   s   ÿÿþz0TestFindAllByName.test_find_all_by_name_and_textc                 C   s   |   | jj d¡dg¡ d S )Nr?   ru   )r!   rn   Úcr=   ro   r   r   r   Ú!test_find_all_on_non_root_elementº   s   z3TestFindAllByName.test_find_all_on_non_root_elementc                 C   s   |   |  d¡ddg¡ d S rs   )r!   rn   ro   r   r   r   Ú%test_calling_element_invokes_find_all¾   s   z7TestFindAllByName.test_calling_element_invokes_find_allc                 C   s    |   | j tdƒ¡ddg¡ d S rs   )r!   rn   r=   r   ro   r   r   r   Útest_find_all_by_tag_strainerÁ   ó   þz/TestFindAllByName.test_find_all_by_tag_strainerc                 C   s    |   | j ddg¡g d¢¡ d S )Nr?   r-   ©rt   zSecond tag.ru   rv   ro   r   r   r   Útest_find_all_by_tag_namesÆ   r~   z,TestFindAllByName.test_find_all_by_tag_namesc                 C   s"   |   | j dddœ¡g d¢¡ d S )NT)r?   r-   r   rv   ro   r   r   r   Útest_find_all_by_tag_dictË   ó   þz+TestFindAllByName.test_find_all_by_tag_dictc                 C   s"   |   | j t d¡¡g d¢¡ d S )Nz^[ab]$r   rx   ro   r   r   r   Útest_find_all_by_tag_reÐ   r‚   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%   )rf   Ú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.rS   )r   r†   rn   r   r   r   Ú'test_find_all_with_tags_matching_methodÕ   s
   
ÿz9TestFindAllByName.test_find_all_with_tags_matching_methodc                 C   sx   |   d¡}| dd¡}| dt d¡¡}| dddg¡\}}|  d|j¡ |  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 brN   rM   )r/   r0   rG   rH   r=   r   r   )r   r/   Úr1Úr2Zr3Zr4r   r   r   Ú%test_find_with_multi_valued_attributeâ   s   ÿz7TestFindAllByName.test_find_with_multi_valued_attribute)r(   r)   r*   rA   rm   rw   ry   r{   r|   r}   r€   r   rƒ   r‡   r‹   Ú__classcell__r   r   rp   r   ri       s    ri   c                   @   óŒ   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   ó&   |   d¡}|  |jddddg¡ d S )NzÅ
                         <a id="first">Matching a.</a>
                         <a id="second">
                          Non-matching <b id="first">Matching b.</b>a.
                         </a>Úfirstr$   zMatching a.zMatching b.rS   ©r   rn   r   r   r   Útest_find_all_by_attribute_nameñ   s   
ÿz6TestFindAllByAttribute.test_find_all_by_attribute_namec                 C   st   d  d¡}d  d¡}|  |¡}|  |jg|j|d¡ |  |jg|j| d¡d¡ |  |jg|j|dgd¡ d S )Nu   ××•×œ×©Úutf8u   <a title="××•×œ×©"></a>)Útitlezsomething else)Úencoder/   r   r?   r=   Údecode)r   ZpeaceÚdatar/   r   r   r   Ú%test_find_all_by_utf8_attribute_valueü   s   


 z<TestFindAllByAttribute.test_find_all_by_utf8_attribute_valuec                 C   sX   |   d¡}|  |jdddg¡ |  |jddiddg¡ |  |jdd	idd
g¡ d S )Na0  
                         <a name="name1" class="class1">Name match.</a>
                         <a name="name2" class="class2">Class match.</a>
                         <a name="name3" class="class3">Non-match.</a>
                         <name1>A tag called 'name1'.</name1>
                         Zname1©rf   zA tag called 'name1'.rf   rd   zName match.ÚclassZclass2zClass match.rS   r‘   r   r   r   Útest_find_all_by_attribute_dict  s   
ÿÿÿz6TestFindAllByAttribute.test_find_all_by_attribute_dictc                 C   s°   |   d¡}|  |jddddg¡ |  |jddddg¡ |  |jdd	ddg¡ |  | dd¡dg¡ |  |jdd
ddg¡ |  | dd¡dg¡ |  | dd	¡dg¡ d S )Nzî
                         <a class="1">Class 1.</a>
                         <a class="2">Class 2.</a>
                         <b class="1">Class 1.</b>
                         <c class="3 4">Class 3 and 4.</c>
                         r?   rM   ©Úclass_zClass 1.rz   rN   zClass 3 and 4.rQ   rd   rS   r‘   r   r   r   Útest_find_all_by_class  s   
	z-TestFindAllByAttribute.test_find_all_by_classc                 C   st   |   d¡}|jdt d¡d}|  |dg¡ |jdt d¡d}|  |dg¡ |jdt d¡d}|  |dg¡ d S )Nz#<gar class='foo bar'>Found it</gar>ZgarÚorœ   úFound itr?   zo b)r/   r=   rG   rH   r!   )r   rn   Úfr   r   r   Ú0test_find_by_class_when_multiple_classes_present-  s   
zGTestFindAllByAttribute.test_find_by_class_when_multiple_classes_presentc                 C   sd   |   d¡}|  | dt d¡¡dg¡ dd„ }|  | d|¡g ¡ dd„ }|  | d|¡dg¡ d S )	Nz<a class='bar'>Found it</a>r?   Úbar    c                 S   s   t | ƒdkS ©NrJ   ©r<   ©Úvaluer   r   r   Úbig_attribute_value@  ó   znTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.big_attribute_valuec                 S   s   t | ƒdkS r¤   r¥   r¦   r   r   r   Úsmall_attribute_valueE  r©   zpTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.small_attribute_value©r/   r!   r=   rG   rH   )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>r?   rU   rC   zfoo barrœ   zbar foo)r/   r=   r   )r   r/   r?   Za2r   r   r   Ú:test_find_all_with_string_for_attrs_finds_multiple_classesK  s   
zQTestFindAllByAttribute.test_find_all_with_string_for_attrs_finds_multiple_classesc                 C   s0   |   d¡}tddid}|  | |¡dg¡ d S )Nzi
                         <a id="first">Match.</a>
                         <a id="second">Non-match.</a>r%   r   rd   zMatch.)r/   r   r!   r=   )r   rn   Ústrainerr   r   r   Ú'test_find_all_by_attribute_soupstrainerW  s   
z>TestFindAllByAttribute.test_find_all_by_attribute_soupstrainerc                 C   s&   |   d¡}|  |jdd ddg¡ d S )Nú<a id="1">ID present.</a>
                            <a>No ID present.</a>
                            <a id="">ID is empty.</a>r?   r$   zNo ID present.rS   r‘   r   r   r   Ú$test_find_all_with_missing_attribute_  s   
z;TestFindAllByAttribute.test_find_all_with_missing_attributec                 C   r   )Nr°   Tr$   zID present.zID is empty.rS   r‘   r   r   r   Ú$test_find_all_with_defined_attributeg  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.rO   r$   rM   rS   )r   rn   Úexpectedr   r   r   Ú$test_find_all_with_numeric_attributep  s   
z;TestFindAllByAttribute.test_find_all_with_numeric_attributec                 C   s*   |   d¡}|  |jg d¢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>)rM   rN   rQ   r$   rM   rN   rS   r‘   r   r   r   Ú(test_find_all_with_list_attribute_valuesy  s   
ÿz?TestFindAllByAttribute.test_find_all_with_list_attribute_valuesc                 C   s,   |   d¡}|  |jt d¡dddg¡ d S )NzÞ<a id="a">One a.</a>
                            <a id="aa">Two as.</a>
                            <a id="ab">Mixed as and bs.</a>
                            <a id="b">One b.</a>
                            <a>No ID.</a>z^a+$r$   zOne a.zTwo as.r«   r‘   r   r   r   Ú5test_find_all_with_regular_expression_attribute_valueƒ  s   
ÿzLTestFindAllByAttribute.test_find_all_with_regular_expression_attribute_valuec                 C   sX   |   d¡}|j}|  |g|jddd¡ |  g |jddd¡ |  g |jddd¡ d S )Nz<b>foo</b><b>bar</b><a>foo</a>r?   rU   rD   rC   ©r/   r?   r   r=   ©r   r/   r?   r   r   r   Ú'test_find_by_name_and_containing_string  s
   
z>TestFindAllByAttribute.test_find_by_name_and_containing_stringc                 C   s*   |   d¡}|  | d¡|jddd¡ d S )Nz"<a>foo</a><a><b><c>foo</c></b></a>r?   rU   rD   )r/   r   r=   r1   r   r   r   Ú=test_find_by_name_and_containing_string_when_string_is_buried˜  s   
 zTTestFindAllByAttribute.test_find_by_name_and_containing_string_when_string_is_buriedc                 C   sB   |   d¡}|j}|  |g|jddd¡ |  g |jddd¡ d S )Nz"<b id="1">foo</b><a id="2">foo</a>r:   rU   )r%   r7   rO   rC   r·   r¸   r   r   r   Ú,test_find_by_attribute_and_containing_stringœ  s   
zCTestFindAllByAttribute.test_find_by_attribute_and_containing_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Ž   ï   s"    		
rŽ   c                   @   ó   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-   rz   z	Comment 1z	Comment 2ÚdÚspanrM   r.   é   é   Úabcr   Z12rO   r:   )r/   rˆ   rY   r   Údefault_builderr   r   r¿   r   r<   ÚcontentsZsmooth)r   r/   rˆ   Úbuilderr¿   r   r   r   Útest_smooth§  s(   






zTestSmooth.test_smoothN)r(   r)   r*   rA   rÆ   r   r   r   r   r½   ¤  s    r½   c                   @   r¼   )Ú	TestIndexzTest Tag.indexc                 C   sJ   |   d¡}|j}t|jƒD ]\}}|  || |¡¡ q|  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>rO   )r/   rˆ   Ú	enumeraterÄ   r   ÚindexÚassertRaisesÚ
ValueError)r   rn   rˆ   ÚiÚelementr   r   r   Ú
test_indexÒ  s
   
	zTestIndex.test_indexN)r(   r)   r*   rA   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>)rl   rÏ   rm   r/   rn   r-   Ústartro   rp   r   r   rm   å  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Ð   Úparentro   r   r   r   Útest_parentñ  s   z TestParentOperations.test_parentc                 C   s    | j jd }|  |j| j ¡ d S )Nr   )rn   rÄ   r   rÔ   )r   Ztop_tagr   r   r   Ú%test_parent_of_top_tag_is_soup_objectö  ó   z:TestParentOperations.test_parent_of_top_tag_is_soup_objectc                 C   s   |   d | jj¡ d S ©N)r   rn   rÔ   ro   r   r   r   Útest_soup_object_has_no_parentú  ó   z3TestParentOperations.test_soup_object_has_no_parentc                 C   s6   |   | j d¡g d¢¡ |   | jjddddg¡ d S )NÚul©rÑ   rÒ   rÓ   rÒ   r$   )r'   rÐ   Zfind_parentsro   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_parentro   r   r   r   Útest_find_parent  s    z%TestParentOperations.test_find_parentc                 C   s"   | j jdd}|  |jjd¡ d S )Nú
Start hererD   r-   )rn   r0   r   rÔ   rf   ©r   r7   r   r   r   Útest_parent_of_text_element  ó   z0TestParentOperations.test_parent_of_text_elementc                 C   s(   | j jdd}|  | d¡d d¡ d S )Nrà   rD   rÛ   r%   rÑ   )rn   r0   r   rÞ   rá   r   r   r   Útest_text_element_find_parent  s   z2TestParentOperations.test_text_element_find_parentc                 C   s&   dd„ | j jD ƒ}|  |g d¢¡ d S )Nc                 S   s&   g | ]}|d urd|j v r|d ‘qS r„   rd   )r   rÔ   r   r   r   r     s    ÿz>TestParentOperations.test_parent_generator.<locals>.<listcomp>rÜ   )rÐ   Úparentsr   )r   rå   r   r   r   Útest_parent_generator  s   z*TestParentOperations.test_parent_generator)r(   r)   r*   rA   rm   rÕ   rÖ   rÙ   rÝ   rß   râ   rä   ræ   rŒ   r   r   rp   r   rÏ   â  s    rÏ   c                       ó   e Zd Z‡ fdd„Z‡  ZS )ÚProximityTestc                    rj   )Nzg<html id="start"><head></head><body><b id="1">One</b><b id="2">Two</b><b id="3">Three</b></body></html>rk   ro   rp   r   r   rm     s   
ÿzProximityTest.setUp©r(   r)   r*   rm   rŒ   r   r   rp   r   rè     ó    rè   c                       óT   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 rØ   )rl   rì   rm   rn   r-   rÐ   ro   rp   r   r   rm     s   zTestNextOperations.setUpc                 C   s*   |   | jjd¡ |   | jjjd d¡ d S )NÚOner%   r.   )r   rÐ   Únext_elementro   r   r   r   Ú	test_next#  s   zTestNextOperations.test_nextc                 C   s    | j jdd}|  |jd ¡ d S ©NÚThreerD   )rn   r0   r   rî   )r   Úlastr   r   r   Útest_next_of_last_item_is_none'  s   z1TestNextOperations.test_next_of_last_item_is_nonec                 C   ó   |   | jjd ¡ d S rØ   )r   rn   rî   ro   r   r   r   Útest_next_of_root_is_none+  s   z,TestNextOperations.test_next_of_root_is_nonec                 C   sB   |   | j d¡ddg¡ | jjdd |   | jjdddg¡ d S )Nr-   ÚTworñ   rJ   r$   )r!   rÐ   Úfind_all_nextro   r   r   r   Útest_find_all_next/  s   z%TestNextOperations.test_find_all_nextc                 C   ó2   |   | j d¡d d¡ |   | jjddd¡ d S )Nr-   r%   r.   rñ   rD   )r   rÐ   Ú	find_nextro   r   r   r   Útest_find_next4  ó   z!TestNextOperations.test_find_nextc                 C   s<   | j jdd}|  | d¡jd¡ |  | d¡ddg¡ d S )Nrí   rD   r-   rö   rñ   )rn   r0   r   rú   r   r!   r÷   rá   r   r   r   Útest_find_next_for_text_element8  s   z2TestNextOperations.test_find_next_for_text_elementc                 C   sF   | j jdd}dd„ |jD ƒ}|\}}|  |d d¡ |  |d¡ d S )Nrö   rD   c                 S   ó   g | ]}|‘qS r   r   ©r   Únoder   r   r   r   ?  ó    z:TestNextOperations.test_next_generator.<locals>.<listcomp>r%   rN   rñ   )rn   r0   Znext_elementsr   )r   rÐ   Ú
successorsr   rÄ   r   r   r   Útest_next_generator=  s
   z&TestNextOperations.test_next_generator)r(   r)   r*   rm   rï   ró   rõ   rø   rû   rý   r  rŒ   r   r   rp   r   rì     s    rì   c                       rë   )ÚTestPreviousOperationsc                    ó"   t t| ƒ ¡  | jjdd| _d S rð   )rl   r  rm   rn   r0   Úendro   rp   r   r   rm   G  rã   zTestPreviousOperations.setUpc                 C   s*   |   | jjd d¡ |   | jjjd¡ d S )Nr%   rN   rö   )r   r  Úprevious_elementro   r   r   r   Útest_previousK  s   z$TestPreviousOperations.test_previousc                 C   s   | j  d¡}|  |jd ¡ d S )NÚhtml)rn   r0   r   r  )r   r   r   r   r   Ú#test_previous_of_first_item_is_noneO  s   z:TestPreviousOperations.test_previous_of_first_item_is_nonec                 C   s   d S rØ   r   ro   r   r   r   Útest_previous_of_root_is_noneS  s   z4TestPreviousOperations.test_previous_of_root_is_nonec                 C   s4   |   | j d¡g d¢¡ |   | jjdddg¡ d S )Nr-   ©rñ   rö   rí   rO   r$   rí   )r!   r  Úfind_all_previousro   r   r   r   Útest_find_all_previousY  s   ÿz-TestPreviousOperations.test_find_all_previousc                 C   rù   )Nr-   r%   rN   rí   rD   )r   r  Úfind_previousro   r   r   r   Útest_find_previousa  rü   z)TestPreviousOperations.test_find_previousc                 C   s<   | j jdd}|  | d¡jd¡ |  | d¡g d¢¡ d S )Nrñ   rD   r-   r  )rn   r0   r   r  r   r!   r  rá   r   r   r   Ú#test_find_previous_for_text_elemente  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í   rD   c                 S   rþ   r   r   rÿ   r   r   r   r   m  r  zBTestPreviousOperations.test_previous_generator.<locals>.<listcomp>r%   rM   ÚbodyÚheadr	  )rn   r0   Zprevious_elementsr   rf   )r   rÐ   Zpredecessorsr-   r  r  r	  r   r   r   Útest_previous_generatork  s   z.TestPreviousOperations.test_previous_generator)r(   r)   r*   rm   r  r
  r  r  r  r  r  rŒ   r   r   rp   r   r  E  s    r  c                       rç   )Ú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*Ú )rl   r  rm   rG   rH   Úsubr/   rn   ©r   Úmarkuprp   r   r   rm   z  s   zSiblingTest.setUpré   r   r   rp   r   r  x  rê   r  c                       óL   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                    r  )NrM   r$   )rl   r  rm   rn   r0   rÐ   ro   rp   r   r   rm     rã   zTestNextSibling.setUpc                 C   rô   rØ   )r   rn   Únext_siblingro   r   r   r   Ú!test_next_sibling_of_root_is_none”  rÚ   z1TestNextSibling.test_next_sibling_of_root_is_nonec                 C   óB   |   | jjd d¡ |   | jjjd d¡ |   | jjd d¡ d S )Nr%   r.   rN   ú1.1)r   rÐ   r  rî   ro   r   r   r   Útest_next_sibling—  ó   z!TestNextSibling.test_next_siblingc                 C   óN   |   | jjjd ¡ | jjdd}|   |jd ¡ | jjdd}|   |jd ¡ d S )Nr  r$   rQ   )r   rn   r	  r  r0   )r   Únested_spanZ	last_spanr   r   r   Útest_next_sibling_may_not_existž  ó
   z/TestNextSibling.test_next_sibling_may_not_existc                 C   ó   |   | j d¡d d¡ d S )Nr¿   r%   r.   )r   rÐ   Úfind_next_siblingro   r   r   r   Útest_find_next_sibling§  ó   z&TestNextSibling.test_find_next_siblingc                 C   ó4   |   | j d¡g d¢¡ |   | jjdddg¡ d S )Nr¿   )r.   rN   rQ   rN   r$   )r'   rÐ   Úfind_next_siblingsro   r   r   r   Útest_next_siblingsª  ó   ÿz"TestNextSibling.test_next_siblingsc                 C   óv   |   d¡}|jdd}|  |jjd¡ |  |jjd¡ |  | d¡dg¡ |  |jddd¡ |  |jddd ¡ d S )NúFoo<b>bar</b>bazrE   rD   r-   ÚbazrC   Únonesuch)r/   r0   r   r  rf   r!   r+  r'  ©r   r/   rÐ   r   r   r   Ú"test_next_sibling_for_text_element°  ó   
z2TestNextSibling.test_next_sibling_for_text_element)r(   r)   r*   rm   r  r   r$  r(  r,  r3  rŒ   r   r   rp   r   r  Ž  ó    	r  c                       r  )ÚTestPreviousSiblingc                    r  )NrQ   r$   )rl   r6  rm   rn   r0   r  ro   rp   r   r   rm   ½  rã   zTestPreviousSibling.setUpc                 C   rô   rØ   )r   rn   Úprevious_siblingro   r   r   r   Ú%test_previous_sibling_of_root_is_noneÁ  rÚ   z9TestPreviousSibling.test_previous_sibling_of_root_is_nonec                 C   r  )Nr%   rN   r.   z3.1)r   r  r7  r  ro   r   r   r   Útest_previous_siblingÄ  r!  z)TestPreviousSibling.test_previous_siblingc                 C   r"  )Nr  r$   rM   )r   rn   r	  r7  r0   )r   r#  Z
first_spanr   r   r   Ú#test_previous_sibling_may_not_existË  r%  z7TestPreviousSibling.test_previous_sibling_may_not_existc                 C   r&  )Nr¿   r%   rN   )r   r  Úfind_previous_siblingro   r   r   r   Útest_find_previous_siblingÔ  r)  z.TestPreviousSibling.test_find_previous_siblingc                 C   r*  )Nr¿   )rN   r.   rM   rM   r$   )r'   r  Úfind_previous_siblingsro   r   r   r   Útest_previous_siblings×  r-  z*TestPreviousSibling.test_previous_siblingsc                 C   r.  )Nr/  r0  rD   r-   rE   rC   r1  )r/   r0   r   r7  rf   r!   r=  r;  r2  r   r   r   Ú&test_previous_sibling_for_text_elementÝ  r4  z:TestPreviousSibling.test_previous_sibling_for_text_element)r(   r)   r*   rm   r8  r9  r:  r<  r>  r?  rŒ   r   r   rp   r   r6  »  r5  r6  c                   @   ra   )Ú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_tagrO   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*   rC  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  rU   r0  rf   za name)rC   re   )rC   rf   )
r/   rA  r]   Ú
isinstancer   r   rf   Údictre   rÔ   )r   r/   rA  r   r   r   Útest_new_tag  s   
zTestTagCreation.test_new_tagc                 C   s„   t r!tddƒ}| d¡}| d¡}|  d| ¡ ¡ |  d| ¡ ¡ tddƒ}| d¡}| d¡}|  d| ¡ ¡ |  d| ¡ ¡ d S )	Nr  zlxml-xmlÚbrÚps   <br/>s   <p/>úhtml.parsers   <p></p>)ÚXML_BUILDER_PRESENTr   rA  r   r•   )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  rU   )r/   Ú
new_stringr   r]   rE  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 rM  )r/   rN  r   r   r]   rE  rO  r   r   r   Ú3test_new_string_can_create_navigablestring_subclass$  s   
zCTestTagCreation.test_new_string_can_create_navigablestring_subclassN)r(   r)   r*   rA   rG  rL  rQ  rR  r   r   r   r   rD     s    rD  c                   @   sT  e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Zd1d2„ Zd3d4„ Zd5d6„ Zd7d8„ Zd9d:„ Zd;d<„ Z d=d>„ Z!d?d@„ Z"dAdB„ Z#dCdD„ Z$dEdF„ Z%dGdH„ Z&dIdJ„ Z'dKdL„ Z(dMdN„ Z)dOdP„ Z*dQdR„ Z+dSS )TÚTestTreeModificationc                 C   sl   |   d¡}d|jd< |  | ¡ |  d¡¡ |jd= |  | ¡ |  d¡¡ d|jd< |  | ¡ |  d¡¡ d S )	Nz<a id="1"></a>r:   r%   z<a id="2"></a>rX   rU   Zid2z<a id2="foo"></a>)r/   r?   r   r–   Údocument_forr1   r   r   r   Útest_attribute_modification,  s   


z0TestTreeModification.test_attribute_modificationc                 C   sl   t  d¡ƒ }| jd|d}t||dƒ}t||dƒ}d|d< |j d|¡ |j d	|¡ |  |j ¡ d
¡ d S )Nr	  z<body></body>©rÅ   r?   Úolzhttp://foo.com/Úhrefr   rO   s4   <body><a href="http://foo.com/"></a><ol></ol></body>)r   Úlookupr/   r   r  Úinsertr   r•   )r   rÅ   r/   r?   rW  r   r   r   Útest_new_tag_creation5  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/   r0   r-   rY   r   rÔ   r–   rT  )r   Údocr/   Zsecond_paraÚboldr   r   r   Ú!test_append_to_contents_moves_tagA  s   

ÿÿz6TestTreeModification.test_append_to_contents_moves_tagc                 C   s0   d}|   |¡}|j}| |j¡}|  ||¡ d S )Nz<a></a><b><c></c></b>)r/   r?   Úreplace_withrz   r   ©r   r7   r/   r?   Znew_ar   r   r   Ú1test_replace_with_returns_thing_that_was_replacedS  s
   
zFTestTreeModification.test_replace_with_returns_thing_that_was_replacedc                 C   s,   d}|   |¡}|j}| ¡ }|  ||¡ d S )Nú<a><b></b><c></c></a>)r/   r?   Úunwrapr   r`  r   r   r   Ú+test_unwrap_returns_thing_that_was_replacedZ  s
   
z@TestTreeModification.test_unwrap_returns_thing_that_was_replacedc                 C   sJ   |   d¡}|j}| ¡  |  d |j¡ |  t|j¡ |  t|j|j	¡ d S )Nz<a><b>Foo</b></a><c>Bar</c>)
r/   r?   Úextractr   rÔ   rÊ   rË   rc  r_  rz   r¸   r   r   r   ÚItest_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parenta  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/   rz   r_  r   r–   rT  )r   r7   r/   rz   r   r   r   Útest_replace_tag_with_itselfi  s
   
z1TestTreeModification.test_replace_tag_with_itselfc                 C   s&   d}|   |¡}|  t|jj|j¡ d S ©Nú<a><b></b></a>)r/   rÊ   rË   r-   r_  r?   ©r   r7   r/   r   r   r   Ú1test_replace_tag_with_its_parent_raises_exceptionp  ó   
zFTestTreeModification.test_replace_tag_with_its_parent_raises_exceptionc                 C   s(   d}|   |¡}|  t|jjd|j¡ d S )Nri  r   )r/   rÊ   rË   r?   rZ  rj  r   r   r   Ú,test_insert_tag_into_itself_raises_exceptionu  s   
zATestTreeModification.test_insert_tag_into_itself_raises_exceptionc           	      C   sŒ   |   d¡}d}|   |¡}| d|¡ |jD ]	}t|tƒrJ ‚q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>rO   zAnd now, a word:Úp2Úp3zAnd we're back.N)	r/   rZ  ZdescendantsrE  r   ÚlistÚchildrenr   r   )	r   r/   r7   Z	to_insertrÌ   Úp1rn  ro  Zp4r   r   r   Ú1test_insert_beautifulsoup_object_inserts_childrenz  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   rO   Útwor  Úthree)r/   r?   rÄ   rZ  ÚreplaceWithr   r-   r   )r   r/   r?   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>úArgh!rD   úHooray!)r/   r0   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>rO   r{  z!<a><b>Argh!Hooray!</b><c></c></a>rD   rz  )r/   r-   rZ  r   r–   rT  r0   r  rî   r7  r  rz   )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 )NrX   r   rC   rU   )r/   r?   rZ  r   rÄ   rî   r1   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>rV  Zmagictagr   ÚtherO   z=<a><b>Find</b><magictag>the</magictag><c>lady!</c><d></d></a>ZFindrD   )rÃ   r/   r   rZ  r?   r   r–   rT  r-   r  r7  r0   rî   r  rz   rÔ   )r   rÅ   r/   Z	magic_tagZb_tagr0   Zc_tagr€  r   r   r   Útest_insert_tagÅ  s2   ÿ
ÿÿz$TestTreeModification.test_insert_tagc                 C   s0   d}|   |¡}|j |j¡ |  || ¡ ¡ d S rh  )r/   r?   rY   r-   r   r–   ©r   r—   r/   r   r   r   Ú*test_append_child_thats_already_at_the_endã  ó   
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/   Úgr¡   Úer¾   rz   r-   r?   Úextendr   r–   )r   r—   r/   rZ   r   r   r   Útest_extendé  s
   
z TestTreeModification.test_extendc                 C   s2   d}|   |¡}|j d|j¡ |  d| ¡ ¡ d S )Nz<a><b></b><c></c><d></d></a>r   z<a><d></d><b></b><c></c></a>)r/   r?   rZ  r¾   r   r–   r‚  r   r   r   Ú$test_move_tag_to_beginning_of_parentð  s   
z9TestTreeModification.test_move_tag_to_beginning_of_parentc                 C   s.   |   d¡}|j dd¡ |  t|jƒd¡ d S )Nz<br/>rO   ZContentsz<br>Contents</br>)r/   rH  rZ  r   r6   r1   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 )	Nr9   ÚBAZÚQUUXzQUUX<a>foo</a>BAZ<b>bar</b>úQUUX<b>bar</b><a>foo</a>BAZÚnopeú<a>r?   )r/   r-   Úinsert_beforer?   r   r–   rT  rÊ   rË   re  rA  ©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 )Nr9   r‹  ú rŒ  z$QUUX BAZ<a>foo</a>BAZ QUUX<b>bar</b>ÚFOOz'QUUX BAZ<b>bar</b>FOO<a>foo</a>BAZ QUUX)r/   r-   r  r?   r   r–   rT  r1   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 )	Nr9   r‹  rŒ  z<a>foo</a>QUUX<b>bar</b>BAZr  rŽ  r  r?   )r/   r-   Úinsert_afterr?   r   r–   rT  rÊ   rË   re  r  rA  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 )Nr9   r‹  r“  rŒ  z$<a>foo</a>QUUX BAZ<b>bar</b>BAZ QUUXzFOO z(QUUX BAZ<b>bar</b><a>foo</a>FOO BAZ QUUX)r/   r-   r–  r?   r   r–   rT  r1   r   r   r   Útest_insert_multiple_after7  s   
ÿÿz/TestTreeModification.test_insert_multiple_afterc                 C   óR   |   d¡}| d¡}| d¡}|  t|j|¡ |  t|j|¡ |  t|j|¡ d S ©Nr  r?   )r/   rA  rN  rÊ   rË   r–  ÚNotImplementedError©r   r/   r   r   r   r   r   Ú:test_insert_after_raises_exception_if_after_has_no_meaningA  ó   


zOTestTreeModification.test_insert_after_raises_exception_if_after_has_no_meaningc                 C   r™  rš  )r/   rA  rN  rÊ   rË   r  r›  rœ  r   r   r   ÚFtest_insert_before_raises_notimplementederror_if_before_has_no_meaningI  rž  z[TestTreeModification.test_insert_before_raises_notimplementederror_if_before_has_no_meaningc                 C   sv   |   d¡}| d¡\}}| |¡ |  | ¡ |  d¡¡ |  |jd ¡ |  |j|j¡ |  |jd¡ |  |j	d¡ d S )Nz;<p>There's <b>no</b> business like <b>show</b> business</p>r-   z0<p>There's  business like <b>no</b> business</p>Únoz	 business)
r/   r=   r_  r   r–   rT  rÔ   rI  rî   r  )r   r/   r   Úshowr   r   r   Útest_replace_withQ  s   ÿ
ÿþz&TestTreeModification.test_replace_withc                 C   ó0   d}|   |¡}|j |j¡ |  d| ¡ ¡ d S )Nrb  z<a><c></c></a>)r/   r-   r_  rz   r   r–   r‚  r   r   r   Útest_replace_first_child`  r„  z-TestTreeModification.test_replace_first_childc                 C   r£  )Nrb  ri  )r/   rz   r_  r-   r   r–   r‚  r   r   r   Útest_replace_last_childf  r„  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>rx  rD   ZWeÚto)r/   r-   r¡   r_  r   r–   rT  rÔ   r0   rî   r  r  r7  r?   r†  r…  )r   r/   Z
remove_tagZmove_tagZto_textZg_tagr   r   r   Útest_nested_tag_replace_withl  s4   ÿ

ÿÿ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/   Úemrc  r   rI  r7   r‘   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-   ú<b>I wish I was bold.</b>)r/   r   ÚwraprA  r   r–   rT  )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.rª  )r/   r-   r  r«  r   r–   rT  r1   r   r   r   Ú%test_wrap_extracts_tag_from_elsewhereŸ  s
   
ÿz:TestTreeModification.test_wrap_extracts_tag_from_elsewherec                 C   sH   |   d¡}|jj |j¡ |  dt|jjƒ¡ |  | ¡ |  d¡¡ d S )Nz+<b>I like being bold.</b>I wish I was bold.r:   z+<b>I like being bold.I wish I was bold.</b>)	r/   r-   r  r«  r   r<   rÄ   r–   rT  r1   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>rJ   Znavr$   z6<html><body>Some content.  More content.</body></html>z<div id="nav">Nav crap</div>r:   zSome content. rD   z More content.)r/   r   r<   r  rÄ   r0   re  r–   rÔ   r  rî   r  r7  )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 )Nr9   rU   rC   )r/   r?   r   r-   rN  rY   re  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   )Úscriptre  )r   rÌ   ©r/   r   r   r   ã  s    zKTestTreeModification.test_extract_multiples_of_same_tag.<locals>.<listcomp>r±  z<body>

<a></a>
</body>)r/   r=   r   r6   r  ro   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/   r0   re  r   r1   r   r   r   ÚBtest_extract_works_when_element_is_surrounded_by_identical_stringsç  s
   ÿzWTestTreeModification.test_extract_works_when_element_is_surrounded_by_identical_stringsc                 C   sf   |   d¡}|j}|j ¡  |  t|jjƒd¡ |  t|dƒ¡ |j	}|jdd |  dt|jƒ¡ dS )zTag.clear()z4<p><a>String <em>Italicized</em></a> and another</p>r   rÄ   T)Z	decomposeN)
r/   r?   rI  Úclearr   r<   rÄ   r]   r^   r¨  )r   r/   r?   r¨  r   r   r   Ú
test_clearð  s   

zTestTreeModification.test_clearc                 C   sB   |   d¡}d|j_|  |jjdg¡ d|j_|  |jjdg¡ dS )zTag.string = 'string'z<a></a> <b><c></c></b>rU   rC   N)r/   r?   r   r   rÄ   r-   r1   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/   rz   r   r-   r   r?   r•   r1   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 )NrX   rU   )r/   r   r?   r   r]   rE  ©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*   rU  r[  r^  ra  rd  rf  rg  rk  rm  rs  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   rS  *  sT    	
		
$	rS  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>rO   rJ   N)r/   r   r<   rÄ   rÓ   r1   r   r   r   Útest_len  s
   
zTestElementObjects.test_lenc                 C   sL   |   d¡}|  |j| d¡¡ |  |jj| d¡ d¡¡ |  |jd¡ dS )z2Accessing a Python member .foo invokes find('foo')ú<b><i></i></b>r-   rÌ   N)r/   r   r-   r0   rÌ   r?   r1   r   r   r   Útest_member_access_invokes_find"  s   
z2TestElementObjects.test_member_access_invokes_findc                 C   sd   |   d¡}tjdd}|j}W d   ƒ n1 sw   Y  |  |j|¡ |  dt|d jƒ¡ d S )Nr¾  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-   r6   Úmessage)r   r/   Úwr   r   r   r   Útest_deprecated_member_access)  s   
ÿþz0TestElementObjects.test_deprecated_member_accessc                 C   s2   |   d¡}|  |j d¡¡ |  |j d¡¡ dS )zÙhas_attr() checks for the presence of an attribute.

        Please note note: has_attr() is different from
        __in__. has_attr() checks the tag's attributes and __in__
        checks the tag's chidlren.
        z<foo attr='bar'>ÚattrZattr2N)r/   r]   rU   Úhas_attrÚassertFalser1   r   r   r   Útest_has_attr2  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assertSoupEqualsr  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>rU   ©r/   r   r-   r   r1   r   r   r   Útest_stringB  s   
zTestElementObjects.test_stringc                 C   s   |   d¡}|  |jjd ¡ d S )Nú<b></b>rË  r1   r   r   r   Útest_empty_tag_has_no_stringH  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>rO   rC   )r/   r   r-   r   r?   rZ  r1   r   r   r   Ú-test_tag_with_multiple_children_has_no_stringM  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>rU   )r/   r   r?   r   r1   r   r   r   Ú)test_tag_with_recursive_string_has_string[  s   
z<TestElementObjects.test_tag_with_recursive_string_has_stringc                 C   s4   |   d¡}|  |jj¡ |   d¡}|  |jj¡ dS )z7Only a tag containing a single text node has a .string.z<b>f<i>e</i>o</b>rÍ  N)r/   rÈ  r-   r   r1   r   r   r   Útest_lack_of_stringb  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)ÚstripÚartú,z	a,r, , t za,r,tN)r/   r   r?   r7   Úget_textr1   r   r   r   Útest_all_textj  s
   
z TestElementObjects.test_all_textc                 C   sJ   |   d¡}|  | ¡ d¡ |  |jttfdd¡ |  |jd dd¡ d S )Núfoo<!--IGNORE-->barZfoobar)ÚtypesZfooIGNOREbar)r/   r   rÕ  r   r   r1   r   r   r   Útest_get_text_ignores_commentsr  s   
ÿÿz1TestElementObjects.test_get_text_ignores_commentsc                 C   s$   |   d¡}|  ddgt|jƒ¡ d S )Nr×  rU   rC   )r/   r   rp  Ústringsr1   r   r   r   Ú!test_all_strings_ignores_comments{  ó   
z4TestElementObjects.test_all_strings_ignores_commentsN)r(   r)   r*   rA   r½  r¿  rÅ  rÉ  rÊ  rÌ  rÎ  rÏ  rÐ  rÑ  rÖ  rÙ  rÛ  r   r   r   r   r¼    s    		r¼  c                   @   óP   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'>rU   rš   ©r/   r   r?   r1   r   r   r   Útest_single_value_becomes_listƒ  r3   z6TestCDAtaListAttributes.test_single_value_becomes_listc                 C   ó$   |   d¡}|  ddg|jd ¡ d S )Nz<a class='foo bar'>rU   rC   rš   rß  r1   r   r   r   Ú!test_multiple_values_becomes_list‡  rÜ  z9TestCDAtaListAttributes.test_multiple_values_becomes_listc                 C   s$   |   d¡}|  g d¢|jd ¡ d S )Nz<a class='foo	bar
baz'>)rU   rC   r0  rš   rß  r1   r   r   r   Ú2test_multiple_values_separated_by_weird_whitespace‹  rÜ  zJTestCDAtaListAttributes.test_multiple_values_separated_by_weird_whitespacec                 C   ó    |   d¡}|  d|j ¡ ¡ d S )Nz<a class='foo	bar'>s   <a class="foo bar"></a>)r/   r   r?   r•   r1   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   r?   Zget_attribute_listr1   r   r   r   Útest_get_attribute_list“  rÜ  z/TestCDAtaListAttributes.test_get_attribute_listc                 C   rá  )Nz(<form accept-charset="ISO-8859-1 UTF-8">z
ISO-8859-1zUTF-8úaccept-charset)r/   r   Úformr1   r   r   r   Útest_accept_charset—  rÜ  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-8rç  rß  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 )NrP  c                      s
   dˆ _ d S )NrU   r™   r   r   r   r   Út¦  s   
zJTestCDAtaListAttributes.test_string_has_immutable_name_property.<locals>.t)r/   r   r   rf   rÊ   ÚAttributeError)r   rë  r   r   r   Ú'test_string_has_immutable_name_property£  s   z?TestCDAtaListAttributes.test_string_has_immutable_name_propertyN)r(   r)   r*   rA   rà  râ  rã  rå  ræ  ré  rê  rí  r   r   r   r   rÞ    s    rÞ  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>)rl   rî  rm   Úpager/   rn   ro   rp   r   r   rm   ­  s   zTestPersistence.setUpc                 C   s@   t  | jd¡}t  |¡}|  |jt¡ |  | ¡ | j ¡ ¡ d S )Nr:   )ÚpickleÚdumpsrn   Úloadsr   rq   r   r–   )r   ÚdumpedÚloadedr   r   r   Ú!test_pickle_and_unpickle_identityÁ  s   
z1TestPersistence.test_pickle_and_unpickle_identityc                 C   s&   t  | j¡}|  | ¡ | j ¡ ¡ d S rØ   )ÚcopyÚdeepcopyrn   r   r–   )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>rJ  u	   <p>Â </p>)r   Zoriginal_encodingÚ__copy__r   r6   )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>rP   é!   )	r/   rI  Z
sourcelineZ	sourceposrú  r   Zcan_be_empty_elementZcdata_list_attributesrB  )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 )Nõ
   <b>â˜ƒ</b>)r/   rð  rñ  ÚHIGHEST_PROTOCOLrò  r   r–   )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>rE   r   )	r/   r0   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   r]   rE  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 )Nú)<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|ƒ¡ |  ||¡ |  ||u ¡ |  d |j¡ |  d |j¡ |  d |jddj	¡ |  
d |jddj	¡ d S )Nr  ZBarr   )r/   rˆ   rö  r   r6   rÈ  rÔ   r  r0   rî   r  )r   r	  r/   rˆ   Zdiv_copyr   r   r   Útest_copy_tag_copies_contents  s   

z-TestPersistence.test_copy_tag_copies_contents)r(   r)   r*   rA   rm   rõ  rù  rü  rþ  r  r  r  r	  r
  rŒ   r   r   rp   r   rî  ª  s    rî  c                   @   r   )"ÚTestSubstitutionsc                 C   ó0   d}|   |¡}|jdd}|  ||  d¡¡ d S ©Nõ#   <b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>Úminimal©Ú	formatter©r/   r–   r   rT  ©r   r  r/   Údecodedr   r   r   Ú!test_default_formatter_is_minimal&  ó   
ÿþz3TestSubstitutions.test_default_formatter_is_minimalc                 C   ó0   d}|   |¡}|jdd}|  ||  d¡¡ d S )Nõ'   <br><b>&lt;&lt;SacrÃ© bleu!&gt;&gt;</b>r	  r  z.<br/><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>r  r  r   r   r   Útest_formatter_html0  ó   
þz%TestSubstitutions.test_formatter_htmlc                 C   r  )Nr  Úhtml5r  z-<br><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>r  r  r   r   r   Útest_formatter_html58  r  z&TestSubstitutions.test_formatter_html5c                 C   r  r  r  r  r   r   r   Útest_formatter_minimal@  r  z(TestSubstitutions.test_formatter_minimalc                 C   s0   d}|   |¡}|jd d}|  ||  d¡¡ d S )Nr  r  u   <b><<SacrÃ© bleu!>></b>r  r  r   r   r   Útest_formatter_nullJ  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 rØ   ©Úupper©Úxr   r   r   Ú<lambda>V  ó    z9TestSubstitutions.test_formatter_custom.<locals>.<lambda>r  z<b><FOO></b><b>BAR</b><br/>r  r  r   r   r   Útest_formatter_customS  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   r  rØ   r   r"  r   r   r   r$  l  r%  zMTestSubstitutions.test_formatter_is_run_on_attribute_values.<locals>.<lambda>)r/   r?   r   r–   )r   r  r/   r?   Zexpect_minimalZexpect_htmlZexpect_upperr   r   r   Ú)test_formatter_is_run_on_attribute_values]  s   
z;TestSubstitutions.test_formatter_is_run_on_attribute_valuesc                 C   ó$   d}t |dƒ ¡ }|  d|v ¡ d S )NzO
  <script type="text/javascript">
   console.log("< < hey > > ");
  </script>
rJ  ó   < < hey > >©r   r•   r]   ©r   r\  Úencodedr   r   r   Ú2test_formatter_skips_script_tag_for_html_documentsn  ó   zDTestSubstitutions.test_formatter_skips_script_tag_for_html_documentsc                 C   r(  )NzF
  <style type="text/css">
   console.log("< < hey > > ");
  </style>
rJ  r)  r*  r+  r   r   r   Ú1test_formatter_skips_style_tag_for_html_documentsw  r.  zCTestSubstitutions.test_formatter_skips_style_tag_for_html_documentsc                 C   rä  )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   rˆ   Úprettifyr1   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|v ¡ d S )Nz<html><body>foo</body></html>rJ  c                 S   r  rØ   r   r"  r   r   r   r$  Š  r%  zLTestSubstitutions.test_prettify_accepts_formatter_function.<locals>.<lambda>r  r”  )r   r0  r]   )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 rW   )r/   r   r6   Útyper0  r1   r   r   r   Ú(test_prettify_outputs_unicode_by_default  r3   z:TestSubstitutions.test_prettify_outputs_unicode_by_defaultc                 C   s$   |   d¡}|  tt| d¡ƒ¡ d S )NrX   úutf-8)r/   r   Úbytesr4  r0  r1   r   r   r   Útest_prettify_can_encode_data‘  rÜ  z/TestSubstitutions.test_prettify_can_encode_datac                 C   s0   d}|   |¡}|j d¡}|  || d¡¡ d S )Nu   <b>SacrÃ© bleu!</b>r6  )r/   r-   r•   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|v ¡ | d¡}|  d|v ¡ | d¡}|  d	|v ¡ | d
¡ d
¡}|  d|v ¡ d S )NzE<meta content="text/html; charset=x-sjis" http-equiv="Content-type"/>Úcontentztext/html; charset=x-sjisr6  s   charset=utf-8Úeuc_jps   charset=euc_jpz	shift-jiss   charset=shift-jiszutf-16zcharset=utf-16)r/   r   Úmetar•   r]   r–   )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Ä   rf   )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/  r1  r3  r5  r8  r9  r?  rA  r   r   r   r   r  $  s"    

	
		r  c                   @   rÝ  )ÚTestEncodingz0Test the ability to encode objects into strings.c                 C   s.   d}|   |¡}|  |jj d¡d d¡¡ d S )Nrÿ  r6  õ   â˜ƒ)r/   r   r-   r   r•   ©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 )Nrÿ  r6  ©r/   r   r-   r•   rD  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 )Nrÿ  Úasciis   <b>&#9731;</b>rF  rD  r   r   r   Ú<test_encoding_substitutes_unrecognized_characters_by_defaultÍ  rl  zITestEncoding.test_encoding_substitutes_unrecognized_characters_by_defaultc                 C   s&   d}|   |¡}| jt|jddd d S )Nrÿ  rH  Ústrict)Úerrors)r/   rÊ   ÚUnicodeEncodeErrorr•   rD  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 )Nrÿ  rC  )r/   r   r-   Zdecode_contentsrD  r   r   r   Útest_decode_contentsØ  s   
z!TestEncoding.test_decode_contentsc                 C   s.   d}|   |¡}|  d d¡|jjdd¡ d S )Nrÿ  rC  r“   )rû  )r/   r   r•   r-   Zencode_contentsrD  r   r   r   Útest_encode_contentsÝ  s   
ÿÿz!TestEncoding.test_encode_contentsc                 C   s*   d}|   |¡}|  d d¡|j ¡ ¡ d S )Nrÿ  rC  r“   )r/   r   r•   r-   ZrenderContentsrD  r   r   r   Útest_deprecated_renderContentsä  s
   
ÿz+TestEncoding.test_deprecated_renderContentsc                 C   s:   d}|   |¡}tr|  |t|ƒ¡ d S |  dt|ƒ¡ d S )Nrÿ  s   <b>\u2603</b>)r/   r   r   ÚreprrD  r   r   r   Ú	test_reprê  s
   
zTestEncoding.test_reprN)r(   r)   r*   rA   rE  rG  rI  rM  rN  rO  rP  rR  r   r   r   r   rB  ¾  s    rB  c                   @   ra   )ÚTestFormatterc                 C   sL   G dd„ dt ƒ}|  d¡}|ƒ }|j|d}|  |j|j¡ |  d|¡ d S )Nc                   @   ra   )z=TestFormatter.test_sort_attributes.<locals>.UnsortedFormatterc                 s   s8    || _ t|j ¡ ƒD ]\}}|dkrq||fV  qd S )NÚignore)Úcalled_withÚsortedre   Úitems)r   r   ÚkÚvr   r   r   Ú
attributesø  s   €ýzHTestFormatter.test_sort_attributes.<locals>.UnsortedFormatter.attributesN)r(   r)   r*   rZ  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/   r–   r   rU  rI  )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   rS  ò  rh   rS  c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚTestNavigableStringSubclassesc                 C   sX   |   d¡}tdƒ}| d|¡ |  t|ƒd¡ |  |jddd¡ |  |jd d¡ d S )Nr  rU   rO   z<![CDATA[foo]]>rD   r   )r/   r   rZ  r   r6   r0   rÄ   r¹  r   r   r   Ú
test_cdata  s   
z(TestNavigableStringSubclasses.test_cdatac                    sV   dˆ _ ‡ fdd„}ˆ  d¡}tdƒ}| d|¡ ˆ  d|j|d¡ ˆ  dˆ j ¡ d	S )
zkText inside a CData object is passed into the formatter.

        But the return value is ignored.
        r   c                     s   ˆ  j d7  _ dS )NrO   zBITTER FAILURE)Úcount)Úargsro   r   r   Ú	increment  s   zNTestNavigableStringSubclasses.test_cdata_is_never_formatted.<locals>.incrementr  z<><><>rO   s   <![CDATA[<><><>]]>r  N)r_  r/   r   rZ  r   r•   )r   ra  r/   rº  r   ro   r   Útest_cdata_is_never_formatted  s   
ÿz;TestNavigableStringSubclasses.test_cdata_is_never_formattedc                 C   s2   t dƒ}|  d¡}| d|¡ |  | ¡ d¡ d S )NrU   r  rO   s   <!DOCTYPE foo>
)r
   r/   rZ  r   r•   )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 )NrU   z<?foo?>)r	   r   Zoutput_ready)r   r¾   r   r   r   Útest_declaration/  s   z.TestNavigableStringSubclasses.test_declarationN)r(   r)   r*   r^  rb  rd  re  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 )NrJ  )r   ÚHTMLr/   ro   r   r   r   rm   f  ó   zTestSoupSelector.setUpc              
   K   sV   dd„ | j j|fi |¤ŽD ƒ}| ¡  | ¡  |  ||d|d |¡d |¡f ¡ d S )Nc                 S   r#   r$   r   )r   Úelr   r   r   r   j  r&   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!   i  s   ÿÿzTestSoupSelector.assertSelectsc                 G   s   |D ]
\}}|   ||¡ qd S rØ   )ÚassertSelect)r   Útestsrm  rn  r   r   r   ÚassertSelectMultipleu  s   ÿz%TestSoupSelector.assertSelectMultiplec                 C   sF   | j  d¡}|  t|ƒd¡ |  |d jd¡ |  |d jdg¡ d S )Nr”   rO   r   z	The title)r/   rj  r   r<   rf   rÄ   ©r   Úelsr   r   r   Útest_one_tag_oney  s   z!TestSoupSelector.test_one_tag_onec                 C   sT   | j  d¡}|  t|ƒd¡ |D ]	}|  |jd¡ q| j  d¡}|  d|d ¡ d S )Nrˆ   é   Úmainr%   )r/   rj  r   r<   rf   Ú
select_one)r   rt  rˆ   ri  r   r   r   Útest_one_tag_many  s   z"TestSoupSelector.test_one_tag_manyc                 C   s   | j  d¡}|  d |¡ d S )NZnonexistenttag)r/   rx  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/   rj  r!   rs  r   r   r   Útest_tag_in_tag_one  r×   z$TestSoupSelector.test_tag_in_tag_onec                 C   s   dD ]
}|   |g d¢¡ qd S )N)úhtml divúhtml body divúbody div©r}  rw  r|  Úfooter©r!   ©r   rm  r   r   r   Útest_tag_in_tag_many‘  s   ÿz%TestSoupSelector.test_tag_in_tag_manyc                 C   s>   | j ddgdd | j dddgdd | j dg d	¢d
d d S )Nr  rw  rO   rK   r€  r|  r:   r  r‚  rP   r„  ro   r   r   r   Ú
test_limit–  s
   
ÿzTestSoupSelector.test_limitc                 C   s   |   t| j d¡ƒd¡ d S )NÚdelr   ©r   r<   r/   rj  ro   r   r   r   Útest_tag_no_matchœ  r)  z"TestSoupSelector.test_tag_no_matchc                 C   ó   |   t| jjd¡ d S )Nztag%t©rÊ   ÚSyntaxErrorr/   rj  ro   r   r   r   Útest_invalid_tagŸ  ó   z!TestSoupSelector.test_invalid_tagc                 C   ó   |   dddg¡ d S )Núcustom-dashed-tagÚdash1Údash2r„  ro   r   r   r   Útest_select_dashed_tag_ids¢  rÚ   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   r‘  r%   r“  )r/   rj  r   rf   )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/   rj  r7   ro   r   r   r   Útest_dashed_tag_textª  s   z%TestSoupSelector.test_dashed_tag_textc                 C   s    |   | j d¡| j d¡¡ d S )Nr‘  )r   r/   rj  r=   ro   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©rr  ro   r   r   r   Útest_header_tags°  s   
þz!TestSoupSelector.test_header_tagsc                 C   sR   dD ]$}| j  |¡}|  t|ƒd¡ |  |d jd¡ |  |d d dg¡ qd S )N)z.onepzp.onepzhtml p.oneprO   r   rI  rš   Úonep)r/   rj  r   r<   rf   )r   rm  rt  r   r   r   Útest_class_one¶  s   üzTestSoupSelector.test_class_onec                 C   ó    | j  d¡}|  t|ƒd¡ d S )Nzdiv.onepr   ©r/   rj  r   r<   rs  r   r   r   Útest_class_mismatched_tag½  r×   z*TestSoupSelector.test_class_mismatched_tagc                 C   ó   dD ]	}|   |dg¡ qd S )N)z	div#innerz#innerzdiv div#innerr|  r„  r…  r   r   r   Útest_one_idÁ  s   ÿzTestSoupSelector.test_one_idc                 C   r¡  )Nz#doesnotexistr   r¢  rs  r   r   r   Útest_bad_idÅ  r×   zTestSoupSelector.test_bad_idc                 C   sb   | j  d¡}|  t|ƒd¡ |D ]	}|  |jd¡ q|  |d d dg¡ |  |d  d¡¡ d S )Nzdiv#inner prJ   rI  rO   rš   rŸ  r   )r/   rj  r   r<   rf   rÈ  rÇ  )r   rt  ri  r   r   r   Útest_items_in_idÉ  s   z!TestSoupSelector.test_items_in_idc                 C   s&   dD ]}|   t| j |¡ƒd¡ qd S )N)zdiv#main delzdiv#main div.oopszdiv div#mainr   r‰  r…  r   r   r   Útest_a_bunch_of_emptysÑ  s   ÿz'TestSoupSelector.test_a_bunch_of_emptysc                 C   r¤  )N)z.class1zp.class1z.class2zp.class2z.class3zp.class3zhtml p.class2zdiv#inner .class2Úpmultir„  r…  r   r   r   Útest_multi_class_supportÕ  ó   þz)TestSoupSelector.test_multi_class_supportc                 C   r¤  )N)z.class1.class3z.class3.class2z.class1.class2.class3r©  r„  r…  r   r   r   Útest_multi_class_selectionÚ  r«  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Ús1a2s1r„  ro   r   r   r   Útest_child_selectorß  s   z$TestSoupSelector.test_child_selectorc                 C   ó   |   ddg¡ d S )Nz.s1 > a#s1a2 spanr¯  r„  ro   r   r   r   Útest_child_selector_idã  rh  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"]rr  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  ro   r   r   r   Útest_attribute_equalsæ  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  ro   r   r   r   Útest_attribute_tildeø  s   öz%TestSoupSelector.test_attribute_tildec                 C   sv   |   ddgfddgfdg fdg fdg fddgfdd	d
gfdd	d
gfdddgfdd
dgfddgfdd
gfddgf¡ d S )Nz[rel^="style"]r³  zlink[rel^="style"]znotlink[rel^="notstyle"]z[rel^="notstyle"]zlink[rel^="notstyle"]zlink[href^="bla"]za[href^="http://"]rµ  Úmez[href^="http://"]z	[id^="p"]r©  rr  z	[id^="m"]rw  zdiv[id^="m"]z
a[id^="m"]zdiv[data-tag^="dashed"]r}  r  ro   r   r   r   Útest_attribute_startswith  s   



óz*TestSoupSelector.test_attribute_startswithc              	   C   s<   |   ddgfddgfddgfdg d¢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³  rr  r™  r­  Ús2a1r¯  r’  zdiv[id$="1"]r}  z[id$="noending"]r  ro   r   r   r   Útest_attribute_endswith  s   
úz(TestSoupSelector.test_attribute_endswithc                 C   sÀ   |   ddgfddgfdg fdg fdg fddgfdd	d
gfdddgfddgfdd
gfddgfddgfddgfdg d¢fddgfdg fdg d¢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©  rr  zdiv[id*="m"]rw  z
a[id*="m"]z[href*=".css"]zlink[href*=".css"]zlink[id*="1"]z	[id*="1"])	r}  r³  rr  r™  r­  r®  r¹  r¯  r’  zdiv[id*="1"]r}  z[id*="noending"]z[href*="."])rµ  r·  r³  za[href*="."]zlink[href*="."]zdiv[id*="n"]r|  zdiv[id*="nn"]zdiv[data-tag*="edval"]r  ro   r   r   r   Útest_attribute_contains!  s0   





çz(TestSoupSelector.test_attribute_containsc                 C   s.   |   dg d¢fdg d¢fddgfdg f¡ d S )Nzp[lang|="en"])úlang-enú
lang-en-gbú
lang-en-usz[lang|="en"]zp[lang|="fr"]úlang-frzp[lang|="gb"]r  ro   r   r   r   Útest_attribute_exact_or_hypen>  s   

üz.TestSoupSelector.test_attribute_exact_or_hypenc                 C   sP   |   dg d¢fddgfdddgfdg d	¢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]r³  za[rel]rµ  r·  z[lang])r¼  r½  r¾  r¿  zp[class]rr  r©  z[blah]zp[blah]zdiv[data-tag]r}  r  ro   r   r   r   Útest_attribute_existsF  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>
        rJ  zdiv[style="display: right"]Úyes)r   rj  r   r   )r   r	  r/   Zchosenr   r   r   Ú"test_quoted_space_in_selector_nameR  s   
z3TestSoupSelector.test_quoted_space_in_selector_namec                 C   s(   |   t| jjd¡ |   t| jjd¡ d S )Nza:no-such-pseudoclassza:nth-of-type(a))rÊ   r›  r/   rj  r  ro   r   r   r   Útest_unsupported_pseudoclassZ  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)rO   r   ú	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/   rj  r   r<   r   rs  r   r   r   Útest_nth_of_typea  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)rO   r   rÅ  rÆ  rs  r   r   r   Ú"test_nth_of_type_direct_descendantt  s   z3TestSoupSelector.test_nth_of_type_direct_descendantc                 C   r±  )Nz#inner > p:nth-of-type(2)rr  r„  ro   r   r   r   Ú"test_id_child_selector_nth_of_typey  rh  z3TestSoupSelector.test_id_child_selector_nth_of_typec                 C   s.   | j jddd}| d¡}|  |ddg¡ d S )Nrˆ   rw  r$   r|  r}  )r/   r0   rj  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 #innerr„  ro   r   r   r   Útest_overspecified_child_id…  rr   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/   rj  ro   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 ~ h2rÍ  ro   r   r   r   Útest_general_sibling_selector  s
   z.TestSoupSelector.test_general_sibling_selectorc                 C   r‹  )Nzh1 >rŒ  ro   r   r   r   Útest_dangling_combinator–  r  z)TestSoupSelector.test_dangling_combinatorc                 C   ó   |   dg d¢¡ d S )Nzp[lang] ~ p)r½  r¾  r¿  r„  ro   r   r   r   Ú2test_sibling_combinator_wont_select_same_tag_twice™  rÚ   zCTestSoupSelector.test_sibling_combinator_wont_select_same_tag_twicec                 C   r  )Nzx, yÚxidÚyidr„  ro   r   r   r   Útest_multiple_select  rÚ   z%TestSoupSelector.test_multiple_selectc                 C   r  )Nzx,yrÓ  rÔ  r„  ro   r   r   r   Ú"test_multiple_select_with_no_space   rÚ   z3TestSoupSelector.test_multiple_select_with_no_spacec                 C   r  )Nzx,    yrÓ  rÔ  r„  ro   r   r   r   Ú$test_multiple_select_with_more_space£  rÚ   z5TestSoupSelector.test_multiple_select_with_more_spacec                 C   r±  )Nzx, xrÓ  r„  ro   r   r   r   Útest_multiple_select_duplicated¦  rh  z0TestSoupSelector.test_multiple_select_duplicatedc                 C   r  )Nzx, y ~ p[lang=fr]rÓ  r¿  r„  ro   r   r   r   Útest_multiple_select_sibling©  rÚ   z-TestSoupSelector.test_multiple_select_siblingc                 C   r  )Nzx, y > zrÓ  Úzidbr„  ro   r   r   r   Ú.test_multiple_select_tag_and_direct_descendant¬  rÚ   z?TestSoupSelector.test_multiple_select_tag_and_direct_descendantc                 C   rÑ  )Nzdiv > x, y, z©rÓ  rÔ  ZzidarÚ  ÚzidabZzidacr„  ro   r   r   r   Ú/test_multiple_select_direct_descendant_and_tags¯  rÚ   z@TestSoupSelector.test_multiple_select_direct_descendant_and_tagsc                 C   rÑ  )Nzdiv x,y,  zrÜ  r„  ro   r   r   r   Ú(test_multiple_select_indirect_descendant²  rÚ   z9TestSoupSelector.test_multiple_select_indirect_descendantc                 C   s(   |   t| jjd¡ |   t| jjd¡ d S )Nz,x, yzx,,yrŒ  ro   r   r   r   Útest_invalid_multiple_selectµ  s   z-TestSoupSelector.test_invalid_multiple_selectc                 C   r  )Nzp[lang=en], p[lang=en-gb]r¼  r½  r„  ro   r   r   r   Útest_multiple_select_attrs¹  rÚ   z+TestSoupSelector.test_multiple_select_attrsc                 C   rÑ  )Nz*x, y > z[id=zida], z[id=zidab], z[id=zidb])rÓ  rÚ  rÝ  r„  ro   r   r   r   Útest_multiple_select_ids¼  rÚ   z)TestSoupSelector.test_multiple_select_idsc                 C   r  )Nzbody > div > x, y > zrÓ  rÚ  r„  ro   r   r   r   Útest_multiple_select_nested¿  rÚ   z,TestSoupSelector.test_multiple_select_nestedc                 C   sN   d}t |dƒ}| d¡}|  dt|ƒ¡ |jddgdD ]}||v s$J ‚qd S )Nz3<div class="c1"/><div class="c2"/><div class="c1"/>rJ  z.c1, .c2rJ   Úc1Úc2rœ   )r   rj  r   r<   r=   )r   r  r/   rÊ  rÍ   r   r   r   Útest_select_duplicate_elementsÂ  s   

ÿz/TestSoupSelector.test_select_duplicate_elementsN)>r(   r)   r*   rg  rm   r!   rp  rr  ru  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Ù  rÛ  rÞ  rß  rà  rá  râ  rã  ræ  r   r   r   r   rf  3  sx    1
	
	rf  )6rA   Úpdbr   rö  rð  rG   rÁ  Zbs4r   Zbs4.builderr   r   Zbs4.elementr   r   r   r	   r
   r   r   r   r   Zbs4.testingr   r   rY  rK  ZLXML_PRESENTr   r,   rB   rb   ri   rŽ   r½   rÇ   rÏ   rè   rì   r  r  r  r6  r@  rD  rS  r¼  rÞ  rî  r  rB  rS  r]  rf  r   r   r   r   Ú<module>   sV   
,;O 6,3(3--*   jn+z 4*