HEX
Server: LiteSpeed
System: Linux standart9.isimtescil.net 3.10.0-962.3.2.lve1.5.26.7.el7.x86_64 #1 SMP Wed Oct 2 07:53:12 EDT 2019 x86_64
User: karalev (5310)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: //opt/alt/python37/lib/python3.7/site-packages/bs4/tests/__pycache__/test_tree.cpython-37.pyc
B

G.�`�0�@sdZddlmZddlZddlZddlZddlZddlmZddl	m
Z
mZddlm
Z
mZmZmZmZmZmZmZddlmZmZe
�d�dk	Ze
�d	�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|�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�D/opt/alt/python37/lib/python3.7/site-packages/bs4/tests/test_tree.py�
<listcomp>1sz*TreeTest.assertSelects.<locals>.<listcomp>N)�assertEqual)�self�tags�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)�idr)rrrrrr:sz-TreeTest.assertSelectsIDs.<locals>.<listcomp>N)r)rrrrrr�assertSelectsIDs3szTreeTest.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"|�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_tagDs
zTestFind.test_find_tagcCs"|�d�}|�|jdd�d�dS)Nu<h1>Räksmörgås</h1>u
Räksmörgås)r)r$rr%)rr$rrr�test_unicode_text_findHs
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 isu
Räksmörgås)r)r$�strrr%�text)rr$rrr�test_unicode_attribute_findLs
z$TestFind.test_unicode_attribute_findcCs"|�d�}|�dt|����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_everythingRs
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>r+�aN)r$rr,r-)rr$rrr�test_find_everything_with_nameWs
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�|�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>�bar)r)r)�Fooz.*�»TN)r$rr-�re�compile)rr$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>r/�)�limit�1r#�3��
�4�5rN)r$rr-)rr$rrr�test_find_all_limitos
zTestFindAll.test_find_all_limitcCs:|�d�}|�|ddd�dg�|�|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.|�d�}g}|�|�|�g|�|��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^|�d�}|�d�}|�t|d��|�d�}|�t|d��|jdd�}|�t|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<|�d�}|�d|�d�j�|�d|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|���|�d�|_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�d�ddg�dS)Nr/z
First tag.zNested tag.)rrSr-)rrrr�test_find_all_by_tag_name�sz+TestFindAllByName.test_find_all_by_tag_namecCs\|�|jjddd�dg�|�|jjddd�ddg�|�|jjdt�d�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|�|jj�d�dg�dS)Nr/zNested tag.)rrS�cr-)rrrr�!test_find_all_on_non_root_element�sz3TestFindAllByName.test_find_all_on_non_root_elementcCs|�|�d�ddg�dS)Nr/z
First tag.zNested tag.)rrS)rrrr�%test_calling_element_invokes_find_all�sz7TestFindAllByName.test_calling_element_invokes_find_allcCs |�|j�td��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�ddg�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�ddd��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�t�d��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�}|�d�}|�|�|�ddg�dS)NcSs|j|�d�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|�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 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&|�d�}|�|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_namecCstd�d�}d�d�}|�|�}|�|jg|j|d��|�|jg|j|�d�d��|�|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|�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)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�|�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>
                         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|�d�}|jdt�d�d�}|�|dg�|jdt�d�d�}|�|dg�|jdt�d�d�}|�|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|�d�}|�|�dt�d��dg�dd�}|�|�d|�g�dd�}|�|�d|�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_valueCszpTestFindAllByAttribute.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_class9s
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>r/rBr3zfoo bar)rozbar foo)r$r-r)rr$r/Za2rrr�:test_find_all_with_string_for_attrs_finds_multiple_classesIs
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>rre)rMzMatch.)r$rrr-)rrS�strainerrrr�'test_find_all_by_attribute_soupstrainerUsz>TestFindAllByAttribute.test_find_all_by_attribute_soupstrainercCs&|�d�}|�|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&|�d�}|�|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_attributeesz;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.r=)rr;)r$rr-)rrSZexpectedrrr�$test_find_all_with_numeric_attributens
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>r;r<r?)r)r$rr-)rrSrrr�(test_find_all_with_list_attribute_valueswsz?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$rr-r6r7)rrSrrr�5test_find_all_with_regular_expression_attribute_value�szLTestFindAllByAttribute.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>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*|�d�}|�|�d�|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|�d�}|j}|�|g|jddd��|�g|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|�d�}|j}x(t|j�D]\}}|�||�|��qW|�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>r=)r$ra�	enumerate�contentsr�index�assertRaises�
ValueError)rrSra�iZelementrrr�
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|���|�d�|_|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|�|jjdd�|�|jjjdd�|�|jjjjdd�dS)Nr�bottom�middle�top)rr��parent)rrrr�test_parent�sz TestParentOperations.test_parentcCs |jjd}|�|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|�d|jj�dS)N)rrSr�)rrrr�test_soup_object_has_no_parent�sz3TestParentOperations.test_soup_object_has_no_parentcCs8|�|j�d�dddg�|�|jjddd�dg�dS)N�ulr�r�r�)r)rr�Zfind_parents)rrrr�test_find_parents�sz&TestParentOperations.test_find_parentscCs8|�|j�d�dd�|�|jjddd�dd�dS)Nr�rr�r�)r)rr��find_parent)rrrr�test_find_parent�sz%TestParentOperations.test_find_parentcCs"|jjdd�}|�|jjd�dS)Nz
Start here)r)r")rSr%rr�rN)rr)rrr�test_parent_of_text_element�sz0TestParentOperations.test_parent_of_text_elementcCs(|jjdd�}|�|�d�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�}|�|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|���|�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>)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|���|jj|_dS)N)rQr�rRrSr"r�)r)rTrrrR�szTestNextOperations.setUpcCs*|�|jjd�|�|jjjdd�dS)N�Onerr#)rr��next_element)rrrr�	test_next�szTestNextOperations.test_nextcCs |jjdd�}|�|jd�dS)N�Three)r))rSr%rr�)rZlastrrr�test_next_of_last_item_is_none�sz1TestNextOperations.test_next_of_last_item_is_nonecCs|�|jjd�dS)N)rrSr�)rrrr�test_next_of_root_is_none�sz,TestNextOperations.test_next_of_root_is_nonecCsB|�|j�d�ddg�|jjdd�|�|jjdd�dg�dS)Nr"�Twor�r9)r)rr��
find_all_next)rrrr�test_find_all_nextsz%TestNextOperations.test_find_all_nextcCs2|�|j�d�dd�|�|jjdd�d�dS)Nr"rr#r�)r))rr��	find_next)rrrr�test_find_nextsz!TestNextOperations.test_find_nextcCs<|jjdd�}|�|�d�jd�|�|�d�ddg�dS)Nr�)r)r"r�r�)rSr%rr�rrr�)rr)rrr�test_find_next_for_text_elementsz2TestNextOperations.test_find_next_for_text_elementcCsF|jjdd�}dd�|jD�}|\}}|�|dd�|�|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|���|jjdd�|_dS)Nr�)r))rQr�rRrSr%�end)r)rTrrrRszTestPreviousOperations.setUpcCs*|�|jjdd�|�|jjjd�dS)Nrr<r�)rr��previous_element)rrrr�
test_previoussz$TestPreviousOperations.test_previouscCs|j�d�}|�|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�d�dddg�|�|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�d�dd�|�|jjdd�d�dS)Nr"rr<r�)r))rr��
find_previous)rrrr�test_find_previous5sz)TestPreviousOperations.test_find_previouscCs>|jjdd�}|�|�d�jd�|�|�d�dddg�dS)Nr�)r)r"r�r�)rSr%rr�rrr�)rr)rrr�#test_find_previous_for_text_element9sz:TestPreviousOperations.test_find_previous_for_text_elementcCsh|jjdd�}dd�|jD�}|\}}}}|�|dd�|�|jd�|�|jd�|�|jd	�dS)
Nr�)r)cSsg|]}|�qSrr)rr�rrrrAszBTestPreviousOperations.test_previous_generator.<locals>.<listcomp>rr;�body�headr�)rSr%Zprevious_elementsrrN)rr�Zpredecessorsr"r�r�r�rrr�test_previous_generator?sz.TestPreviousOperations.test_previous_generator)rrr rRr�r�r�r�r�r�r�rcrr)rTrr�s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
\s*�)rQr�rRr6r7�subr$rS)r�markup)rTrrrRNszSiblingTest.setUp)rrr rRrcrr)rTrr�Lsr�csLeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	�Z
S)�TestNextSiblingcs"tt|���|jjdd�|_dS)Nr;)r)rQr�rRrSr%r�)r)rTrrrRdszTestNextSibling.setUpcCs|�|jjd�dS)N)rrS�next_sibling)rrrr�!test_next_sibling_of_root_is_nonehsz1TestNextSibling.test_next_sibling_of_root_is_nonecCsB|�|jjdd�|�|jjjdd�|�|jjdd�dS)Nrr#r<z1.1)rr�r�r�)rrrr�test_next_siblingksz!TestNextSibling.test_next_siblingcCsN|�|jjjd�|jjdd�}|�|jd�|jjdd�}|�|jd�dS)Nz1.1)rr?)rrSr�r�r%)r�nested_spanZ	last_spanrrr�test_next_sibling_may_not_existrs
z/TestNextSibling.test_next_sibling_may_not_existcCs|�|j�d�dd�dS)N�spanrr#)rr��find_next_sibling)rrrr�test_find_next_sibling{sz&TestNextSibling.test_find_next_siblingcCs6|�|j�d�dddg�|�|jjdd�dg�dS)Nr�r#r<r?)r)rr��find_next_siblings)rrrr�test_next_siblings~sz"TestNextSibling.test_next_siblingscCsv|�d�}|jdd�}|�|jjd�|�|jjd�|�|�d�dg�|�|jdd�d�|�|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�bs	r�csLeZdZ�fdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	�Z
S)�TestPreviousSiblingcs"tt|���|jjdd�|_dS)Nr?)r)rQr�rRrSr%r�)r)rTrrrR�szTestPreviousSibling.setUpcCs|�|jjd�dS)N)rrS�previous_sibling)rrrr�%test_previous_sibling_of_root_is_none�sz9TestPreviousSibling.test_previous_sibling_of_root_is_nonecCsB|�|jjdd�|�|jjjdd�|�|jjdd�dS)Nrr<r#z3.1)rr�r�r�)rrrr�test_previous_sibling�sz)TestPreviousSibling.test_previous_siblingcCsN|�|jjjd�|jjdd�}|�|jd�|jjdd�}|�|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�d�dd�dS)Nr�rr<)rr��find_previous_sibling)rrrr�test_find_previous_sibling�sz.TestPreviousSibling.test_find_previous_siblingcCs6|�|j�d�dddg�|�|jjdd�dg�dS)Nr�r<r#r;)r)rr��find_previous_siblings)rrrr�test_previous_siblings�sz*TestPreviousSibling.test_previous_siblingscCsv|�d�}|jdd�}|�|jjd�|�|jjd�|�|�d�dg�|�|jdd�d�|�|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.cCs\|�d�}|jddd�}|�t|t��|�d|j�|�tdd�|j�|�d|j	�dS)Nr�rBr�)r3)
r$�new_tagrH�
isinstancer
rrN�dictrMr�)rr$r�rrr�test_new_tag�s
zTestTagCreation.test_new_tagcCs�trBtdd�}|�d�}|�d�}|�d|���|�d|���tdd�}|�d�}|�d�}|�d|���|�d|���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|�d�}|�d�}|�d|�|�t|t��dS)Nr�rB)r$�
new_stringrrHr�r)rr$�srrr�'test_new_string_creates_navigablestring�s

z7TestTagCreation.test_new_string_creates_navigablestringcCs6|�d�}|�dt�}|�d|�|�t|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@s4eZdZdd�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'dKS)L�TestTreeModificationcCsl|�d�}d|jd<|�|��|�d��|jd=|�|��|�d��d|jd<|�|��|�d��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_modificationcCslt�d��}|jd|d�}t||d�}t||d�}d|d<|j�d|�|j�d	|�|�|j��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}|�|�}|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"rDrr�rjr�)r�docr$Zsecond_paraZboldrrr�!test_append_to_contents_moves_tag�s

z6TestTreeModification.test_append_to_contents_moves_tagcCs0d}|�|�}|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}|��}|�||�dS)Nz<a><b></b><c></c></a>)r$r/�unwrapr)rr)r$r/r�rrr�+test_unwrap_returns_thing_that_was_replaceds

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$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�|�|�|��|�|��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}|�|�}|�t|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}|�|�}|�t|jjd|j�dS)Nz<a><b></b></a>r)r$r�r�r/r�)rr)r$rrr�,test_insert_tag_into_itself_raises_exception1s
zATestTreeModification.test_insert_tag_into_itself_raises_exceptioncCsX|�d�}|j}|jd}|�dd�|j\}}|�d�|�d�|�d|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_throughout6s




zHTestTreeModification.test_replace_with_maintains_next_element_throughoutcCsl|�d�}|jdd��d�|jdd�}|j}|�|j|�|�|j|�|�|jj|�|�|jd�dS)Nz<b>Argh!</b>zArgh!)r)zHooray!)r$r%r�r"rr�r�r�)rr$�new_textr"rrr�test_replace_final_nodeEs
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>r=zHooray!z!<a><b>Argh!Hooray!</b><c></c></a>)r)zArgh!)r$r"r�rrjr�r%r�r�r�r�rW)rr$r�rrr�test_consecutive_text_nodesOs

z0TestTreeModification.test_consecutive_text_nodescCsT|�d�}|j�dd�|j�dd�|�ddg|jj�|�|jjdjd�dS)Nz<a></a>rr3rB)r$r/r�rr�r�)rr$rrr�test_insert_stringds

z'TestTreeModification.test_insert_stringcCs�|j}|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�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_tagr�rrr�test_insert_tagms,

z$TestTreeModification.test_insert_tagcCs0d}|�|�}|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�d|j�|�d|���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.|�d�}|j�dd�|�t|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`|�d�}|j�d�|j�d�|�|��|�d��|j�|j�|�|��|�d��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`|�d�}|j�d�|j�d�|�|��|�d��|j�|j�|�|��|�d��dS)Nz<a>foo</a><b>bar</b>rrz<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|�d�}|�d�}|�d�}|�t|j|�|�t|j|�|�t|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|�d�}|�d�}|�d�}|�t|j|�|�t|j|�|�t|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|�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$r-r�rrjr�r�r�r�r�)rr$rZshowrrr�test_replace_with�s
z&TestTreeModification.test_replace_withcCs0d}|�|�}|j�|j�|�d|���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�|j�|�d|���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|�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"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|�d�}|j��|�|jd�|�|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|�d�}|j�|�d��}|�|��d�|�|��|�d��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|�d�}|jj�|j�|�|��|�d��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_elsewheres
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.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_ends

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>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_extract!s"z!TestTreeModification.test_extractcCsz|�d�}|jj}|jj}|�d�}|�d�}|j�|�|j�|�|��|��|�||jj�|�||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_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$rrrWszKTestTreeModification.test_extract_multiples_of_same_tag.<locals>.<listcomp>rz<body>

<a></a>
</body>)r$r-rr(r�)rr)r$r�"test_extract_multiples_of_same_tagKs
z7TestTreeModification.test_extract_multiples_of_same_tagcCs.|�d�}|�d���|�d|�d��dS)Nz<html>
<body>hi</body>
</html>r�)r$r%r�r)rr$rrr�Btest_extract_works_when_element_is_surrounded_by_identical_strings[szWTestTreeModification.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$r/r��clearrr,r�rHrIr)rr$r/rrrr�
test_cleards

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

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$rWrr"rr/ri)rr$rrr�/test_string_set_does_not_affect_original_stringzs
zDTestTreeModification.test_string_set_does_not_affect_original_stringcCs2|�d�}td�}||j_|�t|jjt��dS)Nz<a></a>rB)r$rr/rrHr�)rr$�cdatarrr�)test_set_string_preserves_class_of_strings
z>TestTreeModification.test_set_string_preserves_class_of_stringN)(rrr r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrrr
rr
rrrrrrrrrrrr r"r#r$r&rrrrr��sJ	
		
$	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|�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>r=r9N)r$rr,r�r�)rr$rrr�test_len�s

zTestElementObjects.test_lencCsL|�d�}|�|j|�d��|�|jj|�d��d��|�|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|�d�}tjdd��}|j}WdQRX|�|j|�|�dt|dj��dS)Nz<b><i></i></b>T)�recordz,.bTag is deprecated, use .find("b") instead.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$rHrB�has_attr�assertFalse)rr$rrr�
test_has_attr�s
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>)ZassertSoupEquals)rr�rrr�.test_attributes_come_out_in_alphabetical_order�szATestElementObjects.test_attributes_come_out_in_alphabetical_ordercCs|�d�}|�|jjd�dS)Nz
<b>foo</b>rB)r$rr"r)rr$rrr�test_string�s
zTestElementObjects.test_stringcCs|�d�}|�|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`|�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>r=r3)r$rr"rr/r�)rr$rrr�-test_tag_with_multiple_children_has_no_string�s


