Преглед на файлове

Better patch parser; support svn log --diff

Matthew Wang преди 12 години
родител
ревизия
20a8acacf6
променени са 10 файла, в които са добавени 306 реда и са изтрити 107 реда
  1. 1
    2
      Makefile
  2. 1
    4
      cdiff
  3. 71
    99
      cdiff.py
  4. 3
    1
      tests/README
  5. 2
    1
      tests/regression.sh
  6. 53
    0
      tests/svn-log/in.diff
  7. 52
    0
      tests/svn-log/out.normal
  8. 50
    0
      tests/svn-log/out.side-by-side
  9. 50
    0
      tests/svn-log/out.w70
  10. 23
    0
      tests/test_cdiff.py

+ 1
- 2
Makefile Целия файл

5
 .PHONY: dogfood test clean build dist-test dist
5
 .PHONY: dogfood test clean build dist-test dist
6
 
6
 
7
 dogfood:
7
 dogfood:
8
-	./cdiff.py -s
9
-	git diff | ./cdiff.py
8
+	./cdiff.py
10
 	git diff | ./cdiff.py -s
9
 	git diff | ./cdiff.py -s
11
 
10
 
12
 test:
11
 test:

+ 1
- 4
cdiff Целия файл

4
 import sys
4
 import sys
5
 import cdiff
5
 import cdiff
6
 
6
 
7
-try:
8
-    sys.exit(cdiff.main())
9
-except:
10
-    sys.exit(1)
7
+sys.exit(cdiff.main())
11
 
8
 
12
 # vim:set et sts=4 sw=4 tw=80:
9
 # vim:set et sts=4 sw=4 tw=80:

+ 71
- 99
cdiff.py Целия файл

68
 
68
 
69
 class Hunk(object):
69
 class Hunk(object):
70
 
70
 
71
-    def __init__(self, hunk_header, old_addr, new_addr):
72
-        self._hunk_header = hunk_header
71
+    def __init__(self, hunk_headers, hunk_meta, old_addr, new_addr):
72
+        self._hunk_headers = hunk_headers
73
+        self._hunk_meta = hunk_meta
73
         self._old_addr = old_addr   # tuple (start, offset)
74
         self._old_addr = old_addr   # tuple (start, offset)
74
         self._new_addr = new_addr   # tuple (start, offset)
75
         self._new_addr = new_addr   # tuple (start, offset)
75
         self._hunk_list = []        # list of tuple (attr, line)
76
         self._hunk_list = []        # list of tuple (attr, line)
76
 
77
 
77
-    def get_header(self):
78
-        return self._hunk_header
78
+    def get_hunk_headers(self):
79
+        return self._hunk_headers
80
+
81
+    def get_hunk_meta(self):
82
+        return self._hunk_meta
79
 
83
 
80
     def get_old_addr(self):
84
     def get_old_addr(self):
81
         return self._old_addr
85
         return self._old_addr
131
         self._new_path = new_path
135
         self._new_path = new_path
132
         self._hunks = hunks
136
         self._hunks = hunks
133
 
137
 
134
-    # Follow detector and the parse_hunk_header() are suppose to be overwritten
135
-    # by derived class
138
+    # Follow detector and the parse_hunk_meta() are suppose to be overwritten
139
+    # by derived class.  No is_header() anymore, all non-recognized lines are
140
+    # considered as headers
136
     #
141
     #
137
     def is_old_path(self, line):
142
     def is_old_path(self, line):
138
         return False
143
         return False
140
     def is_new_path(self, line):
145
     def is_new_path(self, line):
141
         return False
146
         return False
142
 
147
 
143
-    def is_hunk_header(self, line):
148
+    def is_hunk_meta(self, line):
144
         return False
149
         return False
145
 
150
 
146
-    def parse_hunk_header(self, line):
151
+    def parse_hunk_meta(self, line):
147
         """Returns a 2-eliment tuple, each of them is a tuple in form of (start,
152
         """Returns a 2-eliment tuple, each of them is a tuple in form of (start,
148
         offset)"""
153
         offset)"""
149
         return False
154
         return False
160
     def is_eof(self, line):
165
     def is_eof(self, line):
161
         return False
166
         return False
162
 
167
 
163
-    def is_header(self, line):
164
-        return False
165
-
166
     def markup_traditional(self):
168
     def markup_traditional(self):
167
         """Returns a generator"""
