o
    RhC                     @   sv   d dl Z d dlZd dlmZ d dlmZmZmZ ddlm	Z	m
Z
 e
r(d dlmZ e jje
 ddG d	d
 d
e	ZdS )    N)	MagicMock)CSSBeautifulSoup	ResultSet   )SoupTestSOUP_SIEVE_PRESENT)SelectorSyntaxErrorzSoup Sieve not installed)reasonc                   @   s  e Zd ZdZdZdd Zdd ZeZdd Zd	d
 Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!d;d< Z"d=d> Z#d?d@ Z$dAdB Z%dCdD Z&dEdF Z'dGdH Z(dIdJ Z)dKdL Z*dMdN Z+dOdP Z,dQdR Z-dSdT Z.dUdV Z/dWdX Z0dYdZ Z1d[d\ Z2d]d^ Z3d_d` Z4dadb Z5dcdd Z6dedf Z7dgdh Z8didj Z9dkdl Z:dmdn Z;dodp Z<dqdr Z=dsdt Z>dudv Z?dwdx Z@dydz ZAd{d| ZBd}d~ ZCdd ZDdS )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   T/home/air/sanwanet/backup_V2/venv/lib/python3.10/site-packages/bs4/tests/test_css.pysetup_methodN      zTestCSSSelectors.setup_methodc                 K   sj   | j j|fi |}t|tsJ dd |D }|  |  ||ks3J d|d|d|f d S )Nc                 S   s   g | ]}|d  qS idr   ).0elr   r   r   
<listcomp>T   s    z3TestCSSSelectors.assert_selects.<locals>.<listcomp>z$Selector %s, expected [%s], got [%s]z, )r   select
isinstancer   sortjoin)r   selectorexpected_idskwargsresultsel_idsr   r   r   assert_selectsQ   s   zTestCSSSelectors.assert_selectsc                 G   s   |D ]
\}}|  || qd S )Nr#   )r   testsr   r   r   r   r   assert_select_multiple]   s   z'TestCSSSelectors.assert_select_multiplec                 C   sb   | j jd}| j |}t|dksJ |D ]	}|jdks J q| j |}d|d ks/J d S Ndiv   mainr   )r   csscompiler   lenname
select_one)r   selelsr(   r   r   r   r   test_precompileda   s   z!TestCSSSelectors.test_precompiledc                 C   sF   | j d}t|dksJ |d jdksJ |d jdgks!J d S )Ntitler   r   z	The title)r   r   r-   r.   contentsr   r1   r   r   r   test_one_tag_onel   s   z!TestCSSSelectors.test_one_tag_onec                 C   sT   | j d}t|dksJ |D ]	}|jdksJ q| j d}d|d ks(J d S r'   )r   r   r-   r.   r/   )r   r1   r(   r   r   r   r   test_one_tag_manyr   s   z"TestCSSSelectors.test_one_tag_manyc                 C   s   | j d}d |ksJ d S )Nnonexistenttag)r   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    | j d}| dddg d S )Nzdiv divinnerdata1)r   r   r#   r5   r   r   r   test_tag_in_tag_one      z$TestCSSSelectors.test_tag_in_tag_onec                 C   s   dD ]
}|  |g d qd S )N)html divhtml body divbody divr<   r*   r;   footerr$   r   r   r   r   r   test_tag_in_tag_many   s   z%TestCSSSelectors.test_tag_in_tag_manyc                 C   s>   | j ddgdd | j dddgdd | j dg d	d
d d S )Nr?   r*   r   )limitr@   r;      rA   rB   
   r$   r   r   r   r   
test_limit   s
   
