Kc@sdZddkZddkZddkZddkZddkZddkZddkZddkZddk Z ddk Z ddk Z ddk l Z yddklZWn#ej oddklZnXddkZyddkZWn#ej oddklZnXddklZddklZddklZd Zd efd YZd Zd efdYZdefdYZ defdYZ!defdYZ"defdYZ#defdYZ$defdYZ%ei&dei'Z(dZ)defdYZ*de*fd YZ+e+e*i,d!Z8e7e7e9d?Z:d@Z;e7dAZ<dBZ=dS(Cs 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(t subprocess24(twsgilib(tlint(t HeaderDictcGs ti|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((s1/usr/lib/python2.6/site-packages/paste/fixture.pyttempnam_no_warning&st NoDefaultcBseZRS((t__name__t __module__(((s1/usr/lib/python2.6/site-packages/paste/fixture.pyR .scCst|}|i|S(N(tlisttsort(tl((s1/usr/lib/python2.6/site-packages/paste/fixture.pytsorted1s  t Dummy_smtplibcBsGeZdZdZdZdZdZeeZdZ RS(cCsVddk}|idtd|i p td||_t|_||i_dS(Nis1Dummy_smtplib is not maintained and is deprecatedisIsmtplib.SMTP() called again before Dummy_smtplib.existing.reset() called.( twarningstwarntDeprecationWarningtexistingtAssertionErrortservertTruetopent __class__(tselfRR((s1/usr/lib/python2.6/site-packages/paste/fixture.pyt__init__:s    cCs%|iptd|t|_dS(NsCalled %s.quit() twice(RRtFalse(R((s1/usr/lib/python2.6/site-packages/paste/fixture.pytquitFs  cCs||_||_||_dS(N(t from_addresst to_addressestmessage(RRR tmsg((s1/usr/lib/python2.6/site-packages/paste/fixture.pytsendmailKs  cCs |t_dS(N(tsmtplibtSMTP(tcls((s1/usr/lib/python2.6/site-packages/paste/fixture.pytinstallPscCs%|i p tdd|i_dS(NsSMTP connection not quit(RRtNoneRR(R((s1/usr/lib/python2.6/site-packages/paste/fixture.pytresetUsN( R R R(RRRR#R't classmethodR)(((s1/usr/lib/python2.6/site-packages/paste/fixture.pyR6s    tAppErrorcBseZRS((R R (((s1/usr/lib/python2.6/site-packages/paste/fixture.pyR+ZstTestAppcBseZeZddddddZdZdZddddedZ dddddedZ dddddedZ dddddedZ ddddedZ d Zd Zd Zd Zd ZdZdZRS(cCst|ttfo&ddkl}||d|}n||_||_||_|djo h}n||_ ||_ ||_ |i 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)(RR3R4R.R5R6R7R-((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRbs        cCs h|_dS(sc Resets the state of the application; currently just clears saved cookies. N(tcookies(R((s1/usr/lib/python2.6/site-packages/paste/fixture.pyR)scCs|ii}t|d<|S(Nspaste.throw_errors(R5tcopyR(Rtenviron((s1/usr/lib/python2.6/site-packages/paste/fixture.pyt _make_environs c Cs|djo h}nt}|obt|ttfpti|dt}nd|jo|d7}n |d7}||7}n|i}t|}d|jo |idd\}|d`_ tdoseqt?t&it QUERY_STRINGttstatusN( R(RR/R0R1turllibt urlencodeR;tsplitt _set_headerstupdatet TestRequestt do_request( RturltparamstheadersR5RAt expect_errorst__tracebackhide__R:treq((s1/usr/lib/python2.6/site-packages/paste/fixture.pytgets&          R@c Cs|d jo h}n|d jo h}n|i} t|tttfoti|}nt|doti|i }n|o;t i |dt }|i ||\} }| | d`_ tPOSTRJRKR5RAR^RL(R`(RRIRJRKR5RAR^RL((s1/usr/lib/python2.6/site-packages/paste/fixture.pytposts cCs4|id|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 `_ tPUTRJRKR5RAR^RL(R`(RRIRJRKR5RAR^RL((s1/usr/lib/python2.6/site-packages/paste/fixture.pytputs cCs4|id|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 `_ tDELETERJRKR5RAR^RLN(R`R((RRIRJRKR5RARL((s1/usr/lib/python2.6/site-packages/paste/fixture.pytdeletes  cCs|pdSxz|iD]l\}}|idjo d}n:|idjo d}nd|iddi}|||td|iditt ||i i |i fndS|djoN|idjo|idjodStd|i|i i |i fn||ijotd|i|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 RURAR+t full_statusRttmapR0RRIR|R((RRARRM((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRs(   cCs%|iotd|indS(Ns!Application had errors logged: %s(terrorsR+(RR((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRs cCs+|\}}}}t||||||S(N(t TestResponse(Rt.1t total_timeRARKR|R((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRsN(R R RtdisabledR(RR)R;RROR`RbRdRfRERZRqRHRRR(((s1/usr/lib/python2.6/site-packages/paste/fixture.pyR,]s. +   6 "       <  RcBs5eZdZdZdZdZdZRS(cCst|_||_dS(N(Rtcapturedtactual(RR((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRs cCs$|ii||ii|dS(N(RRR(Rts((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRscCs|iidS(N(Rtflush(R((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRscCs"x|D]}|i|qWdS(N(R(RRwtitem((s1/usr/lib/python2.6/site-packages/paste/fixture.pyt writelinesscCs |iiS(N(RR(R((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRs(R R RRRRR(((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRs     RcBs2eZeZdZdZeeddZdZeeddZ e i de i e i BZdZedZd Zd Zddddded Zddddded Zd ZddZe i dZdZeeddZdZdZdZdZ dZ!RS(cCsz||_t|id|_||_||_ti|i|_||_ ||_ d|_ ||_ d|_dS(Ni(ttest_apptintRDRARRKRtfromlistt header_dictR|RR(t _normal_bodyRt_forms_indexed(RRRARKR|RR((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRs       cCs%|idjo|in|iS(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((s1/usr/lib/python2.6/site-packages/paste/fixture.pyt forms__getstdocs A list of
s found on the page (instances of `Form `_) cCsE|i}|ptdnd|jotdn|dS(Ns*You used response.form, but no forms existis5You used response.form, but more than one form existsi(tformst TypeError(RR((s1/usr/lib/python2.6/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 CsZh}|_g}d}x|ii|iD]}|iddj}|idi}|djoq/n|oB|ptd|i|i |i||i !d}q/| ptd|i|i}q/W| ptd|i|xNt |D]@\}}t ||} | ||<| i o| || i unexpected at %ssNested form tags at %ssDanging form: %r(RR(t_tag_retfinditerR|tgroupRiRtstartRptendt enumeratetFormtid( RRt form_textststartedtmatchRttagtittextR((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRs2         c Csd}xY|iD]N\}}|i|ijo)| ptd|||f|}qqW|djo\|tjoGtd|dig}|iD]\}}||q~fq|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(RKRiRR tKeyErrorRt( RRtdefaulttfoundtcur_nameRmRtntv((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRl.s    AcCsNg}xA|iD]6\}}|i|ijo|i|qqW|S(sE Gets all headers by the ``name``, returns as a list (RKRiRp(RRRRRm((s1/usr/lib/python2.6/site-packages/paste/fixture.pyRDs  cKs}|idjo|idjptd|i|id}ti|\}}ti|\}}|ii||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( RARRRlRBt splittypet splithostRRO(RtkwRttypetrestthostR~((s1/usr/lib/python2.6/site-packages/paste/fixture.pytfollowNs# c Csbt}|idddddd d|d|d|d |d |d | \}} } |i| 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 descriptiontlinkidRtanchorRRRMt found_htmlt found_desct found_attrs((s1/usr/lib/python2.6/site-packages/paste/fixture.pytclick]s'  c Cskt}|idddddtidd|d|d |d |d |d | \}} } |i| d S(s Like ``.click()``, except looks for link-like buttons. This kind of button should look like ``