Current File : //lib/python3.6/site-packages/bs4/tests/__pycache__/test_tree.cpython-36.pyc
3

6]�8�@sdZddlmZddlZddlZddlZddlZddlmZddl	m
Z
mZddlm
Z
mZmZmZmZmZmZmZddlmZmZe
jd�dk	Ze
jd	�dk	ZGd
d�de�ZGdd
�d
e�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�Z Gdd�de�Z!Gdd�de�Z"Gdd�de�Z#Gdd�de#�Z$Gdd�de#�Z%Gd d!�d!e�Z&Gd"d#�d#e&�Z'Gd$d%�d%e&�Z(Gd&d'�d'e�Z)Gd(d)�d)e�Z*Gd*d+�d+e�Z+Gd,d-�d-e�Z,Gd.d/�d/e�Z-Gd0d1�d1e�Z.Gd2d3�d3e�Z/Gd4d5�d5e�Z0Gd6d7�d7e�Z1dS)8a8Tests for Beautiful Soup's tree traversal methods.

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

Different parsers will build different Beautiful Soup trees given the
same markup, but all Beautiful Soup trees can be traversed with the
methods tested here.
�)�	set_traceN)�
BeautifulSoup)�builder_registry�HTMLParserTreeBuilder)�PY3K�CData�Comment�Declaration�Doctype�NavigableString�SoupStrainer�Tag)�SoupTest�skipIfZxmlZlxmlc@seZdZdd�Zdd�ZdS)�TreeTestcCs|jdd�|D�|�dS)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.
        cSsg|]
}|j�qS�)�string)�.0�tagrr�/usr/lib/python3.6/test_tree.py�
<listcomp>2sz*TreeTest.assertSelects.<locals>.<listcomp>N)�assertEqual)�self�tags�should_matchrrr�
assertSelects+szTreeTest.assertSelectscCs|jdd�|D�|�dS)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.
        cSsg|]}|d�qS)�idr)rrrrrr;sz-TreeTest.assertSelectsIDs.<locals>.<listcomp>N)r)rrrrrr�assertSelectsIDs4szTreeTest.assertSelectsIDsN)�__name__�
__module__�__qualname__rrrrrrr)s	rc@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zd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.
    cCs"|jd�}|j|jd�jd�dS)Nz <a>1</a><b>2</b><a>3</a><b>4</b>�b�2)�soupr�findr)rr$rrr�
test_find_tagEs
zTestFind.test_find_tagcCs"|jd�}|j|jdd�d�dS)Nu<h1>Räksmörgås</h1>u
Räksmörgås)r)r$rr%)rr$rrr�test_unicode_text_findIs
zTestFind.test_unicode_text_findcCs,|jd�}t|�|jd|jdd�j�dS)Nu&<h1 id="Räksmörgås">here it is</h1>z
here it isu
Räksmörgås)r)r$�strrr%�text)rr$rrr�test_unicode_attribute_findMs
z$TestFind.test_unicode_attribute_findcCs"|jd�}|jdt|j���dS)z)Test an optimization that finds all tags.z<a>foo</a><b>bar</b>�N)r$r�len�find_all)rr$rrr�test_find_everythingSs
zTestFind.test_find_everythingcCs$|jd�}|jdt|jd���dS)z;Test an optimization that finds all tags with a given name.z<a>foo</a><b>bar</b><a>baz</a>r+�aN)r$rr,r-)rr$rrr�test_find_everything_with_nameXs
z'TestFind.test_find_everything_with_nameN)	rrr �__doc__r&r'r*r.r0rrrrr!>sr!c@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�TestFindAllz%Basic tests of the find_all() method.cCs�|jd�}|j|jdd�dg�|j|jdd�dg�|j|jddgd�ddg�|j|jtjd�d�dddg�|j|jdd�dddg�d	S)
z'You can search the tree for text nodes.u<html>Foo<b>bar</b>»</html>�bar)r)r)�Fooz.*�»TN)r$rr-�re�compile)rr$rrr�test_find_all_text_nodes`s
z$TestFindAll.test_find_all_text_nodescCs�|jd�}|j|jddd�dddg�|j|jddd�dg�|j|jdd	d�dddd
dg�|j|jddd�dddd
dg�d
S)z7You can limit the number of items returned by find_all.z(<a>1</a><a>2</a><a>3</a><a>4</a><a>5</a>r/�)�limit�1r#�3��
�4�5rN)r$rr-)rr$rrr�test_find_all_limitps
zTestFindAll.test_find_all_limitcCs:|jd�}|j|ddd�dg�|j|jdd�dg�dS)	Nz!<a>1</a><b>2<a id='foo'>3</a></b>r/r=)r:r;�foo)rr<)r$rr")rr$rrr�%test_calling_a_tag_is_calling_findall|s
z1TestFindAll.test_calling_a_tag_is_calling_findallcCs.|jd�}g}|j|�|jg|j|��dS)Nz<a></a>)r$�appendrr-)rr$�lrrr�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_recursioncCs^|jd�}|jd�}|jt|d��|jd�}|jt|d��|jdd�}|jt|d��dS)z%All find_all calls return a ResultSetz<a></a>r/�sourceTrB)r)N)r$r-�
assertTrue�hasattr)rr$�resultrrr�test_find_all_resultset�s


z#TestFindAll.test_find_all_resultsetN)	rrr r1r8rArCrFrKrrrrr2]s
r2c@seZdZdd�ZdS)�TestFindAllBasicNamespacescCs<|jd�}|jd|jd�j�|jd|jddid�j�dS)Nz0<mathml:msqrt>4</mathml:msqrt><a svg:fill="red">r?zmathml:msqrtr/zsvg:fillZred)�attrs)r$rr%r�name)rr$rrr�test_find_by_namespaced_name�s
z7TestFindAllBasicNamespaces.test_find_by_namespaced_nameN)rrr rOrrrrrL�srLcspeZdZdZ�fdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Z�ZS)�TestFindAllByNamez&Test ways of finding tags by tag name.cstt|�j�|jd�|_dS)Nz�<a>First tag.</a>
                                  <b>Second tag.</b>
                                  <c>Third <a>Nested tag.</a> tag.</c>)�superr�setUpr$�tree)r)�	__class__rrrR�szTestFindAllByName.setUpcCs|j|jjd�ddg�dS)Nr/z
