Blender V5.0
asset_representation_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
7
9
10#include "BKE_lib_id.hh"
11#include "BKE_main.hh"
12
13#include "DNA_asset_types.h"
14#include "DNA_object_types.h"
15
17
18#include "BLI_string.h"
19
20#include "../intern/utils.hh"
21
22#include "testing/testing.h"
23
25
31 public:
33 {
35
37 ref.type = type;
38 return service->get_asset_library(nullptr, ref);
39 }
40
42 {
43 std::unique_ptr<AssetMetaData> dummy_metadata = std::make_unique<AssetMetaData>();
44 return *library
45 .add_external_asset(relative_path, "Some asset name", 0, std::move(dummy_metadata))
46 .lock();
47 }
48
50 {
51 /* Ensure ID is marked as asset (no-op if already marked). */
53
54 return *library.add_local_id_asset(id).lock();
55 }
56};
57
58TEST_F(AssetRepresentationTest, library_relative_identifier__id_name_change)
59{
60 Main *bmain = BKE_main_new();
61 Object *object = BKE_id_new<Object>(bmain, "Before rename");
62
63 AssetLibrary *library = get_builtin_library_from_type(ASSET_LIBRARY_LOCAL);
64
65 AssetRepresentation &asset = add_dummy_id_asset(*library, object->id);
66
67 EXPECT_EQ(asset.library_relative_identifier(), "Object" SEP_STR "Before rename");
68
69 BKE_id_rename(*bmain, object->id, "Renamed!");
70 EXPECT_EQ(asset.library_relative_identifier(), "Object" SEP_STR "Renamed!");
71
72 BKE_id_rename(*bmain, object->id, "Name/With\\Slashes/");
73 EXPECT_EQ(asset.library_relative_identifier(), "Object" SEP_STR "Name/With\\Slashes/");
74
75 BKE_main_free(bmain);
76}
77
78TEST_F(AssetRepresentationTest, weak_reference__current_file)
79{
80 AssetLibrary *library = get_builtin_library_from_type(ASSET_LIBRARY_LOCAL);
81 AssetRepresentation &asset = add_dummy_asset(*library, "path/to/an/asset");
82
83 {
84 AssetWeakReference weak_ref = asset.make_weak_reference();
86 EXPECT_EQ(weak_ref.asset_library_identifier, nullptr);
87 EXPECT_STREQ(weak_ref.relative_asset_identifier, "path/to/an/asset");
88 }
89}
90
91TEST_F(AssetRepresentationTest, weak_reference__custom_library)
92{
94 AssetLibrary *const library = service->get_asset_library_on_disk_custom("My custom lib",
95 asset_library_root_);
96 AssetRepresentation &asset = add_dummy_asset(*library, "path/to/an/asset");
97
98 {
99 AssetWeakReference weak_ref = asset.make_weak_reference();
101 EXPECT_STREQ(weak_ref.asset_library_identifier, "My custom lib");
102 EXPECT_STREQ(weak_ref.relative_asset_identifier, "path/to/an/asset");
103 }
104}
105
106/* Test if new weak references the ID name changes. */
107TEST_F(AssetRepresentationTest, weak_reference__id_name_change)
108{
109 Main *bmain = BKE_main_new();
110 Object *object = BKE_id_new<Object>(bmain, "Before rename");
111
112 AssetLibrary *library = get_builtin_library_from_type(ASSET_LIBRARY_LOCAL);
113
114 AssetRepresentation &asset = add_dummy_id_asset(*library, object->id);
115
116 {
117 AssetWeakReference weak_ref = asset.make_weak_reference();
119 EXPECT_STREQ(weak_ref.asset_library_identifier, nullptr);
120 EXPECT_STREQ(weak_ref.relative_asset_identifier, "Object" SEP_STR "Before rename");
121 }
122
123 BKE_id_rename(*bmain, object->id, "Renamed!");
124 {
125 AssetWeakReference weak_ref = asset.make_weak_reference();
127 EXPECT_STREQ(weak_ref.asset_library_identifier, nullptr);
128 EXPECT_STREQ(weak_ref.relative_asset_identifier, "Object" SEP_STR "Renamed!");
129 }
130
131 BKE_id_rename(*bmain, object->id, "Name/With\\Slashes/");
132 {
133 AssetWeakReference weak_ref = asset.make_weak_reference();
135 EXPECT_STREQ(weak_ref.asset_library_identifier, nullptr);
136 EXPECT_STREQ(weak_ref.relative_asset_identifier, "Object" SEP_STR "Name/With\\Slashes/");
137 }
138
139 BKE_main_free(bmain);
140}
141
142TEST_F(AssetRepresentationTest, weak_reference__compare)
143{
144 {
147 EXPECT_EQ(a, b);
148
149 /* Arbitrary individual member changes to test how it affects the comparison. */
150 b.asset_library_identifier = "My lib";
151 EXPECT_NE(a, b);
152 a.asset_library_identifier = "My lib";
153 EXPECT_EQ(a, b);
155 EXPECT_NE(a, b);
156 b.asset_library_type = ASSET_LIBRARY_LOCAL;
157 EXPECT_NE(a, b);
158 b.asset_library_type = ASSET_LIBRARY_ESSENTIALS;
159 EXPECT_EQ(a, b);
161 EXPECT_NE(a, b);
162 b.relative_asset_identifier = "Bar";
163 EXPECT_NE(a, b);
165 EXPECT_EQ(a, b);
166
167 /* Make the destructor work. */
168 a.asset_library_identifier = b.asset_library_identifier = nullptr;
169 a.relative_asset_identifier = b.relative_asset_identifier = nullptr;
170 }
171
172 {
175 a.asset_library_identifier = "My custom lib";
176 a.relative_asset_identifier = "path/to/an/asset";
177
179 EXPECT_NE(a, b);
180
181 b.asset_library_type = ASSET_LIBRARY_LOCAL;
182 b.asset_library_identifier = "My custom lib";
183 b.relative_asset_identifier = "path/to/an/asset";
184 EXPECT_EQ(a, b);
185
186 /* Make the destructor work. */
187 a.asset_library_identifier = b.asset_library_identifier = nullptr;
188 a.relative_asset_identifier = b.relative_asset_identifier = nullptr;
189 }
190
191 {
193 AssetLibrary *const library = service->get_asset_library_on_disk_custom("My custom lib",
194 asset_library_root_);
195 AssetRepresentation &asset = add_dummy_asset(*library, "path/to/an/asset");
196
197 AssetWeakReference weak_ref = asset.make_weak_reference();
198 AssetWeakReference other;
200 other.asset_library_identifier = "My custom lib";
201 other.relative_asset_identifier = "path/to/an/asset";
202 EXPECT_EQ(weak_ref, other);
203
204 other.relative_asset_identifier = "";
205 EXPECT_NE(weak_ref, other);
206 other.relative_asset_identifier = nullptr;
207 EXPECT_NE(weak_ref, other);
208
209 /* Make the destructor work. */
210 other.asset_library_identifier = nullptr;
211 other.relative_asset_identifier = nullptr;
212 }
213
214 /* Same but comparing windows and unix style paths. */
215 {
217 AssetLibrary *const library = service->get_asset_library_on_disk_custom("My custom lib",
218 asset_library_root_);
219 AssetRepresentation &asset = add_dummy_asset(*library, "path/to/an/asset");
220
221 AssetWeakReference weak_ref = asset.make_weak_reference();
222 AssetWeakReference other;
224 other.asset_library_identifier = "My custom lib";
225 other.relative_asset_identifier = "path\\to\\an\\asset";
226 EXPECT_EQ(weak_ref, other);
227
228 other.relative_asset_identifier = "";
229 EXPECT_NE(weak_ref, other);
230 other.relative_asset_identifier = nullptr;
231 EXPECT_NE(weak_ref, other);
232
233 /* Make the destructor work. */
234 other.asset_library_identifier = nullptr;
235 other.relative_asset_identifier = nullptr;
236 }
237}
238
239TEST_F(AssetRepresentationTest, weak_reference__resolve_to_full_path__current_file)
240{
242 AssetLibrary *library = get_builtin_library_from_type(ASSET_LIBRARY_LOCAL);
243 AssetRepresentation &asset = add_dummy_asset(*library, "path/to/an/asset");
244
245 AssetWeakReference weak_ref = asset.make_weak_reference();
246
247 std::string resolved_path = service->resolve_asset_weak_reference_to_full_path(weak_ref);
248 EXPECT_EQ(resolved_path, "");
249}
250
251/* #AssetLibraryService::resolve_asset_weak_reference_to_full_path(). */
252TEST_F(AssetRepresentationTest, weak_reference__resolve_to_full_path__custom_library)
253{
255 AssetLibrary *const library = service->get_asset_library_on_disk_custom("My custom lib",
256 asset_library_root_);
257 AssetRepresentation &asset = add_dummy_asset(*library, "path/to/an/asset");
258
259 AssetWeakReference weak_ref = asset.make_weak_reference();
260
261 std::string expected_path = utils::normalize_path(asset_library_root_ + "/" + "path/") +
262 "to/an/asset";
263 std::string resolved_path = service->resolve_asset_weak_reference_to_full_path(weak_ref);
264
265 EXPECT_EQ(BLI_path_cmp(resolved_path.c_str(), expected_path.c_str()), 0);
266}
267
269 weak_reference__resolve_to_full_path__custom_library__windows_pathsep)
270{
272 AssetLibrary *const library = service->get_asset_library_on_disk_custom("My custom lib",
273 asset_library_root_);
274 AssetRepresentation &asset = add_dummy_asset(*library, "path\\to\\an\\asset");
275
276 AssetWeakReference weak_ref = asset.make_weak_reference();
277
278 std::string expected_path = utils::normalize_path(asset_library_root_ + "\\" + "path\\") +
279 "to\\an\\asset";
280 std::string resolved_path = service->resolve_asset_weak_reference_to_full_path(weak_ref);
281
282 EXPECT_EQ(BLI_path_cmp(resolved_path.c_str(), expected_path.c_str()), 0);
283}
284
285/* #AssetLibraryService::resolve_asset_weak_reference_to_exploded_path(). */
286TEST_F(AssetRepresentationTest, weak_reference__resolve_to_exploded_path__current_file)
287{
289 AssetLibrary *library = get_builtin_library_from_type(ASSET_LIBRARY_LOCAL);
290 AssetRepresentation &asset = add_dummy_asset(*library, "path/to/an/asset");
291
292 AssetWeakReference weak_ref = asset.make_weak_reference();
293
294 std::string expected_full_path = utils::normalize_path("path/to/an/asset", 5);
295 std::optional<AssetLibraryService::ExplodedPath> resolved_path =
297
298 EXPECT_EQ(*resolved_path->full_path, expected_full_path);
299 EXPECT_EQ(resolved_path->dir_component, "");
300 EXPECT_EQ(resolved_path->group_component, "path");
301 /* ID names may contain slashes. */
302 EXPECT_EQ(resolved_path->name_component, "to/an/asset");
303}
304
305/* #AssetLibraryService::resolve_asset_weak_reference_to_exploded_path(). */
306TEST_F(AssetRepresentationTest, weak_reference__resolve_to_exploded_path__custom_library)
307{
309 AssetLibrary *const library = service->get_asset_library_on_disk_custom("My custom lib",
310 asset_library_root_);
311 AssetRepresentation &asset = add_dummy_asset(*library, "some.blend/Material/asset/name");
312
313 AssetWeakReference weak_ref = asset.make_weak_reference();
314
315 std::string expected_full_path = utils::normalize_path(asset_library_root_ +
316 "/some.blend/Material/") +
317 "asset/name";
318 std::optional<AssetLibraryService::ExplodedPath> resolved_path =
320
321 EXPECT_EQ(BLI_path_cmp(resolved_path->full_path->c_str(), expected_full_path.c_str()), 0);
322 EXPECT_EQ(BLI_path_cmp_normalized(std::string(resolved_path->dir_component).c_str(),
323 std::string(asset_library_root_ + "/some.blend").c_str()),
324 0);
325 EXPECT_EQ(resolved_path->group_component, "Material");
326 /* ID names may contain slashes. */
327 EXPECT_EQ(resolved_path->name_component, "asset/name");
328}
329
330/* #AssetLibraryService::resolve_asset_weak_reference_to_exploded_path(). */
332 weak_reference__resolve_to_exploded_path__custom_library__windows_pathsep)
333{
335 AssetLibrary *const library = service->get_asset_library_on_disk_custom("My custom lib",
336 asset_library_root_);
337 AssetRepresentation &asset = add_dummy_asset(*library, "some.blend\\Material\\asset/name");
338
339 AssetWeakReference weak_ref = asset.make_weak_reference();
340
341 std::string expected_full_path = utils::normalize_path(asset_library_root_ +
342 "\\some.blend\\Material\\") +
343 "asset/name";
344 std::optional<AssetLibraryService::ExplodedPath> resolved_path =
346
347 EXPECT_EQ(BLI_path_cmp(resolved_path->full_path->c_str(), expected_full_path.c_str()), 0);
348 EXPECT_EQ(BLI_path_cmp_normalized(std::string(resolved_path->dir_component).c_str(),
349 std::string(asset_library_root_ + "\\some.blend").c_str()),
350 0);
351 EXPECT_EQ(resolved_path->group_component, "Material");
352 /* ID names may contain slashes. */
353 EXPECT_EQ(resolved_path->name_component, "asset/name");
354}
355
356} // namespace blender::asset_system::tests
Main runtime representation of an asset.
IDNewNameResult BKE_id_rename(Main &bmain, ID &id, blender::StringRefNull name, const IDNewNameMode mode=IDNewNameMode::RenameExistingNever)
Definition lib_id.cc:2392
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1514
Main * BKE_main_new()
Definition main.cc:89
void BKE_main_free(Main *bmain)
Definition main.cc:192
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
int BLI_path_cmp_normalized(const char *p1, const char *p2) ATTR_NONNULL(1
#define BLI_path_cmp
eAssetLibraryType
@ ASSET_LIBRARY_CUSTOM
@ ASSET_LIBRARY_ESSENTIALS
@ ASSET_LIBRARY_LOCAL
Object is a sort of wrapper for general info.
AssetLibrary * get_asset_library(const Main *bmain, const AssetLibraryReference &library_reference)
std::optional< ExplodedPath > resolve_asset_weak_reference_to_exploded_path(const AssetWeakReference &asset_reference)
std::string resolve_asset_weak_reference_to_full_path(const AssetWeakReference &asset_reference)
AssetLibrary * get_asset_library_on_disk_custom(StringRef name, StringRefNull root_path)
std::weak_ptr< AssetRepresentation > add_local_id_asset(ID &id)
std::weak_ptr< AssetRepresentation > add_external_asset(StringRef relative_asset_path, StringRef name, int id_type, std::unique_ptr< AssetMetaData > metadata)
AssetRepresentation & add_dummy_id_asset(AssetLibrary &library, ID &id)
AssetLibrary * get_builtin_library_from_type(eAssetLibraryType type)
AssetRepresentation & add_dummy_asset(AssetLibrary &library, StringRef relative_path)
TEST_F(AssetCatalogTest, load_single_file)
std::string normalize_path(StringRefNull path, int64_t max_len)
const char * relative_asset_identifier
const char * asset_library_identifier
Definition DNA_ID.h:414
#define SEP_STR
Definition unit.cc:39