169
         """Returns a generator"""
168
         for line in self._headers:
170
         for line in self._headers:
172
         yield self._markup_new_path(self._new_path)
174
         yield self._markup_new_path(self._new_path)
173
 
175
 
174
         for hunk in self._hunks:
176
         for hunk in self._hunks:
175
-            yield self._markup_hunk_header(hunk.get_header())
177
+            for hunk_header in hunk.get_hunk_headers():
178
+                yield self._markup_hunk_header(hunk_header)
179
+            yield self._markup_hunk_meta(hunk.get_hunk_meta())
176
             for old, new, changed in hunk.mdiff():
180
             for old, new, changed in hunk.mdiff():
177
                 if changed:
181
                 if changed:
178
                     if not old[0]:
182
                     if not old[0]:
253
 
257
 
254
         # yield hunks
258
         # yield hunks
255
         for hunk in self._hunks:
259
         for hunk in self._hunks:
256
-            yield self._markup_hunk_header(hunk.get_header())
260
+            for hunk_header in hunk.get_hunk_headers():
261
+                yield self._markup_hunk_header(hunk_header)
262
+            yield self._markup_hunk_meta(hunk.get_hunk_meta())
257
             for old, new, changed in hunk.mdiff():
263
             for old, new, changed in hunk.mdiff():
258
                 if old[0]:
264
                 if old[0]:
259
                     left_num = str(hunk.get_old_addr()[0] + int(old[0]) - 1)
265
                     left_num = str(hunk.get_old_addr()[0] + int(old[0]) - 1)
300
         return colorize(line, 'yellow')
306
         return colorize(line, 'yellow')
301
 
307
 
302
     def _markup_hunk_header(self, line):
308
     def _markup_hunk_header(self, line):
309
+        return colorize(line, 'lightcyan')
310
+
311
+    def _markup_hunk_meta(self, line):
303
         return colorize(line, 'lightblue')
312
         return colorize(line, 'lightblue')
304
 
313
 
305
     def _markup_common(self, line):
314
     def _markup_common(self, line):
337
     def is_new_path(self, line):
346
     def is_new_path(self, line):
338
         return line.startswith('+++ ')
347
         return line.startswith('+++ ')
339
 
348
 
340
-    def is_hunk_header(self, line):
341
-        return line.startswith('@@ -')
349
+    def is_hunk_meta(self, line):
350
+        return line.startswith('@@ -') or line.startswith('## -')
342
 
351
 
343
-    def parse_hunk_header(self, hunk_header):
352
+    def parse_hunk_meta(self, hunk_meta):
344
         # @@ -3,7 +3,6 @@
353
         # @@ -3,7 +3,6 @@
345
-        a = hunk_header.split()[1].split(',')   # -3 7
354
+        a = hunk_meta.split()[1].split(',')   # -3 7
346
         if len(a) > 1:
355
         if len(a) > 1:
347
             old_addr = (int(a[0][1:]), int(a[1]))
356
             old_addr = (int(a[0][1:]), int(a[1]))
348
         else:
357
         else:
349
             # @@ -1 +1,2 @@
358
             # @@ -1 +1,2 @@
350
             old_addr = (int(a[0][1:]), 0)
359
             old_addr = (int(a[0][1:]), 0)
351
 
360
 
352
-        b = hunk_header.split()[2].split(',')   # +3 6
361
+        b = hunk_meta.split()[2].split(',')   # +3 6
353
         if len(b) > 1:
362
         if len(b) > 1:
354
             new_addr = (int(b[0][1:]), int(b[1]))
363
             new_addr = (int(b[0][1:]), int(b[1]))
355
         else:
364
         else:
359
         return (old_addr, new_addr)
368
         return (old_addr, new_addr)
360
 
369
 
361
     def is_old(self, line):
370
     def is_old(self, line):
362
-        return line.startswith('-') and not self.is_old_path(line)
371
+        """Exclude header line from svn log --diff output"""
372
+        return line.startswith('-') and not self.is_old_path(line) and \
373
+                not re.match(r'^-{4,}$', line.rstrip())
363
 
374
 
364
     def is_new(self, line):
375
     def is_new(self, line):
365
         return line.startswith('+') and not self.is_new_path(line)
376
         return line.startswith('+') and not self.is_new_path(line)
369
 
380
 
370
     def is_eof(self, line):
381
     def is_eof(self, line):
