HEX
Server: Apache
System: Linux srv1.prosuiteplus.com 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User: prosuiteplus (1001)
PHP: 8.3.20
Disabled: NONE
Upload Files
File: //lib/python3/dist-packages/bs4/tests/__pycache__/test_tree.cpython-38.pyc
U

t�^�P�@sHdZddlmZddlZddlZddlZddlZddlmZddl	m
Z
mZddlm
Z
mZmZmZmZmZmZmZmZddlmZmZe
�d�dk	Ze
�d	�dk	ZGd
d�de�ZGdd
�d
e�ZGdd�de�ZGdd�de�ZGdd�de�Z Gdd�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�Z0Gd4d5�d5e�Z1Gd6d7�d7e�Z2Gd8d9�d9e�Z3Gd:d;�d;e�Z4Gd<d=�d=e�Z5dS)>a8Tests 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�skipIfZxmlZlxmlc@seZdZdd�Zdd�ZdS)�TreeTestcCs|�dd�|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�5/usr/lib/python3/dist-packages/bs4/tests/test_tree.py�
<listcomp>2sz*TreeTest.assertSelects.<locals>.<listcomp>N��assertEqual��selfZtagsZshould_matchrrr�
assertSelects+szTreeTest.assertSelectscCs|�dd�|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��idrrrrrr;sz-TreeTest.assertSelectsIDs.<locals>.<listcomp>Nrrrrr�assertSelectsIDs4szTreeTest.assertSelectsIDsN)�__name__�
__module__�__qualname__rr!rrrrr)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"|�d�}|�|�d�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"|�d�}|�|jdd�d�dS)Nu<h1>Räksmörgås</h1>�
Räksmörgåsr)r(rr)r*rrr�test_unicode_text_findIs
zTestFind.test_unicode_text_findcCs,|�d�}t|�|�d|jdd�j�dS)Nu&<h1 id="Räksmörgås">here it is</h1>z
here it isr,r)r(�strrr)�textr*rrr�test_unicode_attribute_findMs
z$TestFind.test_unicode_attribute_findcCs"|�d�}|�dt|����dS)z)Test an optimization that finds all tags.�<a>foo</a><b>bar</b>�N�r(r�len�find_allr*rrr�test_find_everythingSs
zTestFind.test_find_everythingcCs$|�d�}|�dt|�d���dS)z;Test an optimization that finds all tags with a given name.z<a>foo</a><b>bar</b><a>baz</a>r2�aNr3r*rrr�test_find_everything_with_nameXs
z'TestFind.test_find_everything_with_nameN)	r"r#r$�__doc__r+r-r0r6r8rrrrr%>sr%c@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�TestFindAllz%Basic tests of the find_all() method.cCs�|�d�}|�|jdd�dg�|�|jdd�dg�|�|jddgd�ddg�|�|jt�d�d�dddg�|�|jdd�dddg�d	S)
z'You can search the tree for text nodes.u<html>Foo<b>bar</b>»</html>�barr�r/�Fooz.*�»TN)r(rr5�re�compiler*rrr�test_find_all_text_nodes`s
���z$TestFindAll.test_find_all_text_nodescCs�|�d�}|�|jddd�dddg�|�|jddd�dg�|�|jdd	d�dddd
dg�|�|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>r7���limit�1r'�3��
�4�5rN�r(rr5r*rrr�test_find_all_limitps
��zTestFindAll.test_find_all_limitcCs:|�d�}|�|ddd�dg�|�|jdd�dg�dS)	Nz!<a>1</a><b>2<a id='foo'>3</a></b>r7rGrCrE�foorrF)r(rr&r*rrr�%test_calling_a_tag_is_calling_findall|s
z1TestFindAll.test_calling_a_tag_is_calling_findallcCs.|�d�}g}|�|�|�g|�|��dS�N�<a></a>)r(�appendrr5)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^|�d�}|�d�}|�t|d��|�d�}|�t|d��|jdd�}|�t|d��dS)z%All find_all calls return a ResultSetrPr7�sourceTrMr<N)r(r5�
assertTrue�hasattr)rr(�resultrrr�test_find_all_resultset�s


z#TestFindAll.test_find_all_resultsetN)	r"r#r$r9rArLrNrSrXrrrrr:]s
r:c@seZdZdd�ZdS)�TestFindAllBasicNamespacescCs<|�d�}|�d|�d�j�|�d|jddid�j�dS)Nz0<mathml:msqrt>4</mathml:msqrt><a svg:fill="red">rIzmathml:msqrtr7zsvg:fillZred��attrs)r(rr)r�namer*rrr�test_find_by_namespaced_name�s
z7TestFindAllBasicNamespaces.test_find_by_namespaced_nameN)r"r#r$r]rrrrrY�srYcspeZdZdZ�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|���|�d�|_dS)Nz�<a>First tag.</a>
                                  <b>Second tag.</b>
                                  <c>Third <a>Nested tag.</a> tag.</c>��superr�setUpr(�tree�r��	__class__rrra�szTestFindAllByName.setUpcCs|�|j�d�ddg�dS�Nr7�
First tag.�Nested tag.�rrbr5rcrrr�test_find_all_by_tag_name�s
�z+TestFindAllByName.test_find_all_by_tag_namecCs\|�|jjddd�dg�|�|jjddd�ddg�|�|jjdt�d�d�ddg�dS)Nr7rgr<Trhr�rrbr5r?r@rcrrr�test_find_all_by_name_and_text�s���z0TestFindAllByName.test_find_all_by_name_and_textcCs|�|jj�d�dg�dS)Nr7rh)rrb�cr5rcrrr�!test_find_all_on_non_root_element�sz3TestFindAllByName.test_find_all_on_non_root_elementcCs|�|�d�ddg�dSrf)rrbrcrrr�%test_calling_element_invokes_find_all�sz7TestFindAllByName.test_calling_element_invokes_find_allcCs |�|j�td��ddg�dSrf)rrbr5r
rcrrr�test_find_all_by_tag_strainer�s�z/TestFindAllByName.test_find_all_by_tag_strainercCs"|�|j�ddg�dddg�dS)Nr7r&rg�Second tag.rhrircrrr�test_find_all_by_tag_names�s�z,TestFindAllByName.test_find_all_by_tag_namescCs$|�|j�ddd��dddg�dS)NT)r7r&rgrqrhrircrrr�test_find_all_by_tag_dict�s�z+TestFindAllByName.test_find_all_by_tag_dictcCs$|�|j�t�d��dddg�dS)Nz^[ab]$rgrqrhrkrcrrr�test_find_all_by_tag_re�s�z)TestFindAllByName.test_find_all_by_tag_recCs,dd�}|�d�}|�|�|�ddg�dS)NcSs|j|�d�kS�Nr )r\�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.rK)rrwrbrrr�'test_find_all_with_tags_matching_method�s
�z9TestFindAllByName.test_find_all_with_tags_matching_methodcCsx|�d�}|�dd�}|�dt�d��}|�dddg�\}}|�d|j�|�d|j�|�d|j�|�d|j�dS)NzH<div class='a b'>1</div><div class='a c'>2</div><div class='a d'>3</div>�divza dza brFrE)r(r)r?r@r5rr)rr(Zr1Zr2Zr3Zr4rrr�%test_find_with_multi_valued_attribute�s�z7TestFindAllByName.test_find_with_multi_valued_attribute)r"r#r$r9rarjrlrnrorprrrsrtrxrz�
__classcell__rrrdrr^�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!S)"�TestFindAllByAttributecCs&|�d�}|�|jdd�ddg�dS)Nz�
                         <a id="first">Matching a.</a>
                         <a id="second">
                          Non-matching <b id="first">Matching b.</b>a.
                         </a>�firstrzMatching a.zMatching b.rK�rrbrrr�test_find_all_by_attribute_name�s
�z6TestFindAllByAttribute.test_find_all_by_attribute_namecCstd�d�}d�d�}|�|�}|�|jg|j|d��|�|jg|j|�d�d��|�|jg|j|dgd��dS)Nuםולש�utf8u<a title="םולש"></a>)�titlezsomething else)�encoder(rr7r5�decode)rZpeace�datar(rrr�%test_find_all_by_utf8_attribute_value�s


z<TestFindAllByAttribute.test_find_all_by_utf8_attribute_valuecCsX|�d�}|�|jdd�dg�|�|jddid�dg�|�|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�r\zA tag called 'name1'.r\rZzName match.�classZclass2zClass match.rKr~rrr�test_find_all_by_attribute_dicts
���z6TestFindAllByAttribute.test_find_all_by_attribute_dictcCs�|�d�}|�|jddd�dg�|�|jddd�dg�|�|jdd	d�dg�|�|�dd�dg�|�|jdd
�ddg�|�|�dd�dg�|�|�dd	�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>
                         r7rE�Zclass_zClass 1.rmrFzClass 3 and 4.rIrZrKr~rrr�test_find_all_by_classs
	z-TestFindAllByAttribute.test_find_all_by_classcCst|�d�}|jdt�d�d�}|�|dg�|jdt�d�d�}|�|dg�|jdt�d�d�}|�|dg�dS)Nz#<gar class='foo bar'>Found it</gar>Zgar�or��Found itr7zo b)r(r5r?r@r)rrb�frrr�0test_find_by_class_when_multiple_classes_present-s