First tag.zNested tag.)rrSr-)rrrr�test_find_all_by_tag_name�sz+TestFindAllByName.test_find_all_by_tag_namecCs\|j|jjddd�dg�|j|jjddd�ddg�|j|jjdtjd�d�ddg�dS)Nr/z
First tag.)r)TzNested tag.r)rrSr-r6r7)rrrr�test_find_all_by_name_and_text�sz0TestFindAllByName.test_find_all_by_name_and_textcCs|j|jjjd�dg�dS)Nr/zNested tag.)rrS�cr-)rrrr�!test_find_all_on_non_root_element�sz3TestFindAllByName.test_find_all_on_non_root_elementcCs|j|jd�ddg�dS)Nr/z
First tag.zNested tag.)rrS)rrrr�%test_calling_element_invokes_find_all�sz7TestFindAllByName.test_calling_element_invokes_find_allcCs |j|jjtd��ddg�dS)Nr/z
First tag.zNested tag.)rrSr-r)rrrr�test_find_all_by_tag_strainer�sz/TestFindAllByName.test_find_all_by_tag_strainercCs"|j|jjddg�dddg�dS)Nr/r"z
First tag.zSecond tag.zNested tag.)rrSr-)rrrr�test_find_all_by_tag_names�sz,TestFindAllByName.test_find_all_by_tag_namescCs$|j|jjddd��dddg�dS)NT)r/r"z
First tag.zSecond tag.zNested tag.)rrSr-)rrrr�test_find_all_by_tag_dict�sz+TestFindAllByName.test_find_all_by_tag_dictcCs$|j|jjtjd��dddg�dS)Nz^[ab]$z
First tag.zSecond tag.zNested tag.)rrSr-r6r7)rrrr�test_find_all_by_tag_re�sz)TestFindAllByName.test_find_all_by_tag_recCs,dd�}|jd�}|j|j|�ddg�dS)NcSs|j|jd�kS)Nr)rN�get)rrrr�id_matches_name�szRTestFindAllByName.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>zMatch 1.zMatch 2.)r$rr-)rr_rSrrr�'test_find_all_with_tags_matching_method�s
z9TestFindAllByName.test_find_all_with_tags_matching_methodcCsx|jd�}|jdd�}|jdtjd��}|jdddg�\}}|jd|j�|jd|j�|jd|j�|jd|j�dS)NzH<div class='a b'>1</div><div class='a c'>2</div><div class='a d'>3</div>�divza dza br<r;)r$r%r6r7r-rr)rr$Zr1Zr2Zr3Zr4rrr�%test_find_with_multi_valued_attribute�sz7TestFindAllByName.test_find_with_multi_valued_attribute)rrr r1rRrUrVrXrYrZr[r\r]r`rb�
__classcell__rr)rTrrP�s
rPc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!S)"�TestFindAllByAttributecCs&|jd�}|j|jdd�ddg�dS)Nz�
                         <a id="first">Matching a.</a>
                         <a id="second">
                          Non-matching <b id="first">Matching b.</b>a.
                         </a>�first)rzMatching a.zMatching b.)r$rr-)rrSrrr�test_find_all_by_attribute_name�sz6TestFindAllByAttribute.test_find_all_by_attribute_namecCstdjd�}djd�}|j|�}|j|jg|j|d��|j|jg|j|jd�d��|j|jg|j|dgd��dS)Nuםולש�utf8u<a title="םולש"></a>)�titlezsomething else)�encoder$rr/r-�decode)rZpeace�datar$rrr�%test_find_all_by_utf8_attribute_value�s


z<TestFindAllByAttribute.test_find_all_by_utf8_attribute_valuecCsX|jd�}|j|jdd�dg�|j|jddid�dg�|j|jdd	id�d
g�dS)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>
                         Zname1)rNzA tag called 'name1'.rN)rMzName match.�classZclass2zClass match.)r$rr-)rrSrrr�test_find_all_by_attribute_dictsz6TestFindAllByAttribute.test_find_all_by_attribute_dictcCs�|jd�}|j|jddd�dg�|j|jddd�dg�|j|jdd	d�dg�|j|jdd�dg�|j|jdd
�ddg�|j|jdd�dg�|j|jdd	�dg�dS)Nz�
                         <a class="1">Class 1.</a>
                         <a class="2">Class 2.</a>
                         <b class="1">Class 1.</b>
                         <c class="3 4">Class 3 and 4.</c>
                         r/r;)�class_zClass 1.rWr<zClass 3 and 4.r?)rM)r$rr-)rrSrrr�test_find_all_by_classsz-TestFindAllByAttribute.test_find_all_by_classcCst|jd�}|jdtjd�d�}|j|dg�|jdtjd�d�}|j|dg�|jdtjd�d�}|j|dg�dS)Nz#<gar class='foo bar'>Found it</gar>Zgar�o)rozFound itr/zo b)r$r-r6r7r)rrS�frrr�0test_find_by_class_when_multiple_classes_present-s
zGTestFindAllByAttribute.test_find_by_class_when_multiple_classes_presentcCsd|jd�}|j|jdtjd��dg�dd�}|j|jd|�g�dd�}|j|jd|�dg�dS)	Nz<a class='bar'>Found it</a>r/ZbazFound itcSst|�dkS)Nr9)r,)�valuerrr�big_attribute_value@sznTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.big_attribute_valuecSst|�dkS)Nr9)r,)rtrrr�small_attribute_valueEszpTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.small_attribute_value)r$rr-r6r7)rr$rurvrrr�:test_find_all_with_non_dictionary_for_attrs_finds_by_class;s
zQTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_classcCs�|jd�}|jd�\}}|j||g|jdd��|j|g|jdd��|j|g|jddd��|j|g|jdd��|jg|jdd��dS)Nz*<a class="foo bar"></a><a class="foo"></a>r/rBr3zfoo bar)rozbar foo)r$r-r)rr$r/Za2rrr�:test_find_all_with_string_for_attrs_finds_multiple_classesKs
zQTestFindAllByAttribute.test_find_all_with_string_for_attrs_finds_multiple_classescCs0|jd�}tddid�}|j|j|�dg�dS)Nzi
                         <a id="first">Match.</a>
                         <a id="second">Non-match.</a>rre)rMzMatch.)r$rrr-)rrS�strainerrrr�'test_find_all_by_attribute_soupstrainerWsz>TestFindAllByAttribute.test_find_all_by_attribute_soupstrainercCs&|jd�}|j|jddd�dg�dS)Nz�<a id="1">ID present.</a>
                            <a>No ID present.</a>
                            <a id="">ID is empty.</a>r/)rzNo ID present.)r$rr-)rrSrrr�$test_find_all_with_missing_attribute_sz;TestFindAllByAttribute.test_find_all_with_missing_attributecCs&|jd�}|j|jdd�ddg�dS)Nz�<a id="1">ID present.</a>
                            <a>No ID present.</a>
                            <a id="">ID is empty.</a>T)rzID present.zID is empty.)r$rr-)rrSrrr�$test_find_all_with_defined_attributegsz;TestFindAllByAttribute.test_find_all_with_defined_attributecCs>|jd�}ddg}|j|jdd�|�|j|jdd�|�dS)Nz[<a id=1>Unquoted attribute.</a>
                            <a id="1">Quoted attribute.</a>zUnquoted attribute.zQuoted attribute.r=)rr;)r$rr-)rrSZexpectedrrr�$test_find_all_with_numeric_attributeps
z;TestFindAllByAttribute.test_find_all_with_numeric_attributecCs,|jd�}|j|jdddgd�ddg�dS)Nz�<a id="1">1</a>
                            <a id="2">2</a>
                            <a id="3">3</a>
                            <a>No ID.</a>r;r<r?)r)r$rr-)rrSrrr�(test_find_all_with_list_attribute_valuesysz?TestFindAllByAttribute.test_find_all_with_list_attribute_valuescCs,|jd�}|j|jtjd�d�ddg�dS)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+$)rzOne a.zTwo as.)r$rr-r6r7)rrSrrr�5test_find_all_with_regular_expression_attribute_value�szLTestFindAllByAttribute.test_find_all_with_regular_expression_attribute_valuecCsX|jd�}|j}|j|g|jddd��|jg|jddd��|jg|jddd��dS)Nz<b>foo</b><b>bar</b><a>foo</a>r/rB)r)r3)r$r/rr-)rr$r/rrr�'test_find_by_name_and_containing_string�s

z>TestFindAllByAttribute.test_find_by_name_and_containing_stringcCs*|jd�}|j|jd�|jddd��dS)Nz"<a>foo</a><a><b><c>foo</c></b></a>r/rB)r))r$rr-)rr$rrr�=test_find_by_name_and_containing_string_when_string_is_buried�s
zTTestFindAllByAttribute.test_find_by_name_and_containing_string_when_string_is_buriedcCsB|jd�}|j}|j|g|jddd��|jg|jddd��dS)Nz"<b id="1">foo</b><a id="2">foo</a>r+rB)rr)r=r3)r$r/rr-)rr$r/rrr�,test_find_by_attribute_and_containing_string�s
zCTestFindAllByAttribute.test_find_by_attribute_and_containing_stringN)rrr rfrlrnrprsrwrxrzr{r|r}r~rr�r�r�rrrrrd�s 		

rdc@seZdZdZdd�ZdS)�	TestIndexzTest Tag.indexcCsN|jd�}|j}x(t|j�D]\}}|j||j|��qW|jt|jd�dS)Nah<div>
                            <a>Identical</a>
                            <b>Not identical</b>
                            <a>Identical</a>

                            <c><d>Identical with child</d></c>
                            <b>Also not identical</b>
                            <c><d>Identical with child</d></c>
                            </div>r=)r$ra�	enumerate�contentsr�index�assertRaises�
ValueError)rrSra�i�elementrrr�
test_index�szTestIndex.test_indexN)rrr r1r�rrrrr��sr�cs`eZdZdZ�fdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Z�Z
S)�TestParentOperationsz;Test navigation and searching through an element's parents.cs(tt|�j�|jd�|_|jj|_dS)Na1<ul id="empty"></ul>
                                 <ul id="top">
                                  <ul id="middle">
                                   <ul id="bottom">
                                    <b>Start here</b>
                                   </ul>
                                  </ul>)rQr�rRr$rSr"�start)r)rTrrrR�szTestParentOperations.setUpcCsF|j|jjdd�|j|jjjdd�|j|jjjjdd�dS)Nr�bottom�middle�top)rr��parent)rrrr�test_parent�sz TestParentOperations.test_parentcCs |jjd}|j|j|j�dS)Nr)rSr�rr�)rZtop_tagrrr�%test_parent_of_top_tag_is_soup_object�sz:TestParentOperations.test_parent_of_top_tag_is_soup_objectcCs|jd|jj�dS)N)rrSr�)rrrr�test_soup_object_has_no_parent�sz3TestParentOperations.test_soup_object_has_no_parentcCs8|j|jjd�dddg�|j|jjddd�dg�dS)N�ulr�r�r�)r)rr�Zfind_parents)rrrr�test_find_parents�sz&TestParentOperations.test_find_parentscCs8|j|jjd�dd�|j|jjddd�dd�dS)Nr�rr�r�)r)rr��find_parent)rrrr�test_find_parent�sz%TestParentOperations.test_find_parentcCs"|jjdd�}|j|jjd�dS)Nz
