�9�c@s�dZeZddlZddlZddlmZddlmZm Z yddl
mZmZWn'e
k
r�ddlmZmZnXeje�Zdefd��YZdS(s�
This plugin adds a test id (like #1) to each test name output. After
you've run once to generate test ids, you can re-run individual
tests by activating the plugin and passing the ids (with or
without the # prefix) instead of test names.
For example, if your normal test run looks like::
% nosetests -v
tests.test_a ... ok
tests.test_b ... ok
tests.test_c ... ok
When adding ``--with-id`` you'll see::
% nosetests -v --with-id
#1 tests.test_a ... ok
#2 tests.test_b ... ok
#2 tests.test_c ... ok
Then you can re-run individual tests by supplying just an id number::
% nosetests -v --with-id 2
#2 tests.test_b ... ok
You can also pass multiple id numbers::
% nosetests -v --with-id 2 3
#2 tests.test_b ... ok
#3 tests.test_c ... ok
Since most shells consider '#' a special character, you can leave it out when
specifying a test id.
Note that when run without the -v switch, no special output is displayed, but
the ids file is still written.
Looping over failed tests
-------------------------
This plugin also adds a mode that will direct the test runner to record
failed tests. Subsequent test runs will then run only the tests that failed
last time. Activate this mode with the ``--failed`` switch::
% nosetests -v --failed
#1 test.test_a ... ok
#2 test.test_b ... ERROR
#3 test.test_c ... FAILED
#4 test.test_d ... ok
On the second run, only tests #2 and #3 will run::
% nosetests -v --failed
#2 test.test_b ... ERROR
#3 test.test_c ... FAILED
As you correct errors and tests pass, they'll drop out of subsequent runs.
First::
% nosetests -v --failed
#2 test.test_b ... ok
#3 test.test_c ... FAILED
Second::
% nosetests -v --failed
#3 test.test_c ... FAILED
When all tests pass, the full set will run on the next invocation.
First::
% nosetests -v --failed
#3 test.test_c ... ok
Second::
% nosetests -v --failed
#1 test.test_a ... ok
#2 test.test_b ... ok
#3 test.test_c ... ok
#4 test.test_d ... ok
.. note ::
If you expect to use ``--failed`` regularly, it's a good idea to always run
run using the ``--with-id`` option. This will ensure that an id file is
always created, allowing you to add ``--failed`` to the command line as soon
as you have failing tests. Otherwise, your first run using ``--failed`` will
(perhaps surprisingly) run *all* tests, because there won't be an id file
containing the record of failed tests from your previous run.
i�N(tPlugin(tsrctset(tdumptloadtTestIdcBs�eZdZdZdZeZeZ d�Z
d�Zd�Zdd�Z
d�Zd�Zd�Zd �Zd
�Zd�ZRS(
s
Activate to add a test id (like #1) to each test name output. Activate
with --failed to rerun failing tests only.
tidcCsgtj|||�|jddddddddd d
d�|jddd
dddtd
d�dS(s&Register commandline options.
s --id-filetactiontstoretdestt
testIdFiletdefaults.noseidstmetavartFILEthelpsfStore test ids found in test runs in this file. Default is the file .noseids in the working directory.s--failedt
store_truetfaileds/Run the tests that failed in the last test run.N(Rtoptionst
add_optiontFalse(tselftparsertenv((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pyRxscCs�tj|||�|jr>t|_t|_tjd�ntj j
|j�|_tj j
|j�s�tj j|j|j�|_nd|_i|_i|_g|_g|_i|_|jdk|_dS(sConfigure plugin.
sLooping on failed testsiiN(Rt configureRtTruetenabledtloopOnFailedtlogtdebugtostpatht
expanduserR
tidfiletisabstjoint
workingDirRtidstteststsource_namest_seent verbosityt
_write_hashes(RRtconf((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pyR�s ! cCs�|j�rg|_n|jr]tttt|jj��t|jj�����}n |j }t
|jd�}ti|d6|jd6|j
d6|�|j�tjd||j|j�dS(s&Save new ids file, if needed.
twbR$RR&s#Saved test ids: %s, failed %s to %sN(t
wasSuccessfulRt
collectingtdicttlisttzipR%tvaluestkeysR$topenR RR&tcloseRR(RtresultR$tfh((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pytfinalize�s <
c
Cs�tjd||�yt|jd�}t|�}d|krj|d|_|d|_|d|_n||_g|_||_|jr�|j�d|_ t
ttt|jj
��t|jj�����|_n d|_ tjd|j|j|j|j|j�|j�Wn$tk
rHtjd|j�nX|jry|jryt|_|j}g|_ng}g}g}xF|D]>}|j|�} | |kr�|j| �q�|j|�q�W|rXt|�}
t|j�}tjd ||
�g|D]}||kr|^q}|rF|jj|�n|sa|}qan t|_tjd
|||�d||p�|fS(sTranslate ids in the list of requested names into their
test addresses, if they are found in my dict of tests.
s
ltfn %s %strbR$RR&is8Loaded test ids %s tests %s failed %s sources %s from %ssIO error reading %ssold: %s new: %ss&translated: %s new sources %s names %sN(RRR3R RR$RR&tmaxRR.R/R0R1R2R%R4tIOErrorRRR-ttrtappendRtextendtNone(
RtnamestmoduleR6tdatat
translatedt
new_sourcet
really_newtnamettranstnew_settold_setts((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pytloadTestsFromNames�s`
?
cCs^tjd|�|\}}}|dk r:t|�}n|}|dk rZd||fS|S(NsMake name %ss%s:%s(RRR>R(RtaddrtfilenameR@tcallthead((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pytmakeName�scCs
||_dS(sBGet handle on output stream so the plugin can print id #s
N(tstream(RRP((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pytsetOutputStream�scCs�|j�}tjd|||jk�||jkr||jkrV|jd�n%|jd|j|�d|j|<dS|j|j|<|jd|j�|jd7_dS(s�Maybe output an id # before the test name.
Example output::
#1 test.test ... ok
#2 test.test_two ... ok
sstart test %s (%s)s s#%s iN(taddressRRR%R'twriteR(Rttesttadr((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pyt startTests
cCsi|jtkreyt|j|j��}Wntk
r?qeX||jkre|jj|�qendS(N(tpassedRtstrR%RRtKeyErrorRR<(RRTtkey((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pyt afterTests
cCsxtjd|�yt|jdd��}Wntk
r@|SXtjd|�||jkrt|j|j|�S|S(Nstr '%s't#ts
Got key %s(RRtinttreplacet
ValueErrorR$RO(RRERZ((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pyR;#s
cCs |jr|jj|�ndS(N(R)RPRS(Rtoutput((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pyRS0s N(t__name__t
__module__t__doc__RER>R RR-RRRRR7RJRORQRVR[R;RS(((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pyRns C
(RdRt__test__tloggingRtnose.pluginsRt nose.utilRRtcPickleRRtImportErrortpicklet getLoggerRbRR(((s7/sys/lib/python2.7/site-packages/nose/plugins/testid.pyt<module>^s
|