Blender  V2.93
object_identifier_test.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2019 Blender Foundation.
17  * All rights reserved.
18  */
20 
21 #include "testing/testing.h"
22 
23 #include "BLI_utildefines.h"
24 
25 #include <climits>
26 
27 namespace blender::io {
28 
29 namespace {
30 
31 /* Return object pointer for use in tests. This makes it possible to reliably test for
32  * order/equality functions while using hard-coded values for simplicity. */
33 Object *fake_pointer(int value)
34 {
35  return static_cast<Object *>(POINTER_FROM_INT(value));
36 }
37 
38 /* PersistentID subclass for use in tests, making it easier to construct test values. */
39 class TestPersistentID : public PersistentID {
40  public:
41  TestPersistentID(int value0,
42  int value1,
43  int value2,
44  int value3,
45  int value4,
46  int value5,
47  int value6,
48  int value7)
49  {
50  persistent_id_[0] = value0;
51  persistent_id_[1] = value1;
52  persistent_id_[2] = value2;
53  persistent_id_[3] = value3;
54  persistent_id_[4] = value4;
55  persistent_id_[5] = value5;
56  persistent_id_[6] = value6;
57  persistent_id_[7] = value7;
58  }
59  TestPersistentID(int value0, int value1, int value2)
60  : TestPersistentID(value0, value1, value2, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX)
61  {
62  }
63  TestPersistentID(int value0, int value1) : TestPersistentID(value0, value1, INT_MAX)
64  {
65  }
66  explicit TestPersistentID(int value0) : TestPersistentID(value0, INT_MAX)
67  {
68  }
69 };
70 
71 /* ObjectIdentifier subclass for use in tests, making it easier to construct test values. */
72 class TestObjectIdentifier : public ObjectIdentifier {
73  public:
74  TestObjectIdentifier(Object *object, Object *duplicated_by, const PersistentID &persistent_id)
75  : ObjectIdentifier(object, duplicated_by, persistent_id)
76  {
77  }
78 };
79 
80 } // namespace
81 
82 class ObjectIdentifierOrderTest : public testing::Test {
83 };
84 
86 {
89  EXPECT_TRUE(id_root_1 == id_root_2);
90  EXPECT_FALSE(id_root_1 < id_root_2);
91  EXPECT_FALSE(id_root_2 < id_root_1);
92 
94  EXPECT_FALSE(id_root_1 == id_a);
95  EXPECT_TRUE(id_root_1 < id_a);
96  EXPECT_FALSE(id_a < id_root_1);
97 
98  ObjectIdentifier id_accidental_root = ObjectIdentifier::for_real_object(nullptr);
99  EXPECT_TRUE(id_root_1 == id_accidental_root);
100  EXPECT_FALSE(id_root_1 < id_accidental_root);
101  EXPECT_FALSE(id_accidental_root < id_root_1);
102 }
103 
105 {
106  ObjectIdentifier id_a = ObjectIdentifier::for_real_object(fake_pointer(1));
107  ObjectIdentifier id_b = ObjectIdentifier::for_real_object(fake_pointer(2));
108  EXPECT_FALSE(id_a == id_b);
109  EXPECT_TRUE(id_a < id_b);
110 }
111 
112 TEST_F(ObjectIdentifierOrderTest, duplicated_objects)
113 {
114  ObjectIdentifier id_real_a = ObjectIdentifier::for_real_object(fake_pointer(1));
115  TestObjectIdentifier id_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
116  TestObjectIdentifier id_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
117  TestObjectIdentifier id_different_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(1));
118 
119  EXPECT_FALSE(id_real_a == id_dupli_a);
120  EXPECT_FALSE(id_dupli_a == id_dupli_b);
121  EXPECT_TRUE(id_real_a < id_dupli_a);
122  EXPECT_TRUE(id_real_a < id_dupli_b);
123  EXPECT_TRUE(id_dupli_a < id_dupli_b);
124  EXPECT_TRUE(id_dupli_a < id_different_dupli_b);
125 
126  EXPECT_FALSE(id_dupli_b == id_different_dupli_b);
127  EXPECT_FALSE(id_dupli_a == id_different_dupli_b);
128  EXPECT_TRUE(id_dupli_b < id_different_dupli_b);
129  EXPECT_FALSE(id_different_dupli_b < id_dupli_b);
130 }
131 
132 TEST_F(ObjectIdentifierOrderTest, behavior_as_map_keys)
133 {
136  ObjectIdentifier id_real_a = ObjectIdentifier::for_real_object(fake_pointer(1));
137  TestObjectIdentifier id_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
138  TestObjectIdentifier id_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
140 
141  /* This inserts the keys with default values. */
142  graph[id_root];
143  graph[id_real_a];
144  graph[id_dupli_a];
145  graph[id_dupli_b];
146  graph[id_another_root];
147 
148  EXPECT_EQ(4, graph.size());
149 
150  graph.erase(id_another_root);
151  EXPECT_EQ(3, graph.size());
152 
153  TestObjectIdentifier id_another_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
154  graph.erase(id_another_dupli_b);
155  EXPECT_EQ(2, graph.size());
156 }
157 
158 TEST_F(ObjectIdentifierOrderTest, map_copy_and_update)
159 {
161  ObjectIdentifier id_real_a = ObjectIdentifier::for_real_object(fake_pointer(1));
162  TestObjectIdentifier id_dupli_a(fake_pointer(1), fake_pointer(2), TestPersistentID(0));
163  TestObjectIdentifier id_dupli_b(fake_pointer(1), fake_pointer(3), TestPersistentID(0));
164  TestObjectIdentifier id_dupli_c(fake_pointer(1), fake_pointer(3), TestPersistentID(1));
166 
167  /* This inserts the keys with default values. */
168  graph[id_root];
169  graph[id_real_a];
170  graph[id_dupli_a];
171  graph[id_dupli_b];
172  graph[id_dupli_c];
173  EXPECT_EQ(5, graph.size());
174 
176  EXPECT_EQ(5, graph_copy.size());
177 
178  /* Updating a value in a copy should not update the original. */
179  HierarchyContext ctx1;
180  HierarchyContext ctx2;
181  ctx1.object = fake_pointer(1);
182  ctx2.object = fake_pointer(2);
183 
184  graph_copy[id_root].insert(&ctx1);
185  EXPECT_EQ(0, graph[id_root].size());
186 
187  /* Deleting a key in the copy should not update the original. */
188  graph_copy.erase(id_dupli_c);
189  EXPECT_EQ(4, graph_copy.size());
190  EXPECT_EQ(5, graph.size());
191 }
192 
193 class PersistentIDTest : public testing::Test {
194 };
195 
196 TEST_F(PersistentIDTest, is_from_same_instancer)
197 {
198  PersistentID child_id_a = TestPersistentID(42, 327);
199  PersistentID child_id_b = TestPersistentID(17, 327);
200  PersistentID child_id_c = TestPersistentID(17);
201 
202  EXPECT_TRUE(child_id_a.is_from_same_instancer_as(child_id_b));
203  EXPECT_FALSE(child_id_a.is_from_same_instancer_as(child_id_c));
204 }
205 
206 TEST_F(PersistentIDTest, instancer_id)
207 {
208  PersistentID child_id = TestPersistentID(42, 327);
209 
210  PersistentID expect_instancer_id = TestPersistentID(327);
211  EXPECT_EQ(expect_instancer_id, child_id.instancer_pid());
212 
213  PersistentID empty_id;
214  EXPECT_EQ(empty_id, child_id.instancer_pid().instancer_pid());
215 
216  EXPECT_LT(child_id, expect_instancer_id);
217  EXPECT_LT(expect_instancer_id, empty_id);
218 }
219 
220 TEST_F(PersistentIDTest, as_object_name_suffix)
221 {
222  EXPECT_EQ("", PersistentID().as_object_name_suffix());
223  EXPECT_EQ("47", TestPersistentID(47).as_object_name_suffix());
224  EXPECT_EQ("327-47", TestPersistentID(47, 327).as_object_name_suffix());
225  EXPECT_EQ("42-327-47", TestPersistentID(47, 327, 42).as_object_name_suffix());
226 
227  EXPECT_EQ("7-6-5-4-3-2-1-0", TestPersistentID(0, 1, 2, 3, 4, 5, 6, 7).as_object_name_suffix());
228 
229  EXPECT_EQ("0-0-0", TestPersistentID(0, 0, 0).as_object_name_suffix());
230  EXPECT_EQ("0-0", TestPersistentID(0, 0).as_object_name_suffix());
231  EXPECT_EQ("-3--2--1", TestPersistentID(-1, -2, -3).as_object_name_suffix());
232 }
233 
234 } // namespace blender::io
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define POINTER_FROM_INT(i)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
std::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
Depsgraph * graph
TEST_F(AbstractHierarchyIteratorTest, ExportHierarchyTest)