Skip to content

Commit

Permalink
Playing around with fixing generated code with generic paramters (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
Keboo committed May 3, 2022
1 parent a34fe6f commit 7f6c1f8
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 35 deletions.
5 changes: 5 additions & 0 deletions GeneratorTests/Moq.AutoMocker.Generator.Example/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@ public Controller(IService service, string name)
Name = name ?? throw new ArgumentNullException(nameof(name));
}

public Controller(ILogger<Controller> logger)
{
_ = logger ?? throw new ArgumentNullException(nameof(logger));
}

public string Name { get; } = "";
}
6 changes: 6 additions & 0 deletions GeneratorTests/Moq.AutoMocker.Generator.Example/ILogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Moq.AutoMock.Generator.Example;

public interface ILogger<T>
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing.Verifiers;

namespace Moq.AutoMocker.TestGenerator.Tests;
Expand Down
75 changes: 64 additions & 11 deletions Moq.AutoMocker.TestGenerator.Tests/UnitTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using Microsoft.CodeAnalysis.Testing;
using System.Text;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text;
using System.Threading.Tasks;

using VerifyCS = Moq.AutoMocker.TestGenerator.Tests.CSharpSourceGeneratorVerifier<Moq.AutoMocker.TestGenerator.UnitTestSourceGenerator>;

Expand Down Expand Up @@ -48,10 +47,7 @@ public class Controller { }
.WithArguments("TestNamespace.ControllerTests");
await new VerifyCS.Test
{
TestState =
{
Sources = { code },
},
TestCode = code,
ExpectedDiagnostics =
{
expectedResult
Expand Down Expand Up @@ -81,14 +77,71 @@ public class Controller { }
.WithArguments("TestNamespace.ControllerTests");
await new VerifyCS.Test
{
TestState =
{
Sources = { code },
},
TestCode = code,
ExpectedDiagnostics =
{
expectedResult
}
}.RunAsync();
}

[TestMethod]
[Description("Issue 142")]
public async Task Generation_WithGenericParameter_RemovesInvalidCharactersFromTestsName()
{
var code = @"
using Moq.AutoMock;
namespace TestNamespace;
[ConstructorTests(typeof(Controller))]
public partial class ControllerTests
{
}
public class Controller
{
public Controller(ILogger<Controller> logger) { }
}
public interface ILogger<Controller> { }
";
string expected = @"namespace TestNamespace
{
partial class ControllerTests
{
partial void AutoMockerTestSetup(Moq.AutoMock.AutoMocker mocker, string testName);
partial void ControllerConstructor_WithNullILoggerController_ThrowsArgumentNullExceptionSetup(Moq.AutoMock.AutoMocker mocker);
public void ControllerConstructor_WithNullILoggerController_ThrowsArgumentNullException()
{
Moq.AutoMock.AutoMocker mocker = new Moq.AutoMock.AutoMocker();
AutoMockerTestSetup(mocker, ""ControllerConstructor_WithNullILoggerController_ThrowsArgumentNullException"");
ControllerConstructor_WithNullILoggerController_ThrowsArgumentNullExceptionSetup(mocker);
}
}
}
";

await new VerifyCS.Test
{
TestCode = code,
TestState =
{
GeneratedSources =
{
GetSourceFile(expected, "ControllerTests.g.cs")
}
}

}.RunAsync();
}

private static (string FileName, SourceText SourceText) GetSourceFile(string content, string fileName)
{
return (Path.Combine("Moq.AutoMocker.TestGenerator", "Moq.AutoMocker.TestGenerator.UnitTestSourceGenerator", fileName), SourceText.From(content, Encoding.UTF8));
}
}
9 changes: 9 additions & 0 deletions Moq.AutoMocker.TestGenerator/TargetTestingFramework.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Moq.AutoMocker.TestGenerator;

public enum TargetTestingFramework
{
Unknown,
MSTest,
Xunit,
NUnit
}
43 changes: 43 additions & 0 deletions Moq.AutoMocker.TestGenerator/TestNameBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Text;
using Microsoft.CodeAnalysis.CSharp;

namespace Moq.AutoMocker.TestGenerator;

internal static class TestNameBuilder
{
public static IEnumerable<string> CreateTestName(GeneratorTargetClass testClass, NullConstructorParameterTest test)
{
int testNameIndex = 0;
for (string testName = $"{testClass.Sut!.Name}Constructor_WithNull{test.NullTypeName}_ThrowsArgumentNullException";
;
testName = $"{testClass.Sut!.Name}Constructor_WithNull{test.NullTypeName}{++testNameIndex}_ThrowsArgumentNullException")
{
if (!SyntaxFacts.IsValidIdentifier(testName))
{
StringBuilder sb = new(testName.Length);
for (int i = 0; i < testName.Length; i++)
{
if (sb.Length == 0)
{
if (SyntaxFacts.IsIdentifierStartCharacter(testName[i]))
{
sb.Append(testName[i]);
}
}
else
{
if (SyntaxFacts.IsIdentifierPartCharacter(testName[i]))
{
sb.Append(testName[i]);
}
}
}
yield return sb.ToString();
}
else
{
yield return testName;
}
}
}
}
37 changes: 14 additions & 23 deletions Moq.AutoMocker.TestGenerator/UnitTestSourceGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;

namespace Moq.AutoMocker.TestGenerator;
Expand Down Expand Up @@ -41,12 +42,15 @@ public void Execute(GeneratorExecutionContext context)

foreach (var test in testClass.Sut?.NullConstructorParameterTests ?? Enumerable.Empty<NullConstructorParameterTest>())
{
string testName;
int testNameIndex = 0;
for (testName = $"{testClass.Sut!.Name}Constructor_WithNull{test.NullTypeName}_ThrowsArgumentNullException";
!testNames.Add(testName);
testName = $"{testClass.Sut!.Name}Constructor_WithNull{test.NullTypeName}{++testNameIndex}_ThrowsArgumentNullException")
{ }
string testName = "";
foreach(var name in TestNameBuilder.CreateTestName(testClass, test))
{
if (testNames.Add(name))
{
testName = name;
break;
}
}

builder.AppendLine($" partial void {testName}Setup(Moq.AutoMock.AutoMocker mocker);");
builder.AppendLine();
Expand Down Expand Up @@ -78,7 +82,7 @@ public void Execute(GeneratorExecutionContext context)
builder.AppendLine($" var {parameter.Name} = mocker.Get<{parameter.ParameterType}>();");
}

string constructorInvocation = $"_ = new {testClass.Sut.FullName}({string.Join(",", GetParameterNames(test))})";
string constructorInvocation = $"_ = new {testClass.Sut!.FullName}({string.Join(",", GetParameterNames(test))})";

switch (testingFramework)
{
Expand Down Expand Up @@ -111,14 +115,9 @@ static IEnumerable<string> GetParameterNames(NullConstructorParameterTest test)
{
for (int i = 0; i < test.Parameters?.Count; i++)
{
if (i == test.NullParameterIndex)
{
yield return $"default({test.Parameters[i].ParameterType})";
}
else
{
yield return test.Parameters[i].Name;
}
yield return i == test.NullParameterIndex
? $"default({test.Parameters[i].ParameterType})"
: test.Parameters[i].Name;
}
}
}
Expand Down Expand Up @@ -154,11 +153,3 @@ private static TargetTestingFramework GetTestingFramework(IEnumerable<AssemblyId
return TargetTestingFramework.Unknown;
}
}

public enum TargetTestingFramework
{
Unknown,
MSTest,
Xunit,
NUnit
}

0 comments on commit 7f6c1f8

Please sign in to comment.