Skip to content

Commit

Permalink
ability to run as a sanity test
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpar committed Aug 28, 2024
1 parent be5e620 commit 42dbd78
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
run: dotnet pack -p:PackageOutputPath="${GITHUB_WORKSPACE}/packages" -p:IncludeSymbols=false -p:RepositoryCommit=${GITHUB_SHA} -p:PackageVersion="0.0.0.1"

- name: Test
run: dotnet test --no-build --verbosity normal
run: dotnet test --framework net8.0 --no-build --verbosity normal

- name: Upload Binary Log
uses: actions/upload-artifact@v3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFrameworks>net8.0;net472</TargetFrameworks>
<IsPackable>false</IsPackable>
<RollForward>LatestMajor</RollForward>
</PropertyGroup>
Expand Down
82 changes: 82 additions & 0 deletions Src/Basic.Reference.Assemblies.UnitTests/CompilationUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Basic.Reference.Assemblies.UnitTests;
internal static class CompilationUtil
{
public static MemoryStream CompileToLibrary(string code, string assemblyName)
{
var references =
#if NET
Net80.References.All;
#else
Net461.References.All;
#endif
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
var compilation = CSharpCompilation.Create(
assemblyName,
[CSharpSyntaxTree.ParseText(code)],
references,
options);

var peStream = new MemoryStream();
var emitResult = compilation.Emit(peStream);
if (!emitResult.Success)
{
throw new Exception(GetMessage(emitResult.Diagnostics));
}

peStream.Position = 0;
return peStream;

static string GetMessage(IEnumerable<Diagnostic> diagnostics)
{
var builder = new StringBuilder();
builder.AppendLine("Compilation failed with the following errors:");
foreach (var d in diagnostics)
{
builder.AppendLine(d.ToString());
}
return builder.ToString();
}
}

public static Assembly CompileToLibraryAndLoad(string code, string assemblyName)
{
var stream = CompileToLibrary(code, assemblyName);
return Load(stream, assemblyName);
}

/// <summary>
/// Compile and run the code expecting to find a static Lib.Go method
/// </summary>
public static string? CompileAndRun(string code, string assemblyName)
{
var assembly = CompileToLibraryAndLoad(code, assemblyName);
var libType = assembly
.GetTypes()
.Where(x => x.Name == "Lib")
.Single();
var method = libType.GetMethod("Go", BindingFlags.Static | BindingFlags.NonPublic);
var obj = method!.Invoke(null, null);
return (string?)obj;
}

public static Assembly Load(MemoryStream stream, string assemblyName)
{
stream.Position = 0;
#if NET
var alc = new System.Runtime.Loader.AssemblyLoadContext(assemblyName);
return alc.LoadFromStream(stream);
#else
return Assembly.Load(stream.ToArray());
#endif
}
}
3 changes: 3 additions & 0 deletions Src/Basic.Reference.Assemblies.UnitTests/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

Expand Down
17 changes: 17 additions & 0 deletions Src/Basic.Reference.Assemblies.UnitTests/SanityUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,21 @@ static void Main()
Assert.True(emitResult.Success);
Assert.Empty(emitResult.Diagnostics);
}

[Fact]
public void RunTuple()
{
var source = """
static class Lib
{
public static string Go()
{
var tuple = (1, 2);
return tuple.ToString();
}
}
""";
var actual = CompilationUtil.CompileAndRun(source, nameof(RunTuple));
Assert.Equal("(1, 2)", actual);
}
}

0 comments on commit 42dbd78

Please sign in to comment.