z@TestElementObjects.test_tag_with_multiple_children_has_no_stringcCs,|�d�}|�|jjd�|�|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|�d�}|�|jj�|�d�}|�|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$r2r"r)rr$rrr�test_lack_of_string�s

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$rr/r)�get_text)rr$rrr�
test_all_text�s

z TestElementObjects.test_all_textcCsJ|�d�}|�|��d�|�|jttfd�d�|�|jdd�d�dS)Nzfoo<!--IGNORE-->barZfoobar)�typesZfooIGNOREbar)r$rr<rr)rr$rrr�test_get_text_ignores_comments�s
z1TestElementObjects.test_get_text_ignores_commentscCs$|�d�}|�ddgt|j��dS)Nzfoo<!--IGNORE-->barrBr3)r$r�listZstrings)rr$rrr�!test_all_strings_ignores_comments�s
z4TestElementObjects.test_all_strings_ignores_commentsN)rrr r1r(r)r/r3r4r5r6r7r8r9r=r?rArrrrr'�s		r'c@sHeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dS)�TestCDAtaListAttributesz0Testing cdata-list attributes like 'class'.
    cCs"|�d�}|�dg|jd�dS)Nz<a class='foo'>rBrm)r$rr/)rr$rrr�test_single_value_becomes_list�s
