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