ϪfmudZddlmZddlmZddlmZddlmZddlm Z dZ d Z gd Z d Z Gd d eZGddeZGddeZy)z" Tests for L{twisted.python.url}. ) annotations)Iterable)Protocol)SynchronousTestCaseURL*http://www.foo.com/a/nice/path/?zot=23&zuthttp://a/b/c/d;p?q)()ghttp://a/b/c/g)z./gr )zg/http://a/b/c/g/)z/g http://a/g)z//gzhttp://g)z?yzhttp://a/b/c/d;p?y)zg?yzhttp://a/b/c/g?y)z#szhttp://a/b/c/d;p?q#s)zg#szhttp://a/b/c/g#s)zg?y#szhttp://a/b/c/g?y#s)z;xzhttp://a/b/c/;x)zg;xzhttp://a/b/c/g;x)zg;x?y#szhttp://a/b/c/g;x?y#s)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)zg.zhttp://a/b/c/g.)z.gzhttp://a/b/c/.g)zg..zhttp://a/b/c/g..)z..gzhttp://a/b/c/..g)z./../gr)z./g/.r)zg/./hzhttp://a/b/c/g/h)zg/../hzhttp://a/b/c/h)z g;x=1/./yzhttp://a/b/c/g;x=1/y)z g;x=1/../yzhttp://a/b/c/y)zg?y/./xzhttp://a/b/c/g?y/./x)zg?y/../xzhttp://a/b/c/g?y/../x)zg#s/./xzhttp://a/b/c/g#s/./x)zg#s/../xzhttp://a/b/c/g#s/../xc2djd|DS)Nrc38K|]}dt|zyw)z%%%02XN)ord).0cs >/usr/lib/python3/dist-packages/twisted/python/test/test_url.py z..Ls=a3q6 1=s)join)ss rr Ls=1==ceZdZeddZy) _HasExceptioncy)Nselfs r exceptionz_HasException.exceptionPs r!N)return BaseException)__name__ __module__ __qualname__propertyr(r%r!rr#r#Os   r!r#ceZdZdZd/dZ d0 d1dZd2dZd2dZd2dZd2dZ d2dZ d2d Z d2d Z d2d Z d2d Zd2d Zd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZd2dZ d2dZ!d2d Z"d2d!Z#d2d"Z$d2d#Z%d2d$Z&d2d%Z'd2d&Z(d2d'Z)d2d(Z*d2d)Z+d2d*Z,d2d+Z-d2d,Z.d2d-Z/y.)3TestURLz Tests for L{URL}. c(|j|jtt||j|jtt||j D]"}|j|tt|$|j D]T\}}|j|tt||j|duxst|tt|V|j|jtt|y)zl The given L{URL}'s components should be L{unicode}. @param u: The L{URL} to test. N) assertIsInstanceschemestrreprhostpathquery assertTrue isinstancefragment)r'usegkvs rassertUnicodedzTestURL.assertUnicodedZs ahhT!W5 affc47366 5C  ! !#sDG 4 5GG FDAq  ! !!S$q' 2 OOAI;As);T!W E F ajj#tAw7r!c |j|j|j|j|j|j |j f} ||t|t||||j f} |j| | y)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) r3r6r7r8r;portuserinfotuple assertEqual) r'r<r3r6r7r8r;rBrCactualexpecteds r assertURLzTestURL.assertURLisd<((AFFAFFAGGQZZTD%+uU|XtQZZX *r!c dfd }|tdd|tddgg|tddggdy)z@ L{URL} should have appropriate default values. c Xj|j|ddggdddy)NhttprP)r@rH)r<r's rcheckz(TestURL.test_initDefaults..checks+    " NN1fb"b"b" =r!rKrNr<r r)Noner)r'rMs` rtest_initDefaultszTestURL.test_initDefaultss@  > c&"o c&"b"%& c&"b"b)*r!c tdddgddgd}|j||j|dddgddgdd|jtdd d gd gd dd d gd gd d y)z= L{URL} should accept L{unicode} parameters. rhpr>r?)r>NfNrKàé)uλuπu⊥rLr r@rHr'r<s r test_initzTestURL.test_inits S3%*k!:C @ A q#sSEJ +Dc4P  +?*@( K   H ! "   r!c ~tdddgddgd}|j||j|dddgddgddy)zN L{URL} should accept (and not interpret) percent characters. rz%68z%70)%6Bz%76)r\Nz%66NrXrYs rtest_initPercentzTestURL.test_initPercentsM UUGnm%De L A  sEE7^]$CUD r!c |jttdddgddgddjtd y ) 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. rKfoobar)bazNrTfrob)r3r6r7r8r;zURL.from_text({})zhttp://foo/bar?baz&k=v#frobN)rEr5r formatr&s r test_reprzTestURL.test_reprsN  !(*5#   & &t,I'J K r!c~tjt}|jt|j y)zb Round-tripping L{URL.fromText} with C{str} results in an equivalent URL. N)r fromTexttheurlrEasTextr'urlpaths r test_fromTextzTestURL.test_fromTexts) ,,v& !12r!cd}|D]7}tj|j}|j||9y)z> L{URL.asText} should invert L{URL.fromText}. )zhttp://localhosthttp://localhost/zhttp://localhost/foozhttp://localhost/foo/zhttp://localhost/foo!!bar/zhttp://localhost/foo%20bar/zhttp://localhost/foo%2Fbar/zhttp://localhost/foo?nzhttp://localhost/foo?n=vzhttp://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 OOH % , , . >,,w'  9 OOH % , , . r!ctjt}|jd|j dj |jd|j dj |jd|j dj |jd|j dj |j d |j d j tjd }|jd |j d j tjd}|j|j dj dy)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 rz$http://www.foo.com/a/nice/path/clickclickzhttp://www.foo.com/clickz/clickz$http://www.foo.com/a/nice/path/?burpz?burpz//foobarzhttp://www.foo.com/foobarzhttp://www.foo.com/me/noqueryz!http://www.foo.com/me/17?spam=158z/me/17?spam=158zhttp://localhost/foo?abc=defzhttp://www.python.orgN)r rfrgrErrh assertNotIn)r'rjr<s r test_clickzTestURL.test_click<s? ,,v&  8'--:K:R:R:T   2GMM'4J4Q4Q4S  3W]]85L5S5S5UV  2GMM'4J4Q4Q4S   &ABIIK LL8 9  /9J1K1R1R1T LL7 8  GG+ , 3 3 57N r!ctjt}tD]4\}}|j |j |j |6y)zQ L{URL.click} should correctly resolve the examples in RFC 3986. N)r rfrelativeLinkBaseForRFC3986relativeLinkTestsForRFC3986rErrh)r'baserefrGs rtest_clickRFC3986zTestURL.test_clickRFC3986dsI||678 AMC   TZZ_335x @ Ar!ctjt}|jt|j d|jt|j dy)zM L{URL.click} should not accept schemes with relative paths. zg:hzhttp:hN)r rfr assertRaisesNotImplementedErrorr)r'rs rtest_clickSchemeRelPathzTestURL.test_clickSchemeRelPathlsA||67 -tzz5A -tzz8Dr!c 2tjd}|j|j|j|j |j |j|j|j||j|j|y)zf Verify that L{URL.replace} doesn't change any of the arguments it is passed. zhttps://x:1/y?z=1#AN) r rfrEreplacer3r6r7r8r;rBris rtest_cloneUnchangedzTestURL.test_cloneUnchangedtsw ,,45  OO          *G4r!c.gdgdgdgdgdgdgdgdgd gd gd gd gd g }|D]g\}}}tj|j|j}|j ||dj |t |||iy)zd L{URL.click} collapses C{.} and C{..} according to RFC 3986 section 5.2.4. )rmrrm)rmrrm)http://localhost/a/b/crzhttp://localhost/a/b/)rrzhttp://localhost/a/)rz./d/ezhttp://localhost/a/b/d/e)r../d/ehttp://localhost/a/d/e)rz/./d/ehttp://localhost/d/e)rz/../d/er)zhttp://localhost/a/b/c/z ../../d/e/zhttp://localhost/a/d/e/)zhttp://localhost/a/./crr)zhttp://localhost/a/./c/rr)zhttp://localhost/a/b/c/dz ./e/../f/../gzhttp://localhost/a/b/c/g)rzd//ezhttp://localhost/a/b/d//ez1{start}.click({click}) => {actual} not {expected})startrrFrGN)r rfrrhrErcr5)r'rnrrrGrFs rtest_clickCollapsezTestURL.test_clickCollapses < < D C K J H I P H K U K ',  "E5(\\%(..u5<<>F   CJJu+!% K  r!cj|jdtjdjddj |jdtdjddj tjt }|jd|jd j |jd |jd d j |jd |jd d jd j |jd|jd jd d j |jd|jd d jddj y)z3 L{URL.add} adds query parameters. z'http://www.foo.com/a/nice/path/?foo=barzhttp://www.foo.com/a/nice/path/r_r`zhttp://www.foo.com/?foo=barrrz/http://www.foo.com/a/nice/path/?zot=23&zut&burpburpz3http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxxxxxz8http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxx&zingzingz8http://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=32zot32N)rEr rfaddrhrgris r test_queryAddzTestURL.test_queryAddsj  5 LL: ; ? ?u M T T V   ) ] # ' 'u 5 < < > ,,v&  = KK  & & (   A KK & - - /   F KK & * *6 2 9 9 ;  F KK  # #FE 2 9 9 ;  H KK & * *5$ 7 > > @ r!ctjt}|jd|j ddj |jd|j dj ddj |jd|j ddj ddj y) z? L{URL.set} replaces query parameters by name. z*http://www.foo.com/a/nice/path/?zot=32&zutrrz0http://www.foo.com/a/nice/path/?zot&zut=itworkedzutitworkedrN)r rfrgrEsetrhrris r test_querySetzTestURL.test_querySets,,v&  8 KKt $ + + -  > KK  " "5* 5 < < >  8 KKu % ) )% 6 = = ? r!ctjd}|j|jdtjdy)zK L{URL.remove} removes all instances of a query parameter. z*https://example.com/a/b/?foo=1&bar=2&foo=3r_zhttps://example.com/a/b/?bar=2N)r rfrEremover'urls rtest_queryRemovezTestURL.test_queryRemoves9llGH  JJu s||,LM r!cT|jtjdy)zG An empty L{URL} should serialize as the empty string. rN)rEr rhr&s r test_emptyzTestURL.test_emptys ,r!c^tdg}|j|jdy)zP An L{URL} with query text should serialize as just query text. helloworldr8z ?hello=worldN)r rErhrYs rtest_justQueryTextzTestURL.test_justQueryTexts( )* + ^4r!cRtjd}|j||y)z2 L{URL} compares equal to itself. rmNr rfrErYs rtest_identicalEqualzTestURL.test_identicalEquals# LL, - Ar!c|tjd}tjd}|j||y)zG URLs with equivalent components should compare equal. rmNrr'u1u2s rtest_similarEqualzTestURL.test_similarEquals2\\- . \\- . R r!ctjd}tjd}|j||k(|d||j||y)z| L{URL}s that refer to different resources are both unequal (C{!=}) and also not equal (not C{==}). http://localhost/ahttp://localhost/b != N)r rf assertFalsersrs rtest_differentNotEqualzTestURL.test_differentNotEqualsQ \\. / \\. / rbV4v#67 B#r!ctjd}|j|dk(d|j|tk(d|j |d|j |ty)z= L{URL} is not equal (C{==}) to other types. rm*zURL must not equal a number.zURL must not equal an object.N)r rfrobjectrsrYs rtest_otherTypesNotEqualzTestURL.test_otherTypesNotEqualsa LL, - b"@A fh(GH Ar" Avx(r!c^tjd}|j||k7d|zy)zJ Identical L{URL}s are not unequal (C{!=}) to each other. rmz %r == itselfNr rfrrYs rtest_identicalNotUnequalz TestURL.test_identicalNotUnequals, LL, - a!!34r!ctjd}tjd}|j||k7|d|y)zU Structurally similar L{URL}s are not unequal (C{!=}) to each other. rm == Nrrs rtest_similarNotUnequalzTestURL.test_similarNotUnequal!sA\\- . \\- . rbV4v#67r!ctjd}tjd}|j||k7|d|y)zS Structurally different L{URL}s are unequal (C{!=}) to each other. rrrN)r rfr9rs rtest_differentUnequalzTestURL.test_differentUnequal)s?\\. / \\. / bRF$rf"56r!ctjd}|j|dk7d|j|tk7dy)z; L{URL} is unequal (C{!=}) to other types. rmrzURL must differ from a number.z"URL must be differ from an object.N)r rfr9rrYs rtest_otherTypesUnequalzTestURL.test_otherTypesUnequal1s; LL, - R!AB VX 'KLr!c\d}tj|}|j}|j|jd|j|j dd|j|j |d}|j }|j|||d|y)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/é?á=í#úué.comrué.http://xn--9ca.com/%C3%A9?%C3%A1=%C3%AD#%C3%BArN)r rfasURIrEr6r7rh)r'unicodeyiriuri expectedURI actualURIs r test_asURIzTestURL.test_asURI9s  B ll8$iik #LM  HHQKM  x0F JJL  KI=[O1TUr!c\d}tj|}|j}|j|jd|j|j dd|j|j |d}|j }|j|||d|y)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}. rz xn--9ca.comrz%C3%A9uhttp://é.com/é?á=í#úrN)r rfasIRIrEr6r7rh)r'asciiishrr expectedIRI actualIRIs r test_asIRIzTestURL.test_asIRIPs Dll8$iik =1 !h/ x0 3 JJL  KI=[O1TUr!cd}tj|}|j}d}|j}|j |||d|y)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%A9uhttp://é.com/%00%FF/érN)r rfrrhrE)r' urlWithBinaryrrrrs rtest_badUTF8AsIRIzTestURL.test_badUTF8AsIRIesV ; ll=)iik 2  JJL  KI=[O1TUr!cd}tj|}|j}|j|j |y)zT A L{URL} composed of non-ASCII text will result in non-ASCII text. rN)r rfrrErh)r'rralsoIRIs rtest_alreadyIRIAsIRIzTestURL.test_alreadyIRIAsIRIus?  B ll8$))+ )84r!cd}tj|}|jj}|j ||y)zH A L{URL} composed of encoded text will remain encoded. rN)r rfrrhrE)r'rrrs rtest_alreadyURIAsURIzTestURL.test_alreadyURIAsURIs<G ll;'IIK&&(  K0r!ctjd}|j|jdd|j|jdd|j|jd|j|j d|j|j d|j|jd j d y ) zz L{URL.fromText} will parse the C{userinfo} portion of the URI separately from the host and port. z? :.  JJLL   KKK , 3 3 5 = r!ctjd}|j|jd|j|j dy)zI L{URL.fromText} parses custom port numbers as integers. zhttp://www.example.com:8080/iN)r rfrErBrh)r'portURLs r test_portTextzTestURL.test_portTexts?,,=> t, )+IJr!cj|jtjdjdy)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. zmailto:user@example.comN)rEr rfrhr&s r test_mailtozTestURL.test_mailtos+  LL2 3 : : <>W r!cZtddgg}|j|jdy)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. alphabetar))rrN)r rEr8rs rtest_queryIterablezTestURL.test_queryIterables+ '6*+, $89r!cXtddg}|j|jdy)zr When a L{URL} is created with a C{path} argument, the C{path} is converted into a tuple. rrr7rN)r rEr7rs rtest_pathIterablezTestURL.test_pathIterables( )* #56r!cGddtturdnd}dfd |fdfd }|d|d |d |d d |d |ddjt5}t gddd|djt5}t dfgddd||dzdjt5}t dfgddd||djt5t gdddjt 5t dgdddjt 5t dgdddt j d}jt5}|jddd||djt5}|jddd||djt5}|jddd||dy#1swYxYw#1swYxYw#1swYxYw#1swYWxYw#1swY9xYw#1swYxYw#1swYxYw#1swYxYw#1swYzxYw)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. ceZdZddZddZy)1TestURL.test_invalidArguments..Unexpectedcy)Nwrongr%r&s r__str__z9TestURL.test_invalidArguments..Unexpected.__str__sr!cy)N r%r&s r__repr__z:TestURL.test_invalidArguments..Unexpected.__repr__s%r!N)r)r4)r+r,r-rr r%r!r Unexpectedrs   &r!r unicoder4namecrjt|jdj||dy)Nzexpected {} for {}, got {}r)rEr4r(rc)raised expectationr r's r assertRaisedz3TestURL.test_invalidArguments..assertRaiseds1   F$$%,33K~V r!cjt5}tdi|iddd||y#1swYxYw)Nr%)r TypeErrorr )paramrrr rr's rrMz,TestURL.test_invalidArguments..checksF""9- -,ujl+, - e 4 - -s =Ar3r6r;rboolrCrBzint or NoneTyperNz path segmentrz or NoneTypezquery parameter valuevaluezquery parameter name)r>r?vv)r>zhttps://valid.example.com/z relative URL)rr#rr4r r4r)rO)rr4rr4r)rO) bytesr4rrr ValueErrorrfryrr)r'defaultExpectationrMrrr rs` @@rtest_invalidArgumentszTestURL.test_invalidArgumentss & &+03,YE  2D 5 5 h f  j h j f'(   y ) V L   V/@   y ) V Z\*    &79P   y ) V \7+   V/1GH  y ) & z|n % &   z * * '( ) *   z * vh  ll78   y ) $V IIjl # $V/@   y ) &V KK % &V/@   y ) $V IIjl # $V/@S       & & * *   $ $ & & $ $sl5I+/I8.J*JJJ,J9KK+I58JJJJ),J69KKKc|jt5}tdddd|jt j dj tdy#1swYGxYw)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. r_rNz+expected iterable of text for path, not: {})rrr rEr4r(rcr5)r'rs r!test_technicallyTextIsIterableButz)TestURL.test_technicallyTextIsIterableButs^   y ) V UO     ! 9 @ @e M   s A))A2NrN)r)r<r r3r4r6r4r7z Iterable[str]r8z Iterable[tuple[str, str | None]]r;r4rBz int | NonerCr4r)rOr)rO)0r+r,r-__doc__r@rHrPrZr]rdrkrqrtrvrzr~rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr%r!rr0r0UsO 80 +  + + +  + 0 + + + +  +D + $  &3+0    . D $& PAE5&B" H * - 5!$)587MV.V*V 51 (K  :7OAb  r!r0ceZdZdZddZy)URLDeprecationTestsz. L{twisted.python.url} is deprecated. cddlm}||j|jg}|j dt ||j d|ddy)zK L{twisted.python.url} is deprecated since Twisted 17.5.0. r)rz\twisted.python.url was deprecated in Twisted 17.5.0: Please use hyperlink from PyPI instead.messageN)twisted.pythonr flushWarningstest_urlDeprecationrElen)r'r warningsShowns rr&z'URLDeprecationTests.test_urlDeprecation)sZ ' **D,D,D+EF  C ./ ; ! Y '  r!Nr)r+r,r-rr&r%r!rr r $s  r!r N)r __future__rtypingrrtwisted.trial.unittestrrr rgrr _percentencr#r0r r%r!rr-sa #6 524n>  H L  !L  ^ - r!