z6TestCDAtaListAttributes.test_single_value_becomes_listcCs$|�d�}|�ddg|jd�dS)Nz<a class='foo bar'>rBr3rm)r$rr/)rr$rrr�!test_multiple_values_becomes_list�s
z9TestCDAtaListAttributes.test_multiple_values_becomes_listcCs&|�d�}|�dddg|jd�dS)Nz<a class='foo	bar
baz'>rBr3r�rm)r$rr/)rr$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$rr/ri)rr$rrr�,test_attributes_joined_into_string_on_outputs
zDTestCDAtaListAttributes.test_attributes_joined_into_string_on_outputcCs$|�d�}|�ddg|jd�dS)Nz(<form accept-charset="ISO-8859-1 UTF-8">z
ISO-8859-1zUTF-8zaccept-charset)r$rZform)rr$rrr�test_accept_charsets
z+TestCDAtaListAttributes.test_accept_charsetcCs$d}|�|�}|�d|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_tags
zETestCDAtaListAttributes.test_cdata_attribute_applying_only_to_one_tagcs6|�d�j�|�d�j��fdd�}|�t|�dS)Nr�cs
d�_dS)NrB)rNr)rrr�tszJTestCDAtaListAttributes.test_string_has_immutable_name_property.<locals>.t)r$rrrNr��AttributeError)rrIr)rr�'test_string_has_immutable_name_propertysz?TestCDAtaListAttributes.test_string_has_immutable_name_propertyN)rrr r1rCrDrErFrGrHrKrrrrrB�srBcs`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|���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>)rQrLrRZpager$rS)r)rTrrrRszTestPersistence.setUpcCs@t�|jd�}t�|�}|�|jt�|�|��|j���dS)Nr+)�pickle�dumpsrS�loadsrrTrrj)r�dumped�loadedrrr�!test_pickle_and_unpickle_identity1s
z1TestPersistence.test_pickle_and_unpickle_identitycCs&t�|j�}|�|��|j���dS)N)�copyZdeepcopyrSrrj)rZcopiedrrr�test_deepcopy_identity9sz&TestPersistence.test_deepcopy_identitycCs:tdd�}|j}|��}|�dt|��|�||j�dS)Ns
<p>&nbsp;</p>zhtml.parseru	<p> </p>)rZoriginal_encoding�__copy__rr()rr$�encodingrSrrr�test_copy_preserves_encoding>s

