using System; using System.Reflection; using JetBrains.ReSharper.TaskRunnerFramework; using MbUnit.ReSharperRunner.MbUnit; using MbUnit.ReSharperRunner.Tasks; namespace MbUnit.ReSharperRunner { internal class MbUnitRecursiveTaskRunner : RecursiveRemoteTaskRunner { private TaskExecutionNode currentNode; private readonly IMbUnitTestActionRunner actionRunner; private TaskResult globalResult = TaskResult.Success; private PlugInAssemblyResolver resolver; public MbUnitRecursiveTaskRunner(IRemoteTaskServer server) : base(server) { resolver = new PlugInAssemblyResolver(); AppDomain.CurrentDomain.AssemblyResolve+=CurrentDomain_OnAssemblyResolve; // Late Binding Type type = Type.GetType("MbUnit.ReSharperRunner.MbUnit.MbUnitTestActionRunner"); actionRunner = (IMbUnitTestActionRunner)Activator.CreateInstance(type); actionRunner.RunResult += OnRunResult; } private Assembly CurrentDomain_OnAssemblyResolve(object sender, ResolveEventArgs args) { return resolver.Resolve(sender, args); } ~MbUnitRecursiveTaskRunner() { AppDomain.CurrentDomain.AssemblyResolve-=CurrentDomain_OnAssemblyResolve; } private void OnRunResult(object sender, MbUnitRunEventArgs e) { string className = TestHelper.GetClassName(e.Name); string[] methodNames = TestHelper.GetMethodNames(e.Name); foreach (string methodName in methodNames) { DoResultMethod(string.Format("{0}.{1}", className, methodName), e); } } private void DoResultMethod(string methodName, MbUnitRunEventArgs e) { RemoteTask task = FindRemoteTask(methodName); if (task != null) { OutputTask(task, e); string message = string.Empty; TaskResult result = e.Result; switch (result) { case TaskResult.Success: message = string.Format("{0} ms", e.Duration); break; case TaskResult.Skipped: break; case TaskResult.Error: message = e.Description; Server.TaskError(task, message); break; case TaskResult.Exception: Server.TaskException(task, e.Exceptions); if (e.Exceptions.Length > 0) { message = e.Exceptions[0].Message; } break; } Server.TaskFinished(task, message, result); if (globalResult != TaskResult.Error) { globalResult = result; } } } private void OutputTask(RemoteTask task, MbUnitRunEventArgs run) { if (!string.IsNullOrEmpty(run.ConsoleOut)) { Server.TaskOutput(task, run.ConsoleOut, TaskOutputType.STDOUT); } if (!string.IsNullOrEmpty(run.ConsoleError)) { Server.TaskOutput(task, run.ConsoleError, TaskOutputType.STDERR); } } private RemoteTask FindRemoteTask(string runName) { return FindRemoteTask(currentNode, runName); } private static RemoteTask FindRemoteTask(TaskExecutionNode node, string runName) { foreach (TaskExecutionNode executionNode in node.Children) { RemoteTask task = FindRemoteTask(executionNode, runName); if (task != null) { return task; } } MbUnitRemoteTask remoteTask = node.RemoteTask as MbUnitRemoteTask; string runName2 = runName.EndsWith("()") ? runName.Substring(0, runName.Length - 2) : runName; if (remoteTask != null) { if (remoteTask.RunName == runName || remoteTask.RunName == runName2) { return remoteTask; } } return null; } public override void ExecuteRecursive(TaskExecutionNode node) { currentNode = node; RemoteTask task = node.RemoteTask; if (task is MbUnitTestFixtureTask) { ExecuteRecursive((task as MbUnitTestFixtureTask).MbUnitTestAction); } if (task is MbUnitTestTask) { ExecuteRecursive((task as MbUnitTestTask).MbUnitTestAction); } } public void ExecuteRecursive(MbUnitTestAction testAction) { actionRunner.Execute(testAction); } public override TaskResult Execute(TaskExecutionNode node) { return TaskResult.Success; } public override TaskResult Finish(TaskExecutionNode node) { return globalResult; } public override TaskResult Start(TaskExecutionNode node) { return TaskResult.Success; } } }