zGTestFindAllByAttribute.test_find_by_class_when_multiple_classes_presentcCsd|�d�}|�|�dt�d��dg�dd�}|�|�d|�g�dd�}|�|�d|�dg�dS)	Nz<a class='bar'>Found it</a>r7Zbar�cSst|�dkS�NrB�r4��valuerrr�big_attribute_value@sznTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.big_attribute_valuecSst|�dkSr�r�r�rrr�small_attribute_valueEszpTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_class.<locals>.small_attribute_value�r(rr5r?r@)rr(r�r�rrr�:test_find_all_with_non_dictionary_for_attrs_finds_by_class;s

�zQTestFindAllByAttribute.test_find_all_with_non_dictionary_for_attrs_finds_by_classcCs�|�d�}|�d�\}}|�||g|�dd��|�|g|�dd��|�|g|jddd��|�|g|�dd��|�g|�dd��dS)Nz*<a class="foo bar"></a><a class="foo"></a>r7rMr;zfoo barr�zbar foo)r(r5r)rr(r7Za2rrr�:test_find_all_with_string_for_attrs_finds_multiple_classesKs
zQTestFindAllByAttribute.test_find_all_with_string_for_attrs_finds_multiple_classescCs0|�d�}tddid�}|�|�|�dg�dS)Nzi
                         <a id="first">Match.</a>
                         <a id="second">Non-match.</a>r r}rZzMatch.)r(r
rr5)rrb�strainerrrr�'test_find_all_by_attribute_soupstrainerWs
z>TestFindAllByAttribute.test_find_all_by_attribute_soupstrainercCs&|�d�}|�|jddd�dg�dS)N��<a id="1">ID present.</a>
                            <a>No ID present.</a>
                            <a id="">ID is empty.</a>r7rzNo ID present.rKr~rrr�$test_find_all_with_missing_attribute_s
z;TestFindAllByAttribute.test_find_all_with_missing_attributecCs&|�d�}|�|jdd�ddg�dS)Nr�TrzID present.zID is empty.rKr~rrr�$test_find_all_with_defined_attributegs


�z;TestFindAllByAttribute.test_find_all_with_defined_attributecCs>|�d�}ddg}|�|jdd�|�|�|jdd�|�dS)Nz[<a id=1>Unquoted attribute.</a>
                            <a id="1">Quoted attribute.</a>zUnquoted attribute.zQuoted attribute.rGrrErK)rrbZexpectedrrr�$test_find_all_with_numeric_attributeps
z;TestFindAllByAttribute.test_find_all_with_numeric_attributecCs,|�d�}|�|jdddgd�ddg�dS)Nz�<a id="1">1</a>
                            <a id="2">2</a>
                            <a id="3">3</a>
                            <a>No ID.</a>rErFrIrrKr~rrr�(test_find_all_with_list_attribute_valuesys
�z?TestFindAllByAttribute.test_find_all_with_list_attribute_valuescCs,|�d�}|�|jt�d�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�r~rrr�5test_find_all_with_regular_expression_attribute_value�s
�zLTestFindAllByAttribute.test_find_all_with_regular_expression_attribute_valuecCsX|�d�}|j}|�|g|jddd��|�g|jddd��|�g|jddd��dS)Nz<b>foo</b><b>bar</b><a>foo</a>r7rMr<r;�r(r7rr5�rr(r7rrr�'test_find_by_name_and_containing_string�s

z>TestFindAllByAttribute.test_find_by_name_and_containing_stringcCs*|�d�}|�|�d�|jddd��dS)Nz"<a>foo</a><a><b><c>foo</c></b></a>r7rMr<)r(rr5r*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|�d�}|j}|�|g|jddd��|�g|jddd��dS)Nz"<b id="1">foo</b><a id="2">foo</a>r2rM)r r/rGr;r�r�rrr�,test_find_by_attribute_and_containing_string�s
zCTestFindAllByAttribute.test_find_by_attribute_and_containing_stringN)r"r#r$rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrr|�s 		

r|c@seZdZdZdd�ZdS)�
TestSmoothzTest Tag.smooth.cCs|�d�}|j}|�d�|�d�|�td��|�td��|�d�|��}t||d�}|�d�|�d	�|�|�|�d|jj�|�d
t	|j
��|��|�dt	|j
��|�d|j
d
�|�d|jj�|�d|j
d�|�d|j
d�dS)Nz<div>a</div>r&rmz	Comment 1z	Comment 2�d�spanrEr'���abcrZ12rGr2)r(ryrQr�default_builderrrr�rr4�contentsZsmooth)rr(ry�builderr�rrr�test_smooth�s(






zTestSmooth.test_smoothN)r"r#r$r9r�rrrrr��sr�c@seZdZdZdd�ZdS)�	TestIndexzTest Tag.indexcCsJ|�d�}|j}t|j�D]\}}|�||�|��q|�t|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>rG)r(ry�	enumerater�r�index�assertRaises�
ValueError)rrbry�i�elementrrr�
test_index�s

	zTestIndex.test_indexN)r"r#r$r9r�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|���|�d�|_|jj|_dS)Na1<ul id="empty"></ul>
                                 <ul id="top">
                                  <ul id="middle">
                                   <ul id="bottom">
                                    <b>Start here</b>
                                   </ul>
                                  </ul>)r`r�rar(rbr&�startrcrdrrra�szTestParentOperations.setUpcCsF|�|jjdd�|�|jjjdd�|�|jjjjdd�dS)Nr �bottom�middle�top)rr��parentrcrrr�test_parent�sz TestParentOperations.test_parentcCs |jjd}|�|j|j�dS)Nr)rbr�rr�)rZtop_tagrrr�%test_parent_of_top_tag_is_soup_object�sz:TestParentOperations.test_parent_of_top_tag_is_soup_objectcCs|�d|jj�dS�N)rrbr�rcrrr�test_soup_object_has_no_parent�sz3TestParentOperations.test_soup_object_has_no_parentcCs8|�|j�d�dddg�|�|jjddd�dg�dS)N�ulr�r�r�r)r!r�Zfind_parentsrcrrr�test_find_parents�s
��z&TestParentOperations.test_find_parentscCs8|�|j�d�dd�|�|jjddd�dd�dS)Nr�r r�r�r)rr��find_parentrcrrr�test_find_parentsz%TestParentOperations.test_find_parentcCs"|jjdd�}|�|jjd�dS)N�
Start herer<r&)rbr)rr�r\�rr/rrr�test_parent_of_text_elementsz0TestParentOperations.test_parent_of_text_elementcCs(|jjdd�}|�|�d�dd�dS)Nr�r<r�r r�)rbr)rr�r�rrr�test_text_element_find_parentsz2TestParentOperations.test_text_element_find_parentcCs(dd�|jjD�}|�|dddg�dS)NcSs&g|]}|dk	rd|jkr|d�qSrurZ)rr�rrrrs
�z>TestParentOperations.test_parent_generator.<locals>.<listcomp>r�r�r�)r��parentsr)rr�rrr�test_parent_generatorsz*TestParentOperations.test_parent_generator)r"r#r$r9rar�r�r�r�r�r�r�r�r{rrrdrr��sr�cseZdZ�fdd�Z�ZS)�
ProximityTestcstt|���|�d�|_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>r_rcrdrrras�zProximityTest.setUp�r"r#r$rar{rrrdrr�sr�csTeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
�ZS)�TestNextOperationscstt|���|jj|_dSr�)r`r�rarbr&r�rcrdrrraszTestNextOperations.setUpcCs*|�|jjd�|�|jjjdd�dS)N�Oner r')rr��next_elementrcrrr�	test_next#szTestNextOperations.test_nextcCs |jjdd�}|�|jd�dS�N�Threer<)rbr)rr�)rZlastrrr�test_next_of_last_item_is_none'sz1TestNextOperations.test_next_of_last_item_is_nonecCs|�|jjd�dSr�)rrbr�rcrrr�test_next_of_root_is_none+sz,TestNextOperations.test_next_of_root_is_nonecCsB|�|j�d�ddg�|jjdd�|�|jjdd�dg�dS)Nr&�Twor�rBr)rr��
find_all_nextrcrrr�test_find_all_next/sz%TestNextOperations.test_find_all_nextcCs2|�|j�d�dd�|�|jjdd�d�dS)Nr&r r'r�r<)rr��	find_nextrcrrr�test_find_next4sz!TestNextOperations.test_find_nextcCs<|jjdd�}|�|�d�jd�|�|�d�ddg�dS)Nr�r<r&r�r�)rbr)rr�rrr�r�rrr�test_find_next_for_text_element8sz2TestNextOperations.test_find_next_for_text_elementcCsF|jjdd�}dd�|jD�}|\}}|�|dd�|�|d�dS)Nr�r<cSsg|]}|�qSrr�rZnoderrrr?sz:TestNextOperations.test_next_generator.<locals>.<listcomp>r rFr�)rbr)Z
next_elementsr)rr�Z
successorsrr�rrr�test_next_generator=s
z&TestNextOperations.test_next_generator)r"r#r$rar�r�r�r�r�r�r�r{rrrdrr�sr�csTeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
�ZS)�TestPreviousOperationscs"tt|���|jjdd�|_dSr�)r`r�rarbr)�endrcrdrrraGszTestPreviousOperations.setUpcCs*|�|jjdd�|�|jjjd�dS)Nr rFr�)rr��previous_elementrcrrr�
test_previousKsz$TestPreviousOperations.test_previouscCs|j�d�}|�|jd�dS)N�html)rbr)rr�)rr}rrr�#test_previous_of_first_item_is_noneOsz:TestPreviousOperations.test_previous_of_first_item_is_nonecCsdSr�rrcrrr�test_previous_of_root_is_noneSsz4TestPreviousOperations.test_previous_of_root_is_nonecCs6|�|j�d�dddg�|�|jjdd�dg�dS)Nr&r�r�r�rGr)rr��find_all_previousrcrrr�test_find_all_previousYs

