diff options
Diffstat (limited to 'source/blender/blenkernel/intern/lib_remap_test.cc')
-rw-r--r-- | source/blender/blenkernel/intern/lib_remap_test.cc | 328 |
1 files changed, 281 insertions, 47 deletions
diff --git a/source/blender/blenkernel/intern/lib_remap_test.cc b/source/blender/blenkernel/intern/lib_remap_test.cc index 008bd6b75c2..16717d3ceaa 100644 --- a/source/blender/blenkernel/intern/lib_remap_test.cc +++ b/source/blender/blenkernel/intern/lib_remap_test.cc @@ -21,7 +21,9 @@ #include "CLG_log.h" +#include "DNA_mesh_types.h" #include "DNA_node_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "RNA_define.h" @@ -33,7 +35,9 @@ #include "BKE_lib_id.h" #include "BKE_lib_remap.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_node.h" +#include "BKE_object.h" #include "BKE_scene.h" #include "IMB_imbuf.h" @@ -44,12 +48,99 @@ namespace blender::bke::tests { -struct Context { +class TestData { + public: Main *bmain = nullptr; - Scene *scene = nullptr; - bNodeTree *composite_nodetree = nullptr; struct bContext *C = nullptr; + virtual void setup() + { + if (bmain == nullptr) { + bmain = BKE_main_new(); + G.main = bmain; + } + + if (C == nullptr) { + C = CTX_create(); + CTX_data_main_set(C, bmain); + } + } + + virtual void teardown() + { + if (bmain != nullptr) { + BKE_main_free(bmain); + bmain = nullptr; + G.main = nullptr; + } + + if (C != nullptr) { + CTX_free(C); + C = nullptr; + } + } +}; + +class SceneTestData : public TestData { + public: + Scene *scene = nullptr; + virtual void setup() + { + TestData::setup(); + scene = BKE_scene_add(bmain, "IDRemapScene"); + CTX_data_scene_set(C, scene); + } +}; + +class CompositorTestData : public SceneTestData { + public: + bNodeTree *compositor_nodetree = nullptr; + virtual void setup() + { + SceneTestData::setup(); + ED_node_composit_default(C, scene); + compositor_nodetree = scene->nodetree; + } +}; + +class MeshTestData : public TestData { + public: + Mesh *mesh = nullptr; + + void setup() override + { + TestData::setup(); + mesh = BKE_mesh_add(bmain, nullptr); + } +}; + +class TwoMeshesTestData : public MeshTestData { + public: + Mesh *other_mesh = nullptr; + + void setup() override + { + MeshTestData::setup(); + other_mesh = BKE_mesh_add(bmain, nullptr); + } +}; + +class MeshObjectTestData : public MeshTestData { + public: + Object *object; + void setup() override + { + MeshTestData::setup(); + + object = BKE_object_add_only_object(bmain, OB_MESH, nullptr); + object->data = mesh; + } +}; + +template<typename TestData> class Context { + public: + TestData test_data; + Context() { CLG_init(); @@ -59,77 +150,220 @@ struct Context { BKE_appdir_init(); IMB_init(); - bmain = BKE_main_new(); - /* TODO(jbakker): node_composit_poll_rlayers uses G.main directly. Should be refactored. */ - G.main = bmain; - C = CTX_create(); - CTX_data_main_set(C, bmain); - init_test_data(); + test_data.setup(); } ~Context() { - BKE_main_free(bmain); - CTX_free(C); - G.main = nullptr; - bmain = nullptr; - C = nullptr; - scene = nullptr; + test_data.teardown(); + BKE_node_system_exit(); RNA_exit(); IMB_exit(); BKE_appdir_exit(); CLG_exit(); } - - void init_test_data() - { - add_scene(); - add_composite(); - } - - void add_scene() - { - scene = BKE_scene_add(bmain, "IDRemapScene"); - CTX_data_scene_set(C, scene); - } - - void add_composite() - { - ED_node_composit_default(C, scene); - composite_nodetree = scene->nodetree; - } }; +/* -------------------------------------------------------------------- */ +/** \name Embedded IDs + * \{ */ + TEST(lib_remap, embedded_ids_can_not_be_remapped) { - Context context; + Context<CompositorTestData> context; bNodeTree *other_tree = static_cast<bNodeTree *>(BKE_id_new_nomain(ID_NT, nullptr)); - EXPECT_NE(context.scene, nullptr); - EXPECT_NE(context.composite_nodetree, nullptr); - EXPECT_EQ(context.composite_nodetree, context.scene->nodetree); + EXPECT_NE(context.test_data.scene, nullptr); + EXPECT_NE(context.test_data.compositor_nodetree, nullptr); + EXPECT_EQ(context.test_data.compositor_nodetree, context.test_data.scene->nodetree); - BKE_libblock_remap(context.bmain, context.composite_nodetree, other_tree, 0); + BKE_libblock_remap( + context.test_data.bmain, context.test_data.compositor_nodetree, other_tree, 0); - EXPECT_EQ(context.composite_nodetree, context.scene->nodetree); - EXPECT_NE(context.scene->nodetree, other_tree); + EXPECT_EQ(context.test_data.compositor_nodetree, context.test_data.scene->nodetree); + EXPECT_NE(context.test_data.scene->nodetree, other_tree); BKE_id_free(nullptr, other_tree); } TEST(lib_remap, embedded_ids_can_not_be_deleted) { - Context context; + Context<CompositorTestData> context; - EXPECT_NE(context.scene, nullptr); - EXPECT_NE(context.composite_nodetree, nullptr); - EXPECT_EQ(context.composite_nodetree, context.scene->nodetree); + EXPECT_NE(context.test_data.scene, nullptr); + EXPECT_NE(context.test_data.compositor_nodetree, nullptr); + EXPECT_EQ(context.test_data.compositor_nodetree, context.test_data.scene->nodetree); - BKE_libblock_remap(context.bmain, context.composite_nodetree, nullptr, 0); + BKE_libblock_remap(context.test_data.bmain, + context.test_data.compositor_nodetree, + nullptr, + ID_REMAP_SKIP_NEVER_NULL_USAGE); - EXPECT_EQ(context.composite_nodetree, context.scene->nodetree); - EXPECT_NE(context.scene->nodetree, nullptr); + EXPECT_EQ(context.test_data.compositor_nodetree, context.test_data.scene->nodetree); + EXPECT_NE(context.test_data.scene->nodetree, nullptr); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Remap to self + * \{ */ + +TEST(lib_remap, delete_when_remap_to_self_not_allowed) +{ + Context<TwoMeshesTestData> context; + + EXPECT_NE(context.test_data.mesh, nullptr); + EXPECT_NE(context.test_data.other_mesh, nullptr); + context.test_data.mesh->texcomesh = context.test_data.other_mesh; + + BKE_libblock_remap( + context.test_data.bmain, context.test_data.other_mesh, context.test_data.mesh, 0); + + EXPECT_EQ(context.test_data.mesh->texcomesh, nullptr); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Userref counting + * \{ */ + +TEST(lib_remap, users_are_decreased_when_not_skipping_never_null) +{ + Context<MeshObjectTestData> context; + + EXPECT_NE(context.test_data.object, nullptr); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); + EXPECT_EQ(context.test_data.mesh->id.us, 1); + + /* This is an invalid situation, test case tests this in between value until we have a better + * solution. */ + BKE_libblock_remap(context.test_data.bmain, context.test_data.mesh, nullptr, 0); + EXPECT_EQ(context.test_data.mesh->id.us, 0); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_NE(context.test_data.object->data, nullptr); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); +} + +TEST(lib_remap, users_are_same_when_skipping_never_null) +{ + Context<MeshObjectTestData> context; + + EXPECT_NE(context.test_data.object, nullptr); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); + EXPECT_EQ(context.test_data.mesh->id.us, 1); + + BKE_libblock_remap( + context.test_data.bmain, context.test_data.mesh, nullptr, ID_REMAP_SKIP_NEVER_NULL_USAGE); + EXPECT_EQ(context.test_data.mesh->id.us, 1); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_NE(context.test_data.object->data, nullptr); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Never Null + * \{ */ + +TEST(lib_remap, do_not_delete_when_cannot_unset) +{ + Context<MeshObjectTestData> context; + + EXPECT_NE(context.test_data.object, nullptr); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + + BKE_libblock_remap( + context.test_data.bmain, context.test_data.mesh, nullptr, ID_REMAP_SKIP_NEVER_NULL_USAGE); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_NE(context.test_data.object->data, nullptr); +} + +TEST(lib_remap, force_never_null_usage) +{ + Context<MeshObjectTestData> context; + + EXPECT_NE(context.test_data.object, nullptr); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + + BKE_libblock_remap( + context.test_data.bmain, context.test_data.mesh, nullptr, ID_REMAP_FORCE_NEVER_NULL_USAGE); + EXPECT_EQ(context.test_data.object->data, nullptr); +} + +TEST(lib_remap, never_null_usage_flag_not_requested_on_delete) +{ + Context<MeshObjectTestData> context; + + EXPECT_NE(context.test_data.object, nullptr); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); + + /* Never null usage isn't requested so the flag should not be set.*/ + BKE_libblock_remap( + context.test_data.bmain, context.test_data.mesh, nullptr, ID_REMAP_SKIP_NEVER_NULL_USAGE); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_NE(context.test_data.object->data, nullptr); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); +} + +TEST(lib_remap, never_null_usage_flag_requested_on_delete) +{ + Context<MeshObjectTestData> context; + + EXPECT_NE(context.test_data.object, nullptr); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); + + /* Never null usage is requested so the flag should be set. */ + BKE_libblock_remap(context.test_data.bmain, + context.test_data.mesh, + nullptr, + ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_FLAG_NEVER_NULL_USAGE); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_NE(context.test_data.object->data, nullptr); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, LIB_TAG_DOIT); +} + +TEST(lib_remap, never_null_usage_flag_not_requested_on_remap) +{ + Context<MeshObjectTestData> context; + Mesh *other_mesh = BKE_mesh_add(context.test_data.bmain, nullptr); + + EXPECT_NE(context.test_data.object, nullptr); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); + + /* Never null usage isn't requested so the flag should not be set.*/ + BKE_libblock_remap( + context.test_data.bmain, context.test_data.mesh, other_mesh, ID_REMAP_SKIP_NEVER_NULL_USAGE); + EXPECT_EQ(context.test_data.object->data, other_mesh); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); +} + +TEST(lib_remap, never_null_usage_flag_requested_on_remap) +{ + Context<MeshObjectTestData> context; + Mesh *other_mesh = BKE_mesh_add(context.test_data.bmain, nullptr); + + EXPECT_NE(context.test_data.object, nullptr); + EXPECT_EQ(context.test_data.object->data, context.test_data.mesh); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0); + + /* Never null usage is requested so the flag should be set. */ + BKE_libblock_remap(context.test_data.bmain, + context.test_data.mesh, + other_mesh, + ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_FLAG_NEVER_NULL_USAGE); + EXPECT_EQ(context.test_data.object->data, other_mesh); + EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, LIB_TAG_DOIT); +} + +/** \} */ + } // namespace blender::bke::tests |