zTestCSSSelectors.test_limitc                 C   s   t | jddksJ d S )Ndelr   r-   r   r   r   r   r   r   test_tag_no_match   s   z"TestCSSSelectors.test_tag_no_matchc                 C   <   t t | jd W d    d S 1 sw   Y  d S )Nztag%tpytestraisesr	   r   r   r   r   r   r   test_invalid_tag      "z!TestCSSSelectors.test_invalid_tagc                 C      |  dddg d S )Ncustom-dashed-tagdash1dash2r$   r   r   r   r   test_select_dashed_tag_ids      z+TestCSSSelectors.test_select_dashed_tag_idsc                 C   s6   | j d}|d jdksJ |d d dksJ d S )Nzcustom-dashed-tag[id="dash2"]r   rT   r   rV   )r   r   r.   )r   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J d S )Nzbody > custom-dashed-tagr   zHello there.)r   r   textr   r   r   r   test_dashed_tag_text   s   z%TestCSSSelectors.test_dashed_tag_textc                 C   s    | j d| j dksJ d S )NrT   )r   r   find_allr   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 ]$}| j |}t|dksJ |d jdksJ |d d dgks&J qd S )N)z.onepzp.onepzhtml p.onepr   r   pclassonep)r   r   r-   r.   )r   r   r1   r   r   r   test_class_one   s   zTestCSSSelectors.test_class_onec                 C       | j d}t|dksJ d S )Nzdiv.onepr   r   r   r-   r5   r   r   r   test_class_mismatched_tag   r>   z*TestCSSSelectors.test_class_mismatched_tagc                 C      dD ]	}|  |dg qd S )N)z	div#innerz#innerzdiv div#innerr;   r$   rD   r   r   r   test_one_id   s   zTestCSSSelectors.test_one_idc                 C   rj   )Nz#doesnotexistr   rk   r5   r   r   r   test_bad_id   r>   zTestCSSSelectors.test_bad_idc                 C   s`   | j d}t|dksJ |D ]	}|jdksJ q|d d dgks%J |d dr.J d S )Nzdiv#inner p   rf   r   rg   rh   r   )r   r   r-   r.   has_attr)r   r1   r   r   r   r   test_items_in_id   s   z!TestCSSSelectors.test_items_in_idc                 C   s&   dD ]}t | j|dksJ qd S )N)zdiv#main delzdiv#main div.oopszdiv div#mainr   rK   rD   r   r   r   test_a_bunch_of_emptys   s   z'TestCSSSelectors.test_a_bunch_of_emptysc                 C   rm   )N)z.class1zp.class1z.class2zp.class2z.class3zp.class3zhtml p.class2zdiv#inner .class2pmultir$   rD   r   r   r   test_multi_class_support      z)TestCSSSelectors.test_multi_class_supportc                 C   rm   )N)z.class1.class3z.class3.class2z.class1.class2.class3rt   r$   rD   r   r   r   test_multi_class_selection   rv   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      |  ddg d S )Nz.s1 > a#s1a2 spanrz   r$   r   r   r   r   test_child_selector_id   r   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"]rd   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"]rt   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"]rd   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"]r   zlink[rel^="style"]znotlink[rel^="notstyle"]z[rel^="notstyle"]zlink[rel^="notstyle"]zlink[href^="bla"]za[href^="http://"]r   mez[href^="http://"]z	[id^="p"]rt   r~   z	[id^="m"]r*   zdiv[id^="m"]z
a[id^="m"]zdiv[data-tag^="dashed"]r<   rd   r   r   r   r   test_attribute_startswith   s   



z*TestCSSSelectors.test_attribute_startswithc              	   C   s<   |  ddgfddgfddgfdg dfddgfd	g f d S )
Nz[href$=".css"]r   zlink[href$=".css"]zlink[id$="1"]z	[id$="1"])r<   r   r~   r`   rx   s2a1rz   rU   zdiv[id$="1"]r<   z[id$="noending"]rd   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g dfddgfdg fdg dfdd	d
gfddgfdddgfddgfd dgf d S )!Nz[rel*="style"]r   zlink[rel*="style"]znotlink[rel*="notstyle"]z[rel*="notstyle"]zlink[rel*="notstyle"]zlink[href*="bla"]z[href*="http://"]r   r   z	[id*="p"]rt   r~   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   r~   r`   rx   ry   r   rz   rU   zdiv[id*="1"]r<   z[id*="noending"]z[href*="."])r   r   r   za[href*="."]zlink[href*="."]zdiv[id*="n"]r;   zdiv[id*="nn"]zdiv[data-tag*="edval"]rd   r   r   r   r   test_attribute_contains  s0   





