diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2019-12-18 18:09:47 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2019-12-20 16:29:35 +0300 |
commit | 9984dd332f77a66def0ad23d71f729570a93dcbe (patch) | |
tree | dd29358630273fe23f714225d965aaa5db964b5c /tests | |
parent | 9a1bbca5b15ec91175ba595ff52df6adeefb6528 (diff) |
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.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/python/CMakeLists.txt | 8 | ||||
-rw-r--r-- | tests/python/bl_id_management.py | 184 |
2 files changed, 192 insertions, 0 deletions
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 @@ -114,6 +114,14 @@ add_blender_test( ) # ------------------------------------------------------------------------------ +# DATA MANAGEMENT TESTS + +add_blender_test( + id_management + --python ${CMAKE_CURRENT_LIST_DIR}/bl_id_management.py +) + +# ------------------------------------------------------------------------------ # MODELING TESTS add_blender_test( bmesh_bevel 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() |