Coverage for C:\__py\mylib\python-patch\patch : - 77% -
-
-
-
-Hot-keys on this page
-- r - m - x - p toggle line displays -
-- j - k next/prev highlighted chunk -
-- 0 (zero) top of page -
-- 1 (one) first highlighted chunk -
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | -
- #!/usr/bin/env python - -- Brute-force line-by-line non-recursive parsing -- Copyright (c) 2008-2014 anatoly techtonik -Available under the terms of MIT license -- Project home: http://code.google.com/p/python-patch/ -- - $Id$ -$HeadURL$ -""" -- - - - - - - # cStringIO doesn't support unicode in 2.5 - - -- - - - - - - #------------------------------------------------ -# Logging is controlled by logger named after the -# module name (e.g. 'patch' for patch.py module) -- - - - - - - - - - """ Copied from Python 2.7 to avoid getting -`No handlers could be found for logger "patch"` -http://bugs.python.org/issue16539 -""" - - - -pass - - -- - - #------------------------------------------------ -# Constants for Patch/PatchSet types -- - - - - # mixed type is only actual when PatchSet contains -# Patches of different type - -- - #------------------------------------------------ -# Helpers (these could come with Python stdlib) -- # x...() function are used to work with paths in -# cross-platform manner - all paths use forward -# slashes even on Windows. -- - """ Cross-platform version of `os.path.isabs()` -Returns True if `filename` is absolute on -Linux, OS X or Windows. -""" - - - - - - - -- - """ Cross-platform version of os.path.normpath """ -# replace escapes and Windows slashes - -# fold the result - -- - """ Make relative path out of absolute by stripping -prefixes used on Linux, OS X and Windows. -- This function is critical for security. -""" - -# strip windows drive with all slashes - - -# strip all slashes - - - -- #----------------------------------------------- -# Main API functions -- - """ Parse patch file. If successful, returns -PatchSet() object. Otherwise returns False. -""" - - - - - - - - -- - - """ Parse text string and return PatchSet() -object (or False if parsing fails) -""" - - - -return False -- - - """ Parse patch from an URL, return False -if an error occured. Note that this also -can throw urlopen() exceptions. -""" -ps = PatchSet( urllib2.urlopen(url) ) -if ps.errors == 0: -return ps -return False -- - # --- Utility functions --- -# [ ] reuse more universal pathsplit() - -""" Strip n leading components from the given path """ - - - - -# --- /Utility function --- -- - - """ Parsed hunk data container (hunk starts with @@ -R +R @@) """ -- - - - - - - - - - # def apply(self, estream): -# """ write hunk data into enumerable stream -# return strings one by one until hunk is -# over -# -# enumerable stream are tuples (lineno, line) -# where lineno starts with 0 -# """ -# pass -- - - """ Patch for a single file. -If used as an iterable, returns hunks. -""" - - - - - - -- - - - for h in self.hunks: -yield h -- - - """ PatchSet is a patch parser and container. -When used as an iterable, returns patches. -""" -- - # --- API accessible fields --- -- # name of the PatchSet (filename or ...) - -# patch set type - one of constants - -- # list of Patch objects - -- - - # --- /API --- -- - - - - - - - - - - - """ parse unified diff -return True on success -""" - - -- - - # hunkactual variable is used to calculate hunk lines for comparison - -- - - """Enumerate wrapper that uses boolean end of stream status instead of -StopIteration exception, and properties to access line information. -""" -- - # we don't call parent, it is magically created by __new__ method -- - - - - - """Try to read the next line and return True if it is available, -False if end of stream is reached.""" - - -- - - - - - - - - - def is_empty(self): - -- - def line(self): - -- - def lineno(self): - -- # define states (possible file regions) that direct parse flow - - -- - - - - - - # regexp to match start of hunk, used groups - 1,3,4,6 - -- - # temp buffers for header and filenames info - - - -- # start of main cycle -# each parsing block already has line available in fe.line - - -- # -- deciders: these only switch state to decide who should process -# -- line fetched at the start of this cycle - - - - - -filenames = True -else: - -# -- ------------------------------------ -- # read out header - - - - - - - - -else: - - -# TODO check for \No new line at the end.. -# TODO test for unparsed bytes -# otherwise error += 1 -# this is actually a loop exit - -- - # switch to filenames state - -- - - - - # hunkskip and hunkbody code skipped until definition of hunkhead is parsed - -# [x] treat empty lines inside hunks as containing single space -# (this happens when diff is saved by copy/pasting to editor -# that strips trailing whitespace) - - - - -- # process line first - -# gather stats about line endings - - - - -elif line.endswith("\r"): -p.hunkends["cr"] += 1 -- - - - - - - - - # todo: handle \ No newline cases -else: - -# add hunk status node - - - -# switch to hunkskip state - - -- # check exit conditions - -warning("extra lines for hunk no.%d at %d for target %s" % (nexthunkno, lineno+1, p.target)) -# add hunk status node -hunk.invalid = True -p.hunks.append(hunk) -self.errors += 1 -# switch to hunkskip state -hunkbody = False -hunkskip = True - -# hunk parsed successfully - -# switch to hunkparsed state - - -- # detect mixed window/unix line ends - - -warning("inconsistent line ends in patch hunks for %s" % p.source) -self.warnings += 1 - -debuglines = dict(ends) -debuglines.update(file=p.target, hunk=nexthunkno) -debug("crlf: %(crlf)d lf: %(lf)d cr: %(cr)d\t - file: %(file)s hunk: %(hunk)d" % debuglines) -# fetch next line -continue -- - - # switch to hunkhead state -hunkskip = False -hunkhead = True - -# switch to filenames state - - - -debug("- %2d hunks for %s" % (len(p.hunks), p.source)) -- - - - # XXX testcase -warning("skipping false patch for %s" % srcname) -srcname = None -# XXX header += srcname -# double source filename line is encountered -# attempt to restart from this second line - - -# todo: support spaces in filenames - - -else: -warning("skipping invalid filename at line %d" % lineno) -self.errors += 1 -# XXX p.header += line -# switch back to headscan state -filenames = False -headscan = True - - - - - -# XXX header += srcname -# XXX header += line -else: -# this should be unreachable -warning("skipping invalid target patch") - - -else: - -# XXX seems to be a dead branch -warning("skipping invalid patch - double target at line %d" % lineno) -self.errors += 1 -srcname = None -tgtname = None -# XXX header += srcname -# XXX header += tgtname -# XXX header += line -# double target filename line is encountered -# switch back to headscan state -filenames = False -headscan = True -else: - - - -warning("skipping invalid patch - no target filename at line %d" % lineno) -self.errors += 1 -srcname = None -# switch back to headscan state -filenames = False -headscan = True -else: - - - - - - - - -# switch to hunkhead state - - - - - -- - - - if not p.hunks: -warning("skipping invalid patch with no hunks for file %s" % p.source) -self.errors += 1 -# XXX review switch -# switch to headscan state -hunkhead = False -headscan = True -continue -else: -# TODO review condition case -# switch to headscan state -hunkhead = False -headscan = True -else: - - - - - - - - - - -- - - # switch to hunkbody state - - - - -- # /while fe.next() -- - - - - - warning("warning: finished with errors, some hunks may be invalid") - - - - -else: # extra data at the end of file -pass -else: - - - - -- - debug("- %2d hunks for %s" % (len(p.hunks), p.source)) -- # XXX fix total hunks calculation - -sum(len(p.hunks) for p in self.items))) -- # ---- detect patch and patchset types ---- - - -- - - - else: - -# -------- -- - - - - - """ detect and return type for the specified Patch object -analyzes header and filenames info -- NOTE: must be run before filenames are normalized -""" -- # check for SVN -# - header starts with Index: -# - next line is ===... delimiter -# - filename is followed by revision number -# TODO add SVN revision - -and p.header[-1].startswith("="*67)): - -- # common checks for both HG and GIT - -and (p.target.startswith('b/') or p.target == '/dev/null')) -- # GIT type check -# - header[-2] is like "diff --git a/oldname b/newname" -# - header[-1] is like "index <hash>..<hash> <mode>" -# TODO add git rename diffs and add/remove diffs -# add git diff with spaced filename -# TODO http://www.kernel.org/pub/software/scm/git/docs/git-diff.html -- # detect the start of diff header - there might be some comments before - - - - - - -and re.match(r'index \w{7}..\w{7} \d{6}', p.header[idx+1])): - - -- # HG check -# -# - for plain HG format header is like "diff -r b2d9961ff1f5 filename" -# - for Git-style HG patches it is "diff --git a/oldname b/newname" -# - filename starts with a/, b/ or is equal to /dev/null -# - exported changesets also contain the header -# # HG changeset patch -# # User name@example.com -# ... -# TODO add MQ -# TODO add revision info - - - - - - - - -- - - - - """ sanitize filenames, normalizing paths, i.e.: -1. strip a/ and b/ prefixes from GIT and HG style patches -2. remove all references to parent directories (with warning) -3. translate any absolute paths to relative (with warning) -- [x] always use forward slashes to be crossplatform -(diff/patch were born as a unix utility after all) -- return None -""" - - -# TODO: figure out how to deal with /dev/null entries - - - -warning("invalid source filename") -else: - - - -warning("invalid target filename") -else: - -- - - - - - # references to parent are not allowed - - - - - - - - - - -# absolute paths are not allowed - - - - - - - - - -- - - - - - """ calculate diffstat and return as a string -Notes: -- original diffstat ouputs target filename -- single + or - shouldn't escape histogram -""" - - - - - - -# (for histogram width calculation) - - - - - - - - - - - - - - - - - - -# %-19s | %-4d %s - -- - # -- calculating histogram -- - - - - -else: -iratio = (float(insert[i]) / maxdiff) * histwidth -dratio = (float(delete[i]) / maxdiff) * histwidth -- # make sure every entry gets at least one + or - -iwidth = 1 if 0 < iratio < 1 else int(iratio) -dwidth = 1 if 0 < dratio < 1 else int(dratio) -#print iratio, dratio, iwidth, dwidth, histwidth -hist = "+"*int(iwidth) + "-"*int(dwidth) -# -- /calculating +- histogram -- - -- - % (len(names), sum(insert), sum(delete), delta)) - -- - - """ return name of file to be patched or None """ - - -elif exists(new): -return new -else: -# [w] Google Code generates broken patches with its online editor -debug("broken patch from Google Code, stripping prefixes..") -if old.startswith('a/') and new.startswith('b/'): -old, new = old[2:], new[2:] -debug(" %s" % old) -debug(" %s" % new) -if exists(old): -return old -elif exists(new): -return new -return None -- - - """ Apply parsed patch, optionally stripping leading components -from file paths. `root` parameter specifies working dir. -return True on success -""" - - - -- - - - # [ ] test strip level exceeds nesting level -# [ ] test the same only for selected files -# [ ] test if files end up being on the same level - - -except ValueError: -errors += 1 -warning("error: strip parameter '%s' must be an integer" % strip) -strip = 0 -- #for fileno, filename in enumerate(self.source): - - - - - - - -else: - -- - - - warning("source/target file does not exist:\n --- %s\n +++ %s" % (old, new)) -errors += 1 -continue - -warning("not a file - %s" % filename) -errors += 1 -continue -- # [ ] check absolute paths security here - -- # validate before patching - - - - - - - - - - - - - -#pprint(hunkreplace) - -- # todo \ No newline at end of file -- # check hunks in source file - - - -else: -info("file %d/%d:\t %s" % (i+1, total, filename)) -info(" hunk no.%d doesn't match source file at line %d" % (hunkno+1, lineno)) -info(" expected: %s" % hunkfind[hunklineno]) -info(" actual : %s" % line.rstrip("\r\n")) -# not counting this as error, because file may already be patched. -# check if file is already patched is done after the number of -# invalid hunks if found -# TODO: check hunks against source/target file in one pass -# API - check(stream, srchunks, tgthunks) -# return tuple (srcerrs, tgterrs) -- # continue to check other hunks for completeness -hunkno += 1 -if hunkno < len(p.hunks): -hunk = p.hunks[hunkno] -continue -else: -break -- # check if processed line is the last line - - - - - - -else: - -# patch file - - -else: - - - -- - - - - warning("already patched %s" % filename) -else: - - - - - -warning("can't backup original file to %s - aborting" % backupname) -else: - - - - - -else: -errors += 1 -warning("error patching file %s" % filename) -shutil.copy(filename, filename+".invalid") -warning("invalid version is saved to %s" % filename+".invalid") -# todo: proper rejects -shutil.move(backupname, filename) -- - - - # todo: check for premature eof - -- - - """ reverse patch direction (this doesn't touch filenames) """ - - - - - - - - - -- - """ apply patch in reverse order """ - - - -- - - """ Check if specified filename can be patched. Returns None if file can -not be found among source filenames. False if patch can not be applied -clearly. True otherwise. -- :returns: True, False or None -""" - - - - - -- - - - - - - - - - - - - - # skip to first line of the hunk - - - - - - - - - - -debug("check failed - premature eof on hunk: %d" % (hno+1)) -# todo: \ No newline at the end of file -raise NoMatch - - - - - -- - - # todo: display failed hunk, i.e. expected/found -- - - - - - """ Generator that yields stream patched with hunks iterable -- Converts lineends in hunk lines to the best suitable format -autodetected from input -""" -- # todo: At the moment substituted lineends may not be the same -# at the start and at the end of patching. Also issue a -# warning/throw about mixed lineends (is it really needed?) -- - - - - - - """ -local utility function - return line from source stream -collecting line end statistics on the way -""" - -# 'U' mode works only with text files - - - - -elif line.endswith("\r"): -lineends["\r"] += 1 - -- - - # skip to line just before hunk starts - - - -- - # todo: check \ No newline at the end of file - - - - -else: - - - - -# detect if line ends are consistent in source file - - - -else: # newlines are mixed -yield line2write -- - - - - - - - - - - - - - - # [ ] TODO: add test for permission copy - - -- - - for p in self.items: -for headline in p.header: -print headline.rstrip('\n') -print '--- ' + p.source -print '+++ ' + p.target -for h in p.hunks: -print '@@ -%s,%s +%s,%s @@' % (h.startsrc, h.linessrc, h.starttgt, h.linestgt) -for line in h.text: -print line.rstrip('\n') -- - - from optparse import OptionParser -from os.path import exists -import sys -- opt = OptionParser(usage="1. %prog [options] unified.diff\n" -" 2. %prog [options] http://host/patch\n" -" 3. %prog [options] -- < unified.diff", -version="python-patch %s" % __version__) -opt.add_option("-q", "--quiet", action="store_const", dest="verbosity", -const=0, help="print only warnings and errors", default=1) -opt.add_option("-v", "--verbose", action="store_const", dest="verbosity", -const=2, help="be verbose") -opt.add_option("--debug", action="store_true", dest="debugmode", help="debug mode") -opt.add_option("--diffstat", action="store_true", dest="diffstat", -help="print diffstat and exit") -opt.add_option("-d", "--directory", metavar='DIR', -help="specify root directory for applying patch") -opt.add_option("-p", "--strip", type="int", metavar='N', default=0, -help="strip N path components from filenames") -opt.add_option("--revert", action="store_true", -help="apply patch in reverse order (unpatch)") -(options, args) = opt.parse_args() -- if not args and sys.argv[-1:] != ['--']: -opt.print_version() -opt.print_help() -sys.exit() -readstdin = (sys.argv[-1:] == ['--'] and not args) -- debugmode = options.debugmode -- verbosity_levels = {0:logging.WARNING, 1:logging.INFO, 2:logging.DEBUG} -loglevel = verbosity_levels[options.verbosity] -logformat = "%(message)s" -if debugmode: -loglevel = logging.DEBUG -logformat = "%(levelname)8s %(message)s" -logger.setLevel(loglevel) -loghandler = logging.StreamHandler() -loghandler.setFormatter(logging.Formatter(logformat)) -logger.addHandler(loghandler) -- - if readstdin: -patch = PatchSet(sys.stdin) -else: -patchfile = args[0] -urltest = patchfile.split(':')[0] -if (':' in patchfile and urltest.isalpha() -and len(urltest) > 1): # one char before : is a windows drive letter -patch = fromurl(patchfile) -else: -if not exists(patchfile) or not isfile(patchfile): -sys.exit("patch file does not exist - %s" % patchfile) -patch = fromfile(patchfile) -- if options.diffstat: -print patch.diffstat() -sys.exit(0) -- #pprint(patch) -if options.revert: -patch.revert(options.strip, root=options.directory) or sys.exit(-1) -else: -patch.apply(options.strip, root=options.directory) or sys.exit(-1) -- # todo: document and test line ends handling logic - patch.py detects proper line-endings -# for inserted hunks and issues a warning if patched file has incosistent line ends -- - # Legend: -# [ ] - some thing to be done -# [w] - official wart, external or internal that is unlikely to be fixed -- # [ ] API break (2.x) wishlist -# PatchSet.items --> PatchSet.patches -- # [ ] run --revert test for all dataset items -# [ ] run .parse() / .dump() test for dataset - - |
-
-
- Hot-keys on this page
-- n - s - m - x - - c change column sorting -
-| Module | -statements | -missing | -excluded | - -coverage | -
|---|---|---|---|---|
| Total | -927 | -164 | -0 | - -82% | -
| C:\__py\mylib\python-patch\patch | -673 | -157 | -0 | - -77% | -
| run_tests | -254 | -7 | -0 | - -97% | -
| t |
":function(g,j){var o=typeof j==="string",m,p=0,q=g.length;if(o&&!/\W/.test(j))for(j=j.toLowerCase();p=0))o||m.push(t);else if(o)j[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var j=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=j[1]+(j[2]||1)-0;g[3]=j[3]-0}g[0]=e++;return g},ATTR:function(g,j,o, -m,p,q){j=g[1].replace(/\\/g,"");if(!q&&n.attrMap[j])g[1]=n.attrMap[j];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,j,o,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=l(g[3],null,null,j);else{g=l.filter(g[3],j,o,true^p);o||m.push.apply(m,g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled=== -true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,j,o){return!!l(o[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"=== -g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,j){return j===0},last:function(g,j,o,m){return j===m.length-1},even:function(g,j){return j%2===0},odd:function(g,j){return j%2===1},lt:function(g,j,o){return jo[3]-0},nth:function(g,j,o){return o[3]- -0===j},eq:function(g,j,o){return o[3]-0===j}},filter:{PSEUDO:function(g,j,o,m){var p=j[1],q=n.filters[p];if(q)return q(g,o,j,m);else if(p==="contains")return(g.textContent||g.innerText||l.getText([g])||"").indexOf(j[3])>=0;else if(p==="not"){j=j[3];o=0;for(m=j.length;o =0}},ID:function(g,j){return g.nodeType===1&&g.getAttribute("id")===j},TAG:function(g,j){return j==="*"&&g.nodeType===1||g.nodeName.toLowerCase()=== -j},CLASS:function(g,j){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(j)>-1},ATTR:function(g,j){var o=j[1];o=n.attrHandle[o]?n.attrHandle[o](g):g[o]!=null?g[o]:g.getAttribute(o);var m=o+"",p=j[2],q=j[4];return o==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&o!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,j,o,m){var p=n.setFilters[j[2]]; -if(p)return p(g,o,j,m)}}},s=n.match.POS,v=function(g,j){return"\\"+(j-0+1)},B;for(B in n.match){n.match[B]=RegExp(n.match[B].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[B]=RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[B].source.replace(/\\(\d+)/g,v))}var D=function(g,j){g=Array.prototype.slice.call(g,0);if(j){j.push.apply(j,g);return j}return g};try{Array.prototype.slice.call(u.documentElement.childNodes,0)}catch(H){D=function(g,j){var o=j||[],m=0;if(f.call(g)==="[object Array]")Array.prototype.push.apply(o, -g);else if(typeof g.length==="number")for(var p=g.length;m";var o=u.documentElement;o.insertBefore(g,o.firstChild);if(u.getElementById(j)){n.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:A:[]};n.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}o.removeChild(g); -o=g=null})();(function(){var g=u.createElement("div");g.appendChild(u.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(j,o){var m=o.getElementsByTagName(j[1]);if(j[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(j){return j.getAttribute("href",2)};g=null})();u.querySelectorAll&& -function(){var g=l,j=u.createElement("div");j.innerHTML="";if(!(j.querySelectorAll&&j.querySelectorAll(".TEST").length===0)){l=function(m,p,q,t){p=p||u;if(!t&&!l.isXML(p))if(p.nodeType===9)try{return D(p.querySelectorAll(m),q)}catch(x){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var C=p.id,P=p.id="__sizzle__";try{return D(p.querySelectorAll("#"+P+" "+m),q)}catch(N){}finally{if(C)p.id=C;else p.removeAttribute("id")}}return g(m,p,q,t)};for(var o in g)l[o]=g[o]; -j=null}}();(function(){var g=u.documentElement,j=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,o=false;try{j.call(u.documentElement,":sizzle")}catch(m){o=true}if(j)l.matchesSelector=function(p,q){try{if(o||!n.match.PSEUDO.test(q))return j.call(p,q)}catch(t){}return l(q,null,null,[p]).length>0}})();(function(){var g=u.createElement("div");g.innerHTML="";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length=== -0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(j,o,m){if(typeof o.getElementsByClassName!=="undefined"&&!m)return o.getElementsByClassName(j[1])};g=null}}})();l.contains=u.documentElement.contains?function(g,j){return g!==j&&(g.contains?g.contains(j):true)}:function(g,j){return!!(g.compareDocumentPosition(j)&16)};l.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var M=function(g, -j){for(var o=[],m="",p,q=j.nodeType?[j]:j;p=n.match.PSEUDO.exec(g);){m+=p[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;p=0;for(var t=q.length;p 0)for(var h=d;h 0},closest:function(a, -b){var d=[],e,f,h=this[0];if(c.isArray(a)){var k={},l,n=1;if(h&&a.length){e=0;for(f=a.length;e -1:c(h).is(e))d.push({selector:l,elem:h,level:n})}h=h.parentNode;n++}}return d}k=$a.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e -1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h|| -!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context):c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}}); -c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling", -d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Wa.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||Ya.test(e))&&Xa.test(a))f=f.reverse();return this.pushStack(f,a,Za.call(arguments).join(","))}}); -c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===A||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var xa=/ jQuery\d+="(?:\d+|null)"/g, -$=/^\s+/,ya=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,za=/<([\w:]+)/,ab=/\s]+\/)>/g,O={option:[1,""],legend:[1,""],thead:[1," ","
"],tr:[2,"","
"],td:[3,""],col:[2,"
"," "], -area:[1,""],_default:[0,"",""]};O.optgroup=O.option;O.tbody=O.tfoot=O.colgroup=O.caption=O.thead;O.th=O.td;if(!c.support.htmlSerialize)O._default=[1,"div
"," ",""];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==A)return this.empty().append((this[0]&&this[0].ownerDocument||u).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this, -d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})}, -unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a= -c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*")); -c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(xa,"").replace(cb,'="$1">').replace($, -"")],e)[0]}else return this.cloneNode(true)});if(a===true){la(this,b);la(this.find("*"),b.find("*"))}return b},html:function(a){if(a===A)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(xa,""):null;else if(typeof a==="string"&&!Aa.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!O[(za.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ya,"<$1>$2>");try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?l.cloneNode(true):l)}k.length&&c.each(k,Ka)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:u;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===u&&!Aa.test(a[0])&&(c.support.checkClone|| -!Ba.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h= -d.length;f 0?this.clone(true):this).get();c(d[f])[b](k);e=e.concat(k)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||u;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||u;for(var f=[],h=0,k;(k=a[h])!=null;h++){if(typeof k==="number")k+="";if(k){if(typeof k==="string"&&!bb.test(k))k=b.createTextNode(k);else if(typeof k==="string"){k=k.replace(ya,"<$1>$2>");var l=(za.exec(k)||["",""])[1].toLowerCase(),n=O[l]||O._default, -s=n[0],v=b.createElement("div");for(v.innerHTML=n[1]+k+n[2];s--;)v=v.lastChild;if(!c.support.tbody){s=ab.test(k);l=l==="table"&&!s?v.firstChild&&v.firstChild.childNodes:n[1]===" "&&!s?v.childNodes:[];for(n=l.length-1;n>=0;--n)c.nodeName(l[n],"tbody")&&!l[n].childNodes.length&&l[n].parentNode.removeChild(l[n])}!c.support.leadingWhitespace&&$.test(k)&&v.insertBefore(b.createTextNode($.exec(k)[0]),v.firstChild);k=v.childNodes}if(k.nodeType)f.push(k);else f=c.merge(f,k)}}if(d)for(h=0;f[h];h++)if(e&& -c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script"))));d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,k=0,l;(l=a[k])!=null;k++)if(!(l.nodeName&&c.noData[l.nodeName.toLowerCase()]))if(d=l[c.expando]){if((b=e[d])&&b.events)for(var n in b.events)f[n]? -c.event.remove(l,n):c.removeEvent(l,n,b.handle);if(h)delete l[c.expando];else l.removeAttribute&&l.removeAttribute(c.expando);delete e[d]}}});var Ca=/alpha\([^)]*\)/i,db=/opacity=([^)]*)/,eb=/-([a-z])/ig,fb=/([A-Z])/g,Da=/^-?\d+(?:px)?$/i,gb=/^-?\d/,hb={position:"absolute",visibility:"hidden",display:"block"},La=["Left","Right"],Ma=["Top","Bottom"],W,ib=u.defaultView&&u.defaultView.getComputedStyle,jb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===A)return this; -return c.access(this,a,b,true,function(d,e,f){return f!==A?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true,zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),k=a.style,l=c.cssHooks[h];b=c.cssProps[h]|| -h;if(d!==A){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!l||!("set"in l)||(d=l.set(a,d))!==A)try{k[b]=d}catch(n){}}}else{if(l&&"get"in l&&(f=l.get(a,false,e))!==A)return f;return k[b]}}},css:function(a,b,d){var e,f=c.camelCase(b),h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==A)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]= -e[f]},camelCase:function(a){return a.replace(eb,jb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=ma(d,b,f);else c.swap(d,hb,function(){h=ma(d,b,f)});return h+"px"}},set:function(d,e){if(Da.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return db.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"": -b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f=d.filter||"";d.filter=Ca.test(f)?f.replace(Ca,e):d.filter+" "+e}};if(ib)W=function(a,b,d){var e;d=d.replace(fb,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return A;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};else if(u.documentElement.currentStyle)W=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b], -h=a.style;if(!Da.test(f)&&gb.test(f)){d=h.left;e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f};if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var kb=c.now(),lb=/ - - - - - - - -
-- ---Coverage for run_tests : - 97% -
--
- 254 statements - - - - -
--- --
Hot-keys on this page
---- r - m - x - p toggle line displays -
-- j - k next/prev highlighted chunk -
-- 0 (zero) top of page -
-- 1 (one) first highlighted chunk -
--- - - - --
-- -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- -#!/usr/bin/env python
- -python-patch test suite
--
There are two kind of tests:
-- file-based tests
-- directory-based tests
-- unit tests
--
File-based test is patch file, initial file and resulting file
-for comparison.
--
Directory-based test is a self-sufficient directory with:
-files to be patched, patch file itself and [result] dir. You can
-manually apply patch and compare outcome with [result] directory.
-This is what this test runner does.
--
Unit tests test API and are all inside this runner.
--
-
== Code Coverage ==
--
To refresh code coverage stats, get 'coverage' tool from
-http://pypi.python.org/pypi/coverage/ and run this file with:
--
coverage run run_tests.py
-coverage html -d coverage
--
On Windows it may be more convenient instead of `coverage` call
-`python -m coverage.__main__`
-"""
-- - - - - - - - - -
- - -
verbose = True
--
-
# full path for directory with tests
- - - --
-
# import patch.py from parent directory
- - - - --
-
# ----------------------------------------------------------------------------
- -"""
-unittest hack - test* methods are generated by add_test_methods() function
-below dynamically using information about *.patch files from tests directory
--
"""
- - - - - - - --
finally:
- - - - -- -
"""
-compare dir2 with reference dir1, ignoring entries
-from supplied list
--
"""
-# recursive
- -ignore = [ignore]
- - - -continue
- - - - - - - -else:
- - - -self.fail("extra file or directory: %s" % e2)
--
- -
"""
-boilerplate for running *.patch file tests
-"""
--
# 1. create temp test directory
-# 2. copy files
-# 3. execute file-based patch
-# 4. compare results
-# 5. cleanup on success
-- -
- - -
- -
- - -
- - - -
else:
-# directory-based
- - - - -else:
- --
-
# 3.
-# test utility as a whole
- - - - -cmd = '%s %s "%s"' % (sys.executable, patch_tool, patch_file)
-print "\n"+cmd
-else:
- - - - --
-
# 4.
-# compare results
- - -else:
-# recursive comparison
- -tmpdir,
-ignore=["%s.patch" % testname, ".svn", "[result]"])
--
- - -
-
- -
"""
-hack to generate test* methods in target class - one
-for each *.patch file in tests directory
-"""
--
# list testcases - every test starts with number
-# and add them as test* methods
- -- - -
- - - - - - - -
print "added test method %s to %s" % (methname, cls)
- --
# ----------------------------------------------------------------------------
-- - - - -
- - -
- - - - -
- - - -
- - - - -
- - - - -
- - - -
- - - -
-
# ----------------------------------------------------------------------------
-- - - - - -
finally:
- - - -- - - - - - -
- - - -
- - - - -
- - - -
- - - - - -
- -
# [ ] exception vs return codes for error recovery
-# [x] separate return code when patch lib compensated the error
-# (implemented as warning count)
- - - - -- - - - -
- - - - - -
- - - - - -
- - - - - -
- - -
updatedlg.cpp | 20 ++++++++++++++++++--
-updatedlg.h | 1 +
-manifest.xml | 15 ++++++++-------
-conf.cpp | 23 +++++++++++++++++------
-conf.h | 7 ++++---
-5 files changed, 48 insertions(+), 18 deletions(-), +1203 bytes"""
- - -- - - - -
- - - -
- - - -
- - - -
- - - - - -
- - - -
- -
"""copy file(s) from test_dir to self.tmpdir"""
- - -- - -
'data/failing/upload.py'])
- - -- - -
'03trail_fname.from'])
- - -- - -
'03trail_fname.from'])
- - - -open(tests_dir + '/03trail_fname.from').read())
- - -open(tests_dir + '/03trail_fname.from').read())
-- - - - - -
- - - - - - - - -
- -
# unittest setting
- -- - -
- - - - - -
- - - -
- - - - - -
# test relative paths are not affected
- - -- - - - -
-
# ----------------------------------------------------------------------------
-- - - -