�z-TestPreviousOperations.test_find_all_previouscCs2|�|j�d�dd�|�|jjdd�d�dS)Nr&r rFr�r<)rr��
find_previousrcrrr�test_find_previousasz)TestPreviousOperations.test_find_previouscCs>|jjdd�}|�|�d�jd�|�|�d�dddg�dS)Nr�r<r&r�r�)rbr)rr�rrr�r�rrr�#test_find_previous_for_text_elementes�z:TestPreviousOperations.test_find_previous_for_text_elementcCsh|jjdd�}dd�|jD�}|\}}}}|�|dd�|�|jd�|�|jd�|�|jd	�dS)
Nr�r<cSsg|]}|�qSrrr�rrrrmszBTestPreviousOperations.test_previous_generator.<locals>.<listcomp>r rE�body�headr�)rbr)Zprevious_elementsrr\)rr�Zpredecessorsr&r�r�r�rrr�test_previous_generatorksz.TestPreviousOperations.test_previous_generator)r"r#r$rar�r�r�r�r�r�r�r{rrrdrr�Esr�cseZdZ�fdd�Z�ZS)�SiblingTestcs4tt|���d}t�d��d|�}|�|�|_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*�)r`r�rar?r@�subr(rb�r�markuprdrrrazszSiblingTest.setUpr�rrrdrr�xsr�csLeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	�Z
S)�TestNextSiblingcs"tt|���|jjdd�|_dS)NrEr)r`r�rarbr)r�rcrdrrra�szTestNextSibling.setUpcCs|�|jjd�dSr�)rrb�next_siblingrcrrr�!test_next_sibling_of_root_is_none�sz1TestNextSibling.test_next_sibling_of_root_is_nonecCsB|�|jjdd�|�|jjjdd�|�|jjdd�dS)Nr r'rF�1.1)rr�r�r�rcrrr�test_next_sibling�sz!TestNextSibling.test_next_siblingcCsN|�|jjjd�|jjdd�}|�|jd�|jjdd�}|�|jd�dS)Nr�rrI)rrbr�r�r))r�nested_spanZ	last_spanrrr�test_next_sibling_may_not_exist�s
z/TestNextSibling.test_next_sibling_may_not_existcCs|�|j�d�dd�dS)Nr�r r')rr��find_next_siblingrcrrr�test_find_next_sibling�sz&TestNextSibling.test_find_next_siblingcCs6|�|j�d�dddg�|�|jjdd�dg�dS)Nr�r'rFrIr)r!r��find_next_siblingsrcrrr�test_next_siblings�s�z"TestNextSibling.test_next_siblingscCsv|�d�}|jdd�}|�|jjd�|�|jjd�|�|�d�dg�|�|jdd�d�|�|jdd�d�dS)N�Foo<b>bar</b>bazr=r<r&�bazr;�nonesuch)r(r)rr�r\rr�r��rr(r�rrr�"test_next_sibling_for_text_element�s
z2TestNextSibling.test_next_sibling_for_text_element)r"r#r$rar�r�r�r�r�rr{rrrdrr��s	r�csLeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	�Z
S)�TestPreviousSiblingcs"tt|���|jjdd�|_dS)NrIr)r`rrarbr)r�rcrdrrra�szTestPreviousSibling.setUpcCs|�|jjd�dSr�)rrb�previous_siblingrcrrr�%test_previous_sibling_of_root_is_none�sz9TestPreviousSibling.test_previous_sibling_of_root_is_nonecCsB|�|jjdd�|�|jjjdd�|�|jjdd�dS)Nr rFr'z3.1)rr�rr�rcrrr�test_previous_sibling�sz)TestPreviousSibling.test_previous_siblingcCsN|�|jjjd�|jjdd�}|�|jd�|jjdd�}|�|jd�dS)Nr�rrE)rrbr�rr))rr�Z
first_spanrrr�#test_previous_sibling_may_not_exist�s
z7TestPreviousSibling.test_previous_sibling_may_not_existcCs|�|j�d�dd�dS)Nr�r rF)rr��find_previous_siblingrcrrr�test_find_previous_sibling�sz.TestPreviousSibling.test_find_previous_siblingcCs6|�|j�d�dddg�|�|jjdd�dg�dS)Nr�rFr'rEr)r!r��find_previous_siblingsrcrrr�test_previous_siblings�s�z*TestPreviousSibling.test_previous_siblingscCsv|�d�}|jdd�}|�|jjd�|�|jjd�|�|�d�dg�|�|jdd�d�|�|jdd�d�dS)Nr�r�r<r&r=r;r�)r(r)rrr\rrrr�rrr�&test_previous_sibling_for_text_element�s
z:TestPreviousSibling.test_previous_sibling_for_text_element)r"r#r$rarrrrr	r
r{rrrdrr�s	rc@seZdZdd�ZdS)�TestTagcCst|�d��d�}d|_|�d|�d��dg|_|�d|�d��|�d|�d��ddg|_|�d|�d��dS)Nr�Za_tagTrZsome_other_tagrGF)r(�new_tagZ_preserve_whitespace_tagsrZ_should_pretty_print�preserve_whitespace_tags)rrrrr�test__should_pretty_print�s
z!TestTag.test__should_pretty_printN)r"r#r$rrrrrr�src@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�TestTagCreationz$Test the ability to create new tags.cCsd|�d�}|jddddid�}|�t|t��|�d|j�|�tddd�|j�|�d|j	�dS)Nr�rMr�r\za name)r;r[)r;r\)
r(rrU�
isinstancerrr\�dictr[r�)rr(rrrr�test_new_tags
zTestTagCreation.test_new_tagcCs�trBtdd�}|�d�}|�d�}|�d|���|�d|���tdd�}|�d�}|�d�}|�d|���|�d|���dS)	Nr�zlxml-xml�br�ps<br/>s<p/>�html.parsers<p></p>)�XML_BUILDER_PRESENTrrrr�)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|�d�}|�d�}|�d|�|�t|t��dS�Nr�rM)r(�
new_stringrrUrr�rr(�srrr�'test_new_string_creates_navigablestrings

z7TestTagCreation.test_new_string_creates_navigablestringcCs6|�d�}|�dt�}|�d|�|�t|t��dSr)r(rrrrUrrrrr�3test_new_string_can_create_navigablestring_subclass$s
zCTestTagCreation.test_new_string_can_create_navigablestring_subclassN)r"r#r$r9rrrrrrrrrs
rc@sTeZdZdd�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(dMdN�Z)dOdP�Z*dQdR�Z+dSS)T�TestTreeModificationcCsl|�d�}d|jd<|�|��|�d��|jd=|�|��|�d��d|jd<|�|��|�d��dS)	Nz<a id="1"></a>r2r z<a id="2"></a>rPrMZid2z<a id2="foo"></a>)r(r7rr��document_forr*rrr�test_attribute_modification,s


z0TestTreeModification.test_attribute_modificationcCslt�d��}|jd|d�}t||d�}t||d�}d|d<|j�d|�|j�d	|�|�|j��d
�dS)Nr�z
<body></body>�r�r7�olzhttp://foo.com/ZhrefrrGs4<body><a href="http://foo.com/"></a><ol></ol></body>)r�lookupr(rr��insertrr�)rr�r(r7r"rrr�test_new_tag_creation5s�z*TestTreeModification.test_new_tag_creationcCs\d}|�|�}|jdd�}|j}|jdd��|j�|�|j|�|�|��|�d��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&rQrr�r�r)r�docr(Zsecond_paraZboldrrr�!test_append_to_contents_moves_tagAs
��z6TestTreeModification.test_append_to_contents_moves_tagcCs0d}|�|�}|j}|�|j�}|�||�dS)Nz<a></a><b><c></c></b>)r(r7�replace_withrmr�rr/r(r7Znew_arrr�1test_replace_with_returns_thing_that_was_replacedSs

zFTestTreeModification.test_replace_with_returns_thing_that_was_replacedcCs,d}|�|�}|j}|��}|�||�dS)N�<a><b></b><c></c></a>)r(r7�unwraprr)rrr�+test_unwrap_returns_thing_that_was_replacedZs

