using System;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection;
using JetBrains.Application;
using JetBrains.CommonControls;
using JetBrains.Metadata.Reader.API;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.Tree;
using JetBrains.ReSharper.TaskRunnerFramework;
using JetBrains.ReSharper.UnitTestExplorer;
using JetBrains.TreeModels;
using JetBrains.UI;
using JetBrains.UI.TreeView;
using JetBrains.Util;
using MbUnit.ReSharperRunner.Elements;
using MbUnit.ReSharperRunner.Explorer;
using MbUnit.ReSharperRunner.Tasks;
namespace MbUnit.ReSharperRunner
{
[UnitTestProvider]
internal class MbUnitTestProvider : IUnitTestProvider
{
internal const string ProviderId = "MbUnit_2.4";
private static readonly MbUnitTestPresenter mbUnitPresenter = new MbUnitTestPresenter();
public MbUnitTestProvider()
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_OnTypeResolve;
}
private static Assembly CurrentDomain_OnTypeResolve(object sender, ResolveEventArgs args)
{
return new PlugInAssemblyResolver().Resolve(sender, args);
}
~MbUnitTestProvider()
{
AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_OnTypeResolve;
}
#if RS45
public ProviderCustomOptionsControl GetCustomOptionsControl(ISolution solution)
{
return null;
}
#endif
///
///
/// Explores the "world", i.e. retrieves tests not associated with current solution
///
///
///
///
public void ExploreExternal(UnitTestElementConsumer consumer)
{
// throw new NotImplementedException();
}
///
///
/// Explores given solution, but not containing projects
///
///
///
///
///
public void ExploreSolution(ISolution solution, UnitTestElementConsumer consumer)
{
// throw new NotImplementedException();
}
///
///
/// Explores given compiled project
///
///
///
///
///
///
public void ExploreAssembly(IMetadataAssembly assembly, IProject project, UnitTestElementConsumer consumer)
{
if (assembly == null) throw new ArgumentNullException("assembly");
if (project == null) throw new ArgumentNullException("project");
if (consumer == null) throw new ArgumentNullException("consumer");
new MbUnitAssemblyExplorer().ExploreAssembly(this, assembly, project, consumer);
}
///
///
/// Explores given PSI file
///
///
///
///
///
///
public void ExploreFile(IFile psiFile, UnitTestElementLocationConsumer consumer, CheckForInterrupt interrupted)
{
if (psiFile == null)
{
throw new ArgumentNullException("psiFile");
}
if (consumer == null)
{
throw new ArgumentNullException("consumer");
}
psiFile.ProcessDescendants(new MbUnitFileExplorer(this, consumer, psiFile, interrupted));
}
///
///
/// Checks if given declared element is UnitTestElement
///
///
///
///
///
///
///
///
public bool IsUnitTestElement(IDeclaredElement element)
{
var testClass = element as IClass;
if ((testClass != null) && FileHelper.IsTestFixture(testClass))
{
return true;
}
var method = element as IMethod;
if (method != null)
{
testClass = method.GetContainingType() as IClass;
if (((testClass != null) && FileHelper.IsTestFixture(testClass)) &&
FileHelper.IsTestMethod(method))
{
return true;
}
}
return false;
}
#if RS45
private static readonly CLRTypeName SetUpAttribute = new CLRTypeName(AttributesNames.SetUpAttributeName);
private static readonly CLRTypeName TearDownAttribute = new CLRTypeName(AttributesNames.TearDownAttributeName);
private static readonly CLRTypeName TestFixtureSetUpAttribute = new CLRTypeName(AttributesNames.TestFixtureSetUpAttributeName);
private static readonly CLRTypeName TestFixtureTearDownAttribute = new CLRTypeName(AttributesNames.TestFixtureTearDownAttributeName);
private static readonly CLRTypeName SetUpFixtureAttribute = new CLRTypeName(AttributesNames.SetUpFixtureAttributeName);
public bool IsUnitTestStuff(IDeclaredElement element)
{
if (IsUnitTestElement(element))
{
return true;
}
var method = element as IMethod;
if (method != null)
{
if (method.HasAttributeInstance(SetUpAttribute, false))
{
return true;
}
if (method.HasAttributeInstance(TearDownAttribute, false))
{
return true;
}
if (method.HasAttributeInstance(TestFixtureSetUpAttribute, false))
{
return true;
}
if (method.HasAttributeInstance(TestFixtureTearDownAttribute, false))
{
return true;
}
if (method.HasAttributeInstance(SetUpFixtureAttribute, false))
{
return true;
}
}
return false;
}
#endif
///
///
/// Present unit test
///
///
///
///
///
///
///
public void Present(UnitTestElement element, IPresentableItem item, TreeModelNode node, PresentationState state)
{
mbUnitPresenter.UpdateItem(element, node, item, state);
}
///
///
/// Gets instance of
///
///
///
///
///
///
public RemoteTaskRunnerInfo GetTaskRunnerInfo()
{
return new RemoteTaskRunnerInfo(typeof (MbUnitRecursiveTaskRunner));
}
///
///
/// Serializes element for persistence
///
///
///
///
///
///
///
///
public string Serialize(UnitTestElement element)
{
return null;
}
///
///
/// Deserializes element from persisted string
///
///
///
///
///
///
///
///
///
public UnitTestElement Deserialize(ISolution solution, string elementString)
{
return null;
}
///
///
/// Gets task information for from element
///
///
///
///
///
///
///
///
///
public IList GetTaskSequence(UnitTestElement element, IList explicitElements)
{
var testElement = element as MbUnitTestElement;
if (testElement != null)
{
var childElement = element as MbUnitChildTestElement;
if (childElement != null)
{
MbUnitTestFixtureElement parentFixture = testElement.Fixture;
var parentElement = (MbUnitTestElement) childElement.Parent;
return new[]
{
new UnitTestTask(null, new AssemblyLoadTask(parentFixture.AssemblyLocation)),
new UnitTestTask(parentFixture,
new MbUnitTestFixtureTask(parentFixture.AssemblyLocation,
parentFixture.GetTypeClrName(),
explicitElements.Contains(parentFixture))),
new UnitTestTask(parentElement,
new MbUnitTestTask(parentFixture.GetTypeClrName(), parentElement.MethodName,
explicitElements.Contains(parentElement))),
new UnitTestTask(childElement,
new MbUnitTestTask(parentFixture.GetTypeClrName(), childElement.MethodName,
explicitElements.Contains(childElement)))
};
}
else
{
MbUnitTestFixtureElement parentFixture = testElement.Fixture;
return new[]
{
new UnitTestTask(null, new AssemblyLoadTask(parentFixture.AssemblyLocation)),
new UnitTestTask(parentFixture,
new MbUnitTestFixtureTask(parentFixture.AssemblyLocation,
parentFixture.GetTypeClrName(),
explicitElements.Contains(parentFixture))),
new UnitTestTask(testElement,
new MbUnitTestTask(parentFixture.GetTypeClrName(), testElement.MethodName,
explicitElements.Contains(testElement)))
};
}
}
var fixture = element as MbUnitTestFixtureElement;
if (fixture != null)
{
return EmptyArray.Instance;
}
throw new ArgumentException(string.Format("element is not MbUnit: '{0}'", element));
}
public int CompareUnitTestElements(UnitTestElement x, UnitTestElement y)
{
if (Equals(x, y))
{
return 0;
}
int compare = StringComparer.CurrentCultureIgnoreCase.Compare(x.GetTypeClrName(), y.GetTypeClrName());
if (compare != 0)
{
return compare;
}
if ((x is MbUnitChildTestElement) && (y is MbUnitTestElement))
{
return -1;
}
if ((y is MbUnitChildTestElement) && (x is MbUnitTestElement))
{
return 1;
}
if ((x is MbUnitTestElement) && (y is MbUnitTestFixtureElement))
{
return -1;
}
if ((y is MbUnitTestElement) && (x is MbUnitTestFixtureElement))
{
return 1;
}
if ((x is MbUnitTestFixtureElement) && (y is MbUnitTestFixtureElement))
{
return 0;
}
return 0;
}
public void ProfferConfiguration(TaskExecutorConfiguration configuration, UnitTestSession session)
{
}
///
/// ID of provider
///
///
public string ID
{
get { return ProviderId; }
}
#if RS45
public string Name
{
get { return ProviderId; }
}
public Image Icon
{
get
{
return ImageLoader.GetImage("MbUnit", new Assembly[0]);
}
}
#endif
}
}