Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/lib_remap_test.cc')
-rw-r--r--source/blender/blenkernel/intern/lib_remap_test.cc328
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