U
    
W[èt  ã                (   @   s¸   d Z ddlmZ ddlmZ edƒZddlmZ dZ	dZ
d	d
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0g(Zd1d2„ ZG d3d4„ d4eƒZG d5d6„ d6eƒZd7S )8z"
Tests for L{twisted.python.url}.
é    )Úunicode_literalsé   ©ÚURLÚ )ÚSynchronousTestCaseú*http://www.foo.com/a/nice/path/?zot=23&zutúhttp://a/b/c/d;p?q)Úgúhttp://a/b/c/g)z./gr   )zg/úhttp://a/b/c/g/)z/gú
http://a/g)z//gzhttp://g)z?yzhttp://a/b/c/d;p?y)zg?yzhttp://a/b/c/g?y)z#szhttp://a/b/c/d;p?q#s)zg#szhttp://a/b/c/g#s)zg?y#szhttp://a/b/c/g?y#s)z;xzhttp://a/b/c/;x)zg;xzhttp://a/b/c/g;x)zg;x?y#szhttp://a/b/c/g;x?y#s)r   r	   )Ú.úhttp://a/b/c/)z./r   )ú..úhttp://a/b/)z../r   )z../gúhttp://a/b/g)z../..ú	http://a/)z../../r   )z../../gr   )z
../../../gr   )z../../../../gr   )z/./gr   )z/../gr   )zg.zhttp://a/b/c/g.)z.gzhttp://a/b/c/.g)zg..zhttp://a/b/c/g..)z..gzhttp://a/b/c/..g)z./../gr   )z./g/.r   )zg/./hzhttp://a/b/c/g/h)zg/../hzhttp://a/b/c/h)z	g;x=1/./yzhttp://a/b/c/g;x=1/y)z
g;x=1/../yzhttp://a/b/c/y)zg?y/./xzhttp://a/b/c/g?y/./x)zg?y/../xzhttp://a/b/c/g?y/../x)zg#s/./xzhttp://a/b/c/g#s/./x)zg#s/../xzhttp://a/b/c/g#s/../xc                 C   s   d  dd„ | D ƒ¡S )Nr   c                 s   s   | ]}d t |ƒ V  qdS )z%%%02XN)Úord)Ú.0Úc© r   ú>/usr/lib/python3/dist-packages/twisted/python/test/test_url.pyÚ	<genexpr>O   s     z<lambda>.<locals>.<genexpr>)Újoin)Úsr   r   r   Ú<lambda>O   ó    r   c                   @   sz  e Zd ZdZdd„ Z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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„ Z.dYdZ„ Z/d[d\„ Z0d]S )_ÚTestURLz
    Tests for L{URL}.
    c                 C   sº   |   t|jtƒp|jdkt|ƒ¡ |   t|jtƒp:|jdkt|ƒ¡ |jD ]}|  |tt|ƒ¡ qJ|jD ]8\}}|  |tt|ƒ¡ |   |dkp–t|tƒt|ƒ¡ qh|  |j	tt|ƒ¡ dS )zl
        The given L{URL}'s components should be L{unicode}.

        @param u: The L{URL} to test.
        N)
Ú
assertTrueÚ
isinstanceÚschemeÚunicodeÚreprÚhostÚpathZassertIsInstanceÚqueryÚfragment)ÚselfÚuZsegÚkÚvr   r   r   ÚassertUnicodedV   s     ÿ ÿ
 zTestURL.assertUnicodedr   c	                 C   sL   |j |j|j|j|j|j|jf}	||t|ƒt|ƒ|||jf}