z(TestCSSSelectors.test_attribute_containsc                 C   s.   |  dg dfdg dfddgfdg f d S )Nzp[lang|="en"])lang-en
lang-en-gb
lang-en-usz[lang|="en"]zp[lang|="fr"]lang-frzp[lang|="gb"]rd   r   r   r   r   test_attribute_exact_or_hypen2  s   

z.TestCSSSelectors.test_attribute_exact_or_hypenc                 C   sP   |  dg dfddgfdddgfdg d	fd
ddgfdg fdg fddgf d S )Nz[rel])r   r   r   z	link[rel]r   za[rel]r   r   z[lang])r   r   r   r   zp[class]r~   rt   z[blah]zp[blah]zdiv[data-tag]r<   rd   r   r   r   r   test_attribute_exists:  s   



z&TestCSSSelectors.test_attribute_existsc                 C   s,   d}t |d}|d\}d|jksJ d S )Nz]<div style="display: wrong">nope</div>
        <div style="display: right">yes</div>
        r   zdiv[style="display: right"]yes)r   r   string)r   htmlr   chosenr   r   r   "test_quoted_space_in_selector_nameF  s   
z3TestCSSSelectors.test_quoted_space_in_selector_namec                 C   sr   t t | jd W d    n1 sw   Y  t t | jd W d    d S 1 s2w   Y  d S )Nza:no-such-pseudoclassza:nth-of-type(a))rO   rP   NotImplementedErrorr   r   r	   r   r   r   r   test_unsupported_pseudoclassN  s   "z-TestCSSSelectors.test_unsupported_pseudoclassc                 C   s   | j d}t|dksJ |d jdksJ | j d}t|dks%J |d jdks.J | j d}t|dks<J | j d}t|dksJJ d S )	Nzdiv#inner p:nth-of-type(1)r   r   	Some textzdiv#inner p:nth-of-type(3)Anotherzdiv#inner p:nth-of-type(4)zdiv p:nth-of-type(0)r   r   r-   r   r5   r   r   r   test_nth_of_typeU  s   z!TestCSSSelectors.test_nth_of_typec                 C   s2   | j d}t|dksJ |d jdksJ d S )Nzdiv#inner > p:nth-of-type(1)r   r   r   r   r5   r   r   r   "test_nth_of_type_direct_descendanth  s   z3TestCSSSelectors.test_nth_of_type_direct_descendantc                 C   r|   )Nz#inner > p:nth-of-type(2)r~   r$   r   r   r   r   "test_id_child_selector_nth_of_typem  r   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   assert_selects_ids)r   r;   selectedr   r   r   test_select_on_elementp  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_idy  s   z,TestCSSSelectors.test_overspecified_child_idc                 C   sB   |  ddg |  ddg |  ddg g | jdksJ d S )Nz#p1 + h2rb   z#p1 + h2 + prt   z#p1 + #header2 + .class1z#p1 + p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s'J d S )	Nz#p1 ~ h2rb   rc   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   rM   )Nzh1 >rN   r   r   r   r   test_dangling_combinator  rR   z)TestCSSSelectors.test_dangling_combinatorc                 C      |  dg d d S )Nzp[lang] ~ p)r   r   r   r$   r   r   r   r   2test_sibling_combinator_wont_select_same_tag_twice  rX   zCTestCSSSelectors.test_sibling_combinator_wont_select_same_tag_twicec                 C   rS   )Nzx, yxidyidr$   r   r   r   r   test_multiple_select  rX   z%TestCSSSelectors.test_multiple_selectc                 C   rS   )Nzx,yr   r   r$   r   r   r   r   "test_multiple_select_with_no_space  rX   z3TestCSSSelectors.test_multiple_select_with_no_spacec                 C   rS   )Nzx,    yr   r   r$   r   r   r   r   $test_multiple_select_with_more_space  rX   z5TestCSSSelectors.test_multiple_select_with_more_spacec                 C   r|   )Nzx, xr   r$   r   r   r   r   test_multiple_select_duplicated  r   z0TestCSSSelectors.test_multiple_select_duplicatedc                 C   rS   )Nzx, y ~ p[lang=fr]r   r   r$   r   r   r   r   test_multiple_select_sibling  rX   z-TestCSSSelectors.test_multiple_select_siblingc                 C   rS   )Nzx, y > zr   zidbr$   r   r   r   r   .test_multiple_select_tag_and_direct_descendant  rX   z?TestCSSSelectors.test_multiple_select_tag_and_direct_descendantc                 C   r   )Nzdiv > x, y, zr   r   zidar   zidabzidacr$   r   r   r   r   /test_multiple_select_direct_descendant_and_tags  rX   z@TestCSSSelectors.test_multiple_select_direct_descendant_and_tagsc                 C   r   )Nzdiv x,y,  zr   r$   r   r   r   r   (test_multiple_select_indirect_descendant  rX   z9TestCSSSelectors.test_multiple_select_indirect_descendantc                 C   sr   t t | jd W d    n1 sw   Y  t t | jd W d    d S 1 s2w   Y  d S )Nz,x, yzx,,yrN   r   r   r   r   test_invalid_multiple_select  s   "z-TestCSSSelectors.test_invalid_multiple_selectc                 C   rS   )Nzp[lang=en], p[lang=en-gb]r   r   r$   r   r   r   r   test_multiple_select_attrs  rX   z+TestCSSSelectors.test_multiple_select_attrsc                 C   r   )Nz*x, y > z[id=zida], z[id=zidab], z[id=zidb])r   r   r   r$   r   r   r   r   test_multiple_select_ids  rX   z)TestCSSSelectors.test_multiple_select_idsc                 C   rS   )Nzbody > div > x, y > zr   r   r$   r   r   r   r   test_multiple_select_nested  rX   z,TestCSSSelectors.test_multiple_select_nestedc                 C   sN   d}t |d}|d}dt|ksJ |jddgdD ]}||v s$J qd S )Nz3<div class="c1"/><div class="c2"/><div class="c1"/>r   z.c1, .c2rp   c1c2)class_)r   r   r-   r]   )r   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sJ d S )Nr(   r;   r   div[id=main]r*   )r   r   r+   closest)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sJ |jddks$J d S )Nr(   r;   r   r*   r   FT)r   r   r+   r9   )r   r;   r*   r   r   r   
test_match  s   zTestCSSSelectors.test_matchc                 C   sJ   | j jd}t|tjsJ |\}}|d dksJ |d dks#J d S )Nra   r   rb   rc   )r   r+   iselectr   typesGeneratorType)r   genrb   rc   r   r   r   test_iselect  s
   zTestCSSSelectors.test_iselectc                 C   sh   | j jddd}|jd}t|jddksJ |jd}t|ts'J |\}|d dks2J d S )	Nr(   r;   r   ra   rG   zh2[id=header3]r   rc   )r   r   r+   filterr-   r   r   )r   r;   r!   resultr   r   r   test_filter  s   zTestCSSSelectors.test_filterc                 C   sH   | j jj}|ddksJ |ddksJ |d| j jdks"J d S )Nz.foo#barz
\.foo\#barz()[]{}z\(\)\[\]\{\}z.foo)r   r+   escape)r   mr   r   r   test_escape  s   
zTestCSSSelectors.test_escapeN)E__name__
__module____qualname____doc__r   r   r#   assertSelectr&   r2   r6   r7   r:   r=   rE   rI   rL   rQ   rW   rZ   r\   r^   re   ri   rl   rn   ro   rr   rs   ru   rw   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      s    1
	
	
r   )rO   r   unittest.mockr   bs4r   r   r    r   r   	soupsiever	   markskipifr   r   r   r   r   <module>   s    