z,TestPersistence.test_copy_preserves_encodingcCs>d}|�|�}t�|tj�}t�|�}|�|��|���dS)Nu
<b>☃</b>)r$rMrNZHIGHEST_PROTOCOLrOrrj)rr�r$rPrQrrr�test_unicode_pickleEs


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>r4)r)	r$r%rSrr�r��assertNotEqualr�r�)rr�r$�s1�s2rrr�1test_copy_navigablestring_is_not_attached_to_treeMs

zATestPersistence.test_copy_navigablestring_is_not_attached_to_treecCs>d}|�|�}|j}t�|�}|�||�|�t|t��dS)Nz<b><!--Foo--></b>)r$rrSrrHr�r)rr�r$rZr[rrr�0test_copy_navigablestring_subclass_has_same_typeYs

z@TestPersistence.test_copy_navigablestring_subclass_has_same_typecCs(d}|�|�}t�|�}|�||�dS)Nz)<div><b>Foo<a></a></b><b>Bar</b></div>end)r$rSr)rr�r$Z	soup_copyrrr�test_copy_entire_soupas

z%TestPersistence.test_copy_entire_soupcCs�d}|�|�}|j}t�|�}|�t|�t|��|�||�|�||k�|�d|j�|�d|j�|�d|jdd�j	�|�
d|jdd�j	�dS)Nz)<div><b>Foo<a></a></b><b>Bar</b></div>endZBar)r)r$rarSrr(r2r�r�r%r�rY)rr�r$raZdiv_copyrrr�test_copy_tag_copies_contentsgs