|  |	|
¡ dS )aª  
        The given L{URL} should have the given components.

        @param u: The actual L{URL} to examine.

        @param scheme: The expected scheme.

        @param host: The expected host.

        @param path: The expected path.

        @param query: The expected query.

        @param fragment: The expected fragment.

        @param port: The expected port.

        @param userinfo: The expected userinfo.
        N)	r!   r$   r%   r&   r'   ÚportÚuserinfoÚtupleÚassertEqual)r(   r)   r!   r$   r%   r&   r'   r-   r.   ÚactualÚexpectedr   r   r   Ú	assertURLh   s      ÿ  ÿzTestURL.assertURLc                    sD   ‡ fdd„}|t ddƒƒ |t ddg g ƒƒ |t ddg g dƒƒ dS )z@
        L{URL} should have appropriate default values.
        c              
      s&   ˆ   | ¡ ˆ  | ddg g ddd¡ d S )NÚhttpr   éP   )r,   r3   )r)   ©r(   r   r   Úcheckˆ   s    
z(TestURL.test_initDefaults.<locals>.checkr4   r   Nr   )r(   r7   r   r6   r   Útest_initDefaults„   s    zTestURL.test_initDefaultsc              	   C   sj   t dddgddgdƒ}|  |¡ |  |dddgddgdd¡ |  t dd	d
gdgdƒdd	d
gdgdd¡ dS )z=
        L{URL} should accept L{unicode} parameters.
        r   ÚhÚp©r*   r+   )r*   NÚfNr4   õ   Ã õ   Ã©)u   Î»u   Ï€u   âŠ¥r5   ©r   r,   r3   ©r(   r)   r   r   r   Ú	test_init‘   s"    
 ÿ ÿ    ýzTestURL.test_initc              	   C   s@   t dddgddgdƒ}|  |¡ |  |dddgddgdd¡ dS )zN
        L{URL} should accept (and not interpret) percent characters.
        r   z%68z%70)ú%6Bz%76)rB   Nz%66Nr?   r@   r   r   r   Útest_initPercent    s    ÿ
   ýzTestURL.test_initPercentc              
   C   s2   |   ttdddgddgddƒdtd	ƒf ¡ d
S )z¹
        L{URL.__repr__} will display the canonical form of the URL, wrapped in
        a L{URL.fromText} invocation, so that it is C{eval}-able but still easy
        to read.
        r4   ÚfooÚbar)ZbazNr;   Zfrob)r!   r$   r%   r&   r'   zURL.from_text(%s)zhttp://foo/bar?baz&k=v#frobN)r0   r#   r   r6   r   r   r   Ú	test_repr­   s    þüzTestURL.test_reprc                 C   s   t  t¡}|  t| ¡ ¡ dS )zb
        Round-tripping L{URL.fromText} with C{str} results in an equivalent
        URL.
        N)r   ÚfromTextÚtheurlr0   ÚasText©r(   Úurlpathr   r   r   Útest_fromText»   s    
zTestURL.test_fromTextc                 C   s,   d}|D ]}t  |¡ ¡ }|  ||¡ qdS )z>
        L{URL.asText} should invert L{URL.fromText}.
        )zhttp://localhostúhttp://localhost/zhttp://localhost/foozhttp://localhost/foo/zhttp://localhost/foo!!bar/zhttp://localhost/foo%20bar/zhttp://localhost/foo%2Fbar/zhttp://localhost/foo?nzhttp://localhost/foo?n=vzhttp://localhost/foo?n=/a/bz%http://example.com/foo!@$bar?b!@z=123z$http://localhost/asd?a=asd%20sdf/345z6http://(%2525)/(%2525)?(%2525)&(%2525)=(%2525)#(%2525)z<http://(%C3%A9)/(%C3%A9)?(%C3%A9)&(%C3%A9)=(%C3%A9)#(%C3%A9)N)r   rG   rI   r0   )r(   ÚtestsZtestÚresultr   r   r   Útest_roundtripÄ   s    zTestURL.test_roundtripc                 C   s2   t  t¡}|  |t  t¡¡ |  |t  d¡¡ dS )z¶
        Two URLs decoded using L{URL.fromText} will be equal (C{==}) if they
        decoded same URL string, and unequal (C{!=}) if they decoded different
        strings.
        z:ftp://www.anotherinvaliddomain.com/foo/bar/baz/?zot=21&zutN)r   rG   rH   r0   ÚassertNotEqualrJ   r   r   r   Útest_equalityÝ   s    
þzTestURL.test_equalityc                 C   s0   |   tddtƒ ¡ |   t d¡t d¡¡ dS )zŒ
        An URL created with the empty string for a fragment compares equal
        to an URL created with an unspecified fragment.
        r   )r'   zhttp://localhost/#rM   N)r0   r   rG   r6   r   r   r   Útest_fragmentEqualityì   s    ÿzTestURL.test_fragmentEqualityc                 C   sf   t  t¡}|  d| d¡ ¡ ¡ |  d| d¡ ¡ ¡ |  d| d¡ ¡ ¡ |  d| d¡ ¡ ¡ d	S )