z@TestTreeModification.test_unwrap_returns_thing_that_was_replacedcCsJ|�d�}|j}|��|�d|j�|�t|j�|�t|j|j	�dS)Nz<a><b>Foo</b></a><c>Bar</c>)
r(r7�extractrr�r�r�r,r(rmr�rrr�Itest_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parentas
z^TestTreeModification.test_replace_with_and_unwrap_give_useful_exception_when_tag_has_no_parentcCs:d}|�|�}|j}|j�|�|�|��|�|��dS)Nz-<a><b></b><c>Foo<d></d></c></a><a><e></e></a>)r(rmr(rr�r)rr/r(rmrrr�test_replace_tag_with_itselfis

z1TestTreeModification.test_replace_tag_with_itselfcCs&d}|�|�}|�t|jj|j�dS�N�<a><b></b></a>)r(r�r�r&r(r7�rr/r(rrr�1test_replace_tag_with_its_parent_raises_exceptionps
zFTestTreeModification.test_replace_tag_with_its_parent_raises_exceptioncCs(d}|�|�}|�t|jjd|j�dS)Nr2r)r(r�r�r7r$r3rrr�,test_insert_tag_into_itself_raises_exceptionus
zATestTreeModification.test_insert_tag_into_itself_raises_exceptionc	Cs�|�d�}d}|�|�}|�d|�|jD]}t|t�r*t�q*t|j�\}}}}|�d|j	�|�d|j	�|�d|j	�|�d|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>rGzAnd now, a word:�p2�p3zAnd we're back.N)
r(r$Zdescendantsrr�AssertionError�listZchildrenrr)	rr(r/Z	to_insertr��p1r6r7Zp4rrr�1test_insert_beautifulsoup_object_inserts_childrenzs


zFTestTreeModification.test_insert_beautifulsoup_object_inserts_childrencCsX|�d�}|j}|jd}|�dd�|j\}}|�d�|�d�|�d|jj�dS)Nz<p><a>one</a><b>three</b></p>rrGZtwor�Zthree)r(r7r�r$ZreplaceWithrr&r)rr(r7r&�left�rightrrr�3test_replace_with_maintains_next_element_throughout�s




zHTestTreeModification.test_replace_with_maintains_next_element_throughoutcCsl|�d�}|jdd��d�|jdd�}|j}|�|j|�|�|j|�|�|jj|�|�|jd�dS)Nz<b>Argh!</b>�Argh!r<�Hooray!)r(r)r(r&rr�r�r�)rr(�new_textr&rrr�test_replace_final_node�s
z,TestTreeModification.test_replace_final_nodecCs�|�d�}|j�dd�|�|��|�d��|jdd�}|�|jd�|�|jj|�|�|j	d�|�|j	j
|�|�|j
d�|�|j|j�dS)Nz<a><b>Argh!</b><c></c></a>rGr@z!<a><b>Argh!Hooray!</b><c></c></a>r<r?)r(r&r$rr�rr)r�r�rr�rm)rr(rArrr�test_consecutive_text_nodes�s
��z0TestTreeModification.test_consecutive_text_nodescCsT|�d�}|j�dd�|j�dd�|�ddg|jj�|�|jjdjd�dS)NrPrr;rM)r(r7r$rr�r�r*rrr�test_insert_string�s

z'TestTreeModification.test_insert_stringcCs�|��}|jd|d�}t||d�}|�dd�|j�d|�|�|��|�d��|j}|�|j	|�|�|j
|�|jdd	�}|�|j|�|�|j
|�|j}|�|j	|�|�|j
|�|jdd	�}|�|j|�|�|j|�|�|j
|�dS)
Nz%<a><b>Find</b><c>lady!</c><d></d></a>r!Zmagictagr�therGz=<a><b>Find</b><magictag>the</magictag><c>lady!</c><d></d></a>ZFindr<)r�r(rr$r7rr�rr&r�rr)r�r�rmr�)rr�r(Z	magic_tagZb_tagr)Zc_tagrErrr�test_insert_tag�s6���z$TestTreeModification.test_insert_tagcCs0d}|�|�}|j�|j�|�||���dSr1)r(r7rQr&rr��rr�r(rrr�*test_append_child_thats_already_at_the_end�s
z?TestTreeModification.test_append_child_thats_already_at_the_endcCsJd}|�|�}|j|j|j|j|j|jg}|j�|�|�	d|�
��dS)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�rmr&r7�extendrr�)rr�r(rRrrr�test_extend�s

z TestTreeModification.test_extendcCs2d}|�|�}|j�d|j�|�d|���dS)Nz<a><b></b><c></c><d></d></a>rz<a><d></d><b></b><c></c></a>)r(r7r$r�rr�rGrrr�$test_move_tag_to_beginning_of_parent�s
z9TestTreeModification.test_move_tag_to_beginning_of_parentcCs.|�d�}|j�dd�|�t|j�d�dS)Nz<br/>rGZContentsz<br>Contents</br>)r(rr$rr.r*rrr�&test_insert_works_on_empty_element_tag�s
z;TestTreeModification.test_insert_works_on_empty_element_tagcCs�|�d�}|j�d�|j�d�|�|��|�d��|j�|j�|�|��|�d��|j}|�t|j|�|�	�|�t|jd�|�d�}|j�|�
d��dS)	Nr1�BAZ�QUUXzQUUX<a>foo</a>BAZ<b>bar</b>�QUUX<b>bar</b><a>foo</a>BAZ�nope�<a>r7)r(r&�
insert_beforer7rr�rr�r�r.r�rr(r&rrr�test_insert_before�s$
��
z'TestTreeModification.test_insert_beforecCsj|�d�}|j�ddd�|j�ddd�|�|��|�d��|j�|jd�|�|��|�d��dS)Nr1rO� rPz$QUUX BAZ<a>foo</a>BAZ QUUX<b>bar</b>�FOOz'QUUX BAZ<b>bar</b>FOO<a>foo</a>BAZ QUUX)r(r&rTr7rr�rr*rrr�test_insert_multiple_befores
��z0TestTreeModification.test_insert_multiple_beforecCs�|�d�}|j�d�|j�d�|�|��|�d��|j�|j�|�|��|�d��|j}|�t|j|�|�	�|�t|jd�|�d�}|j�
|�d��dS)	Nr1rOrPz<a>foo</a>QUUX<b>bar</b>BAZrQrRrSr7)r(r&�insert_afterr7rr�rr�r�r.rTrrUrrr�test_insert_after!s$
��
z&TestTreeModification.test_insert_aftercCsj|�d�}|j�ddd�|j�ddd�|�|��|�d��|j�|jd�|�|��|�d��dS)Nr1rOrWrPz$<a>foo</a>QUUX BAZ<b>bar</b>BAZ QUUXzFOO z(QUUX BAZ<b>bar</b><a>foo</a>FOO BAZ QUUX)r(r&rZr7rr�rr*rrr�test_insert_multiple_after7s
��z/TestTreeModification.test_insert_multiple_aftercCsR|�d�}|�d�}|�d�}|�t|j|�|�t|j|�|�t|j|�dS�Nr�r7)r(rrr�r�rZ�NotImplementedError�rr(rrrrr�:test_insert_after_raises_exception_if_after_has_no_meaningAs


zOTestTreeModification.test_insert_after_raises_exception_if_after_has_no_meaningcCsR|�d�}|�d�}|�d�}|�t|j|�|�t|j|�|�t|j|�dSr])r(rrr�r�rTr^r_rrr�Ftest_insert_before_raises_notimplementederror_if_before_has_no_meaningIs


z[TestTreeModification.test_insert_before_raises_notimplementederror_if_before_has_no_meaningcCsv|�d�}|�d�\}}|�|�|�|��|�d��|�|jd�|�|j|j�|�|jd�|�|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(r5r(rr�rr�rr�r�)rr(rbZshowrrr�test_replace_withQs�
��z&TestTreeModification.test_replace_withcCs0d}|�|�}|j�|j�|�d|���dS)Nr+z<a><c></c></a>)r(r&r(rmrr�rGrrr�test_replace_first_child`s
z-TestTreeModification.test_replace_first_childcCs0d}|�|�}|j�|j�|�d|���dS)Nr+r2)r(rmr(r&rr�rGrrr�test_replace_last_childfs
z,TestTreeModification.test_replace_last_childcCs|�d�}|j}|j}|�|�|�|��|�d��|�|jd�|�|jdd�j	d�|�|j
d�|�|jd�|�|jd�|�|j|j
�|�|j
d�|�|j	j	|j�|�|jd�|jdd�}|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<ZWe�to)r(r&r�r(rr�rr�r)r�r�r�rr7rJrI)rr(Z
remove_tagZmove_tagZto_textZg_tagrrr�test_nested_tag_replace_withls6�
��z1TestTreeModification.test_nested_tag_replace_withcCs6|�d�}|j��|�|jd�|�|jjd�dS)NzI
            <p>Unneeded <em>formatting</em> is unneeded</p>
            zUnneeded formatting is unneeded)r(�emr,rrr/r~rrr�test_unwrap�s

z TestTreeModification.test_unwrapcCsF|�d�}|j�|�d��}|�|��d�|�|��|�d��dS)NzI wish I was bold.r&�<b>I wish I was bold.</b>)r(r�wraprrr�r)rr(r�rrr�	test_wrap�s
�zTestTreeModification.test_wrapcCs4|�d�}|jj�|j�|�|��|�d��dS)Nz<b></b>I wish I was bold.rj)r(r&r�rkrr�rr*rrr�%test_wrap_extracts_tag_from_elsewhere�s
�z:TestTreeModification.test_wrap_extracts_tag_from_elsewherecCsH|�d�}|jj�|j�|�dt|jj��|�|��|�d��dS)Nz+<b>I like being bold.</b>I wish I was bold.r2z+<b>I like being bold.I wish I was bold.</b>)	r(r&r�rkrr4r�r�rr*rrr�&test_wrap_puts_new_contents_at_the_end�s
��z;TestTreeModification.test_wrap_puts_new_contents_at_the_endcCs�|�d�}|�t|jj�d�|jdd���}|�|��d�|�|��d�|�t|jj�d�|�|jd�|�|j	d�|�|j
j
d�|jdd	�}|jd
d	�}|�|j
|�|�|j|�|�|j	|�|�|j|�dS)NzR<html><body>Some content. <div id="nav">Nav crap</div> More content.</body></html>rBZnavrz6<html><body>Some content.  More content.</body></html>z<div id="nav">Nav crap</div>r2zSome content. r<z More content.)
r(rr4r�r�r)r.r�r�r�r�r�r)rr(Z	extractedZ	content_1Z	content_2rrr�test_extract�s(��z!TestTreeModification.test_extractcCsz|�d�}|jj}|jj}|�d�}|�d�}|j�|�|j�|�|��|��|�||jj�|�||jj�dS)Nr1rMr;)r(r7rr&rrQr.r)rr(Zfoo_1Zbar_1Zfoo_2Zbar_2rrr�4test_extract_distinguishes_between_identical_strings�s


zITestTreeModification.test_extract_distinguishes_between_identical_stringscs8|�d���fdd���d�D�|�dt�j��dS)Nzv
<html>
<head>
<script>foo</script>
</head>
<body>
 <script>bar</script>
 <a></a>
</body>
<script>baz</script>
</html>csg|]}�j���qSr)�scriptr.)rr��r(rrr�szKTestTreeModification.test_extract_multiples_of_same_tag.<locals>.<listcomp>rqz<body>

<a></a>
</body>)r(r5rr.r�rcrrrr�"test_extract_multiples_of_same_tag�s
z7TestTreeModification.test_extract_multiples_of_same_tagcCs.|�d�}|�d���|�d|�d��dS)Nz<html>
<body>hi</body>
</html>r�)r(r)r.rr*rrr�Btest_extract_works_when_element_is_surrounded_by_identical_strings�s
�zWTestTreeModification.test_extract_works_when_element_is_surrounded_by_identical_stringscCsf|�d�}|j}|j��|�t|jj�d�|�t|d��|j	}|jdd�|�dt|j��dS)zTag.clear()z4<p><a>String <em>Italicized</em></a> and another</p>rr�T)Z	decomposeN)
r(r7r�clearrr4r�rUrVrh)rr(r7rhrrr�
test_clear�s

zTestTreeModification.test_clearcCsB|�d�}d|j_|�|jjdg�d|j_|�|jjdg�dS)zTag.string = 'string'z<a></a> <b><c></c></b>rMr;N)r(r7rrr�r&r*rrr�test_string_set�s

z$TestTreeModification.test_string_setcCs,|�d�}|jj|j_|�|j��d�dS)Nz<a><b>foo</b><c>bar</c>s<a><b>bar</b><c>bar</c></a>)r(rmrr&rr7r�r*rrr�/test_string_set_does_not_affect_original_strings
zDTestTreeModification.test_string_set_does_not_affect_original_stringcCs2|�d�}td�}||j_|�t|jjt��dS)NrPrM)r(rr7rrUr�rr(�cdatarrr�)test_set_string_preserves_class_of_strings
z>TestTreeModification.test_set_string_preserves_class_of_stringN),r"r#r$r r%r'r*r-r/r0r4r5r;r>rBrCrDrFrHrLrMrNrVrYr[r\r`rarcrdrergrirlrmrnrorprsrtrvrwrxr{rrrrr*sR	
		
$	rc@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|�d�}|�t|j�d�|�t|�d�|�t|j�d�|�t|jj�d�dS)z3The length of an element is its number of children.z<top>1<b>2</b>3</top>rGrBN)r(rr4r�r�r*rrr�test_lens

zTestElementObjects.test_lencCsL|�d�}|�|j|�d��|�|jj|�d��d��|�|jd�dS)z2Accessing a Python member .foo invokes find('foo')�<b><i></i></b>r&r�N)r(rr&r)r�r7r*rrr�test_member_access_invokes_find"s
z2TestElementObjects.test_member_access_invokes_findc	CsP|�d�}tjdd��}|j}W5QRX|�|j|�|�dt|dj��dS)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_warningsZbTagrr&r.�message)rr(�wrrrr�test_deprecated_member_access)s
�z0TestElementObjects.test_deprecated_member_accesscCs2|�d�}|�|j�d��|�|j�d��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(rUrM�has_attr�assertFalser*rrr�
test_has_attr2s
z TestElementObjects.test_has_attrcCsd}|�|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>)ZassertSoupEqualsr�rrr�.test_attributes_come_out_in_alphabetical_order>szATestElementObjects.test_attributes_come_out_in_alphabetical_ordercCs|�d�}|�|jjd�dS)Nz
<b>foo</b>rM�r(rr&rr*rrr�test_stringBs
zTestElementObjects.test_stringcCs|�d�}|�|jjd�dS)N�<b></b>r�r*rrr�test_empty_tag_has_no_stringHs
z/TestElementObjects.test_empty_tag_has_no_stringcCs`|�d�}|�|jjd�|�d�}|�|jjd�|�d�}|j�dd�|�|jjd�dS)Nz<a>foo<b></b><b></b></b>z<a>foo<b></b>bar</b>z
<a>foo</b>rGr;)r(rr&rr7r$r*rrr�-test_tag_with_multiple_children_has_no_stringMs


z@TestElementObjects.test_tag_with_multiple_children_has_no_stringcCs,|�d�}|�|jjd�|�|jd�dS)Nz<a><b>foo</b></a>rM)r(rr7rr*rrr�)test_tag_with_recursive_string_has_string[s
z<TestElementObjects.test_tag_with_recursive_string_has_stringcCs4|�d�}|�|jj�|�d�}|�|jj�dS)z7Only a tag containing a single text node has a .string.z<b>f<i>e</i>o</b>r�N)r(r�r&rr*rrr�test_lack_of_stringbs

z&TestElementObjects.test_lack_of_stringcCs`|�d�}|�|jjd�|�|jjdd�d�|�|j�d�d�|�|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(rr7r/�get_textr*rrr�
test_all_textjs

z TestElementObjects.test_all_textcCsJ|�d�}|�|��d�|�|jttfd�d�|�|jdd�d�dS)N�foo<!--IGNORE-->barZfoobar)�typesZfooIGNOREbar)r(rr�rrr*rrr�test_get_text_ignores_commentsrs
�
�z1TestElementObjects.test_get_text_ignores_commentscCs$|�d�}|�ddgt|j��dS)Nr�rMr;)r(rr9Zstringsr*rrr�!test_all_strings_ignores_comments{s
z4TestElementObjects.test_all_strings_ignores_commentsN)r"r#r$r9r}rr�r�r�r�r�r�r�r�r�r�r�rrrrr|s		r|c@sPeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�ZdS)�TestCDAtaListAttributesz0Testing cdata-list attributes like 'class'.
    cCs"|�d�}|�dg|jd�dS)Nz<a class='foo'>rMr��r(rr7r*rrr�test_single_value_becomes_list�s
z6TestCDAtaListAttributes.test_single_value_becomes_listcCs$|�d�}|�ddg|jd�dS)Nz<a class='foo bar'>rMr;r�r�r*rrr�!test_multiple_values_becomes_list�s
z9TestCDAtaListAttributes.test_multiple_values_becomes_listcCs&|�d�}|�dddg|jd�dS)Nz<a class='foo	bar
baz'>rMr;r�r�r�r*rrr�2test_multiple_values_separated_by_weird_whitespace�s
zJTestCDAtaListAttributes.test_multiple_values_separated_by_weird_whitespacecCs |�d�}|�d|j���dS)Nz<a class='foo	bar'>s<a class="foo bar"></a>)r(rr7r�r*rrr�,test_attributes_joined_into_string_on_output�s
zDTestCDAtaListAttributes.test_attributes_joined_into_string_on_outputcCs$|�d�}|�dg|j�d��dS)Nz<a id='abc def'>zabc defr )r(rr7Zget_attribute_listr*rrr�test_get_attribute_list�s
z/TestCDAtaListAttributes.test_get_attribute_listcCs$|�d�}|�ddg|jd�dS)Nz(<form accept-charset="ISO-8859-1 UTF-8">z
ISO-8859-1zUTF-8�accept-charset)r(rZformr*rrr�test_accept_charset�s
z+TestCDAtaListAttributes.test_accept_charsetcCs$d}|�|�}|�d|jd�dS)Nz)<a accept-charset="ISO-8859-1 UTF-8"></a>zISO-8859-1 UTF-8r�r�rGrrr�-test_cdata_attribute_applying_only_to_one_tag�s
zETestCDAtaListAttributes.test_cdata_attribute_applying_only_to_one_tagcs6|�d�j�|�d�j��fdd�}|�t|�dS)Nrcs
d�_dS)NrMr�rrrr�t�szJTestCDAtaListAttributes.test_string_has_immutable_name_property.<locals>.t)r(rrr\r��AttributeError)rr�rrr�'test_string_has_immutable_name_property�sz?TestCDAtaListAttributes.test_string_has_immutable_name_propertyN)r"r#r$r9r�r�r�r�r�r�r�r�rrrrr�sr�csheZdZdZ�fdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
�ZS)�TestPersistencez*Testing features like pickle and deepcopy.cs&tt|���d|_|�|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: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>)r`r�raZpager(rbrcrdrrra�szTestPersistence.setUpcCs@t�|jd�}t�|�}|�|jt�|�|��|j���dS)Nr2)�pickle�dumpsrb�loadsrrerr�)r�dumped�loadedrrr�!test_pickle_and_unpickle_identity�s
z1TestPersistence.test_pickle_and_unpickle_identitycCs&t�|j�}|�|��|j���dSr�)�copy�deepcopyrbrr�)r�copiedrrr�test_deepcopy_identity�sz&TestPersistence.test_deepcopy_identitycCs:tdd�}|j}|��}|�dt|��|�||j�dS)Ns
<p>&nbsp;</p>ru	<p> </p>)rZoriginal_encoding�__copy__rr.)rr(�encodingr�rrr�test_copy_preserves_encoding�s

z,TestPersistence.test_copy_preserves_encodingcCst|�d�j}d|_d|_|��}|�|j|j�|�|j|j�|�|j|j�|�|j|j�|�|j|j�dS)Nz<p></p>rH�!)	r(rZ
sourcelineZ	sourceposr�rZcan_be_empty_elementZcdata_list_attributesr
)rrr�rrr�'test_copy_preserves_builder_information�s$���z7TestPersistence.test_copy_preserves_builder_informationcCs>d}|�|�}t�|tj�}t�|�}|�|��|���dS)N�
<b>☃</b>)r(r�r�ZHIGHEST_PROTOCOLr�rr�)rr�r(r�r�rrr�test_unicode_pickle�s


z#TestPersistence.test_unicode_picklecCszd}|�|�}|jdd�}t�|�}|�||�|�d|j�|�d|j�|�d|j�|�d|j�|�d|j�dS)Nz<b>Foo<a></a></b><b>Bar</b>r=r)	r(r)r�rr�r��assertNotEqualr�r��rr�r(�s1�s2rrr�1test_copy_navigablestring_is_not_attached_to_tree�s

zATestPersistence.test_copy_navigablestring_is_not_attached_to_treecCs>d}|�|�}|j}t�|�}|�||�|�t|t��dS)Nz<b><!--Foo--></b>)r(rr�rrUrrr�rrr�0test_copy_navigablestring_subclass_has_same_types

z@TestPersistence.test_copy_navigablestring_subclass_has_same_typecCs(d}|�|�}t�|�}|�||�dS)N�)<div><b>Foo<a></a></b><b>Bar</b></div>end)r(r�r)rr�r(Z	soup_copyrrr�test_copy_entire_soup
s

z%TestPersistence.test_copy_entire_soupcCs�d}|�|�}|j}t�|�}|�t|�t|��|�||�|�||k�|�d|j�|�d|j�|�d|jdd�j	�|�
d|jdd�j	�dS)Nr�ZBarr)r(ryr�rr.r�r�r�r)r�r�)rr�r(ryZdiv_copyrrr�test_copy_tag_copies_contentss

z-TestPersistence.test_copy_tag_copies_contents)r"r#r$r9rar�r�r�r�r�r�r�r�r�r{rrrdrr��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!S)"�TestSubstitutionscCs0d}|�|�}|jdd�}|�||�d��dS�N�#<b>&lt;&lt;Sacré bleu!&gt;&gt;</b>�minimal��	formatter�r(r�rr�rr�r(�decodedrrr�!test_default_formatter_is_minimal&s
��z3TestSubstitutions.test_default_formatter_is_minimalcCs0d}|�|�}|jdd�}|�||�d��dS)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�rrr�test_formatter_html0s
�z%TestSubstitutions.test_formatter_htmlcCs0d}|�|�}|jdd�}|�||�d��dS)Nr�Zhtml5r�z-<br><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>r�r�rrr�test_formatter_html58s
�z&TestSubstitutions.test_formatter_html5cCs0d}|�|�}|jdd�}|�||�d��dSr�r�r�rrr�test_formatter_minimal@s
��z(TestSubstitutions.test_formatter_minimalcCs0d}|�|�}|jdd�}|�||�d��dS)Nr�r�u<b><<Sacré bleu!>></b>r�r�rrr�test_formatter_nullJs
�z%TestSubstitutions.test_formatter_nullcCs4d}|�|�}|jdd�d�}|�||�d��dS)Nz!<b>&lt;foo&gt;</b><b>bar</b><br/>cSs|��Sr���upper��xrrr�<lambda>V�z9TestSubstitutions.test_formatter_custom.<locals>.<lambda>r�z<b><FOO></b><b>BAR</b><br/>r�r�rrr�test_formatter_customSs
�z'TestSubstitutions.test_formatter_customcCs�d}|�|�}|j}d}|�||���|�||jdd��d}|�||jdd��|�||jdd��d}|�||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>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>cSs|��Sr�r�r�rrrr�lr�zMTestSubstitutions.test_formatter_is_run_on_attribute_values.<locals>.<lambda>)r(r7rr�)rr�r(r7Zexpect_minimalZexpect_htmlZexpect_upperrrr�)test_formatter_is_run_on_attribute_values]s
z;TestSubstitutions.test_formatter_is_run_on_attribute_valuescCs$d}t|d���}|�d|k�dS)NzO
  <script type="text/javascript">
   console.log("< < hey > > ");
  </script>
r�< < hey > >�rr�rU�rr&�encodedrrr�2test_formatter_skips_script_tag_for_html_documentsnszDTestSubstitutions.test_formatter_skips_script_tag_for_html_documentscCs$d}t|d���}|�d|k�dS)NzF
  <style type="text/css">
   console.log("< < hey > > ");
  </style>
rr�r�r�rrr�1test_formatter_skips_style_tag_for_html_documentswszCTestSubstitutions.test_formatter_skips_style_tag_for_html_documentscCs |�d�}|�d|j���dS)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(rry�prettifyr*rrr�,test_prettify_leaves_preformatted_text_alone�s

�z>TestSubstitutions.test_prettify_leaves_preformatted_text_alonecCs,tdd�}|jdd�d�}|�d|k�dS)Nz<html><body>foo</body></html>rcSs|��Sr�r�r�rrrr��r�zLTestSubstitutions.test_prettify_accepts_formatter_function.<locals>.<lambda>r�rX)rr�rU)rr(Zprettyrrr�(test_prettify_accepts_formatter_function�s
z:TestSubstitutions.test_prettify_accepts_formatter_functioncCs"|�d�}|�tt|����dSrO)r(rr.�typer�r*rrr�(test_prettify_outputs_unicode_by_default�s
z:TestSubstitutions.test_prettify_outputs_unicode_by_defaultcCs$|�d�}|�tt|�d���dS)NrP�utf-8)r(r�bytesr�r�r*rrr�test_prettify_can_encode_data�s
z/TestSubstitutions.test_prettify_can_encode_datacCs0d}|�|�}|j�d�}|�||�d��dS)Nu<b>Sacré bleu!</b>r�)r(r&r�r)rr�r(r�rrr�,test_html_entity_substitution_off_by_default�s
z>TestSubstitutions.test_html_entity_substitution_off_by_defaultcCs�d}|�|�}|�|jdd�|�d�}|�d|k�|�d�}|�d|k�|�d�}|�d	|k�|�d
��d
�}|�d|k�dS)NzE<meta content="text/html; charset=x-sjis" http-equiv="Content-type"/>Zcontentztext/html; charset=x-sjisr�s
charset=utf-8�euc_jpscharset=euc_jpz	shift-jisscharset=shift-jiszutf-16zcharset=utf-16)r(r�metar�rUr�)rZmeta_tagr(�utf_8r��	shift_jisZutf_16_urrr�test_encoding_substitution�s



z,TestSubstitutions.test_encoding_substitutioncCs2d}td�}|j||d�}|�|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�r\)rr�r�r(rrr�;test_encoding_substitution_doesnt_happen_if_tag_is_strained�szMTestSubstitutions.test_encoding_substitution_doesnt_happen_if_tag_is_strainedN)r"r#r$r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrr�$s 

	
		r�c@sPeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�ZdS)�TestEncodingz0Test the ability to encode objects into strings.cCs.d}|�|�}|�|jj�d�d�d��dS)Nr�r��☃)r(rr&rr��rr�r(rrr�"test_unicode_string_can_be_encoded�s

�z/TestEncoding.test_unicode_string_can_be_encodedcCs,d}|�|�}|�|j�d�|�d��dS)Nr�r��r(rr&r�r�rrr�1test_tag_containing_unicode_string_can_be_encoded�s

�z>TestEncoding.test_tag_containing_unicode_string_can_be_encodedcCs&d}|�|�}|�|j�d�d�dS)Nr��asciis<b>&#9731;</b>r�r�rrr�<test_encoding_substitutes_unrecognized_characters_by_default�s
zITestEncoding.test_encoding_substitutes_unrecognized_characters_by_defaultcCs&d}|�|�}|jt|jddd�dS)Nr�r��strict)�errors)r(r��UnicodeEncodeErrorr�r�rrr� test_encoding_can_be_made_strict�s
�z-TestEncoding.test_encoding_can_be_made_strictcCs$d}|�|�}|�d|j���dS)Nr�r�)r(rr&Zdecode_contentsr�rrr�test_decode_contents�s
z!TestEncoding.test_decode_contentscCs.d}|�|�}|�d�d�|jjdd��dS)Nr�r�r�)r�)r(rr�r&Zencode_contentsr�rrr�test_encode_contents�s
��z!TestEncoding.test_encode_contentscCs*d}|�|�}|�d�d�|j���dS)Nr�r�r�)r(rr�r&ZrenderContentsr�rrr�test_deprecated_renderContents�s
�z+TestEncoding.test_deprecated_renderContentscCs8d}|�|�}tr$|�|t|��n|�dt|��dS)Nr�s
<b>\u2603</b>)r(rr�reprr�rrr�	test_repr�s

zTestEncoding.test_reprN)r"r#r$r9r�r�r�r�r�r�r�r�rrrrr��sr�c@seZdZdd�ZdS)�
TestFormattercCsLGdd�dt�}|�d�}|�}|j|d�}|�|j|j�|�d|�dS)Nc@seZdZdd�ZdS)z=TestFormatter.test_sort_attributes.<locals>.UnsortedFormattercss6||_t|j���D]\}}|dkr&q||fVqdS)N�ignore)�called_with�sortedr[�items)rr�k�vrrr�
attributes�s
zHTestFormatter.test_sort_attributes.<locals>.UnsortedFormatter.attributesN)r"r#r$rrrrr�UnsortedFormatter�srz*<p cval="1" aval="2" ignore="ignored"></p>r�z<p aval="2" cval="1"></p>)rr(r�rrr)rrr(r�r�rrr�test_sort_attributes�s
z"TestFormatter.test_sort_attributesN)r"r#r$rrrrrr��sr�c@s,eZdZdd�Zdd�Zdd�Zdd�Zd	S)
�TestNavigableStringSubclassescCsX|�d�}td�}|�d|�|�t|�d�|�|jdd�d�|�|jdd�dS)Nr�rMrGz<![CDATA[foo]]>r<r)r(rr$rr.r)r�ryrrr�
test_cdatas
z(TestNavigableStringSubclasses.test_cdatacsVd�_�fdd�}��d�}td�}|�d|���d|j|d����d�j�d	S)
zkText inside a CData object is passed into the formatter.

        But the return value is ignored.
        rcs�jd7_dS)NrGzBITTER FAILURE)�count)�argsrcrr�	incrementszNTestNavigableStringSubclasses.test_cdata_is_never_formatted.<locals>.incrementr�z<><><>rGs<![CDATA[<><><>]]>r�N)rr(rr$rr�)rr
r(rzrrcr�test_cdata_is_never_formatteds

�z;TestNavigableStringSubclasses.test_cdata_is_never_formattedcCs2td�}|�d�}|�d|�|�|��d�dS)NrMr�rGs<!DOCTYPE foo>
)r
r(r$rr�)rZdoctyper(rrr�test_doctype_ends_in_newline's
z:TestNavigableStringSubclasses.test_doctype_ends_in_newlinecCstd�}|�d|���dS)NrMz<?foo?>)r	rZoutput_ready)rr�rrr�test_declaration/sz.TestNavigableStringSubclasses.test_declarationN)r"r#r$r
rrrrrrrr		s
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)Nr)r�HTMLr(rcrrrrafszTestSoupSelector.setUpc
KsRdd�|jj|f|�D�}|��|��|�||d|d�|�d�|�f�dS)NcSsg|]}|d�qSrr)r�elrrrrjsz2TestSoupSelector.assertSelects.<locals>.<listcomp>z$Selector %s, expected [%s], got [%s]z, )r(�select�sortr�join)r�selector�expected_ids�kwargsZel_idsrrrris��zTestSoupSelector.assertSelectscGs|D]\}}|�||�qdSr�)�assertSelect)rZtestsrrrrr�assertSelectMultipleusz%TestSoupSelector.assertSelectMultiplecCsF|j�d�}|�t|�d�|�|djd�|�|djdg�dS)Nr�rGrz	The title)r(rrr4r\r��r�elsrrr�test_one_tag_oneysz!TestSoupSelector.test_one_tag_onecCsT|j�d�}|�t|�d�|D]}|�|jd�q |j�d�}|�d|d�dS)Nry��mainr )r(rrr4r\�
select_one)rrryrrrr�test_one_tag_manysz"TestSoupSelector.test_one_tag_manycCs|j�d�}|�d|�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 |j�d�}|�dddg�dS)Nzdiv div�inner�data1)r(rrrrrr�test_tag_in_tag_one�sz$TestSoupSelector.test_tag_in_tag_onecCs"dD]}|�|ddddg�qdS)N)�html div�
html body div�body divr&r r%�footer�r�rrrrr�test_tag_in_tag_many�sz%TestSoupSelector.test_tag_in_tag_manycCsB|jddgdd�|jdddgdd�|jdd	ddd
gdd�dS)Nr(r rGrCr)r%r2r*r&r+rHr,rcrrr�
test_limit�s
�zTestSoupSelector.test_limitcCs|�t|j�d��d�dS)N�delr�rr4r(rrcrrr�test_tag_no_match�sz"TestSoupSelector.test_tag_no_matchcCs|�t|jjd�dS)Nztag%t�r��SyntaxErrorr(rrcrrr�test_invalid_tag�sz!TestSoupSelector.test_invalid_tagcCs|�dddg�dS)N�custom-dashed-tag�dash1�dash2r,rcrrr�test_select_dashed_tag_ids�sz+TestSoupSelector.test_select_dashed_tag_idscCs6|j�d�}|�|djd�|�|ddd�dS)Nzcustom-dashed-tag[id="dash2"]rr6r r8)r(rrr\)rZdashedrrr�test_select_dashed_by_id�sz)TestSoupSelector.test_select_dashed_by_idcCs|�|j�d�djd�dS)Nzbody > custom-dashed-tagrzHello there.)rr(rr/rcrrr�test_dashed_tag_text�sz%TestSoupSelector.test_dashed_tag_textcCs |�|j�d�|j�d��dS)Nr6)rr(rr5rcrrr�#test_select_dashed_matches_find_all�sz4TestSoupSelector.test_select_dashed_matches_find_allcCs|�ddgfdddgf�dS)NZh1�header1Zh2�header2�header3�rrcrrr�test_header_tags�s
�z!TestSoupSelector.test_header_tagscCsRdD]H}|j�|�}|�t|�d�|�|djd�|�|dddg�qdS)N)z.onepzp.onepzhtml p.oneprGrrr��onep)r(rrr4r\)rrrrrr�test_class_one�s
zTestSoupSelector.test_class_onecCs |j�d�}|�t|�d�dS)Nzdiv.onepr�r(rrr4rrrr�test_class_mismatched_tag�sz*TestSoupSelector.test_class_mismatched_tagcCsdD]}|�|dg�qdS)N)z	div#innerz#innerz
div div#innerr%r,r-rrr�test_one_id�szTestSoupSelector.test_one_idcCs |j�d�}|�t|�d�dS)Nz
#doesnotexistrrDrrrr�test_bad_id�szTestSoupSelector.test_bad_idcCsb|j�d�}|�t|�d�|D]}|�|jd�q |�|dddg�|�|d�d��dS)Nzdiv#inner prBrrGr�rBr)r(rrr4r\r�r�)rrrrrr�test_items_in_id�sz!TestSoupSelector.test_items_in_idcCs&dD]}|�t|j�|��d�qdS)N)zdiv#main delzdiv#main div.oopszdiv div#mainrr1r-rrr�test_a_bunch_of_emptys�sz'TestSoupSelector.test_a_bunch_of_emptyscCsdD]}|�|dg�qdS)N)z.class1zp.class1z.class2zp.class2z.class3zp.class3z
html p.class2zdiv#inner .class2�pmultir,r-rrr�test_multi_class_support�sz)TestSoupSelector.test_multi_class_supportcCsdD]}|�|dg�qdS)N)z.class1.class3z.class3.class2z.class1.class2.class3rJr,r-rrr�test_multi_class_selection�sz+TestSoupSelector.test_multi_class_selectioncCs"|�dddg�|�ddg�dS)Nz.s1 > a�s1a1�s1a2z.s1 > a span�s1a2s1r,rcrrr�test_child_selector�sz$TestSoupSelector.test_child_selectorcCs|�ddg�dS)Nz.s1 > a#s1a2 spanrOr,rcrrr�test_child_selector_id�sz'TestSoupSelector.test_child_selector_idcCst|�ddgfddgfddgfddgfddgfddgfd	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@rcrrr�test_attribute_equals�s �z&TestSoupSelector.test_attribute_equalsc
Cs\|�ddgfddgfddgfddgfddgfddgfdd	gfd
d	gfdd	gfdd	gf�
dS)
Nzp[class~="class1"]rJzp[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@rcrrr�test_attribute_tilde�s�z%TestSoupSelector.test_attribute_tildecCsv|�ddgfddgfdgfdgfdgfddgfdd	d
gfdd	d
gfdd
dgfdd
dgfddgfdd
gfddgf�
dS)Nz[rel^="style"]rRzlink[rel^="style"]znotlink[rel^="notstyle"]z[rel^="notstyle"]zlink[rel^="notstyle"]zlink[href^="bla"]za[href^="http://"]rT�mez[href^="http://"]z	[id^="p"]rJr:z	[id^="m"]r zdiv[id^="m"]z
a[id^="m"]zdiv[data-tag^="dashed"]r&r@rcrrr�test_attribute_startswiths



�z*TestSoupSelector.test_attribute_startswithcCsH|�ddgfddgfddgfdddddd	d
ddgfd
dgfdgf�dS)Nz[href$=".css"]rRzlink[href$=".css"]z
link[id$="1"]z	[id$="1"]r&r:r=rM�s2a1rOr7zdiv[id$="1"]z[id$="noending"]r@rcrrr�test_attribute_endswiths�z(TestSoupSelector.test_attribute_endswithcCs�|�ddgfddgfdgfdgfdgfddgfdd	d
gfddd
gfddgfdd
gfddgfddgfddgfdddd
ddddddg	fddgfdgfdd	d
dgfdd	d
gfd dgfd!dd"gfd#d"gfd$dgf�dS)%Nz[rel*="style"]rRzlink[rel*="style"]znotlink[rel*="notstyle"]z[rel*="notstyle"]zlink[rel*="notstyle"]zlink[href*="bla"]z[href*="http://"]rTrVz	[id*="p"]rJr:zdiv[id*="m"]r z
a[id*="m"]z[href*=".css"]zlink[href*=".css"]z
link[id*="1"]z	[id*="1"]r&r=rMrNrXrOr7z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@rcrrr�test_attribute_contains!s0



�z(TestSoupSelector.test_attribute_containscCs2|�ddddgfddddgfddgfdgf�dS)	Nz
p[lang|="en"]�lang-en�
lang-en-gb�
lang-en-usz[lang|="en"]z
p[lang|="fr"]�lang-frz
p[lang|="gb"]r@rcrrr�test_attribute_exact_or_hypen>s�z.TestSoupSelector.test_attribute_exact_or_hypencCsV|�ddddgfddgfdddgfddd	d
dgfdd
dgfdgfdgfddgf�dS)Nz[rel]rRrTrVz	link[rel]za[rel]z[lang]r[r\r]r^zp[class]r:rJz[blah]zp[blah]z
div[data-tag]r&r@rcrrr�test_attribute_existsFs

�z&TestSoupSelector.test_attribute_existscCs,d}t|d�}|�d�\}|�d|j�dS)Nz]<div style="display: wrong">nope</div>
        <div style="display: right">yes</div>
        rzdiv[style="display: right"]Zyes)rrrr)rr�r(Zchosenrrr�"test_quoted_space_in_selector_nameRs
z3TestSoupSelector.test_quoted_space_in_selector_namecCs(|�t|jjd�|�t|jjd�dS)Nza:no-such-pseudoclassza:nth-of-type(a))r�r^r(rr4rcrrr�test_unsupported_pseudoclassZs��z-TestSoupSelector.test_unsupported_pseudoclasscCs�|j�d�}|�t|�d�|�|djd�|j�d�}|�t|�d�|�|djd�|j�d�}|�t|�d�|j�d�}|�t|�d�dS)	Nzdiv#inner p:nth-of-type(1)rGr�	Some textzdiv#inner p:nth-of-type(3)ZAnotherzdiv#inner p:nth-of-type(4)zdiv p:nth-of-type(0)�r(rrr4rrrrr�test_nth_of_typeasz!TestSoupSelector.test_nth_of_typecCs2|j�d�}|�t|�d�|�|djd�dS)Nzdiv#inner > p:nth-of-type(1)rGrrcrdrrrr�"test_nth_of_type_direct_descendanttsz3TestSoupSelector.test_nth_of_type_direct_descendantcCs|�ddg�dS)Nz#inner > p:nth-of-type(2)r:r,rcrrr�"test_id_child_selector_nth_of_typeysz3TestSoupSelector.test_id_child_selector_nth_of_typecCs.|jjddd�}|�d�}|�|ddg�dS)Nryr rr%r&)r(r)rr!)rr%�selectedrrr�test_select_on_element|s
z'TestSoupSelector.test_select_on_elementcCs|�ddg�|�dg�dS)Nz
.fancy #innerr%z.normal #innerr,rcrrr�test_overspecified_child_id�sz,TestSoupSelector.test_overspecified_child_idcCsB|�ddg�|�ddg�|�ddg�|�g|j�d��dS)Nz#p1 + h2r>z#p1 + h2 + prJz#p1 + #header2 + .class1z#p1 + p�rrr(rrcrrr�test_adjacent_sibling_selector�sz/TestSoupSelector.test_adjacent_sibling_selectorcCsR|�dddg�|�ddg�|�ddg�|�ddg�|�g|j�d��dS)	Nz#p1 ~ h2r>r?z#p1 ~ #header2z#p1 ~ h2 + arVz#p1 ~ h2 + [rel="me"]z#inner ~ h2rkrcrrr�test_general_sibling_selector�s
z.TestSoupSelector.test_general_sibling_selectorcCs|�t|jjd�dS)Nzh1 >r3rcrrr�test_dangling_combinator�sz)TestSoupSelector.test_dangling_combinatorcCs|�ddddg�dS)Nzp[lang] ~ pr\r]r^r,rcrrr�2test_sibling_combinator_wont_select_same_tag_twice�szCTestSoupSelector.test_sibling_combinator_wont_select_same_tag_twicecCs|�dddg�dS)Nzx, y�xid�yidr,rcrrr�test_multiple_select�sz%TestSoupSelector.test_multiple_selectcCs|�dddg�dS)Nzx,yrprqr,rcrrr�"test_multiple_select_with_no_space�sz3TestSoupSelector.test_multiple_select_with_no_spacecCs|�dddg�dS)Nzx,    yrprqr,rcrrr�$test_multiple_select_with_more_space�sz5TestSoupSelector.test_multiple_select_with_more_spacecCs|�ddg�dS)Nzx, xrpr,rcrrr�test_multiple_select_duplicated�sz0TestSoupSelector.test_multiple_select_duplicatedcCs|�dddg�dS)Nzx, y ~ p[lang=fr]rpr^r,rcrrr�test_multiple_select_sibling�sz-TestSoupSelector.test_multiple_select_siblingcCs|�dddg�dS)Nzx, y > zrp�zidbr,rcrrr�.test_multiple_select_tag_and_direct_descendant�sz?TestSoupSelector.test_multiple_select_tag_and_direct_descendantc	Cs|�dddddddg�dS)Nz
div > x, y, zrprq�zidarw�zidab�zidacr,rcrrr�/test_multiple_select_direct_descendant_and_tags�sz@TestSoupSelector.test_multiple_select_direct_descendant_and_tagsc	Cs|�dddddddg�dS)Nzdiv x,y,  zrprqryrwrzr{r,rcrrr�(test_multiple_select_indirect_descendant�sz9TestSoupSelector.test_multiple_select_indirect_descendantcCs(|�t|jjd�|�t|jjd�dS)Nz,x, yzx,,yr3rcrrr�test_invalid_multiple_select�sz-TestSoupSelector.test_invalid_multiple_selectcCs|�dddg�dS)Nzp[lang=en], p[lang=en-gb]r[r\r,rcrrr�test_multiple_select_attrs�sz+TestSoupSelector.test_multiple_select_attrscCs|�ddddg�dS)Nz*x, y > z[id=zida], z[id=zidab], z[id=zidb]rprwrzr,rcrrr�test_multiple_select_ids�sz)TestSoupSelector.test_multiple_select_idscCs|�dddg�dS)Nzbody > div > x, y > zrprwr,rcrrr�test_multiple_select_nested�sz,TestSoupSelector.test_multiple_select_nestedcCsNd}t|d�}|�d�}|�dt|��|jddgd�D]}||ks8t�q8dS)Nz3<div class="c1"/><div class="c2"/><div class="c1"/>rz.c1, .c2rBZc1Zc2r�)rrrr4r5r8)rr�r(rhr�rrr�test_select_duplicate_elements�s

z/TestSoupSelector.test_select_duplicate_elementsN)>r"r#r$rrarrrrr"r$r'r.r/r2r5r9r:r;r<rArCrErFrGrHrIrKrLrPrQrSrUrWrYrZr_r`rarbrerfrgrirjrlrmrnrorrrsrtrurvrxr|r}r~rr�r�r�rrrrr3sv1
	
	r)6r9Zpdbrr�r�r?r�Zbs4rZbs4.builderrrZbs4.elementrrrr	r
rrr
rZbs4.testingrrr#rZLXML_PRESENTrr%r:rYr^r|r�r�r�r�r�r�r�r�rrrrr|r�r�r�r�r�r	rrrrr�<module>sT
,;O6,3(3--*jn+z4*