namespace SceneTests.GameObjects;
///
/// Pins the GameObject-level component convenience API (AddComponent,
/// GetOrAddComponent, GetComponents, the InChildren/InParent variants) which
/// wraps ComponentList with specific FindMode combinations.
///
[TestClass]
[DoNotParallelize]
public class GetComponentFamilyTest : SceneTest
{
///
/// AddComponent creates the component, honouring the startEnabled flag.
///
[TestMethod]
public void AddComponentRespectsStartEnabled()
{
var scene = new Scene();
using var sceneScope = scene.Push();
var go = scene.CreateObject();
var enabled = go.AddComponent();
Assert.IsTrue( enabled.Enabled );
var disabled = go.AddComponent( false );
Assert.IsFalse( disabled.Enabled );
Assert.AreEqual( 2, go.Components.Count );
}
///
/// GetOrAddComponent returns an existing component - even a disabled one -
/// instead of creating a duplicate, and creates one when none exists.
///
[TestMethod]
public void GetOrAddComponentReturnsExistingIncludingDisabled()
{
var scene = new Scene();
using var sceneScope = scene.Push();
var go = scene.CreateObject();
var created = go.GetOrAddComponent();
Assert.IsNotNull( created );
Assert.AreEqual( 1, go.Components.Count );
Assert.AreEqual( created, go.GetOrAddComponent() );
Assert.AreEqual( 1, go.Components.Count );
created.Enabled = false;
Assert.AreEqual( created, go.GetOrAddComponent(), "a disabled component still counts as existing" );
Assert.AreEqual( 1, go.Components.Count );
}
///
/// GetComponent skips disabled components unless includeDisabled is passed.
///
[TestMethod]
public void GetComponentIncludeDisabled()
{
var scene = new Scene();
using var sceneScope = scene.Push();
var go = scene.CreateObject();
var comp = go.AddComponent( false );
Assert.IsNull( go.GetComponent() );
Assert.AreEqual( comp, go.GetComponent( true ) );
}
///
/// GetComponents enumerates only this object's components, filtering
/// disabled ones by default.
///
[TestMethod]
public void GetComponentsFiltersDisabled()
{
var scene = new Scene();
using var sceneScope = scene.Push();
var go = scene.CreateObject();
go.AddComponent();
go.AddComponent( false );
var child = new GameObject( go );
child.AddComponent();
Assert.AreEqual( 1, go.GetComponents().Count() );
Assert.AreEqual( 2, go.GetComponents( true ).Count() );
}
///
/// GetComponentsInChildren spans self plus all descendants, with includeSelf
/// and includeDisabled narrowing/widening the search.
///
[TestMethod]
public void GetComponentsInChildrenFlags()
{
var scene = new Scene();
using var sceneScope = scene.Push();
var go = scene.CreateObject();
var selfComp = go.AddComponent();
var child = new GameObject( go );
var childComp = child.AddComponent();
var grandchild = new GameObject( child );
var grandchildComp = grandchild.AddComponent();
var disabledChild = new GameObject( go, false );
var disabledComp = disabledChild.AddComponent();
Assert.AreEqual( 3, go.GetComponentsInChildren().Count() );
Assert.AreEqual( 2, go.GetComponentsInChildren( includeSelf: false ).Count() );
Assert.AreEqual( 4, go.GetComponentsInChildren( includeDisabled: true ).Count() );
Assert.AreEqual( selfComp, go.GetComponentInChildren(), "self is searched first" );
Assert.AreEqual( childComp, go.GetComponentInChildren( includeSelf: false ) );
}
///
/// Despite the name, GetComponentsInParent searches all ancestors - a
/// grandparent's component is found from a grandchild.
///
[TestMethod]
public void GetComponentsInParentSearchesAllAncestors()
{
var scene = new Scene();
using var sceneScope = scene.Push();
var grandparent = scene.CreateObject();
var gpComp = grandparent.AddComponent();
var parent = new GameObject( grandparent );
var parentComp = parent.AddComponent();
var go = new GameObject( parent );
var selfComp = go.AddComponent();
Assert.AreEqual( 3, go.GetComponentsInParent().Count() );
Assert.AreEqual( 2, go.GetComponentsInParent( includeSelf: false ).Count() );
Assert.AreEqual( selfComp, go.GetComponentInParent() );
Assert.AreEqual( parentComp, go.GetComponentInParent( includeSelf: false ) );
var all = go.GetComponentsInParent( includeSelf: false ).ToList();
CollectionAssert.Contains( all, gpComp );
}
///
/// The includeDisabled flag on the ancestor search picks up disabled
/// components on the way up.
///
[TestMethod]
public void GetComponentInParentIncludeDisabled()
{
var scene = new Scene();
using var sceneScope = scene.Push();
var parent = scene.CreateObject();
var disabledComp = parent.AddComponent( false );
var go = new GameObject( parent );
Assert.IsNull( go.GetComponentInParent() );
Assert.AreEqual( disabledComp, go.GetComponentInParent( includeDisabled: true ) );
}
}
///
/// Bare component used by the GetComponent family tests.
///
public class FamilyProbeComponent : Component
{
}