zm
        L{URL.child} appends a new path segment, but does not affect the query
        or fragment.
        z.http://www.foo.com/a/nice/path/gong?zot=23&zutZgongz1http://www.foo.com/a/nice/path/gong%2F?zot=23&zutzgong/z7http://www.foo.com/a/nice/path/gong%2Fdouble?zot=23&zutzgong/doublez:http://www.foo.com/a/nice/path/gong%2Fdouble%2F?zot=23&zutzgong/double/N)r   rG   rH   r0   ÚchildrI   rJ   r   r   r   Ú
test_childö   s    
ÿÿþþzTestURL.test_childc                 C   s$   |   t d¡ ddd¡ ¡ d¡ dS )zg
        L{URL.child} receives multiple segments as C{*args} and appends each in
        turn.
        zhttp://example.com/a/br   ÚdÚezhttp://example.com/a/b/c/d/eN)r0   r   rG   rT   rI   r6   r   r   r   Útest_multiChild
  s      ÿþzTestURL.test_multiChildc                 C   s0   t dd d¡}|  |j¡ |  d| ¡ ¡ dS )zo
        L{URL.child} of a L{URL} without a path produces a L{URL} with a single
        path segment.
        úwww.foo.com©r$   r   zhttp://www.foo.com/cN)r   rT   r   Úrootedr0   rI   )r(   ZchildURLr   r   r   Útest_childInitRoot  s    zTestURL.test_childInitRootc                 C   sH   t  t¡}|  d| d¡ ¡ ¡ d}t  |¡}|  d| d¡ ¡ ¡ dS )z
        L{URL.sibling} of a L{URL} replaces the last path segment, but does not
        affect the query or fragment.
        z0http://www.foo.com/a/nice/path/sister?zot=23&zutZsisterz)http://www.foo.com/a/nice/path?zot=23&zutz+http://www.foo.com/a/nice/sister?zot=23&zutN)r   rG   rH   r0   ÚsiblingrI   )r(   rK   Ztheurl2r   r   r   Útest_sibling  s    
þ
þzTestURL.test_siblingc                 C   s¼   t  t¡}|  d| d¡ ¡ ¡ |  d| d¡ ¡ ¡ |  d| d¡ ¡ ¡ |  d| d¡ ¡ ¡ |  d	| d
¡ ¡ ¡ t  d¡}|  d| d¡ ¡ ¡ t  d¡}|  | d¡ ¡ d¡ dS )z¦
        L{URL.click} interprets the given string as a relative URI-reference
        and returns a new L{URL} interpreting C{self} as the base absolute URI.
        r   r   z$http://www.foo.com/a/nice/path/clickÚclickzhttp://www.foo.com/clickz/clickz$http://www.foo.com/a/nice/path/?burpz?burpz//foobarzhttp://www.foo.com/foobarzhttp://www.foo.com/me/noqueryz!http://www.foo.com/me/17?spam=158z/me/17?spam=158zhttp://localhost/foo?abc=defzhttp://www.python.orgN)r   rG   rH   r0   r_   rI   ZassertNotIn)r(   rK   r)   r   r   r   Ú
test_click1  s0    
ÿÿÿÿÿ
ÿ
ÿzTestURL.test_clickc                 C   s2   t  t¡}tD ]\}}|  | |¡ ¡ |¡ qdS )zQ
        L{URL.click} should correctly resolve the examples in RFC 3986.
        N)r   rG   ÚrelativeLinkBaseForRFC3986ÚrelativeLinkTestsForRFC3986r0   r_   rI   )r(   ÚbaseÚrefr2   r   r   r   Útest_clickRFC3986U  s    
zTestURL.test_clickRFC3986c                 C   s.   t  t¡}|  t|jd¡ |  t|jd¡ dS )zM
        L{URL.click} should not accept schemes with relative paths.
        zg:hzhttp:hN)r   rG   ra   ÚassertRaisesÚNotImplementedErrorr_   )r(   rc   r   r   r   Útest_clickSchemeRelPath^  s    
zTestURL.test_clickSchemeRelPathc              
   C   sF   t  d¡}|  | |j|j|j|j|j|j	¡|¡ |  | ¡ |¡ dS )zf
        Verify that L{URL.replace} doesn't change any of the arguments it
        is passed.
        zhttps://x:1/y?z=1#AN)
