From a68368264a030d40795d01035dada26a9fb960a2 Mon Sep 17 00:00:00 2001 From: Christian Soltenborn Date: Thu, 28 Jun 2018 18:46:23 +0200 Subject: [PATCH] source locations for tests contained in namespaces are found again --- .../Core.Tests/Core.Tests.csproj | 1 + .../Core.Tests/GoogleTestDiscovererTests.cs | 4 + .../GoogleTestDiscovererTraitTestsBase.cs | 6 +- .../Helpers/ProcessExecutorTests.cs | 2 +- .../TestCases/TestCaseResolverTests.cs | 85 +++++++++++++++++++ .../Core/TestCases/MethodSignatureCreator.cs | 4 +- .../Core/TestCases/TestCaseDescriptor.cs | 2 +- .../Core/TestCases/TestCaseLocation.cs | 6 +- .../Core/TestCases/TestCaseResolver.cs | 10 +-- .../TestExecutorTestsBase.cs | 10 ++- .../Tests.Common/TestResources.cs | 6 +- ...soleDllTests__List_TestsOf_SampleTests.txt | 6 ++ ...eDllTests__List_TestsOf_SampleTests170.txt | 6 ++ ...tionProjectSettings_Coverage_Isolation.xml | 26 +++++- ...tionProjectSettings_Coverage_Isolation.xml | 26 +++++- SampleTests/Tests/NamespaceTests.cpp | 57 +++++++++++++ SampleTests/Tests/Tests.vcxproj | 1 + SampleTests/Tests/Tests.vcxproj.filters | 3 + SampleTests/Tests_1.7.0/Tests_1.7.0.vcxproj | 1 + .../Tests_1.7.0/Tests_1.7.0.vcxproj.filters | 3 + 20 files changed, 245 insertions(+), 20 deletions(-) create mode 100644 GoogleTestAdapter/Core.Tests/TestCases/TestCaseResolverTests.cs create mode 100644 SampleTests/Tests/NamespaceTests.cpp diff --git a/GoogleTestAdapter/Core.Tests/Core.Tests.csproj b/GoogleTestAdapter/Core.Tests/Core.Tests.csproj index 97d7e9fe5..666919774 100644 --- a/GoogleTestAdapter/Core.Tests/Core.Tests.csproj +++ b/GoogleTestAdapter/Core.Tests/Core.Tests.csproj @@ -92,6 +92,7 @@ + diff --git a/GoogleTestAdapter/Core.Tests/GoogleTestDiscovererTests.cs b/GoogleTestAdapter/Core.Tests/GoogleTestDiscovererTests.cs index 59de66dab..a61f5e4dd 100644 --- a/GoogleTestAdapter/Core.Tests/GoogleTestDiscovererTests.cs +++ b/GoogleTestAdapter/Core.Tests/GoogleTestDiscovererTests.cs @@ -415,6 +415,10 @@ private void AssertFindsTest(string fullyQualifiedName, Regex displayNameRegex) var discoverer = new GoogleTestDiscoverer(TestEnvironment.Logger, TestEnvironment.Options); IList tests = discoverer.GetTestsFromExecutable(TestResources.Tests_DebugX86); + MockLogger.Verify(l => l.LogError(It.IsAny()), Times.Never); + MockLogger.Verify(l => l.DebugError(It.IsAny()), Times.Never); + tests.Should().NotBeEmpty(); + TestCase testCase = tests.Single(t => t.FullyQualifiedName == fullyQualifiedName); testCase.DisplayName.Should().MatchRegex(displayNameRegex.ToString()); } diff --git a/GoogleTestAdapter/Core.Tests/GoogleTestDiscovererTraitTestsBase.cs b/GoogleTestAdapter/Core.Tests/GoogleTestDiscovererTraitTestsBase.cs index 4b7331aef..77c384c83 100644 --- a/GoogleTestAdapter/Core.Tests/GoogleTestDiscovererTraitTestsBase.cs +++ b/GoogleTestAdapter/Core.Tests/GoogleTestDiscovererTraitTestsBase.cs @@ -340,8 +340,12 @@ private void AssertFindsTestWithTraits(string displayName, Trait[] traits) GoogleTestDiscoverer discoverer = new GoogleTestDiscoverer(TestEnvironment.Logger, TestEnvironment.Options); List tests = discoverer.GetTestsFromExecutable(SampleTestToUse).ToList(); + MockLogger.Verify(l => l.LogError(It.IsAny()), Times.Never); + MockLogger.Verify(l => l.DebugError(It.IsAny()), Times.Never); + tests.Should().NotBeEmpty(); + TestCase testCase = tests.Find(tc => tc.Traits.Count == traits.Length && tc.DisplayName.StartsWith(displayName)); - testCase.Should().NotBeNull($"Test not found: {displayName}, {traits.Length}"); + testCase.Should().NotBeNull($"Test should exist: {displayName}, {traits.Length}"); foreach (Trait trait in traits) { diff --git a/GoogleTestAdapter/Core.Tests/Helpers/ProcessExecutorTests.cs b/GoogleTestAdapter/Core.Tests/Helpers/ProcessExecutorTests.cs index c653e5264..53a32b09e 100644 --- a/GoogleTestAdapter/Core.Tests/Helpers/ProcessExecutorTests.cs +++ b/GoogleTestAdapter/Core.Tests/Helpers/ProcessExecutorTests.cs @@ -49,7 +49,7 @@ public void ExecuteProcessBlocking_SampleTests() exitCode.Should().Be(1); output.Should().Contain(s => s.Contains("TestMath.AddPasses")); - output.Count.Should().Be(533); + output.Count.Should().Be(563); } } diff --git a/GoogleTestAdapter/Core.Tests/TestCases/TestCaseResolverTests.cs b/GoogleTestAdapter/Core.Tests/TestCases/TestCaseResolverTests.cs new file mode 100644 index 000000000..18e555c97 --- /dev/null +++ b/GoogleTestAdapter/Core.Tests/TestCases/TestCaseResolverTests.cs @@ -0,0 +1,85 @@ +using System.Linq; +using FluentAssertions; +using GoogleTestAdapter.DiaResolver; +using GoogleTestAdapter.Helpers; +using GoogleTestAdapter.Tests.Common; +using GoogleTestAdapter.Tests.Common.Fakes; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using static GoogleTestAdapter.Tests.Common.TestMetadata.TestCategories; + +namespace GoogleTestAdapter.TestCases +{ + + [TestClass] + public class TestCaseResolverTests : TestsBase + { + private FakeLogger _fakeLogger; + + [TestInitialize] + public void Setup() + { + _fakeLogger = new FakeLogger(() => true, false); + } + + [TestMethod] + [TestCategory(Integration)] + public void FindTestCaseLocation_Namespace_Named_LocationIsFound() + { + AssertCorrectTestLocationIsFound("Namespace_Named", 9); + } + + [TestMethod] + [TestCategory(Integration)] + public void FindTestCaseLocation_Namespace_Named_Named_LocationIsFound() + { + AssertCorrectTestLocationIsFound("Namespace_Named_Named", 16); + } + + [TestMethod] + [TestCategory(Integration)] + public void FindTestCaseLocation_Namespace_Named_Anon_LocationIsFound() + { + AssertCorrectTestLocationIsFound("Namespace_Named_Anon", 25); + } + + [TestMethod] + [TestCategory(Integration)] + public void FindTestCaseLocation_Namespace_Anon_LocationIsFound() + { + AssertCorrectTestLocationIsFound("Namespace_Anon", 35); + } + + [TestMethod] + [TestCategory(Integration)] + public void FindTestCaseLocation_Namespace_Anon_Anon_LocationIsFound() + { + AssertCorrectTestLocationIsFound("Namespace_Anon_Anon", 42); + } + + [TestMethod] + [TestCategory(Integration)] + public void FindTestCaseLocation_Namespace_Anon_Named_LocationIsFound() + { + AssertCorrectTestLocationIsFound("Namespace_Anon_Named", 51); + } + + private void AssertCorrectTestLocationIsFound(string suite, uint line) + { + var resolver = new TestCaseResolver(TestResources.Tests_ReleaseX64, "", "".Yield(), + new DefaultDiaResolverFactory(), true, _fakeLogger); + var signatureCreator = new MethodSignatureCreator(); + var descriptor = new TestCaseDescriptor(suite, "Test", $"{suite}.Test", $"{suite}.Test", + TestCaseDescriptor.TestTypes.Simple); + var signatures = signatureCreator.GetTestMethodSignatures(descriptor); + + var testCaseLocation = resolver.FindTestCaseLocation(signatures.ToList()); + + _fakeLogger.Errors.Should().BeEmpty(); + + testCaseLocation.Should().NotBeNull(); + testCaseLocation.Sourcefile.Should().EndWithEquivalent(@"sampletests\tests\namespacetests.cpp"); + testCaseLocation.Line.Should().Be(line); + } + } + +} \ No newline at end of file diff --git a/GoogleTestAdapter/Core/TestCases/MethodSignatureCreator.cs b/GoogleTestAdapter/Core/TestCases/MethodSignatureCreator.cs index 6fec42a4c..7e5f774b5 100644 --- a/GoogleTestAdapter/Core/TestCases/MethodSignatureCreator.cs +++ b/GoogleTestAdapter/Core/TestCases/MethodSignatureCreator.cs @@ -5,10 +5,10 @@ namespace GoogleTestAdapter.TestCases { - internal class MethodSignatureCreator + public class MethodSignatureCreator { - internal IEnumerable GetTestMethodSignatures(TestCaseDescriptor descriptor) + public IEnumerable GetTestMethodSignatures(TestCaseDescriptor descriptor) { switch (descriptor.TestType) { diff --git a/GoogleTestAdapter/Core/TestCases/TestCaseDescriptor.cs b/GoogleTestAdapter/Core/TestCases/TestCaseDescriptor.cs index 2f82a125a..c65602017 100644 --- a/GoogleTestAdapter/Core/TestCases/TestCaseDescriptor.cs +++ b/GoogleTestAdapter/Core/TestCases/TestCaseDescriptor.cs @@ -11,7 +11,7 @@ public enum TestTypes { Simple, Parameterized, TypeParameterized } public string DisplayName { get; } public TestTypes TestType { get; } - internal TestCaseDescriptor(string suite, string name, string fullyQualifiedName, string displayName, TestTypes testType) + public TestCaseDescriptor(string suite, string name, string fullyQualifiedName, string displayName, TestTypes testType) { Suite = suite; Name = name; diff --git a/GoogleTestAdapter/Core/TestCases/TestCaseLocation.cs b/GoogleTestAdapter/Core/TestCases/TestCaseLocation.cs index a1d99308a..97caf85b0 100644 --- a/GoogleTestAdapter/Core/TestCases/TestCaseLocation.cs +++ b/GoogleTestAdapter/Core/TestCases/TestCaseLocation.cs @@ -5,11 +5,11 @@ namespace GoogleTestAdapter.TestCases { - internal class TestCaseLocation : SourceFileLocation + public class TestCaseLocation : SourceFileLocation { - internal List Traits { get; } = new List(); + public List Traits { get; } = new List(); - internal TestCaseLocation(string symbol, string sourceFile, uint line) : base(symbol, sourceFile, line) + public TestCaseLocation(string symbol, string sourceFile, uint line) : base(symbol, sourceFile, line) { } } diff --git a/GoogleTestAdapter/Core/TestCases/TestCaseResolver.cs b/GoogleTestAdapter/Core/TestCases/TestCaseResolver.cs index c695c5a8a..ea090d9c2 100644 --- a/GoogleTestAdapter/Core/TestCases/TestCaseResolver.cs +++ b/GoogleTestAdapter/Core/TestCases/TestCaseResolver.cs @@ -11,7 +11,7 @@ namespace GoogleTestAdapter.TestCases { - internal class TestCaseResolver + public class TestCaseResolver { // see GTA_Traits.h private const string TraitSeparator = "__GTA__"; @@ -29,7 +29,7 @@ internal class TestCaseResolver private bool _loadedSymbolsFromAdditionalPdbs; private bool _loadedSymbolsFromImports; - internal TestCaseResolver(string executable, string pathExtension, IEnumerable additionalPdbs, IDiaResolverFactory diaResolverFactory, bool parseSymbolInformation, ILogger logger) + public TestCaseResolver(string executable, string pathExtension, IEnumerable additionalPdbs, IDiaResolverFactory diaResolverFactory, bool parseSymbolInformation, ILogger logger) { _executable = executable; _pathExtension = pathExtension; @@ -48,7 +48,7 @@ internal TestCaseResolver(string executable, string pathExtension, IEnumerable testMethodSignatures) + public TestCaseLocation FindTestCaseLocation(List testMethodSignatures) { TestCaseLocation result = DoFindTestCaseLocation(testMethodSignatures); if (result == null && !_loadedSymbolsFromAdditionalPdbs) @@ -124,7 +124,7 @@ private void AddSymbolsFromBinary(string binary, string pdb) } catch (Exception e) { - _logger.DebugError($"Exception while resolving test locations and traits in {binary}\n{e}"); + _logger.DebugError($"Exception while resolving test locations and traits in '{binary}':{Environment.NewLine}{e}"); } } } @@ -132,7 +132,7 @@ private void AddSymbolsFromBinary(string binary, string pdb) private TestCaseLocation DoFindTestCaseLocation(List testMethodSignatures) { return _allTestMethodSymbols - .Where(nsfl => testMethodSignatures.Any(tms => Regex.IsMatch(nsfl.Symbol, $"^{tms}"))) // Regex instead of == because nsfl might contain namespace + .Where(nsfl => testMethodSignatures.Any(tms => Regex.IsMatch(nsfl.Symbol, $@"^(((\w+)|(`anonymous namespace'))::)*{tms}"))) // Regex instead of == because nsfl might contain namespace .Select(nsfl => ToTestCaseLocation(nsfl, _allTraitSymbols)) .FirstOrDefault(); // we need to force immediate query execution, otherwise our session object will already be released } diff --git a/GoogleTestAdapter/TestAdapter.Tests/TestExecutorTestsBase.cs b/GoogleTestAdapter/TestAdapter.Tests/TestExecutorTestsBase.cs index cf720d138..f487915cf 100644 --- a/GoogleTestAdapter/TestAdapter.Tests/TestExecutorTestsBase.cs +++ b/GoogleTestAdapter/TestAdapter.Tests/TestExecutorTestsBase.cs @@ -203,7 +203,7 @@ public virtual void RunTests_WithNonexistingSetupBatch_LogsError() { MockOptions.Setup(o => o.BatchForTestSetup).Returns("some_nonexisting_file"); - RunAndVerifyTests(TestResources.DllTests_ReleaseX86, 1, 1, 0); + RunAndVerifyTests(TestResources.DllTests_ReleaseX86, 1, 1, 0, checkNoErrorsLogged: false); MockLogger.Verify(l => l.LogError( It.Is(s => s.Contains(PreparingTestRunner.TestSetup.ToLower()))), @@ -254,11 +254,17 @@ public virtual void RunTests_WithoutPathExtension_ExecutionFails() } } - protected void RunAndVerifyTests(string executable, int nrOfPassedTests, int nrOfFailedTests, int nrOfUnexecutedTests, int nrOfSkippedTests = 0) + protected void RunAndVerifyTests(string executable, int nrOfPassedTests, int nrOfFailedTests, int nrOfUnexecutedTests, int nrOfSkippedTests = 0, bool checkNoErrorsLogged = true) { TestExecutor executor = new TestExecutor(TestEnvironment.Logger, TestEnvironment.Options); executor.RunTests(executable.Yield(), MockRunContext.Object, MockFrameworkHandle.Object); + if (checkNoErrorsLogged) + { + MockLogger.Verify(l => l.LogError(It.IsAny()), Times.Never); + MockLogger.Verify(l => l.DebugError(It.IsAny()), Times.Never); + } + CheckMockInvocations(nrOfPassedTests, nrOfFailedTests, nrOfUnexecutedTests, nrOfSkippedTests); } diff --git a/GoogleTestAdapter/Tests.Common/TestResources.cs b/GoogleTestAdapter/Tests.Common/TestResources.cs index 767b81e99..39aa0fd0d 100644 --- a/GoogleTestAdapter/Tests.Common/TestResources.cs +++ b/GoogleTestAdapter/Tests.Common/TestResources.cs @@ -38,10 +38,10 @@ public static class TestResources public const string Tests_DebugX64 = SampleTestsBuildDir + @"Debug-x64\Tests_gta.exe"; public const string Tests_ReleaseX64 = SampleTestsBuildDir + @"Release-x64\Tests_gta.exe"; public const string Tests_ReleaseX64_Output = TestdataDir + @"Tests_gta_exe_output.txt"; - public const int NrOfTests = 101; - public const int NrOfPassingTests = 47; + public const int NrOfTests = 107; + public const int NrOfPassingTests = 53; public const int NrOfFailingTests = 54; - public const int NrOfGtest170CompatibleTests = 97; + public const int NrOfGtest170CompatibleTests = 103; public static readonly string LoadTests_ReleaseX86 = Path.Combine(SampleTestsBuildDir, @"Release\LoadTests_gta.exe"); diff --git a/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__List_TestsOf_SampleTests.txt b/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__List_TestsOf_SampleTests.txt index e75e35844..fea979489 100644 --- a/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__List_TestsOf_SampleTests.txt +++ b/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__List_TestsOf_SampleTests.txt @@ -30,6 +30,12 @@ OutputHandling.OneLine abcd.t bbcd.t bcd.t +Namespace_Named.Test +Namespace_Named_Named.Test +Namespace_Named_Anon.Test +Namespace_Anon.Test +Namespace_Anon_Anon.Test +Namespace_Anon_Named.Test MessageParserTests.SimpleAssert MessageParserTests.SimpleExpect MessageParserTests.ExpectAndAssert diff --git a/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__List_TestsOf_SampleTests170.txt b/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__List_TestsOf_SampleTests170.txt index 3e51f8795..453e10c35 100644 --- a/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__List_TestsOf_SampleTests170.txt +++ b/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__List_TestsOf_SampleTests170.txt @@ -30,6 +30,12 @@ TheFixture.Crash TheFixture.AddPassesWithTraits TheFixture.AddPassesWithTraits2 TheFixture.AddPassesWithTraits3 +Namespace_Named.Test +Namespace_Named_Named.Test +Namespace_Named_Anon.Test +Namespace_Anon.Test +Namespace_Anon_Anon.Test +Namespace_Anon_Named.Test MessageParserTests.SimpleAssert MessageParserTests.SimpleExpect MessageParserTests.ExpectAndAssert diff --git a/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__SampleTests170_SolutionProjectSettings_Coverage_Isolation.xml b/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__SampleTests170_SolutionProjectSettings_Coverage_Isolation.xml index 5178ca2fb..40f89ad16 100644 --- a/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__SampleTests170_SolutionProjectSettings_Coverage_Isolation.xml +++ b/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__SampleTests170_SolutionProjectSettings_Coverage_Isolation.xml @@ -266,6 +266,12 @@ at -->TestMethod Outer in $(Directory)\sampletests\tests\scopedtracestests.cp + + + + + + @@ -707,6 +713,24 @@ Which is: "\xE4\xF6\xFC\xDF\xC4\xD6\xDC" + + + + + + + + + + + + + + + + + + @@ -889,7 +913,7 @@ Which is: "\xE4\xF6\xFC\xDF\xC4\xD6\xDC" - + \ No newline at end of file diff --git a/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__SampleTests_SolutionProjectSettings_Coverage_Isolation.xml b/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__SampleTests_SolutionProjectSettings_Coverage_Isolation.xml index 5159aa9cb..49f621fb0 100644 --- a/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__SampleTests_SolutionProjectSettings_Coverage_Isolation.xml +++ b/GoogleTestAdapter/VsPackage.Tests.Generated/GoldenFiles/ConsoleDllTests__SampleTests_SolutionProjectSettings_Coverage_Isolation.xml @@ -270,6 +270,12 @@ at -->TestMethod Outer in $(Directory)\sampletests\tests\scopedtracestests.cp + + + + + + @@ -723,6 +729,24 @@ To be equal to: GetParam().s + + + + + + + + + + + + + + + + + + @@ -905,7 +929,7 @@ To be equal to: GetParam().s - + \ No newline at end of file diff --git a/SampleTests/Tests/NamespaceTests.cpp b/SampleTests/Tests/NamespaceTests.cpp new file mode 100644 index 000000000..49ccaf838 --- /dev/null +++ b/SampleTests/Tests/NamespaceTests.cpp @@ -0,0 +1,57 @@ +#include "gtest/gtest.h" + +// NOTE THAT getest discourages the use of namespaces (see e.g. this thread: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/MwPIo2BnVhM) +// GTA still makes a best effort to handle such tests... + +namespace Namespace_1 { + + TEST(Namespace_Named, Test) + { + EXPECT_EQ(1, 1); + } + + namespace Namespace_2_Nested { + + TEST(Namespace_Named_Named, Test) + { + EXPECT_EQ(1, 1); + } + + } // Namespace_1 + + namespace { + + TEST(Namespace_Named_Anon, Test) + { + EXPECT_EQ(1, 1); + } + } + +} // Namespace_2_Nested + +namespace { + + TEST(Namespace_Anon, Test) + { + EXPECT_EQ(1, 1); + } + + namespace { + + TEST(Namespace_Anon_Anon, Test) + { + EXPECT_EQ(1, 1); + } + + } + + namespace Anon_Nested { + + TEST(Namespace_Anon_Named, Test) + { + EXPECT_EQ(1, 1); + } + + } +} + diff --git a/SampleTests/Tests/Tests.vcxproj b/SampleTests/Tests/Tests.vcxproj index 001c67f76..0d1737dea 100644 --- a/SampleTests/Tests/Tests.vcxproj +++ b/SampleTests/Tests/Tests.vcxproj @@ -152,6 +152,7 @@ + diff --git a/SampleTests/Tests/Tests.vcxproj.filters b/SampleTests/Tests/Tests.vcxproj.filters index 9d005f515..f50d54226 100644 --- a/SampleTests/Tests/Tests.vcxproj.filters +++ b/SampleTests/Tests/Tests.vcxproj.filters @@ -42,6 +42,9 @@ Source Files + + Source Files + diff --git a/SampleTests/Tests_1.7.0/Tests_1.7.0.vcxproj b/SampleTests/Tests_1.7.0/Tests_1.7.0.vcxproj index 68eb553b3..4e3b50c8d 100644 --- a/SampleTests/Tests_1.7.0/Tests_1.7.0.vcxproj +++ b/SampleTests/Tests_1.7.0/Tests_1.7.0.vcxproj @@ -168,6 +168,7 @@ + diff --git a/SampleTests/Tests_1.7.0/Tests_1.7.0.vcxproj.filters b/SampleTests/Tests_1.7.0/Tests_1.7.0.vcxproj.filters index 93e0582ae..22ad6773a 100644 --- a/SampleTests/Tests_1.7.0/Tests_1.7.0.vcxproj.filters +++ b/SampleTests/Tests_1.7.0/Tests_1.7.0.vcxproj.filters @@ -50,5 +50,8 @@ Source Files + + Source Files + \ No newline at end of file