371
         # \ No newline at end of file
382
         # \ No newline at end of file
372
-        return line.startswith('\\')
373
-
374
-    def is_header(self, line):
375
-        return re.match(r'^[^+@\\ -]', line)
383
+        # \ No newline at end of property
384
+        return line.startswith(r'\ No newline at end of')
376
 
385
 
377
 
386
 
378
 class DiffParser(object):
387
 class DiffParser(object):
379
 
388
 
380
     def __init__(self, stream):
389
     def __init__(self, stream):
381
-        """Detect Udiff with 3 conditions"""
390
+        """Detect Udiff with 3 conditions, '## ' uaually indicates svn property
391
+        changes in output from `svn log --diff`
392
+        """
382
         flag = 0
393
         flag = 0
383
-        for line in stream[:20]:
394
+        for line in stream[:100]:
384
             if line.startswith('--- '):
395
             if line.startswith('--- '):
385
                 flag |= 1
396
                 flag |= 1
386
             elif line.startswith('+++ '):
397
             elif line.startswith('+++ '):
387
                 flag |= 2
398
                 flag |= 2
388
-            elif line.startswith('@@ '):
399
+            elif line.startswith('@@ ') or line.startswith('## '):
389
                 flag |= 4
400
                 flag |= 4
390
-        if flag & 7:
391
-            self._type = 'udiff'
401
+            if flag & 7:
402
+                self._type = 'udiff'
403
+                break
392
         else:
404
         else:
393
             raise RuntimeError('unknown diff type')
405
             raise RuntimeError('unknown diff type')
394
 
406
 
409
 
421
 
410
         out_diffs = []
422
         out_diffs = []
411
         headers = []
423
         headers = []
412
-        old_path = None
413
-        new_path = None
414
-        hunks = []
415
-        hunk = None
416
 
424
 
417
         while stream:
425
         while stream:
418
-            # 'common' line occurs before 'old_path' is considered as header
419
-            # too, this happens with `git log -p` and `git show <commit>`
420
-            #
421
-            if difflet.is_header(stream[0]) or \
422
-                    (difflet.is_common(stream[0]) and old_path is None):
423
-                if headers and old_path:
424
-                    # Encounter a new header
425
-                    assert new_path is not None
426
-                    assert hunk is not None
427
-                    hunks.append(hunk)
428
-                    out_diffs.append(Diff(headers, old_path, new_path, hunks))
429
-                    headers = []
430
-                    old_path = None
431
-                    new_path = None
432
-                    hunks = []
433
-                    hunk = None
434
-                else:
435
-                    headers.append(stream.pop(0))
436
-
437
-            elif difflet.is_old_path(stream[0]):
438
-                if old_path:
439
-                    # Encounter a new patch set
440
-                    assert new_path is not None
441
-                    assert hunk is not None
442
-                    hunks.append(hunk)
443
-                    out_diffs.append(Diff(headers, old_path, new_path, hunks))
444
-                    headers = []
445
-                    old_path = None
446
-                    new_path = None
447
-                    hunks = []
448
-                    hunk = None
449
-                else:
450
-                    old_path = stream.pop(0)
426
+            if difflet.is_old_path(stream[0]):
427
+                old_path = stream.pop(0)
428
+                out_diffs.append(Diff(headers, old_path, None, []))
429
+                headers = []
451
 
430
 
452
             elif difflet.is_new_path(stream[0]):
431
             elif difflet.is_new_path(stream[0]):
453
-                assert old_path is not None
454
-                assert new_path is None
455
                 new_path = stream.pop(0)
432
                 new_path = stream.pop(0)
456
-
457
-            elif difflet.is_hunk_header(stream[0]):
458
-                assert old_path is not None
459
-                assert new_path is not None
460
-                if hunk:
461
-                    # Encounter a new hunk header
462
-                    hunks.append(hunk)
463
-                    hunk = None
464
-                else:
465
-                    hunk_header = stream.pop(0)
466
-                    old_addr, new_addr = difflet.parse_hunk_header(hunk_header)
467
-                    hunk = Hunk(hunk_header, old_addr, new_addr)
468
-
469
-            elif difflet.is_old(stream[0]) or difflet.is_new(stream[0]) or \
470
-                    difflet.is_common(stream[0]):
471
-                assert old_path is not None
472
-                assert new_path is not None
473
-                assert hunk is not None
433
+                out_diffs[-1]._new_path = new_path
434
+
435
+            elif difflet.is_hunk_meta(stream[0]):
436
+                hunk_meta = stream.pop(0)
437
+                old_addr, new_addr = difflet.parse_hunk_meta(hunk_meta)
438
+                hunk = Hunk(headers, hunk_meta, old_addr, new_addr)
439
+                headers = []
440
+                out_diffs[-1]._hunks.append(hunk)
441
+
442
+            elif out_diffs and out_diffs[-1]._hunks and \
443
+                    (difflet.is_old(stream[0]) or difflet.is_new(stream[0]) or \
444
+                    difflet.is_common(stream[0])):
474
                 hunk_line = stream.pop(0)