r   rG   r0   Úreplacer!   r$   r%   r&   r'   r-   rJ   r   r   r   Útest_cloneUnchangedg  s    
ûùþzTestURL.test_cloneUnchangedc                 C   s´   dddgdddgdddgdddgdddgdd	d
gdddgdddgdddgdd	dgdd	d
gdddgdddgg}|D ]>\}}}t  |¡ |¡ ¡ }|  ||dj|t|ƒ||d¡ qpdS )zd
        L{URL.click} collapses C{.} and C{..} according to RFC 3986 section
        5.2.4.
        rM   r   r   zhttp://localhost/a/b/czhttp://localhost/a/b/zhttp://localhost/a/z./d/ezhttp://localhost/a/b/d/ez../d/ezhttp://localhost/a/d/ez/./d/ezhttp://localhost/d/ez/../d/ezhttp://localhost/a/b/c/z
../../d/e/zhttp://localhost/a/d/e/zhttp://localhost/a/./czhttp://localhost/a/./c/zhttp://localhost/a/b/c/dz./e/../f/../gzhttp://localhost/a/b/c/gzd//ezhttp://localhost/a/b/d//ez1{start}.click({click}) => {actual} not {expected})Ústartr_   r1   r2   N)r   rG   r_   rI   r0   Úformatr#   )r(   rN   rk   r_   r2   r1   r   r   r   Útest_clickCollapsez  s<    ÿÿñüýzTestURL.test_clickCollapsec                 C   sÔ   |   dt d¡ dd¡ ¡ ¡ |   dtdd dd¡ ¡ ¡ t t¡}|   d| d	¡ ¡ ¡ |   d
| d	d¡ ¡ ¡ |   d| d	d¡ d¡ ¡ ¡ |   d| d¡ d	d¡ ¡ ¡ |   d| d	d¡ dd¡ ¡ ¡ dS )z3
        L{URL.add} adds query parameters.
        z'http://www.foo.com/a/nice/path/?foo=barzhttp://www.foo.com/a/nice/path/rD   rE   zhttp://www.foo.com/?foo=barrY   rZ   z/http://www.foo.com/a/nice/path/?zot=23&zut&burpZburpz3http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxxÚxxxz8http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxx&zingZzingz8http://www.foo.com/a/nice/path/?zot=23&zut&zing&burp=xxxz:http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxx&zot=32ÚzotÚ32N)r0   r   rG   ÚaddrI   rH   rJ   r   r   r   Útest_queryAddž  s@    
 ÿþþ
þþþþþzTestURL.test_queryAddc                 C   sd   t  t¡}|  d| dd¡ ¡ ¡ |  d| d¡ dd¡ ¡ ¡ |  d| dd¡ dd¡ ¡ ¡ dS )	z?
        L{URL.set} replaces query parameters by name.
        z*http://www.foo.com/a/nice/path/?zot=32&zutro   rp   z0http://www.foo.com/a/nice/path/?zot&zut=itworkedZzutZitworkedrn   N)r   rG   rH   r0   ÚsetrI   rq   rJ   r   r   r   Útest_querySet¿  s    
þþþzTestURL.test_querySetc                 C   s&   t  d¡}|  | d¡t  d¡¡ dS )zK
        L{URL.remove} removes all instances of a query parameter.
        z*https://example.com/a/b/?foo=1&bar=2&foo=3rD   zhttps://example.com/a/b/?bar=2N)r   rG   r0   Úremove©r(   Úurlr   r   r   Útest_queryRemoveÔ  s
    
þzTestURL.test_queryRemovec                 C   sZ   t  d¡}|  | d¡dg¡ |  | ¡ d¡ t  d¡}|  |jd¡ |  | ¡ d¡ dS )	z€
        Every C{=}-sign after the first in a query parameter is simply included
        in the value of the parameter.
        zhttp://localhost/?=x=x=xr   úx=x=xzhttp://localhost/?=x%3Dx%3Dxz!http://localhost/?foo=x=x=x&bar=y))rD   ry   )rE   Úyz%http://localhost/?foo=x%3Dx%3Dx&bar=yN)r   rG   r0   ÚgetrI   r&   r@   r   r   r   Útest_parseEqualSignInParamValueß  s    

z'TestURL.test_parseEqualSignInParamValuec                 C   s   |   tƒ  ¡ d¡ dS )zG
        An empty L{URL} should serialize as the empty string.
        r   N)r0   r   rI   r6   r   r   r   Ú
