From f518e9670c228c52dd523ff4917831db81442210 Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Tue, 26 Mar 2024 22:19:12 +0900 Subject: [PATCH 1/3] Add and use ScreenPointStrategy and ReachableStrategy into instance field of InteractiveComponent --- Runtime/Hints/InteractiveComponentHint.cs | 4 +- Runtime/InteractiveComponent.cs | 50 ++++++++++++++++--- .../Annotations/PositionAnnotationTest.cs | 3 +- Tests/Runtime/InteractiveComponentTest.cs | 8 +-- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/Runtime/Hints/InteractiveComponentHint.cs b/Runtime/Hints/InteractiveComponentHint.cs index 0d242f7..78bef45 100644 --- a/Runtime/Hints/InteractiveComponentHint.cs +++ b/Runtime/Hints/InteractiveComponentHint.cs @@ -15,7 +15,7 @@ namespace TestHelper.Monkey.Hints public class InteractiveComponentHint : MonoBehaviour { private static readonly Color s_orange = new Color(0xef, 0x81, 0x0f); - + /// /// Color for interactive components that users can operate /// @@ -100,7 +100,7 @@ private void Refresh() foreach (var component in InteractiveComponentCollector.FindInteractableComponents()) { - var dst = component.IsReallyInteractiveFromUser(GetScreenPoint) + var dst = component.IsReachable() ? _tmpReallyInteractives : _tmpNotReallyInteractives; diff --git a/Runtime/InteractiveComponent.cs b/Runtime/InteractiveComponent.cs index 86fe3a9..5fc5fea 100644 --- a/Runtime/InteractiveComponent.cs +++ b/Runtime/InteractiveComponent.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Koji Hasegawa. +// Copyright (c) 2023-2024 Koji Hasegawa. // This software is released under the MIT License. using System; @@ -10,6 +10,7 @@ using TestHelper.Monkey.Extensions; using TestHelper.Monkey.Operators; using TestHelper.Monkey.Random; +using TestHelper.Monkey.ScreenPointStrategies; using UnityEngine; using UnityEngine.EventSystems; @@ -39,32 +40,55 @@ public class InteractiveComponent [SuppressMessage("ReSharper", "InconsistentNaming")] public GameObject gameObject => component.gameObject; + private readonly Func _getScreenPoint; + private readonly Func, bool> _isReachable; + private readonly PointerEventData _eventData = new PointerEventData(EventSystem.current); + private readonly List _results = new List(); + /// /// Constructor /// /// - public InteractiveComponent(MonoBehaviour component) + /// The function returns the screen position where raycast for the found GameObject. + /// Default is DefaultScreenPointStrategy.GetScreenPoint. + /// The function returns the GameObject is reachable from user or not. + /// Default is DefaultReachableStrategy.IsReachable. + public InteractiveComponent(MonoBehaviour component, + Func getScreenPoint = null, + Func, bool> isReachable = null) { this.component = component; + _getScreenPoint = getScreenPoint ?? DefaultScreenPointStrategy.GetScreenPoint; + _isReachable = isReachable ?? DefaultReachableStrategy.IsReachable; } /// /// Create InteractableComponent instance from GameObject. /// /// - /// The function returns the Component is interactable or not. + /// The function returns the screen position where raycast for the found GameObject. + /// Default is DefaultScreenPointStrategy.GetScreenPoint. + /// The function returns the Component is interactable or not. /// Default is DefaultComponentInteractableStrategy.IsInteractable. + /// The function returns the GameObject is reachable from user or not. + /// Default is DefaultReachableStrategy.IsReachable. /// Returns new InteractableComponent instance from GameObject. If GameObject is not interactable so, return null. public static InteractiveComponent CreateInteractableComponent(GameObject gameObject, - Func isInteractable = null) + Func getScreenPoint = null, + Func isComponentInteractable = null, + Func, bool> isReachable = null) { - isInteractable = isInteractable ?? DefaultComponentInteractableStrategy.IsInteractable; + getScreenPoint = getScreenPoint ?? DefaultScreenPointStrategy.GetScreenPoint; + isComponentInteractable = isComponentInteractable ?? DefaultComponentInteractableStrategy.IsInteractable; + isReachable = isReachable ?? DefaultReachableStrategy.IsReachable; foreach (var component in gameObject.GetComponents()) { - if (isInteractable(component)) + if (isComponentInteractable.Invoke(component)) { - return new InteractiveComponent(component); + return new InteractiveComponent(component, + getScreenPoint, + isReachable); } } @@ -78,13 +102,23 @@ public static InteractiveComponent CreateInteractableComponent(GameObject gameOb /// Specify if avoid GC memory allocation /// Specify if avoid GC memory allocation /// true: this object can control by user - [Obsolete("Use GameObjectExtensions.IsReachable() instead")] + [Obsolete("Use IsReachable() instead")] public bool IsReallyInteractiveFromUser(Func screenPointStrategy, PointerEventData eventData = null, List results = null) { return gameObject.IsReachable(screenPointStrategy, eventData, results); } + /// + /// Hit test using raycaster + /// + /// true: this object can control by user + public bool IsReachable() + { + _eventData.position = _getScreenPoint.Invoke(gameObject); + return _isReachable.Invoke(gameObject, _eventData, _results); + } + /// /// Check inner component can receive click event /// diff --git a/Tests/Runtime/Annotations/PositionAnnotationTest.cs b/Tests/Runtime/Annotations/PositionAnnotationTest.cs index 66ed024..bd81d5f 100644 --- a/Tests/Runtime/Annotations/PositionAnnotationTest.cs +++ b/Tests/Runtime/Annotations/PositionAnnotationTest.cs @@ -4,7 +4,6 @@ using System.Linq; using NUnit.Framework; using TestHelper.Attributes; -using TestHelper.Monkey.ScreenPointStrategies; namespace TestHelper.Monkey.Annotations { @@ -32,7 +31,7 @@ string name // Without no position annotations, IsReallyInteractiveFromUser() is always false because // gameObject.transform.position is not in the mesh. So IsReallyInteractiveFromUser() is true means // the position annotation work well - Assert.That(target.IsReallyInteractiveFromUser(DefaultScreenPointStrategy.GetScreenPoint), Is.True); + Assert.That(target.IsReachable(), Is.True); } } } diff --git a/Tests/Runtime/InteractiveComponentTest.cs b/Tests/Runtime/InteractiveComponentTest.cs index 3781a1d..d8e17f7 100644 --- a/Tests/Runtime/InteractiveComponentTest.cs +++ b/Tests/Runtime/InteractiveComponentTest.cs @@ -64,7 +64,7 @@ public void IsReallyInteractiveFromUser_reachableObjects_returnTrue(string targe var target = InteractiveComponentCollector.FindInteractableComponents() .First(x => x.gameObject.name == targetName); - Assert.That(target.IsReallyInteractiveFromUser(DefaultScreenPointStrategy.GetScreenPoint), Is.True); + Assert.That(target.IsReachable(), Is.True); } [TestCase("BeyondTheWall")] // Beyond the another object @@ -75,7 +75,7 @@ public void IsReallyInteractiveFromUser_unreachableObjects_returnFalse(string ta var target = InteractiveComponentCollector.FindInteractableComponents() .First(x => x.gameObject.name == targetName); - Assert.That(target.IsReallyInteractiveFromUser(DefaultScreenPointStrategy.GetScreenPoint), Is.False); + Assert.That(target.IsReachable(), Is.False); } } @@ -99,7 +99,7 @@ public async Task IsReallyInteractiveFromUser_reachableObjects_returnTrue(string var target = InteractiveComponentCollector.FindInteractableComponents() .First(x => x.gameObject.name == targetName); - Assert.That(target.IsReallyInteractiveFromUser(DefaultScreenPointStrategy.GetScreenPoint), Is.True); + Assert.That(target.IsReachable(), Is.True); } [TestCase("BeyondTheWall")] // Beyond the another object @@ -114,7 +114,7 @@ public async Task IsReallyInteractiveFromUser_unreachableObjects_returnFalse(str var target = InteractiveComponentCollector.FindInteractableComponents() .First(x => x.gameObject.name == targetName); - Assert.That(target.IsReallyInteractiveFromUser(DefaultScreenPointStrategy.GetScreenPoint), Is.False); + Assert.That(target.IsReachable(), Is.False); } [TestCase("Button", "ReceiveOnClick")] From 358efbcf0c4d17c3a16a4de892b64b9f30c86fcf Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Tue, 26 Mar 2024 22:54:39 +0900 Subject: [PATCH 2/3] Add and use ScreenPointStrategy, ComponentInteractableStrategy, and ReachableStrategy into instance field of InteractiveComponentCollector --- Runtime/GameObjectFinder.cs | 2 +- Runtime/Hints/InteractiveComponentHint.cs | 3 +- Runtime/InteractiveComponentCollector.cs | 66 +++++++++++-------- Runtime/Monkey.cs | 29 ++++---- .../Annotations/PositionAnnotationTest.cs | 2 +- .../InteractiveComponentCollectorTest.cs | 26 +++----- Tests/Runtime/InteractiveComponentTest.cs | 10 +-- Tests/Runtime/MonkeyTest.cs | 30 +++++---- Tests/Runtime/Operators/ClickOperatorTest.cs | 6 +- .../Operators/TextInputOperatorTest.cs | 4 +- .../Operators/TouchAndHoldOperatorTest.cs | 4 +- 11 files changed, 95 insertions(+), 87 deletions(-) diff --git a/Runtime/GameObjectFinder.cs b/Runtime/GameObjectFinder.cs index 3c06ec7..b589556 100644 --- a/Runtime/GameObjectFinder.cs +++ b/Runtime/GameObjectFinder.cs @@ -73,7 +73,7 @@ private enum Reason if (reachable) { - _eventData.position = _getScreenPoint(foundObject); + _eventData.position = _getScreenPoint.Invoke(foundObject); if (!_isReachable.Invoke(foundObject, _eventData, _results)) { return (null, Reason.NotReachable); diff --git a/Runtime/Hints/InteractiveComponentHint.cs b/Runtime/Hints/InteractiveComponentHint.cs index 78bef45..322bcc8 100644 --- a/Runtime/Hints/InteractiveComponentHint.cs +++ b/Runtime/Hints/InteractiveComponentHint.cs @@ -98,7 +98,8 @@ private void Refresh() { Clear(); - foreach (var component in InteractiveComponentCollector.FindInteractableComponents()) + var interactiveComponentCollector = new InteractiveComponentCollector(getScreenPoint: GetScreenPoint); + foreach (var component in interactiveComponentCollector.FindInteractableComponents()) { var dst = component.IsReachable() ? _tmpReallyInteractives diff --git a/Runtime/InteractiveComponentCollector.cs b/Runtime/InteractiveComponentCollector.cs index cc59a46..5aa8cc1 100644 --- a/Runtime/InteractiveComponentCollector.cs +++ b/Runtime/InteractiveComponentCollector.cs @@ -1,9 +1,10 @@ -// Copyright (c) 2023 Koji Hasegawa. +// Copyright (c) 2023-2024 Koji Hasegawa. // This software is released under the MIT License. using System; using System.Collections.Generic; using TestHelper.Monkey.DefaultStrategies; +using TestHelper.Monkey.ScreenPointStrategies; using UnityEngine; using UnityEngine.EventSystems; using Object = UnityEngine.Object; @@ -14,28 +15,49 @@ namespace TestHelper.Monkey /// Find InteractableComponents in the scene. /// // TODO: Rename to InteractableComponentsFinder - public static class InteractiveComponentCollector + public class InteractiveComponentCollector { + private readonly Func _getScreenPoint; + private readonly Func _isComponentInteractable; + private readonly Func, bool> _isReachable; + private readonly PointerEventData _eventData = new PointerEventData(EventSystem.current); + private readonly List _results = new List(); + + /// + /// Constructor. + /// + /// The function returns the screen position where raycast for the found GameObject. + /// Default is DefaultScreenPointStrategy.GetScreenPoint. + /// The function returns the Component is interactable or not. + /// Default is DefaultComponentInteractableStrategy.IsInteractable. + /// The function returns the GameObject is reachable from user or not. + /// Default is DefaultReachableStrategy.IsReachable. + public InteractiveComponentCollector( + Func getScreenPoint = null, + Func isComponentInteractable = null, + Func, bool> isReachable = null) + { + _getScreenPoint = getScreenPoint ?? DefaultScreenPointStrategy.GetScreenPoint; + _isComponentInteractable = isComponentInteractable ?? DefaultComponentInteractableStrategy.IsInteractable; + _isReachable = isReachable ?? DefaultReachableStrategy.IsReachable; + } + /// /// Find components attached EventTrigger or implements IEventSystemHandler in scene. /// Includes UI elements that inherit from the Selectable class, such as Button. /// /// Note: If you only need UI elements, using UnityEngine.UI.Selectable.allSelectablesArray is faster. /// - /// The function returns the Component is interactable or not. - /// Default is DefaultComponentInteractableStrategy.IsInteractable. /// Interactive components - // TODO: Change to instance method - public static IEnumerable FindInteractableComponents( - Func isInteractable = null) + public IEnumerable FindInteractableComponents() { - isInteractable = isInteractable ?? DefaultComponentInteractableStrategy.IsInteractable; - foreach (var component in FindMonoBehaviours()) { - if (isInteractable(component)) + if (_isComponentInteractable.Invoke(component)) { - yield return new InteractiveComponent(component); + yield return new InteractiveComponent(component, + _getScreenPoint, + _isReachable); } } } @@ -43,7 +65,8 @@ public static IEnumerable FindInteractableComponents( [Obsolete("Use FindInteractableComponents() instead")] public static IEnumerable FindInteractiveComponents() { - return FindInteractableComponents(); + var instance = new InteractiveComponentCollector(); + return instance.FindInteractableComponents(); } /// @@ -52,23 +75,13 @@ public static IEnumerable FindInteractiveComponents() /// /// Note: If you only need UI elements, using UnityEngine.UI.Selectable.allSelectablesArray is faster. /// - /// Function returns the screen position where monkey operators operate on for the specified gameObject /// Really interactive components - /// The function returns the GameObject is reachable from user or not. - /// Default is DefaultReachableStrategy.IsReachable. - // TODO: Change to instance method - public static IEnumerable FindReachableInteractableComponents( - Func screenPointStrategy, - Func, bool> isReachable = null) + public IEnumerable FindReachableInteractableComponents() { - isReachable = isReachable ?? DefaultReachableStrategy.IsReachable; - var data = new PointerEventData(EventSystem.current); - var results = new List(); - foreach (var interactiveComponent in FindInteractableComponents()) { - data.position = screenPointStrategy(interactiveComponent.gameObject); - if (isReachable(interactiveComponent.gameObject, data, results)) + _eventData.position = _getScreenPoint.Invoke(interactiveComponent.gameObject); + if (_isReachable.Invoke(interactiveComponent.gameObject, _eventData, _results)) { yield return interactiveComponent; } @@ -79,7 +92,8 @@ public static IEnumerable FindReachableInteractableCompone public static IEnumerable FindReallyInteractiveComponents( Func screenPointStrategy) { - return FindReachableInteractableComponents(screenPointStrategy); + var instance = new InteractiveComponentCollector(getScreenPoint: screenPointStrategy); + return instance.FindReachableInteractableComponents(); } private static IEnumerable FindMonoBehaviours() diff --git a/Runtime/Monkey.cs b/Runtime/Monkey.cs index 180ea16..2e97320 100644 --- a/Runtime/Monkey.cs +++ b/Runtime/Monkey.cs @@ -6,12 +6,10 @@ using System.Linq; using System.Threading; using Cysharp.Threading.Tasks; -using TestHelper.Monkey.DefaultStrategies; using TestHelper.Random; using TestHelper.RuntimeInternals; using UnityEngine; using UnityEngine.Assertions; -using UnityEngine.EventSystems; namespace TestHelper.Monkey { @@ -46,13 +44,18 @@ public static async UniTask Run(MonkeyConfig config, CancellationToken cancellat GameViewControlHelper.SetGizmos(true); } + var interactiveComponentCollector = new InteractiveComponentCollector( + getScreenPoint: config.ScreenPointStrategy + ); + // TODO: Set other strategies + config.Logger.Log($"Using {config.Random}"); try { while (Time.time < endTime) { - var didAct = await RunStep(config, cancellationToken); + var didAct = await RunStep(config, interactiveComponentCollector, cancellationToken); if (didAct) { lastOperationTime = Time.time; @@ -85,14 +88,16 @@ private class CoroutineRunner : MonoBehaviour /// Run a step of monkey testing. /// /// Run configuration for monkey testing + /// /// Cancellation token /// - public static async UniTask RunStep(MonkeyConfig config, CancellationToken cancellationToken = default) + public static async UniTask RunStep(MonkeyConfig config, + InteractiveComponentCollector interactiveComponentCollector, CancellationToken cancellationToken = default) { - var components = InteractiveComponentCollector + var components = interactiveComponentCollector .FindInteractableComponents() .ToList(); - var component = Lottery(ref components, config.Random, config.ScreenPointStrategy); + var component = Lottery(ref components, config.Random); if (component == null) { return false; @@ -120,20 +125,13 @@ await ScreenshotHelper.TakeScreenshot( internal static InteractiveComponent Lottery( ref List components, - IRandom random, - Func screenPointStrategy - ) + IRandom random) { if (components == null || components.Count == 0) { return null; } - Func, bool> isReachable = - DefaultReachableStrategy.IsReachable; - var eventData = new PointerEventData(EventSystem.current); - var results = new List(); - while (true) { if (components.Count == 0) @@ -142,8 +140,7 @@ Func screenPointStrategy } var next = components[random.Next(components.Count)]; - eventData.position = screenPointStrategy(next.gameObject); - if (isReachable(next.gameObject, eventData, results) && GetCanOperations(next).Any()) + if (next.IsReachable() && GetCanOperations(next).Any()) { return next; } diff --git a/Tests/Runtime/Annotations/PositionAnnotationTest.cs b/Tests/Runtime/Annotations/PositionAnnotationTest.cs index bd81d5f..c671ebe 100644 --- a/Tests/Runtime/Annotations/PositionAnnotationTest.cs +++ b/Tests/Runtime/Annotations/PositionAnnotationTest.cs @@ -24,7 +24,7 @@ public void IsReallyInteractive( string name ) { - var target = InteractiveComponentCollector + var target = new InteractiveComponentCollector() .FindInteractableComponents() .First(x => x.gameObject.name == name); diff --git a/Tests/Runtime/InteractiveComponentCollectorTest.cs b/Tests/Runtime/InteractiveComponentCollectorTest.cs index d55bd92..bd25cc2 100644 --- a/Tests/Runtime/InteractiveComponentCollectorTest.cs +++ b/Tests/Runtime/InteractiveComponentCollectorTest.cs @@ -6,7 +6,6 @@ using System.Threading.Tasks; using NUnit.Framework; using TestHelper.Attributes; -using TestHelper.Monkey.ScreenPointStrategies; namespace TestHelper.Monkey { @@ -44,7 +43,7 @@ private static IEnumerable s_interactiveObjects() [LoadScene(TestScene)] public void FindInteractiveObjects_findAllInteractiveObjects() { - var actual = InteractiveComponentCollector.FindInteractableComponents() + var actual = new InteractiveComponentCollector().FindInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_interactiveObjects())); @@ -54,8 +53,7 @@ public void FindInteractiveObjects_findAllInteractiveObjects() [LoadScene(TestScene)] public void FindInteractiveObjects_reallyInteractiveOnly_findReachableObjects() { - var actual = InteractiveComponentCollector - .FindReachableInteractableComponents(DefaultScreenPointStrategy.GetScreenPoint) + var actual = new InteractiveComponentCollector().FindReachableInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_reachableObjects)); @@ -93,7 +91,7 @@ private static IEnumerable s_interactiveObjects() [LoadScene(TestScene)] public void FindInteractiveObjects_findAllInteractiveObjects() { - var actual = InteractiveComponentCollector.FindInteractableComponents() + var actual = new InteractiveComponentCollector().FindInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_interactiveObjects())); @@ -105,8 +103,7 @@ public async Task FindInteractiveObjects_reallyInteractiveOnly_findReachableObje { await Task.Yield(); // wait for GraphicRaycaster initialization - var actual = InteractiveComponentCollector - .FindReachableInteractableComponents(DefaultScreenPointStrategy.GetScreenPoint) + var actual = new InteractiveComponentCollector().FindReachableInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_reachableObjects)); @@ -160,7 +157,7 @@ private static IEnumerable s_interactiveUiObjectsInOverlayCanvas() [LoadScene(TestScene)] public void FindInteractiveObjects_findAllInteractiveObjects() { - var actual = InteractiveComponentCollector.FindInteractableComponents() + var actual = new InteractiveComponentCollector().FindInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_interactiveUiObjectsInOverlayCanvas())); @@ -172,8 +169,7 @@ public async Task FindInteractiveObjects_reallyInteractiveOnly_findReachableObje { await Task.Yield(); // wait for GraphicRaycaster initialization - var actual = InteractiveComponentCollector - .FindReachableInteractableComponents(DefaultScreenPointStrategy.GetScreenPoint) + var actual = new InteractiveComponentCollector().FindReachableInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_reachableUiObjects)); @@ -193,7 +189,7 @@ public class ScreenSpaceCamera [LoadScene(TestScene)] public void FindInteractiveObjects_findAllInteractiveObjects() { - var actual = InteractiveComponentCollector.FindInteractableComponents() + var actual = new InteractiveComponentCollector().FindInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_interactiveUiObjects())); @@ -205,8 +201,7 @@ public async Task FindInteractiveObjects_reallyInteractiveOnly_findReachableObje { await Task.Yield(); // wait for GraphicRaycaster initialization - var actual = InteractiveComponentCollector - .FindReachableInteractableComponents(DefaultScreenPointStrategy.GetScreenPoint) + var actual = new InteractiveComponentCollector().FindReachableInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_reachableUiObjects)); @@ -226,7 +221,7 @@ public class WorldSpace [LoadScene(TestScene)] public void FindInteractiveObjects_findAllInteractiveObjects() { - var actual = InteractiveComponentCollector.FindInteractableComponents() + var actual = new InteractiveComponentCollector().FindInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_interactiveUiObjects())); @@ -238,8 +233,7 @@ public async Task FindInteractiveObjects_reallyInteractiveOnly_findReachableObje { await Task.Yield(); // wait for GraphicRaycaster initialization - var actual = InteractiveComponentCollector - .FindReachableInteractableComponents(DefaultScreenPointStrategy.GetScreenPoint) + var actual = new InteractiveComponentCollector().FindReachableInteractableComponents() .Select(x => x.gameObject.name) .ToArray(); Assert.That(actual, Is.EquivalentTo(s_reachableUiObjects)); diff --git a/Tests/Runtime/InteractiveComponentTest.cs b/Tests/Runtime/InteractiveComponentTest.cs index d8e17f7..5e93553 100644 --- a/Tests/Runtime/InteractiveComponentTest.cs +++ b/Tests/Runtime/InteractiveComponentTest.cs @@ -61,7 +61,7 @@ public void Fields() [LoadScene(TestScene)] public void IsReallyInteractiveFromUser_reachableObjects_returnTrue(string targetName) { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.IsReachable(), Is.True); @@ -72,7 +72,7 @@ public void IsReallyInteractiveFromUser_reachableObjects_returnTrue(string targe [LoadScene(TestScene)] public void IsReallyInteractiveFromUser_unreachableObjects_returnFalse(string targetName) { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.IsReachable(), Is.False); @@ -96,7 +96,7 @@ public async Task IsReallyInteractiveFromUser_reachableObjects_returnTrue(string { await Task.Yield(); // wait for GraphicRaycaster initialization - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.IsReachable(), Is.True); @@ -111,7 +111,7 @@ public async Task IsReallyInteractiveFromUser_unreachableObjects_returnFalse(str { await Task.Yield(); // wait for GraphicRaycaster initialization - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.IsReachable(), Is.False); @@ -121,7 +121,7 @@ public async Task IsReallyInteractiveFromUser_unreachableObjects_returnFalse(str [LoadScene(TestScene)] public void Tap_Tapped(string targetName, string expectedMessage) { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.CanTap(), Is.True); diff --git a/Tests/Runtime/MonkeyTest.cs b/Tests/Runtime/MonkeyTest.cs index b698c01..afba53b 100644 --- a/Tests/Runtime/MonkeyTest.cs +++ b/Tests/Runtime/MonkeyTest.cs @@ -12,7 +12,6 @@ using NUnit.Framework; using TestHelper.Attributes; using TestHelper.Monkey.Annotations; -using TestHelper.Monkey.ScreenPointStrategies; using TestHelper.Monkey.TestDoubles; using TestHelper.Random; using TestHelper.RuntimeInternals; @@ -36,7 +35,7 @@ public async Task RunStep_finish() TouchAndHoldDelayMillis = 1, // 1ms }; - var didAct = await Monkey.RunStep(config); + var didAct = await Monkey.RunStep(config, new InteractiveComponentCollector()); Assert.That(didAct, Is.EqualTo(true)); } @@ -44,7 +43,8 @@ public async Task RunStep_finish() [LoadScene(TestScene)] public async Task RunStep_noInteractiveComponent_abort() { - foreach (var component in InteractiveComponentCollector.FindInteractableComponents()) + var interactiveComponentCollector = new InteractiveComponentCollector(); + foreach (var component in interactiveComponentCollector.FindInteractableComponents()) { component.gameObject.SetActive(false); } @@ -55,7 +55,7 @@ public async Task RunStep_noInteractiveComponent_abort() TouchAndHoldDelayMillis = 1, // 1ms }; - var didAct = await Monkey.RunStep(config); + var didAct = await Monkey.RunStep(config, interactiveComponentCollector); Assert.That(didAct, Is.EqualTo(false)); } @@ -99,7 +99,8 @@ public async Task Run_cancel() [LoadScene(TestScene)] public async Task Run_noInteractiveComponent_abort() { - foreach (var component in InteractiveComponentCollector.FindInteractableComponents()) + var interactiveComponentCollector = new InteractiveComponentCollector(); + foreach (var component in interactiveComponentCollector.FindInteractableComponents()) { component.gameObject.SetActive(false); } @@ -125,7 +126,8 @@ public async Task Run_noInteractiveComponent_abort() [LoadScene(TestScene)] public async Task Run_noInteractiveComponentAndSecondsToErrorForNoInteractiveComponentIsZero_finish() { - foreach (var component in InteractiveComponentCollector.FindInteractableComponents()) + var interactiveComponentCollector = new InteractiveComponentCollector(); + foreach (var component in interactiveComponentCollector.FindInteractableComponents()) { component.gameObject.SetActive(false); } @@ -186,13 +188,13 @@ public async Task Run_withGizmos_showGizmosAndReverted() [LoadScene(TestScene)] public void Lottery_hitInteractiveComponent_returnComponent() { - var components = InteractiveComponentCollector - .FindReachableInteractableComponents(DefaultScreenPointStrategy.GetScreenPoint).ToList(); + var interactiveComponentCollector = new InteractiveComponentCollector(); + var components = interactiveComponentCollector.FindReachableInteractableComponents().ToList(); for (var i = 0; i < components.Count; i++) { var random = new StubRandom(i); var expected = components[i]; - var actual = Monkey.Lottery(ref components, random, DefaultScreenPointStrategy.GetScreenPoint); + var actual = Monkey.Lottery(ref components, random); Assert.That(actual.gameObject.name, Is.EqualTo(expected.gameObject.name)); } @@ -217,7 +219,7 @@ public void Lottery_hitNotInteractiveComponent_returnNextLotteryComponent() var random = new StubRandom(0, 1); var expected = components[2]; - var actual = Monkey.Lottery(ref components, random, DefaultScreenPointStrategy.GetScreenPoint); + var actual = Monkey.Lottery(ref components, random); Assert.That(actual.gameObject.name, Is.EqualTo(expected.gameObject.name)); Assert.That(components, Has.Count.EqualTo(3)); // Removed not interactive objects. @@ -235,7 +237,7 @@ public void Lottery_noInteractiveComponent_returnNull() components[0].gameObject.SetActive(false); var random = new StubRandom(0); - var actual = Monkey.Lottery(ref components, random, DefaultScreenPointStrategy.GetScreenPoint); + var actual = Monkey.Lottery(ref components, random); Assert.That(actual, Is.Null); Assert.That(components, Has.Count.EqualTo(0)); // Removed not interactive objects. @@ -253,7 +255,7 @@ public void Lottery_withIgnoreAnnotation_returnNull() components[0].gameObject.AddComponent(); var random = new StubRandom(0); - var actual = Monkey.Lottery(ref components, random, DefaultScreenPointStrategy.GetScreenPoint); + var actual = Monkey.Lottery(ref components, random); Assert.That(actual, Is.Null); Assert.That(components, Has.Count.EqualTo(0)); // Removed not interactive objects. @@ -273,7 +275,7 @@ public void Lottery_withIgnoreAnnotation_returnNull() [LoadScene(TestScene)] public async Task DoOperation_invokeOperationByLottery(string target, int index, string operation) { - var component = InteractiveComponentCollector.FindInteractableComponents() + var component = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == target); var spyLogger = new SpyLogger(); var config = new MonkeyConfig @@ -296,7 +298,7 @@ public async Task DoOperation_cancelDuringTouchAndHold_cancel() const int Index = 0; const string Operation = "TouchAndHold"; - var component = InteractiveComponentCollector.FindInteractableComponents() + var component = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == Target); var spyLogger = new SpyLogger(); var config = new MonkeyConfig diff --git a/Tests/Runtime/Operators/ClickOperatorTest.cs b/Tests/Runtime/Operators/ClickOperatorTest.cs index e7f76f4..bdc81ea 100644 --- a/Tests/Runtime/Operators/ClickOperatorTest.cs +++ b/Tests/Runtime/Operators/ClickOperatorTest.cs @@ -20,7 +20,7 @@ public class ClickOperatorTest [LoadScene(TestScene)] public void Click(string targetName, string expectedMessage) { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.CanClick(), Is.True); @@ -33,7 +33,7 @@ public void Click(string targetName, string expectedMessage) [LoadScene(TestScene)] public void Tap(string targetName, string expectedMessage) // Same as Click { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.CanTap(), Is.True); @@ -46,7 +46,7 @@ public void Tap(string targetName, string expectedMessage) // Same as Click [LoadScene(TestScene)] public void CanNotClick(string targetName) { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.CanClick(), Is.False); diff --git a/Tests/Runtime/Operators/TextInputOperatorTest.cs b/Tests/Runtime/Operators/TextInputOperatorTest.cs index 2eadaa0..6385323 100644 --- a/Tests/Runtime/Operators/TextInputOperatorTest.cs +++ b/Tests/Runtime/Operators/TextInputOperatorTest.cs @@ -20,7 +20,7 @@ public class TextInputOperatorTest [LoadScene(TestScene)] public void InputText(string targetName) { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.CanTextInput(), Is.True); @@ -42,7 +42,7 @@ public void InputText(string targetName) [LoadScene(TestScene)] public void CanNotInputText(string targetName) { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.CanTextInput(), Is.False); diff --git a/Tests/Runtime/Operators/TouchAndHoldOperatorTest.cs b/Tests/Runtime/Operators/TouchAndHoldOperatorTest.cs index 2b88479..44b17db 100644 --- a/Tests/Runtime/Operators/TouchAndHoldOperatorTest.cs +++ b/Tests/Runtime/Operators/TouchAndHoldOperatorTest.cs @@ -22,7 +22,7 @@ public class TouchAndHoldOperatorTest [LoadScene(TestScene)] public async Task TouchAndHold(string targetName, string expectedMessage1, string expectedMessage2) { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.CanTouchAndHold(), Is.True); @@ -36,7 +36,7 @@ public async Task TouchAndHold(string targetName, string expectedMessage1, strin [LoadScene(TestScene)] public void CanNotTouchAndHold(string targetName) { - var target = InteractiveComponentCollector.FindInteractableComponents() + var target = new InteractiveComponentCollector().FindInteractableComponents() .First(x => x.gameObject.name == targetName); Assert.That(target.CanTouchAndHold(), Is.False); From 6214d44b6b989c2bd627c6874369b2cf1062456e Mon Sep 17 00:00:00 2001 From: Koji Hasegawa Date: Tue, 26 Mar 2024 23:25:40 +0900 Subject: [PATCH 3/3] Remove screen-point-strategy from parameter of InteractiveComponent operator methods Use instance field of InteractiveComponent --- Runtime/InteractiveComponent.cs | 13 ++++--------- Runtime/Monkey.cs | 3 +-- Tests/Runtime/InteractiveComponentTest.cs | 3 +-- Tests/Runtime/Operators/ClickOperatorTest.cs | 5 ++--- Tests/Runtime/Operators/TouchAndHoldOperatorTest.cs | 3 +-- 5 files changed, 9 insertions(+), 18 deletions(-) diff --git a/Runtime/InteractiveComponent.cs b/Runtime/InteractiveComponent.cs index 5fc5fea..35d5d1d 100644 --- a/Runtime/InteractiveComponent.cs +++ b/Runtime/InteractiveComponent.cs @@ -128,9 +128,7 @@ public bool IsReachable() /// /// Click inner component /// - /// Function returns the screen position where monkey operators operate on for the specified gameObject - public void Click(Func screenPointStrategy = null) => - ClickOperator.Click(component, screenPointStrategy); + public void Click() => ClickOperator.Click(component, _getScreenPoint); /// /// Check inner component can receive tap (click) event @@ -141,9 +139,7 @@ public void Click(Func screenPointStrategy = null) => /// /// Tap (click) inner component /// - /// Function returns the screen position where monkey operators operate on for the specified gameObject - public void Tap(Func screenPointStrategy = null) => - ClickOperator.Click(component, screenPointStrategy); + public void Tap() => ClickOperator.Click(component, _getScreenPoint); /// /// Check inner component can receive touch-and-hold event @@ -157,9 +153,8 @@ public void Tap(Func screenPointStrategy = null) => /// Function returns the screen position where monkey operators operate on for the specified gameObject /// Delay time between down to up /// Task cancellation token - public async UniTask TouchAndHold(Func screenPointStrategy = null, int delayMillis = 1000, - CancellationToken cancellationToken = default) - => await TouchAndHoldOperator.TouchAndHold(component, screenPointStrategy, delayMillis, cancellationToken); + public async UniTask TouchAndHold(int delayMillis = 1000, CancellationToken cancellationToken = default) + => await TouchAndHoldOperator.TouchAndHold(component, _getScreenPoint, delayMillis, cancellationToken); /// /// Check inner component can input text diff --git a/Runtime/Monkey.cs b/Runtime/Monkey.cs index 2e97320..86ba328 100644 --- a/Runtime/Monkey.cs +++ b/Runtime/Monkey.cs @@ -175,11 +175,10 @@ internal static async UniTask DoOperation( switch (operation) { case SupportOperation.Click: - component.Click(config.ScreenPointStrategy); + component.Click(); break; case SupportOperation.TouchAndHold: await component.TouchAndHold( - config.ScreenPointStrategy, config.TouchAndHoldDelayMillis, cancellationToken ); diff --git a/Tests/Runtime/InteractiveComponentTest.cs b/Tests/Runtime/InteractiveComponentTest.cs index 5e93553..3c03c1d 100644 --- a/Tests/Runtime/InteractiveComponentTest.cs +++ b/Tests/Runtime/InteractiveComponentTest.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using NUnit.Framework; using TestHelper.Attributes; -using TestHelper.Monkey.ScreenPointStrategies; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.TestTools; @@ -125,7 +124,7 @@ public void Tap_Tapped(string targetName, string expectedMessage) .First(x => x.gameObject.name == targetName); Assert.That(target.CanTap(), Is.True); - target.Tap(DefaultScreenPointStrategy.GetScreenPoint); + target.Tap(); LogAssert.Expect(LogType.Log, $"{targetName}.{expectedMessage}"); } diff --git a/Tests/Runtime/Operators/ClickOperatorTest.cs b/Tests/Runtime/Operators/ClickOperatorTest.cs index bdc81ea..79e1047 100644 --- a/Tests/Runtime/Operators/ClickOperatorTest.cs +++ b/Tests/Runtime/Operators/ClickOperatorTest.cs @@ -4,7 +4,6 @@ using System.Linq; using NUnit.Framework; using TestHelper.Attributes; -using TestHelper.Monkey.ScreenPointStrategies; using UnityEngine; using UnityEngine.TestTools; @@ -24,7 +23,7 @@ public void Click(string targetName, string expectedMessage) .First(x => x.gameObject.name == targetName); Assert.That(target.CanClick(), Is.True); - target.Click(DefaultScreenPointStrategy.GetScreenPoint); + target.Click(); LogAssert.Expect(LogType.Log, $"{targetName}.{expectedMessage}"); } @@ -37,7 +36,7 @@ public void Tap(string targetName, string expectedMessage) // Same as Click .First(x => x.gameObject.name == targetName); Assert.That(target.CanTap(), Is.True); - target.Tap(DefaultScreenPointStrategy.GetScreenPoint); + target.Tap(); LogAssert.Expect(LogType.Log, $"{targetName}.{expectedMessage}"); } diff --git a/Tests/Runtime/Operators/TouchAndHoldOperatorTest.cs b/Tests/Runtime/Operators/TouchAndHoldOperatorTest.cs index 44b17db..ea6831a 100644 --- a/Tests/Runtime/Operators/TouchAndHoldOperatorTest.cs +++ b/Tests/Runtime/Operators/TouchAndHoldOperatorTest.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using NUnit.Framework; using TestHelper.Attributes; -using TestHelper.Monkey.ScreenPointStrategies; using UnityEngine; using UnityEngine.TestTools; @@ -26,7 +25,7 @@ public async Task TouchAndHold(string targetName, string expectedMessage1, strin .First(x => x.gameObject.name == targetName); Assert.That(target.CanTouchAndHold(), Is.True); - await target.TouchAndHold(DefaultScreenPointStrategy.GetScreenPoint); + await target.TouchAndHold(); LogAssert.Expect(LogType.Log, $"{targetName}.{expectedMessage1}"); LogAssert.Expect(LogType.Log, $"{targetName}.{expectedMessage2}"); }