445
                 hunk_line = stream.pop(0)
475
-                hunk.append(hunk_line[0], hunk_line[1:])
446
+                out_diffs[-1]._hunks[-1].append(hunk_line[0], hunk_line[1:])
476
 
447
 
477
             elif difflet.is_eof(stream[0]):
448
             elif difflet.is_eof(stream[0]):
478
                 # ignore
449
                 # ignore
479
                 stream.pop(0)
450
                 stream.pop(0)
480
 
451
 
481
             else:
452
             else:
482
-                raise RuntimeError('unknown patch format: %s' % stream[0])
483
-
484
-        # The last patch
485
-        if hunk:
486
-            hunks.append(hunk)
487
-        if old_path:
488
-            if new_path:
489
-                out_diffs.append(Diff(headers, old_path, new_path, hunks))
490
-            else:
491
-                raise RuntimeError('unknown patch format after "%s"' % old_path)
492
-        elif headers:
493
-            raise RuntimeError('unknown patch format: %s' % \
494
-                    ('\n'.join(headers)))
453
+                # All other non-recognized lines are considered as headers or
454
+                # hunk headers respectively
455
+                #
456
+                headers.append(stream.pop(0))
457
+
458
+        if headers:
459
+            raise RuntimeError('dangling header(s):\n%s' % ''.join(headers))
460
+
461
+        # Validate the last patch set
462
+        if out_diffs:
463
+            assert out_diffs[-1]._old_path is not None
464
+            assert out_diffs[-1]._new_path is not None
465
+            assert len(out_diffs[-1]._hunks) > 0
466
+            assert len(out_diffs[-1]._hunks[-1]._hunk_meta) > 0
495
 
467
 
496
         return out_diffs
468
         return out_diffs
497
 
469
 

+ 3
- 1
tests/README Целия файл

1
-# To generate expected output, use following command, then review with `less -R`
1
+# To generate expected output, chdir to a subdir and use following command, then
2
+# review with `less -R`
3
+#
2
 ../../cdiff.py -c always in.diff > out.normal 
4
 ../../cdiff.py -c always in.diff > out.normal 
3
 ../../cdiff.py -c always -s in.diff > out.side-by-side
5
 ../../cdiff.py -c always -s in.diff > out.side-by-side
4
 ../../cdiff.py -c always -s in.diff -w70 > out.w70
6
 ../../cdiff.py -c always -s in.diff -w70 > out.w70

+ 2
- 1
tests/regression.sh Целия файл

30
     local cdiff_opt=${3:-""}
30
     local cdiff_opt=${3:-""}
31
 
31
 
32
     echo -n "Test option '$cdiff_opt' with input '$input' ... "
32
     echo -n "Test option '$cdiff_opt' with input '$input' ... "
33
-    if $CDIFF $cdiff_opt $input | diff -ubq $expected_out - >& /dev/null; then
33
+    if $CDIFF $cdiff_opt $input 2>/dev/null \
34
+            | diff -ubq $expected_out - >& /dev/null; then
34
         pass
35
         pass
35
         return 0
36
         return 0
36
     else
37
     else

+ 53
- 0
tests/svn-log/in.diff Целия файл