test_emptyí  s    zTestURL.test_emptyc                 C   s    t dgd}|  | ¡ d¡ dS )zP
        An L{URL} with query text should serialize as just query text.
        ©ÚhelloÚworld©r&   z?hello=worldN)r   r0   rI   r@   r   r   r   Útest_justQueryTextô  s    zTestURL.test_justQueryTextc                 C   s   t  d¡}|  ||¡ dS )z2
        L{URL} compares equal to itself.
        rM   N©r   rG   r0   r@   r   r   r   Útest_identicalEqualü  s    
zTestURL.test_identicalEqualc                 C   s$   t  d¡}t  d¡}|  ||¡ dS )zG
        URLs with equivalent components should compare equal.
        rM   Nrƒ   ©r(   Zu1Zu2r   r   r   Útest_similarEqual  s    

zTestURL.test_similarEqualc                 C   s<   t  d¡}t  d¡}|  ||kd||f ¡ |  ||¡ dS )z|
        L{URL}s that refer to different resources are both unequal (C{!=}) and
        also not equal (not C{==}).
        úhttp://localhost/aúhttp://localhost/bú%r != %rN)r   rG   ÚassertFalserQ   r…   r   r   r   Útest_differentNotEqual  s    

zTestURL.test_differentNotEqualc                 C   sJ   t  d¡}|  |dkd¡ |  |tƒ kd¡ |  |d¡ |  |tƒ ¡ dS )z=
        L{URL} is not equal (C{==}) to other types.
        rM   é*   zURL must not equal a number.zURL must not equal an object.N)r   rG   rŠ   ÚobjectrQ   r@   r   r   r   Útest_otherTypesNotEqual  s
    
zTestURL.test_otherTypesNotEqualc                 C   s"   t  d¡}|  ||kd| ¡ dS )zJ
        Identical L{URL}s are not unequal (C{!=}) to each other.
        rM   z%r == itselfN©r   rG   rŠ   r@   r   r   r   Útest_identicalNotUnequal#  s    
z TestURL.test_identicalNotUnequalc                 C   s0   t  d¡}t  d¡}|  ||kd||f ¡ dS )zU
        Structurally similar L{URL}s are not unequal (C{!=}) to each other.
        rM   ú%r == %rNr   r…   r   r   r   Útest_similarNotUnequal+  s    

zTestURL.test_similarNotUnequalc                 C   s0   t  d¡}t  d¡}|  ||kd||f ¡ dS )zS
        Structurally different L{URL}s are unequal (C{!=}) to each other.
        r‡   rˆ   r‘   N)r   rG   r   r…   r   r   r   Útest_differentUnequal4  s    

zTestURL.test_differentUnequalc                 C   s0   t  d¡}|  |dkd¡ |  |tƒ kd¡ dS )z;
        L{URL} is unequal (C{!=}) to other types.
        rM   rŒ   zURL must differ from a number.z"URL must be differ from an object.N)r   rG   r   r   r@   r   r   r   Útest_otherTypesUnequal=  s    
zTestURL.test_otherTypesUnequalc                 C   sl   d}t  |¡}| ¡ }|  |jd¡ |  |jd d¡ |  | ¡ |¡ d}| ¡ }|  ||d||f ¡ dS )z‹
        L{URL.asURI} produces an URI which converts any URI unicode encoding
        into pure US-ASCII and returns a new L{URL}.
        õ   http://Ã©.com/eÌ?aÌ=iÌ#uÌu   Ã©.comr   u   eÌú.http://xn--9ca.com/%C3%A9?%C3%A1=%C3%AD#%C3%BAr‰   N)r   rG   ÚasURIr0   r$   r%   rI   )r(   ÚunicodeyÚiriÚuriÚexpectedURIÚ	actualURIr   r   r   Ú
test_asURIF  s    
ÿ
ÿzTestURL.test_asURIc                 C   sl   d}t  |¡}| ¡ }|  |jd¡ |  |jd d¡ |  | ¡ |¡ d}| ¡ }|  ||d||f ¡ dS )zœ
        L{URL.asIRI} decodes any percent-encoded text in the URI, making it
        more suitable for reading by humans, and returns a new L{URL}.
        r–   zxn--9ca.comr   z%C3%A9u   http://Ã©.com/Ã©?Ã¡=Ã­#Ãºr‰   N)r   rG   ÚasIRIr0   r$   r%   rI   )r(   Zasciiishrš   r™   ÚexpectedIRIÚ	actualIRIr   r   r   Ú
