123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using NUnit.Framework.Internal;
- using NUnit.Framework.Internal.Commands;
- using UnityEngine.TestTools;
- using UnityEngine.TestTools.Logging;
- using UnityEngine.TestTools.TestRunner;
- namespace UnityEngine.TestRunner.NUnitExtensions.Runner
- {
- class UnityLogCheckDelegatingCommand : DelegatingTestCommand, IEnumerableTestMethodCommand
- {
- static Dictionary<object, bool?> s_AttributeCache = new Dictionary<object, bool?>();
- public UnityLogCheckDelegatingCommand(TestCommand innerCommand)
- : base(innerCommand) {}
- public override TestResult Execute(ITestExecutionContext context)
- {
- using (var logScope = new LogScope())
- {
- if (ExecuteAndCheckLog(logScope, context.CurrentResult, () => innerCommand.Execute(context)))
- PostTestValidation(logScope, innerCommand, context.CurrentResult);
- }
- return context.CurrentResult;
- }
- public IEnumerable ExecuteEnumerable(ITestExecutionContext context)
- {
- if (!(innerCommand is IEnumerableTestMethodCommand enumerableTestMethodCommand))
- {
- Execute(context);
- yield break;
- }
- using (var logScope = new LogScope())
- {
- IEnumerable executeEnumerable = null;
- if (!ExecuteAndCheckLog(logScope, context.CurrentResult,
- () => executeEnumerable = enumerableTestMethodCommand.ExecuteEnumerable(context)))
- yield break;
- foreach (var step in executeEnumerable)
- {
- // do not check expected logs here - we want to permit expecting and receiving messages to run
- // across frames. (but we do always want to catch a fail immediately.)
- if (!CheckFailingLogs(logScope, context.CurrentResult))
- yield break;
- yield return step;
- }
- if (!CheckLogs(context.CurrentResult, logScope))
- yield break;
-
- PostTestValidation(logScope, innerCommand, context.CurrentResult);
- }
- }
- static bool CaptureException(TestResult result, Action action)
- {
- try
- {
- action();
- return true;
- }
- catch (Exception e)
- {
- result.RecordException(e);
- return false;
- }
- }
-
- static bool ExecuteAndCheckLog(LogScope logScope, TestResult result, Action action)
- => CaptureException(result, action) && CheckLogs(result, logScope);
- static void PostTestValidation(LogScope logScope, TestCommand command, TestResult result)
- {
- if (MustExpect(command.Test.Method.MethodInfo))
- CaptureException(result, logScope.NoUnexpectedReceived);
- }
- static bool CheckLogs(TestResult result, LogScope logScope)
- => CheckFailingLogs(logScope, result) && CheckExpectedLogs(logScope, result);
- static bool CheckFailingLogs(LogScope logScope, TestResult result)
- {
- if (!logScope.AnyFailingLogs())
- return true;
-
- var failingLog = logScope.FailingLogs.First();
- result.RecordException(new UnhandledLogMessageException(failingLog));
- return false;
- }
-
- static bool CheckExpectedLogs(LogScope logScope, TestResult result)
- {
- if (!logScope.ExpectedLogs.Any())
- return true;
-
- var expectedLog = logScope.ExpectedLogs.Peek();
- result.RecordException(new UnexpectedLogMessageException(expectedLog));
- return false;
- }
-
- static bool MustExpect(MemberInfo method)
- {
- // method
-
- var methodAttr = method.GetCustomAttributes<TestMustExpectAllLogsAttribute>(true).FirstOrDefault();
- if (methodAttr != null)
- return methodAttr.MustExpect;
-
- // fixture
-
- var fixture = method.DeclaringType;
- if (!s_AttributeCache.TryGetValue(fixture, out var mustExpect))
- {
- var fixtureAttr = fixture.GetCustomAttributes<TestMustExpectAllLogsAttribute>(true).FirstOrDefault();
- mustExpect = s_AttributeCache[fixture] = fixtureAttr?.MustExpect;
- }
-
- if (mustExpect != null)
- return mustExpect.Value;
- // assembly
-
- var assembly = fixture.Assembly;
- if (!s_AttributeCache.TryGetValue(assembly, out mustExpect))
- {
- var assemblyAttr = assembly.GetCustomAttributes<TestMustExpectAllLogsAttribute>().FirstOrDefault();
- mustExpect = s_AttributeCache[assembly] = assemblyAttr?.MustExpect;
- }
- return mustExpect == true;
- }
- }
- }
|