Skip to content

Commit

Permalink
Merge pull request #280 from csoltenborn/#278_helper_files
Browse files Browse the repository at this point in the history
#278 helper files
  • Loading branch information
csoltenborn authored Apr 27, 2019
2 parents 65b49f5 + 97d5b71 commit 2fb42b6
Show file tree
Hide file tree
Showing 26 changed files with 1,001 additions and 136 deletions.
4 changes: 4 additions & 0 deletions GoogleTestAdapter/Core.Tests/Core.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -98,6 +100,8 @@
<Compile Include="Runners\CommandLineGeneratorTests.cs" />
<Compile Include="Runners\DebuggerKindConverterTests.cs" />
<Compile Include="Runners\SequentialTestRunnerTests.cs" />
<Compile Include="Settings\HelperFilesCacheTests.cs" />
<Compile Include="Settings\PlaceholderReplacerTests.cs" />
<Compile Include="TestCases\TestCaseResolverTests.cs" />
<Compile Include="TestCases\TestCaseFactoryTests.cs" />
<Compile Include="TestCases\ListTestsParserTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ private SettingsWrapper CreateSettings(string solutionWorkingDir, string project

return new SettingsWrapper(mockContainer.Object, TestResources.SampleTestsSolutionDir)
{
RegexTraitParser = new RegexTraitParser(MockLogger.Object)
RegexTraitParser = new RegexTraitParser(MockLogger.Object),
HelperFilesCache = new HelperFilesCache(MockLogger.Object)
};
}

Expand Down
132 changes: 132 additions & 0 deletions GoogleTestAdapter/Core.Tests/Settings/HelperFilesCacheTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.IO;
using FluentAssertions;
using GoogleTestAdapter.Tests.Common;
using GoogleTestAdapter.Tests.Common.Assertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static GoogleTestAdapter.Tests.Common.TestMetadata.TestCategories;

namespace GoogleTestAdapter.Settings
{
[TestClass]
public class HelperFilesCacheTests : TestsBase
{
[TestMethod]
[TestCategory(Unit)]
public void GetReplacementsMap_NoFile_EmptyDictionary()
{
string executable = TestResources.Tests_DebugX86;
var extraSettings = HelperFilesCache.GetHelperFile(executable);
extraSettings.AsFileInfo().Should().NotExist();

var cache = new HelperFilesCache(MockLogger.Object);
var map = cache.GetReplacementsMap(executable);

map.Should().BeEmpty();
}

[TestMethod]
[TestCategory(Unit)]
public void GetReplacementsMap_EmptyString_EmptyDictionary()
{
DoTest("", map =>
{
map.Should().BeEmpty();
});
}

[TestMethod]
[TestCategory(Unit)]
public void GetReplacementsMap_InvalidString_EmptyDictionary()
{
DoTest("Foo", map =>
{
map.Should().BeEmpty();
});
}

[TestMethod]
[TestCategory(Unit)]
public void GetReplacementsMap_SingleValue_ProperDictionary()
{
DoTest("Foo=Bar", map =>
{
map.Should().HaveCount(1);
map.Should().Contain(new KeyValuePair<string, string>("Foo", "Bar"));
});
}

[TestMethod]
[TestCategory(Unit)]
public void GetReplacementsMap_TwoValues_ProperDictionary()
{
DoTest($"Placeholder1=value1{HelperFilesCache.SettingsSeparator}Placeholder2=value2", map =>
{
map.Should().HaveCount(2);
map.Should().Contain(new KeyValuePair<string, string>("Placeholder1", "value1"));
map.Should().Contain(new KeyValuePair<string, string>("Placeholder2", "value2"));
});
}

[TestMethod]
[TestCategory(Unit)]
public void GetReplacementsMap_SingleWithEmptyValue_ProperDictionary()
{
DoTest("Placeholder1=", map =>
{
map.Should().HaveCount(1);
map.Should().Contain(new KeyValuePair<string, string>("Placeholder1", ""));
});
}

[TestMethod]
[TestCategory(Unit)]
public void GetReplacementsMap_SingleWithTrailingSeparator_ProperDictionary()
{
DoTest($"Ph=V{HelperFilesCache.SettingsSeparator}", map =>
{
map.Should().HaveCount(1);
map.Should().Contain(new KeyValuePair<string, string>("Ph", "V"));
});
}

[TestMethod]
[TestCategory(Unit)]
public void GetReplacementsMap_OnlySeparator_ProperDictionary()
{
DoTest($"{HelperFilesCache.SettingsSeparator}", map =>
{
map.Should().BeEmpty();
});
}

[TestMethod]
[TestCategory(Unit)]
public void GetReplacementsMap_OnlyTwoSeparators_ProperDictionary()
{
DoTest($"{HelperFilesCache.SettingsSeparator}{HelperFilesCache.SettingsSeparator}", map =>
{
map.Should().BeEmpty();
});
}

private void DoTest(string content, Action<IDictionary<string, string>> assertions, string executable = TestResources.Tests_DebugX86)
{
var extraSettings = HelperFilesCache.GetHelperFile(executable);
try
{
extraSettings.AsFileInfo().Should().NotExist();
File.WriteAllText(extraSettings, content);

var cache = new HelperFilesCache(MockLogger.Object);
var map = cache.GetReplacementsMap(executable);
assertions(map);
}
finally
{
File.Delete(extraSettings);
}
}
}
}
171 changes: 171 additions & 0 deletions GoogleTestAdapter/Core.Tests/Settings/PlaceholderReplacerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using FluentAssertions;
using GoogleTestAdapter.Common;
using GoogleTestAdapter.Tests.Common;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using static GoogleTestAdapter.Tests.Common.TestMetadata.TestCategories;

