You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
9.8 KiB
180 lines
9.8 KiB
using NUnit.Framework;
|
|
using System;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using UnityEditor;
|
|
using UnityEditor.Rendering;
|
|
|
|
namespace UnityEngine.Rendering.Tests
|
|
{
|
|
class RemoveComponent
|
|
{
|
|
#region Components
|
|
interface ITest { }
|
|
protected class Apple : MonoBehaviour, ITest { }
|
|
protected class Banana : MonoBehaviour, ITest { }
|
|
[RequireComponent(typeof(Apple))]
|
|
protected class AdditionalApple : MonoBehaviour, IAdditionalData, ITest { }
|
|
[RequireComponent(typeof(Banana))]
|
|
protected class AdditionalBanana : MonoBehaviour, IAdditionalData, ITest { }
|
|
[RequireComponent(typeof(Banana))]
|
|
protected class AdditionalBananaColor : MonoBehaviour, IAdditionalData, ITest { }
|
|
protected class WaterMelon : MonoBehaviour, IAdditionalData, ITest{ }
|
|
[RequireComponent(typeof(Apple), typeof(Banana))]
|
|
protected class FruitBasket : MonoBehaviour, IAdditionalData, ITest { }
|
|
#endregion
|
|
|
|
#region SetUp & TearDown
|
|
|
|
protected GameObject m_GameObject;
|
|
[SetUp]
|
|
public void SetUp()
|
|
{
|
|
m_GameObject = new("RemoveComponentTestsRoot");
|
|
}
|
|
|
|
[TearDown]
|
|
public void TearDown()
|
|
{
|
|
GameObject.DestroyImmediate(m_GameObject);
|
|
}
|
|
#endregion
|
|
|
|
protected Type[] GenericRemoveComponent(
|
|
[DisallowNull] int selectionAmount,
|
|
[DisallowNull] Type componentToRemove,
|
|
[DisallowNull] Type[] componentsToAdd,
|
|
[DisallowNull] Action<Component> removeMethod)
|
|
{
|
|
Assert.IsTrue(selectionAmount > 0, "GenericRemoveComponent should only be called with a non null selection");
|
|
|
|
//Create object to select
|
|
GameObject[] selectedGameObjects = new GameObject[selectionAmount];
|
|
for (int i = 0; i < selectionAmount; ++i)
|
|
{
|
|
(selectedGameObjects[i] = new GameObject($"Selected_{i}", componentsToAdd)).transform.parent = m_GameObject.transform;
|
|
}
|
|
|
|
//update selected objects
|
|
Selection.objects = selectedGameObjects;
|
|
|
|
//Call method to test
|
|
removeMethod(Selection.activeGameObject.GetComponent(componentToRemove));
|
|
|
|
//Assert all selection have same component
|
|
var typesOfFirstSelected = selectedGameObjects[0].GetComponents<ITest>().Select(c => c.GetType());
|
|
Assert.IsTrue(DoesAllGameObjectHaveSameComponents(selectedGameObjects.Skip(1), typesOfFirstSelected), "Not all the GameObject of the selection have same Components");
|
|
|
|
//Will assert that remaining components are the desired ones
|
|
return typesOfFirstSelected.ToArray();
|
|
}
|
|
|
|
bool DoesAllGameObjectHaveSameComponents([NotNull] System.Collections.Generic.IEnumerable<GameObject> objectsToCheck, System.Collections.Generic.IEnumerable<Type> typesToCheck)
|
|
{
|
|
var typeAmount = typesToCheck.Count();
|
|
foreach(var objectToCheck in objectsToCheck)
|
|
{
|
|
if (objectToCheck.GetComponents<ITest>().Length != typeAmount)
|
|
return false;
|
|
|
|
foreach (var typeToCheck in typesToCheck)
|
|
if (!objectToCheck.TryGetComponent(typeToCheck, out _))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
[TestOf(typeof(RemoveComponentUtils))]
|
|
class RemoveComponentUtilsTests : RemoveComponent
|
|
{
|
|
//No multiedition test needed as this is not Selection dependant
|
|
static TestCaseData[] s_RemoveComponentTestCaseDatas =
|
|
{
|
|
new TestCaseData(typeof(Banana), new Type[] {typeof(Banana), typeof(AdditionalBanana)})
|
|
.SetName("Removal of target component removes it's additional data")
|
|
.Returns(Array.Empty<Type>()),
|
|
new TestCaseData(typeof(Banana), new Type[] {typeof(Banana), typeof(AdditionalBanana), typeof(AdditionalBananaColor)})
|
|
.SetName("Removal of target component removes all it's additional datas")
|
|
.Returns(Array.Empty<Type>()),
|
|
new TestCaseData(typeof(Apple), new Type[] {typeof(Banana), typeof(AdditionalBanana), typeof(Apple), typeof(AdditionalApple)})
|
|
.SetName("Given multiple components, each with additional datas, the removal of the component only removes its additional datas")
|
|
.Returns(new Type[] {typeof(Banana), typeof(AdditionalBanana) }),
|
|
};
|
|
|
|
[Test, TestCaseSource(nameof(s_RemoveComponentTestCaseDatas))]
|
|
public Type[] RemoveComponentAndPropagateTheDeleteToAdditionalDatas([DisallowNull] Type componentToRemove, [DisallowNull] Type[] componentsToAdd)
|
|
{
|
|
return GenericRemoveComponent(1, componentToRemove, componentsToAdd, RemoveComponentUtils.RemoveComponent);
|
|
}
|
|
}
|
|
|
|
[TestOf(typeof(RemoveAdditionalDataUtils))]
|
|
class RemoveAdditionalDataUtilsTests : RemoveComponent
|
|
{
|
|
//No multiedition test needed as this is not Selection dependant
|
|
static TestCaseData[] s_TryGetComponentsToRemoveTestCaseDatas =
|
|
{
|
|
new TestCaseData(typeof(AdditionalBanana))
|
|
.Returns(new string[] {"Banana"})
|
|
.SetName("For additional data targeting one component, return the targeted component (most common case)"),
|
|
new TestCaseData(typeof(FruitBasket))
|
|
.Returns(new string[] { "Apple", "Banana" })
|
|
.SetName("For additional data targeting multiple components, return all the targeted components"),
|
|
new TestCaseData(typeof(WaterMelon))
|
|
.Returns(Array.Empty<string>())
|
|
.SetName("For additional data targetting no component, return empty collection."),
|
|
};
|
|
|
|
[Test, TestCaseSource(nameof(s_TryGetComponentsToRemoveTestCaseDatas))]
|
|
public string[] TryGetComponentsToRemove([DisallowNull] Type type)
|
|
{
|
|
string[] result = Array.Empty<string>();
|
|
var additionalData = m_GameObject.AddComponent(type) as IAdditionalData;
|
|
|
|
using (ListPool<Type>.Get(out var componentsToRemove))
|
|
{
|
|
if (RemoveAdditionalDataUtils.TryGetComponentsToRemove(additionalData, componentsToRemove, out var error))
|
|
result = componentsToRemove.Select(t => t.Name).ToArray();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//No multiedition RECQUIRED: This is Selection dependent to handle correctly the popup
|
|
static TestCaseData[] s_RemoveAdditionalDataComponentTestCaseDatas =
|
|
{
|
|
new TestCaseData(1, typeof(AdditionalBanana), new Type[] {typeof(Banana), typeof(AdditionalBanana) })
|
|
.SetName("For single additional data, when removing it, the target component is deleted")
|
|
.Returns(Array.Empty<Type>()),
|
|
new TestCaseData(1, typeof(AdditionalBananaColor), new Type[] {typeof(Banana), typeof(AdditionalBanana), typeof(AdditionalBananaColor)})
|
|
.SetName("For multiple additional datas, when removing one of them, target component is deleted, and the other additional data")
|
|
.Returns(Array.Empty<Type>()),
|
|
new TestCaseData(1, typeof(AdditionalBananaColor), new Type[] {typeof(Banana), typeof(Banana), typeof(AdditionalBanana), typeof(AdditionalBananaColor)})
|
|
.SetName("For multiple additional component and datas, when removing one of them everything is removed")
|
|
.Returns(Array.Empty<Type>()),
|
|
new TestCaseData(1, typeof(AdditionalApple), new Type[] {typeof(Banana), typeof(AdditionalBanana), typeof(Apple), typeof(AdditionalApple)})
|
|
.SetName("For multiple types of target component, when deleting an additional data, only the target component is being removed")
|
|
.Returns(new Type[] {typeof(Banana), typeof(AdditionalBanana)}),
|
|
new TestCaseData(3, typeof(AdditionalBanana), new Type[] {typeof(Banana), typeof(AdditionalBanana) })
|
|
.SetName("For single additional data, when removing it, the target component is deleted (multiedition case)")
|
|
.Returns(Array.Empty<Type>()),
|
|
new TestCaseData(3, typeof(AdditionalBananaColor), new Type[] {typeof(Banana), typeof(AdditionalBanana), typeof(AdditionalBananaColor)})
|
|
.SetName("For multiple additional datas, when removing one of them, target component is deleted, and the other additional data (multiedition case)")
|
|
.Returns(Array.Empty<Type>()),
|
|
new TestCaseData(3, typeof(AdditionalBananaColor), new Type[] {typeof(Banana), typeof(Banana), typeof(AdditionalBanana), typeof(AdditionalBananaColor)})
|
|
.SetName("For multiple additional component and datas, when removing one of them everything is removed (multiedition case)")
|
|
.Returns(Array.Empty<Type>()),
|
|
new TestCaseData(3, typeof(AdditionalApple), new Type[] {typeof(Banana), typeof(AdditionalBanana), typeof(Apple), typeof(AdditionalApple)})
|
|
.SetName("For multiple types of target component, when deleting an additional data, only the target component is being removed (multiedition case)")
|
|
.Returns(new Type[] {typeof(Banana), typeof(AdditionalBanana)})
|
|
};
|
|
|
|
[Test, TestCaseSource(nameof(s_RemoveAdditionalDataComponentTestCaseDatas))]
|
|
[NUnit.Framework.Property("FogBugz", "1396805")]
|
|
[NUnit.Framework.Property("Jira", "UUM-5452")]
|
|
public Type[] RemoveAdditionalDataComponentAndPropagateToComponent(int selectionAmount, [DisallowNull] Type componentToRemove, [DisallowNull] Type[] componentsToAdd)
|
|
{
|
|
return GenericRemoveComponent(selectionAmount, componentToRemove, componentsToAdd, c => RemoveAdditionalDataUtils.RemoveAdditionalData(new UnityEditor.MenuCommand(c), false));
|
|
}
|
|
}
|
|
}
|