[Bf-blender-cvs] [04feaa8bd05] master: Core: Library Remap test cases.

Jeroen Bakker noreply at git.blender.org
Mon Jan 17 12:46:02 CET 2022


Commit: 04feaa8bd0569a5453bec7a282f3f4a593eeb6ff
Author: Jeroen Bakker
Date:   Mon Jan 17 12:44:55 2022 +0100
Branches: master
https://developer.blender.org/rB04feaa8bd0569a5453bec7a282f3f4a593eeb6ff

Core: Library Remap test cases.

For an upcoming refactoring of library remapping we want to be able to test if the logic won't change.
It also increased my experience inside the remapping codebase and find out what exactly needed to
be refactored.

This patch adds test cases for the core functionality of `foreach_libblock_remap_callback`. The test cases
don't cover of all the branches. Also pre-, post-processing, referencing and proxies are not tested.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D13815

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

M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/lib_remap_test.cc

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

diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 4449a1bce62..7f8a917e002 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -819,6 +819,7 @@ if(WITH_GTESTS)
     intern/lattice_deform_test.cc
     intern/layer_test.cc
     intern/lib_id_test.cc
+    intern/lib_remap_test.cc
     intern/tracking_test.cc
   )
   set(TEST_INC
diff --git a/source/blender/blenkernel/intern/lib_remap_test.cc b/source/blender/blenkernel/intern/lib_remap_test.cc
new file mode 100644
index 00000000000..f803e600787
--- /dev/null
+++ b/source/blender/blenkernel/intern/lib_remap_test.cc
@@ -0,0 +1,369 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2022 by Blender Foundation.
+ */
+#include "testing/testing.h"
+
+#include "BLI_utildefines.h"
+
+#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"
+
+#include "BKE_appdir.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_idtype.h"
+#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"
+
+#include "ED_node.h"
+
+#include "MEM_guardedalloc.h"
+
+namespace blender::bke::tests {
+
+class TestData {
+ public:
+  Main *bmain = 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;
+  void setup() override
+  {
+    TestData::setup();
+    scene = BKE_scene_add(bmain, "IDRemapScene");
+    CTX_data_scene_set(C, scene);
+  }
+};
+
+class CompositorTestData : public SceneTestData {
+ public:
+  bNodeTree *compositor_nodetree = nullptr;
+  void setup() override
+  {
+    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();
+    BKE_idtype_init();
+    RNA_init();
+    BKE_node_system_init();
+    BKE_appdir_init();
+    IMB_init();
+
+    test_data.setup();
+  }
+
+  ~Context()
+  {
+    test_data.teardown();
+
+    BKE_node_system_exit();
+    RNA_exit();
+    IMB_exit();
+    BKE_appdir_exit();
+    CLG_exit();
+  }
+};
+
+/* -------------------------------------------------------------------- */
+/** \name Embedded IDs
+ * \{ */
+
+TEST(lib_remap, embedded_ids_can_not_be_remapped)
+{
+  Context<CompositorTestData> context;
+  bNodeTree *other_tree = static_cast<bNodeTree *>(BKE_id_new_nomain(ID_NT, nullptr));
+
+  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.test_data.bmain, context.test_data.compositor_nodetree, other_tree, 0);
+
+  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<CompositorTestData> context;
+
+  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.test_data.bmain,
+                     context.test_data.compositor_nodetree,
+                     nullptr,
+                     ID_REMAP_SKIP_NEVER_NULL_USAGE);
+
+  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.

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list