18#include "testing/testing.h"
72 for (
const auto &catalog_uptr :
get_catalogs().values()) {
73 if (catalog_uptr->path == path) {
88 "blender_assets.cats.txt";
100 &
U,
"Test", registered_asset_lib.c_str());
101 ASSERT_NE(
nullptr, asset_lib_pref);
104 if (should_top_level_cdf_exist) {
105 ASSERT_EQ(0,
BLI_copy(original_cdf_file.c_str(), cdf_toplevel.c_str()));
115 const CatalogFilePath blendfilename = asset_lib_subdir +
"some_file.blend";
122 EXPECT_TRUE(
BLI_exists(cdf_toplevel.c_str()));
124 const bool backup_exists =
BLI_exists(backup_filename.c_str());
125 EXPECT_EQ(should_top_level_cdf_exist, backup_exists)
126 <<
"Overwritten CDF should have been backed up.";
130 std::string native_cdf_path = cdf->
file_path;
132 EXPECT_EQ(cdf_toplevel, native_cdf_path);
142 if (should_top_level_cdf_exist) {
143 EXPECT_NE(
nullptr, poses_ellie_catalog);
166 ASSERT_EQ(
nullptr, cat_without_path);
170 ASSERT_NE(
nullptr, poses_ellie);
177 ASSERT_NE(
nullptr, poses_whitespace);
179 EXPECT_EQ(
"character/Ellie/poselib/white space", poses_whitespace->
path.
str());
184 ASSERT_NE(
nullptr, poses_ruzena);
191 ASSERT_NE(
nullptr, another_ruzena);
203 ASSERT_NE(
nullptr, found_by_id);
205 <<
"Backslashes should be normalized when loading from disk.";
210 <<
"Catalog with backslashed path should be findable by the normalized path.";
213 <<
"Nothing should be found when searching for backslashes.";
223 <<
"Adding a catalog at runtime should never mark it as 'first loaded'; "
224 "only loading from disk is allowed to do that.";
228 <<
"Adding a new catalog with an already-loaded path should not mark it as 'first loaded'";
237 <<
"The first-seen definition of a catalog should be returned";
250 EXPECT_NE(
nullptr, catalog);
253 EXPECT_NE(
nullptr, catalog);
258 EXPECT_NE(
nullptr, catalog);
298 const CatalogFilePath save_to_path = use_temp_path() +
"новый.cats.txt";
300 ASSERT_NE(
nullptr, cdf) <<
"unable to load " << load_from_path;
307 const bUUID materials_uuid(
"a2151dff-dead-4f29-b6bc-b2c7d6cccdb4");
309 ASSERT_NE(
nullptr, cat);
323 EXPECT_FALSE(
BLI_exists(default_cdf_path.c_str()));
333 "blender_assets.cats.txt";
337 ASSERT_EQ(0,
BLI_copy(original_cdf_file.c_str(), cdf_filename.c_str()))
338 <<
"Unable to copy " << original_cdf_file <<
" to " << cdf_filename;
352 EXPECT_TRUE(
BLI_exists(cdf_filename.c_str()));
353 EXPECT_TRUE(
BLI_exists(backup_filename.c_str()))
354 <<
"Overwritten CDF should have been backed up.";
360 <<
"Expected to see the newly-created catalog.";
362 <<
"Expected to see the already-existing catalog.";
379 EXPECT_TRUE(
BLI_exists(expected_cdf_path.c_str()));
383 ASSERT_NE(
nullptr, cdf);
397 "blender_assets.cats.txt";
400 ASSERT_EQ(0,
BLI_copy(original_cdf_file.c_str(), writable_cdf_file.c_str()));
412 EXPECT_TRUE(
BLI_exists(writable_cdf_file.c_str()));
413 EXPECT_TRUE(
BLI_exists(backup_filename.c_str()))
414 <<
"Overwritten CDF should have been backed up.";
418 ASSERT_NE(
nullptr, cdf);
432 on_blendfile_save__from_memory_into_existing_asset_lib_without_top_level_cdf)
434 save_from_memory_into_existing_asset_lib(
true);
442 save_from_memory_into_existing_asset_lib(
false);
452 EXPECT_FALSE(
BLI_exists(temp_lib_root.c_str()));
455 ASSERT_NE(
nullptr, cat);
460 EXPECT_FALSE(
BLI_exists(temp_lib_root.c_str()));
468 EXPECT_TRUE(
BLI_is_dir(temp_lib_root.c_str()));
472 EXPECT_TRUE(
BLI_is_file(definition_file_path.c_str()));
479 ASSERT_NE(
nullptr, written_cat);
494 ASSERT_EQ(0,
BLI_copy(default_catalog_path.c_str(), writable_catalog_path.c_str()));
495 EXPECT_TRUE(
BLI_is_dir(temp_lib_root.c_str()));
496 EXPECT_TRUE(
BLI_is_file(writable_catalog_path.c_str()));
514 <<
"expected pre-existing catalogs to be kept in the file";
516 <<
"expecting newly added catalog to not yet be saved to " << temp_lib_root;
523 <<
"expected pre-existing catalogs to be kept in the file";
524 EXPECT_NE(
nullptr, reloaded_service.
find_catalog(new_catalog_id))
525 <<
"expecting newly added catalog to exist in the file";
542 "production/Spite Fright/Characters/Victora/Pose Library/Approved/Body Parts/Hands");
545 EXPECT_EQ(
"production/Spite Fright/Characters/Victora/Pose Library/Approved/Body Parts/Hands",
562 std::vector<AssetCatalogPath> expected_paths{
565 "character/Ellie/backslashes",
566 "character/Ellie/poselib",
567 "character/Ellie/poselib/tailslash",
568 "character/Ellie/poselib/white space",
570 "character/Ružena/poselib",
571 "character/Ružena/poselib/face",
575 "path/without/simplename",
619 std::vector<AssetCatalogPath> expected_paths{
622 "character/Ellie/backslashes",
623 "character/Ellie/poselib",
624 "character/Ellie/poselib/tailslash",
625 "character/Ellie/poselib/white space",
629 "path/without/simplename",
672 <<
"The original (pre-rename) path should not be associated with a catalog any more.";
675 ASSERT_NE(
nullptr, renamed_cat);
676 ASSERT_EQ(orig_cat, renamed_cat) <<
"Changing the path should not reallocate the catalog.";
678 <<
"Changing the path should not change the catalog ID.";
681 <<
"Changing the path should change the path. Surprise.";
684 <<
"Changing the path should update children.";
686 <<
"Changing the path should update children.";
700 <<
"Changing the path should update the simplename.";
702 <<
"Changing the path should update the simplename of children.";
710 const std::string new_path =
711 "this/is/a/very/long/path/that/exceeds/the/simple-name/length/of/assets";
713 <<
"This test case should work with paths longer than AssetMetaData::catalog_simple_name";
719 <<
"The new simple name should fit in the asset metadata.";
720 EXPECT_EQ(
"...very-long-path-that-exceeds-the-simple-name-length-of-assets", new_simple_name)
721 <<
"Changing the path should update the simplename.";
722 EXPECT_EQ(
"...long-path-that-exceeds-the-simple-name-length-of-assets-face",
724 <<
"Changing the path should update the simplename of children.";
741 <<
"The original (pre-rename) path should not be associated with a catalog any more.";
744 ASSERT_NE(
nullptr, renamed_cat);
746 <<
"Changing the path should not change the catalog ID.";
749 <<
"When creating a new catalog by renaming + adding a slash, the renamed catalog should be "
750 "assigned the path passed to update_catalog_path()";
754 ASSERT_NE(
nullptr, new_cat) <<
"Renaming to .../X/Y should cause .../X to exist as well.";
760 EXPECT_EQ(
"character/Ružena/poses/general/hand",
762 <<
"Changing the path should update children.";
763 EXPECT_EQ(
"character/Ružena/poses/general/face",
765 <<
"Changing the path should update children.";
772 "blender_assets.cats.txt";
774 "modified_assets.cats.txt";
775 const CatalogFilePath temp_cdf_file = cdf_dir +
"blender_assets.cats.txt";
776 ASSERT_EQ(0,
BLI_copy(original_cdf_file.c_str(), temp_cdf_file.c_str()));
784 ASSERT_EQ(0,
BLI_copy(modified_cdf_file.c_str(), temp_cdf_file.c_str()));
814 "blender_assets.cats.txt";
816 "catalog_reload_test.cats.txt";
817 const CatalogFilePath temp_cdf_file = cdf_dir +
"blender_assets.cats.txt";
818 ASSERT_EQ(0,
BLI_copy(original_cdf_file.c_str(), temp_cdf_file.c_str()));
834 ASSERT_EQ(0,
BLI_copy(modified_cdf_file.c_str(), temp_cdf_file.c_str()));
856 EXPECT_NE(ellie_whitespace_after_reload, ellie_whitespace_before_reload);
858 EXPECT_EQ(std::string(
"Hah simple name after all"),
879 <<
"The catalogs whose path we changed should now be saved";
881 <<
"Deleted catalogs should not be remembered after saving.";
888 "blender_assets.cats.txt";
890 ASSERT_EQ(0,
BLI_copy(original_cdf_file.c_str(), writable_cdf_file.c_str()));
917 const bUUID cat2_uuid(
"22222222-b847-44d9-bdca-ff04db1c24f5");
918 const bUUID cat4_uuid(
"11111111-b847-44d9-bdca-ff04db1c24f5");
923 cat4_uuid,
"simple/path",
"different ID, same path");
924 const AssetCatalog cat5(cat4_uuid,
"simple/path",
"same ID, same path");
927 by_path.insert(&cat1);
928 by_path.insert(&cat2);
929 by_path.insert(&cat3);
930 by_path.insert(&cat4);
931 by_path.insert(&cat5);
933 AssetCatalogOrderedSet::const_iterator set_iter = by_path.begin();
939 ASSERT_EQ(4, by_path.size()) <<
"Expecting cat5 to not be stored in the set, as it duplicates "
940 "an already-existing path + UUID";
947 if (set_iter != by_path.end()) {
949 FAIL() <<
"Did not expect more items in the set, had at least " << next_cat->
catalog_id <<
":"
959 const bUUID first_seen_uuid(
"3d451c87-27d1-40fd-87fc-f4c9e829c848");
960 const bUUID first_sorted_uuid(
"00000000-0000-0000-0000-000000000001");
961 const bUUID last_sorted_uuid(
"ffffffff-ffff-ffff-ffff-ffffffffffff");
963 AssetCatalog first_seen_cat(first_seen_uuid,
"simple/path/child",
"");
964 const AssetCatalog first_sorted_cat(first_sorted_uuid,
"simple/path/child",
"");
965 const AssetCatalog last_sorted_cat(last_sorted_uuid,
"simple/path/child",
"");
976 by_path.insert(&first_seen_cat);
977 by_path.insert(&first_sorted_cat);
978 by_path.insert(&last_sorted_cat);
980 AssetCatalogOrderedSet::const_iterator set_iter = by_path.begin();
982 EXPECT_EQ(1, by_path.count(&first_seen_cat));
983 EXPECT_EQ(1, by_path.count(&first_sorted_cat));
984 EXPECT_EQ(1, by_path.count(&last_sorted_cat));
985 ASSERT_EQ(3, by_path.size());
987 EXPECT_EQ(first_seen_uuid, (*(set_iter++))->catalog_id);
988 EXPECT_EQ(first_sorted_uuid, (*(set_iter++))->catalog_id);
989 EXPECT_EQ(last_sorted_uuid, (*(set_iter++))->catalog_id);
991 if (set_iter != by_path.end()) {
993 FAIL() <<
"Did not expect more items in the set, had at least " << next_cat->
catalog_id <<
":"
1004 <<
"Missing parents should not be immediately created.";
1013 <<
"Empty path should never be valid, even when after missing catalogs";
1024 ASSERT_NE(
nullptr, cat_char) <<
"Missing parents should be created immediately after loading.";
1025 ASSERT_NE(
nullptr, cat_ellie) <<
"Missing parents should be created immediately after loading.";
1026 ASSERT_NE(
nullptr, cat_ruzena) <<
"Missing parents should be created immediately after loading.";
1029 <<
"Missing parents should be marked as having changes.";
1031 <<
"Missing parents should be marked as having changes.";
1033 <<
"Missing parents should be marked as having changes.";
1036 ASSERT_NE(
nullptr, cdf);
1037 EXPECT_TRUE(cdf->
contains(cat_char->
catalog_id)) <<
"Missing parents should be saved to a CDF.";
1038 EXPECT_TRUE(cdf->
contains(cat_ellie->
catalog_id)) <<
"Missing parents should be saved to a CDF.";
1040 <<
"Missing parents should be saved to a CDF.";
1063 <<
"Main catalog should be included in the filter.";
1065 <<
"Sub-catalog should be included in the filter.";
1067 <<
"Sub-catalog should be included in the filter.";
1071 <<
"Alias of main catalog should be included in the filter.";
1073 <<
"Alias of sub-catalog should be included in the filter.";
1076 EXPECT_FALSE(
filter.contains(
BLI_uuid_nil())) <<
"Nil catalog should not be included.";
1090 EXPECT_TRUE(
filter.contains(unknown_uuid));
1092 EXPECT_FALSE(
filter.contains(
BLI_uuid_nil())) <<
"Nil catalog should not be included.";
1109 EXPECT_NE(&empty,
copy.get());
1136 auto cat1 = std::make_unique<AssetCatalog>(
UUID_POSES_RUZENA,
"poses/Henrik",
"");
1139 cat3->flags.is_deleted =
true;
1149 EXPECT_NE(&catcoll,
copy.get());
1164 <<
"AssetCatalogs should be actual copies.";
1168 <<
"AssetCatalogs should be actual copies.";
1182 auto cat1 = std::make_unique<AssetCatalog>(
UUID_POSES_RUZENA,
"poses/Henrik",
"");
1185 cat3->flags.is_deleted =
true;
1196 "path/to/somewhere.cats.txt");
1210 <<
"AssetCatalog pointers should have been remapped to the copy.";
1214 <<
"Deleted AssetCatalog pointers should have been remapped to the copy.";
1227 <<
"Undo steps should be created explicitly, and not after creating any catalog.";
1232 <<
"Undo should be possible after creating an undo snapshot.";
1237 <<
"Undoing the only stored step should make it impossible to undo further.";
1238 EXPECT_TRUE(service.
is_redo_possbile()) <<
"Undoing a step should make redo possible.";
1240 <<
"Undone catalog should not exist after undo.";
1242 <<
"First catalog should still exist after undo.";
1244 <<
"The CDF should also not contain the undone catalog.";
1249 <<
"Undoing and then redoing a step should make it possible to undo again.";
1251 <<
"Undoing and then redoing a step should make redo impossible.";
1253 <<
"Redone catalog should exist after redo.";
1255 <<
"First catalog should still exist after redo.";
1257 <<
"The CDF should contain the redone catalog.";
1278 <<
"After storing an undo snapshot, the redo buffer should be empty.";
1280 <<
"After storing an undo snapshot, undoing should be possible";
1284 "POSES_ELLIE WHITESPACE");
struct bUserAssetLibrary * BKE_preferences_asset_library_add(struct UserDef *userdef, const char *name, const char *dirpath) ATTR_NONNULL(1)
void BKE_preferences_asset_library_remove(struct UserDef *userdef, struct bUserAssetLibrary *library) ATTR_NONNULL()
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
File and directory operations.
bool BLI_file_touch(const char *filepath) ATTR_NONNULL(1)
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_copy(const char *path_src, const char *path_dst) ATTR_NONNULL()
bool BLI_dir_create_recursive(const char *dirname) ATTR_NONNULL()
bool BLI_is_file(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
size_t BLI_file_size(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_path_slash_native(char *path) ATTR_NONNULL(1)
bool BLI_uuid_is_nil(bUUID uuid)
bUUID BLI_uuid_generate_random()
const Value & lookup(const Key &key) const
void add_new(const Key &key, const Value &value)
bool contains(const Key &key) const
OwningAssetCatalogMap catalogs_
AssetCatalogCollection()=default
std::unique_ptr< AssetCatalogDefinitionFile > catalog_definition_file_
OwningAssetCatalogMap deleted_catalogs_
std::unique_ptr< AssetCatalogCollection > deep_copy() const
Map< CatalogID, AssetCatalog * > catalogs_
AssetCatalogDefinitionFile(const CatalogFilePath &file_path)
void add_new(AssetCatalog *catalog)
bool contains(CatalogID catalog_id) const
const CatalogFilePath file_path
bool write_to_disk() const
const std::string & str() const
bool is_undo_possbile() const
void delete_catalog_by_id_soft(CatalogID catalog_id)
AssetCatalogFilter create_catalog_filter(CatalogID active_catalog_id) const
AssetCatalog * find_catalog_by_path(const AssetCatalogPath &path) const
AssetCatalog * find_catalog(CatalogID catalog_id) const
void prune_catalogs_by_path(const AssetCatalogPath &path)
bool write_to_disk(const CatalogFilePath &blend_file_path)
bool has_unsaved_changes() const
void create_missing_catalogs()
AssetCatalogService(const CatalogFilePath &asset_library_root={})
AssetCatalog * create_catalog(const AssetCatalogPath &catalog_path)
void update_catalog_path(CatalogID catalog_id, const AssetCatalogPath &new_catalog_path)
void prune_catalogs_by_id(CatalogID catalog_id)
bool is_redo_possbile() const
const OwningAssetCatalogMap & get_deleted_catalogs() const
void tag_has_unsaved_changes(AssetCatalog *edited_catalog=nullptr)
static const CatalogFilePath DEFAULT_CATALOG_FILENAME
const AssetCatalogDefinitionFile * get_catalog_definition_file() const
const AssetCatalogTree & catalog_tree()
const OwningAssetCatalogMap & get_catalogs() const
const CatalogID catalog_id
struct blender::asset_system::AssetCatalog::Flags flags
void save_from_memory_into_existing_asset_lib(const bool should_top_level_cdf_exist)
static void expect_tree_items(const AssetCatalogTree &tree, const std::vector< AssetCatalogPath > &expected_paths)
std::string asset_library_root_
std::string create_temp_path()
AssetCatalogDefinitionFile * allocate_catalog_definition_file(StringRef file_path)
OwningAssetCatalogMap & get_catalogs()
OwningAssetCatalogMap & get_deleted_catalogs()
AssetCatalogDefinitionFile * get_catalog_definition_file()
Map< CatalogID, AssetCatalog * > get_catalogs()
TestableAssetCatalogService()=default
const OwningAssetCatalogMap & get_deleted_catalogs() const
void create_missing_catalogs()
TestableAssetCatalogService(const CatalogFilePath &asset_library_root)
void delete_catalog_by_id_soft(CatalogID catalog_id)
const AssetCatalogDefinitionFile * get_catalog_definition_file()
int64_t count_catalogs_with_path(const CatalogFilePath &path)
const bUUID UUID_POSES_RUZENA_HAND("81811c31-1a88-4bd7-bb34-c6fc2607a12e")
TEST_F(AssetCatalogTest, load_single_file)
const bUUID UUID_ANOTHER_RUZENA("00000000-d9fa-4b91-b704-e6af1f1339ef")
const bUUID UUID_POSES_RUZENA_FACE("82162c1f-06cc-4d91-a9bf-4f72c104e348")
const bUUID UUID_POSES_ELLIE_TRAILING_SLASH("3376b94b-a28d-4d05-86c1-bf30b937130d")
const bUUID UUID_POSES_ELLIE_BACKSLASHES("a51e17ae-34fc-47d5-ba0f-64c2c9b771f7")
const bUUID UUID_POSES_ELLIE("df60e1f6-2259-475b-93d9-69a1b4a8db78")
const bUUID UUID_WITHOUT_SIMPLENAME("d7916a31-6ca9-4909-955f-182ca2b81fa3")
const bUUID UUID_POSES_RUZENA("79a4f887-ab60-4bd4-94da-d572e27d6aed")
const bUUID UUID_POSES_ELLIE_WHITESPACE("b06132f6-5687-4751-a6dd-392740eb3c46")
const bUUID UUID_ID_WITHOUT_PATH("e34dd2c5-5d2e-4668-9794-1db5de2a4f71")
const bUUID UUID_AGENT_47("c5744ba5-43f5-4f73-8e52-010ad4a61b34")
Map< CatalogID, std::unique_ptr< AssetCatalog > > OwningAssetCatalogMap
std::set< const AssetCatalog *, AssetCatalogLessThan > AssetCatalogOrderedSet
std::string CatalogFilePath
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)