1
+------------------------------------------------------------------------
2
+r1235 | ymattw | 2011-09-01 17:00:02 +0800 (Thu, 01 Sep 2011) | 3 lines
3
+
4
+Interpreter fix
5
+
6
+
7
+Index: src/share/example.sh
8
+===================================================================
9
+--- src/share/example.sh	(revision 1234)
10
++++ src/share/example.sh	(revision 1235)
11
+@@ -1,3 +1,3 @@
12
+-#!/bin/sh
13
++#!/bin/bash
14
+ #
15
+ # Test program, also try run me as yroot (sudo ./example.sh)
16
+
17
+------------------------------------------------------------------------
18
+r1234 | ymattw | 2011-09-01 16:00:02 +0800 (Thu, 01 Sep 2011) | 3 lines
19
+
20
+Implement common tool to run command as headless account
21
+
22
+
23
+Index: ChangeLog
24
+===================================================================
25
+--- ChangeLog	(revision 1233)
26
++++ ChangeLog	(revision 1234)
27
+@@ -1,3 +1,6 @@
28
++Version 0.0.4
29
++    * Add prototype of perl module
30
++
31
+ Version 0.0.3
32
+     * Implement '-d' option
33
+     * Add configfile to set global debug flag
34
+Index: src/share/example.sh
35
+===================================================================
36
+--- src/share/example.sh	(revision 0)
37
++++ src/share/example.sh	(revision 1234)
38
+@@ -0,0 +1,4 @@
39
++#!/bin/sh
40
++#
41
++# Test program, also try run me as yroot (sudo ./example.sh)
42
++#
43
+
44
+Property changes on: src/share/example.sh
45
+___________________________________________________________________
46
+Added: svn:executable
47
+## -0,0 +1 ##
48
++*
49
+\ No newline at end of property
50
+Added: svn:keywords
51
+## -0,0 +1 ##
52
++Id
53
+\ No newline at end of property

+ 52
- 0
tests/svn-log/out.normal Целия файл

1
+------------------------------------------------------------------------
2
+r1235 | ymattw | 2011-09-01 17:00:02 +0800 (Thu, 01 Sep 2011) | 3 lines
3
+
4
+Interpreter fix
5
+
6
+
7
+Index: src/share/example.sh
8
+===================================================================
9
+--- src/share/example.sh	(revision 1234)
10
++++ src/share/example.sh	(revision 1235)
11
+@@ -1,3 +1,3 @@
12
+-#!/bin/sh
13
++#!/bin/bash
14
+ #
15
+ # Test program, also try run me as yroot (sudo ./example.sh)
16
+
17
+------------------------------------------------------------------------
18
+r1234 | ymattw | 2011-09-01 16:00:02 +0800 (Thu, 01 Sep 2011) | 3 lines
19
+
20
+Implement common tool to run command as headless account
21
+
22
+
23
+Index: ChangeLog
24
+===================================================================
25
+--- ChangeLog	(revision 1233)
26
++++ ChangeLog	(revision 1234)
27
+@@ -1,3 +1,6 @@
28
++Version 0.0.4
29
++    * Add prototype of perl module
30
++
31
+ Version 0.0.3
32
+     * Implement '-d' option
33
+     * Add configfile to set global debug flag
34
+Index: src/share/example.sh
35
+===================================================================
36
+--- src/share/example.sh	(revision 0)
37
++++ src/share/example.sh	(revision 1234)
38
+@@ -0,0 +1,4 @@
39
++#!/bin/sh
40
++#
41
++# Test program, also try run me as yroot (sudo ./example.sh)
42
++#
43
+
44
+Property changes on: src/share/example.sh
45
+___________________________________________________________________
46
+Added: svn:executable
47
+## -0,0 +1 ##
48
++*
49
+Added: svn:keywords
50
+## -0,0 +1 ##
51
++Id
52
+

+ 50
- 0
tests/svn-log/out.side-by-side Целия файл

