ActionDelegator.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System;
  2. using System.Linq;
  3. using UnityEngine.TestRunner.NUnitExtensions.Runner;
  4. using UnityEngine.TestTools.Logging;
  5. using UnityEngine.TestTools.TestRunner;
  6. namespace UnityEngine.TestTools.NUnitExtensions
  7. {
  8. /// <summary>
  9. /// This class delegates actions from the NUnit thread that should be executed on the main thread.
  10. /// NUnit thread calls Delegate which blocks the execution on the thread until the action is executed.
  11. /// The main thread will poll for awaiting actions (HasAction) and invoke them (Execute).
  12. /// Once the action is executed, the main thread releases the lock and executino on the NUnit thread is continued.
  13. /// </summary>
  14. internal class ActionDelegator : BaseDelegator
  15. {
  16. private Func<object> m_Action;
  17. public object Delegate(Action action)
  18. {
  19. return Delegate(() => { action(); return null; });
  20. }
  21. public object Delegate(Func<object> action)
  22. {
  23. if (m_Aborted)
  24. {
  25. return null;
  26. }
  27. AssertState();
  28. m_Context = UnityTestExecutionContext.CurrentContext;
  29. m_Signal.Reset();
  30. m_Action = action;
  31. WaitForSignal();
  32. return HandleResult();
  33. }
  34. private void AssertState()
  35. {
  36. if (m_Action != null)
  37. {
  38. throw new Exception("Action not executed yet");
  39. }
  40. }
  41. public bool HasAction()
  42. {
  43. return m_Action != null;
  44. }
  45. public void Execute(LogScope logScope)
  46. {
  47. try
  48. {
  49. SetCurrentTestContext();
  50. m_Result = m_Action();
  51. if (logScope.AnyFailingLogs())
  52. {
  53. var failingLog = logScope.FailingLogs.First();
  54. throw new UnhandledLogMessageException(failingLog);
  55. }
  56. if (logScope.ExpectedLogs.Any())
  57. throw new UnexpectedLogMessageException(LogScope.Current.ExpectedLogs.Peek());
  58. }
  59. catch (Exception e)
  60. {
  61. m_Exception = e;
  62. }
  63. finally
  64. {
  65. m_Action = null;
  66. m_Signal.Set();
  67. }
  68. }
  69. }
  70. }