Compare commits
6 Commits
temp-T9593
...
tmp-core-i
Author | SHA1 | Date | |
---|---|---|---|
1eccb4fcbd | |||
46162902eb | |||
88a9a851d8 | |||
91abc0fdf6 | |||
4d927c4533 | |||
481c47ef47 |
@@ -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
|
||||
|
369
source/blender/blenkernel/intern/lib_remap_test.cc
Normal file
369
source/blender/blenkernel/intern/lib_remap_test.cc
Normal file
@@ -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;
|
||||
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();
|
||||
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.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
|
Reference in New Issue
Block a user