1
+------------------------------------------------------------------------
2
+r1235 | ymattw | 2011-09-01 17:00:02 +0800 (Thu, 01 Sep 2011) | 3 lines
3
+
4
+Interpreter fix
5
+
6
+
7
+Index: src/share/example.sh
8
+===================================================================
9
+--- src/share/example.sh	(revision 1234)
10
++++ src/share/example.sh	(revision 1235)
11
+@@ -1,3 +1,3 @@
12
+1 #!/bin/sh                                                                        1 #!/bin/bash
13
+2 #                                                                                2 #
14
+3 # Test program, also try run me as yroot (sudo ./example.sh)                     3 # Test program, also try run me as yroot (sudo ./example.sh)
15
+
16
+------------------------------------------------------------------------
17
+r1234 | ymattw | 2011-09-01 16:00:02 +0800 (Thu, 01 Sep 2011) | 3 lines
18
+
19
+Implement common tool to run command as headless account
20
+
21
+
22
+Index: ChangeLog
23
+===================================================================
24
+--- ChangeLog	(revision 1233)
25
++++ ChangeLog	(revision 1234)
26
+@@ -1,3 +1,6 @@
27
+                                                                                   1 Version 0.0.4
28
+                                                                                   2     * Add prototype of perl module
29
+                                                                                   3 
30
+1 Version 0.0.3                                                                    4 Version 0.0.3
31
+2     * Implement '-d' option                                                      5     * Implement '-d' option
32
+3     * Add configfile to set global debug flag                                    6     * Add configfile to set global debug flag
33
+Index: src/share/example.sh
34
+===================================================================
35
+--- src/share/example.sh	(revision 0)
36
++++ src/share/example.sh	(revision 1234)
37
+@@ -0,0 +1,4 @@
38
+                                                                                     1 #!/bin/sh
39
+                                                                                     2 #
40
+                                                                                     3 # Test program, also try run me as yroot (sudo ./example.sh)
41
+                                                                                     4 #
42
+
43
+Property changes on: src/share/example.sh
44
+___________________________________________________________________
45
+Added: svn:executable
46
+## -0,0 +1 ##
47
+                                                                                     1 *
48
+Added: svn:keywords
49
+## -0,0 +1 ##
50
+                                                                                     1 Id

+ 50
- 0
tests/svn-log/out.w70 Целия файл

1
+------------------------------------------------------------------------
2
+r1235 | ymattw | 2011-09-01 17:00:02 +0800 (Thu, 01 Sep 2011) | 3 lines
3
+
4
+Interpreter fix
5
+
6
+
7
+Index: src/share/example.sh
8
+===================================================================
9
+--- src/share/example.sh	(revision 1234)
10
++++ src/share/example.sh	(revision 1235)
11
+@@ -1,3 +1,3 @@
12
+1 #!/bin/sh                                                              1 #!/bin/bash
13
+2 #                                                                      2 #
14
+3 # Test program, also try run me as yroot (sudo ./example.sh)           3 # Test program, also try run me as yroot (sudo ./example.sh)
15
+
16
+------------------------------------------------------------------------
17
+r1234 | ymattw | 2011-09-01 16:00:02 +0800 (Thu, 01 Sep 2011) | 3 lines
18
+
19
+Implement common tool to run command as headless account
20
+
21
+
22
+Index: ChangeLog
23
+===================================================================
24
+--- ChangeLog	(revision 1233)
25
++++ ChangeLog	(revision 1234)
26
+@@ -1,3 +1,6 @@
27
+                                                                         1 Version 0.0.4
28
+                                                                         2     * Add prototype of perl module
29
+                                                                         3 
30
+1 Version 0.0.3                                                          4 Version 0.0.3
31
+2     * Implement '-d' option                                            5     * Implement '-d' option
32
+3     * Add configfile to set global debug flag                          6     * Add configfile to set global debug flag
33
+Index: src/share/example.sh
34
+===================================================================
35
+--- src/share/example.sh	(revision 0)
36
++++ src/share/example.sh	(revision 1234)
37
+@@ -0,0 +1,4 @@
38
+                                                                           1 #!/bin/sh
39
+                                                                           2 #
40
+                                                                           3 # Test program, also try run me as yroot (sudo ./example.sh)
41
+                                                                           4 #
42
+
43
+Property changes on: src/share/example.sh
44
+___________________________________________________________________
45
+Added: svn:executable
46
+## -0,0 +1 ##
47
+                                                                           1 *
48
+Added: svn:keywords
49
+## -0,0 +1 ##
50
+                                                                           1 Id

+ 23
- 0
tests/test_cdiff.py Целия файл

1
+#!/usr/bin/env python
2
+# -*- coding: utf-8 -*-
3
+
4
+"""Unit test for cdiff"""
5
+
6
+import sys
7
+if sys.hexversion < 0x02050000:
8
+    raise SystemExit("*** Requires python >= 2.5.0")
9
+
10
+sys.path.insert(0, '..')
11
+
12
+import unittest
13
+import cdiff
14
+
15
+class TestCdiff(unittest.TestCase):
16
+
17
+    def test_foo(self):
18
+        self.assertTrue(1)
19
+
20
+if __name__ == '__main__':
21
+    unittest.main()
22
+
23
+# vim:set et sts=4 sw=4 tw=80: