Skip to content

Commit

Permalink
initial draft for improved source gen
Browse files Browse the repository at this point in the history
  • Loading branch information
floribe2000 committed Oct 6, 2023
1 parent a62fbc4 commit 9272b88
Show file tree
Hide file tree
Showing 20 changed files with 1,474 additions and 441 deletions.
11 changes: 5 additions & 6 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggesti
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
dotnet_style_qualification_for_event = false:suggestion
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_event = true:suggestion
dotnet_style_qualification_for_field = true:suggestion
dotnet_style_qualification_for_method = true:suggestion
dotnet_style_qualification_for_property = true:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion

# ReSharper properties
Expand Down Expand Up @@ -112,9 +112,8 @@ dotnet_diagnostic.rs2008.severity = none # Ignore analyzer release tracking
dotnet_diagnostic.sa0001.severity = none # Ignore disabled xml documentation
dotnet_diagnostic.sa1000.severity = none # Ignore missing space after "new"
dotnet_diagnostic.sa1009.severity = none # Ignore missing space after closing parenthesis
dotnet_diagnostic.sa1028.severity = none # Ignore trailing whitespace
dotnet_diagnostic.sa1100.severity = none # Ignore base. prefix if there is no local override
dotnet_diagnostic.sa1101.severity = none # Ignore missing this prefix for local calls
dotnet_diagnostic.sa1101.severity = suggestion # Ignore missing this prefix for local calls
dotnet_diagnostic.sa1122.severity = none # Don't force the use of string.Empty
dotnet_diagnostic.sa1124.severity = none # Allow the use of regions
dotnet_diagnostic.sa1127.severity = none # Generic constraints may share a line with other declarations
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.CodeAnalysis.Testing.Verifiers;
using NUnit.Framework;
using WoWsShipBuilder.Data.Generator.Attributes;
using WoWsShipBuilder.DataElements.DataElements;

namespace WoWsShipBuilder.Data.Generator.Test.DataElementGeneratorTest;

[TestFixture]
public partial class DataElementGeneratorTest
{
private static CSharpSourceGeneratorTest<DataElementGenerator, NUnitVerifier> CreateTest(string source, string expected)
{
const string baseClass = """
namespace WoWsShipBuilder.DataElements.DataElements;

public abstract record DataContainerBase
{
public global::System.Collections.Generic.List<IDataElement> DataElements { get; } = new();

protected static bool ShouldAdd(object? value)
{
return value switch
{
string strValue => !string.IsNullOrEmpty(strValue),
decimal decValue => decValue != 0,
(decimal min, decimal max) => min > 0 || max > 0,
int intValue => intValue != 0,
_ => false,
};
}
}
""";
return new()
{
TestState =
{
Sources = { baseClass, source },
GeneratedSources =
{
(typeof(DataElementGenerator), "DataElementTypes.g.cs", AttributeHelper.DataElementTypesEnum),
(typeof(DataElementGenerator), "DataContainerAttribute.g.cs", AttributeHelper.DataContainerAttribute),
(typeof(DataElementGenerator), "DataElementTypeAttribute.g.cs", AttributeHelper.DataElementTypeAttribute),
(typeof(DataElementGenerator), "DataElementFilteringAttribute.g.cs", AttributeHelper.DataElementFilteringAttribute),
(typeof(DataElementGenerator), "TestRecord.g.cs", expected),
},
ReferenceAssemblies = ReferenceAssemblies.Net.Net70,
AdditionalReferences = { MetadataReference.CreateFromFile(typeof(IDataElement).GetTypeInfo().Assembly.Location) },
},
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using NUnit.Framework;

namespace WoWsShipBuilder.Data.Generator.Test.DataElementGeneratorTest;

[SuppressMessage("Maintainability", "S2699", Justification = "false-positive since sonarlint does not recognize custom CreateTest method")]
public partial class DataElementGeneratorTest
{
[Test]
public async Task GenerateCode_EmptyRecord_EmptyMethod()
{
var source = """
using WoWsShipBuilder.DataElements.DataElementAttributes;
using WoWsShipBuilder.DataElements.DataElements;

namespace Test;

[DataContainer]
public partial record TestRecord : DataContainerBase
{
}
""";

var expected = """
// <auto-generated />
#nullable enable
namespace Test
{
public partial record TestRecord
{
private void UpdateDataElements()
{
this.DataElements.Clear();
}
}
}

""";

await CreateTest(source, expected).RunAsync();
}

[Test]
public async Task GenerateCode_SingleKeyValueUnit_Success()
{
var source = """
using WoWsShipBuilder.DataElements.DataElementAttributes;
using WoWsShipBuilder.DataElements.DataElements;

namespace Test;

[DataContainer]
public partial record TestRecord : DataContainerBase
{
[DataElementType(DataElementTypes.KeyValueUnit, UnitKey = "Knots")]
public decimal ManeuverabilityMaxSpeed { get; set; }
}
""";

var expected = """
// <auto-generated />
#nullable enable
namespace Test
{
public partial record TestRecord
{
private void UpdateDataElements()
{
this.DataElements.Clear();
if (global::WoWsShipBuilder.DataElements.DataElements.DataContainerBase.ShouldAdd(this.ManeuverabilityMaxSpeed))
{
this.DataElements.Add(new global::WoWsShipBuilder.DataElements.DataElements.KeyValueUnitDataElement("ShipStats_", this.ManeuverabilityMaxSpeed.ToString(), "Unit_Knots"));
}
}
}
}

""";

await CreateTest(source, expected).RunAsync();
}

[Test]
public async Task GenerateCode_OneGroupTwoElements_Success()
{
var source = """
using WoWsShipBuilder.DataElements.DataElementAttributes;
using WoWsShipBuilder.DataElements.DataElements;

namespace Test;

[DataContainer]
public partial record TestRecord : DataContainerBase
{
[DataElementType(DataElementTypes.Grouped | DataElementTypes.KeyValue, GroupKey = "Loaders")]
public string BowLoaders { get; set; } = default!;

[DataElementType(DataElementTypes.Grouped | DataElementTypes.KeyValue, GroupKey = "Loaders")]
public string SternLoaders { get; set; } = default!;
}
""";

var expected = """
// <auto-generated />
#nullable enable
namespace Test
{
public partial record TestRecord
{
private void UpdateDataElements()
{
this.DataElements.Clear();
var LoadersList = new global::System.Collections.Generic.List<global::WoWsShipBuilder.DataElements.DataElements.IDataElement>();
if (global::WoWsShipBuilder.DataElements.DataElements.DataContainerBase.ShouldAdd(this.BowLoaders))
{
LoadersList.Add(new global::WoWsShipBuilder.DataElements.DataElements.KeyValueDataElement("ShipStats_", this.BowLoaders, false, false));
}

if (global::WoWsShipBuilder.DataElements.DataElements.DataContainerBase.ShouldAdd(this.SternLoaders))
{
LoadersList.Add(new global::WoWsShipBuilder.DataElements.DataElements.KeyValueDataElement("ShipStats_", this.SternLoaders, false, false));
}

if (LoadersList.Count > 0)
{
this.DataElements.Add(new global::WoWsShipBuilder.DataElements.DataElements.GroupedDataElement("ShipStats_Loaders", LoadersList));
}
}
}
}

""";

await CreateTest(source, expected).RunAsync();
}
}
86 changes: 43 additions & 43 deletions WoWsShipBuilder.Data.Generator.Test/SourceGeneratorResultTest.cs
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using WoWsShipBuilder.Data.Generator.Test.TestStructures;
using WoWsShipBuilder.DataElements.DataElements;

namespace WoWsShipBuilder.Data.Generator.Test;

public class SourceGeneratorResultTest
{
[Test]
public void SingleDataValue_DataElementsNotEmpty()
{
const string testString = "1234test";
var testRecord = new TestDataUi1
{
TestValue = testString,
};

testRecord.UpdateData();

testRecord.DataElements.Should().NotBeEmpty();
}

[Test]
public void GroupedValuesSet_DataElementHasGroup()
{
const string testString = "1234test";
var testRecord = new TestDataUi1
{
TestGroup1 = testString,
Test2Group1 = testString,
};

testRecord.UpdateData();

testRecord.DataElements.Should().NotBeEmpty();
testRecord.DataElements.OfType<GroupedDataElement>().Should().HaveCount(1);
var groupedData = testRecord.DataElements.OfType<GroupedDataElement>().Single();
groupedData.Key.Should().BeEquivalentTo("ShipStats_test1");
groupedData.Children.Should().HaveCount(2);
}
}
// using System.Linq;
// using FluentAssertions;
// using NUnit.Framework;
// using WoWsShipBuilder.Data.Generator.Test.TestStructures;
// using WoWsShipBuilder.DataElements.DataElements;
//
// namespace WoWsShipBuilder.Data.Generator.Test;
//
// public class SourceGeneratorResultTest
// {
// [Test]
// public void SingleDataValue_DataElementsNotEmpty()
// {
// const string testString = "1234test";
// var testRecord = new TestDataUi1
// {
// TestValue = testString,
// };
//
// testRecord.UpdateData();
//
// testRecord.DataElements.Should().NotBeEmpty();
// }
//
// [Test]
// public void GroupedValuesSet_DataElementHasGroup()
// {
// const string testString = "1234test";
// var testRecord = new TestDataUi1
// {
// TestGroup1 = testString,
// Test2Group1 = testString,
// };
//
// testRecord.UpdateData();
//
// testRecord.DataElements.Should().NotBeEmpty();
// testRecord.DataElements.OfType<GroupedDataElement>().Should().HaveCount(1);
// var groupedData = testRecord.DataElements.OfType<GroupedDataElement>().Single();
// groupedData.Key.Should().BeEquivalentTo("ShipStats_test1");
// groupedData.Children.Should().HaveCount(2);
// }
// }
Loading

0 comments on commit 9272b88

Please sign in to comment.