test_asIRI\  s    

ÿzTestURL.test_asIRIc                 C   s<   d}t  |¡}| ¡ }d}| ¡ }|  ||d||f ¡ dS )zœ
        Bad UTF-8 in a path segment, query parameter, or fragment results in
        that portion of the URI remaining percent-encoded in the IRI.
        z http://xn--9ca.com/%00%FF/%C3%A9u   http://Ã©.com/%00%FF/Ã©r‰   N)r   rG   rž   rI   r0   )r(   ZurlWithBinaryrš   r™   rŸ   r    r   r   r   Útest_badUTF8AsIRIq  s    

ÿzTestURL.test_badUTF8AsIRIc                 C   s*   d}t  |¡}| ¡ }|  | ¡ |¡ dS )zT
        A L{URL} composed of non-ASCII text will result in non-ASCII text.
        r•   N)r   rG   rž   r0   rI   )r(   r˜   r™   ZalsoIRIr   r   r   Útest_alreadyIRIAsIRI  s    
zTestURL.test_alreadyIRIAsIRIc                 C   s*   d}t  |¡}| ¡  ¡ }|  ||¡ dS )zH
        A L{URL} composed of encoded text will remain encoded.
        r–   N)r   rG   r—   rI   r0   )r(   r›   rš   rœ   r   r   r   Útest_alreadyURIAsURI  s    
zTestURL.test_alreadyURIAsURIc                 C   sv   t  d¡}|  | d¡d¡ |  | d¡d¡ |  |jd¡ |  |jd¡ |  | ¡ d¡ |  |jdd	 ¡ d
¡ dS )zz
        L{URL.fromText} will parse the C{userinfo} portion of the URI
        separately from the host and port.
        z<http://someuser:somepassword@example.com/some-segment@ignoreTz!someuser:somepassword@example.comFzsomeuser:@example.comzsomeuser:somepasswordZsomeuserz0http://someuser:@example.com/some-segment@ignore)r.   z/http://someuser@example.com/some-segment@ignoreN)r   rG   r0   Z	authorityr.   ÚuserrI   ri   rv   r   r   r   Útest_userinfo™  s     ÿÿ
ÿþzTestURL.test_userinfoc                 C   s,   t  d¡}|  |jd¡ |  | ¡ d¡ dS )zI
        L{URL.fromText} parses custom port numbers as integers.
        zhttp://www.example.com:8080/i  N)r   rG   r0   r-   rI   )r(   ZportURLr   r   r   Útest_portText®  s    
zTestURL.test_portTextc                 C   s   |   t d¡ ¡ d¡ dS )a  
        Although L{URL} instances are mainly for dealing with HTTP, other
        schemes (such as C{mailto:}) should work as well.  For example,
        L{URL.fromText}/L{URL.asText} round-trips cleanly for a C{mailto:} URL
        representing an email address.
        zmailto:user@example.comN)r0   r   rG   rI   r6   r   r   r   Útest_mailto·  s    ÿzTestURL.test_mailtoc                 C   s"   t ddggd}|  |jd¡ dS )zŒ
        When a L{URL} is created with a C{query} argument, the C{query}
        argument is converted into an N-tuple of 2-tuples.
        ÚalphaÚbetar   ))r©   rª   N)r   r0   r&   rv   r   r   r   Útest_queryIterableÂ  s    zTestURL.test_queryIterablec                 C   s    t ddgd}|  |jd¡ dS )zr
        When a L{URL} is created with a C{path} argument, the C{path} is
        converted into a tuple.
        r   r€   ©r%   r~   N)r   r0   r%   rv   r   r   r   Útest_pathIterableË  s    zTestURL.test_pathIterablec              	      s  G dd„ dt ƒ‰ ttkrdnd}‡fdd„‰|f‡ ‡‡fdd„	}|d	ƒ |d
