ÿØÿàJFIFÿþ ÿÛC       ÿÛC ÿÀÿÄÿÄ"#QrÿÄÿÄ&1!A"2qQaáÿÚ ?Øy,æ/3JæÝ¹È߲؋5êXw²±ÉyˆR”¾I0ó2—PI¾IÌÚiMö¯–þrìN&"KgX:Šíµ•nTJnLK„…@!‰-ý ùúmë;ºgµŒ&ó±hw’¯Õ@”Ü— 9ñ-ë.²1<yà‚¹ïQÐU„ہ?.’¦èûbß±©Ö«Âw*VŒ) `$‰bØÔŸ’ëXÖ-ËTÜíGÚ3ð«g Ÿ§¯—Jx„–’U/ÂÅv_s(Hÿ@TñJÑãõçn­‚!ÈgfbÓc­:él[ðQe 9ÀPLbÃãCµm[5¿ç'ªjglå‡Ûí_§Úõl-;"PkÞÞÁQâ¼_Ñ^¢SŸx?"¸¦ùY騐ÒOÈ q’`~~ÚtËU¹CڒêV  I1Áß_ÿÙ ]c@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z yddlmZWn!ek rddlmZnXddlZddlZddlmZddlmZddlmZdZd efd YZd Zd efd YZdefdYZdefdYZdefdYZ defdYZ!defdYZ"defdYZ#ej$dej%Z&dZ'defdYZ(de(fdYZ)e)e(j*d Z8d?Z9e5d@Z:dAZ;dS(Bs Routines for testing WSGI applications. Most interesting is the `TestApp `_ for testing WSGI applications, and the `TestFileEnvironment `_ class for testing the effects of command-line scripts. iN(t BaseCookie(tStringIO(twsgilib(tlint(t HeaderDictcGs tj|S(s An os.tempnam with the warning turned off, because sometimes you just need to use this and don't care about the stupid security warning. (tosttempnam(targs((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyttempnam_no_warning#st NoDefaultcBseZRS((t__name__t __module__(((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyR +scCst|}|j|S(N(tlisttsort(tl((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytsorted.s  t Dummy_smtplibcBsGeZdZdZdZdZdZeeZdZ RS(cCsWddl}|jdtd|j s5td||_t|_||j_dS(Nis1Dummy_smtplib is not maintained and is deprecatedisIsmtplib.SMTP() called again before Dummy_smtplib.existing.reset() called.( twarningstwarntDeprecationWarningtexistingtAssertionErrortservertTruetopent __class__(tselfRR((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyt__init__7s      cCs&|jstd|t|_dS(NsCalled %s.quit() twice(RRtFalse(R((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytquitCs  cCs||_||_||_dS(N(t from_addresst to_addressestmessage(RRRtmsg((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytsendmailHs  cCs |t_dS(N(tsmtplibtSMTP(tcls((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytinstallMscCs&|j stdd|j_dS(NsSMTP connection not quit(RRtNoneRR(R((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytresetRs  N( R R R'RRRR"R&t classmethodR((((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyR3s    tAppErrorcBseZRS((R R (((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyR*WstTestAppcBseZeZddddddZdZdZddddedZ dddddedZ dddddedZ dddddedZ ddddedZ d Zd Zd Zd Zd ZdZdZRS(cCst|ttfr:ddlm}||d|}n||_||_||_|dkrji}n||_ ||_ ||_ |j dS(s} Wraps a WSGI application in a more convenient interface for testing. ``app`` may be an application, or a Paste Deploy app URI, like ``'config:filename.ini#test'``. ``namespace`` is a dictionary that will be written to (if provided). This can be used with doctest or some other system, and the variable ``res`` will be assigned everytime you make a request (instead of returning the request). ``relative_to`` is a directory, and filenames used for file uploads are calculated relative to this. Also ``config:`` URIs that aren't absolute. ``extra_environ`` is a dictionary of values that should go into the environment for each request. These can provide a communication channel with the application. ``pre_request_hook`` is a function to be called prior to making requests (such as ``post`` or ``get``). This function must take one argument (the instance of the TestApp). ``post_request_hook`` is a function, similar to ``pre_request_hook``, to be called after requests are made. i(tloadappt relative_toN( t isinstancetstrtunicodet paste.deployR,tappt namespaceR-R't extra_environtpre_request_hooktpost_request_hookR((RR2R3R-R4R5R6R,((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyR_s        cCs i|_dS(sc Resets the state of the application; currently just clears saved cookies. N(tcookies(R((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyR(scCs|jj}t|d<|S(Nspaste.throw_errors(R4tcopyR(Rtenviron((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyt _make_environs c Cs |dkri}nt}|r~t|ttfsNtj|dt}nd|krg|d7}n |d7}||7}n|j}t|}d|kr|jdd\}|d`_ tdoseqt?t&it QUERY_STRINGttstatusN( R'RR.R/R0turllibt urlencodeR:tsplitt _set_headerstupdatet TestRequestt do_request( RturltparamstheadersR4R@t expect_errorst__tracebackhide__R9treq((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytgets&           R?c Cs|d kri}n|d kr*i}n|j} t|tttfr`tj|}nt|drtj|j }n|rt j |dt }|j ||\} }| | dR?tCONTENT_LENGTHtREQUEST_METHODs wsgi.inputR@N(R'R:R.R ttupletdictRARBthasattrROtcgit parse_qslRtencode_multipartt setdefaultRCR/tlenRRDRERFRG( RtmethodRHRIRJR4R@t upload_filesRKR9t content_typeRM((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyt _gen_requests4          cCs4|jd|d|d|d|d|d|d|S(s Do a POST request. Very like the ``.get()`` method. ``params`` are put in the body of the request. ``upload_files`` is for file uploads. It should be a list of ``[(fieldname, filename, file_content)]``. You can also use just ``[(fieldname, filename)]`` and the file content will be read from disk. Returns a `response object `_ tPOSTRIRJR4R@R]RK(R_(RRHRIRJR4R@R]RK((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytposts cCs4|jd|d|d|d|d|d|d|S(s Do a PUT request. Very like the ``.get()`` method. ``params`` are put in the body of the request. ``upload_files`` is for file uploads. It should be a list of ``[(fieldname, filename, file_content)]``. You can also use just ``[(fieldname, filename)]`` and the file content will be read from disk. Returns a `response object `_ tPUTRIRJR4R@R]RK(R_(RRHRIRJR4R@R]RK((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytputs cCs4|jd|d|d|d|d|ddd|S( s Do a DELETE request. Very like the ``.get()`` method. ``params`` are put in the body of the request. Returns a `response object `_ tDELETERIRJR4R@R]RKN(R_R'(RRHRIRJR4R@RK((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytdeletes  cCs|s dSxv|jD]h\}}|jdkr>d}n7|jdkrYd}nd|jddj}|||/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRD(s  c CsCdtj}g}xP|D]H\}}|jd||jd||jd|j|qWx|D]}|j|\}}}|jd||jd||ftj|d} |jd| pd|jd|j|qpW|jd|d|jdd j|} d |} | | fS( s Encodes a set of parameters (typically a name/value list) and a set of files (a list of (name, filename, file_body)) into a typical POST body, returning the (content_type, body). s----------a_BoUnDaRy%s$s--s)Content-Disposition: form-data; name="%s"R?s8Content-Disposition: form-data; name="%s"; filename="%s"isContent-Type: %ssapplication/octet-streams s multipart/form-data; boundary=%s(trandomtappendt_get_file_infot mimetypest guess_typetjoin( RRItfilestboundarytlinestkeyRlt file_infotfilenametfcontenttbodyR^((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRY7s,       cCst|dkrv|d}|jr@tjj|j|}nt|d}|j}|j|d||fSt|dkr|Stdt |d dS(Niitrbiisuupload_files need to be a list of tuples of (fieldname, filename, filecontent) or (fieldname, filename); you gave: %rid( R[R-RtpathRsRtreadtcloset ValueErrortrepr(RRxRytftcontent((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRpTs    cCs|jr|j|nt}|jrt}x'|jjD]\}}|||\}}t||rtd|nt|||qW|jdk r||jd /opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRGgs`   =                 cCst}|dkrdSt|ttfr{|j|krwtd|jdjtt ||j j |j fndS|dkr|jdkr|jdkrdStd|j|j j |j fn||jkrtd|j|fndS(Nt*s*Bad response: %s (not one of %s for %s) %ss, iis7Bad response: %s (not 200 OK or 3xx redirect for %s) %ssBad response: %s (not %s)(RR.R RTR@R*t full_statusRstmapR/RRHR{R'(RR@RRL((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRs(  cCs#|jrtd|jndS(Ns!Application had errors logged: %s(terrorsR*(RR((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRs cCs+|\}}}}t||||||S(N(t TestResponse(Rt.1t total_timeR@RJR{R((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRsN(R R RtdisabledR'RR(R:RRNR_RaRcReRDRYRpRGRRR(((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyR+Zs. +   6 "       <  RcBs5eZdZdZdZdZdZRS(cCst|_||_dS(N(Rtcapturedtactual(RR((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRs cCs$|jj||jj|dS(N(RRR(Rts((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRscCs|jjdS(N(Rtflush(R((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRscCs"x|D]}|j|qWdS(N(R(RRvtitem((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyt writeliness cCs |jjS(N(RR(R((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRs(R R RRRRR(((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRs     RcBs2eZeZdZdZeeddZdZeeddZ e j de j e j BZdZedZd Zd Zddddded Zddddded Zd ZddZe j dZdZeeddZdZdZdZdZ dZ!RS(cCsz||_t|jd|_||_||_tj|j|_||_ ||_ d|_ ||_ d|_dS(Ni(ttest_apptintRCR@RRJRtfromlistt header_dictR{RR't _normal_bodyRt_forms_indexed(RRR@RJR{RR((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRs       cCs#|jdkr|jn|jS(s Returns a dictionary of ``Form`` objects. Indexes are both in order (from zero) and by form id (if the form is given an id). N(RR't _parse_forms(R((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyt forms__gets tdocs A list of
s found on the page (instances of `Form `_) cCsA|j}|stdnd|kr9tdn|dS(Ns*You used response.form, but no forms existis5You used response.form, but more than one form existsi(tformst TypeError(RR((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyt form__gets    s Returns a single `Form `_ instance; it is an error if there are multiple forms on the page. s<(/?)([:a-z0-9_\-]*)(.*?)>c CsWi}|_g}d}x|jj|jD]}|jddk}|jdj}|dkrqq/n|r|std|j|j |j||j !d}q/| std|j|j}q/W| std|j|xLt |D]>\}}t ||} | ||<| j r| || j unexpected at %ssNested form tags at %ssDanging form: %r(RR't_tag_retfinditerR{tgroupRhRtstartRotendt enumeratetFormtid( RRt form_textststartedtmatchRttagtittextR((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRs.        cCsd}xX|jD]M\}}|j|jkr| sTtd|||f|}qqW|dkr|tkrtd|djg|jD]\}}|^qfq|Sn|S(s Returns the named header; an error if there is not exactly one matching header (unless you give a default -- always an error if there is more than one header) s&Ambiguous header: %s matches %r and %rsNo header found: %r (from %s)s, N(R'RJRhRR tKeyErrorRs(RRtdefaulttfoundtcur_nameRltntv((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRk+s    8cCsLg}x?|jD]4\}}|j|jkr|j|qqW|S(sE Gets all headers by the ``name``, returns as a list (RJRhRo(RRRRRl((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pyRAs cKs}|jdkr|jdks1td|j|jd}tj|\}}tj|\}}|jj||S(s If this request is a redirect, follow that redirect. It is an error if this is not a redirect response. Returns another response object. i,is/You can only follow redirect responses (not %s)tlocation( R@RRRkRAt splittypet splithostRRN(RtkwRttypetrestthostR}((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytfollowKs! c Csbt}|jdddddd d|d|d|d |d |d | \}} } |j| d S(s Click the link as described. Each of ``description``, ``linkid``, and ``url`` are *patterns*, meaning that they are either strings (regular expressions), compiled regular expressions (objects with a ``search`` method), or callables returning true or false. All the given patterns are ANDed together: * ``description`` is a pattern that matches the contents of the anchor (HTML and all -- everything between ```` and ````) * ``linkid`` is a pattern that matches the ``id`` attribute of the anchor. It will receive the empty string if no id is given. * ``href`` is a pattern that matches the ``href`` of the anchor; the literal content of that attribute, not the fully qualified attribute. * ``anchor`` is a pattern that matches the entire anchor, with its contents. If more than one link matches, then the ``index`` link is followed. If ``index`` is not given and more than one link matches, or if no link matches, then ``IndexError`` will be raised. If you give ``verbose`` then messages will be printed about each link, and why it does or doesn't match. If you use ``app.click(verbose=True)`` you'll see a list of all the links. You can use multiple criteria to essentially assert multiple aspects about the link, e.g., where the link's destination is. Rtat href_attrthreft href_extractRRt href_patternt html_patterntindextverboseturiN(Rt _find_elementR'tgoto( Rt descriptiontlinkidRtanchorRRRLt found_htmlt found_desct found_attrs((s>/opt/alt/python27/lib/python2.7/site-packages/paste/fixture.pytclickZs'  c Cskt}|jdddddtjdd|d|d |d |d |d | \}} } |j| d S(s Like ``.click()``, except looks for link-like buttons. This kind of button should look like ``