Blender  V3.3
lib_id_test.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2020 Blender Foundation. */
3 #include "testing/testing.h"
4 
5 #include "MEM_guardedalloc.h"
6 
7 #include "BLI_listbase.h"
8 #include "BLI_string.h"
9 
10 #include "BKE_idtype.h"
11 #include "BKE_lib_id.h"
12 #include "BKE_main.h"
13 #include "BKE_main_namemap.h"
14 
15 #include "DNA_ID.h"
16 #include "DNA_mesh_types.h"
17 #include "DNA_object_types.h"
18 
19 namespace blender::bke::tests {
20 
22  Main *bmain = nullptr;
23 
25  {
27  bmain = BKE_main_new();
28  }
30  {
32  }
33 };
34 
35 static void test_lib_id_main_sort_check_order(std::initializer_list<ID *> list)
36 {
37  ID *prev_id = nullptr;
38  for (ID *id : list) {
39  EXPECT_EQ(id->prev, prev_id);
40  if (prev_id != nullptr) {
41  EXPECT_EQ(prev_id->next, id);
42  }
43  prev_id = id;
44  }
45  EXPECT_EQ(prev_id->next, nullptr);
46 }
47 
48 TEST(lib_id_main_sort, local_ids_1)
49 {
51  EXPECT_TRUE(BLI_listbase_is_empty(&ctx.bmain->libraries));
52 
53  ID *id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_C"));
54  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_A"));
55  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_B"));
56  EXPECT_TRUE(ctx.bmain->objects.first == id_a);
57  EXPECT_TRUE(ctx.bmain->objects.last == id_c);
58  test_lib_id_main_sort_check_order({id_a, id_b, id_c});
59 }
60 
61 static void change_lib(Main *bmain, ID *id, Library *lib)
62 {
63  if (id->lib == lib) {
64  return;
65  }
66  BKE_main_namemap_remove_name(bmain, id, id->name + 2);
67  id->lib = lib;
68  BKE_main_namemap_get_name(bmain, id, id->name + 2);
69 }
70 
71 static void change_name(Main *bmain, ID *id, const char *name)
72 {
73  BKE_main_namemap_remove_name(bmain, id, id->name + 2);
74  BLI_strncpy(id->name + 2, name, MAX_NAME);
75  BKE_id_new_name_validate(bmain, &bmain->objects, id, nullptr, true);
76 }
77 
78 TEST(lib_id_main_sort, linked_ids_1)
79 {
81  EXPECT_TRUE(BLI_listbase_is_empty(&ctx.bmain->libraries));
82 
83  Library *lib_a = static_cast<Library *>(BKE_id_new(ctx.bmain, ID_LI, "LI_A"));
84  Library *lib_b = static_cast<Library *>(BKE_id_new(ctx.bmain, ID_LI, "LI_B"));
85  ID *id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_C"));
86  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_A"));
87  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_B"));
88 
89  change_lib(ctx.bmain, id_a, lib_a);
90  id_sort_by_name(&ctx.bmain->objects, id_a, nullptr);
91  change_lib(ctx.bmain, id_b, lib_a);
92  id_sort_by_name(&ctx.bmain->objects, id_b, nullptr);
93  EXPECT_TRUE(ctx.bmain->objects.first == id_c);
94  EXPECT_TRUE(ctx.bmain->objects.last == id_b);
95  test_lib_id_main_sort_check_order({id_c, id_a, id_b});
96 
97  change_lib(ctx.bmain, id_a, lib_b);
98  id_sort_by_name(&ctx.bmain->objects, id_a, nullptr);
99  EXPECT_TRUE(ctx.bmain->objects.first == id_c);
100  EXPECT_TRUE(ctx.bmain->objects.last == id_a);
101  test_lib_id_main_sort_check_order({id_c, id_b, id_a});
102 
103  change_lib(ctx.bmain, id_b, lib_b);
104  id_sort_by_name(&ctx.bmain->objects, id_b, nullptr);
105  EXPECT_TRUE(ctx.bmain->objects.first == id_c);
106  EXPECT_TRUE(ctx.bmain->objects.last == id_b);
107  test_lib_id_main_sort_check_order({id_c, id_a, id_b});
108 
109  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
110 }
111 
112 TEST(lib_id_main_unique_name, local_ids_1)
113 {
115  EXPECT_TRUE(BLI_listbase_is_empty(&ctx.bmain->libraries));
116 
117  ID *id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_C"));
118  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_A"));
119  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_B"));
120  test_lib_id_main_sort_check_order({id_a, id_b, id_c});
121 
122  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
123 
124  change_name(ctx.bmain, id_c, "OB_A");
125 
126  EXPECT_STREQ(id_c->name + 2, "OB_A.001");
127  EXPECT_STREQ(id_a->name + 2, "OB_A");
128  EXPECT_TRUE(ctx.bmain->objects.first == id_a);
129  EXPECT_TRUE(ctx.bmain->objects.last == id_b);
130  test_lib_id_main_sort_check_order({id_a, id_c, id_b});
131 
132  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
133 }
134 
135 TEST(lib_id_main_unique_name, linked_ids_1)
136 {
138  EXPECT_TRUE(BLI_listbase_is_empty(&ctx.bmain->libraries));
139 
140  Library *lib_a = static_cast<Library *>(BKE_id_new(ctx.bmain, ID_LI, "LI_A"));
141  Library *lib_b = static_cast<Library *>(BKE_id_new(ctx.bmain, ID_LI, "LI_B"));
142  ID *id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_C"));
143  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_A"));
144  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "OB_B"));
145 
146  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
147 
148  change_lib(ctx.bmain, id_a, lib_a);
149  id_sort_by_name(&ctx.bmain->objects, id_a, nullptr);
150  change_lib(ctx.bmain, id_b, lib_a);
151  id_sort_by_name(&ctx.bmain->objects, id_b, nullptr);
152 
153  change_name(ctx.bmain, id_b, "OB_A");
154  EXPECT_STREQ(id_b->name + 2, "OB_A.001");
155  EXPECT_STREQ(id_a->name + 2, "OB_A");
156  EXPECT_TRUE(ctx.bmain->objects.first == id_c);
157  EXPECT_TRUE(ctx.bmain->objects.last == id_b);
158  test_lib_id_main_sort_check_order({id_c, id_a, id_b});
159 
160  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
161 
162  change_lib(ctx.bmain, id_b, lib_b);
163  id_sort_by_name(&ctx.bmain->objects, id_b, nullptr);
164  change_name(ctx.bmain, id_b, "OB_A");
165  EXPECT_STREQ(id_b->name + 2, "OB_A");
166  EXPECT_STREQ(id_a->name + 2, "OB_A");
167  EXPECT_TRUE(ctx.bmain->objects.first == id_c);
168  EXPECT_TRUE(ctx.bmain->objects.last == id_b);
169  test_lib_id_main_sort_check_order({id_c, id_a, id_b});
170 
171  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
172 }
173 
174 TEST(lib_id_main_unique_name, ids_sorted_by_default)
175 {
177 
178  ID *id_foo = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
179  ID *id_bar = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Bar"));
180  ID *id_baz = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Baz"));
181  ID *id_yes = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Yes"));
182  test_lib_id_main_sort_check_order({id_bar, id_baz, id_foo, id_yes});
183 
184  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
185 }
186 
187 static ID *add_id_in_library(Main *bmain, const char *name, Library *lib)
188 {
189  ID *id = static_cast<ID *>(BKE_id_new(bmain, ID_OB, name));
190  change_lib(bmain, id, lib);
191  id_sort_by_name(&bmain->objects, id, nullptr);
192  return id;
193 }
194 
195 TEST(lib_id_main_unique_name, ids_sorted_by_default_with_libraries)
196 {
198 
199  Library *lib_one = static_cast<Library *>(BKE_id_new(ctx.bmain, ID_LI, "LibOne"));
200  Library *lib_two = static_cast<Library *>(BKE_id_new(ctx.bmain, ID_LI, "LibTwo"));
201 
202  ID *id_foo = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
203  ID *id_bar = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Bar"));
204 
205  ID *id_l1c = add_id_in_library(ctx.bmain, "C", lib_one);
206  ID *id_l2b = add_id_in_library(ctx.bmain, "B", lib_two);
207  ID *id_l1a = add_id_in_library(ctx.bmain, "A", lib_one);
208 
209  ID *id_baz = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Baz"));
210  ID *id_yes = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Yes"));
211 
212  test_lib_id_main_sort_check_order({id_bar, id_baz, id_foo, id_yes, id_l1a, id_l1c, id_l2b});
213 
214  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
215 }
216 
217 TEST(lib_id_main_unique_name, name_too_long_handling)
218 {
220  const char *name_a = "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_Truncated";
221  const char *name_b = "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123456";
222  const char *name_c = "Name_That_Has_Too_Long_Number_Suffix.1234567890";
223 
224  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, name_a));
225  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, name_b));
226  ID *id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, name_c));
227 
228  EXPECT_STREQ(id_a->name + 2, "Long_Name_That_Does_Not_Fit_Into_Max_Name_Limit_And_Should_Get_");
229  EXPECT_STREQ(id_b->name + 2, "Another_Long_Name_That_Does_Not_Fit_And_Has_A_Number_Suffix.123");
230  EXPECT_STREQ(id_c->name + 2, "Name_That_Has_Too_Long_Number_Suffix.1234567890"); /* Unchanged */
231 
232  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
233 }
234 
235 TEST(lib_id_main_unique_name, create_equivalent_numeric_suffixes)
236 {
238 
239  /* Create names where many of their numeric suffixes are
240  * the same number, yet the names are different and thus
241  * should be allowed as-is. */
242  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.123"));
243  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.000"));
244  ID *id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.003"));
245  ID *id_d = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.3"));
246  ID *id_e = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.0"));
247  ID *id_f = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo."));
248  ID *id_g = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.0123"));
249  ID *id_h = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
250  ID *id_i = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.."));
251  ID *id_j = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo..001"));
252  ID *id_k = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo..000"));
253 
254  EXPECT_STREQ(id_a->name + 2, "Foo.123");
255  EXPECT_STREQ(id_b->name + 2, "Foo.000");
256  EXPECT_STREQ(id_c->name + 2, "Foo.003");
257  EXPECT_STREQ(id_d->name + 2, "Foo.3");
258  EXPECT_STREQ(id_e->name + 2, "Foo.0");
259  EXPECT_STREQ(id_f->name + 2, "Foo.");
260  EXPECT_STREQ(id_g->name + 2, "Foo.0123");
261  EXPECT_STREQ(id_h->name + 2, "Foo");
262  EXPECT_STREQ(id_i->name + 2, "Foo..");
263  EXPECT_STREQ(id_j->name + 2, "Foo..001");
264  EXPECT_STREQ(id_k->name + 2, "Foo..000");
265 
266  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
267 
268  /* Now create their exact duplicates again, and check what happens. */
269  id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.123"));
270  id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.000"));
271  id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.003"));
272  id_d = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.3"));
273  id_e = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.0"));
274  id_f = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo."));
275  id_g = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.0123"));
276  id_h = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
277  id_i = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.."));
278  id_j = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo..001"));
279  id_k = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo..000"));
280 
281  EXPECT_STREQ(id_a->name + 2, "Foo.001");
282  EXPECT_STREQ(id_b->name + 2, "Foo.002");
283  EXPECT_STREQ(id_c->name + 2, "Foo.004");
284  EXPECT_STREQ(id_d->name + 2, "Foo.005");
285  EXPECT_STREQ(id_e->name + 2, "Foo.006");
286  EXPECT_STREQ(id_f->name + 2, "Foo..002");
287  EXPECT_STREQ(id_g->name + 2, "Foo.007");
288  EXPECT_STREQ(id_h->name + 2, "Foo.008");
289  EXPECT_STREQ(id_i->name + 2, "Foo...001");
290  EXPECT_STREQ(id_j->name + 2, "Foo..003");
291  EXPECT_STREQ(id_k->name + 2, "Foo..004");
292 
293  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
294 }
295 
296 TEST(lib_id_main_unique_name, zero_suffix_is_never_assigned)
297 {
299 
300  /* Creating these should assign 002 to the first one, but the next
301  * ones should start numbers starting from 1: 001 and 003. */
302  ID *id_002 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.002"));
303  ID *id_001 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.002"));
304  ID *id_003 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.002"));
305 
306  EXPECT_STREQ(id_002->name + 2, "Foo.002");
307  EXPECT_STREQ(id_001->name + 2, "Foo.001");
308  EXPECT_STREQ(id_003->name + 2, "Foo.003");
309 
310  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
311 }
312 
313 TEST(lib_id_main_unique_name, remove_after_dup_get_original_name)
314 {
316 
317  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
318  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
319 
320  EXPECT_STREQ(id_a->name + 2, "Foo");
321  EXPECT_STREQ(id_b->name + 2, "Foo.001");
322  BKE_id_free(ctx.bmain, id_a);
323 
324  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
325 
326  id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
327  EXPECT_STREQ(id_a->name + 2, "Foo");
328 
329  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
330 }
331 
332 TEST(lib_id_main_unique_name, name_number_suffix_assignment)
333 {
335 
336  /* Create <1k objects first. */
337  const int total_object_count = 1200;
338  ID *ids[total_object_count] = {};
339  for (int i = 0; i < total_object_count / 2; ++i) {
340  ids[i] = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
341  }
342 
343  /* They should get assigned sequential numeric suffixes. */
344  EXPECT_STREQ(ids[0]->name + 2, "Foo");
345  EXPECT_STREQ(ids[1]->name + 2, "Foo.001");
346  EXPECT_STREQ(ids[total_object_count / 2 - 1]->name + 2, "Foo.599");
347 
348  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
349 
350  /* Free some of the objects. */
351  BKE_id_free(ctx.bmain, ids[10]);
352  BKE_id_free(ctx.bmain, ids[20]);
353  BKE_id_free(ctx.bmain, ids[30]);
354 
355  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
356 
357  /* Create objects again; they should get suffixes that were just free'd up. */
358  ID *id_010 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
359  EXPECT_STREQ(id_010->name + 2, "Foo.010");
360  ID *id_020 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.123"));
361  EXPECT_STREQ(id_020->name + 2, "Foo.020");
362  /* Suffixes >1k do not get the "use the most proper free one" treatment. */
363  ID *id_2000 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.2000"));
364  EXPECT_STREQ(id_2000->name + 2, "Foo.2000");
365  /* But smaller than 1k suffixes do get proper empty spots. */
366  ID *id_030 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
367  EXPECT_STREQ(id_030->name + 2, "Foo.030");
368  ID *id_600 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
369  EXPECT_STREQ(id_600->name + 2, "Foo.600");
370 
371  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
372 
373  /* Max possible numeric suffix. */
374  ID *id_max = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.999999999"));
375  EXPECT_STREQ(id_max->name + 2, "Foo.999999999");
376  /* Try with max. possible suffix again: will assign free suffix under 1k. */
377  ID *id_max1 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.999999999"));
378  EXPECT_STREQ(id_max1->name + 2, "Foo.601");
379 
380  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
381 
382  /* Now create the rest of objects, to use all the suffixes up to 1k.
383  * Once all the ones up to 1k are used, the logic will fall back to
384  * "use largest number seen + 1", but the largest one is already the max
385  * possible. So it will shorten the name part and restart the counter,
386  * i.e. "Fo.001". */
387  for (int i = total_object_count / 2; i < total_object_count; ++i) {
388  ids[i] = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
389  }
390  /* At this point creating "Foo" based objects will fall always
391  * result in shortened name to "Fo". */
392  ID *id_fo178 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
393  EXPECT_STREQ(id_fo178->name + 2, "Fo.178");
394  ID *id_fo179 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.2000"));
395  EXPECT_STREQ(id_fo179->name + 2, "Fo.179");
396  ID *id_fo180 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.999999999"));
397  EXPECT_STREQ(id_fo180->name + 2, "Fo.180");
398 
399  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
400 }
401 
402 TEST(lib_id_main_unique_name, renames_with_duplicates)
403 {
405 
406  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
407  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
408  ID *id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Bar"));
409 
410  EXPECT_STREQ(id_a->name + 2, "Foo");
411  EXPECT_STREQ(id_b->name + 2, "Foo.001");
412  EXPECT_STREQ(id_c->name + 2, "Bar");
413 
414  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
415 
416  BKE_libblock_rename(ctx.bmain, id_a, "Foo.002");
417  EXPECT_STREQ(id_a->name + 2, "Foo.002");
418  BKE_libblock_rename(ctx.bmain, id_b, "Bar");
419  EXPECT_STREQ(id_b->name + 2, "Bar.001");
420  BKE_libblock_rename(ctx.bmain, id_c, "Foo");
421  EXPECT_STREQ(id_c->name + 2, "Foo");
422  BKE_libblock_rename(ctx.bmain, id_b, "Bar");
423  EXPECT_STREQ(id_b->name + 2, "Bar");
424 
425  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
426 }
427 
428 TEST(lib_id_main_unique_name, names_are_unique_per_id_type)
429 {
431 
432  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
433  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_CA, "Foo"));
434  ID *id_c = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
435 
436  EXPECT_STREQ(id_a->name + 2, "Foo");
437  EXPECT_STREQ(id_b->name + 2, "Foo"); /* Different types (OB & CA) can have the same name. */
438  EXPECT_STREQ(id_c->name + 2, "Foo.001");
439 
440  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
441 }
442 
443 TEST(lib_id_main_unique_name, name_huge_number_suffix)
444 {
446 
447  /* Use numeric suffix that is really large: should come through
448  * fine, since no duplicates with other names. */
449  ID *id_a = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "SuperLong.1234567890"));
450  EXPECT_STREQ(id_a->name + 2, "SuperLong.1234567890");
451  /* Now create with the same name again: should get 001 suffix. */
452  ID *id_b = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "SuperLong.1234567890"));
453  EXPECT_STREQ(id_b->name + 2, "SuperLong.001");
454 
455  EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
456 }
457 
458 } // namespace blender::bke::tests
void BKE_idtype_init(void)
Definition: idtype.c:106
void BKE_libblock_rename(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL()
Definition: lib_id.c:1832
bool BKE_id_new_name_validate(struct Main *bmain, struct ListBase *lb, struct ID *id, const char *name, bool do_linked_data) ATTR_NONNULL(1
void BKE_id_free(struct Main *bmain, void *idv)
void * BKE_id_new(struct Main *bmain, short type, const char *name)
Definition: lib_id.c:1159
void id_sort_by_name(struct ListBase *lb, struct ID *id, struct ID *id_sorting_hint)
Definition: lib_id.c:1318
struct Main * BKE_main_new(void)
Definition: main.c:32
void BKE_main_free(struct Main *mainvar)
Definition: main.c:40
void BKE_main_namemap_remove_name(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL()
bool BKE_main_namemap_validate(struct Main *bmain) ATTR_NONNULL()
bool BKE_main_namemap_get_name(struct Main *bmain, struct ID *id, char *name) ATTR_NONNULL()
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
ID and Library types, which are fundamental for sdna.
@ ID_CA
Definition: DNA_ID_enums.h:56
@ ID_LI
Definition: DNA_ID_enums.h:46
@ ID_OB
Definition: DNA_ID_enums.h:47
#define MAX_NAME
Definition: DNA_defs.h:48
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
DRWShaderLibrary * lib
static void change_name(Main *bmain, ID *id, const char *name)
Definition: lib_id_test.cc:71
static void change_lib(Main *bmain, ID *id, Library *lib)
Definition: lib_id_test.cc:61
static ID * add_id_in_library(Main *bmain, const char *name, Library *lib)
Definition: lib_id_test.cc:187
TEST(action_groups, ReconstructGroupsWithReordering)
Definition: action_test.cc:17
static void test_lib_id_main_sort_check_order(std::initializer_list< ID * > list)
Definition: lib_id_test.cc:35
Definition: DNA_ID.h:368
struct Library * lib
Definition: DNA_ID.h:372
void * prev
Definition: DNA_ID.h:369
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase libraries
Definition: BKE_main.h:169
ListBase objects
Definition: BKE_main.h:170