public void RunAllTestsInDocument_ShouldExtractAllTestCases()
        {
            // arrange
            var project = CreateProject("SampleTestsProject");
            var semanticModel = Substitute.For<ISemanticModel>();

            var testNode = CSharpSyntaxTree.ParseText("[TestFixture]class HelloWorldTests{" +
                                             " [Test] public void TestMethod()" +
                                             "{}" +
                                             "}");

            var testClass = testNode.GetRoot().GetClassDeclarationSyntax();
            var fixtureDetails = new TestFixtureDetails();
            var testCase = new TestCase(fixtureDetails) { SyntaxNode = testClass.GetPublicMethods().Single() };
            fixtureDetails.Cases.Add(testCase);

            _testExtractorMock.GetTestClasses(Arg.Any<CSharpSyntaxNode>())
                .Returns(new[] { testClass });

            _testExtractorMock.GetTestFixtureDetails(Arg.Any<ClassDeclarationSyntax>(), Arg.Any<ISemanticModel>()).Returns(fixtureDetails);
            var rewrittenDocument = new RewrittenDocument(testNode, null, false);

            // act
            _sut.RunAllTestsInDocument(rewrittenDocument, semanticModel, project, new string[0]);

            // assert
            _testExtractorMock.Received(1).GetTestFixtureDetails(testClass, semanticModel);
        }
        public void CalculateForAllTests_Should_CompileProvidedDocuments()
        {
            // arrange
            var rewrittenItemsByProject = new Dictionary<Project, List<RewrittenDocument>>();

            var workspace = new AdhocWorkspace();
            var project1 = workspace.AddProject("foo1.dll", LanguageNames.CSharp);

            RewriteResult rewriteResult = new RewriteResult(rewrittenItemsByProject);
            var rewrittenTree = CSharpSyntaxTree.ParseText("");

            var rewrittenDocument1 = new RewrittenDocument( rewrittenTree, null, false);
            rewriteResult.Items[project1] = new List<RewrittenDocument>() { rewrittenDocument1 };

            var compiledItem = Substitute.For<ICompiledItem>();
            compiledItem.Project.Returns(project1);
            _compiledAllItems.Add(compiledItem);

            // act
            _sut.CalculateForAllTests(rewriteResult);

            // assert
            _compilerMock.Received(1).Compile
                (Arg.Is<IEnumerable<CompilationItem>>(x => x.First().SyntaxTrees[0] ==
                rewriteResult.ToCompilationItems().First().SyntaxTrees[0]));
        }
        public void RunAllTestsInDocument_ShouldExtractAllProjectReferences_And_PassItTo_TestSandbox()
        {
            // arrange
            var project = CreateProject("SampleTestsProject");
            string[] allProjectReferences = { "A" };

            _solutionExplorerMock.GetAllProjectReferences(project.Name).Returns(allProjectReferences);
            var testNode = CSharpSyntaxTree.ParseText("[TestFixture]class HelloWorldTests{" +
                                             " [Test] public void TestMethod()" +
                                             "{}" +
                                             "}");

            var testClass = testNode.GetRoot().GetClassDeclarationSyntax();
            var fixtureDetails = new TestFixtureDetails();
            var testCase = new TestCase(fixtureDetails) { SyntaxNode = testClass.GetPublicMethods().Single() };
            fixtureDetails.Cases.Add(testCase);

            _testExtractorMock.GetTestClasses(Arg.Any<CSharpSyntaxNode>())
                .Returns(new[] { testClass });
            _testExtractorMock.GetTestFixtureDetails(testClass, Arg.Any<ISemanticModel>()).Returns(fixtureDetails);

            var rewrittenDocument = new RewrittenDocument(testNode, null, false);

            // act
            _sut.RunAllTestsInDocument(rewrittenDocument, null, project, new string[0]);

            // assert
            _testExecutorEngineMock.Received(1).
                RunTestFixture(Arg.Is<string[]>(x => x[0] == allProjectReferences[0]), Arg.Any<TestFixtureExecutionScriptParameters>());
        }
        public void GetReferencedTests_Should_ReturnDocumentContainingTest_When_CoverageWasBeforeCalculated()
        {
            // arrange
            var tree = CSharpSyntaxTree.ParseText("public class MathHelper" +
                                                  "{ public int Divide(int a,b) {return a/b;}}");
            var testTree = CSharpSyntaxTree.ParseText(@"class MathHelperTests{ public void DivideTest();}}");

            var lineCoverage = new LineCoverage
            {
                NodePath = "Math.MathHelper.MathHelper.Divide",
                TestDocumentPath = @"c:\\MathHelperTests.cs",
                TestPath = "MathTests.MathHelperTests.MathHelperTests.DivideTest"
            };

            _coverageStoreMock.ReadAll().Returns(new[] { lineCoverage });
            _solutionExplorerMock.OpenFile(lineCoverage.TestDocumentPath).Returns(testTree);

            var document = new RewrittenDocument( tree, @"c:\MathHelper.cs",false);

            // act
            RewrittenDocument[] output = _sut.GetReferencedTests(document, "Math");

            // assert
            Assert.That(output.Length,Is.EqualTo(1));
            Assert.That(output[0].DocumentPath,Is.EqualTo(lineCoverage.TestDocumentPath));
            Assert.That(output[0].SyntaxTree, Is.EqualTo(testTree));
        }
        public void CalculateForAllTests_Should_Return_OneCoverage_From_AllTests_When_There_IsOneProject_And_OneLineCoverage()
        {
            // arrange
            var rewrittenItemsByProject = new Dictionary<Project, List<RewrittenDocument>>();
            var workspace = new AdhocWorkspace();
            var project1 = workspace.AddProject("foo1.dll", LanguageNames.CSharp);

            RewriteResult rewriteResult = new RewriteResult(rewrittenItemsByProject);
            var rewrittenTree = CSharpSyntaxTree.ParseText("");

            var rewrittenDocument1 = new RewrittenDocument( rewrittenTree, null, true);
            rewriteResult.Items[project1] = new List<RewrittenDocument>() { rewrittenDocument1 };

            var semanticModel = Substitute.For<ISemanticModel>();
            var compiledItem = Substitute.For<ICompiledItem>();
            string assembly = "assembly path";

            compiledItem.Project.Returns(project1);
            compiledItem.DllPath.Returns(assembly);
            compiledItem.GetSemanticModel(rewrittenDocument1.SyntaxTree).Returns(semanticModel);
            _compiledAllItems.Add(compiledItem);

            var expectedLineCoverage = new[] {new LineCoverage()};
            _testRunnerMock.RunAllTestsInDocument(rewrittenDocument1,
                semanticModel,
                project1,
                Arg.Is<string[]>(x=>assembly==x[0]))
                .Returns(expectedLineCoverage);

            // act
            LineCoverage[] output = _sut.CalculateForAllTests(rewriteResult);

            // assert
            Assert.That(output, Is.EquivalentTo(expectedLineCoverage));
        }
        public LineCoverage[] RunTest(Project project,
            RewrittenDocument rewrittenDocument,
            MethodDeclarationSyntax method,
            ISemanticModel semanticModel,
            string[] rewrittenAssemblies)
        {
            var testClass = method.GetParentClass();
            var rewrittenTestClass =
                rewrittenDocument.SyntaxTree
                    .GetRoot()
                    .DescendantNodes()
                    .OfType<ClassDeclarationSyntax>().First(x => x.Identifier.ToString() == testClass.Identifier.ToString());

            var fixtureDetails = _testsExtractor.GetTestFixtureDetails(rewrittenTestClass, semanticModel);
            var allReferences = _solutionExplorer.GetAllProjectReferences(project.Name);

            fixtureDetails.Cases.RemoveAll(x => x.MethodName != method.Identifier.ToString());

            if (fixtureDetails.Cases.Count == 0)
                return null;

            var compiledTestInfo = new CompiledTestFixtureInfo
            {
                AllReferences = allReferences.Union(rewrittenAssemblies).ToArray(),
                TestDocumentPath = rewrittenDocument.DocumentPath,
                SemanticModel = semanticModel
            };

            var coverage = RunTestFixture(fixtureDetails, compiledTestInfo, project.Name);

            return coverage;
        }
        public LineCoverage[] RunAllTestsInDocument(RewrittenDocument rewrittenDocument,
            ISemanticModel semanticModel,
            Project project,
            string[] rewrittenAssemblies)
        {
            var allReferences = _solutionExplorer.GetAllProjectReferences(project.Name);

            var compiledTestInfo = new CompiledTestFixtureInfo
            {
                AllReferences = allReferences.Union(rewrittenAssemblies).ToArray(),
                TestDocumentPath = rewrittenDocument.DocumentPath,
                SemanticModel = semanticModel
            };

            var coverage = new List<LineCoverage>();

            var testClasses = _testsExtractor.GetTestClasses(rewrittenDocument.SyntaxTree.GetRoot());

            if (testClasses.Length == 0)
                return null;

            foreach (ClassDeclarationSyntax testClass in testClasses)
            {
                compiledTestInfo.TestClass = testClass;

                var partialCoverage = RunAllTestsInFixture(compiledTestInfo, project.Name);
                coverage.AddRange(partialCoverage);
            }

            return coverage.ToArray();
        }
        public LineCoverage[] CalculateForDocument(Project project, RewrittenDocument rewrittenDocument)
        {
            ICompiledItem[] newCompiledItems;

            string[] allAssemblies = CompileDocument(project, rewrittenDocument, out newCompiledItems);

            ISemanticModel semanticModel = newCompiledItems[0].GetSemanticModel(rewrittenDocument.SyntaxTree);
            LineCoverage[] fullCoverage = _testRunner.RunAllTestsInDocument(rewrittenDocument, semanticModel, project, allAssemblies);

            if (fullCoverage == null)
                fullCoverage = CalculateCoverageForReferencedTests(project, rewrittenDocument, allAssemblies);

            return fullCoverage.ToArray();
        }
        public LineCoverage[] CalculateForMethod(Project project, RewrittenDocument rewrittenDocument, MethodDeclarationSyntax method)
        {
            ICompiledItem[] newCompiledItems;

            string[] rewrittenAssemblies = CompileDocument(project, rewrittenDocument, out newCompiledItems);

            ISemanticModel semanticModel = newCompiledItems[0].GetSemanticModel(rewrittenDocument.SyntaxTree);
            LineCoverage[] fullCoverage = _testRunner.RunTest(project,
                rewrittenDocument,
                method,
                semanticModel, rewrittenAssemblies);

            if (fullCoverage == null)
                fullCoverage = CalculateCoverageForReferencedTests(project, rewrittenDocument, rewrittenAssemblies);

            return fullCoverage.ToArray();
        }
        public RewrittenDocument[] GetReferencedTests(RewrittenDocument document, string projectName)
        {
            var methods = document.SyntaxTree.GetRoot().GetPublicMethods();
            string documentName = Path.GetFileNameWithoutExtension(document.DocumentPath);
            var currentCoverage = _coverageStore.ReadAll();
            var rewrittenDocuments = new List<RewrittenDocument>();
            foreach (var method in methods)
            {
                string path = NodePathBuilder.BuildPath(method, documentName, projectName);

                foreach (var docCoverage in currentCoverage.Where(x => x.NodePath == path))
                {
                    if (rewrittenDocuments.All(x => x.DocumentPath != docCoverage.TestDocumentPath))
                    {
                        SyntaxTree testRoot = _solutionExplorer.OpenFile(docCoverage.TestDocumentPath);

                        var rewrittenDocument = new RewrittenDocument(testRoot, docCoverage.TestDocumentPath, false);
                        rewrittenDocuments.Add(rewrittenDocument);
                    }
                }
            }

            return rewrittenDocuments.ToArray();
        }
        public void RunAllTestsInDocument_ShouldExtractAllTestClasses()
        {
            // arrange
            var project = CreateProject("SampleTestsProject");

            var testNode = CSharpSyntaxTree.ParseText("[TestFixture]class HelloWorldTests{" +
                                             " [Test] public void TestMethod()" +
                                             "{}" +
                                             "}");

            var rewrittenDocument = new RewrittenDocument(testNode, null, false);

            // act
            _sut.RunAllTestsInDocument(rewrittenDocument, null, project, new string[0]);

            // assert
            _testExtractorMock.Received(1).GetTestClasses(testNode.GetRoot());
        }
        public void RunAllTestsInDocument_ShouldReturn_One_Line_Coverage_When_ThereIsOneClass_And_OneTestCase_And_ItContains_One_LineCoverage()
        {
            // arrange
            var testNode = CSharpSyntaxTree.ParseText("[TestFixture]class HelloWorldTests{" +
                                             " [Test] public void TestMethod()" +
                                             "{}" +
                                             "}");

            var testClass = testNode.GetRoot().GetClassDeclarationSyntax();
            var fixtureDetails = new TestFixtureDetails();
            var testCase = new TestCase(fixtureDetails) { SyntaxNode = testClass.GetPublicMethods().Single(), MethodName = "TestMethod" };
            fixtureDetails.Cases.Add(testCase);

            _testExtractorMock.GetTestClasses(Arg.Any<CSharpSyntaxNode>())
                .Returns(new[] { testClass });
            _testExtractorMock.GetTestFixtureDetails(testClass, Arg.Any<ISemanticModel>()).Returns(fixtureDetails);

            var testRunResultMock = Substitute.For<ITestRunResult>();
            testRunResultMock.TestName.Returns("TestMethod");

            var expectedLineCoverage = new[] { new LineCoverage() };

            testRunResultMock.GetCoverage(Arg.Any<SyntaxNode>(), Arg.Any<string>(),
                Arg.Any<string>())
                .Returns(expectedLineCoverage);

            _testExecutorEngineMock.RunTestFixture(Arg.Any<string[]>(), Arg.Any<TestFixtureExecutionScriptParameters>()).
                Returns(new[] { testRunResultMock });

            var project = CreateProject("SampleTestsProject");
            var rewrittenDocument = new RewrittenDocument(testNode, null, false);

            // act
            LineCoverage[] output = _sut.RunAllTestsInDocument(rewrittenDocument, null, project, new string[0]);

            // assert
            Assert.That(output, Is.SameAs(output));
        }
        public void CalculateForAllTests_Should_Return_TwoLinesCoverage_From_AllTests_When_There_AreTwoProjects_And_EachProjectHasOneLineCoverage()
        {
            // arrange
            var rewrittenItemsByProject = new Dictionary<Project, List<RewrittenDocument>>();
            var workspace = new AdhocWorkspace();
            var project1 = workspace.AddProject("foo1.dll", LanguageNames.CSharp);
            var project2 = workspace.AddProject("foo2.dll", LanguageNames.CSharp);

            RewriteResult rewriteResult = new RewriteResult(rewrittenItemsByProject);
            var rewrittenTree = CSharpSyntaxTree.ParseText("");

            var rewrittenDocument1 = new RewrittenDocument(rewrittenTree, null, true);
            rewriteResult.Items[project1] = new List<RewrittenDocument>() { rewrittenDocument1 };
            rewriteResult.Items[project2] = new List<RewrittenDocument>() { rewrittenDocument1 };

            var compiledItem1 = Substitute.For<ICompiledItem>();
            var compiledItem2 = Substitute.For<ICompiledItem>();

            compiledItem1.Project.Returns(project1);
            compiledItem2.Project.Returns(project2);

            _compiledAllItems.Add(compiledItem1);
            _compiledAllItems.Add(compiledItem2);

            var expectedLineCoverage = new[] { new LineCoverage() };
            _testRunnerMock.RunAllTestsInDocument(rewrittenDocument1,
                Arg.Any<ISemanticModel>(),
                project1,
                Arg.Any<string[]>())
                .Returns(expectedLineCoverage);

            _testRunnerMock.RunAllTestsInDocument(rewrittenDocument1,
                Arg.Any<ISemanticModel>(),
                project2,
                Arg.Any<string[]>())
                .Returns(expectedLineCoverage);

            // act
            LineCoverage[] output = _sut.CalculateForAllTests(rewriteResult);

            // assert
            Assert.That(output.Length, Is.EqualTo(2));
        }
        public void CalculateForDocument_Should_Execute_TestsInReferencedTestDocuments_When_ProvidedDocumentIsNotTestDocument()
        {
            // arrange
            var rewrittenItemsByProject = new Dictionary<Project, List<RewrittenDocument>>();
            var workspace = new AdhocWorkspace();
            var testProject = workspace.AddProject("TestProject.dll", LanguageNames.CSharp);
            var businessLogicProject = workspace.AddProject("BusinessLogicProject.dll", LanguageNames.CSharp);

            RewriteResult rewriteResult = new RewriteResult(rewrittenItemsByProject);
            var rewrittenTree = CSharpSyntaxTree.ParseText("");

            var businessLogicDocument = new RewrittenDocument( rewrittenTree, null, false);
            var testDocument = new RewrittenDocument( rewrittenTree, null, false);

            rewriteResult.Items[businessLogicProject] = new List<RewrittenDocument>() { businessLogicDocument };
            rewriteResult.Items[testProject] = new List<RewrittenDocument>() { testDocument };

            var compiledItem1 = Substitute.For<ICompiledItem>();
            compiledItem1.Project.Returns(testProject);
            _compiledSingleProjectItems.Add(compiledItem1);

            _testRunnerMock.RunAllTestsInDocument(businessLogicDocument,
                Arg.Any<ISemanticModel>(),
                businessLogicProject,
                Arg.Any<string[]>())
                .Returns((LineCoverage[])null);

            var expectedLineCoverage = new[] { new LineCoverage() };

            _testRunnerMock.RunAllTestsInDocument(testDocument,
                Arg.Any<ISemanticModel>(),
                testProject,
                Arg.Any<string[]>())
                .Returns(expectedLineCoverage);

            _testExplorerMock.GetReferencedTests(businessLogicDocument, businessLogicProject.Name)
                .Returns(new[] {testDocument});
            _solutionExplorerMock.GetProjectByDocument(testDocument.DocumentPath).Returns(testProject);

            // act
            LineCoverage[] output = _sut.CalculateForDocument(businessLogicProject, businessLogicDocument);

            // assert
            Assert.That(output, Is.EquivalentTo(expectedLineCoverage));
        }
        private LineCoverage[] CalculateCoverageForReferencedTests(Project project,
            RewrittenDocument rewrittenDocument,
            string[] allAssemblies)
        {
            List<LineCoverage> finalCoverage = new List<LineCoverage>();
            var referencedTests = _testExplorer.GetReferencedTests(rewrittenDocument, project.Name);

            foreach (RewrittenDocument referencedTest in referencedTests)
            {
                var semanticModel = _testExplorer.SolutionExplorer.GetSemanticModelByDocument(referencedTest.DocumentPath);
                var testProject = _testExplorer.SolutionExplorer.GetProjectByDocument(referencedTest.DocumentPath);

                var coverage = _testRunner.RunAllTestsInDocument(referencedTest, semanticModel, testProject, allAssemblies);
                finalCoverage.AddRange(coverage);
            }

            return finalCoverage.ToArray();
        }
        private string[] CompileDocument(Project project, RewrittenDocument rewrittenDocument, out ICompiledItem[] newItems)
        {
            List<string> assemblies = _testExplorer.SolutionExplorer.GetCompiledAssemblies(project.Name).ToList();

            SyntaxTree[] projectTrees = _testExplorer.SolutionExplorer.LoadRewrittenProjectSyntaxTrees(project, rewrittenDocument.DocumentPath).ToArray();

            var allProjectTrees = projectTrees.Union(new[] { rewrittenDocument.SyntaxTree }).ToArray();
            var compiledItems = _compiler.Compile(new CompilationItem(project, allProjectTrees), assemblies);
            assemblies.AddRange(compiledItems.Select(x => x.DllPath));

            newItems = compiledItems;

            return assemblies.ToArray();
        }