using System; using System.Collections.Generic; using System.IO; using System.Reflection; using NUnit.Framework; using UnityEditor.AddressableAssets.GUI; using UnityEditor.AddressableAssets.Settings; using UnityEditor.AddressableAssets.Settings.GroupSchemas; using UnityEditor.IMGUI.Controls; using UnityEngine; using UnityEngine.TestTools; namespace UnityEditor.AddressableAssets.Tests { public class AssetGroupTests : AddressableAssetTestBase { [Test] public void AddRemoveEntry() { var group = Settings.FindGroup(AddressableAssetSettings.DefaultLocalGroupName); Assert.IsNotNull(group); var entry = new AddressableAssetEntry(m_AssetGUID, "test", group, false); group.AddAssetEntry(entry); Assert.IsNotNull(group.GetAssetEntry(m_AssetGUID)); group.RemoveAssetEntry(entry); Assert.IsNull(group.GetAssetEntry(m_AssetGUID)); } [Test] public void RenameSlashesBecomeDashes() { var group = Settings.FindGroup(AddressableAssetSettings.DefaultLocalGroupName); var oldName = group.Name; group.Name = "folder/name"; Assert.AreEqual("folder-name", group.Name); group.Name = oldName; } [Test] public void RenameInvalidCharactersFails() { var group = Settings.FindGroup(AddressableAssetSettings.DefaultLocalGroupName); var oldName = group.Name; string badName = "*#?@>!@*@(#"; LogAssert.Expect(LogType.Error, "Rename of Group failed. Invalid file name: '" + badName + ".asset'"); group.Name = badName; Assert.AreEqual(oldName, group.Name); } [Test] public void RenameAlwaysSetsObjectName() { var group = Settings.FindGroup(AddressableAssetSettings.DefaultLocalGroupName); var oldName = group.Name; group.name = "mismatchName"; Assert.AreNotEqual(oldName, group.name); group.Name = oldName; Assert.AreEqual(oldName, group.name); Assert.AreEqual(oldName, group.Name); } [Test] public void DedupeEntries_WhenGroupsHaveOverlappingAssetEntries_RemovesEntries() { const string guid = "0000"; const string address = "not/a/real/address"; AddressableAssetGroup group1 = Settings.CreateGroup("group1", false, false, true, null, new Type[] { }); AddressableAssetGroup group2 = Settings.CreateGroup("group2", false, false, true, null, new Type[] { }); //We're making 2 identical enteries. This is to simulate each group having it's own copy of an AA Entry that references the same object. //If we use the same object the call to AddAssetEntry won't give us the state we're looking for. AddressableAssetEntry entry = new AddressableAssetEntry(guid, address, group1, false); AddressableAssetEntry entry2 = new AddressableAssetEntry(guid, address, group2, false); group1.AddAssetEntry(entry); group2.AddAssetEntry(entry2); //Ensuring our setup is correct Assert.IsNotNull(group1.GetAssetEntry(guid)); Assert.IsNotNull(group2.GetAssetEntry(guid)); group1.DedupeEnteries(); //We setup our entry with group1 so it should retain its reference group2.DedupeEnteries(); //The entry was added to group2 afterwards and should lose its reference Assert.IsNotNull(group1.GetAssetEntry(guid)); Assert.IsNull(group2.GetAssetEntry(guid)); //Cleanup Settings.RemoveGroup(group1); Settings.RemoveGroup(group2); } [Test] public void RemoveEntries_InvokesModificationNotification() { AddressableAssetGroup group1 = Settings.CreateGroup("group1", false, false, true, null, new Type[] { }); List entries = new List(); for (int i = 0; i < 10; i++) group1.AddAssetEntry(new AddressableAssetEntry("000" + i.ToString(), "unknown" + i.ToString(), group1, false)); List callbackEntries = new List(); Action callback = (x, y, z) => callbackEntries.AddRange((AddressableAssetEntry[])z); AddressableAssetSettings.OnModificationGlobal += callback; group1.RemoveAssetEntries(entries.ToArray()); for (int i = 0; i < entries.Count; i++) Assert.AreEqual(entries[i], callbackEntries[i]); //Cleanup AddressableAssetSettings.OnModificationGlobal -= callback; Settings.RemoveGroup(group1); } [Test] public void SupportsPeriodInName() { //Setup var group = Settings.CreateGroup("name1", false, false, false, new List()); //Test string testName = group.Name = "test1.test"; //Assert Assert.AreEqual(group.name, group.Name); Assert.AreEqual(testName, group.Name); //Cleanup Settings.RemoveGroup(group); } [Test] public void CannotSetInvalidGroupAsDefault() { AddressableAssetGroup group1 = Settings.CreateGroup("group1", false, true, true, null, new Type[] { }); LogAssert.Expect(LogType.Error, "Unable to set " + group1.Name + " as the Default Group. Default Groups must not be ReadOnly."); Settings.DefaultGroup = group1; Assert.AreNotEqual(Settings.DefaultGroup, group1); //Cleanup Settings.RemoveGroup(group1); } [Test] public void DefaultGroupContainsCorrectProperties() { Assert.IsFalse(Settings.DefaultGroup.ReadOnly); } [Test] public void DefaultGroupChangesToValidDefaultGroup() { LogAssert.ignoreFailingMessages = true; AddressableAssetGroup oldDefault = Settings.DefaultGroup; oldDefault.m_ReadOnly = true; AddressableAssetGroup newDefault = Settings.DefaultGroup; Assert.AreNotEqual(oldDefault, newDefault); Assert.IsFalse(Settings.DefaultGroup.ReadOnly); //Cleanup oldDefault.AddSchema(); Settings.DefaultGroup = oldDefault; } [Test] public void PreventNullDefaultGroup() { LogAssert.Expect(LogType.Error, "Unable to set null as the Default Group. Default Groups must not be ReadOnly."); Settings.DefaultGroup = null; Assert.IsNotNull(Settings.DefaultGroup); } [Test] public void ValidGroupsCanBeSetAsDefault() { AddressableAssetGroup oldDefault = Settings.DefaultGroup; AddressableAssetGroup group1 = Settings.CreateGroup("group1", false, false, true, null, new Type[] {typeof(BundledAssetGroupSchema)}); Settings.DefaultGroup = group1; Assert.AreEqual(group1, Settings.DefaultGroup); //Cleanup Settings.DefaultGroup = oldDefault; Settings.RemoveGroup(group1); } [Test] public void ResourcesEntry_AddsCorrectTreeViewItem_ForSubobjects() { using (new HideResourceFoldersScope()) { //Setup string assetPath = "SubFolder/Cube.prefab"; int builtInPackagesResourcesCount = ResourcesTestUtility.GetResourcesEntryCount(Settings, true); CreatePrefabInResourcesSubFolder(assetPath); AddressableAssetEntryTreeView treeView = new AddressableAssetEntryTreeView( new TreeViewState(), new MultiColumnHeaderState(new MultiColumnHeaderState.Column[2]), new AddressableAssetsSettingsGroupEditor(new AddressableAssetsWindow())); //Test AddressableAssetEntry entry = Settings.FindAssetEntry("Resources"); AssetEntryTreeViewItem treeViewItem = new AssetEntryTreeViewItem(entry, 0); treeView.RecurseEntryChildren(entry, treeViewItem, 0); //Assert Assert.AreEqual(1 + builtInPackagesResourcesCount, treeViewItem.children.Count); Assert.AreEqual(assetPath.Replace(".prefab", ""), treeViewItem.children[0].displayName); //Cleanup AssetDatabase.DeleteAsset("Assets/Resources/"); } } void CreatePrefabInResourcesSubFolder(string subFolderAssetPath) { string path = $"Assets/Resources/{subFolderAssetPath}"; Directory.CreateDirectory(Path.GetDirectoryName(path)); GameObject go = new GameObject(); PrefabUtility.SaveAsPrefabAsset(go, path); } } }