refactor: Make TestData object usable outside tests

TestData split out into ResourceDataReader in a new Common project, so
that we have a place to share common code between tests and non-tests.
recyclarr
Robert Dailey 4 years ago
parent 81131c7598
commit 7604397c26

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\TestLibrary\TestLibrary.csproj" />
<ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="DefaultDataFile.txt" />
<EmbeddedResource Include="TestData\DataFile.txt" />
</ItemGroup>
</Project>

@ -0,0 +1,38 @@
using System;
using FluentAssertions;
using NUnit.Framework;
namespace Common.Tests
{
[TestFixture]
[Parallelizable(ParallelScope.All)]
public class ResourceDataReaderTest
{
[Test]
public void GetResourceData_DefaultDir_ReturnResourceData()
{
var testData = new ResourceDataReader(typeof(ResourceDataReaderTest));
var data = testData.ReadData("DefaultDataFile.txt");
data.Trim().Should().Be("DefaultDataFile");
}
[Test]
public void GetResourceData_NonexistentFile_Throw()
{
var testData = new ResourceDataReader(typeof(ResourceDataReaderTest));
Action act = () => testData.ReadData("DataFileWontBeFound.txt");
act.Should()
.Throw<ArgumentException>()
.WithMessage("Embedded resource not found*");
}
[Test]
public void ReadData_ExplicitSubDir_ReturnResourceData()
{
var testData = new ResourceDataReader(typeof(ResourceDataReaderTest), "TestData");
var data = testData.ReadData("DataFile.txt");
data.Trim().Should().Be("DataFile");
}
}
}

@ -0,0 +1,2 @@
<Project Sdk="Microsoft.NET.Sdk">
</Project>

@ -0,0 +1,43 @@
using System;
using System.IO;
using System.Reflection;
using System.Text;
namespace Common
{
public class ResourceDataReader
{
private readonly Assembly? _assembly;
private readonly string? _namespace;
private readonly string _subdirectory;
public ResourceDataReader(Type typeWithNamespaceToUse, string subdirectory = "")
{
_subdirectory = subdirectory;
_namespace = typeWithNamespaceToUse.Namespace;
_assembly = Assembly.GetAssembly(typeWithNamespaceToUse);
}
public string ReadData(string filename)
{
var nameBuilder = new StringBuilder();
nameBuilder.Append(_namespace);
if (!string.IsNullOrEmpty(_subdirectory))
{
nameBuilder.Append($".{_subdirectory}");
}
nameBuilder.Append($".{filename}");
var resourceName = nameBuilder.ToString();
using var stream = _assembly?.GetManifestResourceStream(resourceName);
if (stream == null)
{
throw new ArgumentException($"Embedded resource not found: {resourceName}");
}
using var reader = new StreamReader(stream);
return reader.ReadToEnd();
}
}
}

@ -1,53 +0,0 @@
using System;
using FluentAssertions;
using NUnit.Framework;
namespace TestLibrary.Tests
{
internal class TestFixtureMissingAttribute
{
}
[TestFixture]
public class TestDataTest
{
[Test]
public void Construction_ClassMissingAttribute_Throw()
{
// ReSharper disable once ObjectCreationAsStatement
Action act = () => new TestData<TestFixtureMissingAttribute>();
act.Should()
.Throw<ArgumentException>()
.WithMessage("*does not have the [TestFixture] attribute");
}
[Test]
public void GetResourceData_CustomDir_ReturnResourceData()
{
TestData<TestDataTest> testData = new();
testData.DataSubdirectoryName = "OtherData";
var data = testData.GetResourceData("AnotherDataFile.txt");
data.Trim().Should().Be("AnotherDataFile");
}
[Test]
public void GetResourceData_DefaultDir_ReturnResourceData()
{
TestData<TestDataTest> testData = new();
var data = testData.GetResourceData("DataFile.txt");
data.Trim().Should().Be("DataFile");
}
[Test]
public void GetResourceData_NonexistentFile_Throw()
{
TestData<TestDataTest> testData = new();
Action act = () => testData.GetResourceData("DataFileWontBeFound.txt");
act.Should()
.Throw<ArgumentException>()
.WithMessage("Embedded resource not found*");
}
}
}

@ -6,9 +6,4 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\TestLibrary\TestLibrary.csproj" /> <ProjectReference Include="..\TestLibrary\TestLibrary.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="DataFileWontBeFound.txt" />
<EmbeddedResource Include="OtherData/AnotherDataFile.txt" />
</ItemGroup>
</Project> </Project>

@ -1,41 +0,0 @@
using System;
using System.IO;
using System.Reflection;
using NUnit.Framework;
namespace TestLibrary
{
public class TestData<TTestFixtureClass>
{
private readonly Assembly? _assembly;
private readonly string? _namespace;
public TestData()
{
var attributes = typeof(TTestFixtureClass).GetCustomAttributes(typeof(TestFixtureAttribute), true);
if (attributes.Length == 0)
{
throw new ArgumentException(
$"{typeof(TTestFixtureClass).Name} does not have the [TestFixture] attribute");
}
_namespace = typeof(TTestFixtureClass).Namespace;
_assembly = Assembly.GetAssembly(typeof(TTestFixtureClass));
}
public string DataSubdirectoryName { get; set; } = "Data";
public string GetResourceData(string name)
{
var resourceName = $"{_namespace}.{DataSubdirectoryName}.{name}";
using var stream = _assembly?.GetManifestResourceStream(resourceName);
if (stream == null)
{
throw new ArgumentException($"Embedded resource not found: {resourceName}");
}
using var reader = new StreamReader(stream);
return reader.ReadToEnd();
}
}
}

