##// END OF EJS Templates
diffstat: support filenames with whitespaces on renames...
diffstat: support filenames with whitespaces on renames This is a follow-up patch to D5628. `line.split()` cannot get filenames with whitespaces as mentioned by @yuja. This patch replaces `split()` method with `slice`. Corresponding tests were also added. Differential Revision: https://phab.mercurial-scm.org/D5709

File last commit:

r41386:ab0d762d stable
r41446:4a33a6bf default
Show More
test-rust-ancestor.py
170 lines | 6.4 KiB | text/x-python | PythonLexer
/ tests / test-rust-ancestor.py
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004 from __future__ import absolute_import
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 import sys
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004 import unittest
Georges Racinet
rust-cpython: raising error.WdirUnsupported...
r41386 from mercurial import (
error,
node,
)
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004 try:
from mercurial import rustext
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 rustext.__name__ # trigger immediate actual import
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004 except ImportError:
rustext = None
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 else:
# this would fail already without appropriate ancestor.__package__
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149 from mercurial.rustext.ancestor import (
AncestorsIterator,
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 LazyAncestors,
MissingAncestors,
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149 )
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004
try:
from mercurial.cext import parsers as cparsers
except ImportError:
cparsers = None
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 # picked from test-parse-index2, copied rather than imported
# so that it stays stable even if test-parse-index2 changes or disappears.
data_non_inlined = (
b'\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01D\x19'
b'\x00\x07e\x12\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff'
b'\xff\xff\xff\xff\xd1\xf4\xbb\xb0\xbe\xfc\x13\xbd\x8c\xd3\x9d'
b'\x0f\xcd\xd9;\x8c\x07\x8cJ/\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x01D\x19\x00\x00\x00\x00\x00\xdf\x00'
b'\x00\x01q\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\xff'
b'\xff\xff\xff\xc1\x12\xb9\x04\x96\xa4Z1t\x91\xdfsJ\x90\xf0\x9bh'
b'\x07l&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x01D\xf8\x00\x00\x00\x00\x01\x1b\x00\x00\x01\xb8\x00\x00'
b'\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\x02\n'
b'\x0e\xc6&\xa1\x92\xae6\x0b\x02i\xfe-\xe5\xbao\x05\xd1\xe7\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01F'
b'\x13\x00\x00\x00\x00\x01\xec\x00\x00\x03\x06\x00\x00\x00\x01'
b'\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x12\xcb\xeby1'
b'\xb6\r\x98B\xcb\x07\xbd`\x8f\x92\xd9\xc4\x84\xbdK\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00'
)
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004 @unittest.skipIf(rustext is None or cparsers is None,
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 "rustext or the C Extension parsers module "
"ancestor relies on is not available")
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004 class rustancestorstest(unittest.TestCase):
"""Test the correctness of binding to Rust code.
This test is merely for the binding to Rust itself: extraction of
Python variable, giving back the results etc.
It is not meant to test the algorithmic correctness of the operations
on ancestors it provides. Hence the very simple embedded index data is
good enough.
Algorithmic correctness is asserted by the Rust unit tests.
"""
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 def parseindex(self):
return cparsers.parse_index2(data_non_inlined, False)[0]
def testiteratorrevlist(self):
idx = self.parseindex()
# checking test assumption about the index binary data:
self.assertEqual({i: (r[5], r[6]) for i, r in enumerate(idx)},
{0: (-1, -1),
1: (0, -1),
2: (1, -1),
3: (2, -1)})
ait = AncestorsIterator(idx, [3], 0, True)
self.assertEqual([r for r in ait], [3, 2, 1, 0])
ait = AncestorsIterator(idx, [3], 0, False)
self.assertEqual([r for r in ait], [2, 1, 0])
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149 def testlazyancestors(self):
idx = self.parseindex()
start_count = sys.getrefcount(idx) # should be 2 (see Python doc)
self.assertEqual({i: (r[5], r[6]) for i, r in enumerate(idx)},
{0: (-1, -1),
1: (0, -1),
2: (1, -1),
3: (2, -1)})
lazy = LazyAncestors(idx, [3], 0, True)
# we have two more references to the index:
# - in its inner iterator for __contains__ and __bool__
# - in the LazyAncestors instance itself (to spawn new iterators)
self.assertEqual(sys.getrefcount(idx), start_count + 2)
self.assertTrue(2 in lazy)
self.assertTrue(bool(lazy))
self.assertEqual(list(lazy), [3, 2, 1, 0])
# a second time to validate that we spawn new iterators
self.assertEqual(list(lazy), [3, 2, 1, 0])
# now let's watch the refcounts closer
ait = iter(lazy)
self.assertEqual(sys.getrefcount(idx), start_count + 3)
del ait
self.assertEqual(sys.getrefcount(idx), start_count + 2)
del lazy
self.assertEqual(sys.getrefcount(idx), start_count)
# let's check bool for an empty one
self.assertFalse(LazyAncestors(idx, [0], 0, False))
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 def testmissingancestors(self):
idx = self.parseindex()
missanc = MissingAncestors(idx, [1])
self.assertTrue(missanc.hasbases())
self.assertEqual(missanc.missingancestors([3]), [2, 3])
missanc.addbases({2})
Georges Racinet
rust-cpython: set conversion for MissingAncestors.bases()...
r41279 self.assertEqual(missanc.bases(), {1, 2})
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 self.assertEqual(missanc.missingancestors([3]), [3])
Georges Racinet
rust: MissingAncestors.basesheads()...
r41282 self.assertEqual(missanc.basesheads(), {2})
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224
def testmissingancestorsremove(self):
idx = self.parseindex()
missanc = MissingAncestors(idx, [1])
revs = {0, 1, 2, 3}
missanc.removeancestorsfrom(revs)
self.assertEqual(revs, {2, 3})
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 def testrefcount(self):
idx = self.parseindex()
start_count = sys.getrefcount(idx)
# refcount increases upon iterator init...
ait = AncestorsIterator(idx, [3], 0, True)
self.assertEqual(sys.getrefcount(idx), start_count + 1)
self.assertEqual(next(ait), 3)
# and decreases once the iterator is removed
del ait
self.assertEqual(sys.getrefcount(idx), start_count)
# and removing ref to the index after iterator init is no issue
ait = AncestorsIterator(idx, [3], 0, True)
del idx
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149 self.assertEqual(list(ait), [3, 2, 1, 0])
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004
def testgrapherror(self):
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 data = (data_non_inlined[:64 + 27] +
b'\xf2' +
data_non_inlined[64 + 28:])
idx = cparsers.parse_index2(data, False)[0]
with self.assertRaises(rustext.GraphError) as arc:
AncestorsIterator(idx, [1], -1, False)
exc = arc.exception
self.assertIsInstance(exc, ValueError)
# rust-cpython issues appropriate str instances for Python 2 and 3
self.assertEqual(exc.args, ('ParentOutOfRange', 1))
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004
Georges Racinet
rust-cpython: raising error.WdirUnsupported...
r41386 def testwdirunsupported(self):
# trying to access ancestors of the working directory raises
# WdirUnsupported directly
idx = self.parseindex()
with self.assertRaises(error.WdirUnsupported):
list(AncestorsIterator(idx, [node.wdirrev], -1, False))
Georges Racinet
rust-cpython: testing the bindings from Python...
r41004
if __name__ == '__main__':
import silenttestrunner
silenttestrunner.main(__name__)