z-TestPersistence.test_copy_tag_copies_contents)rrr r1rRrRrTrWrXr\r]r^r_rcrr)rTrrLsrLc@s�eZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�ZdS) �TestSubstitutionscCs0d}|�|�}|jdd�}|�||�d��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}|�|�}|jdd�}|�||�d��dS)Nu#<b>&lt;&lt;Sacré bleu!&gt;&gt;</b>r�)rbz)<b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>)r$rjrr�)rr�r$rcrrr�test_formatter_html�s
z%TestSubstitutions.test_formatter_htmlcCs0d}|�|�}|jdd�}|�||�d��dS)Nu#<b>&lt;&lt;Sacré bleu!&gt;&gt;</b>ra)rb)r$rjrr�)rr�r$rcrrr�test_formatter_minimal�s
z(TestSubstitutions.test_formatter_minimalcCs0d}|�|�}|jdd�}|�||�d��dS)Nu#<b>&lt;&lt;Sacré bleu!&gt;&gt;</b>)rbu<b><<Sacré bleu!>></b>)r$rjrr�)rr�r$rcrrr�test_formatter_null�s

z%TestSubstitutions.test_formatter_nullcCs4d}|�|�}|jdd�d�}|�||�d��dS)Nz<b>&lt;foo&gt;</b><b>bar</b>cSs|��S)N)�upper)�xrrr�<lambda>��z9TestSubstitutions.test_formatter_custom.<locals>.<lambda>)rbz<b><FOO></b><b>BAR</b>)r$rjrr�)rr�r$rcrrr�test_formatter_custom�s
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>ra)rbz/<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|��S)N)rh)rirrrrj�rkzMTestSubstitutions.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���}|�d|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���}|�d|k�dS)NzF
  <style type="text/css">
   console.log("< < hey > > ");
  </style>
