U
    }gH                     @   s   U d dl Z d dlZd dlmZmZ d dlmZmZmZm	Z	 d dl
mZ ddlmZmZ e	e ed< erd dlmZmZ eZeeed	k reZe jje d
dG dd deZdS )    N)BeautifulSoup	ResultSet)AnyListTupleType)Version   )SoupTestSOUP_SIEVE_PRESENT.SOUPSIEVE_EXCEPTION_ON_UNSUPPORTED_PSEUDOCLASS)__version__SelectorSyntaxErrorz2.6zSoup Sieve not installed)reasonc                   @   s2  e Zd ZdZdZdd Zeee eddddZ	e	Z
eeee f d	d
dZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Z d4d5 Z!d6d7 Z"d8d9 Z#d:d; Z$d<d= Z%d>d? Z&d@dA Z'dBdC Z(dDdE Z)dFdG Z*dHdI Z+dJdK Z,dLdM Z-dNdO Z.dPdQ Z/dRdS Z0dTdU Z1dVdW Z2dXdY Z3dZd[ Z4d\d] Z5d^d_ Z6d`da Z7dbdc Z8ddde Z9dfdg Z:dhdi Z;djdk Z<dldm Z=dndo Z>dpdq Z?drds Z@dtdu ZAdvdw ZBdxdy ZCdzd{ ZDd|d} ZEd~d ZFdd ZGdd ZHdS )TestCSSSelectorszTest basic CSS selector functionality.

    This functionality is implemented in soupsieve, which has a much
    more comprehensive test suite, so this is basically an extra check
    that soupsieve works as expected.
    a  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>The title</title>
<link rel="stylesheet" href="blah.css" type="text/css" id="l1">
</head>
<body>
<custom-dashed-tag class="dashed" id="dash1">Hello there.</custom-dashed-tag>
<div id="main" class="fancy">
<div id="inner">
<h1 id="header1">An H1</h1>
<p>Some text</p>
<p class="onep" id="p1">Some more text</p>
<h2 id="header2">An H2</h2>
<p class="class1 class2 class3" id="pmulti">Another</p>
<a href="http://bob.example.org/" rel="friend met" id="bob">Bob</a>
<h2 id="header3">Another H2</h2>
<a id="me" href="http://simonwillison.net/" rel="me">me</a>
<span class="s1">
<a href="#" id="s1a1">span1a1</a>
<a href="#" id="s1a2">span1a2 <span id="s1a2s1">test</span></a>
<span class="span2">
<a href="#" id="s2a1">span2a1</a>
</span>
<span class="span3"></span>
<custom-dashed-tag class="dashed" id="dash2"/>
<div data-tag="dashedvalue" id="data1"/>
</span>
</div>
<x id="xid">
<z id="zida"/>
<z id="zidab"/>
<z id="zidac"/>
</x>
<y id="yid">
<z id="zidb"/>
</y>
<p lang="en" id="lang-en">English</p>
<p lang="en-gb" id="lang-en-gb">English UK</p>
<p lang="en-us" id="lang-en-us">English US</p>
<p lang="fr" id="lang-fr">French</p>
</div>

<div id="footer">
</div>
c                 C   s   t | jd| _d S )Nhtml.parser)r   HTML_soupself r   6/tmp/pip-unpacked-wheel-kgiupv3k/bs4/tests/test_css.pysetup_method^   s    zTestCSSSelectors.setup_methodN)selectorexpected_idskwargsreturnc                 K   sf   | j j|f|}t|tstdd |D }|  |  ||ksbtd|d|d|f d S )Nc                 S   s   g | ]}|d  qS idr   ).0elr   r   r   
<listcomp>f   s     z7TestCSSSelectors.assert_css_selects.<locals>.<listcomp>z$Selector %s, expected [%s], got [%s]z, )r   select
isinstancer   AssertionErrorsortjoin)r   r   r   r   resultsZel_idsr   r   r   assert_css_selectsa   s    z#TestCSSSelectors.assert_css_selects)testsc                 G   s   |D ]\}}|  || qd S )Nr(   )r   r)   r   r   r   r   r   assert_css_select_multipleq   s    z+TestCSSSelectors.assert_css_select_multiplec                 C   sb   | j jd}| j |}t|dks*t|D ]}|jdks.tq.| j |}d|d ks^td S Ndiv   mainr   )r   csscompiler"   lenr$   name
select_one)r   selelsr-   r    r   r   r   test_precompiledu   s    z!TestCSSSelectors.test_precompiledc                 C   sF   | j d}t|dkst|d jdks.t|d jdgksBtd S )Ntitler	   r   z	The title)r   r"   r2   r$   r3   contentsr   r6   r   r   r   test_one_tag_one   s    z!TestCSSSelectors.test_one_tag_onec                 C   sT   | j d}t|dkst|D ]}|jdks tq | j d}d|d ksPtd S r,   )r   r"   r2   r$   r3   r4   )r   r6   r-   r    r   r   r   test_one_tag_many   s    z"TestCSSSelectors.test_one_tag_manyc                 C   s   | j d}d |kstd S )NZnonexistenttag)r   r4   r$   )r   matchr   r   r   (test_select_one_returns_none_if_no_match   s    z9TestCSSSelectors.test_select_one_returns_none_if_no_matchc                 C   s   |  dddg d S )Nzdiv divinnerdata1r*   r   r   r   r   test_tag_in_tag_one   s    z$TestCSSSelectors.test_tag_in_tag_onec                 C   s"   dD ]}|  |ddddg qd S )N)html divhtml body divbody divr@   r/   r?   footerr*   r   r   r   r   r   test_tag_in_tag_many   s    z%TestCSSSelectors.test_tag_in_tag_manyc                 C   sB   | j ddgdd | j dddgdd | j dd	ddd
gdd d S )NrB   r/   r	   )limitrC   r?      rD   r@   rE   
   r*   r   r   r   r   