Start here)r)r")rSr%rr�rN)rr)rrr�test_parent_of_text_element�sz0TestParentOperations.test_parent_of_text_elementcCs(|jjdd�}|j|jd�dd�dS)Nz
Start here)r)r�rr�)rSr%rr�)rr)rrr�test_text_element_find_parent�sz2TestParentOperations.test_text_element_find_parentcCs(dd�|jjD�}|j|dddg�dS)NcSs&g|]}|dk	rd|jkr|d�qS)Nr)rM)rr�rrrr�sz>TestParentOperations.test_parent_generator.<locals>.<listcomp>r�r�r�)r��parentsr)rr�rrr�test_parent_generator�sz*TestParentOperations.test_parent_generator)rrr r1rRr�r�r�r�r�r�r�r�rcrr)rTrr��sr�cseZdZ�fdd�Z�ZS)�
ProximityTestcstt|�j�|jd�|_dS)Nzg<html id="start"><head></head><body><b id="1">One</b><b id="2">Two</b><b id="3">Three</b></body></html>)rQrrRr$rS)r)rTrrrR�szProximityTest.setUp)rrr rRrcrr)rTrr��sr�csTeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
�ZS)�TestNextOperationscstt|�j�|jj|_dS)N)rQr�rRrSr"r�)r)rTrrrR�szTestNextOperations.setUpcCs*|j|jjd�|j|jjjdd�dS)N�Onerr#)rr��next_element)rrrr�	test_next�szTestNextOperations.test_nextcCs |jjdd�}|j|jd�dS)N�Three)r))rSr%rr�)rZlastrrr�test_next_of_last_item_is_none�sz1TestNextOperations.test_next_of_last_item_is_nonecCs|j|jjd�dS)N)rrSr�)rrrr�test_next_of_root_is_nonesz,TestNextOperations.test_next_of_root_is_nonecCsB|j|jjd�ddg�|jjdd�|j|jjdd�dg�dS)Nr"�Twor�r9)r)rr��
find_all_next)rrrr�test_find_all_nextsz%TestNextOperations.test_find_all_nextcCs2|j|jjd�dd�|j|jjdd�d�dS)Nr"rr#r�)r))rr��	find_next)rrrr�test_find_next
sz!TestNextOperations.test_find_nextcCs<|jjdd�}|j|jd�jd�|j|jd�ddg�dS)Nr�)r)r"r�r�)rSr%rr�rrr�)rr)rrr�test_find_next_for_text_elementsz2TestNextOperations.test_find_next_for_text_elementcCsF|jjdd�}dd�|jD�}|\}}|j|dd�|j|d�dS)Nr�)r)cSsg|]}|�qSrr)r�noderrrrsz:TestNextOperations.test_next_generator.<locals>.<listcomp>rr<r�)rSr%Z
next_elementsr)rr�Z
successorsrr�rrr�test_next_generators
z&TestNextOperations.test_next_generator)rrr rRr�r�r�r�r�r�r�rcrr)rTrr��sr�csTeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
�ZS)�TestPreviousOperationscs"tt|�j�|jjdd�|_dS)Nr�)r))rQr�rRrSr%�end)r)rTrrrRszTestPreviousOperations.setUpcCs*|j|jjdd�|j|jjjd�dS)Nrr<r�)rr��previous_element)rrrr�
test_previous!sz$TestPreviousOperations.test_previouscCs|jjd�}|j|jd�dS)N�html)rSr%rr�)rrerrr�#test_previous_of_first_item_is_none%sz:TestPreviousOperations.test_previous_of_first_item_is_nonecCsdS)Nr)rrrr�test_previous_of_root_is_none)sz4TestPreviousOperations.test_previous_of_root_is_nonecCs6|j|jjd�dddg�|j|jjdd�dg�dS)Nr"r�r�r�r=)r)rr��find_all_previous)rrrr�test_find_all_previous/sz-TestPreviousOperations.test_find_all_previouscCs2|j|jjd�dd�|j|jjdd�d�dS)Nr"rr<r�)r))rr��
find_previous)rrrr�test_find_previous7sz)TestPreviousOperations.test_find_previouscCs>|jjdd�}|j|jd�jd�|j|jd�dddg�dS)Nr�)r)r"r�r�)rSr%rr�rrr�)rr)rrr�#test_find_previous_for_text_element;sz:TestPreviousOperations.test_find_previous_for_text_elementcCsh|jjdd�}dd�|jD�}|\}}}}|j|dd�|j|jd�|j|jd�|j|jd	�dS)
Nr�)r)cSsg|]}|�qSrr)rr�rrrrCszBTestPreviousOperations.test_previous_generator.<locals>.<listcomp>rr;�body�headr�)rSr%Zprevious_elementsrrN)rr�Zpredecessorsr"r�r�r�rrr�test_previous_generatorAsz.TestPreviousOperations.test_previous_generator)rrr rRr�r�r�r�r�r�r�rcrr)rTrr�sr�cseZdZ�fdd�Z�ZS)�SiblingTestcs4tt|�j�d}tjd�jd|�}|j|�|_dS)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*�)rQr�rRr6r7�subr$rS)r�markup)rTrrrRPszSiblingTest.setUp)rrr rRrcrr)rTrr�Nsr�csLeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	�Z
S)�TestNextSiblingcs"tt|�j�|jjdd�|_dS)Nr;)r)rQr�rRrSr%r�)r)rTrrrRfszTestNextSibling.setUpcCs|j|jjd�dS)N)rrS�next_sibling)rrrr�!test_next_sibling_of_root_is_nonejsz1TestNextSibling.test_next_sibling_of_root_is_nonecCsB|j|jjdd�|j|jjjdd�|j|jjdd�dS)Nrr#r<z1.1)rr�r�r�)rrrr�test_next_siblingmsz!TestNextSibling.test_next_siblingcCsN|j|jjjd�|jjdd�}|j|jd�|jjdd�}|j|jd�dS)Nz1.1)rr?)rrSr�r�r%)r�nested_spanZ	last_spanrrr�test_next_sibling_may_not_existts
z/TestNextSibling.test_next_sibling_may_not_existcCs|j|jjd�dd�dS)N�spanrr#)rr��find_next_sibling)rrrr�test_find_next_sibling}sz&TestNextSibling.test_find_next_siblingcCs6|j|jjd�dddg�|j|jjdd�dg�dS)Nr�r#r<r?)r)rr��find_next_siblings)rrrr�test_next_siblings�sz"TestNextSibling.test_next_siblingscCsv|jd�}|jdd�}|j|jjd�|j|jjd�|j|jd�dg�|j|jdd�d�|j|jdd�d�dS)NzFoo<b>bar</b>bazr4)r)r"�bazr3�nonesuch)r$r%rr�rNrr�r�)rr$r�rrr�"test_next_sibling_for_text_element�s
z2TestNextSibling.test_next_sibling_for_text_element)rrr rRr�r�r�r�r�r�rcrr)rTrr�ds	r�csLeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	�Z
S)�TestPreviousSiblingcs"tt|�j�|jjdd�|_dS)Nr?)r)rQr�rRrSr%r�)r)rTrrrR�szTestPreviousSibling.setUpcCs|j|jjd�dS)N)rrS�previous_sibling)rrrr�%test_previous_sibling_of_root_is_none�sz9TestPreviousSibling.test_previous_sibling_of_root_is_nonecCsB|j|jjdd�|j|jjjdd�|j|jjdd�dS)Nrr<r#z3.1)rr�r�r�)rrrr�test_previous_sibling�sz)TestPreviousSibling.test_previous_siblingcCsN|j|jjjd�|jjdd�}|j|jd�|jjdd�}|j|jd�dS)Nz1.1)rr;)rrSr�r�r%)rr�Z
first_spanrrr�#test_previous_sibling_may_not_exist�s
z7TestPreviousSibling.test_previous_sibling_may_not_existcCs|j|jjd�dd�dS)Nr�rr<)rr��find_previous_sibling)rrrr�test_find_previous_sibling�sz.TestPreviousSibling.test_find_previous_siblingcCs6|j|jjd�dddg�|j|jjdd�dg�dS)Nr�r<r#r;)r)rr��find_previous_siblings)rrrr�test_previous_siblings�sz*TestPreviousSibling.test_previous_siblingscCsv|jd�}|jdd�}|j|jjd�|j|jjd�|j|jd�dg�|j|jdd�d�|j|jdd�d�dS)NzFoo<b>bar</b>bazr�)r)r"r4r3r�)r$r%rr�rNrr�r�)rr$r�rrr�&test_previous_sibling_for_text_element�s
z:TestPreviousSibling.test_previous_sibling_for_text_element)rrr rRr�r�r�r�r�r�rcrr)rTrr��s	r�c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�TestTagCreationz$Test the ability to create new tags.cCsd|jd�}|jddddid�}|jt|t��|jd|j�|jtddd�|j�|jd|j	�dS)Nr�rBr�rNza name)r3rM)r3rN)
r$�new_tagrH�
isinstancer
rrN�dictrMr�)rr$r�rrr�test_new_tag�s
zTestTagCreation.test_new_tagcCs�trBtdd�}|jd�}|jd�}|jd|j��|jd|j��tdd�}|jd�}|jd�}|jd|j��|jd|j��dS)	Nr�zlxml-xml�br�ps<br/>s<p/>zhtml.parsers<p></p>)�XML_BUILDER_PRESENTrr�rri)rZxml_soupZxml_brZxml_pZ	html_soupZhtml_brZhtml_prrr�1test_tag_inherits_self_closing_rules_from_builder�s





zATestTagCreation.test_tag_inherits_self_closing_rules_from_buildercCs4|jd�}|jd�}|jd|�|jt|t��dS)Nr�rB)r$�
new_stringrrHr�r)rr$�srrr�'test_new_string_creates_navigablestring�s

z7TestTagCreation.test_new_string_creates_navigablestringcCs6|jd�}|jdt�}|jd|�|jt|t��dS)Nr�rB)r$r�rrrHr�)rr$r�rrr�3test_new_string_can_create_navigablestring_subclass�s
zCTestTagCreation.test_new_string_can_create_navigablestring_subclassN)rrr r1r�r�r�r�rrrrr��s
r�c@s<eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d?d@�Z"dAdB�Z#dCdD�Z$dEdF�Z%dGdH�Z&dIdJ�Z'dKdL�Z(dMS)N�TestTreeModificationcCsl|jd�}d|jd<|j|j�|jd��|jd=|j|j�|jd��d|jd<|j|j�|jd��dS)	Nz<a id="1"></a>r+rz<a id="2"></a>z<a></a>rBZid2z<a id2="foo"></a>)r$r/rrj�document_for)rr$rrr�test_attribute_modification�s


z0TestTreeModification.test_attribute_modificationcCsltjd��}|jd|d�}t||d�}t||d�}d|d<|jjd|�|jjd	|�|j|jj�d
�dS)Nr�z
<body></body>)�builderr/�olzhttp://foo.com/Zhrefrr=s4<body><a href="http://foo.com/"></a><ol></ol></body>)r�lookupr$r
r��insertrri)rr�r$r/r�rrr�test_new_tag_creation�sz*TestTreeModification.test_new_tag_creationcCs\d}|j|�}|jdd�}|j}|jdd�j|j�|j|j|�|j|j�|jd��dS)NzT<p id="1">Don't leave me <b>here</b>.</p>
                <p id="2">Don't leave!</p>r#)rzD<p id="1">Don't leave me .</p>
<p id="2">Don't leave!<b>here</b></p>)r$r%r"rDrr�rjr�)r�docr$Zsecond_paraZboldrrr�!test_append_to_contents_moves_tag�s

