[Bf-blender-cvs] [9984dd332f7] master: ID Management: Add some basic tests regarding name handling.

Bastien Montagne noreply at git.blender.org
Fri Dec 20 14:46:25 CET 2019


Commit: 9984dd332f77a66def0ad23d71f729570a93dcbe
Author: Bastien Montagne
Date:   Wed Dec 18 16:09:47 2019 +0100
Branches: master
https://developer.blender.org/rB9984dd332f77a66def0ad23d71f729570a93dcbe

ID Management: Add some basic tests regarding name handling.

Those tests are here mostsly to ensure ID name management is working as
expected (the code ensuring we never have two ilocal data-blocks of the
same type with the same name in a .blend file).

Note: Currently fails in some cases, fixes are incoming.

Note: Ideally this would be in C, but we already have too many tests
linking the whole Blender and its libraries, this is becoming a real
pain to link debug + ASAN + tests build these days... So until we find a
better way to handle those dependencies, sticking to simple python
scripts.

===================================================================

M	tests/python/CMakeLists.txt
A	tests/python/bl_id_management.py

===================================================================

diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index 3036be71564..7241c26dfec 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -113,6 +113,14 @@ add_blender_test(
   --python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_idprop_datablock.py
 )
 
+# ------------------------------------------------------------------------------
+# DATA MANAGEMENT TESTS
+
+add_blender_test(
+  id_management
+  --python ${CMAKE_CURRENT_LIST_DIR}/bl_id_management.py
+)
+
 # ------------------------------------------------------------------------------
 # MODELING TESTS
 add_blender_test(
diff --git a/tests/python/bl_id_management.py b/tests/python/bl_id_management.py
new file mode 100644
index 00000000000..938a1cab134
--- /dev/null
+++ b/tests/python/bl_id_management.py
@@ -0,0 +1,184 @@
+# Apache License, Version 2.0
+
+# ./blender.bin --background -noaudio --python tests/python/bl_id_management.py -- --verbose
+import bpy
+import unittest
+import random
+
+
+class TestHelper:
+
+    @property
+    def data_container(self):
+        return getattr(bpy.data, self.data_container_id)
+
+    def clear_container(self):
+        bpy.data.batch_remove(self.data_container)
+
+    def add_to_container(self, name=""):
+        return self.data_container.new(name)
+
+    def remove_from_container(self, data=None, name=None, index=None):
+        data_container = self.data_container
+        if not data:
+            if name:
+                data = data_container[name]
+            elif index:
+                data = data_container[index]
+        self.assertTrue(data is not None)
+        data_container.remove(data)
+
+    def add_items_with_randomized_names(self, number_items=1, name_prefix=None, name_suffix=""):
+        if name_prefix is None:
+            name_prefix = self.default_name
+        for i in range(number_items):
+            self.add_to_container(name=name_prefix + str(random.random())[2:5] + name_suffix)
+
+    def ensure_proper_order(self):
+        id_prev = None
+        for id in self.data_container:
+            if id_prev:
+                self.assertTrue(id_prev.name < id.name or id.library)
+            id_prev = id
+
+
+class TestIdAddNameManagement(TestHelper, unittest.TestCase):
+    data_container_id = 'meshes'
+    default_name = "Mesh"
+
+    def test_add_remove_single(self):
+        self.clear_container()
+        self.assertEqual(len(self.data_container), 0)
+        data = self.add_to_container()
+        self.assertEqual(len(self.data_container), 1)
+        self.ensure_proper_order()
+        self.remove_from_container(data=data)
+        self.assertEqual(len(self.data_container), 0)
+
+    def test_add_head_tail(self):
+        self.clear_container()
+        self.add_items_with_randomized_names(10)
+        self.assertEqual(len(self.data_container), 10)
+        self.ensure_proper_order()
+
+        name_head = "AAA" + self.default_name
+        data = self.add_to_container(name=name_head)
+        self.assertEqual(len(self.data_container), 11)
+        self.assertEqual(self.data_container[0].name, name_head)
+        self.ensure_proper_order()
+
+        name_tail = "ZZZ" + self.default_name
+        data = self.add_to_container(name=name_tail)
+        self.assertEqual(len(self.data_container), 12)
+        self.assertEqual(self.data_container[-1].name, name_tail)
+        self.ensure_proper_order()
+
+    def test_add_long_names(self):
+        self.clear_container()
+        self.add_items_with_randomized_names(10)
+        self.assertEqual(len(self.data_container), 10)
+        self.ensure_proper_order()
+
+        for i in range(12000):
+            self.add_to_container(name="ABCDEFGHIJKLMNOPQRSTUVWXYZ" * 3)
+        self.assertEqual(len(self.data_container), 12010)
+        self.ensure_proper_order()
+
+        self.clear_container()
+        self.add_items_with_randomized_names(100, name_prefix="", name_suffix="ABCDEFGHIJKLMNOPQRSTUVWXYZ" * 3)
+        self.assertEqual(len(self.data_container), 100)
+        self.ensure_proper_order()
+
+    def test_add_invalid_number_suffixes(self):
+        self.clear_container()
+
+        name = "%s.%.3d" % (self.default_name, 1000000000)
+        data = self.add_to_container(name=name)
+        self.assertEqual(data.name, name)
+
+        data = self.add_to_container(name=name)
+        self.assertEqual(data.name, self.default_name + ".001")
+
+        data = self.add_to_container(name=name)
+        self.assertEqual(data.name, self.default_name + ".002")
+
+        data = self.add_to_container(name=self.default_name)
+        self.assertEqual(data.name, self.default_name)
+
+        data = self.add_to_container(name="%s.%.3d" % (self.default_name, 0))
+        self.assertEqual(data.name, self.default_name + ".000")
+
+        data = self.add_to_container(name="%s.%.3d" % (self.default_name, 0))
+        self.assertEqual(data.name, self.default_name + ".003")
+        
+        self.assertEqual(len(self.data_container), 6)
+        self.ensure_proper_order()
+
+    def test_add_use_smallest_free_number(self):
+        self.clear_container()
+
+        data = self.add_to_container(name="%s.%.3d" % (self.default_name, 2))
+        self.assertEqual(data.name, self.default_name + ".002")
+
+        data = self.add_to_container(name="%s.%.3d" % (self.default_name, 2))
+        self.assertEqual(data.name, self.default_name + ".001")
+
+        data = self.add_to_container(name="%s.%.3d" % (self.default_name, 2))
+        self.assertEqual(data.name, self.default_name + ".003")
+
+        for i in range(5, 1111):
+            name = "%s.%.3d" % (self.default_name, i)
+            data = self.add_to_container(name=name)
+            self.assertEqual(data.name, name)
+
+        for i in range(1112, 1200):
+            name = "%s.%.3d" % (self.default_name, i)
+            data = self.add_to_container(name=name)
+            self.assertEqual(data.name, name)
+
+        # Only slot available below 1024: 004.
+        data = self.add_to_container(name="%s.%.3d" % (self.default_name, 2))
+        self.assertEqual(data.name, self.default_name + ".004")
+
+        # Slot available at 1111 is not 'found' and we get first highest free number, 1200.
+        data = self.add_to_container(name="%s.%.3d" % (self.default_name, 2))
+        self.assertEqual(data.name, self.default_name + ".1200")
+
+        self.assertEqual(len(self.data_container), 1199)
+        self.ensure_proper_order()
+
+
+class TestIdRename(TestHelper, unittest.TestCase):
+    data_container_id = 'meshes'
+    default_name = "Mesh"
+
+    def test_rename(self):
+        self.clear_container()
+        self.add_items_with_randomized_names(100)
+        self.ensure_proper_order()
+
+        data = self.data_container[0]
+        data.name = "ZZZ" + data.name
+        self.assertEqual(self.data_container[-1], data)
+        self.ensure_proper_order()
+        data.name = "AAA" + data.name
+        self.assertEqual(self.data_container[0], data)
+        self.ensure_proper_order()
+
+        name = "%s.%.3d" % (self.default_name, 1000000000)
+        data.name = name
+        self.assertEqual(data.name, name)
+        for dt in self.data_container:
+            if dt is not data:
+                data = dt
+                break
+        data.name = name
+        # This can fail currently, see T71244.
+        # ~ self.assertEqual(data.name, self.default_name + ".001")
+        self.ensure_proper_order()
+
+
+if __name__ == '__main__':
+    import sys
+    sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [])
+    unittest.main()



More information about the Bf-blender-cvs mailing list