test_limit   s     
 zTestCSSSelectors.test_limitc                 C   s   t | jddkstd S )Ndelr   r2   r   r"   r$   r   r   r   r   test_tag_no_match   s    z"TestCSSSelectors.test_tag_no_matchc              	   C   s&   t t | jd W 5 Q R X d S )Nztag%tpytestraisesr   r   r"   r   r   r   r   test_invalid_tag   s    z!TestCSSSelectors.test_invalid_tagc                 C   s   |  dddg d S )Ncustom-dashed-tagdash1dash2r*   r   r   r   r   test_select_dashed_tag_ids   s    z+TestCSSSelectors.test_select_dashed_tag_idsc                 C   s6   | j d}|d jdkst|d d dks2td S )Nzcustom-dashed-tag[id="dash2"]r   rS   r   rU   )r   r"   r3   r$   )r   Zdashedr   r   r   test_select_dashed_by_id   s    z)TestCSSSelectors.test_select_dashed_by_idc                 C   s   | j dd jdkstd S )Nzbody > custom-dashed-tagr   zHello there.)r   r"   textr$   r   r   r   r   test_dashed_tag_text   s    z%TestCSSSelectors.test_dashed_tag_textc                 C   s    | j d| j dkstd S )NrS   )r   r"   find_allr$   r   r   r   r   #test_select_dashed_matches_find_all   s    z4TestCSSSelectors.test_select_dashed_matches_find_allc                 C   s   |  ddgfdddgf d S )Nh1header1h2header2header3r+   r   r   r   r   test_header_tags   s    
z!TestCSSSelectors.test_header_tagsc                 C   sR   dD ]H}| j |}t|dks$t|d jdks6t|d d dgkstqd S )N)z.onepzp.onepzhtml p.onepr	   r   pclassonep)r   r"   r2   r$   r3   )r   r   r6   r   r   r   test_class_one   s
    zTestCSSSelectors.test_class_onec                 C   s    | j d}t|dkstd S )Nzdiv.onepr   r   r"   r2   r$   r:   r   r   r   test_class_mismatched_tag   s    z*TestCSSSelectors.test_class_mismatched_tagc                 C   s   dD ]}|  |dg qd S )N)z	div#innerz#innerzdiv div#innerr?   r*   rF   r   r   r   test_one_id   s    zTestCSSSelectors.test_one_idc                 C   s    | j d}t|dkstd S )Nz#doesnotexistr   rg   r:   r   r   r   test_bad_id   s    zTestCSSSelectors.test_bad_idc                 C   s`   | j d}t|dkst|D ]}|jdks tq |d d dgksJt|d dr\td S )Nzdiv#inner p   rc   r	   rd   re   r   )r   r"   r2   r$   r3   Zhas_attr)r   r6   r    r   r   r   test_items_in_id   s    z!TestCSSSelectors.test_items_in_idc                 C   s&   dD ]}t | j|dkstqd S )N)zdiv#main delzdiv#main div.oopszdiv div#mainr   rM   rF   r   r   r   test_a_bunch_of_emptys   s    z'TestCSSSelectors.test_a_bunch_of_emptysc                 C   s   dD ]}|  |dg qd S )N)z.class1zp.class1z.class2zp.class2z.class3zp.class3zhtml p.class2zdiv#inner .class2pmultir*   rF   r   r   r   test_multi_class_support   s    