z6TestTreeModification.test_append_to_contents_moves_tagcCs0d}|j|�}|j}|j|j�}|j||�dS)Nz<a></a><b><c></c></b>)r$r/�replace_withrWr)rr)r$r/�new_arrr�1test_replace_with_returns_thing_that_was_replaceds

zFTestTreeModification.test_replace_with_returns_thing_that_was_replacedcCs,d}|j|�}|j}|j�}|j||�dS)Nz<a><b></b><c></c></a>)r$r/�unwrapr)rr)r$r/r�rrr�+test_unwrap_returns_thing_that_was_replaceds

[email protected]_unwrap_returns_thing_that_was_replacedcCsJ|jd�}|j}|j�|jd|j�|jt|j�|jt|j|j	�dS)Nz<a><b>Foo</b></a><c>Bar</c>)
r$r/�extractrr�r�r�r�r�rW)rr$r/rrr�Itest_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parents
z^TestTreeModification.test_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parentcCs:d}|j|�}|j}|jj|�|j|j�|j|��dS)Nz-<a><b></b><c>Foo<d></d></c></a><a><e></e></a>)r$rWr�rrjr�)rr)r$rWrrr�test_replace_tag_with_itself's

z1TestTreeModification.test_replace_tag_with_itselfcCs&d}|j|�}|jt|jj|j�dS)Nz<a><b></b></a>)r$r�r�r"r�r/)rr)r$rrr�1test_replace_tag_with_its_parent_raises_exception.s
zFTestTreeModification.test_replace_tag_with_its_parent_raises_exceptioncCs(d}|j|�}|jt|jjd|j�dS)Nz<a><b></b></a>r)r$r�r�r/r�)rr)r$rrr�,test_insert_tag_into_itself_raises_exception3s
zATestTreeModification.test_insert_tag_into_itself_raises_exceptionc	Cs�|jd�}d}|j|�}|jd|�x|jD]}t|t�s,t�q,Wt|j�\}}}}|jd|j	�|jd|j	�|jd|j	�|jd|j	�dS)	z�Inserting one BeautifulSoup object into another actually inserts all
        of its children -- you'll never combine BeautifulSoup objects.
        z-<p>And now, a word:</p><p>And we're back.</p>z<p>p2</p><p>p3</p>r=zAnd now, a word:�p2�p3zAnd we're back.N)
r$r�Zdescendantsr�r�AssertionError�listZchildrenrr)	rr$r)Z	to_insertr��p1r�r�Zp4rrr�1test_insert_beautifulsoup_object_inserts_children8s

zFTestTreeModification.test_insert_beautifulsoup_object_inserts_childrencCsX|jd�}|j}|jd}|jdd�|j\}}|jd�|jd�|jd|jj�dS)Nz<p><a>one</a><b>three</b></p>rr=Ztwor�Zthree)r$r/r�r�ZreplaceWithrr"r)rr$r/r"�left�rightrrr�3test_replace_with_maintains_next_element_throughoutLs




zHTestTreeModification.test_replace_with_maintains_next_element_throughoutcCsl|jd�}|jdd�jd�|jdd�}|j}|j|j|�|j|j|�|j|jj|�|j|jd�dS)Nz<b>Argh!</b>zArgh!)r)zHooray!)r$r%r�r"rr�r�r�)rr$�new_textr"rrr�test_replace_final_node[s
z,TestTreeModification.test_replace_final_nodecCs�|jd�}|jjdd�|j|j�|jd��|jdd�}|j|jd�|j|jj|�|j|j	d�|j|j	j
|�|j|j
d�|j|j|j�dS)Nz<a><b>Argh!</b><c></c></a>r=zHooray!z!<a><b>Argh!Hooray!</b><c></c></a>)r)zArgh!)r$r"r�rrjr�r%r�r�r�r�rW)rr$rrrr�test_consecutive_text_nodeses

z0TestTreeModification.test_consecutive_text_nodescCsT|jd�}|jjdd�|jjdd�|jddg|jj�|j|jjdjd�dS)Nz<a></a>rr3rB)r$r/r�rr�r�)rr$rrr�test_insert_stringzs

z'TestTreeModification.test_insert_stringcCs�|j}|jd|d�}t||d�}|jdd�|jjd|�|j|j�|jd��|j}|j|j	|�|j|j
|�|jdd	�}|j|j|�|j|j
|�|j}|j|j	|�|j|j
|�|jdd	�}|j|j|�|j|j|�|j|j
|�dS)
Nz%<a><b>Find</b><c>lady!</c><d></d></a>)r�Zmagictagr�ther=z=<a><b>Find</b><magictag>the</magictag><c>lady!</c><d></d></a>ZFind)r))Zdefault_builderr$r
r�r/rrjr�r"r�r�r%r�r�rWr�)rr�r$Z	magic_tagZb_tagr%Zc_tagrrrr�test_insert_tag�s,

z$TestTreeModification.test_insert_tagcCs0d}|j|�}|jj|j�|j||j��dS)Nz<a><b></b></a>)r$r/rDr"rrj)rrkr$rrr�*test_append_child_thats_already_at_the_end�s
z?TestTreeModification.test_append_child_thats_already_at_the_endcCs2d}|j|�}|jjd|j�|jd|j��dS)Nz<a><b></b><c></c><d></d></a>rz<a><d></d><b></b><c></c></a>)r$r/r��drrj)rrkr$rrr�$test_move_tag_to_beginning_of_parent�s
z9TestTreeModification.test_move_tag_to_beginning_of_parentcCs.|jd�}|jjdd�|jt|j�d�dS)Nz<br/>r=ZContentsz<br>Contents</br>)r$r�r�rr()rr$rrr�&test_insert_works_on_empty_element_tag�s
z;TestTreeModification.test_insert_works_on_empty_element_tagcCs`|jd�}|jjd�|jjd�|j|j�|jd��|jj|j�|j|j�|jd��dS)Nz<a>foo</a><b>bar</b>�BAZ�QUUXzQUUX<a>foo</a>BAZ<b>bar</b>zQUUX<b>bar</b><a>foo</a>BAZ)r$r"�
insert_beforer/rrjr�)rr$rrr�test_insert_before�s
z'TestTreeModification.test_insert_beforecCs`|jd�}|jjd�|jjd�|j|j�|jd��|jj|j�|j|j�|jd��dS)Nz<a>foo</a><b>bar</b>rr
z<a>foo</a>QUUX<b>bar</b>BAZzQUUX<b>bar</b><a>foo</a>BAZ)r$r"�insert_afterr/rrjr�)rr$rrr�test_insert_after�s
z&TestTreeModification.test_insert_aftercCsR|jd�}|jd�}|jd�}|jt|j|�|jt|j|�|jt|j|�dS)Nr�r/)r$r�r�r�r�r�NotImplementedError)rr$rrrrr�:test_insert_after_raises_exception_if_after_has_no_meaning�s


zOTestTreeModification.test_insert_after_raises_exception_if_after_has_no_meaningcCsR|jd�}|jd�}|jd�}|jt|j|�|jt|j|�|jt|j|�dS)Nr�r/)r$r�r�r�r�rr)rr$rrrrr�Ftest_insert_before_raises_notimplementederror_if_before_has_no_meaning�s


z[TestTreeModification.test_insert_before_raises_notimplementederror_if_before_has_no_meaningcCsv|jd�}|jd�\}}|j|�|j|j�|jd��|j|jd�|j|j|j�|j|jd�|j|j	d�dS)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�rrjr�r�r�r�r�)rr$rZshowrrr�test_replace_with�s
z&TestTreeModification.test_replace_withcCs0d}|j|�}|jj|j�|jd|j��dS)Nz<a><b></b><c></c></a>z<a><c></c></a>)r$r"r�rWrrj)rrkr$rrr�test_replace_first_child�s
z-TestTreeModification.test_replace_first_childcCs0d}|j|�}|jj|j�|jd|j��dS)Nz<a><b></b><c></c></a>z<a><b></b></a>)r$rWr�r"rrj)rrkr$rrr�test_replace_last_child�s
z,TestTreeModification.test_replace_last_childcCs|jd�}|j}|j}|j|�|j|j�|jd��|j|jd�|j|jdd�j	d�|j|j
d�|j|jd�|j|jd�|j|j|j
�|j|j
d�|j|j	j	|j�|j|jd�|jdd�}|j}|j|j	|�|j|j|�|j|j
|�|j|j|�dS)NzQ<a>We<b>reserve<c>the</c><d>right</d></b></a><e>to<f>refuse</f><g>service</g></e>z-<a>We<f>refuse</f></a><e>to<g>service</g></e>r)r)ZWeZto)r$r"rrr�rrjr�r�r%r�r�r�r�r/�e�g)rr$Z
remove_tagZmove_tagZto_textZg_tagrrr�test_nested_tag_replace_with�s.

z1TestTreeModification.test_nested_tag_replace_withcCs6|jd�}|jj�|j|jd�|j|jjd�dS)NzI
            <p>Unneeded <em>formatting</em> is unneeded</p>
            zUnneeded formatting is unneeded)r$�emr�rr�r))rrSrrr�test_unwraps

z TestTreeModification.test_unwrapcCsF|jd�}|jj|jd��}|j|j�d�|j|j�|jd��dS)NzI wish I was bold.r"z<b>I wish I was bold.</b>)r$r�wrapr�rrjr�)rr$rtrrr�	test_wrap"s

zTestTreeModification.test_wrapcCs4|jd�}|jjj|j�|j|j�|jd��dS)Nz<b></b>I wish I was bold.z<b>I wish I was bold.</b>)r$r"r�rrrjr�)rr$rrr�%test_wrap_extracts_tag_from_elsewhere)s
z:TestTreeModification.test_wrap_extracts_tag_from_elsewherecCsH|jd�}|jjj|j�|jdt|jj��|j|j�|jd��dS)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�rrr,r�rjr�)rr$rrr�&test_wrap_puts_new_contents_at_the_end/s