@ -4,4 +4,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="NUnit" /> <PackageReference Include="NUnit" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>
</Project> </Project>

@ -4,6 +4,7 @@ using System.IO;
using System.IO.Abstractions; using System.IO.Abstractions;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Common;
using FluentAssertions; using FluentAssertions;
using NSubstitute; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
@ -22,13 +23,13 @@ namespace Trash.Tests.Config
{ {
private TextReader GetResourceData(string file) private TextReader GetResourceData(string file)
{ {
var testData = new TestData<ConfigurationLoaderTest>(); var testData = new ResourceDataReader(typeof(ConfigurationLoaderTest), "Data");
if (testData == null) if (testData == null)
{ {
throw new InvalidOperationException("TestData object has not been created yet"); throw new InvalidOperationException("TestData object has not been created yet");
} }
return new StringReader(testData.GetResourceData(file)); return new StringReader(testData.ReadData(file));
} }
[Test] [Test]

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Common;
using FluentAssertions; using FluentAssertions;
using NSubstitute; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
@ -38,7 +39,7 @@ namespace Trash.Tests.Sonarr.ReleaseProfile
public SonarrConfiguration Config { get; } public SonarrConfiguration Config { get; }
public ReleaseProfileGuideParser GuideParser { get; } public ReleaseProfileGuideParser GuideParser { get; }
public TestData<ReleaseProfileParserTest> TestData { get; } = new(); public ResourceDataReader TestData { get; } = new(typeof(ReleaseProfileParserTest), "Data");
public IDictionary<string, ProfileData> ParseWithDefaults(string markdown) public IDictionary<string, ProfileData> ParseWithDefaults(string markdown)
{ {
@ -116,7 +117,7 @@ One more
public void Parse_IgnoredRequiredPreferredScores() public void Parse_IgnoredRequiredPreferredScores()
{ {
var context = new Context(); var context = new Context();
var markdown = context.TestData.GetResourceData("test_parse_markdown_complete_doc.md"); var markdown = context.TestData.ReadData("test_parse_markdown_complete_doc.md");
var results = context.GuideParser.ParseMarkdown(context.Config.ReleaseProfiles.First(), markdown); var results = context.GuideParser.ParseMarkdown(context.Config.ReleaseProfiles.First(), markdown);
results.Count.Should().Be(1); results.Count.Should().Be(1);
@ -132,7 +133,7 @@ One more
public void Parse_IncludePreferredWhenRenaming() public void Parse_IncludePreferredWhenRenaming()
{ {
var context = new Context(); var context = new Context();
var markdown = context.TestData.GetResourceData("include_preferred_when_renaming.md"); var markdown = context.TestData.ReadData("include_preferred_when_renaming.md");
var results = context.ParseWithDefaults(markdown); var results = context.ParseWithDefaults(markdown);
results.Should() results.Should()
@ -350,7 +351,7 @@ abc
new() {StrictNegativeScores = true} new() {StrictNegativeScores = true}
}; };
var markdown = context.TestData.GetResourceData("strict_negative_scores.md"); var markdown = context.TestData.ReadData("strict_negative_scores.md");
var results = context.ParseWithDefaults(markdown); var results = context.ParseWithDefaults(markdown);
results.Should() results.Should()

@ -17,4 +17,8 @@
<PackageReference Include="YamlDotNet" /> <PackageReference Include="YamlDotNet" />
<PackageReference Include="System.IO.Abstractions" /> <PackageReference Include="System.IO.Abstractions" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>
</Project> </Project>

@ -14,6 +14,10 @@ ProjectSection(SolutionItems) = preProject
Directory.Build.targets = Directory.Build.targets Directory.Build.targets = Directory.Build.targets
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{18CF1FCA-7983-4423-8B7E-4A830108C624}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Tests", "Common.Tests\Common.Tests.csproj", "{0720939D-1CA6-43D7-BBED-F8F894C4F562}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -36,6 +40,14 @@ Global
{BF105B2F-8E13-48AD-BF72-DF7EFEB018B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {BF105B2F-8E13-48AD-BF72-DF7EFEB018B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF105B2F-8E13-48AD-BF72-DF7EFEB018B6}.Release|Any CPU.ActiveCfg = Release|Any CPU {BF105B2F-8E13-48AD-BF72-DF7EFEB018B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF105B2F-8E13-48AD-BF72-DF7EFEB018B6}.Release|Any CPU.Build.0 = Release|Any CPU {BF105B2F-8E13-48AD-BF72-DF7EFEB018B6}.Release|Any CPU.Build.0 = Release|Any CPU
{18CF1FCA-7983-4423-8B7E-4A830108C624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18CF1FCA-7983-4423-8B7E-4A830108C624}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18CF1FCA-7983-4423-8B7E-4A830108C624}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18CF1FCA-7983-4423-8B7E-4A830108C624}.Release|Any CPU.Build.0 = Release|Any CPU
{0720939D-1CA6-43D7-BBED-F8F894C4F562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0720939D-1CA6-43D7-BBED-F8F894C4F562}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0720939D-1CA6-43D7-BBED-F8F894C4F562}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0720939D-1CA6-43D7-BBED-F8F894C4F562}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
EndGlobalSection EndGlobalSection

Loading…
Cancel
Save