z)TestCSSSelectors.test_multi_class_supportc                 C   s   dD ]}|  |dg qd S )N)z.class1.class3z.class3.class2z.class1.class2.class3rn   r*   rF   r   r   r   test_multi_class_selection   s    z+TestCSSSelectors.test_multi_class_selectionc                 C   s"   |  dddg |  ddg d S )Nz.s1 > as1a1s1a2z.s1 > a spans1a2s1r*   r   r   r   r   test_child_selector   s    z$TestCSSSelectors.test_child_selectorc                 C   s   |  ddg d S )Nz.s1 > a#s1a2 spanrs   r*   r   r   r   r   test_child_selector_id   s    z'TestCSSSelectors.test_child_selector_idc                 C   st   |  ddgfddgfddgfddgfddgfddgfd	dgfd
g fddgfddgfddgfdg fdg fdg f d S )Nzp[class="onep"]p1z
p[id="p1"]z[class="onep"]z	[id="p1"]zlink[rel="stylesheet"]l1zlink[type="text/css"]zlink[href="blah.css"]zlink[href="no-blah.css"]z[rel="stylesheet"]z[type="text/css"]z[href="blah.css"]z[href="no-blah.css"]zp[href="no-blah.css"]ra   r   r   r   r   test_attribute_equals   s     z&TestCSSSelectors.test_attribute_equalsc                 C   s\   |  ddgfddgfddgfddgfddgfddgfdd	gfd
d	gfdd	gfdd	gf
 d S )Nzp[class~="class1"]rn   zp[class~="class2"]zp[class~="class3"]z[class~="class1"]z[class~="class2"]z[class~="class3"]za[rel~="friend"]bobza[rel~="met"]z[rel~="friend"]z[rel~="met"]ra   r   r   r   r   test_attribute_tilde  s    z%TestCSSSelectors.test_attribute_tildec                 C   sv   |  ddgfddgfdg fdg fdg fddgfdd	d
gfdd	d
gfdddgfdd
dgfddgfdd
gfddgf d S )Nz[rel^="style"]rw   zlink[rel^="style"]znotlink[rel^="notstyle"]z[rel^="notstyle"]zlink[rel^="notstyle"]zlink[href^="bla"]za[href^="http://"]ry   mez[href^="http://"]z	[id^="p"]rn   rv   z	[id^="m"]r/   zdiv[id^="m"]z
a[id^="m"]zdiv[data-tag^="dashed"]r@   ra   r   r   r   r   test_attribute_startswith  s    



z*TestCSSSelectors.test_attribute_startswithc                 C   sH   |  ddgfddgfddgfdddddd	d
ddgfddgfdg f d S )Nz[href$=".css"]rw   zlink[href$=".css"]zlink[id$="1"]z	[id$="1"]r@   rv   r]   rq   s2a1rs   rT   zdiv[id$="1"]z[id$="noending"]ra   r   r   r   r   test_attribute_endswith&  s    z(TestCSSSelectors.test_attribute_endswithc                 C   s   |  ddgfddgfdg fdg fdg fddgfdd	d
gfdddgfddgfdd
gfddgfddgfddgfddddddddddg	fddgfdg fdd	d
dgfdd	d
gfd dgfd!dd"gfd#d"gfd$dgf d S )%Nz[rel*="style"]rw   zlink[rel*="style"]znotlink[rel*="notstyle"]z[rel*="notstyle"]zlink[rel*="notstyle"]zlink[href*="bla"]z[href*="http://"]ry   r{   z	[id*="p"]rn   rv   zdiv[id*="m"]r/   z
a[id*="m"]z[href*=".css"]zlink[href*=".css"]zlink[id*="1"]z	[id*="1"]r@   r]   rq   rr   r}   rs   rT   zdiv[id*="1"]z[id*="noending"]z[href*="."]za[href*="."]zlink[href*="."]zdiv[id*="n"]r?   zdiv[id*="nn"]zdiv[data-tag*="edval"]ra   r   r   r   r   test_attribute_contains3  sF    