namespace GoogleTestAdapter.Settings
{
[TestClass]
public class PlaceholderReplacerTests
{
private class PlaceholderAndValue
{
public string Placeholder { get; }
public object Value { get; }

public PlaceholderAndValue(string placeholder, object value)
{
Placeholder = placeholder;
Value = value;
}
}

private class MethodnameAndPlaceholder
{
public string MethodName { get; }
public string Placeholder { get; }

public MethodnameAndPlaceholder(string methodName, string placeholder)
{
MethodName = methodName;
Placeholder = placeholder;
}
}

private static readonly string[] MethodNames = {
nameof(PlaceholderReplacer.ReplaceAdditionalPdbsPlaceholders),
nameof(PlaceholderReplacer.ReplaceAdditionalTestExecutionParamPlaceholdersForDiscovery),
nameof(PlaceholderReplacer.ReplaceAdditionalTestExecutionParamPlaceholdersForExecution),
nameof(PlaceholderReplacer.ReplaceSetupBatchPlaceholders),
nameof(PlaceholderReplacer.ReplaceTeardownBatchPlaceholders),
nameof(PlaceholderReplacer.ReplacePathExtensionPlaceholders),
nameof(PlaceholderReplacer.ReplaceWorkingDirPlaceholdersForDiscovery),
nameof(PlaceholderReplacer.ReplaceWorkingDirPlaceholdersForExecution)
};

private static readonly List<PlaceholderAndValue> PlaceholdersAndExpectedValues = new List<PlaceholderAndValue>
{
new PlaceholderAndValue(PlaceholderReplacer.SolutionDirPlaceholder, TestResources.SampleTestsSolutionDir),
new PlaceholderAndValue(PlaceholderReplacer.PlatformNamePlaceholder, "Win33"),
new PlaceholderAndValue(PlaceholderReplacer.ConfigurationNamePlaceholder, "MyDebug"),
// ReSharper disable once AssignNullToNotNullAttribute
new PlaceholderAndValue(PlaceholderReplacer.ExecutableDirPlaceholder, Path.GetFullPath(Path.GetDirectoryName(TestResources.Tests_DebugX86))),
new PlaceholderAndValue(PlaceholderReplacer.ExecutablePlaceholder, TestResources.Tests_DebugX86),
new PlaceholderAndValue(PlaceholderReplacer.TestDirPlaceholder, "testDirectory"),
new PlaceholderAndValue(PlaceholderReplacer.ThreadIdPlaceholder, 42)
};

private static readonly List<MethodnameAndPlaceholder> UnsupportedCombinations = new List<MethodnameAndPlaceholder>
{
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceAdditionalPdbsPlaceholders), PlaceholderReplacer.TestDirPlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceAdditionalTestExecutionParamPlaceholdersForDiscovery), PlaceholderReplacer.TestDirPlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplacePathExtensionPlaceholders), PlaceholderReplacer.TestDirPlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceWorkingDirPlaceholdersForDiscovery), PlaceholderReplacer.TestDirPlaceholder),

new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceAdditionalPdbsPlaceholders), PlaceholderReplacer.ThreadIdPlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceAdditionalTestExecutionParamPlaceholdersForDiscovery), PlaceholderReplacer.ThreadIdPlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplacePathExtensionPlaceholders), PlaceholderReplacer.ThreadIdPlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceWorkingDirPlaceholdersForDiscovery), PlaceholderReplacer.ThreadIdPlaceholder),

new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceSetupBatchPlaceholders), PlaceholderReplacer.ExecutablePlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceSetupBatchPlaceholders), PlaceholderReplacer.ExecutableDirPlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceSetupBatchPlaceholders), PlaceholderReplacer.ConfigurationNamePlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceSetupBatchPlaceholders), PlaceholderReplacer.PlatformNamePlaceholder),

new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceTeardownBatchPlaceholders), PlaceholderReplacer.ExecutablePlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceTeardownBatchPlaceholders), PlaceholderReplacer.ExecutableDirPlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceTeardownBatchPlaceholders), PlaceholderReplacer.ConfigurationNamePlaceholder),
new MethodnameAndPlaceholder(nameof(PlaceholderReplacer.ReplaceTeardownBatchPlaceholders), PlaceholderReplacer.PlatformNamePlaceholder),
};