zhtml.parsers< < hey > >)rrirH)rr�rnrrr�1test_formatter_skips_style_tag_for_html_documents�szCTestSubstitutions.test_formatter_skips_style_tag_for_html_documentscCs |�d�}|�d|j���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�}|�d|k�dS)Nz<html><body>foo</body></html>zhtml.parsercSs|��S)N)rh)rirrrrj�rkzCTestSubstitutions.test_prettify_accepts_formatter.<locals>.<lambda>)rbZFOO)rrqrH)rr$Zprettyrrr�test_prettify_accepts_formatter�s
z1TestSubstitutions.test_prettify_accepts_formattercCs"|�d�}|�tt|����dS)Nz<a></a>)r$rr(�typerq)rr$rrr�(test_prettify_outputs_unicode_by_default�s
z:TestSubstitutions.test_prettify_outputs_unicode_by_defaultcCs$|�d�}|�tt|�d���dS)Nz<a></a>zutf-8)r$r�bytesrtrq)rr$rrr�test_prettify_can_encode_data�s
z/TestSubstitutions.test_prettify_can_encode_datacCs0d}|�|�}|j�d�}|�||�d��dS)Nu<b>Sacré bleu!</b>zutf-8)r$r"rir)rr�r$rnrrr�,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-sjiszutf-8s
charset=utf-8�euc_jpscharset=euc_jpz	shift-jisscharset=shift-jiszutf-16zcharset=utf-16)r$r�metarirHrj)rZmeta_tagr$�utf_8ry�	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�rN)rr�ryr$rrr�;test_encoding_substitution_doesnt_happen_if_tag_is_strainedszMTestSubstitutions.test_encoding_substitution_doesnt_happen_if_tag_is_strainedN)rrr rdrerfrgrlrmrorprrrsrurwrxr}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)Nu
<b>☃</b>zutf-8u☃)r$rr"rri)rr�r$rrr�"test_unicode_string_can_be_encodeds
z/TestEncoding.test_unicode_string_can_be_encodedcCs,d}|�|�}|�|j�d�|�d��dS)Nu
<b>☃</b>zutf-8)r$rr"ri)rr�r$rrr�1test_tag_containing_unicode_string_can_be_encodeds
z>TestEncoding.test_tag_containing_unicode_string_can_be_encodedcCs&d}|�|�}|�|j�d�d�dS)Nu
<b>☃</b>�asciis<b>&#9731;</b>)r$rr"ri)rr�r$rrr�<test_encoding_substitutes_unrecognized_characters_by_defaults
zITestEncoding.test_encoding_substitutes_unrecognized_characters_by_defaultcCs&d}|�|�}|jt|jddd�dS)Nu
<b>☃</b>r��strict)�errors)r$r��UnicodeEncodeErrorri)rr�r$rrr� test_encoding_can_be_made_strict!s
z-TestEncoding.test_encoding_can_be_made_strictcCs$d}|�|�}|�d|j���dS)Nu
<b>☃</b>u☃)r$rr"Zdecode_contents)rr�r$rrr�test_decode_contents's
z!TestEncoding.test_decode_contentscCs.d}|�|�}|�d�d�|jjdd��dS)Nu
<b>☃</b>u☃rg)rV)r$rrir"Zencode_contents)rr�r$rrr�test_encode_contents,s

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