z(TestCSSSelectors.test_attribute_containsc                 C   s2   |  ddddgfddddgfddgfdg f d S )	Nzp[lang|="en"]lang-en
lang-en-gb
lang-en-usz[lang|="en"]zp[lang|="fr"]lang-frzp[lang|="gb"]ra   r   r   r   r   test_attribute_exact_or_hypen]  s    z.TestCSSSelectors.test_attribute_exact_or_hypenc                 C   sV   |  ddddgfddgfdddgfddd	d
dgfdddgfdg fdg fddgf d S )Nz[rel]rw   ry   r{   z	link[rel]za[rel]z[lang]r   r   r   r   zp[class]rv   rn   z[blah]zp[blah]zdiv[data-tag]r@   ra   r   r   r   r   test_attribute_existse  s    

z&TestCSSSelectors.test_attribute_existsc                 C   s,   d}t |d}|d\}d|jks(td S )Nz]<div style="display: wrong">nope</div>
        <div style="display: right">yes</div>
        r   zdiv[style="display: right"]yes)r   r"   stringr$   )r   htmlsoupZchosenr   r   r   "test_quoted_space_in_selector_nameq  s    
z3TestCSSSelectors.test_quoted_space_in_selector_namec              	   C   sH   t t | jd W 5 Q R X t t | jd W 5 Q R X d S )Nza:no-such-pseudoclassza:nth-of-type(a))rP   rQ   r   r   r"   r   r   r   r   r   test_unsupported_pseudoclassy  s    z-TestCSSSelectors.test_unsupported_pseudoclassc                 C   s   | j d}t|dkst|d jdks.t| j d}t|dksJt|d jdks\t| j d}t|dksxt| j d}t|dkstd S )	Nzdiv#inner p:nth-of-type(1)r	   r   	Some textzdiv#inner p:nth-of-type(3)ZAnotherzdiv#inner p:nth-of-type(4)zdiv p:nth-of-type(0)r   r"   r2   r$   r   r:   r   r   r   test_nth_of_type  s    z!TestCSSSelectors.test_nth_of_typec                 C   s2   | j d}t|dkst|d jdks.td S )Nzdiv#inner > p:nth-of-type(1)r	   r   r   r   r:   r   r   r   "test_nth_of_type_direct_descendant  s    z3TestCSSSelectors.test_nth_of_type_direct_descendantc                 C   s   |  ddg d S )Nz#inner > p:nth-of-type(2)rv   r*   r   r   r   r   "test_id_child_selector_nth_of_type  s    z3TestCSSSelectors.test_id_child_selector_nth_of_typec                 C   s.   | j jddd}|d}| |ddg d S )Nr-   r/   r   r?   r@   )r   findr"   Zassert_selects_ids)r   r?   selectedr   r   r   test_select_on_element  s    
z'TestCSSSelectors.test_select_on_elementc                 C   s   |  ddg |  dg  d S )Nz.fancy #innerr?   z.normal #innerr*   r   r   r   r   test_overspecified_child_id  s    z,TestCSSSelectors.test_overspecified_child_idc                 C   sB   |  ddg |  ddg |  ddg g | jdks>td S )Nz#p1 + h2r_   z#p1 + h2 + prn   z#p1 + #header2 + .class1z#p1 + pr(   r   r"   r$   r   r   r   r   test_adjacent_sibling_selector  s    z/TestCSSSelectors.test_adjacent_sibling_selectorc                 C   sR   |  dddg |  ddg |  ddg |  ddg g | jdksNtd S )	Nz#p1 ~ h2r_   r`   z#p1 ~ #header2z#p1 ~ h2 + ar{   z#p1 ~ h2 + [rel="me"]z#inner ~ h2r   r   r   r   r   test_general_sibling_selector  s
    z.TestCSSSelectors.test_general_sibling_selectorc              	   C   s&   t t | jd W 5 Q R X d S )Nzh1 >rO   r   r   r   r   test_dangling_combinator  s    z)TestCSSSelectors.test_dangling_combinatorc                 C   s   |  ddddg d S )Nzp[lang] ~ pr   r   r   r*   r   r   r   r   2test_sibling_combinator_wont_select_same_tag_twice  s    zCTestCSSSelectors.test_sibling_combinator_wont_select_same_tag_twicec                 C   s   |  dddg d S )Nzx, yxidyidr*   r   r   r   r   test_multiple_select  s    z%TestCSSSelectors.test_multiple_selectc                 C   s   |  dddg d S )Nzx,yr   r   r*   r   r   r   r   "test_multiple_select_with_no_space  s    z3TestCSSSelectors.test_multiple_select_with_no_spacec                 C   s   |  dddg d S )Nzx,    yr   r   r*   r   r   r   r   $test_multiple_select_with_more_space  s    z5TestCSSSelectors.test_multiple_select_with_more_spacec                 C   s   |  ddg d S )Nzx, xr   r*   r   r   r   r   test_multiple_select_duplicated  s    z0TestCSSSelectors.test_multiple_select_duplicatedc                 C   s   |  dddg d S )Nzx, y ~ p[lang=fr]r   r   r*   r   r   r   r   test_multiple_select_sibling  s    z-TestCSSSelectors.test_multiple_select_siblingc                 C   s   |  dddg d S )Nzx, y > zr   zidbr*   r   r   r   r   .test_multiple_select_tag_and_direct_descendant  s    z?TestCSSSelectors.test_multiple_select_tag_and_direct_descendantc              	   C   s   |  dddddddg d S )Nzdiv > x, y, zr   r   zidar   zidabzidacr*   r   r   r   r   /test_multiple_select_direct_descendant_and_tags  s     z@TestCSSSelectors.test_multiple_select_direct_descendant_and_tagsc              	   C   s   |  dddddddg d S )Nzdiv x,y,  zr   r   r   r   r   r   r*   r   r   r   r   (test_multiple_select_indirect_descendant  s     z9TestCSSSelectors.test_multiple_select_indirect_descendantc              	   C   sH   t t | jd W 5 Q R X t t | jd W 5 Q R X d S )Nz,x, yzx,,yrO   r   r   r   r   test_invalid_multiple_select  s    z-TestCSSSelectors.test_invalid_multiple_selectc                 C   s   |  dddg d S )Nzp[lang=en], p[lang=en-gb]r   r   r*   r   r   r   r   test_multiple_select_attrs  s    z+TestCSSSelectors.test_multiple_select_attrsc                 C   s   |  ddddg d S )Nz*x, y > z[id=zida], z[id=zidab], z[id=zidb]r   r   r   r*   r   r   r   r   test_multiple_select_ids  s     z)TestCSSSelectors.test_multiple_select_idsc                 C   s   |  dddg d S )Nzbody > div > x, y > zr   r   r*   r   r   r   r   test_multiple_select_nested  s    z,TestCSSSelectors.test_multiple_select_nestedc                 C   sN   d}t |d}|d}dt|ks(t|jddgdD ]}||ks8tq8d S )Nz3<div class="c1"/><div class="c2"/><div class="c1"/>r   z.c1, .c2rk   Zc1c2)class_)r   r"   r2   r$   rZ   )r   Zmarkupr   r   elementr   r   r   test_select_duplicate_elements  s    

