|
@@ -54,6 +54,39 @@ c_sha = '954a536f7819d40e6f637f849ee187dd10066349'
|
|
|
tree_sha = '70c190eb48fa8bbb50ddc692a17b44cb781af7f6'
|
|
|
tag_sha = '71033db03a03c6a36721efcf1968dd8f8e0cf023'
|
|
|
|
|
|
+
|
|
|
+try:
|
|
|
+ from itertools import permutations
|
|
|
+except ImportError:
|
|
|
+ # Implementation of permutations from Python 2.6 documentation:
|
|
|
+ # http://docs.python.org/2.6/library/itertools.html#itertools.permutations
|
|
|
+ # Copyright (c) 2001-2010 Python Software Foundation; All Rights Reserved
|
|
|
+ def permutations(iterable, r=None):
|
|
|
+ # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
|
|
|
+ # permutations(range(3)) --> 012 021 102 120 201 210
|
|
|
+ pool = tuple(iterable)
|
|
|
+ n = len(pool)
|
|
|
+ r = n if r is None else r
|
|
|
+ if r > n:
|
|
|
+ return
|
|
|
+ indices = range(n)
|
|
|
+ cycles = range(n, n-r, -1)
|
|
|
+ yield tuple(pool[i] for i in indices[:r])
|
|
|
+ while n:
|
|
|
+ for i in reversed(range(r)):
|
|
|
+ cycles[i] -= 1
|
|
|
+ if cycles[i] == 0:
|
|
|
+ indices[i:] = indices[i+1:] + indices[i:i+1]
|
|
|
+ cycles[i] = n - i
|
|
|
+ else:
|
|
|
+ j = cycles[i]
|
|
|
+ indices[i], indices[-j] = indices[-j], indices[i]
|
|
|
+ yield tuple(pool[i] for i in indices[:r])
|
|
|
+ break
|
|
|
+ else:
|
|
|
+ return
|
|
|
+
|
|
|
+
|
|
|
class BlobReadTests(unittest.TestCase):
|
|
|
"""Test decompression of blobs"""
|
|
|
|
|
@@ -250,15 +283,15 @@ default_committer = 'James Westby <jw+debian@jameswestby.net> 1174773719 +0000'
|
|
|
|
|
|
class CommitParseTests(ShaFileCheckTests):
|
|
|
|
|
|
- def make_commit_text(self,
|
|
|
- tree='d80c186a03f423a81b39df39dc87fd269736ca86',
|
|
|
- parents=['ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd',
|
|
|
- '4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
|
|
|
- author=default_committer,
|
|
|
- committer=default_committer,
|
|
|
- encoding=None,
|
|
|
- message='Merge ../b\n',
|
|
|
- extra=None):
|
|
|
+ def make_commit_lines(self,
|
|
|
+ tree='d80c186a03f423a81b39df39dc87fd269736ca86',
|
|
|
+ parents=['ab64bbdcc51b170d21588e5c5d391ee5c0c96dfd',
|
|
|
+ '4cffe90e0a41ad3f5190079d7c8f036bde29cbe6'],
|
|
|
+ author=default_committer,
|
|
|
+ committer=default_committer,
|
|
|
+ encoding=None,
|
|
|
+ message='Merge ../b\n',
|
|
|
+ extra=None):
|
|
|
lines = []
|
|
|
if tree is not None:
|
|
|
lines.append('tree %s' % tree)
|
|
@@ -276,7 +309,10 @@ class CommitParseTests(ShaFileCheckTests):
|
|
|
lines.append('')
|
|
|
if message is not None:
|
|
|
lines.append(message)
|
|
|
- return '\n'.join(lines)
|
|
|
+ return lines
|
|
|
+
|
|
|
+ def make_commit_text(self, **kwargs):
|
|
|
+ return '\n'.join(self.make_commit_lines(**kwargs))
|
|
|
|
|
|
def test_simple(self):
|
|
|
c = Commit.from_string(self.make_commit_text())
|
|
@@ -325,6 +361,31 @@ class CommitParseTests(ShaFileCheckTests):
|
|
|
self.assertCheckFails(Commit(), self.make_commit_text(
|
|
|
author=None, committer=None))
|
|
|
|
|
|
+ def test_check_duplicates(self):
|
|
|
+ # duplicate each of the header fields
|
|
|
+ for i in xrange(5):
|
|
|
+ lines = self.make_commit_lines(parents=[a_sha], encoding='UTF-8')
|
|
|
+ lines.insert(i, lines[i])
|
|
|
+ text = '\n'.join(lines)
|
|
|
+ if lines[i].startswith('parent'):
|
|
|
+ # duplicate parents are ok for now
|
|
|
+ self.assertCheckSucceeds(Commit(), text)
|
|
|
+ else:
|
|
|
+ self.assertCheckFails(Commit(), text)
|
|
|
+
|
|
|
+ def test_check_order(self):
|
|
|
+ lines = self.make_commit_lines(parents=[a_sha], encoding='UTF-8')
|
|
|
+ headers = lines[:5]
|
|
|
+ rest = lines[5:]
|
|
|
+ # of all possible permutations, ensure only the original succeeds
|
|
|
+ for perm in permutations(headers):
|
|
|
+ perm = list(perm)
|
|
|
+ text = '\n'.join(perm + rest)
|
|
|
+ if perm == headers:
|
|
|
+ self.assertCheckSucceeds(Commit(), text)
|
|
|
+ else:
|
|
|
+ self.assertCheckFails(Commit(), text)
|
|
|
+
|
|
|
|
|
|
class TreeTests(ShaFileCheckTests):
|
|
|
|
|
@@ -425,12 +486,12 @@ OK2XeQOiEeXtT76rV4t2WR4=
|
|
|
|
|
|
|
|
|
class TagParseTests(ShaFileCheckTests):
|
|
|
- def make_tag_text(self,
|
|
|
- object_sha="a38d6181ff27824c79fc7df825164a212eff6a3f",
|
|
|
- object_type_name="commit",
|
|
|
- name="v2.6.22-rc7",
|
|
|
- tagger=default_tagger,
|
|
|
- message=default_message):
|
|
|
+ def make_tag_lines(self,
|
|
|
+ object_sha="a38d6181ff27824c79fc7df825164a212eff6a3f",
|
|
|
+ object_type_name="commit",
|
|
|
+ name="v2.6.22-rc7",
|
|
|
+ tagger=default_tagger,
|
|
|
+ message=default_message):
|
|
|
lines = []
|
|
|
if object_sha is not None:
|
|
|
lines.append("object %s" % object_sha)
|
|
@@ -443,7 +504,10 @@ class TagParseTests(ShaFileCheckTests):
|
|
|
lines.append("")
|
|
|
if message is not None:
|
|
|
lines.append(message)
|
|
|
- return "\n".join(lines)
|
|
|
+ return lines
|
|
|
+
|
|
|
+ def make_tag_text(self, **kwargs):
|
|
|
+ return "\n".join(self.make_tag_lines(**kwargs))
|
|
|
|
|
|
def test_parse(self):
|
|
|
x = Tag()
|
|
@@ -480,6 +544,26 @@ class TagParseTests(ShaFileCheckTests):
|
|
|
"Sun 7 Jul 2007 12:54:34 +0700")))
|
|
|
self.assertCheckFails(Tag(), self.make_tag_text(object_sha="xxx"))
|
|
|
|
|
|
+ def test_check_duplicates(self):
|
|
|
+ # duplicate each of the header fields
|
|
|
+ for i in xrange(4):
|
|
|
+ lines = self.make_tag_lines()
|
|
|
+ lines.insert(i, lines[i])
|
|
|
+ self.assertCheckFails(Tag(), '\n'.join(lines))
|
|
|
+
|
|
|
+ def test_check_order(self):
|
|
|
+ lines = self.make_tag_lines()
|
|
|
+ headers = lines[:4]
|
|
|
+ rest = lines[4:]
|
|
|
+ # of all possible permutations, ensure only the original succeeds
|
|
|
+ for perm in permutations(headers):
|
|
|
+ perm = list(perm)
|
|
|
+ text = '\n'.join(perm + rest)
|
|
|
+ if perm == headers:
|
|
|
+ self.assertCheckSucceeds(Tag(), text)
|
|
|
+ else:
|
|
|
+ self.assertCheckFails(Tag(), text)
|
|
|
+
|
|
|
|
|
|
class CheckTests(unittest.TestCase):
|
|
|
|