z;TestTreeModification.test_wrap_puts_new_contents_at_the_endcCs�|jd�}|jt|jj�d�|jdd�j�}|j|j�d�|j|j�d�|jt|jj�d�|j|jd�|j|j	d�|j|j
j
d�|jdd	�}|jd
d	�}|j|j
|�|j|j|�|j|j	|�|j|j|�dS)NzR<html><body>Some content. <div id="nav">Nav crap</div> More content.</body></html>r9Znav)rz6<html><body>Some content.  More content.</body></html>z<div id="nav">Nav crap</div>r+zSome content. )r)z More content.)
r$rr,r�r�r%r�rjr�r�r�r�r�)rr$Z	extractedZ	content_1Z	content_2rrr�test_extract7s"z!TestTreeModification.test_extractcCsz|jd�}|jj}|jj}|jd�}|jd�}|jj|�|jj|�|j�|j�|j||jj�|j||jj�dS)Nz<a>foo</a><b>bar</b>rBr3)r$r/rr"r�rDr�r)rr$Zfoo_1Zbar_1Zfoo_2Zbar_2rrr�4test_extract_distinguishes_between_identical_stringsPs


zITestTreeModification.test_extract_distinguishes_between_identical_stringscs8|jd���fdd��jd�D�|jdt�j��dS)Nzv
<html>
<head>
<script>foo</script>
</head>
<body>
 <script>bar</script>
 <a></a>
</body>
<script>baz</script>
</html>csg|]}�jj��qSr)�scriptr�)rr�)r$rrrmszKTestTreeModification.test_extract_multiples_of_same_tag.<locals>.<listcomp>r$z<body>

<a></a>
</body>)r$r-rr(r�)rr)r$r�"test_extract_multiples_of_same_tagas
z7TestTreeModification.test_extract_multiples_of_same_tagcCs.|jd�}|jd�j�|jd|jd��dS)Nz<html>
<body>hi</body>
</html>r�)r$r%r�r)rr$rrr�Btest_extract_works_when_element_is_surrounded_by_identical_stringsqszWTestTreeModification.test_extract_works_when_element_is_surrounded_by_identical_stringscCsf|jd�}|j}|jj�|jt|jj�d�|jt|d��|j	}|jdd�|jdt|j��dS)zTag.clear()z4<p><a>String <em>Italicized</em></a> and another</p>rr�T)Z	decomposeN)
r$r/r��clearrr,r�rHrIr)rr$r/rrrr�
test_clearzs

zTestTreeModification.test_clearcCsB|jd�}d|j_|j|jjdg�d|j_|j|jjdg�dS)zTag.string = 'string'z<a></a> <b><c></c></b>rBr3N)r$r/rrr�r")rr$rrr�test_string_set�s

z$TestTreeModification.test_string_setcCs,|jd�}|jj|j_|j|jj�d�dS)Nz<a><b>foo</b><c>bar</c>s<a><b>bar</b><c>bar</c></a>)r$rWrr"rr/ri)rr$rrr�/test_string_set_does_not_affect_original_string�s
zDTestTreeModification.test_string_set_does_not_affect_original_stringcCs2|jd�}td�}||j_|jt|jjt��dS)Nz<a></a>rB)r$rr/rrHr�)rr$�cdatarrr�)test_set_string_preserves_class_of_string�s
z>TestTreeModification.test_set_string_preserves_class_of_stringN))rrr r�r�r�r�r�r�r�r�r�r�rrrrrrr
rrrrrrrrrrrr r!r"r#r%r&r(r)r*r,rrrrr��sL	
		
$	r�c@sxeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�ZdS)�TestElementObjectsz)Test various features of element objects.cCsV|jd�}|jt|j�d�|jt|�d�|jt|j�d�|jt|jj�d�dS)z3The length of an element is its number of children.z<top>1<b>2</b>3</top>r=r9N)r$rr,r�r�)rr$rrr�test_len�s

zTestElementObjects.test_lencCsL|jd�}|j|j|jd��|j|jj|jd�jd��|j|jd�dS)z2Accessing a Python member .foo invokes find('foo')z<b><i></i></b>r"r�N)r$rr"r%r�r/)rr$rrr�test_member_access_invokes_find�s
z2TestElementObjects.test_member_access_invokes_findcCsP|jd�}tjdd��}|j}WdQRX|j|j|�|jdt|dj��dS)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_warningsZbTagrr"r(�message)rr$�wrrrr�test_deprecated_member_access�s
z0TestElementObjects.test_deprecated_member_accesscCs2|jd�}|j|jjd��|j|jjd��dS)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'>�attrZattr2N)r$rHrB�has_attr�assertFalse)rr$rrr�
test_has_attr�s
z TestElementObjects.test_has_attrcCsd}|j|d�dS)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>)ZassertSoupEquals)rr�rrr�.test_attributes_come_out_in_alphabetical_order�szATestElementObjects.test_attributes_come_out_in_alphabetical_ordercCs|jd�}|j|jjd�dS)Nz
<b>foo</b>rB)r$rr"r)rr$rrr�test_string�s
zTestElementObjects.test_stringcCs|jd�}|j|jjd�dS)Nz<b></b>)r$rr"r)rr$rrr�test_empty_tag_has_no_string�s
z/TestElementObjects.test_empty_tag_has_no_stringcCs`|jd�}|j|jjd�|jd�}|j|jjd�|jd�}|jjdd�|j|jjd�dS)Nz<a>foo<b></b><b></b></b>z<a>foo<b></b>bar</b>z
<a>foo</b>r=r3)r$rr"rr/r�)rr$rrr�-test_tag_with_multiple_children_has_no_string�s


[email protected]_tag_with_multiple_children_has_no_stringcCs,|jd�}|j|jjd�|j|jd�dS)Nz<a><b>foo</b></a>rB)r$rr/r)rr$rrr�)test_tag_with_recursive_string_has_string�s
z<TestElementObjects.test_tag_with_recursive_string_has_stringcCs4|jd�}|j|jj�|jd�}|j|jj�dS)z7Only a tag containing a single text node has a .string.z<b>f<i>e</i>o</b>z<b></b>N)r$r8r"r)rr$rrr�test_lack_of_string�s

z&TestElementObjects.test_lack_of_stringcCs`|jd�}|j|jjd�|j|jjdd�d�|j|jjd�d�|j|jjddd�d�d	S)
zBTag.text and Tag.get_text(sep=u"") -> all child text, concatenatedz<a>a<b>r</b>   <r> t </r></a>zar  t T)�stripZart�,z	a,r, , t za,r,tN)r$rr/r)�get_text)rr$rrr�
test_all_text�s

z TestElementObjects.test_all_textcCsJ|jd�}|j|j�d�|j|jttfd�d�|j|jdd�d�dS)Nzfoo<!--IGNORE-->barZfoobar)�typesZfooIGNOREbar)r$rrBrr)rr$rrr�test_get_text_ignores_comments�s
z1TestElementObjects.test_get_text_ignores_commentscCs$|jd�}|jddgt|j��dS)Nzfoo<!--IGNORE-->barrBr3)r$rr�Zstrings)rr$rrr�!test_all_strings_ignores_commentss
z4TestElementObjects.test_all_strings_ignores_commentsN)rrr r1r.r/r5r9r:r;r<r=r>r?rCrErFrrrrr-�s		r-c@sPeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�ZdS)�TestCDAtaListAttributesz0Testing cdata-list attributes like 'class'.
    cCs"|jd�}|jdg|jd�dS)Nz<a class='foo'>rBrm)r$rr/)rr$rrr�test_single_value_becomes_list
s
z6TestCDAtaListAttributes.test_single_value_becomes_listcCs$|jd�}|jddg|jd�dS)Nz<a class='foo bar'>rBr3rm)r$rr/)rr$rrr�!test_multiple_values_becomes_lists
z9TestCDAtaListAttributes.test_multiple_values_becomes_listcCs&|jd�}|jdddg|jd�dS)Nz<a class='foo	bar
baz'>rBr3r�rm)r$rr/)rr$rrr�2test_multiple_values_separated_by_weird_whitespaces
zJTestCDAtaListAttributes.test_multiple_values_separated_by_weird_whitespacecCs |jd�}|jd|jj��dS)Nz<a class='foo	bar'>s<a class="foo bar"></a>)r$rr/ri)rr$rrr�,test_attributes_joined_into_string_on_outputs
zDTestCDAtaListAttributes.test_attributes_joined_into_string_on_outputcCs$|jd�}|jdg|jjd��dS)Nz<a id='abc def'>zabc defr)r$rr/Zget_attribute_list)rr$rrr�test_get_attribute_lists
z/TestCDAtaListAttributes.test_get_attribute_listcCs$|jd�}|jddg|jd�dS)Nz(<form accept-charset="ISO-8859-1 UTF-8">z
ISO-8859-1zUTF-8zaccept-charset)r$rZform)rr$rrr�test_accept_charset!s
z+TestCDAtaListAttributes.test_accept_charsetcCs$d}|j|�}|jd|jd�dS)Nz)<a accept-charset="ISO-8859-1 UTF-8"></a>zISO-8859-1 UTF-8zaccept-charset)r$rr/)rrkr$rrr�-test_cdata_attribute_applying_only_to_one_tag%s
zETestCDAtaListAttributes.test_cdata_attribute_applying_only_to_one_tagcs6|jd�j�|jd�j��fdd�}|jt|�dS)Nr�cs
d�_dS)NrB)rNr)rrr�t0szJTestCDAtaListAttributes.test_string_has_immutable_name_property.<locals>.t)r$rrrNr��AttributeError)rrOr)rr�'test_string_has_immutable_name_property-sz?TestCDAtaListAttributes.test_string_has_immutable_name_propertyN)rrr r1rHrIrJrKrLrMrNrQrrrrrG	srGcs`eZdZdZ�fdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Z�Z
S)�TestPersistencez*Testing features like pickle and deepcopy.cs&tt|�j�d|_|j|j�|_dS)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:[email protected]">
<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>)rQrRrRZpager$rS)r)rTrrrR7szTestPersistence.setUpcCs@tj|jd�}tj|�}|j|jt�|j|j�|jj��dS)Nr+)�pickle�dumpsrS�loadsrrTrrj)r�dumped�loadedrrr�!test_pickle_and_unpickle_identityKs
z1TestPersistence.test_pickle_and_unpickle_identitycCs&tj|j�}|j|j�|jj��dS)N)�copy�deepcopyrSrrj)rZcopiedrrr�test_deepcopy_identitySsz&TestPersistence.test_deepcopy_identitycCs:tdd�}|j}|j�}|jdt|��|j||j�dS)Ns
<p>&nbsp;</p>zhtml.parseru	<p> </p>)rZoriginal_encoding�__copy__rr()rr$�encodingrYrrr�test_copy_preserves_encodingXs

