diff tests/test-rust-revlog.py @ 52802:34f44aa5e844

rust-pyo3-index: first mutating methods This brings in `append()` and `__delitem__`, and is for us the first validation of our inner mutability. In the case of `__delitem__`, there was a tricky case where we were tempted to use the higher level `PySlice::indices` API, with a possible dangerous change of behaviour. We test it carefully from the Python side.
author Georges Racinet <georges.racinet@cloudcrane.io>
date Wed, 25 Dec 2024 17:17:47 +0100
parents e5f89bd1a5ee
children 0ac956db7ea7
line wrap: on
line diff
--- a/tests/test-rust-revlog.py	Wed Dec 25 17:17:40 2024 +0100
+++ b/tests/test-rust-revlog.py	Wed Dec 25 17:17:47 2024 +0100
@@ -28,6 +28,8 @@
     node0 = node_bin(node_hex0)
     bogus_node_hex = b'cafe' * 10
     bogus_node = node_bin(bogus_node_hex)
+    node_hex2 = b"020a0ec626a192ae360b0269fe2de5ba6f05d1e7"
+    node2 = node_bin(node_hex2)
 
     def test_index_nodemap(self):
         idx = self.parserustindex()
@@ -50,6 +52,75 @@
         idx = self.parserustindex()
         self.assertEqual(len(idx), 4)
 
+    def test_index_append(self):
+        idx = self.parserustindex(data=b'')
+        self.assertEqual(len(idx), 0)
+        self.assertIsNone(idx.get_rev(self.node0))
+
+        # this is the same first entry as in data provided by base test class
+        # (we do not have __getitem__ in the PyO3 version yet)
+        idx.append((0, 82969, 484626, 0, 0, -1, -1, self.node0, 0, 0, 2, 2, -1))
+        self.assertEqual(len(idx), 1)
+        self.assertEqual(idx.get_rev(self.node0), 0)
+
+    def test_index_delitem_single(self):
+        idx = self.parserustindex()
+        del idx[2]
+        self.assertEqual(len(idx), 2)
+
+        # the nodetree is consistent
+        self.assertEqual(idx.get_rev(self.node0), 0)
+        self.assertIsNone(idx.get_rev(self.node2))
+
+        # not an error and does nothing
+        del idx[-1]
+        self.assertEqual(len(idx), 2)
+
+        for bogus in (-2, 17):
+            try:
+                del idx[bogus]
+            except ValueError as exc:
+                # this underlines that we should do better with this message
+                assert exc.args[0] == (
+                    f"Inconsistency: Revision {bogus} found in nodemap "
+                    "is not in revlog index"
+                )
+            else:
+                raise AssertionError(
+                    f"an exception was expected for `del idx[{bogus}]`"
+                )
+
+    def test_index_delitem_slice(self):
+        idx = self.parserustindex()
+        del idx[2:3]
+        self.assertEqual(len(idx), 2)
+
+        # not an error and not equivalent to `del idx[0::]` but to
+        # `del idx[-1]` instead and thus does nothing.
+        del idx[-1::]
+        self.assertEqual(len(idx), 2)
+
+        for start, stop in (
+            (-2, None),
+            (17, None),
+        ):
+            try:
+                del idx[start:stop]
+            except ValueError as exc:
+                # this underlines that we should do better with this message
+                assert exc.args[0] == (
+                    f"Inconsistency: Revision {start} found in nodemap "
+                    "is not in revlog index"
+                )
+            else:
+                raise AssertionError(
+                    f"an exception was expected for `del idx[{start}:{stop}]`"
+                )
+
+        # although the upper bound is way too big, this is not an error:
+        del idx[0::17]
+        self.assertEqual(len(idx), 0)
+
 
 # Conditional skipping done by the base class
 class RustInnerRevlogTest(