260 lines
8.4 KiB
C#
260 lines
8.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using NUnit.Framework;
|
|
using SepCore.InputModule;
|
|
using SepCore.InputModule.Runtime;
|
|
using UnityEngine;
|
|
|
|
namespace SepCore.InputModule.Tests
|
|
{
|
|
public class InputModuleComponentEventTests
|
|
{
|
|
private GameObject _gameObject;
|
|
private InputModuleComponent _component;
|
|
|
|
[SetUp]
|
|
public void SetUp()
|
|
{
|
|
_gameObject = new GameObject("InputModuleEventTest");
|
|
_component = _gameObject.AddComponent<InputModuleComponent>();
|
|
_component.OnInit();
|
|
}
|
|
|
|
[TearDown]
|
|
public void TearDown()
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(_gameObject);
|
|
}
|
|
|
|
[Test]
|
|
public void ContextChanged_FiresOnSetContext()
|
|
{
|
|
InputContextId receivedContext = InputContextId.None;
|
|
int fireCount = 0;
|
|
|
|
_component.ContextChanged += ctx =>
|
|
{
|
|
receivedContext = ctx;
|
|
fireCount++;
|
|
};
|
|
|
|
_component.SetContext(InputContextId.UI);
|
|
|
|
Assert.That(fireCount, Is.EqualTo(1));
|
|
Assert.That(receivedContext, Is.EqualTo(InputContextId.UI));
|
|
}
|
|
|
|
[Test]
|
|
public void ContextChanged_FiresOnPushContext()
|
|
{
|
|
InputContextId receivedContext = InputContextId.None;
|
|
_component.ContextChanged += ctx => receivedContext = ctx;
|
|
|
|
_component.PushContext(InputContextId.Dialog);
|
|
|
|
Assert.That(receivedContext, Is.EqualTo(InputContextId.Dialog));
|
|
}
|
|
|
|
[Test]
|
|
public void ContextChanged_FiresOnPopContext()
|
|
{
|
|
_component.PushContext(InputContextId.UI);
|
|
|
|
InputContextId receivedContext = InputContextId.None;
|
|
_component.ContextChanged += ctx => receivedContext = ctx;
|
|
|
|
_component.PopContext();
|
|
|
|
Assert.That(receivedContext, Is.EqualTo(InputContextId.None));
|
|
}
|
|
|
|
[Test]
|
|
public void ContextChanged_FiresOnClearContexts()
|
|
{
|
|
_component.SetContext(InputContextId.GameplayExplore);
|
|
|
|
InputContextId receivedContext = InputContextId.None;
|
|
_component.ContextChanged += ctx => receivedContext = ctx;
|
|
|
|
_component.ClearContexts();
|
|
|
|
Assert.That(receivedContext, Is.EqualTo(InputContextId.None));
|
|
}
|
|
|
|
[Test]
|
|
public void ContextChanged_DoesNotFireOnDuplicateSet()
|
|
{
|
|
_component.SetContext(InputContextId.UI);
|
|
|
|
int fireCount = 0;
|
|
_component.ContextChanged += _ => fireCount++;
|
|
|
|
_component.SetContext(InputContextId.UI);
|
|
|
|
Assert.That(fireCount, Is.EqualTo(0));
|
|
}
|
|
|
|
[Test]
|
|
public void CurrentContext_ReflectsStackState()
|
|
{
|
|
Assert.That(_component.CurrentContext, Is.EqualTo(InputContextId.None));
|
|
|
|
_component.SetContext(InputContextId.GameplayExplore);
|
|
Assert.That(_component.CurrentContext, Is.EqualTo(InputContextId.GameplayExplore));
|
|
|
|
_component.PushContext(InputContextId.Dialog);
|
|
Assert.That(_component.CurrentContext, Is.EqualTo(InputContextId.Dialog));
|
|
|
|
_component.PopContext();
|
|
Assert.That(_component.CurrentContext, Is.EqualTo(InputContextId.GameplayExplore));
|
|
}
|
|
|
|
[Test]
|
|
public void CurrentDeviceKind_DefaultsToUnknown()
|
|
{
|
|
Assert.That(_component.CurrentDeviceKind, Is.EqualTo(InputDeviceKind.Unknown));
|
|
}
|
|
|
|
[Test]
|
|
public void RegisterListener_AddsToInternalDictionary()
|
|
{
|
|
bool called = false;
|
|
Action<InputCommand> listener = _ => called = true;
|
|
|
|
_component.RegisterListener(InputActionId.Pause, listener);
|
|
|
|
Dictionary<InputActionId, Action<InputCommand>> listeners =
|
|
GetPrivateListenersDictionary();
|
|
|
|
Assert.That(listeners.ContainsKey(InputActionId.Pause), Is.True);
|
|
}
|
|
|
|
[Test]
|
|
public void UnregisterListener_RemovesFromInternalDictionary()
|
|
{
|
|
Action<InputCommand> listener = _ => { };
|
|
_component.RegisterListener(InputActionId.Pause, listener);
|
|
_component.UnregisterListener(InputActionId.Pause, listener);
|
|
|
|
Dictionary<InputActionId, Action<InputCommand>> listeners =
|
|
GetPrivateListenersDictionary();
|
|
|
|
Assert.That(listeners.ContainsKey(InputActionId.Pause), Is.False);
|
|
}
|
|
|
|
[Test]
|
|
public void RegisterListener_ChainsMultipleListeners()
|
|
{
|
|
int callCount = 0;
|
|
Action<InputCommand> listenerA = _ => callCount++;
|
|
Action<InputCommand> listenerB = _ => callCount++;
|
|
|
|
_component.RegisterListener(InputActionId.Confirm, listenerA);
|
|
_component.RegisterListener(InputActionId.Confirm, listenerB);
|
|
|
|
Dictionary<InputActionId, Action<InputCommand>> listeners =
|
|
GetPrivateListenersDictionary();
|
|
|
|
Assert.That(listeners.ContainsKey(InputActionId.Confirm), Is.True);
|
|
|
|
// Verify both listeners are registered by invoking the combined delegate
|
|
listeners[InputActionId.Confirm].Invoke(default);
|
|
Assert.That(callCount, Is.EqualTo(2));
|
|
}
|
|
|
|
[Test]
|
|
public void UnregisterListener_RemovesOnlySpecifiedCallback()
|
|
{
|
|
int callCount = 0;
|
|
Action<InputCommand> listenerA = _ => callCount++;
|
|
Action<InputCommand> listenerB = _ => callCount += 10;
|
|
|
|
_component.RegisterListener(InputActionId.Cancel, listenerA);
|
|
_component.RegisterListener(InputActionId.Cancel, listenerB);
|
|
_component.UnregisterListener(InputActionId.Cancel, listenerA);
|
|
|
|
Dictionary<InputActionId, Action<InputCommand>> listeners =
|
|
GetPrivateListenersDictionary();
|
|
|
|
listeners[InputActionId.Cancel].Invoke(default);
|
|
Assert.That(callCount, Is.EqualTo(10));
|
|
}
|
|
|
|
[Test]
|
|
public void RegisterListener_NullCallback_DoesNotThrow()
|
|
{
|
|
Assert.DoesNotThrow(() => _component.RegisterListener(InputActionId.Pause, null));
|
|
}
|
|
|
|
[Test]
|
|
public void UnregisterListener_NeverRegistered_DoesNotThrow()
|
|
{
|
|
Assert.DoesNotThrow(() => _component.UnregisterListener(InputActionId.Pause, _ => { }));
|
|
}
|
|
|
|
[Test]
|
|
public void PromptMap_DefaultsToDefaultPromptMap()
|
|
{
|
|
IInputPromptMap promptMap = _component.PromptMap;
|
|
|
|
Assert.That(promptMap, Is.Not.Null);
|
|
Assert.That(promptMap, Is.InstanceOf<InputModuleDefaultPromptMap>());
|
|
}
|
|
|
|
[Test]
|
|
public void PromptMap_CanBeOverridden()
|
|
{
|
|
IInputPromptMap custom = new TestPromptMap();
|
|
_component.PromptMap = custom;
|
|
|
|
Assert.That(_component.PromptMap, Is.SameAs(custom));
|
|
}
|
|
|
|
[Test]
|
|
public void TryGetPrompt_UsesDefaultMap()
|
|
{
|
|
// CurrentDeviceKind defaults to Unknown; default map has no Unknown entries
|
|
_component.PromptMap.TryGetPrompt(InputActionId.Confirm, InputDeviceKind.KeyboardMouse, out InputPrompt prompt);
|
|
|
|
Assert.That(prompt.TextLabel, Is.EqualTo("Enter"));
|
|
}
|
|
|
|
[Test]
|
|
public void TryGetPrompt_UnknownAction_ReturnsFalse()
|
|
{
|
|
bool result = _component.TryGetPrompt(InputActionId.Unknown, out InputPrompt prompt);
|
|
|
|
Assert.That(result, Is.False);
|
|
Assert.That(prompt.IsValid, Is.False);
|
|
}
|
|
|
|
[Test]
|
|
public void TryGetPrompt_NullPromptMap_ReturnsFalse()
|
|
{
|
|
_component.PromptMap = null;
|
|
|
|
bool result = _component.TryGetPrompt(InputActionId.Confirm, out InputPrompt prompt);
|
|
|
|
Assert.That(result, Is.False);
|
|
}
|
|
|
|
private Dictionary<InputActionId, Action<InputCommand>> GetPrivateListenersDictionary()
|
|
{
|
|
FieldInfo field = typeof(InputModuleComponent).GetField(
|
|
"_listeners",
|
|
BindingFlags.NonPublic | BindingFlags.Instance);
|
|
return (Dictionary<InputActionId, Action<InputCommand>>)field.GetValue(_component);
|
|
}
|
|
}
|
|
|
|
internal sealed class TestPromptMap : IInputPromptMap
|
|
{
|
|
public bool TryGetPrompt(InputActionId actionId, InputDeviceKind deviceKind, out InputPrompt prompt)
|
|
{
|
|
prompt = new InputPrompt("Test");
|
|
return true;
|
|
}
|
|
}
|
|
}
|