ƒ |dƒ |ddƒ |dƒ |ddƒ ˆ t¡}tˆ ƒ gd W 5 Q R X ˆ||dƒ ˆ t¡}tdˆ ƒ fgd W 5 Q R X ˆ||d dƒ ˆ t¡}tˆ ƒ dfgd W 5 Q R X ˆ||dƒ ˆ t¡ tˆ ƒ gd W 5 Q R X ˆ t¡ tdgd W 5 Q R X ˆ t¡ tdgd W 5 Q R X t d¡}ˆ t¡}| ˆ ƒ ¡ W 5 Q R X ˆ||dƒ ˆ t¡}| 	ˆ ƒ ¡ W 5 Q R X ˆ||dƒ ˆ t¡}| 
ˆ ƒ ¡ W 5 Q R X ˆ||dƒ dS )a¤  
        Passing an argument of the wrong type to any of the constructor
        arguments of L{URL} will raise a descriptive L{TypeError}.

        L{URL} typechecks very aggressively to ensure that its constitutent
        parts are all properly immutable and to prevent confusing errors when
        bad data crops up in a method call long after the code that called the
        constructor is off the stack.
        c                   @   s   e Zd Zdd„ Zdd„ ZdS )z1TestURL.test_invalidArguments.<locals>.Unexpectedc                 S   s   dS )NZwrongr   r6   r   r   r   Ú__str__ß  s    z9TestURL.test_invalidArguments.<locals>.Unexpected.__str__c                 S   s   dS )Nú<unexpected>r   r6   r   r   r   Ú__repr__á  s    z:TestURL.test_invalidArguments.<locals>.Unexpected.__repr__N)Ú__name__Ú
__module__Ú__qualname__r®   r°   r   r   r   r   Ú
UnexpectedÞ  s   r´   r"   Ústrc                    s    ˆ   t| jƒd ||d¡¡ d S )Nzexpected {} for {}, got {}r¯   )r0   rµ   Ú	exceptionrl   )ÚraisedÚexpectationÚnamer6   r   r   ÚassertRaisedä  s     þÿz3TestURL.test_invalidArguments.<locals>.assertRaisedc              	      s6   ˆ  t¡}tf | ˆ ƒ iŽ W 5 Q R X ˆ||| ƒ d S )N)rf   Ú	TypeErrorr   )Zparamr¸   r·   ©r´   rº   r(   r   r   r7   ê  s    z,TestURL.test_invalidArguments.<locals>.checkr!   r$   r'   r[   Úboolr.   r-   zint or NoneTyper¬   zpath segmentr¹   r   z or NoneTypezquery parameter valueÚvaluezquery parameter name)r*   r+   Zvv)r*   zhttps://valid.example.com/zrelative URLN)r   Úbytesrµ   rf   r»   r   Ú
ValueErrorrG   rT   r]   r_   )r(   ZdefaultExpectationr7   r·   rw   r   r¼   r   Útest_invalidArgumentsÔ  sJ    



ÿ
zTestURL.test_invalidArgumentsc              	   C   s@   |   t¡}tdd W 5 Q R X |  t|jƒd tdƒ¡¡ dS )z·
        Technically, L{str} (or L{unicode}, as appropriate) is iterable, but
        C{URL(path="foo")} resulting in C{URL.fromText("f/o/o")} is never what
        you want.
        rD   r¬   z+expected iterable of text for path, not: {}N)rf   r»   r   r0   rµ   r¶   rl   r#   )r(   r·   r   r   r   Ú!test_technicallyTextIsIterableBut  s    ÿþz)TestURL.test_technicallyTextIsIterableButN)r   )1r±   r²   r³   Ú__doc__r,   r3   r8   rA   rC   rF   rL   rP   rR   rS   rU   rX   r\   r^   r`   re   rh   rj   rm   rr   rt   rx   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   Q   s^    ÿ
	


$		$!				
			@r   c                   @   s   e Zd ZdZdd„ ZdS )ÚURLDeprecationTestsz.
    L{twisted.python.url} is deprecated.
    c                 C   sF   ddl m} | |  | jg¡}|  dt|ƒ¡ |  d|d d ¡ dS )zK
        L{twisted.python.url} is deprecated since Twisted 17.5.0.
        r   )rw   é   z\twisted.python.url was deprecated in Twisted 17.5.0: Please use hyperlink from PyPI instead.ÚmessageN)Ztwisted.pythonrw   ZflushWarningsÚtest_urlDeprecationr0   Úlen)r(   rw   ZwarningsShownr   r   r   rÇ   '  s    
ýz'URLDeprecationTests.test_urlDeprecationN)r±   r²   r³   rÃ   rÇ   r   r   r   r   rÄ   #  s   rÄ   N)rÃ   Z
__future__r   rw   r   Útyper"   Ztwisted.trial.unittestr   rH   ra   rb   Z_percentencr   rÄ   r   r   r   r   Ú<module>   sn   Î:     W