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 } }