zTestEncoding.test_reprN)rrr r1r�r�r�r�r�r�r�r�rrrrr
src@s,eZdZdd�Zdd�Zdd�Zdd�Zd	S)
�TestNavigableStringSubclassescCsX|�d�}td�}|�d|�|�t|�d�|�|jdd�d�|�|jdd�dS)Nr�rBr=z<![CDATA[foo]]>)r)r)r$rr�rr(r%r�)rr$r%rrr�
test_cdataCs
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)Nr=zBITTER FAILURE)�count)�args)rrr�	incrementTszNTestNavigableStringSubclasses.test_cdata_is_never_formatted.<locals>.incrementr�z<><><>r=s<![CDATA[<><><>]]>)rbN)r�r$rr�rri)rr�r$r%r)rr�test_cdata_is_never_formattedMs
z;TestNavigableStringSubclasses.test_cdata_is_never_formattedcCs2td�}|�d�}|�d|�|�|��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�}|�d|���dS)NrBz<?foo?>)r	rZoutput_ready)rrrrr�test_declarationgsz.TestNavigableStringSubclasses.test_declarationN)rrr r�r�r�r�rrrrr�As
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<drS)s�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.setUpc
KsRdd�|jj|f|�D�}|��|��|�||d|d�|�d�|�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]\}}|�||�qWdS)N)�assertSelect)rZtestsr�r�rrr�assertSelectMultiple�sz%TestSoupSelector.assertSelectMultiplecCsF|j�d�}|�t|�d�|�|djd�|�|djdg�dS)Nrhr=rz	The title)r$r�rr,rNr�)r�elsrrr�test_one_tag_one�sz!TestSoupSelector.test_one_tag_onecCsX|j�d�}|�t|�d�x|D]}|�|jd�q"W|j�d�}|�d|d�dS)Nra��mainr)r$r�rr,rN�
select_one)rr�rar�rrr�test_one_tag_many�s
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$r�r)rr�rrr�test_tag_in_tag_one�sz$TestSoupSelector.test_tag_in_tag_onecCs&x dD]}|�|ddddg�qWdS)N)zhtml divz
html body divzbody divr�r�r��footer)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|�t|j�d��d�dS)N�delr)rr,r$r�)rrrr�test_tag_no_match�sz"TestSoupSelector.test_tag_no_matchcCs|�t|jjd�dS)Nztag%t)r�r�r$r�)rrrr�test_invalid_tag�sz!TestSoupSelector.test_invalid_tagcCs|�dddg�dS)Nzcustom-dashed-tag�dash1�dash2)r)rrrr�test_select_dashed_tag_ids�sz+TestSoupSelector.test_select_dashed_tag_idscCs6|j�d�}|�|djd�|�|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�d�djd�dS)Nzbody > custom-dashed-tagrzHello there.)rr$r�r))rrrr�test_dashed_tag_text�sz%TestSoupSelector.test_dashed_tag_textcCs |�|j�d�|j�d��dS)Nzcustom-dashed-tag)rr$r�r-)rrrr�#test_select_dashed_matches_find_all�sz4TestSoupSelector.test_select_dashed_matches_find_allcCs|�ddgfdddgf�dS)NZh1�header1Zh2�header2�header3)r�)rrrr�test_header_tags�sz!TestSoupSelector.test_header_tagscCsVxPdD]H}|j�|�}|�t|�d�|�|djd�|�|dddg�qWdS)N)z.onepzp.onepzhtml p.onepr=rr�rm�onep)r$r�rr,rN)rr�r�rrr�test_class_one�s

zTestSoupSelector.test_class_onecCs |j�d�}|�t|�d�dS)Nzdiv.onepr)r$r�rr,)rr�rrr�test_class_mismatched_tag�sz*TestSoupSelector.test_class_mismatched_tagcCs xdD]}|�|dg�qWdS)N)z	div#innerz#innerz
div div#innerr�)r)rr�rrr�test_one_id�s
zTestSoupSelector.test_one_idcCs |j�d�}|�t|�d�dS)Nz
#doesnotexistr)r$r�rr,)rr�rrr�test_bad_id�szTestSoupSelector.test_bad_idcCsf|j�d�}|�t|�d�x|D]}|�|jd�q"W|�|dddg�|�|d�d��dS)Nzdiv#inner pr9r�r=rmr�r)r$r�rr,rNr2r1)rr�r�rrr�test_items_in_ids
z!TestSoupSelector.test_items_in_idcCs*x$dD]}|�t|j�|��d�qWdS)N)zdiv#main delzdiv#main div.oopszdiv div#mainr)rr,r$r�)rr�rrr�test_a_bunch_of_emptys	s
z'TestSoupSelector.test_a_bunch_of_emptyscCs xdD]}|�|dg�qWdS)N)z.class1zp.class1z.class2zp.class2z.class3zp.class3z
html p.class2zdiv#inner .class2�pmulti)r)rr�rrr�test_multi_class_support
s
z)TestSoupSelector.test_multi_class_supportcCs xdD]}|�|dg�qWdS)N)z.class1.class3z.class3.class2z.class1.class2.class3r�)r)rr�rrr�test_multi_class_selections
z+TestSoupSelector.test_multi_class_selectioncCs"|�dddg�|�ddg�dS)Nz.s1 > a�s1a1�s1a2z.s1 > a span�s1a2s1)r)rrrr�test_child_selectorsz$TestSoupSelector.test_child_selectorcCs|�ddg�dS)Nz.s1 > a#s1a2 spanr�)r)rrrr�test_child_selector_idsz'TestSoupSelector.test_child_selector_idcCst|�ddgfddgfddgfddgfddgfddgfd	dgfd
gfddgfddgfd
dgfdgfdgfdgf�dS)Nzp[class="onep"]�p1z
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_equalssz&TestSoupSelector.test_attribute_equalsc
Cs\|�ddgfddgfddgfddgfddgfddgfdd	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_tilde0sz%TestSoupSelector.test_attribute_tildecCsv|�ddgfddgfdgfdgfdgfddgfdd	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_startswithcCsH|�ddgfddgfddgfdddddd	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_endswithOsz(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"]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_containsYs.



z(TestSoupSelector.test_attribute_containscCs2|�ddddgfddddgfddgfdgf�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_hypenvs
z.TestSoupSelector.test_attribute_exact_or_hypencCsV|�ddddgfddgfdddgfddd	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�}|�d�\}|�d|j�dS)Nz]<div style="display: wrong">nope</div>
        <div style="display: right">yes</div>
        zhtml.parserzdiv[style="display: right"]Zyes)rr�rr)rr�r$Zchosenrrr�"test_quoted_space_in_selector_name�s