z,TestPersistence.test_copy_preserves_encodingcCs>d}|j|�}tj|tj�}tj|�}|j|j�|j��dS)Nu
<b>☃</b>)r$rSrTZHIGHEST_PROTOCOLrUrrj)rr�r$rVrWrrr�test_unicode_pickle_s


z#TestPersistence.test_unicode_picklecCszd}|j|�}|jdd�}tj|�}|j||�|jd|j�|jd|j�|jd|j�|jd|j�|jd|j�dS)Nz<b>Foo<a></a></b><b>Bar</b>r4)r)	r$r%rYrr�r��assertNotEqualr�r�)rr�r$�s1�s2rrr�1test_copy_navigablestring_is_not_attached_to_treegs

zATestPersistence.test_copy_navigablestring_is_not_attached_to_treecCs>d}|j|�}|j}tj|�}|j||�|jt|t��dS)Nz<b><!--Foo--></b>)r$rrYrrHr�r)rr�r$rarbrrr�0test_copy_navigablestring_subclass_has_same_typess

[email protected]_copy_navigablestring_subclass_has_same_typecCs(d}|j|�}tj|�}|j||�dS)Nz)<div><b>Foo<a></a></b><b>Bar</b></div>end)r$rYr)rr�r$Z	soup_copyrrr�test_copy_entire_soup{s

z%TestPersistence.test_copy_entire_soupcCs�d}|j|�}|j}tj|�}|jt|�t|��|j||�|j||k�|jd|j�|jd|j�|jd|jdd�j	�|j
d|jdd�j	�dS)Nz)<div><b>Foo<a></a></b><b>Bar</b></div>endZBar)r)r$rarYrr(r8r�r�r%r�r`)rr�r$raZdiv_copyrrr�test_copy_tag_copies_contents�s

z-TestPersistence.test_copy_tag_copies_contents)rrr r1rRrXr[r^r_rcrdrerfrcrr)rTrrR4srRc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!S)"�TestSubstitutionscCs0d}|j|�}|jdd�}|j||jd��dS)Nu#<b>&lt;&lt;Sacré bleu!&gt;&gt;</b>�minimal)�	formatter)r$rjrr�)rr�r$�decodedrrr�!test_default_formatter_is_minimal�s
z3TestSubstitutions.test_default_formatter_is_minimalcCs0d}|j|�}|jdd�}|j||jd��dS)Nu'<br><b>&lt;&lt;Sacré bleu!&gt;&gt;</b>r�)riz.<br/><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>)r$rjrr�)rr�r$rjrrr�test_formatter_html�s
z%TestSubstitutions.test_formatter_htmlcCs0d}|j|�}|jdd�}|j||jd��dS)Nu'<br><b>&lt;&lt;Sacré bleu!&gt;&gt;</b>Zhtml5)riz-<br><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>)r$rjrr�)rr�r$rjrrr�test_formatter_html5�s
z&TestSubstitutions.test_formatter_html5cCs0d}|j|�}|jdd�}|j||jd��dS)Nu#<b>&lt;&lt;Sacré bleu!&gt;&gt;</b>rh)ri)r$rjrr�)rr�r$rjrrr�test_formatter_minimal�s
z(TestSubstitutions.test_formatter_minimalcCs0d}|j|�}|jdd�}|j||jd��dS)Nu#<b>&lt;&lt;Sacré bleu!&gt;&gt;</b>)riu<b><<Sacré bleu!>></b>)r$rjrr�)rr�r$rjrrr�test_formatter_null�s

z%TestSubstitutions.test_formatter_nullcCs4d}|j|�}|jdd�d�}|j||jd��dS)Nz!<b>&lt;foo&gt;</b><b>bar</b><br/>cSs|j�S)N)�upper)�xrrr�<lambda>�sz9TestSubstitutions.test_formatter_custom.<locals>.<lambda>)riz<b><FOO></b><b>BAR</b><br>)r$rjrr�)rr�r$rjrrr�test_formatter_custom�s
z'TestSubstitutions.test_formatter_customcCs�d}|j|�}|j}d}|j||j��|j||jdd��d}|j||jdd��|j||jdd��d}|j||jdd	�d��dS)
Nu%<a href="http://a.com?a=b&c=é">e</a>u)<a href="http://a.com?a=b&amp;c=é">e</a>rh)riz/<a href="http://a.com?a=b&amp;c=&eacute;">e</a>r�u%<a href="HTTP://A.COM?A=B&C=É">E</a>cSs|j�S)N)rp)rqrrrrr�szMTestSubstitutions.test_formatter_is_run_on_attribute_values.<locals>.<lambda>)r$r/rrj)rr�r$r/Zexpect_minimalZexpect_htmlZexpect_upperrrr�)test_formatter_is_run_on_attribute_values�s
z;TestSubstitutions.test_formatter_is_run_on_attribute_valuescCs$d}t|d�j�}|jd|k�dS)NzO
  <script type="text/javascript">
   console.log("< < hey > > ");
  </script>
zhtml.parsers< < hey > >)rrirH)rr��encodedrrr�2test_formatter_skips_script_tag_for_html_documents�szDTestSubstitutions.test_formatter_skips_script_tag_for_html_documentscCs$d}t|d�j�}|jd|k�dS)NzF
  <style type="text/css">
   console.log("< < hey > > ");
  </style>
zhtml.parsers< < hey > >)rrirH)rr�rurrr�1test_formatter_skips_style_tag_for_html_documents�szCTestSubstitutions.test_formatter_skips_style_tag_for_html_documentscCs |jd�}|jd|jj��dS)Nz*<div>  foo  <pre>  	bar
  
  </pre>  baz  z/<div>
 foo
 <pre>  	bar
  
  </pre>
 baz
</div>)r$rra�prettify)rr$rrr�,test_prettify_leaves_preformatted_text_alone�s
z>TestSubstitutions.test_prettify_leaves_preformatted_text_alonecCs,tdd�}|jdd�d�}|jd|k�dS)Nz<html><body>foo</body></html>zhtml.parsercSs|j�S)N)rp)rqrrrrr�szLTestSubstitutions.test_prettify_accepts_formatter_function.<locals>.<lambda>)riZFOO)rrxrH)rr$Zprettyrrr�(test_prettify_accepts_formatter_function�s
z:TestSubstitutions.test_prettify_accepts_formatter_functioncCs"|jd�}|jtt|j���dS)Nz<a></a>)r$rr(�typerx)rr$rrr�(test_prettify_outputs_unicode_by_default�s
z:TestSubstitutions.test_prettify_outputs_unicode_by_defaultcCs$|jd�}|jtt|jd���dS)Nz<a></a>zutf-8)r$r�bytesr{rx)rr$rrr�test_prettify_can_encode_datas
z/TestSubstitutions.test_prettify_can_encode_datacCs0d}|j|�}|jjd�}|j||jd��dS)Nu<b>Sacré bleu!</b>zutf-8)r$r"rir)rr�r$rurrr�,test_html_entity_substitution_off_by_defaults
z>TestSubstitutions.test_html_entity_substitution_off_by_defaultcCs�d}|j|�}|j|jdd�|jd�}|jd|k�|jd�}|jd|k�|jd�}|jd	|k�|jd
�jd
�}|jd|k�dS)NzE<meta content="text/html; charset=x-sjis" http-equiv="Content-type"/>Zcontentztext/html; charset=x-sjiszutf-8s
charset=utf-8�euc_jpscharset=euc_jpz	shift-jisscharset=shift-jiszutf-16zcharset=utf-16)r$r�metarirHrj)rZmeta_tagr$�utf_8r��	shift_jisZutf_16_urrr�test_encoding_substitutions



z,TestSubstitutions.test_encoding_substitutioncCs2d}td�}|j||d�}|j|jdjd�dS)Nz`<head><meta content="text/html; charset=x-sjis" http-equiv="Content-type"/></head><pre>foo</pre>Zpre)Z
parse_onlyr)rr$rr�rN)rr�ryr$rrr�;test_encoding_substitution_doesnt_happen_if_tag_is_strained$szMTestSubstitutions.test_encoding_substitution_doesnt_happen_if_tag_is_strainedN)rrr rkrlrmrnrorsrtrvrwryrzr|r~rr�r�rrrrrg�s 

	
		rgc@sPeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�ZdS)�TestEncodingz0Test the ability to encode objects into strings.cCs.d}|j|�}|j|jjjd�djd��dS)Nu
