Blender V5.0
object_identifier_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
5
6#include "testing/testing.h"
7
8#include "BLI_utildefines.h"
9
10#include <climits>
11
12namespace blender::io {
13
14namespace {
15
16/* Return object pointer for use in tests. This makes it possible to reliably test for
17 * order/equality functions while using hard-coded values for simplicity. */
18Object *fake_pointer(int value)
19{
20 return static_cast<Object *>(POINTER_FROM_INT(value));
21}
22
23/* PersistentID subclass for use in tests, making it easier to construct test values. */
24class TestPersistentID : public PersistentID {
25 public:
26 TestPersistentID(int value0,
27 int value1,
28 int value2,
29 int value3,
30 int value4,
31 int value5,
32 int value6,
33 int value7)
34 {
35 persistent_id_[0] = value0;
36 persistent_id_[1] = value1;
37 persistent_id_[2] = value2;
38 persistent_id_[3] = value3;
39 persistent_id_[4] = value4;
40 persistent_id_[5] = value5;
41 persistent_id_[6] = value6;
42 persistent_id_[7] = value7;
43 }
44 TestPersistentID(int value0, int value1, int value2)
45 : TestPersistentID(value0, value1, value2, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX)
46 {
47 }
48 TestPersistentID(int value0, int value1) : TestPersistentID(value0, value1, INT_MAX) {}
49 explicit TestPersistentID(int value0) : TestPersistentID(value0, INT_MAX) {}
50};
51
52/* ObjectIdentifier subclass for use in tests, making it easier to construct test values. */
53class TestObjectIdentifier : public ObjectIdentifier {
54 public:
55 TestObjectIdentifier(Object *object, Object *duplicated_by, const PersistentID &persistent_id)
56 : ObjectIdentifier(object, duplicated_by, persistent_id)
57 {
58 }
59};
60
61} // namespace
62
63class ObjectIdentifierOrderTest : public testing::Test {};
64
66{
69 EXPECT_TRUE(id_root_1 == id_root_2);
70 EXPECT_TRUE(id_root_1.hash() == id_root_2.hash());
71
73 EXPECT_FALSE(id_root_1 == id_a);
74
75 ObjectIdentifier id_accidental_root = ObjectIdentifier::for_real_object(nullptr);
76 EXPECT_TRUE(id_root_1 == id_accidental_root);
77 EXPECT_TRUE(id_root_1.hash() == id_accidental_root.hash());
78}
79
81{
84 EXPECT_FALSE(id_a == id_b);
85
87 EXPECT_TRUE(id_a == id_c);
88 EXPECT_TRUE(id_a.hash() == id_c.hash());
89}
90
92{
93 ObjectIdentifier id_real_a = ObjectIdentifier::for_real_object(fake_pointer(1));
94 TestObjectIdentifier id_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
95 TestObjectIdentifier id_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
96 TestObjectIdentifier id_same_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
97 TestObjectIdentifier id_different_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(1));
98
99 EXPECT_FALSE(id_real_a == id_dupli_a);
100 EXPECT_FALSE(id_dupli_a == id_dupli_b);
101
102 EXPECT_FALSE(id_dupli_b == id_different_dupli_b);
103 EXPECT_FALSE(id_dupli_a == id_different_dupli_b);
104
105 EXPECT_TRUE(id_dupli_a == id_same_dupli_a);
106 EXPECT_TRUE(id_dupli_a.hash() == id_same_dupli_a.hash());
107}
108
109TEST_F(ObjectIdentifierOrderTest, behavior_as_map_keys)
110{
113 ObjectIdentifier id_real_a = ObjectIdentifier::for_real_object(fake_pointer(1));
114 TestObjectIdentifier id_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
115 TestObjectIdentifier id_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
117
118 /* This inserts the keys with default values. */
119 graph.add_new(id_root, {});
120 graph.add_new(id_real_a, {});
121 graph.add_new(id_dupli_a, {});
122 graph.add_new(id_dupli_b, {});
123 graph.add(id_another_root, {});
124
125 EXPECT_EQ(4, graph.size());
126
127 graph.remove_contained(id_another_root);
128 EXPECT_EQ(3, graph.size());
129
130 TestObjectIdentifier id_another_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
131 graph.remove_contained(id_another_dupli_b);
132 EXPECT_EQ(2, graph.size());
133}
134
136{
138 ObjectIdentifier id_real_a = ObjectIdentifier::for_real_object(fake_pointer(1));
139 TestObjectIdentifier id_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
140 TestObjectIdentifier id_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
141 TestObjectIdentifier id_dupli_c(fake_pointer(1), fake_pointer(3), TestPersistentID(1));
143
144 /* This inserts the keys with default values. */
145 graph.add_new(id_root, {});
146 graph.add_new(id_real_a, {});
147 graph.add_new(id_dupli_a, {});
148 graph.add_new(id_dupli_b, {});
149 graph.add_new(id_dupli_c, {});
150 EXPECT_EQ(5, graph.size());
151
153 EXPECT_EQ(5, graph_copy.size());
154
155 /* Updating a value in a copy should not update the original. */
156 HierarchyContext ctx1;
157 HierarchyContext ctx2;
158 ctx1.object = fake_pointer(1);
159 ctx2.object = fake_pointer(2);
160
161 graph_copy.lookup(id_root).add_new(&ctx1);
162 EXPECT_EQ(0, graph.lookup(id_root).size());
163
164 /* Deleting a key in the copy should not update the original. */
165 graph_copy.remove_contained(id_dupli_c);
166 EXPECT_EQ(4, graph_copy.size());
167 EXPECT_EQ(5, graph.size());
168}
169
170class PersistentIDTest : public testing::Test {};
171
172TEST_F(PersistentIDTest, is_from_same_instancer)
173{
174 PersistentID child_id_a = TestPersistentID(42, 327);
175 PersistentID child_id_b = TestPersistentID(17, 327);
176 PersistentID child_id_c = TestPersistentID(17);
177
178 EXPECT_TRUE(child_id_a.is_from_same_instancer_as(child_id_b));
179 EXPECT_FALSE(child_id_a.is_from_same_instancer_as(child_id_c));
180}
181
183{
184 PersistentID child_id = TestPersistentID(42, 327);
185
186 PersistentID expect_instancer_id = TestPersistentID(327);
187 EXPECT_EQ(expect_instancer_id, child_id.instancer_pid());
188 EXPECT_EQ(expect_instancer_id.hash(), child_id.instancer_pid().hash());
189
190 PersistentID empty_id;
191 EXPECT_EQ(empty_id, child_id.instancer_pid().instancer_pid());
192 EXPECT_EQ(empty_id.hash(), child_id.instancer_pid().instancer_pid().hash());
193}
194
195TEST_F(PersistentIDTest, as_object_name_suffix)
196{
197 EXPECT_EQ("", PersistentID().as_object_name_suffix());
198 EXPECT_EQ("47", TestPersistentID(47).as_object_name_suffix());
199 EXPECT_EQ("327-47", TestPersistentID(47, 327).as_object_name_suffix());
200 EXPECT_EQ("42-327-47", TestPersistentID(47, 327, 42).as_object_name_suffix());
201
202 EXPECT_EQ("7-6-5-4-3-2-1-0", TestPersistentID(0, 1, 2, 3, 4, 5, 6, 7).as_object_name_suffix());
203
204 EXPECT_EQ("0-0-0", TestPersistentID(0, 0, 0).as_object_name_suffix());
205 EXPECT_EQ("0-0", TestPersistentID(0, 0).as_object_name_suffix());
206 EXPECT_EQ("-3--2--1", TestPersistentID(-1, -2, -3).as_object_name_suffix());
207}
208
209} // namespace blender::io
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define POINTER_FROM_INT(i)
struct Object Object
bool add(const Key &key, const Value &value)
Definition BLI_map.hh:295
const Value & lookup(const Key &key) const
Definition BLI_map.hh:545
void remove_contained(const Key &key)
Definition BLI_map.hh:387
void add_new(const Key &key, const Value &value)
Definition BLI_map.hh:265
int64_t size() const
Definition BLI_map.hh:976
blender::Map< ObjectIdentifier, ExportChildren > ExportGraph
static ObjectIdentifier for_graph_root()
static ObjectIdentifier for_real_object(Object *object)
PersistentID instancer_pid() const
bool is_from_same_instancer_as(const PersistentID &other) const
TEST_F(AbstractHierarchyIteratorTest, ExportHierarchyTest)