z3TestSoupSelector.test_quoted_space_in_selector_namecCs(|�t|jjd�|�t|jjd�dS)Nza:no-such-pseudoclassza:nth-of-type(a))r�rr$r�)rrrr�test_unsupported_pseudoclass�sz-TestSoupSelector.test_unsupported_pseudoclasscCs�|j�d�}|�t|�d�|�|djd�|j�d�}|�t|�d�|�|djd�|j�d�}|�t|�d�|�t|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|j�d�}|�t|�d�|�|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|�ddg�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�}|�d�}|�|ddg�dS)Nrar�)rr�r�)r$r%r�r)rr�Zselectedrrr�test_select_on_element�s
z'TestSoupSelector.test_select_on_elementcCs|�ddg�|�dg�dS)Nz
.fancy #innerr�z.normal #inner)r)rrrr�test_overspecified_child_id�sz,TestSoupSelector.test_overspecified_child_idcCsB|�ddg�|�ddg�|�ddg�|�g|j�d��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|�dddg�|�ddg�|�ddg�|�ddg�|�g|j�d��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|�t|jjd�dS)Nzh1 >)r�r�r$r�)rrrr�test_dangling_combinator�sz)TestSoupSelector.test_dangling_combinatorcCs|�ddddg�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|�dddg�dS)Nzx, y�xid�yid)r)rrrr�test_multiple_select�sz%TestSoupSelector.test_multiple_selectcCs|�dddg�dS)Nzx,yr�r�)r)rrrr�"test_multiple_select_with_no_space�sz3TestSoupSelector.test_multiple_select_with_no_spacecCs|�dddg�dS)Nzx,    yr�r�)r)rrrr�$test_multiple_select_with_more_space�sz5TestSoupSelector.test_multiple_select_with_more_spacecCs|�ddg�dS)Nzx, xr�)r)rrrr�test_multiple_select_duplicated�sz0TestSoupSelector.test_multiple_select_duplicatedcCs|�dddg�dS)Nzx, y ~ p[lang=fr]r�zlang-fr)r)rrrr�test_multiple_select_sibling�sz-TestSoupSelector.test_multiple_select_siblingcCs|�dddg�dS)Nzx, y > zr��zidb)r)rrrr�.test_multiple_select_tag_and_direct_descendant�sz?TestSoupSelector.test_multiple_select_tag_and_direct_descendantc	Cs|�dddddddg�dS)Nz
div > x, y, zr�r��zidar��zidab�zidac)r)rrrr�/test_multiple_select_direct_descendant_and_tags�sz@TestSoupSelector.test_multiple_select_direct_descendant_and_tagsc	Cs|�dddddddg�dS)Nzdiv x,y,  zr�r�r�r�r�r�)r)rrrr�(test_multiple_select_indirect_descendant�sz9TestSoupSelector.test_multiple_select_indirect_descendantcCs(|�t|jjd�|�t|jjd�dS)Nz,x, yzx,,y)r�r�r$r�)rrrr�test_invalid_multiple_select�sz-TestSoupSelector.test_invalid_multiple_selectcCs|�dddg�dS)Nzp[lang=en], p[lang=en-gb]zlang-enz
lang-en-gb)r)rrrr�test_multiple_select_attrs�sz+TestSoupSelector.test_multiple_select_attrscCs|�ddddg�dS)Nz*x, y > z[id=zida], z[id=zidab], z[id=zidb]r�r�r�)r)rrrr�test_multiple_select_ids�sz)TestSoupSelector.test_multiple_select_idscCs|�dddg�dS)Nzbody > div > x, y > zr�r�)r)rrrr�test_multiple_select_nested�sz,TestSoupSelector.test_multiple_select_nestedN)=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�r�r�r�r�r�r�r�r�r�r�r�r�rrrrr�kst1
	
	r�)2r1ZpdbrrSrMr6r+Zbs4rZbs4.builderrrZbs4.elementrrrr	r
rrr
Zbs4.testingrrr�r�ZLXML_PRESENTrr!r2rLrPrdr�r�r�r�r�r�r�r�r�r�r'rBrLr`rr�r�rrrr�<module>
sN(
;N83(3--*"n'a4*