Changeset - ce4b7023a492
[Not reviewed]
beta
0 11 4
Marcin Kuzminski - 13 years ago 2013-05-08 01:19:18
marcin@python-works.com
diff parser: redefined operations stats for changes

- don't loose info about multiple operations like rename + chmod
- new Binary flag when dealing with binary file operations
- fixed diffs after mercurial 2.6 when GIT binary diffs were fixed
- added more tests for multiple operations

- refactored the way diffprocessor returns data. It's
now easier to extract type of operation on binary files
- diffprocessor doesn't append that information into the diff itself
15 files changed with 401 insertions and 127 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/changeset.py
Show inline comments
 
@@ -265,9 +265,8 @@ class ChangesetController(BaseRepoContro
 
                    c.limited_diff = True
 
                for f in _parsed:
 
                    st = f['stats']
 
                    if st[0] != 'b':
 
                        c.lines_added += st[0]
 
                        c.lines_deleted += st[1]
 
                    c.lines_added += st['added']
 
                    c.lines_deleted += st['deleted']
 
                    fid = h.FID(changeset.raw_id, f['filename'])
 
                    diff = diff_processor.as_html(enable_comments=enable_comments,
 
                                                  parsed_lines=[f])
rhodecode/controllers/compare.py
Show inline comments
 
@@ -258,9 +258,9 @@ class CompareController(BaseRepoControll
 
        c.lines_deleted = 0
 
        for f in _parsed:
 
            st = f['stats']
 
            if st[0] != 'b':
 
                c.lines_added += st[0]
 
                c.lines_deleted += st[1]
 
            if not st['binary']:
 
                c.lines_added += st['added']
 
                c.lines_deleted += st['deleted']
 
            fid = h.FID('', f['filename'])
 
            c.files.append([fid, f['operation'], f['filename'], f['stats']])
 
            htmldiff = diff_processor.as_html(enable_comments=False, parsed_lines=[f])
rhodecode/controllers/feed.py
Show inline comments
 
@@ -76,8 +76,8 @@ class FeedController(BaseRepoController)
 
            limited_diff = True
 

	
 
        for st in _parsed:
 
            st.update({'added': st['stats'][0],
 
                       'removed': st['stats'][1]})
 
            st.update({'added': st['stats']['added'],
 
                       'removed': st['stats']['deleted']})
 
            changes.append('\n %(operation)s %(filename)s '
 
                           '(%(added)s lines added, %(removed)s lines removed)'
 
                            % st)
rhodecode/controllers/pullrequests.py
Show inline comments
 
@@ -213,13 +213,10 @@ class PullrequestsController(BaseRepoCon
 

	
 
        c.files = []
 
        c.changes = {}
 
        c.lines_added = 0
 
        c.lines_deleted = 0
 
        for f in _parsed:
 
            st = f['stats']
 
            if st[0] != 'b':
 
                c.lines_added += st[0]
 
                c.lines_deleted += st[1]
 
            c.lines_added += st['added']
 
            c.lines_deleted += st['deleted']
 
            fid = h.FID('', f['filename'])
 
            c.files.append([fid, f['operation'], f['filename'], f['stats']])
 
            htmldiff = diff_processor.as_html(enable_comments=enable_comments,
rhodecode/lib/diffs.py
Show inline comments
 
@@ -128,6 +128,7 @@ DEL_FILENODE = 2
 
MOD_FILENODE = 3
 
RENAMED_FILENODE = 4
 
CHMOD_FILENODE = 5
 
BIN_FILENODE = 6
 

	
 

	
 
class DiffLimitExceeded(Exception):
 
@@ -166,6 +167,7 @@ class DiffProcessor(object):
 
        (?:^deleted[ ]file[ ]mode[ ](?P<deleted_file_mode>.+)(?:\n|$))?
 
        (?:^index[ ](?P<a_blob_id>[0-9A-Fa-f]+)
 
            \.\.(?P<b_blob_id>[0-9A-Fa-f]+)[ ]?(?P<b_mode>.+)?(?:\n|$))?
 
        (?:^(?P<bin_patch>GIT[ ]binary[ ]patch)(?:\n|$))?
 
        (?:^---[ ](a/(?P<a_file>.+)|/dev/null)(?:\n|$))?
 
        (?:^\+\+\+[ ](b/(?P<b_file>.+)|/dev/null)(?:\n|$))?
 
    """, re.VERBOSE | re.MULTILINE)
 
@@ -181,6 +183,7 @@ class DiffProcessor(object):
 
        (?:^deleted[ ]file[ ]mode[ ](?P<deleted_file_mode>.+)(?:\n|$))?
 
        (?:^index[ ](?P<a_blob_id>[0-9A-Fa-f]+)
 
            \.\.(?P<b_blob_id>[0-9A-Fa-f]+)[ ]?(?P<b_mode>.+)?(?:\n|$))?
 
        (?:^(?P<bin_patch>GIT[ ]binary[ ]patch)(?:\n|$))?
 
        (?:^---[ ](a/(?P<a_file>.+)|/dev/null)(?:\n|$))?
 
        (?:^\+\+\+[ ](b/(?P<b_file>.+)|/dev/null)(?:\n|$))?
 
    """, re.VERBOSE | re.MULTILINE)
 
@@ -357,62 +360,84 @@ class DiffProcessor(object):
 
            head, diff = self._get_header(raw_diff)
 

	
 
            op = None
 
            stats = None
 
            msgs = []
 
            stats = {
 
                'added': 0,
 
                'deleted': 0,
 
                'binary': False,
 
                'ops': {},
 
            }
 

	
 
            if head['deleted_file_mode']:
 
                op = 'D'
 
                stats = ['b', DEL_FILENODE]
 
                msgs.append('deleted file')
 
                stats['binary'] = True
 
                stats['ops'][DEL_FILENODE] = 'deleted file'
 

	
 
            elif head['new_file_mode']:
 
                op = 'A'
 
                stats = ['b', NEW_FILENODE]
 
                msgs.append('new file %s' % head['new_file_mode'])
 
            else:
 
                stats['binary'] = True
 
                stats['ops'][NEW_FILENODE] = 'new file %s' % head['new_file_mode']
 
            else:  # modify operation, can be cp, rename, chmod
 
                # CHMOD
 
                if head['new_mode'] and head['old_mode']:
 
                    op = 'M'
 
                    stats = ['b', CHMOD_FILENODE]
 
                    msgs.append('modified file chmod %s => %s'
 
                                  % (head['old_mode'], head['new_mode']))
 
                    stats['binary'] = True
 
                    stats['ops'][CHMOD_FILENODE] = ('modified file chmod %s => %s'
 
                                        % (head['old_mode'], head['new_mode']))
 
                # RENAME
 
                if (head['rename_from'] and head['rename_to']
 
                      and head['rename_from'] != head['rename_to']):
 
                    op = 'M'
 
                    stats = ['b', RENAMED_FILENODE] # might overwrite CHMOD_FILENODE
 
                    msgs.append('file renamed from %s to %s'
 
                                  % (head['rename_from'], head['rename_to']))
 
                if op is None: # fall back: detect missed old style add or remove
 
                    stats['binary'] = True
 
                    stats['ops'][RENAMED_FILENODE] = ('file renamed from %s to %s'
 
                                    % (head['rename_from'], head['rename_to']))
 

	
 
                # FALL BACK: detect missed old style add or remove
 
                if op is None:
 
                    if not head['a_file'] and head['b_file']:
 
                        op = 'A'
 
                        stats = ['b', NEW_FILENODE]
 
                        msgs.append('new file')
 
                        stats['binary'] = True
 
                        stats['ops'][NEW_FILENODE] = 'new file'
 

	
 
                    elif head['a_file'] and not head['b_file']:
 
                        op = 'D'
 
                        stats = ['b', DEL_FILENODE]
 
                        msgs.append('deleted file')
 
                        stats['binary'] = True
 
                        stats['ops'][DEL_FILENODE] = 'deleted file'
 

	
 
                # it's not ADD not DELETE
 
                if op is None:
 
                    op = 'M'
 
                    stats = ['b', MOD_FILENODE]
 
                    stats['binary'] = True
 
                    stats['ops'][MOD_FILENODE] = 'modified file'
 

	
 
            if head['a_file'] or head['b_file']: # a real diff
 
            # a real non-binary diff
 
            if head['a_file'] or head['b_file']:
 
                try:
 
                    chunks, stats = self._parse_lines(diff)
 
                    chunks, _stats = self._parse_lines(diff)
 
                    stats['binary'] = False
 
                    stats['added'] = _stats[0]
 
                    stats['deleted'] = _stats[1]
 
                    # explicit mark that it's a modified file
 
                    if op == 'M':
 
                        stats['ops'][MOD_FILENODE] = 'modified file'
 

	
 
                except DiffLimitExceeded:
 
                    diff_container = lambda _diff: LimitedDiffContainer(
 
                                                self.diff_limit,
 
                                                self.cur_diff_size,
 
                                                _diff)
 
                    diff_container = lambda _diff: \
 
                        LimitedDiffContainer(self.diff_limit,
 
                                            self.cur_diff_size, _diff)
 
                    break
 
            else: # GIT binary patch (or empty diff)
 
            else:  # GIT binary patch (or empty diff)
 
                # GIT Binary patch
 
                if head['bin_patch']:
 
                    stats['ops'][BIN_FILENODE] = 'binary diff not shown'
 
                chunks = []
 
                msgs.append('binary diff not shown') # or no diff because it was a rename or chmod or add/remove of empty file
 

	
 
            if msgs:
 
                chunks.insert(0, [{
 
                    'old_lineno': '',
 
                    'new_lineno': '',
 
                    'action':     'binary',
 
                    'line':       msg,
 
                    } for msg in msgs])
 
            chunks.insert(0, [{
 
                'old_lineno': '',
 
                'new_lineno': '',
 
                'action':     'context',
 
                'line':       msg,
 
                } for _op, msg in stats['ops'].iteritems()
 
                  if _op not in [MOD_FILENODE]])
 

	
 
            _files.append({
 
                'filename':         head['b_path'],
rhodecode/lib/helpers.py
Show inline comments
 
@@ -1078,6 +1078,9 @@ def fancy_file_stats(stats):
 

	
 
    :param stats: two element list of added/deleted lines of code
 
    """
 
    from rhodecode.lib.diffs import NEW_FILENODE, DEL_FILENODE, \
 
        MOD_FILENODE, RENAMED_FILENODE, CHMOD_FILENODE, BIN_FILENODE
 

	
 
    def cgen(l_type, a_v, d_v):
 
        mapping = {'tr': 'top-right-rounded-corner-mid',
 
                   'tl': 'top-left-rounded-corner-mid',
 
@@ -1098,16 +1101,41 @@ def fancy_file_stats(stats):
 
        if l_type == 'd' and not a_v:
 
            return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
 

	
 
    a, d = stats[0], stats[1]
 
    a, d = stats['added'], stats['deleted']
 
    width = 100
 

	
 
    if a == 'b':
 
    if stats['binary']:
 
        #binary mode
 
        b_d = '<div class="bin%s %s" style="width:100%%">%s</div>' % (d, cgen('a', a_v='', d_v=0), 'bin')
 
        b_a = '<div class="bin1" style="width:0%%">%s</div>' % ('bin')
 
        lbl = ''
 
        bin_op = 1
 

	
 
        if BIN_FILENODE in stats['ops']:
 
            lbl = 'bin+'
 

	
 
        if NEW_FILENODE in stats['ops']:
 
            lbl += _('new file')
 
            bin_op = NEW_FILENODE
 
        elif MOD_FILENODE in stats['ops']:
 
            lbl += _('mod')
 
            bin_op = MOD_FILENODE
 
        elif DEL_FILENODE in stats['ops']:
 
            lbl += _('del')
 
            bin_op = DEL_FILENODE
 
        elif RENAMED_FILENODE in stats['ops']:
 
            lbl += _('rename')
 
            bin_op = RENAMED_FILENODE
 

	
 
        #chmod can go with other operations
 
        if CHMOD_FILENODE in stats['ops']:
 
            _org_lbl = _('chmod')
 
            lbl += _org_lbl if lbl.endswith('+') else '+%s' % _org_lbl
 

	
 
        #import ipdb;ipdb.set_trace()
 
        b_d = '<div class="bin bin%s %s" style="width:100%%">%s</div>' % (bin_op, cgen('a', a_v='', d_v=0), lbl)
 
        b_a = '<div class="bin bin1" style="width:0%%"></div>'
 
        return literal('<div style="width:%spx">%s%s</div>' % (width, b_a, b_d))
 

	
 
    t = stats[0] + stats[1]
 
    t = stats['added'] + stats['deleted']
 
    unit = float(width) / (t or 1)
 

	
 
    # needs > 9% of width to be visible or 0 to be hidden
rhodecode/public/css/style.css
Show inline comments
 
@@ -2404,42 +2404,49 @@ h3.files_location {
 
    font-size: 9px;
 
    padding: 2px 0px 2px 0px;
 
}
 
/*new binary*/
 
.cs_files .changes .bin1 {
 
/*new binary
 
NEW_FILENODE = 1
 
DEL_FILENODE = 2
 
MOD_FILENODE = 3
 
RENAMED_FILENODE = 4
 
CHMOD_FILENODE = 5
 
BIN_FILENODE = 6
 
*/
 
.cs_files .changes .bin {
 
    background-color: #BBFFBB;
 
    float: left;
 
    text-align: center;
 
    font-size: 9px;
 
    padding: 2px 0px 2px 0px;
 
}
 
.cs_files .changes .bin.bin1 {
 
    background-color: #BBFFBB;
 
}
 

	
 
/*deleted binary*/
 
.cs_files .changes .bin2 {
 
.cs_files .changes .bin.bin2 {
 
    background-color: #FF8888;
 
    float: left;
 
    text-align: center;
 
    font-size: 9px;
 
    padding: 2px 0px 2px 0px;
 
}
 

	
 
/*mod binary*/
 
.cs_files .changes .bin3 {
 
.cs_files .changes .bin.bin3 {
 
    background-color: #DDDDDD;
 
    float: left;
 
    text-align: center;
 
    font-size: 9px;
 
    padding: 2px 0px 2px 0px;
 
}
 

	
 
/*rename file*/
 
.cs_files .changes .bin4 {
 
.cs_files .changes .bin.bin4 {
 
    background-color: #6D99FF;
 
}
 

	
 
/*rename file*/
 
.cs_files .changes .bin.bin4 {
 
    background-color: #6D99FF;
 
    float: left;
 
    text-align: center;
 
    font-size: 9px;
 
    padding: 2px 0px 2px 0px;
 
}
 

	
 
}
 

	
 
/*chmod file*/
 
.cs_files .changes .bin.bin5 {
 
    background-color: #6D99FF;
 
}
 

	
 
.cs_files .cs_added, .cs_files .cs_A {
 
    background: url("../images/icons/page_white_add.png") no-repeat scroll
rhodecode/templates/changeset/diff_block.html
Show inline comments
 
@@ -9,7 +9,6 @@
 
</div>
 
<div class="diff-container" id="${'diff-container-%s' % (id(change))}">
 
%for FID,(cs1, cs2, change, path, diff, stats) in change.iteritems():
 
    ##%if op !='removed':
 
    <div id="${FID}_target" style="clear:both;margin-top:25px"></div>
 
    <div id="${FID}" class="diffblock  margined comm">
 
        <div class="code-header">
 
@@ -38,7 +37,6 @@
 
            ${diff|n}
 
        </div>
 
    </div>
 
    ##%endif
 
%endfor
 
</div>
 
</%def>
rhodecode/tests/fixtures/hg_diff_binary_and_normal.diff
Show inline comments
 
@@ -9,7 +9,11 @@ y)y@U((_~Lrb!=|_@`K?vV_&A58+!u-Gs6x+MGjB
 

	
 
diff --git a/img/baseline-20px.png b/img/baseline-20px.png
 
deleted file mode 100644
 
Binary file img/baseline-20px.png has changed
 
index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000
 
GIT binary patch
 
literal 0
 
Hc$@<O00001
 

	
 
diff --git a/index.html b/index.html
 
--- a/index.html
 
+++ b/index.html
rhodecode/tests/fixtures/hg_diff_chmod_and_mod_single_binary_file.diff
Show inline comments
 
new file 100644
 
diff --git a/gravatar.png b/gravatar.png
 
old mode 100644
 
new mode 100755
 
index 54d2d129e3372c45a4c68a742e269864222e99ae..0c1d65410bd51fdff935443e01931c9fc3ad7def
 
GIT binary patch
 
literal 740
 
zc%17D@N?(olHy`uVBq!ia0vp^dx3Z#2NRHduQ>B0kYX$ja(7}_cTVOdki%Kv5n0T@
 
zz%2~Ij105pNB{-dOFVsD*>AH+2@7*F&3eGWz`&H|>EaktaqI0JMZd!V5(hqpU(%ki
 
zz<{N_Dc~^g1GeA{8S#b#jBU<`Ij0FINT{SO2`=WI*Kku%Kte?~QvUtk`~FuatbIH`
 
zU*0#<bY2fr$(Coz4(2b|?k<qNz`M&4#A?WcvPzmkEJg29#pjiUe<s|iw%c!Ml>foD
 
zHLr#RtfPb(q61ZL^D3dLy27sS9LG1ks-ApS8e$A1NIi%J(b=2_we?fTsn6Zh<#UVP
 
z|9tiF%$|eaMRt7@#I6)<9go)1-`(@)=Q(p!@3vNKDKmRt(o@-7dHLx1lNY~Ad}g~_
 
za{b)1``zCC$!DbBm~WE-irmOC$k!;|zwzb_^B2daEtWo!yMN=;86Y!nbQtDu5Wn34
 
zbmZh?b(0@$%sb%=43(hD^~>9*yZ+6yNtdtp|J$sq{^jrc-CO$Jn%~HOWByJ0bK9TY
 
zg@4_kydS*R^JDe{4Z08FKRNbQ`g%Ud?r+k+d3UblwmiT6sL83<_jKRAJ-Pr-V6<tp
 
z?epIfY2R5iFZ#Ccl<T?EX78;p`&F5H??E-!-5(q%k>Y5MY!uto=R2=&d?)y?yZLYL
 
zJ^SCEe$Bh{bKS3dDW9<fAX0p_*<5X%lMalj*{B8|p0JPMtzFP9%Uvy?WXj;_>gTe~
 
RDWNH`I3+QqIFSoR0|1y<SJMCh
 
\ No newline at end of file
rhodecode/tests/fixtures/hg_diff_del_single_binary_file.diff
Show inline comments
 
diff --git a/US Warszawa.jpg b/US Warszawa.jpg
 
deleted file mode 100755
 
Binary file US Warszawa.jpg has changed
 
index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000
 
GIT binary patch
 
literal 0
 
Hc$@<O00001
rhodecode/tests/fixtures/hg_diff_mod_file_and_rename.diff
Show inline comments
 
new file 100644
 
diff --git a/README b/README.rst
 
rename from README
 
rename to README.rst
 
--- a/README
 
+++ b/README.rst
 
@@ -1,1 +1,4 @@
 
 readme2
 
+line 1
 
+ line2
 
+
 
\ No newline at end of file
rhodecode/tests/fixtures/hg_diff_mod_single_file_and_rename_and_chmod.diff
Show inline comments
 
new file 100644
 
diff --git a/README.rst b/README
 
old mode 100755
 
new mode 100644
 
rename from README.rst
 
rename to README
 
--- a/README.rst
 
+++ b/README
 
@@ -1,4 +1,7 @@
 
 readme2
 
 line 1
 
  line2
 

	
 
+line 1
 
+ line2
 
+
 
\ No newline at end of file
rhodecode/tests/fixtures/hg_diff_rename_and_chmod_file.diff
Show inline comments
 
new file 100644
 
diff --git a/README.rst b/README
 
old mode 100644
 
new mode 100755
 
rename from README.rst
 
rename to README
 
\ No newline at end of file
rhodecode/tests/models/test_diff_parsers.py
Show inline comments
 
@@ -3,84 +3,249 @@ import os
 
import unittest
 
from rhodecode.tests import *
 
from rhodecode.lib.diffs import DiffProcessor, NEW_FILENODE, DEL_FILENODE, \
 
    MOD_FILENODE, RENAMED_FILENODE, CHMOD_FILENODE
 
    MOD_FILENODE, RENAMED_FILENODE, CHMOD_FILENODE, BIN_FILENODE
 

	
 
dn = os.path.dirname
 
FIXTURES = os.path.join(dn(dn(os.path.abspath(__file__))), 'fixtures')
 

	
 
DIFF_FIXTURES = {
 
    'hg_diff_add_single_binary_file.diff': [
 
        (u'US Warszawa.jpg', 'A', ['b', NEW_FILENODE]),
 
        ('US Warszawa.jpg', 'A',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {NEW_FILENODE: 'new file 100755',
 
                  BIN_FILENODE: 'binary diff not shown'}}),
 
    ],
 
    'hg_diff_mod_single_binary_file.diff': [
 
        (u'US Warszawa.jpg', 'M', ['b', MOD_FILENODE]),
 
        ('US Warszawa.jpg', 'M',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {MOD_FILENODE: 'modified file',
 
                  BIN_FILENODE: 'binary diff not shown'}}),
 
    ],
 

	
 
    'hg_diff_mod_single_file_and_rename_and_chmod.diff': [
 
        ('README', 'M',
 
         {'added': 3,
 
          'deleted': 0,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file',
 
                  RENAMED_FILENODE: 'file renamed from README.rst to README',
 
                  CHMOD_FILENODE: 'modified file chmod 100755 => 100644'}}),
 
    ],
 
    'hg_diff_rename_and_chmod_file.diff': [
 
        ('README', 'M',
 
         {'added': 3,
 
          'deleted': 0,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file',
 
                  BIN_FILENODE: 'binary diff not shown'}}),
 
    ],
 
    'hg_diff_del_single_binary_file.diff': [
 
        (u'US Warszawa.jpg', 'D', ['b', DEL_FILENODE]),
 
        ('US Warszawa.jpg', 'D',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {DEL_FILENODE: 'deleted file',
 
                  BIN_FILENODE: 'binary diff not shown'}}),
 
    ],
 
    'hg_diff_chmod_and_mod_single_binary_file.diff': [
 
        ('gravatar.png', 'M',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {CHMOD_FILENODE: 'modified file chmod 100644 => 100755',
 
                  BIN_FILENODE: 'binary diff not shown'}}),
 
    ],
 
    'hg_diff_chmod.diff': [
 
        ('file', 'M',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {CHMOD_FILENODE: 'modified file chmod 100755 => 100644'}}),
 
    ],
 
    'hg_diff_rename_file.diff': [
 
        ('file_renamed', 'M',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {RENAMED_FILENODE: 'file renamed from file to file_renamed'}}),
 
    ],
 
    'hg_diff_rename_and_chmod_file.diff': [
 
        ('README', 'M',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {CHMOD_FILENODE: 'modified file chmod 100644 => 100755',
 
                  RENAMED_FILENODE: 'file renamed from README.rst to README'}}),
 
    ],
 
    'hg_diff_binary_and_normal.diff': [
 
        (u'img/baseline-10px.png', 'A', ['b', NEW_FILENODE]),
 
        (u'js/jquery/hashgrid.js', 'A', [340, 0]),
 
        (u'index.html',            'M', [3, 2]),
 
        (u'less/docs.less',        'M', [34, 0]),
 
        (u'less/scaffolding.less', 'M', [1, 3]),
 
        (u'readme.markdown',       'M', [1, 10]),
 
        (u'img/baseline-20px.png', 'D', ['b', DEL_FILENODE]),
 
        (u'js/global.js',          'D', [0, 75])
 
    ],
 
    'hg_diff_chmod.diff': [
 
        (u'file', 'M', ['b', CHMOD_FILENODE]),
 
    ],
 
    'hg_diff_rename_file.diff': [
 
        (u'file_renamed', 'M', ['b', RENAMED_FILENODE]),
 
        ('img/baseline-10px.png', 'A',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {NEW_FILENODE: 'new file 100644',
 
                  BIN_FILENODE: 'binary diff not shown'}}),
 
        ('js/jquery/hashgrid.js', 'A',
 
         {'added': 340,
 
          'deleted': 0,
 
          'binary': False,
 
          'ops': {NEW_FILENODE: 'new file 100755'}}),
 
        ('index.html', 'M',
 
         {'added': 3,
 
          'deleted': 2,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('less/docs.less', 'M',
 
         {'added': 34,
 
          'deleted': 0,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('less/scaffolding.less', 'M',
 
         {'added': 1,
 
          'deleted': 3,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('readme.markdown', 'M',
 
         {'added': 1,
 
          'deleted': 10,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('img/baseline-20px.png', 'D',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {DEL_FILENODE: 'deleted file',
 
                  BIN_FILENODE: 'binary diff not shown'}}),
 
        ('js/global.js', 'D',
 
         {'added': 0,
 
          'deleted': 75,
 
          'binary': False,
 
          'ops': {DEL_FILENODE: 'deleted file'}})
 
    ],
 
    'git_diff_chmod.diff': [
 
        (u'work-horus.xls', 'M', ['b', CHMOD_FILENODE]),
 
        ('work-horus.xls', 'M',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {CHMOD_FILENODE: 'modified file chmod 100644 => 100755'}})
 
    ],
 
    'git_diff_rename_file.diff': [
 
        (u'file.xls', 'M', ['b', RENAMED_FILENODE]),
 
        ('file.xls', 'M',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {RENAMED_FILENODE: 'file renamed from work-horus.xls to file.xls'}})
 
    ],
 
    'git_diff_mod_single_binary_file.diff': [
 
        ('US Warszawa.jpg', 'M', ['b', MOD_FILENODE])
 

	
 
        ('US Warszawa.jpg', 'M',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {MOD_FILENODE: 'modified file',
 
                  BIN_FILENODE: 'binary diff not shown'}})
 
    ],
 
    'git_diff_binary_and_normal.diff': [
 
        (u'img/baseline-10px.png', 'A', ['b', NEW_FILENODE]),
 
        (u'js/jquery/hashgrid.js', 'A', [340, 0]),
 
        (u'index.html',            'M', [3, 2]),
 
        (u'less/docs.less',        'M', [34, 0]),
 
        (u'less/scaffolding.less', 'M', [1, 3]),
 
        (u'readme.markdown',       'M', [1, 10]),
 
        (u'img/baseline-20px.png', 'D', ['b', DEL_FILENODE]),
 
        (u'js/global.js',          'D', [0, 75])
 
        ('img/baseline-10px.png', 'A',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {NEW_FILENODE: 'new file 100644',
 
                  BIN_FILENODE: 'binary diff not shown'}}),
 
        ('js/jquery/hashgrid.js', 'A',
 
         {'added': 340,
 
          'deleted': 0,
 
          'binary': False,
 
          'ops': {NEW_FILENODE: 'new file 100755'}}),
 
        ('index.html', 'M',
 
         {'added': 3,
 
          'deleted': 2,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('less/docs.less', 'M',
 
         {'added': 34,
 
          'deleted': 0,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('less/scaffolding.less', 'M',
 
         {'added': 1,
 
          'deleted': 3,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('readme.markdown', 'M',
 
         {'added': 1,
 
          'deleted': 10,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('img/baseline-20px.png', 'D',
 
         {'added': 0,
 
          'deleted': 0,
 
          'binary': True,
 
          'ops': {DEL_FILENODE: 'deleted file',
 
                  BIN_FILENODE: 'binary diff not shown'}}),
 
        ('js/global.js', 'D',
 
         {'added': 0,
 
          'deleted': 75,
 
          'binary': False,
 
          'ops': {DEL_FILENODE: 'deleted file'}}),
 
    ],
 
    'diff_with_diff_data.diff': [
 
        (u'vcs/backends/base.py', 'M', [18, 2]),
 
        (u'vcs/backends/git/repository.py', 'M', [46, 15]),
 
        (u'vcs/backends/hg.py', 'M', [22, 3]),
 
        (u'vcs/tests/test_git.py', 'M', [5, 5]),
 
        (u'vcs/tests/test_repository.py', 'M', [174, 2])
 
        ('vcs/backends/base.py', 'M',
 
         {'added': 18,
 
          'deleted': 2,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('vcs/backends/git/repository.py', 'M',
 
         {'added': 46,
 
          'deleted': 15,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('vcs/backends/hg.py', 'M',
 
         {'added': 22,
 
          'deleted': 3,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('vcs/tests/test_git.py', 'M',
 
         {'added': 5,
 
          'deleted': 5,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
        ('vcs/tests/test_repository.py', 'M',
 
         {'added': 174,
 
          'deleted': 2,
 
          'binary': False,
 
          'ops': {MOD_FILENODE: 'modified file'}}),
 
    ],
 
#    'large_diff.diff': [
 
#
 
#    ],
 

	
 
#     'large_diff.diff': [
 
#         ('.hgignore', 'A', {'deleted': 0, 'binary': False, 'added': 3, 'ops': {1: 'new file 100644'}}),
 
#         ('MANIFEST.in', 'A', {'deleted': 0, 'binary': False, 'added': 3, 'ops': {1: 'new file 100644'}}),
 
#         ('README.txt', 'A', {'deleted': 0, 'binary': False, 'added': 19, 'ops': {1: 'new file 100644'}}),
 
#         ('development.ini', 'A', {'deleted': 0, 'binary': False, 'added': 116, 'ops': {1: 'new file 100644'}}),
 
#         ('docs/index.txt', 'A', {'deleted': 0, 'binary': False, 'added': 19, 'ops': {1: 'new file 100644'}}),
 
#         ('ez_setup.py', 'A', {'deleted': 0, 'binary': False, 'added': 276, 'ops': {1: 'new file 100644'}}),
 
#         ('hgapp.py', 'A', {'deleted': 0, 'binary': False, 'added': 26, 'ops': {1: 'new file 100644'}}),
 
#         ('hgwebdir.config', 'A', {'deleted': 0, 'binary': False, 'added': 21, 'ops': {1: 'new file 100644'}}),
 
#         ('pylons_app.egg-info/PKG-INFO', 'A', {'deleted': 0, 'binary': False, 'added': 10, 'ops': {1: 'new file 100644'}}),
 
#         ('pylons_app.egg-info/SOURCES.txt', 'A', {'deleted': 0, 'binary': False, 'added': 33, 'ops': {1: 'new file 100644'}}),
 
#         ('pylons_app.egg-info/dependency_links.txt', 'A', {'deleted': 0, 'binary': False, 'added': 1, 'ops': {1: 'new file 100644'}}),
 
#         #TODO:
 
#     ],
 

	
 
}
 

	
 

	
 
def _diff_checker(fixture):
 
    with open(os.path.join(FIXTURES, fixture)) as f:
 
        diff = f.read()
 
class DiffLibTest(unittest.TestCase):
 

	
 
    @parameterized.expand([(x,) for x in DIFF_FIXTURES])
 
    def test_diff(self, diff_fixture):
 

	
 
    diff_proc = DiffProcessor(diff)
 
    diff_proc_d = diff_proc.prepare()
 
    data = [(x['filename'], x['operation'], x['stats']) for x in diff_proc_d]
 
    expected_data = DIFF_FIXTURES[fixture]
 
        with open(os.path.join(FIXTURES, diff_fixture)) as f:
 
            diff = f.read()
 

	
 
    assert expected_data == data
 

	
 

	
 
def test_parse_diff():
 
    for fixture in DIFF_FIXTURES:
 
        yield _diff_checker, fixture
 
        diff_proc = DiffProcessor(diff)
 
        diff_proc_d = diff_proc.prepare()
 
        data = [(x['filename'], x['operation'], x['stats']) for x in diff_proc_d]
 
        expected_data = DIFF_FIXTURES[diff_fixture]
 
        self.assertListEqual(expected_data, data)
0 comments (0 inline, 0 general)