<b>☃</b>zutf-8u☃)r$rr"rri)rr�r$rrr�"test_unicode_string_can_be_encoded2s
z/TestEncoding.test_unicode_string_can_be_encodedcCs,d}|j|�}|j|jjd�|jd��dS)Nu
<b>☃</b>zutf-8)r$rr"ri)rr�r$rrr�1test_tag_containing_unicode_string_can_be_encoded8s
z>TestEncoding.test_tag_containing_unicode_string_can_be_encodedcCs&d}|j|�}|j|jjd�d�dS)Nu
<b>☃</b>�asciis<b>&#9731;</b>)r$rr"ri)rr�r$rrr�<test_encoding_substitutes_unrecognized_characters_by_default>s
zITestEncoding.test_encoding_substitutes_unrecognized_characters_by_defaultcCs&d}|j|�}|jt|jddd�dS)Nu
<b>☃</b>r��strict)�errors)r$r��UnicodeEncodeErrorri)rr�r$rrr� test_encoding_can_be_made_strictCs
z-TestEncoding.test_encoding_can_be_made_strictcCs$d}|j|�}|jd|jj��dS)Nu
<b>☃</b>u☃)r$rr"Zdecode_contents)rr�r$rrr�test_decode_contentsIs
z!TestEncoding.test_decode_contentscCs.d}|j|�}|jdjd�|jjdd��dS)Nu
<b>☃</b>u☃rg)r])r$rrir"Zencode_contents)rr�r$rrr�test_encode_contentsNs

z!TestEncoding.test_encode_contentscCs*d}|j|�}|jdjd�|jj��dS)Nu
<b>☃</b>u☃rg)r$rrir"ZrenderContents)rr�r$rrr�test_deprecated_renderContentsUs
z+TestEncoding.test_deprecated_renderContentscCs8d}|j|�}tr$|j|t|��n|jdt|��dS)Nu
<b>☃</b>s
<b>\u2603</b>)r$rr�repr)rr�r$rrr�	test_repr[s

zTestEncoding.test_reprN)rrr r1r�r�r�r�r�r�r�r�rrrrr�/sr�c@s,eZdZdd�Zdd�Zdd�Zdd�Zd	S)
�TestNavigableStringSubclassescCsX|jd�}td�}|jd|�|jt|�d�|j|jdd�d�|j|jdd�dS)Nr�rBr=z<![CDATA[foo]]>)r)r)r$rr�rr(r%r�)rr$r+rrr�
test_cdataes
z(TestNavigableStringSubclasses.test_cdatacsVd�_�fdd�}�jd�}td�}|jd|��jd|j|d���jd�j�d	S)
zkText inside a CData object is passed into the formatter.

        But the return value is ignored.
        rcs�jd7_dS)Nr=zBITTER FAILURE)�count)�args)rrr�	incrementvszNTestNavigableStringSubclasses.test_cdata_is_never_formatted.<locals>.incrementr�z<><><>r=s<![CDATA[<><><>]]>)riN)r�r$rr�rri)rr�r$r+r)rr�test_cdata_is_never_formattedos
z;TestNavigableStringSubclasses.test_cdata_is_never_formattedcCs2td�}|jd�}|jd|�|j|j�d�dS)NrBr�r=s<!DOCTYPE foo>
)r
r$r�rri)rZdoctyper$rrr�test_doctype_ends_in_newline�s
z:TestNavigableStringSubclasses.test_doctype_ends_in_newlinecCstd�}|jd|j��dS)NrBz<?foo?>)r	rZoutput_ready)rr	rrr�test_declaration�sz.TestNavigableStringSubclasses.test_declarationN)rrr r�r�r�r�rrrrr�cs
r�c@s�eZdZdZdd�Zdd�ZeZdd�Zdd	�Zd
d�Z	dd
�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�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>
cCst|jd�|_dS)Nzhtml.parser)r�HTMLr$)rrrrrR�szTestSoupSelector.setUpcKsRdd�|jj|f|�D�}|j�|j�|j||d|dj|�dj|�f�dS)NcSsg|]}|d�qS)rr)r�elrrrr�sz2TestSoupSelector.assertSelects.<locals>.<listcomp>z$Selector %s, expected [%s], got [%s]z, )r$�select�sortr�join)r�selector�expected_ids�kwargsZel_idsrrrr�szTestSoupSelector.assertSelectscGs"x|D]\}}|j||�qWdS)N)�assertSelect)rZtestsr�r�rrr�assertSelectMultiple�sz%TestSoupSelector.assertSelectMultiplecCsF|jjd�}|jt|�d�|j|djd�|j|djdg�dS)Nrhr=rz	The title)r$r�rr,rNr�)r�elsrrr�test_one_tag_one�sz!TestSoupSelector.test_one_tag_onecCsX|jjd�}|jt|�d�x|D]}|j|jd�q"W|jjd�}|jd|d�dS)Nra��mainr)r$r�rr,rN�
select_one)rr�rar�rrr�test_one_tag_many�s
z"TestSoupSelector.test_one_tag_manycCs|jjd�}|jd|�dS)NZnonexistenttag)r$r�r)r�matchrrr�(test_select_one_returns_none_if_no_match�sz9TestSoupSelector.test_select_one_returns_none_if_no_matchcCs |jjd�}|jdddg�dS)Nzdiv div�inner�data1)r$r�r)rr�rrr�test_tag_in_tag_one�sz$TestSoupSelector.test_tag_in_tag_onecCs&x dD]}|j|ddddg�qWdS)	N�html div�
html body div�body divr�r�r��footer)r�r�r�)r)rr�rrr�test_tag_in_tag_many�s
z%TestSoupSelector.test_tag_in_tag_manycCsB|jddgdd�|jdddgdd�|jdd	ddd
gdd�dS)Nzhtml divr�r=)r:z
html body divr�r+zbody divr�r�r>)r)rrrr�
test_limit�szTestSoupSelector.test_limitcCs|jt|jjd��d�dS)N�delr)rr,r$r�)rrrr�test_tag_no_match�sz"TestSoupSelector.test_tag_no_matchcCs|jt|jjd�dS)Nztag%t)r�r�r$r�)rrrr�test_invalid_tag�sz!TestSoupSelector.test_invalid_tagcCs|jdddg�dS)Nzcustom-dashed-tag�dash1�dash2)r)rrrr�test_select_dashed_tag_ids�sz+TestSoupSelector.test_select_dashed_tag_idscCs6|jjd�}|j|djd�|j|ddd�dS)Nzcustom-dashed-tag[id="dash2"]rzcustom-dashed-tagrr�)r$r�rrN)rZdashedrrr�test_select_dashed_by_id�sz)TestSoupSelector.test_select_dashed_by_idcCs|j|jjd�djd�dS)Nzbody > custom-dashed-tagrzHello there.)rr$r�r))rrrr�test_dashed_tag_textsz%TestSoupSelector.test_dashed_tag_textcCs |j|jjd�|jjd��dS)Nzcustom-dashed-tag)rr$r�r-)rrrr�#test_select_dashed_matches_find_allsz4TestSoupSelector.test_select_dashed_matches_find_allcCs|jddgfdddgf�dS)NZh1�header1Zh2�header2�header3)r�)rrrr�test_header_tags
sz!TestSoupSelector.test_header_tagscCsVxPd	D]H}|jj|�}|jt|�d�|j|djd�|j|dddg�qWdS)
N�.onep�p.onep�html p.onepr=rr�rm�onep)r�r�r�)r$r�rr,rN)rr�r�rrr�test_class_ones

