D5514: test: change test's diff generation to use mdiff for nicer output
sangeet259 (Sangeet Kumar Mishra)
phabricator at mercurial-scm.org
Mon Jan 7 14:54:25 UTC 2019
sangeet259 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.
REVISION SUMMARY
The current diff being used by tests upon failing is not very good. Sometimes there is a lot of redundancy.
To see for yourself, follow these steps:
1. Download this bundle : http://bit.ly/2DuJjsS
$ hg clone https://www.mercurial-scm.org/hg
$ cd hg/
$ hg unbundle af8efb83e1d6.hg
$ hg up a1e70c1dbec0^
$ hg revert --all --rev a1e70c1dbec0
$ hg revert -i tests/test-bookmarks-pushpull.t # revert only the last three hunks (press 'n' for the first 8, and 'y' for the last three)
$ cd tests
$ hg diff --rev a1e70c1dbec0 # nice output from Mercurial
$ ./run-test.py test-bookmarks-pushpull.t # poor output from the test runner
If you couldn't follow those steps, you can simply check the diffs here:
- test's diff: https://pastebin.com/Z4LRg4vx
- diff used by hg diff: https://pastebin.com/qanQEsiA
Tests uses _unified_diff based on difflib.py . The output isn't great!
Mercurial's diff uses mdiff which gives better diffs.
This patch uses mdiff's unidiff function to generate the diff for the failed tests.
REPOSITORY
rHG Mercurial
REVISION DETAIL
https://phab.mercurial-scm.org/D5514
AFFECTED FILES
mercurial/mdiff.py
tests/run-tests.py
CHANGE DETAILS
diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -48,8 +48,10 @@
import argparse
import collections
import difflib
+import datetime
import distutils.version as version
import errno
+import itertools
import json
import multiprocessing
import os
@@ -67,6 +69,7 @@
import unittest
import uuid
import xml.dom.minidom as minidom
+from mercurial import mdiff, patch
try:
import Queue as queue
@@ -603,10 +606,16 @@
import functools
_unified_diff = functools.partial(difflib.diff_bytes, difflib.unified_diff)
+try:
+ _diff = mdiff.new_diff
+except Exception:
+ print("Falling back to unified_diff")
+ _diff = _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'):
diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -7,6 +7,8 @@
from __future__ import absolute_import
+import datetime
+import itertools
import re
import struct
import zlib
@@ -525,3 +527,33 @@
def replacediffheader(oldlen, newlen):
return struct.pack(">lll", 0, oldlen, newlen)
+
+def prepare_mdiff(expected, output):
+ """Prepare the inputs for the mdiff.unidiff function"""
+ date1 = datetime.datetime.now().strftime("%a %b %d %y %H:%M:%S %Y %z")
+ date2 = date1
+ # join all the different elements into a single string
+ # to regenerate that file
+ exp = "".join(expected)
+ out = "".join(output)
+ opts = diffopts(noprefix=True)
+ return exp, date1, out, date2, opts
+
+def process_mdiff(uheaders, hunks):
+ """Process the output of mdiff into a list of lines,
+ to be used by getdiff"""
+ # the hunklines are in the hunks generator
+ # get the hunklines from the (hunkrange,hunklines) tuple
+ hunklines = [x[1] for x in hunks]
+ # extract and insert the headers at the beginnng of the hunklines list
+ headers = [uheaders[0].split("\t")[0]+"\n", uheaders[1].split("\t")[0]+"\n"]
+ hunklines.insert(0, headers)
+ difflines = itertools.chain.from_iterable(hunklines)
+ return difflines
+
+def new_diff(expected, output, ref, err):
+ exp, date1, out, date2, opts = prepare_mdiff(expected, output)
+ uheaders, hunks = unidiff(exp, date1, out, date2,
+ ref, err, binary=False, opts=opts)
+ difflines = process_mdiff(uheaders, hunks)
+ return difflines
To: sangeet259, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list