using System; using System.Collections.Generic; using System.IO; using System.Linq; using NUnit.Framework; using UnityEditor.AddressableAssets.Settings; using UnityEditor.AddressableAssets.Settings.GroupSchemas; using UnityEditor.Build.Content; using UnityEditor.SceneManagement; using UnityEditor.U2D; using UnityEngine; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.AddressableAssets.Tests; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; using UnityEngine.TestTools; using UnityEngine.U2D; namespace UnityEditor.AddressableAssets.Tests { public class AddressableAssetEntryTests : AddressableAssetTestBase { string m_guid; AddressableAssetGroup m_testGroup; AddressableAssetSettings m_Settings; protected override void OnInit() { var path = GetAssetPath("subObjectTest.asset"); AssetDatabase.CreateAsset(UnityEngine.AddressableAssets.Tests.TestObject.Create("test"), path); AssetDatabase.AddObjectToAsset(UnityEngine.AddressableAssets.Tests.TestObject2.Create("test2"), path); AssetDatabase.AddObjectToAsset(UnityEngine.AddressableAssets.Tests.TestObject2.Create("test3"), path); AssetDatabase.AddObjectToAsset(UnityEngine.AddressableAssets.Tests.TestObject2.Create("test4"), path); AssetDatabase.AddObjectToAsset(UnityEngine.AddressableAssets.Tests.TestObject2.Create("test5"), path); AssetDatabase.SaveAssets(); m_guid = AssetDatabase.AssetPathToGUID(path); Settings.CreateOrMoveEntry(m_guid, Settings.DefaultGroup); AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); m_testGroup = Settings.CreateGroup("testGroup", false, false, false, null, typeof(BundledAssetGroupSchema)); } protected override void OnCleanup() { Settings.RemoveGroup(m_testGroup); } [Test] public void CreateKeyList_Returns_ExpectedKeys() { var e = Settings.DefaultGroup.GetAssetEntry(m_guid); e.SetAddress("address"); e.SetLabel("label", true, true, true); CollectionAssert.AreEqual(new string[] {"address", m_guid, "label"}, e.CreateKeyList(true, true, true)); CollectionAssert.AreEqual(new string[] {m_guid, "label"}, e.CreateKeyList(false, true, true)); CollectionAssert.AreEqual(new string[] {"address", "label"}, e.CreateKeyList(true, false, true)); CollectionAssert.AreEqual(new string[] {"address", "label"}, e.CreateKeyList(true, false, true)); CollectionAssert.AreEqual(new string[] {"label"}, e.CreateKeyList(false, false, true)); CollectionAssert.AreEqual(new string[] {"address"}, e.CreateKeyList(true, false, false)); CollectionAssert.AreEqual(new string[] {m_guid}, e.CreateKeyList(false, true, false)); } [Test] public void EditorInitialization_RemovesAssetEntriesThatDoesNotExistOnDisk() { //setup var group = Settings.DefaultGroup; AddressableAssetEntry assetEntry = new AddressableAssetEntry("fakeguid", "fakeaddress", group, false); assetEntry.m_cachedAssetPath = "Assets/NotARealAssetPath/test.prefab"; group.AddAssetEntry(assetEntry, false); //test AddressableEditorInitialization.PurgeInvalidAssetEntries(Settings); //Assert Assert.IsFalse(group.entries.Contains(assetEntry)); } [Test] public void EditorInitialization_DoesNotDeleteFoldersThatAreStillOnDisk() { //Setup string folderPath = "Assets/Temp/FakeAddressablesFolder/"; Directory.CreateDirectory(folderPath); AssetDatabase.ImportAsset(folderPath); AddressableAssetEntry entry = new AddressableAssetEntry(AssetDatabase.AssetPathToGUID(folderPath), folderPath, m_testGroup, false); m_testGroup.AddAssetEntry(entry); entry.m_cachedAssetPath = folderPath; Assert.IsTrue(m_testGroup.entries.Contains(entry), "Folder entry is no longer in Addressable group before purge."); //Test AddressableEditorInitialization.PurgeInvalidAssetEntries(Settings); //Assert Assert.IsTrue(m_testGroup.entries.Contains(entry), "Folder entry is no longer in Addressable group after purge."); //Cleanup m_testGroup.RemoveAssetEntry(entry); AssetDatabase.DeleteAsset(folderPath); } [Test] public void EditorInitialization_DoesDeleteFoldersThatAreNotOnDisk() { //Setup string folderPath = "Assets/Temp/FakeAddressablesFolder/"; AddressableAssetEntry entry = new AddressableAssetEntry(AssetDatabase.AssetPathToGUID(folderPath), folderPath, m_testGroup, false); entry.m_cachedAssetPath = folderPath; m_testGroup.AddAssetEntry(entry); //Test AddressableEditorInitialization.PurgeInvalidAssetEntries(Settings); //Assert Assert.IsFalse(m_testGroup.entries.Contains(entry), "Invalid asset entry folder is still in Asset Group after purge."); } [Test] public void GetAssetLoadPath_Returns_ExpectedPath() { var schema = Settings.DefaultGroup.GetSchema(); var e = Settings.DefaultGroup.GetAssetEntry(m_guid); schema.InternalIdNamingMode = BundledAssetGroupSchema.AssetNamingMode.FullPath; Assert.AreEqual(e.AssetPath, e.GetAssetLoadPath(true, null)); schema.InternalIdNamingMode = BundledAssetGroupSchema.AssetNamingMode.Filename; Assert.AreEqual(Path.GetFileName(e.AssetPath), e.GetAssetLoadPath(true, null)); schema.InternalIdNamingMode = BundledAssetGroupSchema.AssetNamingMode.GUID; Assert.AreEqual(m_guid, e.GetAssetLoadPath(true, null)); schema.InternalIdNamingMode = BundledAssetGroupSchema.AssetNamingMode.Dynamic; Assert.AreEqual(m_guid, e.GetAssetLoadPath(true, null)); Assert.AreEqual(m_guid.Substring(0, 1), e.GetAssetLoadPath(true, new HashSet())); var hs = new HashSet(); hs.Add(m_guid.Substring(0, 1)); Assert.AreEqual(m_guid.Substring(0, 2), e.GetAssetLoadPath(true, hs)); } [Test] public void CreateCatalogEntries_WhenObjectHasMultipleSubObjectWithSameType_OnlyOneSubEntryIsCreated() { var e = Settings.DefaultGroup.GetAssetEntry(m_guid); var entries = new List(); var providerTypes = new HashSet(); e.CreateCatalogEntries(entries, false, "doesntMatter", null, null, providerTypes); Assert.AreEqual(2, entries.Count); } [Test] public void DefaultTypeAssetEntry_ResetsCachedTypeData() { //Setup var path = GetAssetPath("entry.prefab"); PrefabUtility.SaveAsPrefabAsset(new GameObject(), path); string guid = AssetDatabase.AssetPathToGUID(path); AddressableAssetEntry entry = new AddressableAssetEntry(guid, "testaddress", Settings.DefaultGroup, false); entry.m_cachedMainAssetType = typeof(DefaultAsset); //Test entry.CreateCatalogEntries(new List(), false, "fakeProvider", new List(), null, new Dictionary() { {new GUID(guid), new AssetLoadInfo() {includedObjects = new List()}} }, new HashSet(), true, false, false, new HashSet()); //Assert Assert.AreEqual(typeof(GameObject), entry.m_cachedMainAssetType); //Cleanup AssetDatabase.DeleteAsset(path); } [Test] public void CreateCatalogEntries_OverridesMainTypeIfWrong() { var e = Settings.DefaultGroup.GetAssetEntry(m_guid); var entries = new List(); var providerTypes = new HashSet(); var savedType = e.m_cachedMainAssetType; e.m_cachedMainAssetType = typeof(Texture2D); //something arbitrarily wrong. e.CreateCatalogEntries(entries, false, "doesntMatter", null, null, providerTypes); e.m_cachedMainAssetType = savedType; Assert.AreEqual(2, entries.Count); bool foundOnlyTestObjects = true; foreach (var entry in entries) { if (entry.ResourceType != typeof(UnityEngine.AddressableAssets.Tests.TestObject) && (entry.ResourceType != typeof(UnityEngine.AddressableAssets.Tests.TestObject2))) { foundOnlyTestObjects = false; } } Assert.IsTrue(foundOnlyTestObjects); } [Test] public void CreateCatalogEntries_EditorTypesShouldBeStripped() { var e = Settings.DefaultGroup.GetAssetEntry(m_guid); var entries = new List(); var providerTypes = new HashSet(); var savedType = e.m_cachedMainAssetType; e.m_cachedMainAssetType = typeof(UnityEditor.AssetImporter); e.CreateCatalogEntries(entries, false, "doesntMatter", null, null, providerTypes); e.m_cachedMainAssetType = savedType; Assert.AreEqual(0, entries.Count); } [Test] public void CreateCatalogEntries_NonUnityObjectsTypesAreStripped() { // Init string id = "testObject"; var path = GetAssetPath("testObjectWithSerializedClass.asset"); var testObject = TestObjectWithSerializableField.Create(id); AssetDatabase.CreateAsset(testObject, path); AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); var e = Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(path), Settings.DefaultGroup); e.address = id; // test try { var entries = new List(); var providerTypes = new HashSet(); e.CreateCatalogEntries(entries, false, "doesntMatter", null, null, providerTypes); var foundCatalogEntryForSerialisedClass = entries.Find(entry => entry.ResourceType == typeof(SerializableClass)); Assert.IsNull(foundCatalogEntryForSerialisedClass, "SerializableClass was found as a catalog entry type. Only Unity Objects are meant to be Assets not serialised objects internal to the type."); } finally { Settings.RemoveAssetEntry(e); AssetDatabase.DeleteAsset(path); UnityEngine.Object.DestroyImmediate(testObject); } } [Test] public void CreateCatalogEntries_IncludesUnityObjectsOnly() { // Init string id = "testObject"; var path = GetAssetPath("testObjectWithSerializedClass.asset"); var testObject = TestObjectWithSerializableField.Create(id); AssetDatabase.CreateAsset(testObject, path); AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); var e = Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(path), Settings.DefaultGroup); e.address = id; // test try { var entries = new List(); var providerTypes = new HashSet(); e.CreateCatalogEntries(entries, false, "doesntMatter", null, null, providerTypes); var foundCatalogEntryForTestObject = entries.Find(entry => entry.ResourceType == typeof(TestObjectWithSerializableField)); Assert.AreEqual(1, entries.Count, "Too many catalog entries found for TestObjectWithSerializableField Asset created"); Assert.IsNotNull(foundCatalogEntryForTestObject, "TestObjectWithSerializableField was not found for catalog entries for the ScriptableObject type."); } finally { Settings.RemoveAssetEntry(e); AssetDatabase.DeleteAsset(path); UnityEngine.Object.DestroyImmediate(testObject); } } [Test] public void MainAsset_WhenEntryIsForSubAsset_ShouldReturnMainAsset() { var mainAssetEntry = Settings.DefaultGroup.GetAssetEntry(m_guid); var entries = new List(); Settings.DefaultGroup.GatherAllAssets(entries, true, true, true); var subAssetEntry = entries.FirstOrDefault(e => e.IsSubAsset); Assert.NotNull(subAssetEntry); Assert.AreEqual(mainAssetEntry.MainAsset, subAssetEntry.MainAsset); } [Test] public void TargetAsset_WhenEntryIsForMainAsset_ShouldReturnMainAsset() { var entry = Settings.DefaultGroup.GetAssetEntry(m_guid); Assert.AreEqual(entry.MainAsset, entry.TargetAsset); } [Test] public void TargetAsset_WhenMainAssetIsSpriteAtlas_ShouldReturnSprite() { var atlasPath = CreateSpriteAtlasWithSprite(); var guid = AssetDatabase.AssetPathToGUID(atlasPath); Settings.CreateOrMoveEntry(guid, Settings.DefaultGroup); AssetDatabase.ImportAsset(atlasPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); var atlas = AssetDatabase.LoadAssetAtPath(atlasPath); var sprites = new Sprite[atlas.spriteCount]; atlas.GetSprites(sprites); var mainAssetEntry = Settings.DefaultGroup.GetAssetEntry(guid); var entries = new List(); mainAssetEntry.GatherAllAssets(entries, false, true, true); // Assert Assert.AreEqual(sprites.Length, entries.Count); foreach (var entry in entries) { Assert.IsTrue(sprites.Any(s => s.name == entry.TargetAsset.name)); Assert.IsTrue(entry.TargetAsset is Sprite); } // Cleanup Settings.RemoveAssetEntry(guid); File.Delete(atlasPath); } [Test] public void TargetAsset_WhenEntryIsForSubAsset_ShouldReturnSubObject() { var mainAssetEntry = Settings.DefaultGroup.GetAssetEntry(m_guid); var entries = new List(); Settings.DefaultGroup.GatherAllAssets(entries, false, true, true); var subObjects = AssetDatabase.LoadAllAssetRepresentationsAtPath(mainAssetEntry.AssetPath); Assert.AreEqual(subObjects.Length, entries.Count); foreach (var entry in entries) { Assert.IsTrue(subObjects.Contains(entry.TargetAsset)); } } [Test] public void WhenGettingFolderSubEntry_OnlyReturnsIfValidSubEntry() { AddressableAssetEntry mainFolderEntry = null; AddressableAssetEntry subFolderEntry = null; string testAssetFolder = GetAssetPath("TestFolder"); try { //Setup string testAssetSubFolder = Path.Combine(testAssetFolder, "SubFolder"); string mainPrefabPath = Path.Combine(testAssetFolder, "mainFolder.prefab").Replace('\\', '/'); string subPrefabPath = Path.Combine(testAssetSubFolder, "subFolder.prefab").Replace('\\', '/'); Directory.CreateDirectory(testAssetFolder); PrefabUtility.SaveAsPrefabAsset(new GameObject("mainFolderAsset"), mainPrefabPath); Directory.CreateDirectory(testAssetSubFolder); PrefabUtility.SaveAsPrefabAsset(new GameObject("subFolderAsset"), subPrefabPath); string mainFolderGuid = AssetDatabase.AssetPathToGUID(testAssetFolder); string subFolderGuid = AssetDatabase.AssetPathToGUID(testAssetSubFolder); mainFolderEntry = Settings.CreateOrMoveEntry(mainFolderGuid, m_testGroup, false); subFolderEntry = Settings.CreateOrMoveEntry(subFolderGuid, m_testGroup, false); //Test var entry = mainFolderEntry.GetFolderSubEntry(AssetDatabase.AssetPathToGUID(mainPrefabPath), mainPrefabPath); Assert.IsNotNull(entry, "Prefab in main folder is expected to be valid subAsset of main folder."); entry = mainFolderEntry.GetFolderSubEntry(AssetDatabase.AssetPathToGUID(subPrefabPath), subPrefabPath); Assert.IsNull(entry, "Prefab in addressable sub folder is not expected to be valid subAsset of main folder."); entry = subFolderEntry.GetFolderSubEntry(AssetDatabase.AssetPathToGUID(mainPrefabPath), mainPrefabPath); Assert.IsNull(entry, "Prefab in main folder is not expected to be valid subAsset of sub folder."); entry = subFolderEntry.GetFolderSubEntry(AssetDatabase.AssetPathToGUID(subPrefabPath), subPrefabPath); Assert.IsNotNull(entry, "Prefab in addressable sub folder is expected to be valid subAsset of sub folder."); } finally { //Cleanup Settings.RemoveAssetEntry(mainFolderEntry, false); Settings.RemoveAssetEntry(subFolderEntry, false); Directory.Delete(testAssetFolder, true); } } [TestCase(true)] [TestCase(false)] public void WhenGatherFolderEntries_ReturnsCorrectAssetObjects(bool includeSubObjects) { AddressableAssetEntry addrFolderEntry = null; string addressableFolderPath = GetAssetPath("TestFolder"); try { //Setup string folderGuid = CreateFolderDeep(addressableFolderPath); addrFolderEntry = Settings.CreateOrMoveEntry(folderGuid, m_testGroup, false); string testAssetPath = Path.Combine(addressableFolderPath, "testObject.asset").Replace('\\', '/'); var testAsset = TestObject.Create("testObject", testAssetPath); testAsset.AddTestSubObject(); //Test List entries = new List(); addrFolderEntry.GatherFolderEntries(entries, true, includeSubObjects, null); if (includeSubObjects) Assert.AreEqual(entries.Count, 2, "GatherFolder entries was expected to return the Asset added and its subObject"); else Assert.AreEqual(entries.Count, 1, "GatherFolder entries was expected to only return the Asset added and not its subObject"); } finally { //Cleanup Settings.RemoveAssetEntry(addrFolderEntry, false); AssetDatabase.DeleteAsset(addressableFolderPath); } } [Test] public void GetFolderSubEntry_SetsLabelsCorrectlyOnShortPath() { AddressableAssetEntry mainFolderEntry = null; string testAssetFolder = GetAssetPath("TestFolder"); try { //Setup string mainPrefabPath = Path.Combine(testAssetFolder, "mainFolder.prefab").Replace('\\', '/'); Directory.CreateDirectory(testAssetFolder); PrefabUtility.SaveAsPrefabAsset(new GameObject("mainFolderAsset"), mainPrefabPath); string mainFolderGuid = AssetDatabase.AssetPathToGUID(testAssetFolder); mainFolderEntry = Settings.CreateOrMoveEntry(mainFolderGuid, m_testGroup, false); mainFolderEntry.SetLabel("testlabel", true); //Test var entry = mainFolderEntry.GetFolderSubEntry(AssetDatabase.AssetPathToGUID(mainPrefabPath), mainPrefabPath); Assert.IsNotNull(entry, "Prefab in main folder is expected to be valid subAsset of main folder."); Assert.AreEqual(1, entry.labels.Count, "Labels should be correctly copied over when using GetFolderSubEntry"); Assert.AreEqual(testAssetFolder + "/mainFolder.prefab", entry.AssetPath, "Asset path should be correctly set when using GetFolderSubEntry"); } finally { //Cleanup Settings.RemoveAssetEntry(mainFolderEntry, false); Directory.Delete(testAssetFolder, true); } } [Test] public void GetFolderSubEntry_SetsLabelsCorrectlyOnLongPath() { AddressableAssetEntry mainFolderEntry = null; string testAssetFolder = GetAssetPath("TestFolder"); try { //Setup string extraFolderPath = Path.Combine(testAssetFolder, "secondaryFolder").Replace('\\', '/'); string mainPrefabPath = Path.Combine(extraFolderPath, "mainFolder.prefab").Replace('\\', '/'); Directory.CreateDirectory(testAssetFolder); Directory.CreateDirectory(extraFolderPath); PrefabUtility.SaveAsPrefabAsset(new GameObject("mainFolderAsset"), mainPrefabPath); string mainFolderGuid = AssetDatabase.AssetPathToGUID(testAssetFolder); mainFolderEntry = Settings.CreateOrMoveEntry(mainFolderGuid, m_testGroup, false); mainFolderEntry.SetLabel("testlabel", true); //Test var entry = mainFolderEntry.GetFolderSubEntry(AssetDatabase.AssetPathToGUID(mainPrefabPath), mainPrefabPath); Assert.IsNotNull(entry, "Prefab in main folder is expected to be valid subAsset of main folder."); Assert.AreEqual(1, entry.labels.Count, "Labels should be correctly copied over when using GetFolderSubEntry"); Assert.AreEqual(extraFolderPath + "/mainFolder.prefab", entry.AssetPath, "Asset path should be correctly set when using GetFolderSubEntry"); } finally { //Cleanup Settings.RemoveAssetEntry(mainFolderEntry, false); Directory.Delete(testAssetFolder, true); } } [Test] public void WhenClassReferencedByAddressableAssetEntryIsReloaded_CachedMainAssetTypeIsReset() { // Setup var path = GetAssetPath("resetCachedMainAssetTypeTestGroup.asset"); AddressableAssetGroup group = ScriptableObject.CreateInstance(); AddressableAssetEntry entry = new AddressableAssetEntry(m_guid, "address", null, false); group.AddAssetEntry(entry); Assert.IsNull(entry.m_cachedMainAssetType); Assert.AreEqual(typeof(UnityEngine.AddressableAssets.Tests.TestObject), entry.MainAssetType); // Test AssetDatabase.CreateAsset(group, path); Resources.UnloadAsset(group); var reloadedGroup = AssetDatabase.LoadAssetAtPath(path); var reloadedEntry = reloadedGroup.GetAssetEntry(m_guid); Assert.IsNull(reloadedEntry.m_cachedMainAssetType); // Cleanup AssetDatabase.DeleteAsset(path); } [Test] public void GatherAllAssets_WhenResourcesExist_RecurseAllIsFalse_ReturnsEntriesForValidFilesAndTopFoldersOnly() { using (new HideResourceFoldersScope()) { var resourcePath = GetAssetPath("Resources"); var subFolderPath = resourcePath + "/Subfolder"; Directory.CreateDirectory(subFolderPath); var group = Settings.FindGroup(AddressableAssetSettings.PlayerDataGroupName); var resourceEntry = Settings.CreateOrMoveEntry(AddressableAssetEntry.ResourcesName, group, false); int builtInResourcesCount = ResourcesTestUtility.GetResourcesEntryCount(Settings, false); var r1GUID = CreateAsset(resourcePath + "/testResource1.prefab", "testResource1"); var r2GUID = CreateAsset(subFolderPath + "/testResource2.prefab", "testResource2"); var entries = new List(); resourceEntry.GatherAllAssets(entries, false, false, true); // Assert var subFolderGUID = AssetDatabase.AssetPathToGUID(subFolderPath); Assert.AreEqual(2 + builtInResourcesCount, entries.Count); Assert.IsTrue(entries.Any(e => e.guid == r1GUID)); Assert.IsFalse(entries.Any(e => e.guid == r2GUID)); Assert.IsTrue(entries.Any(e => e.guid == subFolderGUID)); // Cleanup Directory.Delete(resourcePath, true); } } [Test] public void GatherAllAssets_WhenResourcesExist_RecurseAllIsTrue_ReturnsEntriesRecursivelyForValidFilesOnly() { using (new HideResourceFoldersScope()) { var resourcePath = GetAssetPath("Resources"); var subFolderPath = resourcePath + "/Subfolder"; Directory.CreateDirectory(subFolderPath); var group = Settings.FindGroup(AddressableAssetSettings.PlayerDataGroupName); var resourceEntry = Settings.CreateOrMoveEntry(AddressableAssetEntry.ResourcesName, group, false); int builtInResourcesCount = ResourcesTestUtility.GetResourcesEntryCount(Settings, true); var r1GUID = CreateAsset(resourcePath + "/testResource1.prefab", "testResource1"); var r2GUID = CreateAsset(subFolderPath + "/testResource2.prefab", "testResource2"); var entries = new List(); resourceEntry.GatherAllAssets(entries, false, true, true); // Assert var subFolderGUID = AssetDatabase.AssetPathToGUID(subFolderPath); Assert.AreEqual(2 + builtInResourcesCount, entries.Count); Assert.IsTrue(entries.Any(e => e.guid == r1GUID)); Assert.IsTrue(entries.Any(e => e.guid == r2GUID)); Assert.IsFalse(entries.Any(e => e.guid == subFolderGUID)); // Cleanup Directory.Delete(resourcePath, true); } } [Test] public void GatherAllAssets_WhenNonEmptyAddressableFolderExist_RecurseAllIsFalse_ReturnsEntriesForValidFilesAndTopFoldersOnly() { var folderAssetPath = GetAssetPath("folderAsset"); var prefabPath1 = folderAssetPath + "/testAsset1_gatherAllAssets.prefab"; var subFolderPath = folderAssetPath + "/Subfolder"; var prefabPath2 = subFolderPath + "/testAsset2_gatherAllAssets.prefab"; Directory.CreateDirectory(subFolderPath); var a1GUID = CreateAsset(prefabPath1, Path.GetFileNameWithoutExtension(prefabPath1)); var a2GUID = CreateAsset(prefabPath2, Path.GetFileNameWithoutExtension(prefabPath2)); AssetDatabase.ImportAsset(folderAssetPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); var folderAssetGUID = AssetDatabase.AssetPathToGUID(folderAssetPath); var folderAssetEntry = Settings.CreateOrMoveEntry(folderAssetGUID, m_testGroup, false); var entries = new List(); folderAssetEntry.GatherAllAssets(entries, false, false, true); // Assert var subFolderGUID = AssetDatabase.AssetPathToGUID(subFolderPath); string csvEntries = ""; if (entries.Count != 2) { foreach (AddressableAssetEntry assetEntry in entries) csvEntries += assetEntry.AssetPath + ", "; } Assert.AreEqual(2, entries.Count, $"Expected 2 (testAsset1_gatherAllAssets and testAsset2_gatherAllAssets), but was {entries.Count}: ({csvEntries})"); Assert.IsTrue(entries.Any(e => e.guid == a1GUID)); Assert.IsFalse(entries.Any(e => e.guid == a2GUID)); Assert.IsTrue(entries.Any(e => e.guid == subFolderGUID)); Assert.IsFalse(entries.Any(e => e.guid == folderAssetGUID)); // Cleanup Settings.RemoveAssetEntry(folderAssetPath); Directory.Delete(folderAssetPath, true); } [Test] public void GatherAllAssets_WhenNonEmptyAddressableFolderExist_RecurseAllIsTrue_ReturnsEntriesRecursivelyForValidFilesOnly() { var folderAssetPath = GetAssetPath("folderAsset"); var prefabPath1 = folderAssetPath + "/testAsset1_gatherAllAssets.prefab"; var subFolderPath = folderAssetPath + "/Subfolder"; var prefabPath2 = subFolderPath + "/testAsset2_gatherAllAssets.prefab"; Directory.CreateDirectory(subFolderPath); var a1GUID = CreateAsset(prefabPath1, Path.GetFileNameWithoutExtension(prefabPath1)); var a2GUID = CreateAsset(prefabPath2, Path.GetFileNameWithoutExtension(prefabPath2)); AssetDatabase.ImportAsset(folderAssetPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); var folderAssetGUID = AssetDatabase.AssetPathToGUID(folderAssetPath); var folderAssetEntry = Settings.CreateOrMoveEntry(folderAssetGUID, m_testGroup, false); var entries = new List(); folderAssetEntry.GatherAllAssets(entries, false, true, true); // Assert var subFolderGUID = AssetDatabase.AssetPathToGUID(subFolderPath); Assert.AreEqual(2, entries.Count); Assert.IsTrue(entries.Any(e => e.guid == a1GUID)); Assert.IsTrue(entries.Any(e => e.guid == a2GUID)); Assert.IsFalse(entries.Any(e => e.guid == folderAssetGUID)); Assert.IsFalse(entries.Any(e => e.guid == subFolderGUID)); // Cleanup Settings.RemoveAssetEntry(folderAssetPath); Directory.Delete(folderAssetPath, true); } [Test] public void GatherAllAssetReferenceDrawableEntries_ReturnsBuiltInScenes() { //Setup string scenePath = "TestScenePath"; var savedCache = BuiltinSceneCache.scenes; BuiltinSceneCache.scenes = new EditorBuildSettingsScene[] { new EditorBuildSettingsScene(scenePath, true) }; AddressableAssetEntry entry = Settings.CreateOrMoveEntry(AddressableAssetEntry.EditorSceneListName, m_testGroup, false); //Test List results = new List(); HashSet processed = new HashSet(); m_testGroup.GatherAllDirectAssetReferenceEntryData(results, processed); m_testGroup.GatherAllFolderSubAssetReferenceEntryData(results, processed); //Assert Assert.AreEqual(0, results.Count); //Cleanup BuiltinSceneCache.scenes = savedCache; Settings.RemoveAssetEntry(AddressableAssetEntry.EditorSceneListName, false); } [Test] public void GatherAllAssetReferenceDrawableEntries_DoesNotReturnResources() { //Setup string scenePath = "TestScenePath"; var savedCache = BuiltinSceneCache.scenes; BuiltinSceneCache.scenes = new EditorBuildSettingsScene[] { new EditorBuildSettingsScene(scenePath, true) }; AddressableAssetEntry entry = Settings.CreateOrMoveEntry(AddressableAssetEntry.ResourcesName, m_testGroup, false); //Test List results = new List(); HashSet processed = new HashSet(); m_testGroup.GatherAllDirectAssetReferenceEntryData(results, processed); m_testGroup.GatherAllFolderSubAssetReferenceEntryData(results, processed); //Assert Assert.AreEqual(0, results.Count); //Cleanup BuiltinSceneCache.scenes = savedCache; Settings.RemoveAssetEntry(AddressableAssetEntry.ResourcesName, false); } [Test] public void GatherAllAssetReferenceDrawableEntries_ReturnsFolderSubAssets() { //Setup string testAssetFolder = GetAssetPath("TestFolder"); string testAssetSubFolder = Path.Combine(testAssetFolder, "SubFolder"); string mainPrefabPath = Path.Combine(testAssetFolder, "mainFolder.prefab").Replace('\\', '/'); string subPrefabPath = Path.Combine(testAssetSubFolder, "subFolder.prefab").Replace('\\', '/'); Directory.CreateDirectory(testAssetFolder); PrefabUtility.SaveAsPrefabAsset(new GameObject("mainFolderAsset"), mainPrefabPath); Directory.CreateDirectory(testAssetSubFolder); PrefabUtility.SaveAsPrefabAsset(new GameObject("subFolderAsset"), subPrefabPath); string guid = AssetDatabase.AssetPathToGUID(testAssetFolder); AddressableAssetEntry entry = Settings.CreateOrMoveEntry(guid, m_testGroup, false); //Test List results = new List(); m_testGroup.GatherAllFolderSubAssetReferenceEntryData(results, null); //Assert Assert.AreEqual(2, results.Count); Assert.AreEqual(mainPrefabPath, results[0].AssetPath); Assert.AreEqual(subPrefabPath, results[1].AssetPath); //Cleanup Directory.Delete(testAssetFolder, true); Settings.RemoveAssetEntry(guid, false); } [Test] public void GatherAllAssetReferenceDrawableEntries_DoesNotReturnScenesInFolder_IfSceneIsInBuiltInScenes() { //Setup string testAssetFolder = GetAssetPath("TestFolder"); string testAssetSubFolder = Path.Combine(testAssetFolder, "SubFolder"); Directory.CreateDirectory(testAssetFolder); Directory.CreateDirectory(testAssetSubFolder); AssetDatabase.ImportAsset(testAssetFolder); AssetDatabase.ImportAsset(testAssetSubFolder); string mainPrefabPath = Path.Combine(testAssetFolder, "mainFolder.prefab").Replace('\\', '/'); string subPrefabPath = Path.Combine(testAssetSubFolder, "subFolder.prefab").Replace('\\', '/'); string scenePath = Path.Combine(testAssetFolder, "TestScenePath.unity").Replace('\\', '/'); var savedCache = BuiltinSceneCache.scenes; BuiltinSceneCache.scenes = new EditorBuildSettingsScene[] { new EditorBuildSettingsScene(scenePath, true) }; PrefabUtility.SaveAsPrefabAsset(new GameObject("mainFolderAsset"), mainPrefabPath); PrefabUtility.SaveAsPrefabAsset(new GameObject("subFolderAsset"), subPrefabPath); EditorSceneManager.SaveScene(EditorSceneManager.NewScene(NewSceneSetup.EmptyScene), scenePath); string guid = AssetDatabase.AssetPathToGUID(testAssetFolder); AddressableAssetEntry entry = Settings.CreateOrMoveEntry(guid, m_testGroup, false); //Test List results = new List(); HashSet processed = new HashSet(); m_testGroup.GatherAllDirectAssetReferenceEntryData(results, processed); m_testGroup.GatherAllFolderSubAssetReferenceEntryData(results, processed); //Assert Assert.AreEqual(2, results.Count); Assert.AreEqual(mainPrefabPath, results[0].AssetPath); Assert.AreEqual(subPrefabPath, results[1].AssetPath); //Cleanup DirectoryUtility.DeleteDirectory(testAssetFolder, false); BuiltinSceneCache.scenes = savedCache; Settings.RemoveAssetEntry(guid, false); } [Test] public void GatherAllAssetReferenceDrawableEntries_AddsSimpleAssetEntries() { //Setup string guid = "12345698655"; AddressableAssetEntry entry = Settings.CreateOrMoveEntry(guid, m_testGroup, false); entry.m_cachedAssetPath = "TestPath"; //Test try { List results = new List(); m_testGroup.GatherAllDirectAssetReferenceEntryData(results, null); //Assert Assert.AreEqual(1, results.Count); Assert.AreEqual(entry.AssetPath, results[0].AssetPath); } // cleanup finally { Settings.RemoveAssetEntry(guid, false); } } [Test] public void GatherResourcesEntries_GathersAllResourceEntries_IncludingLowercase() { var resourcePath = GetAssetPath("Resources"); string testAssetFolder = GetAssetPath("TestFolder"); var subFolderPath = testAssetFolder + "/resources"; string r1GUID = null; string r2GUID = null; try { r1GUID = CreateAsset(resourcePath + "/testResourceupper.prefab", "testResourceupper"); r2GUID = CreateAsset(subFolderPath + "/testResourcelower.prefab", "testResourcelower"); var group = Settings.FindGroup(AddressableAssetSettings.PlayerDataGroupName); var resourceEntry = Settings.CreateOrMoveEntry(AddressableAssetEntry.ResourcesName, group, false); var entries = new List(); resourceEntry.GatherResourcesEntries(entries, true, null); // Assert Assert.IsTrue(entries.Any(e => e.guid == r1GUID)); Assert.IsTrue(entries.Any(e => e.guid == r2GUID)); } finally { // Cleanup if (!string.IsNullOrEmpty(r1GUID)) Settings.RemoveAssetEntry(r1GUID); if (!string.IsNullOrEmpty(r2GUID)) Settings.RemoveAssetEntry(r2GUID); if (!string.IsNullOrEmpty(AddressableAssetEntry.ResourcesName)) Settings.RemoveAssetEntry(AddressableAssetEntry.ResourcesName); AssetDatabase.DeleteAsset(resourcePath); AssetDatabase.DeleteAsset(testAssetFolder); } } [Test] public void GetRuntimeProviderType_HandlesEmptyProviderString() { AddressableAssetEntry entry = new AddressableAssetEntry("12345698655", "Entry", null, false); Type providerType = entry.GetRuntimeProviderType(null, typeof(GameObject)); Assert.IsNull(providerType); } [Test] public void GetRuntimeProviderType_ReturnsAtlasProviderForSpriteAtlas() { AddressableAssetEntry entry = new AddressableAssetEntry("12345698655", "Entry", null, false); Type providerType = entry.GetRuntimeProviderType(typeof(AssetDatabaseProvider).FullName, typeof(SpriteAtlas)); Assert.AreEqual(typeof(AtlasSpriteProvider), providerType); } [TestCase(typeof(AssetDatabaseProvider))] [TestCase(typeof(JsonAssetProvider))] [TestCase(typeof(BundledAssetProvider))] [TestCase(typeof(AssetBundleProvider))] [TestCase(typeof(TextDataProvider))] public void GetRuntimeProviderType_ReturnsProviderTypeForNonAtlas(Type testProviderType) { AddressableAssetEntry entry = new AddressableAssetEntry("12345698655", "Entry", null, false); Type providerType = entry.GetRuntimeProviderType(testProviderType.FullName, typeof(GameObject)); Assert.AreEqual(testProviderType, providerType); } [Test] public void GetRuntimeProviderType_HandlesInvalidProviderString() { AddressableAssetEntry entry = new AddressableAssetEntry("12345698655", "Entry", null, false); Type providerType = entry.GetRuntimeProviderType("NotARealProvider", typeof(GameObject)); Assert.IsNull(providerType); } [TestCase(typeof(AssetDatabaseProvider))] [TestCase(typeof(JsonAssetProvider))] [TestCase(typeof(BundledAssetProvider))] [TestCase(typeof(AssetBundleProvider))] [TestCase(typeof(TextDataProvider))] public void GetRuntimeProviderType_HandlesNullAssetType(Type testProviderType) { AddressableAssetEntry entry = new AddressableAssetEntry("12345698655", "Entry", null, false); Type providerType = entry.GetRuntimeProviderType(testProviderType.FullName, null); Assert.AreEqual(testProviderType, providerType); } [Test] public void WhenAddressHasSquareBracketsAndGuidIsNotEmptyString_CreatingNewEntry_ThrowsError() { AddressableAssetEntry entry = new AddressableAssetEntry("12345698655", "[Entry]", null, false); LogAssert.Expect(LogType.Error, $"Address '{entry.address}' cannot contain '[ ]'."); } [Test] public void WhenAddressHasSquareBracketsAndGuidIsEmptyString_CreatingNewEntry_ThrowsNothing() { Assert.DoesNotThrow(() => new AddressableAssetEntry("", "[Entry]", null, false)); } [Test] public void WhenAddressHasSquareBracketsAndGuidIsNotEmptyString_SettingTheAddressOnExistingEntry_ThrowsError() { AddressableAssetEntry entry = new AddressableAssetEntry("12345698655", "Entry", null, false); entry.SetAddress("[Entry]"); LogAssert.Expect(LogType.Error, $"Address '{entry.address}' cannot contain '[ ]'."); } [Test] public void WhenAddressHasSquareBracketsAndGuidIsEmptyString_SettingTheAddressOnExistingEntry_ThrowsNothing() { AddressableAssetEntry entry = new AddressableAssetEntry("", "Entry", null, false); Assert.DoesNotThrow(() => entry.SetAddress("[Entry]")); } [Test] public void WhenTargetAssetNotFoundInAssetDatabase_ReloadObject() { var obj = UnityEngine.AddressableAssets.Tests.TestObject.Create("test_targetAsset"); var obj2 = UnityEngine.AddressableAssets.Tests.TestObject.Create("test_targetAsset2"); string path = GetAssetPath("test_targetAsset.asset"); AssetDatabase.CreateAsset(obj, path); AssetDatabase.SaveAssets(); var entry = new AddressableAssetEntry(AssetDatabase.AssetPathToGUID(path), "Entry", null, false); UnityEngine.Object targetAsset = entry.TargetAsset; AssetDatabase.CreateAsset(obj2, path); AssetDatabase.SaveAssets(); Assert.IsFalse(AssetDatabase.TryGetGUIDAndLocalFileIdentifier(targetAsset, out string guid, out long localId)); UnityEngine.Object targetAsset2 = entry.TargetAsset; Assert.IsTrue(AssetDatabase.TryGetGUIDAndLocalFileIdentifier(targetAsset2, out string guid2, out long localId2)); AssetDatabase.DeleteAsset(path); } #pragma warning disable 0618 [Test] public void CanConvertEntryCollectionToEntries() { Settings.DenyEntryCollectionPermission = true; var collectionPath = Path.Combine(TestFolder, "collection.asset").Replace('\\', '/'); var collection = ScriptableObject.CreateInstance(); var assetPath = GetAssetPath("test.prefab"); var assetGuid = AssetDatabase.AssetPathToGUID(assetPath); var collectionEntry = new AddressableAssetEntry(assetGuid, "TestAssetEntry", null, false); collectionEntry.m_cachedAssetPath = "TestPath"; collection.Entries.Add(collectionEntry); AssetDatabase.CreateAsset(collection, collectionPath); Settings.DenyEntryCollectionPermission = false; bool converted = this.Settings.ConvertAssetEntryCollections(new List() {collectionPath}); Assert.IsTrue(converted, "Failed to convert AssetEntryCollection to standard Group Entries"); var addedEntry = Settings.DefaultGroup.GetAssetEntry(assetGuid); Assert.IsNotNull(addedEntry, "Could not find entry in default Group."); } #pragma warning restore 0618 string CreateSpriteAtlasWithSprite() { // create a Sprite atlas, + sprite var spriteAtlasPath = GetAssetPath("testAtlas.spriteatlas"); SpriteAtlas spriteAtlas = new SpriteAtlas(); AssetDatabase.CreateAsset(spriteAtlas, spriteAtlasPath); Texture2D texture = Texture2D.whiteTexture; byte[] data = texture.EncodeToPNG(); var texturePath = GetAssetPath("testTexture.png"); File.WriteAllBytes(texturePath, data); AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); TextureImporter importer = TextureImporter.GetAtPath(texturePath) as TextureImporter; importer.textureType = TextureImporterType.Sprite; importer.spriteImportMode = SpriteImportMode.Single; importer.SaveAndReimport(); SpriteAtlasExtensions.Add(spriteAtlas, new[] {AssetDatabase.LoadAssetAtPath(texturePath)}); SpriteAtlasUtility.PackAtlases(new SpriteAtlas[] {spriteAtlas}, EditorUserBuildSettings.activeBuildTarget, false); return spriteAtlasPath; } } }