Skip to content

Commit

Permalink
Fixed embedded resources (#54)
Browse files Browse the repository at this point in the history
- Fixed embedded resources for .NET Standard and .NET Core
- Fixed so we read .resx files correctly from embedded resources
  • Loading branch information
MilleBo authored Mar 22, 2020
1 parent 5f6c9d0 commit 931a7aa
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 39 deletions.
4 changes: 2 additions & 2 deletions src/Testura.Mutation.Console/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.6.0.0")]
[assembly: AssemblyFileVersion("1.6.0.0")]
[assembly: AssemblyVersion("1.7.0.0")]
[assembly: AssemblyFileVersion("1.7.0.0")]
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4Net.config", Watch = true)]
41 changes: 8 additions & 33 deletions src/Testura.Mutation.Core/Execution/Compilation/Compiler.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using log4net;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
Expand All @@ -13,6 +10,12 @@ namespace Testura.Mutation.Core.Execution.Compilation
public class Compiler : IMutationDocumentCompiler, IProjectCompiler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(Compiler));
private readonly EmbeddedResourceCreator _embeddedResourceCreator;

public Compiler(EmbeddedResourceCreator embeddedResourceCreator)
{
_embeddedResourceCreator = embeddedResourceCreator;
}

public async Task<CompilationResult> CompileAsync(string path, MutationDocument document)
{
Expand Down Expand Up @@ -49,7 +52,7 @@ private CompilationResult EmitCompilation(
string filePath,
Microsoft.CodeAnalysis.Compilation compilation)
{
var result = compilation.Emit(path, manifestResources: GetEmbeddedResources(assemblyName, filePath));
var result = compilation.Emit(path, manifestResources: _embeddedResourceCreator.GetManifestResources(assemblyName, filePath));

return new CompilationResult
{
Expand All @@ -60,33 +63,5 @@ private CompilationResult EmitCompilation(
.ToList()
};
}

private IList<ResourceDescription> GetEmbeddedResources(string assemblyName, string projectPath)
{
var resources = new List<ResourceDescription>();
var doc = XDocument.Load(projectPath);
var embeddedResources = doc.Descendants().Where(d => d.Name.LocalName.Equals("EmbeddedResource", StringComparison.InvariantCultureIgnoreCase));
foreach (var embeddedResource in embeddedResources)
{
var paths = embeddedResource.Attribute("Include")?.Value;
if (paths == null)
{
continue;
}

foreach (var path in paths.Split(';'))
{
var pathFixed = path.Split('\\');
var resourcePath = Path.Combine(Path.GetDirectoryName(projectPath), path);

resources.Add(new ResourceDescription(
$"{assemblyName}.{string.Join(".", pathFixed)}",
() => File.OpenRead(resourcePath),
true));
}
}

return resources;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Resources;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;

namespace Testura.Mutation.Core.Execution.Compilation
{
public class EmbeddedResourceCreator
{
public IEnumerable<ResourceDescription> GetManifestResources(string assemblyName, string projectPath)
{
var resources = new List<ResourceDescription>();
var doc = XDocument.Load(projectPath);
var embeddedResources = doc.Descendants().Where(d => d.Name.LocalName.Equals("EmbeddedResource", StringComparison.InvariantCultureIgnoreCase));

foreach (var embeddedResource in embeddedResources)
{
var path = GetEmbeddedPath(embeddedResource);
if (path == null)
{
continue;
}

var resourceFullFilename = Path.Combine(Path.GetDirectoryName(projectPath), path);

var resourceName =
path.EndsWith(".resx", StringComparison.OrdinalIgnoreCase) ?
path.Remove(path.Length - 5) + ".resources" :
path;

resources.Add(new ResourceDescription(
$"{assemblyName}.{string.Join(".", resourceName.Split('\\'))}",
() => ProvideResourceData(resourceFullFilename),
true));
}

return resources;
}

private Stream ProvideResourceData(string resourceFullFilename)
{
// For non-.resx files just create a FileStream object to read the file as binary data
if (!resourceFullFilename.EndsWith(".resx", StringComparison.OrdinalIgnoreCase))
{
return File.OpenRead(resourceFullFilename);
}

var shortLivedBackingStream = new MemoryStream();
using (ResourceWriter resourceWriter = new ResourceWriter(shortLivedBackingStream))
{
resourceWriter.TypeNameConverter = TypeNameConverter;
using (var resourceReader = new ResXResourceReader(resourceFullFilename))
{
var dictionaryEnumerator = resourceReader.GetEnumerator();
while (dictionaryEnumerator.MoveNext())
{
if (dictionaryEnumerator.Key is string resourceKey)
{
resourceWriter.AddResource(resourceKey, dictionaryEnumerator.Value);
}
}
}
}

return new MemoryStream(shortLivedBackingStream.GetBuffer());
}

/// <summary>
/// This is needed to fix a "Could not load file or assembly 'System.Drawing, Version=4.0.0.0"
/// exception, although I'm not sure why that exception was occurring.
/// </summary>
private string TypeNameConverter(Type objectType)
{
return objectType.AssemblyQualifiedName.Replace("4.0.0.0", "2.0.0.0");
}

private string GetEmbeddedPath(XElement embeddedResource)
{
var paths = embeddedResource.Attribute("Include")?.Value;
if (paths != null)
{
return paths;
}

paths = embeddedResource.Attribute("Update")?.Value;
return paths;
}
}
}
1 change: 1 addition & 0 deletions src/Testura.Mutation.Core/Testura.Mutation.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<Compile Include="Enums.cs" />
<Compile Include="Exceptions\CompilationException.cs" />
<Compile Include="Exceptions\ProjectSetUpException.cs" />
<Compile Include="Execution\Compilation\EmbeddedResourceCreator.cs" />
<Compile Include="Execution\Compilation\IMutationDocumentCompiler.cs" />
<Compile Include="Execution\Compilation\IProjectCompiler.cs" />
<Compile Include="Execution\Report\Html\HtmlOnlyBodyReportCreator.cs" />
Expand Down
4 changes: 2 additions & 2 deletions src/Testura.Mutation.VsExtension/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.9.1.0")]
[assembly: AssemblyFileVersion("1.9.1.0")]
[assembly: AssemblyVersion("1.9.2.0")]
[assembly: AssemblyFileVersion("1.9.2.0")]
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" ?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="Testura.MutationVsExtension.71e8249a-b76c-4035-af2b-0304cbf33623" Version="1.9.1" Language="en-US" Publisher="Mille Boström" />
<Identity Id="Testura.MutationVsExtension.71e8249a-b76c-4035-af2b-0304cbf33623" Version="1.9.2" Language="en-US" Publisher="Mille Boström" />
<DisplayName>Testura.Mutation</DisplayName>
<Description xml:space="preserve">Testura is a mutation testing extension for visual studio that verifies the quality of your unit tests by injecting different mutations in your production code and then checks whether your unit tests catch them.</Description>
<MoreInfo>https://github.com/Testura/Testura.Mutation</MoreInfo>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Reflection;
using System.Threading.Tasks;
using NUnit.Framework;
using Testura.Mutation.Core.Execution.Compilation;
using Testura.Mutation.Tests.Utils.Creators;

namespace Testura.Mutation.Tests.Core.Execution.Compiler
Expand All @@ -18,7 +19,7 @@ public async Task CompileAsync()
var project = configCreator.Solution.Projects.Last();


var compiler = new Testura.Mutation.Core.Execution.Compilation.Compiler();
var compiler = new Testura.Mutation.Core.Execution.Compilation.Compiler(new EmbeddedResourceCreator());
var result = await compiler.CompileAsync(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), project);
}
}
Expand Down

0 comments on commit 931a7aa

Please sign in to comment.