[TestMethod]
[TestCategory(Unit)]
public void AllReplacementsTest()
{
Mock<HelperFilesCache> mockHelperFilesCache = new Mock<HelperFilesCache>();
mockHelperFilesCache.Setup(c => c.GetReplacementsMap(It.IsAny<string>())).Returns(
new Dictionary<string, string>
{
{nameof(IGoogleTestAdapterSettings.ConfigurationName), "MyDebug"},
{nameof(IGoogleTestAdapterSettings.PlatformName), "Win33"}
});
Mock<IGoogleTestAdapterSettings> mockOptions = new Mock<IGoogleTestAdapterSettings>();
Mock<ILogger> mockLogger = new Mock<ILogger>();
var placeholderReplacer = new PlaceholderReplacer(
() => TestResources.SampleTestsSolutionDir,
() => mockOptions.Object,
mockHelperFilesCache.Object,
mockLogger.Object);

foreach (string methodName in MethodNames)
{
foreach (PlaceholderAndValue placeholder in PlaceholdersAndExpectedValues)
{
if (!UnsupportedCombinations.Any(combination =>
combination.MethodName == methodName && combination.Placeholder == placeholder.Placeholder))
{
var result = InvokeMethodWithStandardParameters(placeholderReplacer, methodName, placeholder.Placeholder);
result.Should().Be(placeholder.Value.ToString(), $"{methodName} should replace {placeholder.Placeholder} with {(object) placeholder.Value.ToString()}");
mockLogger.Verify(l => l.LogWarning(It.IsAny<string>()), Times.Never);
}
}
}
}

[TestMethod]
[TestCategory(Unit)]
public void AllReplacementMethods_UnknownPlaceholderResultsInWarning()
{
Mock<HelperFilesCache> mockHelperFilesCache = new Mock<HelperFilesCache>();
mockHelperFilesCache.Setup(c => c.GetReplacementsMap(It.IsAny<string>()))
.Returns(new Dictionary<string, string>());
Mock<IGoogleTestAdapterSettings> mockOptions = new Mock<IGoogleTestAdapterSettings>();
Mock<ILogger> mockLogger = new Mock<ILogger>();
var replacer = new PlaceholderReplacer(() => "solutiondir", () => mockOptions.Object,
mockHelperFilesCache.Object, mockLogger.Object);

string placeholder = "$(UnknownPlaceholder)";
foreach (string methodName in MethodNames)
{
mockLogger.Reset();
string result = InvokeMethodWithStandardParameters(replacer, methodName, placeholder);
result.Should().Be(placeholder);
mockLogger.Verify(l => l.LogWarning(It.Is<string>(msg => msg.Contains(placeholder))), Times.Once);
}
}

private string InvokeMethodWithStandardParameters(PlaceholderReplacer placeholderReplacer, string methodName,
string input)
{
var method = typeof(PlaceholderReplacer).GetMethod(methodName);
// ReSharper disable once PossibleNullReferenceException
var parameters = method.GetParameters();

var parameterValues = new List<object> {input};
for (int i = 1; i < parameters.Length; i++)
{
parameterValues.Add(GetValue(parameters[i]));
}

return (string) method.Invoke(placeholderReplacer, parameterValues.ToArray());
}

private object GetValue(ParameterInfo parameter)
{
switch (parameter.Name)
{
case "executable": return TestResources.Tests_DebugX86;
case "threadId": return 42;
default: return parameter.Name;
}
}

}
}
6 changes: 4 additions & 2 deletions GoogleTestAdapter/Core.Tests/Settings/SettingsWrapperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public override void SetUp()
containerMock.Setup(c => c.GetSettingsForExecutable(It.IsAny<string>())).Returns(MockXmlOptions.Object);
TheOptions = new SettingsWrapper(containerMock.Object)
{
RegexTraitParser = new RegexTraitParser(TestEnvironment.Logger)
RegexTraitParser = new RegexTraitParser(TestEnvironment.Logger),
HelperFilesCache = new HelperFilesCache(TestEnvironment.Logger)
};
}

Expand Down Expand Up @@ -643,7 +644,8 @@ private SettingsWrapper CreateSettingsWrapper(string solutionWorkdir, params str

return new SettingsWrapper(containerMock.Object)
{
RegexTraitParser = new RegexTraitParser(MockLogger.Object)
RegexTraitParser = new RegexTraitParser(MockLogger.Object),
HelperFilesCache = new HelperFilesCache(MockLogger.Object)
};
}

Expand Down
1 change: 1 addition & 0 deletions GoogleTestAdapter/Core/Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
<Compile Include="Runners\ExecutableResult.cs" />
<Compile Include="Runners\TestResultCollector.cs" />
<Compile Include="Scheduling\SchedulingAnalyzer.cs" />
<Compile Include="Settings\HelperFilesCache.cs" />
<Compile Include="Settings\IGoogleTestAdapterSettingsContainer.cs" />
<Compile Include="Settings\PlaceholderReplacer.cs" />
<Compile Include="Settings\RegexTraitPair.cs" />
Expand Down
Loading

0 comments on commit 2fb42b6

Please sign in to comment.