z/TestCSSSelectors.test_select_duplicate_elementsc                 C   s8   | j jddd}|jd}|| j jdddks4td S )Nr-   r?   r   div[id=main]r/   )r   r   r0   closestr$   )r   r?   r   r   r   r   test_closest  s    zTestCSSSelectors.test_closestc                 C   sL   | j jddd}| j jddd}|jddks4t|jddksHtd S )Nr-   r?   r   r/   r   FT)r   r   r0   r=   r$   )r   r?   r/   r   r   r   
test_match  s    zTestCSSSelectors.test_matchc                 C   sJ   | j jd}t|tjst|\}}|d dks6t|d dksFtd S )Nr^   r   r_   r`   )r   r0   Ziselectr#   typesGeneratorTyper$   )r   genr_   r`   r   r   r   test_iselect  s
    zTestCSSSelectors.test_iselectc                 C   sh   | j jddd}|jd}t|jddks4t|jd}t|tsNt|\}|d dksdtd S )	Nr-   r?   r   r^   rI   zh2[id=header3]r   r`   )r   r   r0   filterr2   r$   r#   r   )r   r?   r'   resultr   r   r   test_filter
  s    zTestCSSSelectors.test_filterc                 C   sH   | j jj}|ddkst|ddks*t|d| j jdksDtd S )Nz.foo#barz
\.foo\#barz()[]{}z\(\)\[\]\{\}z.foo)r   r0   escaper$   )r   mr   r   r   test_escape  s    
zTestCSSSelectors.test_escape)I__name__
__module____qualname____doc__r   r   strr   r   r(   ZassertSelectr   r+   r7   r;   r<   r>   rA   rG   rK   rN   rR   rV   rW   rY   r[   rb   rf   rh   ri   rj   rl   rm   ro   rp   rt   ru   rx   rz   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   $   s   1  	*	
r   )rP   r   Zbs4r   r   typingr   r   r   r   Zpackaging.versionr    r
   r   	Exception__annotations__Z	soupsiever   r   r   NotImplementedErrormarkZskipifr   r   r   r   r   <module>   s    