zTestSoupSelector.test_class_onecCs |jjd�}|jt|�d�dS)Nzdiv.onepr)r$r�rr,)rr�rrr�test_class_mismatched_tagsz*TestSoupSelector.test_class_mismatched_tagcCs xdD]}|j|dg�qWdS)N�	div#inner�#inner�
div div#innerr�)r�r�r�)r)rr�rrr�test_one_ids
zTestSoupSelector.test_one_idcCs |jjd�}|jt|�d�dS)Nz
#doesnotexistr)r$r�rr,)rr�rrr�test_bad_idszTestSoupSelector.test_bad_idcCsf|jjd�}|jt|�d�x|D]}|j|jd�q"W|j|dddg�|j|djd��dS)Nzdiv#inner pr9r�r=rmr�r)r$r�rr,rNr8r7)rr�r�rrr�test_items_in_id#s
z!TestSoupSelector.test_items_in_idcCs*x$dD]}|jt|jj|��d�qWdS)N�div#main del�div#main div.oops�div div#mainr)r�r�r�)rr,r$r�)rr�rrr�test_a_bunch_of_emptys+s
z'TestSoupSelector.test_a_bunch_of_emptyscCs xd
D]}|j|d	g�qWdS)N�.class1�p.class1�.class2�p.class2�.class3�p.class3�
html p.class2�div#inner .class2�pmulti)r�r�r�r�r�r�r�r�)r)rr�rrr�test_multi_class_support/sz)TestSoupSelector.test_multi_class_supportcCs xdD]}|j|dg�qWdS)N�.class1.class3�.class3.class2�.class1.class2.class3r�)r�r�r�)r)rr�rrr�test_multi_class_selection4sz+TestSoupSelector.test_multi_class_selectioncCs"|jdddg�|jddg�dS)Nz.s1 > a�s1a1�s1a2z.s1 > a span�s1a2s1)r)rrrr�test_child_selector9sz$TestSoupSelector.test_child_selectorcCs|jddg�dS)Nz.s1 > a#s1a2 spanr�)r)rrrr�test_child_selector_id=sz'TestSoupSelector.test_child_selector_idcCst|jddgfddgfddgfddgfddgfddgfd	dgfd
gfddgfddgfd
dgfdgfdgfdgf�dS)Nzp[class="onep"]r�z
p[id="p1"]z[class="onep"]z	[id="p1"]zlink[rel="stylesheet"]�l1zlink[type="text/css"]zlink[href="blah.css"]zlink[href="no-blah.css"]z[rel="stylesheet"]z[type="text/css"]z[href="blah.css"]z[href="no-blah.css"]zp[href="no-blah.css"])r�)rrrr�test_attribute_equals@sz&TestSoupSelector.test_attribute_equalscCs\|jddgfddgfddgfddgfddgfddgfdd	gfd
d	gfdd	gfdd	gf�
dS)
Nzp[class~="class1"]r�zp[class~="class2"]zp[class~="class3"]z[class~="class1"]z[class~="class2"]z[class~="class3"]za[rel~="friend"]�bobz
a[rel~="met"]z[rel~="friend"]z[rel~="met"])r�)rrrr�test_attribute_tildeRsz%TestSoupSelector.test_attribute_tildecCsv|jddgfddgfdgfdgfdgfddgfdd	d
gfdd	d
gfdd
dgfdd
dgfddgfdd
gfddgf�
dS)Nz[rel^="style"]r�zlink[rel^="style"]znotlink[rel^="notstyle"]z[rel^="notstyle"]zlink[rel^="notstyle"]zlink[href^="bla"]za[href^="http://"]r��mez[href^="http://"]z	[id^="p"]r�r�z	[id^="m"]r�zdiv[id^="m"]z
a[id^="m"]zdiv[data-tag^="dashed"]r�)r�)rrrr�test_attribute_startswith`s



z*TestSoupSelector.test_attribute_startswithc
CsH|jddgfddgfddgfdddddd	d
ddgfd
dgfdgf�dS)Nz[href$=".css"]r�zlink[href$=".css"]z
link[id$="1"]z	[id$="1"]r�r�r�r��s2a1r�r�zdiv[id$="1"]z[id$="noending"])r�)rrrr�test_attribute_endswithqsz(TestSoupSelector.test_attribute_endswithcCs�|jddgfddgfdgfdgfdgfddgfdd	d
gfddd
gfddgfdd
gfddgfddgfddgfdddd
ddddddg	fddgfdgfdd	d
dgfdd	d
gfd dgfd!dd"gfd#d"gfd$dgf�dS)%Nz[rel*="style"]r�zlink[rel*="style"]znotlink[rel*="notstyle"]z[rel*="notstyle"]zlink[rel*="notstyle"]zlink[href*="bla"]z[href*="http://"]r�r�z	[id*="p"]r�r�zdiv[id*="m"]r�z
a[id*="m"]z[href*=".css"]zlink[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*="."]zlink[href*="."]zdiv[id*="n"]r�z
div[id*="nn"]zdiv[data-tag*="edval"])r�)rrrr�test_attribute_contains{s.



z(TestSoupSelector.test_attribute_containscCs2|jddddgfddddgfddgfdgf�dS)	Nz
p[lang|="en"]zlang-enz
lang-en-gbz
lang-en-usz[lang|="en"]z
p[lang|="fr"]zlang-frz
p[lang|="gb"])r�)rrrr�test_attribute_exact_or_hypen�s
z.TestSoupSelector.test_attribute_exact_or_hypenc
CsV|jddddgfddgfdddgfddd	d
dgfdd
dgfdgfdgfddgf�dS)Nz[rel]r�r�r�z	link[rel]za[rel]z[lang]zlang-enz
lang-en-gbz
lang-en-uszlang-frzp[class]r�r�z[blah]zp[blah]z
div[data-tag]r�)r�)rrrr�test_attribute_exists�s

z&TestSoupSelector.test_attribute_existscCs,d}t|d�}|jd�\}|jd|j�dS)Nz]<div style="display: wrong">nope</div>
        <div style="display: right">yes</div>
        zhtml.parserzdiv[style="display: right"]�yes)rr�rr)rr�r$Zchosenrrr�"test_quoted_space_in_selector_name�s
z3TestSoupSelector.test_quoted_space_in_selector_namecCs(|jt|jjd�|jt|jjd�dS)Nza:no-such-pseudoclassza:nth-of-type(a))r�rr$r�)rrrr�test_unsupported_pseudoclass�sz-TestSoupSelector.test_unsupported_pseudoclasscCs�|jjd�}|jt|�d�|j|djd�|jjd�}|jt|�d�|j|djd�|jjd�}|jt|�d�|jt|jjd�dS)	Nzdiv#inner p:nth-of-type(1)r=rz	Some textzdiv#inner p:nth-of-type(3)ZAnotherzdiv#inner p:nth-of-type(4)zdiv p:nth-of-type(0))r$r�rr,rr�r�)rr�rrr�test_nth_of_type�sz!TestSoupSelector.test_nth_of_typecCs2|jjd�}|jt|�d�|j|djd�dS)Nzdiv#inner > p:nth-of-type(1)r=rz	Some text)r$r�rr,r)rr�rrr�"test_nth_of_type_direct_descendant�sz3TestSoupSelector.test_nth_of_type_direct_descendantcCs|jddg�dS)Nz#inner > p:nth-of-type(2)r�)r)rrrr�"test_id_child_selector_nth_of_type�sz3TestSoupSelector.test_id_child_selector_nth_of_typecCs.|jjddd�}|jd�}|j|ddg�dS)Nrar�)rr�r�)r$r%r�r)rr��selectedrrr�test_select_on_element�s
z'TestSoupSelector.test_select_on_elementcCs|jddg�|jdg�dS)Nz
.fancy #innerr�z.normal #inner)r)rrrr�test_overspecified_child_id�sz,TestSoupSelector.test_overspecified_child_idcCsB|jddg�|jddg�|jddg�|jg|jjd��dS)Nz#p1 + h2r�z#p1 + h2 + pr�z#p1 + #header2 + .class1z#p1 + p)rrr$r�)rrrr�test_adjacent_sibling_selector�sz/TestSoupSelector.test_adjacent_sibling_selectorcCsR|jdddg�|jddg�|jddg�|jddg�|jg|jjd��dS)	Nz#p1 ~ h2r�r�z#p1 ~ #header2z#p1 ~ h2 + ar�z#p1 ~ h2 + [rel="me"]z#inner ~ h2)rrr$r�)rrrr�test_general_sibling_selector�s
z.TestSoupSelector.test_general_sibling_selectorcCs|jt|jjd�dS)Nzh1 >)r�r�r$r�)rrrr�test_dangling_combinator�sz)TestSoupSelector.test_dangling_combinatorcCs|jddddg�dS)Nzp[lang] ~ pz
lang-en-gbz
lang-en-uszlang-fr)r)rrrr�2test_sibling_combinator_wont_select_same_tag_twice�szCTestSoupSelector.test_sibling_combinator_wont_select_same_tag_twicecCs|jdddg�dS)Nzx, y�xid�yid)r)rrrr�test_multiple_select�sz%TestSoupSelector.test_multiple_selectcCs|jdddg�dS)Nzx,yrr)r)rrrr�"test_multiple_select_with_no_space�sz3TestSoupSelector.test_multiple_select_with_no_spacecCs|jdddg�dS)Nzx,    yrr)r)rrrr�$test_multiple_select_with_more_space�sz5TestSoupSelector.test_multiple_select_with_more_spacecCs|jddg�dS)Nzx, xr)r)rrrr�test_multiple_select_duplicatedsz0TestSoupSelector.test_multiple_select_duplicatedcCs|jdddg�dS)Nzx, y ~ p[lang=fr]rzlang-fr)r)rrrr�test_multiple_select_siblingsz-TestSoupSelector.test_multiple_select_siblingcCs|jdddg�dS)Nzx, y > zr�zidb)r)rrrr�.test_multiple_select_tag_and_direct_descendantsz?TestSoupSelector.test_multiple_select_tag_and_direct_descendantcCs|jdddddddg�dS)Nz
div > x, y, zrr�zidar�zidab�zidac)r)rrrr�/test_multiple_select_direct_descendant_and_tags
s[email protected]_multiple_select_direct_descendant_and_tagscCs|jdddddddg�dS)Nzdiv x,y,  zrrr	rr
r)r)rrrr�(test_multiple_select_indirect_descendant
sz9TestSoupSelector.test_multiple_select_indirect_descendantcCs(|jt|jjd�|jt|jjd�dS)Nz,x, yzx,,y)r�r�r$r�)rrrr�test_invalid_multiple_selectsz-TestSoupSelector.test_invalid_multiple_selectcCs|jdddg�dS)Nzp[lang=en], p[lang=en-gb]zlang-enz
lang-en-gb)r)rrrr�test_multiple_select_attrssz+TestSoupSelector.test_multiple_select_attrscCs|jddddg�dS)Nz*x, y > z[id=zida], z[id=zidab], z[id=zidb]rrr
)r)rrrr�test_multiple_select_idssz)TestSoupSelector.test_multiple_select_idscCs|jdddg�dS)Nzbody > div > x, y > zrr)r)rrrr�test_multiple_select_nestedsz,TestSoupSelector.test_multiple_select_nestedcCsRd}t|d�}|jd�}|jdt|��x$|jddgd�D]}||ks:t�q:WdS)Nz3<div class="c1"/><div class="c2"/><div class="c1"/>zhtml.parserz.c1, .c2r9Zc1Zc2)ro)rr�rr,r-r�)rr�r$r�r�rrr�test_select_duplicate_elementss

z/TestSoupSelector.test_select_duplicate_elementsN)>rrr r�rRrr�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�rrrrrrrr
rrrrrrrrrr��sv1
	
	r�)2r1ZpdbrrYrSr6r1Zbs4rZbs4.builderrrZbs4.elementrrrr	r
rrr
Zbs4.testingrrr�r�ZLXML_PRESENTrr!r2rLrPrdr�r�r�r�r�r�r�r�r�r�r-rGrRrgr�r�r�rrrr�<module>sN(
;O83(3--*6n+a4*
Page not found – Hello World !