D6359: test: change test's diff generation to use mdiff for nicer output
sangeet259 (Sangeet Kumar Mishra)
phabricator at mercurial-scm.org
Mon Jun 10 20:56:26 UTC 2019
sangeet259 updated this revision to Diff 15433.
sangeet259 edited the summary of this revision.
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D6359?vs=15052&id=15433
REVISION DETAIL
https://phab.mercurial-scm.org/D6359
AFFECTED FILES
tests/run-tests.py
tests/test-push.t
CHANGE DETAILS
diff --git a/tests/test-push.t b/tests/test-push.t
--- a/tests/test-push.t
+++ b/tests/test-push.t
@@ -8,343 +8,10 @@
$ hg init test-revflag
$ hg -R test-revflag unbundle "$TESTDIR/bundles/remote.hg"
adding changesets
- adding manifests
- adding file changes
- added 9 changesets with 7 changes to 4 files (+1 heads)
- new changesets bfaf4b5cbf01:916f1afdef90 (9 drafts)
- (run 'hg heads' to see heads, 'hg merge' to merge)
-
- $ for i in 0 1 2 3 4 5 6 7 8; do
- > echo
- > hg init test-revflag-"$i"
- > hg -R test-revflag push -r "$i" test-revflag-"$i"
- > hg -R test-revflag-"$i" verify
- > done
-
- pushing to test-revflag-0
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 1 changesets with 1 changes to 1 files
-
- pushing to test-revflag-1
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 2 changesets with 2 changes to 1 files
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 2 changesets with 2 changes to 1 files
-
- pushing to test-revflag-2
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 3 changesets with 3 changes to 1 files
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 3 changesets with 3 changes to 1 files
-
- pushing to test-revflag-3
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 4 changesets with 4 changes to 1 files
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 4 changesets with 4 changes to 1 files
-
- pushing to test-revflag-4
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 2 changesets with 2 changes to 1 files
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 2 changesets with 2 changes to 1 files
-
- pushing to test-revflag-5
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 3 changesets with 3 changes to 1 files
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 3 changesets with 3 changes to 1 files
-
- pushing to test-revflag-6
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 4 changesets with 5 changes to 2 files
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 4 changesets with 5 changes to 2 files
-
- pushing to test-revflag-7
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 5 changesets with 6 changes to 3 files
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 5 changesets with 6 changes to 3 files
-
- pushing to test-revflag-8
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 5 changesets with 5 changes to 2 files
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 5 changesets with 5 changes to 2 files
-
- $ cd test-revflag-8
-
- $ hg pull ../test-revflag-7
- pulling from ../test-revflag-7
- searching for changes
- adding changesets
+ Yeh line aise hi daalte hain
+ Man kar raha hai
+ So je baat
adding manifests
adding file changes
- added 4 changesets with 2 changes to 3 files (+1 heads)
- new changesets c70afb1ee985:faa2e4234c7a
+ added 8 changesets with 7 changes to 4 files (+34 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
-
- $ hg verify
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- checked 9 changesets with 7 changes to 4 files
-
- $ cd ..
-
-Test server side validation during push
-=======================================
-
- $ hg init test-validation
- $ cd test-validation
-
- $ cat > .hg/hgrc <<EOF
- > [server]
- > validate=1
- > EOF
-
- $ echo alpha > alpha
- $ echo beta > beta
- $ hg addr
- adding alpha
- adding beta
- $ hg ci -m 1
-
- $ cd ..
- $ hg clone test-validation test-validation-clone
- updating to branch default
- 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-#if reporevlogstore
-
-Test spurious filelog entries:
-
- $ cd test-validation-clone
- $ echo blah >> beta
- $ cp .hg/store/data/beta.i tmp1
- $ hg ci -m 2
- $ cp .hg/store/data/beta.i tmp2
- $ hg -q rollback
- $ mv tmp2 .hg/store/data/beta.i
- $ echo blah >> beta
- $ hg ci -m '2 (corrupt)'
-
-Expected to fail:
-
- $ hg verify
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- beta at 1: dddc47b3ba30 not in manifests
- checked 2 changesets with 4 changes to 2 files
- 1 integrity errors encountered!
- (first damaged changeset appears to be 1)
- [1]
-
- $ hg push
- pushing to $TESTTMP/test-validation
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- transaction abort!
- rollback completed
- abort: received spurious file revlog entry
- [255]
-
- $ hg -q rollback
- $ mv tmp1 .hg/store/data/beta.i
- $ echo beta > beta
-
-Test missing filelog entries:
-
- $ cp .hg/store/data/beta.i tmp
- $ echo blah >> beta
- $ hg ci -m '2 (corrupt)'
- $ mv tmp .hg/store/data/beta.i
-
-Expected to fail:
-
- $ hg verify
- checking changesets
- checking manifests
- crosschecking files in changesets and manifests
- checking files
- beta at 1: manifest refers to unknown revision dddc47b3ba30
- checked 2 changesets with 2 changes to 2 files
- 1 integrity errors encountered!
- (first damaged changeset appears to be 1)
- [1]
-
- $ hg push
- pushing to $TESTTMP/test-validation
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- transaction abort!
- rollback completed
- abort: missing file data for beta:dddc47b3ba30e54484720ce0f4f768a0f4b6efb9 - run hg verify
- [255]
-
- $ cd ..
-
-#endif
-
-Test push hook locking
-=====================
-
- $ hg init 1
-
- $ echo '[ui]' >> 1/.hg/hgrc
- $ echo 'timeout = 10' >> 1/.hg/hgrc
-
- $ echo foo > 1/foo
- $ hg --cwd 1 ci -A -m foo
- adding foo
-
- $ hg clone 1 2
- updating to branch default
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
- $ hg clone 2 3
- updating to branch default
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
- $ cat <<EOF > $TESTTMP/debuglocks-pretxn-hook.sh
- > hg debuglocks
- > true
- > EOF
- $ echo '[hooks]' >> 2/.hg/hgrc
- $ echo "pretxnchangegroup.a = sh $TESTTMP/debuglocks-pretxn-hook.sh" >> 2/.hg/hgrc
- $ echo 'changegroup.push = hg push -qf ../1' >> 2/.hg/hgrc
-
- $ echo bar >> 3/foo
- $ hg --cwd 3 ci -m bar
-
- $ hg --cwd 3 push ../2 --config devel.legacy.exchange=bundle1
- pushing to ../2
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files
- lock: user *, process * (*s) (glob)
- wlock: free
-
- $ hg --cwd 1 --config extensions.strip= strip tip -q
- $ hg --cwd 2 --config extensions.strip= strip tip -q
- $ hg --cwd 3 push ../2 # bundle2+
- pushing to ../2
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files
- lock: user *, process * (*s) (glob)
- wlock: user *, process * (*s) (glob)
-
-Test bare push with multiple race checking options
---------------------------------------------------
-
- $ hg init test-bare-push-no-concurrency
- $ hg init test-bare-push-unrelated-concurrency
- $ hg -R test-revflag push -r 0 test-bare-push-no-concurrency --config server.concurrent-push-mode=strict
- pushing to test-bare-push-no-concurrency
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files
- $ hg -R test-revflag push -r 0 test-bare-push-unrelated-concurrency --config server.concurrent-push-mode=check-related
- pushing to test-bare-push-unrelated-concurrency
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files
-
-SEC: check for unsafe ssh url
-
- $ cat >> $HGRCPATH << EOF
- > [ui]
- > ssh = sh -c "read l; read l; read l"
- > EOF
-
- $ hg -R test-revflag push 'ssh://-oProxyCommand=touch${IFS}owned/path'
- pushing to ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
- abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
- [255]
- $ hg -R test-revflag push 'ssh://%2DoProxyCommand=touch${IFS}owned/path'
- pushing to ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
- abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
- [255]
- $ hg -R test-revflag push 'ssh://fakehost|touch${IFS}owned/path'
- pushing to ssh://fakehost%7Ctouch%24%7BIFS%7Downed/path
- abort: no suitable response from remote hg!
- [255]
- $ hg -R test-revflag push 'ssh://fakehost%7Ctouch%20owned/path'
- pushing to ssh://fakehost%7Ctouch%20owned/path
- abort: no suitable response from remote hg!
- [255]
-
- $ [ ! -f owned ] || echo 'you got owned'
diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -87,6 +87,10 @@
except NameError:
pass
+tabsplitter = re.compile(br'(\t+|[^\t]+)')
+wordsplitter = re.compile(br'(\t+| +|[a-zA-Z0-9_\x80-\xff]+|'
+ b'[^ \ta-zA-Z0-9_\x80-\xff])')
+
processlock = threading.Lock()
pygmentspresent = False
@@ -210,6 +214,30 @@
# For Windows support
wifexited = getattr(os, "WIFEXITED", lambda x: False)
+_unified_diff = difflib.unified_diff
+if PYTHON3:
+ import functools
+ _unified_diff = functools.partial(difflib.diff_bytes, difflib.unified_diff)
+
+try:
+ from mercurial import mdiff, ui, color
+
+ # load the ui profile for the user
+ uip = ui.ui.load()
+ try:
+ inlineDiff = uip._config('diff','word-diff')
+ except Exception as e:
+ print(e)
+ inlineDiff = False
+ # mdiff.new_diff may not be present if the mercurial version installed
+ # is not up to date hence this try block will throw exception AttributeError
+ # and if Mercurial itself is not installed in the system then it will throw
+ # an ImportError
+ _diff = mdiff.new_diff
+except (ImportError, AttributeError):
+ print("Falling back to unified_diff")
+ _diff = _unified_diff
+
# Whether to use IPv6
def checksocketfamily(name, port=20058):
"""return true if we can listen on localhost using family=name
@@ -598,15 +626,10 @@
except OSError:
pass
-_unified_diff = difflib.unified_diff
-if PYTHON3:
- import functools
- _unified_diff = functools.partial(difflib.diff_bytes, difflib.unified_diff)
-
def getdiff(expected, output, ref, err):
servefail = False
lines = []
- for line in _unified_diff(expected, output, ref, err):
+ for line in _diff(expected, output, ref, err):
if line.startswith(b'+++') or line.startswith(b'---'):
line = line.replace(b'\\', b'/')
if line.endswith(b' \n'):
@@ -1915,8 +1938,53 @@
servefail, lines = getdiff(expected, got,
test.refpath, test.errpath)
self.stream.write('\n')
- for line in lines:
- line = highlightdiff(line, self.color)
+
+ i = 0
+ import pudb;pu.db
+ while i < len(lines):
+
+ lines = lines[i:]
+ line = lines[0]
+
+ if line.startswith(('- ','+ ')) and inlineDiff:
+ hunklines1=[]
+ for line in lines:
+ if line.startswith(('- ','+ ')):
+ i = i+1
+ hunklines1.append(line)
+ else:
+ break
+ hunktokens=[]
+
+ """yield tokens for a list of lines in a single hunk, with inline colors"""
+ # prepare deleted, and inserted content
+ a = ''
+ b = ''
+ for line in hunklines1:
+ if line[0:1] == '-':
+ a += line[1:]
+ elif line[0:1] == '+':
+ b += line[1:]
+ else:
+ raise error.ProgrammingError('unexpected hunk line: %s' % line)
+ if not a or not b:
+ if not a:
+ line = b
+ if not b :
+ line = a
+ else:
+ i, line = processInlineHunks(i,lines[i:])
+
+
+
+ # treat and print the hunklines separately
+ # get the tokens
+ # call a function
+
+ else:
+ line = highlightdiff(line, self.color)
+ i = i+1
+
if PYTHON3:
self.stream.flush()
self.stream.buffer.write(line)
@@ -3248,6 +3316,108 @@
print("WARNING: Did not find prerequisite tool: %s " %
p.decode("utf-8"))
+def processInlineHunks(i, lines):
+ hunklines1=[]
+ for line in lines:
+ if line.startswith(('- ','+ ')):
+ i = i+1
+ hunklines1.append(line)
+ else:
+ break
+ hunktokens=[]
+
+ """yield tokens for a list of lines in a single hunk, with inline colors"""
+ # prepare deleted, and inserted content
+ a = ''
+ b = ''
+ for line in hunklines1:
+ if line[0:1] == '-':
+ a += line[1:]
+ elif line[0:1] == '+':
+ b += line[1:]
+ else:
+ raise error.ProgrammingError('unexpected hunk line: %s' % line)
+ if not a or not b:
+ return
+ # re-split the content into words
+ al = wordsplitter.findall(a)
+ bl = wordsplitter.findall(b)
+ # re-arrange the words to lines since the diff algorithm is line-based
+ aln = [s if s == '\n' else s + '\n' for s in al]
+ bln = [s if s == '\n' else s + '\n' for s in bl]
+ an = ''.join(aln)
+ bn = ''.join(bln)
+ # run the diff algorithm, prepare atokens and btokens
+ atokens = []
+ btokens = []
+ blocks = mdiff.allblocks(an, bn, lines1=aln, lines2=bln)
+ for (a1, a2, b1, b2), btype in blocks:
+ changed = btype == '!'
+ for token in mdiff.splitnewlines(''.join(al[a1:a2])):
+ atokens.append((changed, token))
+ for token in mdiff.splitnewlines(''.join(bl[b1:b2])):
+ btokens.append((changed, token))
+
+ # yield deleted tokens, then inserted ones
+ for prefix, label, tokens in [('-', 'diff.deleted', atokens),
+ ('+', 'diff.inserted', btokens)]:
+ nextisnewline = True
+ for changed, token in tokens:
+ if nextisnewline:
+ hunktokens.append((prefix, label))
+ nextisnewline = False
+ # special handling line end
+ isendofline = token.endswith('\n')
+ if isendofline:
+ chomp = token[:-1] # chomp
+ if chomp.endswith('\r'):
+ chomp = chomp[:-1]
+ endofline = token[len(chomp):]
+ token = chomp.rstrip() # detect spaces at the end
+ endspaces = chomp[len(token):]
+ # scan tabs
+ for maybetab in tabsplitter.findall(token):
+ if b'\t' == maybetab[0:1]:
+ currentlabel = 'diff.tab'
+ else:
+ if changed:
+ currentlabel = label + '.changed'
+ else:
+ currentlabel = label + '.unchanged'
+ hunktokens.append((maybetab, currentlabel))
+ if isendofline:
+ if endspaces:
+ hunktokens.append(endspaces, 'diff.trailingwhitespace')
+ hunktokens.append((endofline, ''))
+ nextisnewline = True
+
+ # iterate through hunktokens and print
+ final_string = ""
+ uip._colormode = 'auto'
+
+ uip._styles = {
+ 'diff.changed': 'white',
+ 'diff.deleted': 'red',
+ 'diff.deleted.changed': 'red bold underline',
+ 'diff.deleted.unchanged': 'red',
+ 'diff.diffline': 'bold',
+ 'diff.extended': 'cyan bold',
+ 'diff.file_a': 'red bold',
+ 'diff.file_b': 'green bold',
+ 'diff.hunk': 'magenta',
+ 'diff.inserted': 'green',
+ 'diff.inserted.changed': 'green bold underline',
+ 'diff.inserted.unchanged': 'green',
+ 'diff.tab': '',
+ 'diff.trailingwhitespace': 'bold red_background',
+ }
+ for msg, label in hunktokens:
+ txt = color.colorlabel(uip,msg,label)
+ final_string = final_string + " " + txt
+ final_string = final_string.lstrip()
+
+ return i,final_string
+
def aggregateexceptions(path):
exceptioncounts = collections.Counter()
testsbyfailure = collections.defaultdict(set)
To: sangeet259, #hg-reviewers
Cc: pulkit, mercurial-devel
More information about the Mercurial-devel
mailing list