From 0317644a21d52c9b55058ff94cb10f9518bcd47f Mon Sep 17 00:00:00 2001 From: sveinungf Date: Wed, 27 Dec 2023 23:33:24 +0100 Subject: [PATCH 01/22] Add ColumnOrderAttribute --- SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs diff --git a/SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs b/SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs new file mode 100644 index 00000000..fd8d7095 --- /dev/null +++ b/SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs @@ -0,0 +1,4 @@ +namespace SpreadCheetah.SourceGeneration; + +[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] +public sealed class ColumnOrderAttribute(int order) : Attribute; From 7853a0ba4b6178984453b11e73ee12431e4ca8b1 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Thu, 28 Dec 2023 00:10:59 +0100 Subject: [PATCH 02/22] Use newer C# features in source generator project --- Directory.Packages.props | 1 + .../Backporting/NotNullWhenAttribute.cs | 11 ----------- .../Helpers/ContextClass.cs | 17 ++++------------- .../Helpers/GeneratorOptions.cs | 10 +--------- .../Helpers/TypePropertiesInfo.cs | 14 +++----------- .../SpreadCheetah.SourceGenerator.csproj | 4 ++++ .../WorksheetRowGenerator.cs | 18 ++++-------------- 7 files changed, 17 insertions(+), 58 deletions(-) delete mode 100644 SpreadCheetah.SourceGenerator/Helpers/Backporting/NotNullWhenAttribute.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 7f9eaa5a..0768315d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -26,6 +26,7 @@ + diff --git a/SpreadCheetah.SourceGenerator/Helpers/Backporting/NotNullWhenAttribute.cs b/SpreadCheetah.SourceGenerator/Helpers/Backporting/NotNullWhenAttribute.cs deleted file mode 100644 index 1e4f733e..00000000 --- a/SpreadCheetah.SourceGenerator/Helpers/Backporting/NotNullWhenAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -#if NETSTANDARD2_0 -namespace System.Diagnostics.CodeAnalysis; - -[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] -internal sealed class NotNullWhenAttribute : Attribute -{ - public bool ReturnValue { get; } - - public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; -} -#endif \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator/Helpers/ContextClass.cs b/SpreadCheetah.SourceGenerator/Helpers/ContextClass.cs index f73ba02d..c965673d 100644 --- a/SpreadCheetah.SourceGenerator/Helpers/ContextClass.cs +++ b/SpreadCheetah.SourceGenerator/Helpers/ContextClass.cs @@ -2,16 +2,7 @@ namespace SpreadCheetah.SourceGenerator.Helpers; -internal sealed class ContextClass -{ - public ITypeSymbol ContextClassType { get; } - public Dictionary RowTypes { get; } - public GeneratorOptions? Options { get; } - - public ContextClass(ITypeSymbol contextClassType, Dictionary rowTypes, GeneratorOptions? options) - { - ContextClassType = contextClassType; - RowTypes = rowTypes; - Options = options; - } -} +internal sealed record ContextClass( + ITypeSymbol ContextClassType, + Dictionary RowTypes, + GeneratorOptions? Options); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator/Helpers/GeneratorOptions.cs b/SpreadCheetah.SourceGenerator/Helpers/GeneratorOptions.cs index b8e01838..f8f94e6f 100644 --- a/SpreadCheetah.SourceGenerator/Helpers/GeneratorOptions.cs +++ b/SpreadCheetah.SourceGenerator/Helpers/GeneratorOptions.cs @@ -1,11 +1,3 @@ namespace SpreadCheetah.SourceGenerator.Helpers; -internal sealed class GeneratorOptions -{ - public bool SuppressWarnings { get; } - - public GeneratorOptions(bool suppressWarnings) - { - SuppressWarnings = suppressWarnings; - } -} +internal sealed record GeneratorOptions(bool SuppressWarnings); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator/Helpers/TypePropertiesInfo.cs b/SpreadCheetah.SourceGenerator/Helpers/TypePropertiesInfo.cs index 8fc6205e..4b53b69e 100644 --- a/SpreadCheetah.SourceGenerator/Helpers/TypePropertiesInfo.cs +++ b/SpreadCheetah.SourceGenerator/Helpers/TypePropertiesInfo.cs @@ -2,14 +2,6 @@ namespace SpreadCheetah.SourceGenerator.Helpers; -internal sealed class TypePropertiesInfo -{ - public List PropertyNames { get; } - public List UnsupportedProperties { get; } - - public TypePropertiesInfo(List propertyNames, List unsupportedProperties) - { - PropertyNames = propertyNames; - UnsupportedProperties = unsupportedProperties; - } -} +internal sealed record TypePropertiesInfo( + List PropertyNames, + List UnsupportedProperties); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator/SpreadCheetah.SourceGenerator.csproj b/SpreadCheetah.SourceGenerator/SpreadCheetah.SourceGenerator.csproj index d547888a..519aac16 100644 --- a/SpreadCheetah.SourceGenerator/SpreadCheetah.SourceGenerator.csproj +++ b/SpreadCheetah.SourceGenerator/SpreadCheetah.SourceGenerator.csproj @@ -15,6 +15,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs index e6b462fa..16ceaf90 100644 --- a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs +++ b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs @@ -56,14 +56,7 @@ private static bool IsSyntaxTargetForGeneration(SyntaxNode syntaxNode) => syntax return null; var classSymbol = context.SemanticModel.GetDeclaredSymbol(classDeclaration, token); - if (classSymbol is null) - return null; - - if (classSymbol.IsStatic) - return null; - - var baseType = classSymbol.BaseType; - if (baseType is null) + if (classSymbol is not { IsStatic: false, BaseType: { } baseType }) return null; var baseContext = GetContextBaseType(context.SemanticModel.Compilation); @@ -116,10 +109,7 @@ private static bool TryParseWorksheetRowAttribute( return false; var args = attribute.ConstructorArguments; - if (args.Length != 1) - return false; - - if (args[0].Value is not INamedTypeSymbol symbol) + if (args is not [{ Value: INamedTypeSymbol symbol }]) return false; if (symbol.Kind == SymbolKind.ErrorType) @@ -215,7 +205,7 @@ private static bool IsSupportedNullableType(Compilation compilation, ITypeSymbol } private static readonly SpecialType[] SupportedPrimitiveTypes = - { + [ SpecialType.System_Boolean, SpecialType.System_DateTime, SpecialType.System_Decimal, @@ -223,7 +213,7 @@ private static bool IsSupportedNullableType(Compilation compilation, ITypeSymbol SpecialType.System_Int32, SpecialType.System_Int64, SpecialType.System_Single - }; + ]; private static void Execute(Compilation compilation, ImmutableArray classes, SourceProductionContext context) { From ad063b3fc6ad5616f100433a87a096d8f2af4d9d Mon Sep 17 00:00:00 2001 From: sveinungf Date: Thu, 28 Dec 2023 00:53:17 +0100 Subject: [PATCH 03/22] WIP for parsing ColumnOrder attributes in src gen --- .../Helpers/TypePropertiesInfo.cs | 2 +- .../WorksheetRowGenerator.cs | 92 +++++++++++++++---- 2 files changed, 77 insertions(+), 17 deletions(-) diff --git a/SpreadCheetah.SourceGenerator/Helpers/TypePropertiesInfo.cs b/SpreadCheetah.SourceGenerator/Helpers/TypePropertiesInfo.cs index 4b53b69e..fd5849be 100644 --- a/SpreadCheetah.SourceGenerator/Helpers/TypePropertiesInfo.cs +++ b/SpreadCheetah.SourceGenerator/Helpers/TypePropertiesInfo.cs @@ -3,5 +3,5 @@ namespace SpreadCheetah.SourceGenerator.Helpers; internal sealed record TypePropertiesInfo( - List PropertyNames, + SortedDictionary PropertyNames, List UnsupportedProperties); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs index 16ceaf90..3f6fbf82 100644 --- a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs +++ b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs @@ -42,6 +42,11 @@ private static bool IsSyntaxTargetForGeneration(SyntaxNode syntaxNode) => syntax return compilation.GetTypeByMetadataName("SpreadCheetah.SourceGeneration.WorksheetRowGenerationOptionsAttribute"); } + private static INamedTypeSymbol? GetColumnOrderAttributeType(Compilation compilation) + { + return compilation.GetTypeByMetadataName("SpreadCheetah.SourceGeneration.ColumnOrderAttribute"); + } + private static INamedTypeSymbol? GetContextBaseType(Compilation compilation) { return compilation.GetTypeByMetadataName("SpreadCheetah.SourceGeneration.WorksheetRowContext"); @@ -152,9 +157,31 @@ private static bool TryParseOptionsAttribute( return false; } + private static bool TryParseColumnOrderAttribute( + AttributeData attribute, + INamedTypeSymbol expectedAttribute, + out int order) + { + order = 0; + + if (!SymbolEqualityComparer.Default.Equals(expectedAttribute, attribute.AttributeClass)) + return false; + + var args = attribute.ConstructorArguments; + if (args is not [{ Value: int attributeValue }]) + return false; + + order = attributeValue; + return true; + } + private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, ITypeSymbol classType) { - var propertyNames = new List(); + // TODO: Is this the correct place to do this? + var columnOrderAttribute = GetColumnOrderAttributeType(compilation)!; + + var implicitOrderPropertyNames = new List(); + var explicitOrderPropertyNames = new SortedDictionary(); var unsupportedPropertyNames = new List(); foreach (var member in classType.GetMembers()) @@ -173,7 +200,29 @@ private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, || SupportedPrimitiveTypes.Contains(p.Type.SpecialType) || IsSupportedNullableType(compilation, p.Type)) { - propertyNames.Add(p.Name); + int? order = null; + + foreach (var attribute in p.GetAttributes()) + { + if (TryParseColumnOrderAttribute(attribute, columnOrderAttribute, out var attributeValue)) + { + order = attributeValue; + break; + } + } + + if (order is not { } orderValue) + { + implicitOrderPropertyNames.Add(p.Name); + } + else if (explicitOrderPropertyNames.ContainsKey(orderValue)) + { + // TODO: Fail + } + else + { + explicitOrderPropertyNames.Add(orderValue, p.Name); + } } else { @@ -181,7 +230,17 @@ private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, } } - return new TypePropertiesInfo(propertyNames, unsupportedPropertyNames); + var implicitOrderNumber = 1; + foreach (var propertyName in implicitOrderPropertyNames) + { + while (explicitOrderPropertyNames.ContainsKey(implicitOrderNumber)) + ++implicitOrderNumber; + + explicitOrderPropertyNames.Add(implicitOrderNumber, propertyName); + ++implicitOrderNumber; + } + + return new TypePropertiesInfo(explicitOrderPropertyNames, unsupportedPropertyNames); } private static bool IsSupportedNullableType(Compilation compilation, ITypeSymbol type) @@ -288,8 +347,9 @@ private static void GenerateCode(StringBuilder sb, ContextClass contextClass, Co var info = AnalyzeTypeProperties(compilation, rowType); ReportDiagnostics(info, rowType, location, contextClass.Options, context); - GenerateAddAsRow(sb, 2, rowType, info.PropertyNames); - GenerateAddRangeAsRows(sb, 2, rowType, info.PropertyNames); + var propertyNames = info.PropertyNames.Values; + GenerateAddAsRow(sb, 2, rowType, propertyNames); + GenerateAddRangeAsRows(sb, 2, rowType, propertyNames); if (info.PropertyNames.Count == 0) { @@ -297,10 +357,10 @@ private static void GenerateCode(StringBuilder sb, ContextClass contextClass, Co continue; } - GenerateAddAsRowInternal(sb, 2, rowTypeFullName, info.PropertyNames); - GenerateAddRangeAsRowsInternal(sb, rowType, info.PropertyNames); + GenerateAddAsRowInternal(sb, 2, rowTypeFullName, propertyNames); + GenerateAddRangeAsRowsInternal(sb, rowType, propertyNames); GenerateAddEnumerableAsRows(sb, 2, rowType); - GenerateAddCellsAsRow(sb, 2, rowType, info.PropertyNames); + GenerateAddCellsAsRow(sb, 2, rowType, propertyNames); } sb.AppendLine(" }"); @@ -318,7 +378,7 @@ private static void ReportDiagnostics(TypePropertiesInfo info, INamedTypeSymbol context.ReportDiagnostic(Diagnostic.Create(Diagnostics.UnsupportedTypeForCellValue, location, rowType.Name, unsupportedProperty.Type.Name)); } - private static void GenerateAddAsRow(StringBuilder sb, int indent, INamedTypeSymbol rowType, List propertyNames) + private static void GenerateAddAsRow(StringBuilder sb, int indent, INamedTypeSymbol rowType, IReadOnlyCollection propertyNames) { sb.AppendLine() .AppendIndentation(indent) @@ -347,7 +407,7 @@ private static void GenerateAddAsRow(StringBuilder sb, int indent, INamedTypeSym sb.AppendLine(indent, "}"); } - private static void GenerateAddAsRowInternal(StringBuilder sb, int indent, string rowTypeFullname, List propertyNames) + private static void GenerateAddAsRowInternal(StringBuilder sb, int indent, string rowTypeFullname, IReadOnlyCollection propertyNames) { sb.AppendLine(); sb.AppendLine(indent, $"private static async ValueTask AddAsRowInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, {rowTypeFullname} obj, CancellationToken token)"); @@ -364,7 +424,7 @@ private static void GenerateAddAsRowInternal(StringBuilder sb, int indent, strin sb.AppendLine(indent, "}"); } - private static void GenerateAddRangeAsRows(StringBuilder sb, int indent, INamedTypeSymbol rowType, List propertyNames) + private static void GenerateAddRangeAsRows(StringBuilder sb, int indent, INamedTypeSymbol rowType, IReadOnlyCollection propertyNames) { sb.AppendLine() .AppendIndentation(indent) @@ -402,7 +462,7 @@ private static void GenerateAddRangeAsEmptyRows(StringBuilder sb, int indent, IN sb.AppendLine(indent, "}"); } - private static void GenerateAddRangeAsRowsInternal(StringBuilder sb, INamedTypeSymbol rowType, List propertyNames) + private static void GenerateAddRangeAsRowsInternal(StringBuilder sb, INamedTypeSymbol rowType, IReadOnlyCollection propertyNames) { var typeString = rowType.ToTypeString(); sb.Append($$""" @@ -439,7 +499,7 @@ private static void GenerateAddEnumerableAsRows(StringBuilder sb, int indent, IN sb.AppendLine(indent, "}"); } - private static void GenerateAddCellsAsRow(StringBuilder sb, int indent, INamedTypeSymbol rowType, List propertyNames) + private static void GenerateAddCellsAsRow(StringBuilder sb, int indent, INamedTypeSymbol rowType, IReadOnlyCollection propertyNames) { sb.AppendLine() .AppendIndentation(indent) @@ -456,13 +516,13 @@ private static void GenerateAddCellsAsRow(StringBuilder sb, int indent, INamedTy sb.AppendLine(); } - for (var i = 0; i < propertyNames.Count; ++i) + foreach (var (propertyName, index) in propertyNames.Select((x, i) => (x, i))) { sb.AppendIndentation(indent + 1) .Append("cells[") - .Append(i) + .Append(index) .Append("] = new DataCell(obj.") - .Append(propertyNames[i]) + .Append(propertyName) .AppendLine(");"); } From 0fcc0e89b6b43829434a6ca88cedaaee8612e846 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Thu, 28 Dec 2023 09:08:31 +0100 Subject: [PATCH 04/22] Src gen snapshot tests for types with inheritance --- .../Models/ClassWithInheritance.cs | 7 ++ .../Models/RecordClassWithInheritance.cs | 4 + ...#MyNamespace.MyGenRowContext.g.verified.cs | 88 +++++++++++++++++++ ...#MyNamespace.MyGenRowContext.g.verified.cs | 88 +++++++++++++++++++ .../Tests/WorksheetRowSourceGeneratorTests.cs | 44 ++++++++++ 5 files changed, 231 insertions(+) create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Models/ClassWithInheritance.cs create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Models/RecordClassWithInheritance.cs create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Models/ClassWithInheritance.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Models/ClassWithInheritance.cs new file mode 100644 index 00000000..637ffda3 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Models/ClassWithInheritance.cs @@ -0,0 +1,7 @@ +namespace SpreadCheetah.SourceGenerator.SnapshotTest.Models; + +public class ClassWithInheritance : ClassWithSingleProperty +{ + public string Address { get; set; } = ""; + public string Country { get; set; } = ""; +} diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Models/RecordClassWithInheritance.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Models/RecordClassWithInheritance.cs new file mode 100644 index 00000000..4e5249d8 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Models/RecordClassWithInheritance.cs @@ -0,0 +1,4 @@ +namespace SpreadCheetah.SourceGenerator.SnapshotTest.Models; + +public record RecordClassWithInheritance(string Name, bool Value, int Age) + : RecordClassWithSingleProperty(Value); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs new file mode 100644 index 00000000..248c2a1d --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs @@ -0,0 +1,88 @@ +//HintName: MyNamespace.MyGenRowContext.g.cs +// +#nullable enable +using SpreadCheetah; +using SpreadCheetah.SourceGeneration; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MyNamespace +{ + public partial class MyGenRowContext + { + private static MyGenRowContext? _default; + public static MyGenRowContext Default => _default ??= new MyGenRowContext(); + + public MyGenRowContext() + { + } + + private WorksheetRowTypeInfo? _ClassWithInheritance; + public WorksheetRowTypeInfo ClassWithInheritance => _ClassWithInheritance ??= WorksheetRowMetadataServices.CreateObjectInfo(AddAsRowAsync, AddRangeAsRowsAsync); + + private static ValueTask AddAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ClassWithInheritance? obj, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + return AddAsRowInternalAsync(spreadsheet, obj, token); + } + + private static ValueTask AddRangeAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (objs is null) + throw new ArgumentNullException(nameof(objs)); + return AddRangeAsRowsInternalAsync(spreadsheet, objs, token); + } + + private static async ValueTask AddAsRowInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ClassWithInheritance obj, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(2); + try + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddRangeAsRowsInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(2); + try + { + await AddEnumerableAsRowsAsync(spreadsheet, objs, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddEnumerableAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, DataCell[] cells, CancellationToken token) + { + foreach (var obj in objs) + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + } + + private static ValueTask AddCellsAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ClassWithInheritance? obj, DataCell[] cells, CancellationToken token) + { + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + + cells[0] = new DataCell(obj.Address); + cells[1] = new DataCell(obj.Country); + return spreadsheet.AddRowAsync(cells.AsMemory(0, 2), token); + } + } +} diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs new file mode 100644 index 00000000..69c37987 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs @@ -0,0 +1,88 @@ +//HintName: MyNamespace.MyGenRowContext.g.cs +// +#nullable enable +using SpreadCheetah; +using SpreadCheetah.SourceGeneration; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MyNamespace +{ + public partial class MyGenRowContext + { + private static MyGenRowContext? _default; + public static MyGenRowContext Default => _default ??= new MyGenRowContext(); + + public MyGenRowContext() + { + } + + private WorksheetRowTypeInfo? _RecordClassWithInheritance; + public WorksheetRowTypeInfo RecordClassWithInheritance => _RecordClassWithInheritance ??= WorksheetRowMetadataServices.CreateObjectInfo(AddAsRowAsync, AddRangeAsRowsAsync); + + private static ValueTask AddAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.RecordClassWithInheritance? obj, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + return AddAsRowInternalAsync(spreadsheet, obj, token); + } + + private static ValueTask AddRangeAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (objs is null) + throw new ArgumentNullException(nameof(objs)); + return AddRangeAsRowsInternalAsync(spreadsheet, objs, token); + } + + private static async ValueTask AddAsRowInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.RecordClassWithInheritance obj, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(2); + try + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddRangeAsRowsInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(2); + try + { + await AddEnumerableAsRowsAsync(spreadsheet, objs, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddEnumerableAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, DataCell[] cells, CancellationToken token) + { + foreach (var obj in objs) + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + } + + private static ValueTask AddCellsAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.RecordClassWithInheritance? obj, DataCell[] cells, CancellationToken token) + { + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + + cells[0] = new DataCell(obj.Name); + cells[1] = new DataCell(obj.Age); + return spreadsheet.AddRowAsync(cells.AsMemory(0, 2), token); + } + } +} diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowSourceGeneratorTests.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowSourceGeneratorTests.cs index 5b46fe70..e4d6809d 100644 --- a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowSourceGeneratorTests.cs +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowSourceGeneratorTests.cs @@ -188,6 +188,28 @@ public partial class MyGenRowContext : WorksheetRowContext return TestHelper.CompileAndVerify(source); } + [Fact] + public Task WorksheetRowSourceGenerator_Generate_ClassWithInheritance() + { + // Arrange + const string source = """ + using SpreadCheetah.SourceGeneration; + using SpreadCheetah.SourceGenerator.SnapshotTest.Models; + using System; + + namespace MyNamespace + { + [WorksheetRow(typeof(ClassWithInheritance))] + public partial class MyGenRowContext : WorksheetRowContext + { + } + } + """; + + // Act & Assert + return TestHelper.CompileAndVerify(source); + } + [Fact] public Task WorksheetRowSourceGenerator_Generate_RecordClassWithSingleProperty() { @@ -298,6 +320,28 @@ public partial class MyGenRowContext : WorksheetRowContext return TestHelper.CompileAndVerify(source); } + [Fact] + public Task WorksheetRowSourceGenerator_Generate_RecordClassWithInheritance() + { + // Arrange + const string source = """ + using SpreadCheetah.SourceGeneration; + using SpreadCheetah.SourceGenerator.SnapshotTest.Models; + using System; + + namespace MyNamespace + { + [WorksheetRow(typeof(RecordClassWithInheritance))] + public partial class MyGenRowContext : WorksheetRowContext + { + } + } + """; + + // Act & Assert + return TestHelper.CompileAndVerify(source); + } + [Fact] public Task WorksheetRowSourceGenerator_Generate_ContextWithTwoWorksheetRowAttributes() { From fa0b4db281da08060e9300152ef06f50448384bf Mon Sep 17 00:00:00 2001 From: sveinungf Date: Thu, 28 Dec 2023 09:27:52 +0100 Subject: [PATCH 05/22] Split code from AnalyzeTypeProperties into methods --- .../Extensions/SortedDictionaryExtensions.cs | 19 ++++++ .../WorksheetRowGenerator.cs | 67 +++++++++---------- 2 files changed, 52 insertions(+), 34 deletions(-) create mode 100644 SpreadCheetah.SourceGenerator/Extensions/SortedDictionaryExtensions.cs diff --git a/SpreadCheetah.SourceGenerator/Extensions/SortedDictionaryExtensions.cs b/SpreadCheetah.SourceGenerator/Extensions/SortedDictionaryExtensions.cs new file mode 100644 index 00000000..c84eb0aa --- /dev/null +++ b/SpreadCheetah.SourceGenerator/Extensions/SortedDictionaryExtensions.cs @@ -0,0 +1,19 @@ +namespace SpreadCheetah.SourceGenerator.Extensions; + +internal static class SortedDictionaryExtensions +{ + public static void AddWithImplicitKeys( + this SortedDictionary dictionary, + IEnumerable values) + { + var implicitKey = 1; + foreach (var value in values) + { + while (dictionary.ContainsKey(implicitKey)) + ++implicitKey; + + dictionary.Add(implicitKey, value); + ++implicitKey; + } + } +} diff --git a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs index 3f6fbf82..b4a56950 100644 --- a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs +++ b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using SpreadCheetah.SourceGenerator; +using SpreadCheetah.SourceGenerator.Extensions; using SpreadCheetah.SourceGenerator.Helpers; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; @@ -196,51 +197,49 @@ private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, continue; } - if (p.Type.SpecialType == SpecialType.System_String - || SupportedPrimitiveTypes.Contains(p.Type.SpecialType) - || IsSupportedNullableType(compilation, p.Type)) + if (!IsSupportedType(p.Type, compilation)) { - int? order = null; - - foreach (var attribute in p.GetAttributes()) - { - if (TryParseColumnOrderAttribute(attribute, columnOrderAttribute, out var attributeValue)) - { - order = attributeValue; - break; - } - } + unsupportedPropertyNames.Add(p); + continue; + } - if (order is not { } orderValue) - { - implicitOrderPropertyNames.Add(p.Name); - } - else if (explicitOrderPropertyNames.ContainsKey(orderValue)) - { - // TODO: Fail - } - else - { - explicitOrderPropertyNames.Add(orderValue, p.Name); - } + if (!TryGetExplicitColumnOrder(p, columnOrderAttribute, out var columnOrder)) + { + implicitOrderPropertyNames.Add(p.Name); + } + else if (explicitOrderPropertyNames.ContainsKey(columnOrder)) + { + // TODO: Fail } else { - unsupportedPropertyNames.Add(p); + explicitOrderPropertyNames.Add(columnOrder, p.Name); } } - var implicitOrderNumber = 1; - foreach (var propertyName in implicitOrderPropertyNames) - { - while (explicitOrderPropertyNames.ContainsKey(implicitOrderNumber)) - ++implicitOrderNumber; + explicitOrderPropertyNames.AddWithImplicitKeys(implicitOrderPropertyNames); + + return new TypePropertiesInfo(explicitOrderPropertyNames, unsupportedPropertyNames); + } + + private static bool TryGetExplicitColumnOrder(IPropertySymbol property, INamedTypeSymbol columnOrderAttribute, out int columnOrder) + { + columnOrder = 0; - explicitOrderPropertyNames.Add(implicitOrderNumber, propertyName); - ++implicitOrderNumber; + foreach (var attribute in property.GetAttributes()) + { + if (TryParseColumnOrderAttribute(attribute, columnOrderAttribute, out columnOrder)) + return true; } - return new TypePropertiesInfo(explicitOrderPropertyNames, unsupportedPropertyNames); + return false; + } + + private static bool IsSupportedType(ITypeSymbol type, Compilation compilation) + { + return type.SpecialType == SpecialType.System_String + || SupportedPrimitiveTypes.Contains(type.SpecialType) + || IsSupportedNullableType(compilation, type); } private static bool IsSupportedNullableType(Compilation compilation, ITypeSymbol type) From 9b78aa68cccfc90458d2608ec0aed67d3d9d1dcc Mon Sep 17 00:00:00 2001 From: sveinungf Date: Thu, 28 Dec 2023 10:00:12 +0100 Subject: [PATCH 06/22] Src gen type for holding references to types from main project --- .../Extensions/CompilationExtensions.cs | 42 ++++++++++++++++ .../Helpers/ContextClass.cs | 2 + .../Models/CompilationTypes.cs | 9 ++++ .../WorksheetRowGenerator.cs | 49 ++++--------------- 4 files changed, 62 insertions(+), 40 deletions(-) create mode 100644 SpreadCheetah.SourceGenerator/Extensions/CompilationExtensions.cs create mode 100644 SpreadCheetah.SourceGenerator/Models/CompilationTypes.cs diff --git a/SpreadCheetah.SourceGenerator/Extensions/CompilationExtensions.cs b/SpreadCheetah.SourceGenerator/Extensions/CompilationExtensions.cs new file mode 100644 index 00000000..a4fe064f --- /dev/null +++ b/SpreadCheetah.SourceGenerator/Extensions/CompilationExtensions.cs @@ -0,0 +1,42 @@ +using Microsoft.CodeAnalysis; +using SpreadCheetah.SourceGenerator.Models; +using System.Diagnostics.CodeAnalysis; + +namespace SpreadCheetah.SourceGenerator.Extensions; + +internal static class CompilationExtensions +{ + public static bool TryGetCompilationTypes( + this Compilation compilation, + [NotNullWhen(true)] out CompilationTypes? result) + { + result = null; + const string ns = "SpreadCheetah.SourceGeneration"; + + if (!compilation.TryGetType($"{ns}.ColumnOrderAttribute", out var columnOrder)) + return false; + if (!compilation.TryGetType($"{ns}.WorksheetRowAttribute", out var row)) + return false; + if (!compilation.TryGetType($"{ns}.WorksheetRowContext", out var context)) + return false; + if (!compilation.TryGetType($"{ns}.WorksheetRowGenerationOptionsAttribute", out var options)) + return false; + + result = new CompilationTypes( + ColumnOrderAttribute: columnOrder, + WorksheetRowAttribute: row, + WorksheetRowContext: context, + WorksheetRowGenerationOptionsAttribute: options); + + return true; + } + + private static bool TryGetType( + this Compilation compilation, + string fullyQualifiedMetadataName, + [NotNullWhen(true)] out INamedTypeSymbol? result) + { + result = compilation.GetTypeByMetadataName(fullyQualifiedMetadataName); + return result is not null; + } +} diff --git a/SpreadCheetah.SourceGenerator/Helpers/ContextClass.cs b/SpreadCheetah.SourceGenerator/Helpers/ContextClass.cs index c965673d..51629ef7 100644 --- a/SpreadCheetah.SourceGenerator/Helpers/ContextClass.cs +++ b/SpreadCheetah.SourceGenerator/Helpers/ContextClass.cs @@ -1,8 +1,10 @@ using Microsoft.CodeAnalysis; +using SpreadCheetah.SourceGenerator.Models; namespace SpreadCheetah.SourceGenerator.Helpers; internal sealed record ContextClass( ITypeSymbol ContextClassType, Dictionary RowTypes, + CompilationTypes CompilationTypes, GeneratorOptions? Options); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator/Models/CompilationTypes.cs b/SpreadCheetah.SourceGenerator/Models/CompilationTypes.cs new file mode 100644 index 00000000..9c5878b2 --- /dev/null +++ b/SpreadCheetah.SourceGenerator/Models/CompilationTypes.cs @@ -0,0 +1,9 @@ +using Microsoft.CodeAnalysis; + +namespace SpreadCheetah.SourceGenerator.Models; + +internal record CompilationTypes( + INamedTypeSymbol WorksheetRowAttribute, + INamedTypeSymbol WorksheetRowGenerationOptionsAttribute, + INamedTypeSymbol ColumnOrderAttribute, + INamedTypeSymbol WorksheetRowContext); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs index b4a56950..a75c1c65 100644 --- a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs +++ b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs @@ -4,6 +4,7 @@ using SpreadCheetah.SourceGenerator; using SpreadCheetah.SourceGenerator.Extensions; using SpreadCheetah.SourceGenerator.Helpers; +using SpreadCheetah.SourceGenerator.Models; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Text; @@ -33,26 +34,6 @@ private static bool IsSyntaxTargetForGeneration(SyntaxNode syntaxNode) => syntax BaseList.Types.Count: > 0 }; - private static INamedTypeSymbol? GetWorksheetRowAttributeType(Compilation compilation) - { - return compilation.GetTypeByMetadataName("SpreadCheetah.SourceGeneration.WorksheetRowAttribute"); - } - - private static INamedTypeSymbol? GetGenerationOptionsAttributeType(Compilation compilation) - { - return compilation.GetTypeByMetadataName("SpreadCheetah.SourceGeneration.WorksheetRowGenerationOptionsAttribute"); - } - - private static INamedTypeSymbol? GetColumnOrderAttributeType(Compilation compilation) - { - return compilation.GetTypeByMetadataName("SpreadCheetah.SourceGeneration.ColumnOrderAttribute"); - } - - private static INamedTypeSymbol? GetContextBaseType(Compilation compilation) - { - return compilation.GetTypeByMetadataName("SpreadCheetah.SourceGeneration.WorksheetRowContext"); - } - private static ContextClass? GetSemanticTargetForGeneration(GeneratorSyntaxContext context, CancellationToken token) { if (context.Node is not ClassDeclarationSyntax classDeclaration) @@ -65,19 +46,10 @@ private static bool IsSyntaxTargetForGeneration(SyntaxNode syntaxNode) => syntax if (classSymbol is not { IsStatic: false, BaseType: { } baseType }) return null; - var baseContext = GetContextBaseType(context.SemanticModel.Compilation); - if (baseContext is null) - return null; - - if (!SymbolEqualityComparer.Default.Equals(baseContext, baseType)) - return null; - - var worksheetRowAttribute = GetWorksheetRowAttributeType(context.SemanticModel.Compilation); - if (worksheetRowAttribute is null) + if (!context.SemanticModel.Compilation.TryGetCompilationTypes(out var compilationTypes)) return null; - var optionsAttribute = GetGenerationOptionsAttributeType(context.SemanticModel.Compilation); - if (optionsAttribute is null) + if (!SymbolEqualityComparer.Default.Equals(compilationTypes.WorksheetRowContext, baseType)) return null; var rowTypes = new Dictionary(SymbolEqualityComparer.Default); @@ -85,19 +57,19 @@ private static bool IsSyntaxTargetForGeneration(SyntaxNode syntaxNode) => syntax foreach (var attribute in classSymbol.GetAttributes()) { - if (TryParseWorksheetRowAttribute(attribute, worksheetRowAttribute, token, out var typeSymbol, out var location) + if (TryParseWorksheetRowAttribute(attribute, compilationTypes.WorksheetRowAttribute, token, out var typeSymbol, out var location) && !rowTypes.ContainsKey(typeSymbol)) { rowTypes[typeSymbol] = location; continue; } - if (TryParseOptionsAttribute(attribute, optionsAttribute, out var options)) + if (TryParseOptionsAttribute(attribute, compilationTypes.WorksheetRowGenerationOptionsAttribute, out var options)) generatorOptions = options; } return rowTypes.Count > 0 - ? new ContextClass(classSymbol, rowTypes, generatorOptions) + ? new ContextClass(classSymbol, rowTypes, compilationTypes, generatorOptions) : null; } @@ -176,11 +148,8 @@ private static bool TryParseColumnOrderAttribute( return true; } - private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, ITypeSymbol classType) + private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, CompilationTypes compilationTypes, ITypeSymbol classType) { - // TODO: Is this the correct place to do this? - var columnOrderAttribute = GetColumnOrderAttributeType(compilation)!; - var implicitOrderPropertyNames = new List(); var explicitOrderPropertyNames = new SortedDictionary(); var unsupportedPropertyNames = new List(); @@ -203,7 +172,7 @@ private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, continue; } - if (!TryGetExplicitColumnOrder(p, columnOrderAttribute, out var columnOrder)) + if (!TryGetExplicitColumnOrder(p, compilationTypes.ColumnOrderAttribute, out var columnOrder)) { implicitOrderPropertyNames.Add(p.Name); } @@ -343,7 +312,7 @@ private static void GenerateCode(StringBuilder sb, ContextClass contextClass, Co sb.AppendLine(2, $"private WorksheetRowTypeInfo<{rowTypeFullName}>? _{rowTypeName};"); sb.AppendLine(2, $"public WorksheetRowTypeInfo<{rowTypeFullName}> {rowTypeName} => _{rowTypeName} ??= WorksheetRowMetadataServices.CreateObjectInfo<{rowTypeFullName}>(AddAsRowAsync, AddRangeAsRowsAsync);"); - var info = AnalyzeTypeProperties(compilation, rowType); + var info = AnalyzeTypeProperties(compilation, contextClass.CompilationTypes, rowType); ReportDiagnostics(info, rowType, location, contextClass.Options, context); var propertyNames = info.PropertyNames.Values; From 79df6b47ec0ee58344a07cb2f4a9deb1809dc761 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Thu, 28 Dec 2023 10:21:54 +0100 Subject: [PATCH 07/22] Rename snapshot tests --- .../Helpers/TestHelper.cs | 2 +- ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...nerate_ClassWithNoProperties.verified.txt} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...ClassWithUnsupportedProperty.verified.txt} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...MyNamespace.MyGenRowContext.g.verified.cs} | 0 ...yNamespace.MyGenRowContext2.g.verified.cs} | 0 ...Tests.cs => WorksheetRowGeneratorTests.cs} | 42 +++++++++---------- 25 files changed, 22 insertions(+), 22 deletions(-) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithAllSupportedTypes#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithAllSupportedTypes#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithMultipleProperties#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithMultipleProperties#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithNoProperties#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithNoProperties#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithNoProperties.verified.txt => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithNoProperties.verified.txt} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithNoPropertiesAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithNoPropertiesAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedProperty#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithUnsupportedProperty#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedProperty.verified.txt => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithUnsupportedProperty.verified.txt} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedPropertyAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithUnsupportedPropertyAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextClassWithDefaultAccessibility#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextClassWithDefaultAccessibility#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextClassWithInternalAccessibility#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextClassWithInternalAccessibility#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextWithTwoSimilarWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextWithTwoSimilarWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextWithTwoWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextWithTwoWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_InternalClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_InternalClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ReadOnlyRecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ReadOnlyRecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ReadOnlyStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ReadOnlyStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_RecordClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_RecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_StructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_StructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/{WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext2.g.verified.cs => WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext2.g.verified.cs} (100%) rename SpreadCheetah.SourceGenerator.SnapshotTest/Tests/{WorksheetRowSourceGeneratorTests.cs => WorksheetRowGeneratorTests.cs} (87%) diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Helpers/TestHelper.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Helpers/TestHelper.cs index 14fd9c90..3708f38a 100644 --- a/SpreadCheetah.SourceGenerator.SnapshotTest/Helpers/TestHelper.cs +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Helpers/TestHelper.cs @@ -24,7 +24,7 @@ internal static class TestHelper MetadataReference.CreateFromFile(typeof(TestHelper).Assembly.Location) }; - var compilation = CSharpCompilation.Create("Tests", new[] { syntaxTree }, references); + var compilation = CSharpCompilation.Create("Tests", [syntaxTree], references); var generator = new T(); #pragma warning disable S3220 // Method calls should not resolve ambiguously to overloads with "params" diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithAllSupportedTypes#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithAllSupportedTypes#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithAllSupportedTypes#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithAllSupportedTypes#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithMultipleProperties#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithMultipleProperties#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithMultipleProperties#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithMultipleProperties#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithNoProperties#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithNoProperties#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithNoProperties#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithNoProperties#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithNoProperties.verified.txt b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithNoProperties.verified.txt similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithNoProperties.verified.txt rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithNoProperties.verified.txt diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithNoPropertiesAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithNoPropertiesAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithNoPropertiesAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithNoPropertiesAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedProperty#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithUnsupportedProperty#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedProperty#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithUnsupportedProperty#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedProperty.verified.txt b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithUnsupportedProperty.verified.txt similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedProperty.verified.txt rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithUnsupportedProperty.verified.txt diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedPropertyAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithUnsupportedPropertyAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedPropertyAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ClassWithUnsupportedPropertyAndWarningsSuppressed#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextClassWithDefaultAccessibility#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextClassWithDefaultAccessibility#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextClassWithDefaultAccessibility#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextClassWithDefaultAccessibility#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextClassWithInternalAccessibility#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextClassWithInternalAccessibility#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextClassWithInternalAccessibility#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextClassWithInternalAccessibility#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextWithTwoSimilarWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextWithTwoSimilarWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextWithTwoSimilarWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextWithTwoSimilarWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextWithTwoWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextWithTwoWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ContextWithTwoWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ContextWithTwoWorksheetRowAttributes#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_InternalClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_InternalClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_InternalClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_InternalClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ReadOnlyRecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ReadOnlyRecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ReadOnlyRecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ReadOnlyRecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ReadOnlyStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ReadOnlyStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_ReadOnlyStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_ReadOnlyStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_RecordClassWithInheritance#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_RecordClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_RecordClassWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_RecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_RecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_RecordStructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_StructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_StructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_StructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_StructWithSingleProperty#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext2.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext2.g.verified.cs similarity index 100% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowSourceGeneratorTests.WorksheetRowSourceGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext2.g.verified.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorTests.WorksheetRowGenerator_Generate_TwoContextClasses#MyNamespace.MyGenRowContext2.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowSourceGeneratorTests.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorTests.cs similarity index 87% rename from SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowSourceGeneratorTests.cs rename to SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorTests.cs index e4d6809d..8f66a14f 100644 --- a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowSourceGeneratorTests.cs +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorTests.cs @@ -4,10 +4,10 @@ namespace SpreadCheetah.SourceGenerator.SnapshotTest.Tests; [UsesVerify] -public class WorksheetRowSourceGeneratorTests +public class WorksheetRowGeneratorTests { [Fact] - public Task WorksheetRowSourceGenerator_Generate_ClassWithSingleProperty() + public Task WorksheetRowGenerator_Generate_ClassWithSingleProperty() { // Arrange const string source = """ @@ -29,7 +29,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_InternalClassWithSingleProperty() + public Task WorksheetRowGenerator_Generate_InternalClassWithSingleProperty() { // Arrange const string source = """ @@ -55,7 +55,7 @@ internal partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ClassWithAllSupportedTypes() + public Task WorksheetRowGenerator_Generate_ClassWithAllSupportedTypes() { // Arrange const string source = """ @@ -77,7 +77,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ClassWithMultipleProperties() + public Task WorksheetRowGenerator_Generate_ClassWithMultipleProperties() { // Arrange const string source = """ @@ -99,7 +99,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ClassWithNoProperties() + public Task WorksheetRowGenerator_Generate_ClassWithNoProperties() { // Arrange const string source = """ @@ -121,7 +121,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ClassWithNoPropertiesAndWarningsSuppressed() + public Task WorksheetRowGenerator_Generate_ClassWithNoPropertiesAndWarningsSuppressed() { // Arrange const string source = """ @@ -144,7 +144,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedProperty() + public Task WorksheetRowGenerator_Generate_ClassWithUnsupportedProperty() { // Arrange const string source = """ @@ -166,7 +166,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ClassWithUnsupportedPropertyAndWarningsSuppressed() + public Task WorksheetRowGenerator_Generate_ClassWithUnsupportedPropertyAndWarningsSuppressed() { // Arrange const string source = """ @@ -189,7 +189,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ClassWithInheritance() + public Task WorksheetRowGenerator_Generate_ClassWithInheritance() { // Arrange const string source = """ @@ -211,7 +211,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_RecordClassWithSingleProperty() + public Task WorksheetRowGenerator_Generate_RecordClassWithSingleProperty() { // Arrange const string source = """ @@ -233,7 +233,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_StructWithSingleProperty() + public Task WorksheetRowGenerator_Generate_StructWithSingleProperty() { // Arrange const string source = """ @@ -255,7 +255,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_RecordStructWithSingleProperty() + public Task WorksheetRowGenerator_Generate_RecordStructWithSingleProperty() { // Arrange const string source = """ @@ -277,7 +277,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ReadOnlyStructWithSingleProperty() + public Task WorksheetRowGenerator_Generate_ReadOnlyStructWithSingleProperty() { // Arrange const string source = """ @@ -299,7 +299,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ReadOnlyRecordStructWithSingleProperty() + public Task WorksheetRowGenerator_Generate_ReadOnlyRecordStructWithSingleProperty() { // Arrange const string source = """ @@ -321,7 +321,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_RecordClassWithInheritance() + public Task WorksheetRowGenerator_Generate_RecordClassWithInheritance() { // Arrange const string source = """ @@ -343,7 +343,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ContextWithTwoWorksheetRowAttributes() + public Task WorksheetRowGenerator_Generate_ContextWithTwoWorksheetRowAttributes() { // Arrange const string source = """ @@ -366,7 +366,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ContextWithTwoSimilarWorksheetRowAttributes() + public Task WorksheetRowGenerator_Generate_ContextWithTwoSimilarWorksheetRowAttributes() { // Arrange const string source = """ @@ -388,7 +388,7 @@ public partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ContextClassWithInternalAccessibility() + public Task WorksheetRowGenerator_Generate_ContextClassWithInternalAccessibility() { // Arrange const string source = """ @@ -410,7 +410,7 @@ internal partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_ContextClassWithDefaultAccessibility() + public Task WorksheetRowGenerator_Generate_ContextClassWithDefaultAccessibility() { // Arrange const string source = """ @@ -432,7 +432,7 @@ partial class MyGenRowContext : WorksheetRowContext } [Fact] - public Task WorksheetRowSourceGenerator_Generate_TwoContextClasses() + public Task WorksheetRowGenerator_Generate_TwoContextClasses() { // Arrange const string source = """ From c7811b7f78bc1e24631718e3195d340b632e0ecf Mon Sep 17 00:00:00 2001 From: sveinungf Date: Thu, 28 Dec 2023 10:26:21 +0100 Subject: [PATCH 08/22] First snapshot test for class with ColumnOrder attributes --- .../ClassWithColumnOrderForAllProperties.cs | 24 +++++ ...#MyNamespace.MyGenRowContext.g.verified.cs | 92 +++++++++++++++++++ .../WorksheetRowGeneratorColumnOrderTests.cs | 30 ++++++ 3 files changed, 146 insertions(+) create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Models/ColumnOrdering/ClassWithColumnOrderForAllProperties.cs create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithColumnOrderForAllProperties#MyNamespace.MyGenRowContext.g.verified.cs create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Models/ColumnOrdering/ClassWithColumnOrderForAllProperties.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Models/ColumnOrdering/ClassWithColumnOrderForAllProperties.cs new file mode 100644 index 00000000..4da144a4 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Models/ColumnOrdering/ClassWithColumnOrderForAllProperties.cs @@ -0,0 +1,24 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering; + +public class ClassWithColumnOrderForAllProperties +{ + [ColumnOrder(2)] + public string FirstName { get; set; } = ""; + + [ColumnOrder(3)] + public string? MiddleName { get; set; } + + [ColumnOrder(1)] + public string LastName { get; set; } = ""; + + [ColumnOrder(5)] + public int Age { get; set; } + + [ColumnOrder(4)] + public bool Employed { get; set; } + + [ColumnOrder(6)] + public double Score { get; set; } +} diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithColumnOrderForAllProperties#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithColumnOrderForAllProperties#MyNamespace.MyGenRowContext.g.verified.cs new file mode 100644 index 00000000..1d4288f9 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithColumnOrderForAllProperties#MyNamespace.MyGenRowContext.g.verified.cs @@ -0,0 +1,92 @@ +//HintName: MyNamespace.MyGenRowContext.g.cs +// +#nullable enable +using SpreadCheetah; +using SpreadCheetah.SourceGeneration; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MyNamespace +{ + public partial class MyGenRowContext + { + private static MyGenRowContext? _default; + public static MyGenRowContext Default => _default ??= new MyGenRowContext(); + + public MyGenRowContext() + { + } + + private WorksheetRowTypeInfo? _ClassWithColumnOrderForAllProperties; + public WorksheetRowTypeInfo ClassWithColumnOrderForAllProperties => _ClassWithColumnOrderForAllProperties ??= WorksheetRowMetadataServices.CreateObjectInfo(AddAsRowAsync, AddRangeAsRowsAsync); + + private static ValueTask AddAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties? obj, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + return AddAsRowInternalAsync(spreadsheet, obj, token); + } + + private static ValueTask AddRangeAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (objs is null) + throw new ArgumentNullException(nameof(objs)); + return AddRangeAsRowsInternalAsync(spreadsheet, objs, token); + } + + private static async ValueTask AddAsRowInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties obj, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(6); + try + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddRangeAsRowsInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(6); + try + { + await AddEnumerableAsRowsAsync(spreadsheet, objs, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddEnumerableAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, DataCell[] cells, CancellationToken token) + { + foreach (var obj in objs) + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + } + + private static ValueTask AddCellsAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForAllProperties? obj, DataCell[] cells, CancellationToken token) + { + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + + cells[0] = new DataCell(obj.LastName); + cells[1] = new DataCell(obj.FirstName); + cells[2] = new DataCell(obj.MiddleName); + cells[3] = new DataCell(obj.Employed); + cells[4] = new DataCell(obj.Age); + cells[5] = new DataCell(obj.Score); + return spreadsheet.AddRowAsync(cells.AsMemory(0, 6), token); + } + } +} diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs new file mode 100644 index 00000000..393fa566 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs @@ -0,0 +1,30 @@ +using SpreadCheetah.SourceGenerator.SnapshotTest.Helpers; +using SpreadCheetah.SourceGenerators; + +namespace SpreadCheetah.SourceGenerator.SnapshotTest.Tests; + +[UsesVerify] +public class WorksheetRowGeneratorColumnOrderTests +{ + [Fact] + public Task WorksheetRowGenerator_Generate_ClassWithColumnOrderForAllProperties() + { + // Arrange + const string source = """ + using SpreadCheetah.SourceGeneration; + using SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering; + using System; + + namespace MyNamespace + { + [WorksheetRow(typeof(ClassWithColumnOrderForAllProperties))] + public partial class MyGenRowContext : WorksheetRowContext + { + } + } + """; + + // Act & Assert + return TestHelper.CompileAndVerify(source); + } +} From 7cbcf36a236b8e52d8adc1bca7a5826508befbcd Mon Sep 17 00:00:00 2001 From: sveinungf Date: Fri, 29 Dec 2023 15:04:52 +0100 Subject: [PATCH 09/22] Emit error if two or more properties have the same explicit column order --- .../AnalyzerReleases.Unshipped.md | 6 +++- SpreadCheetah.SourceGenerator/Diagnostics.cs | 12 ++++++-- .../Models/CompilationTypes.cs | 2 +- .../WorksheetRowGenerator.cs | 30 +++++++++---------- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/SpreadCheetah.SourceGenerator/AnalyzerReleases.Unshipped.md b/SpreadCheetah.SourceGenerator/AnalyzerReleases.Unshipped.md index 5f282702..949f5857 100644 --- a/SpreadCheetah.SourceGenerator/AnalyzerReleases.Unshipped.md +++ b/SpreadCheetah.SourceGenerator/AnalyzerReleases.Unshipped.md @@ -1 +1,5 @@ - \ No newline at end of file +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|-------------------- +SPCH1003 | SpreadCheetah.SourceGenerator | Error | DuplicateColumnOrder \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator/Diagnostics.cs b/SpreadCheetah.SourceGenerator/Diagnostics.cs index 09e0e69f..b28714a7 100644 --- a/SpreadCheetah.SourceGenerator/Diagnostics.cs +++ b/SpreadCheetah.SourceGenerator/Diagnostics.cs @@ -6,7 +6,7 @@ internal static class Diagnostics { private const string Category = "SpreadCheetah.SourceGenerator"; - public static readonly DiagnosticDescriptor NoPropertiesFound = new DiagnosticDescriptor( + public static readonly DiagnosticDescriptor NoPropertiesFound = new( id: "SPCH1001", title: "Missing properties with public getters", messageFormat: "The type '{0}' has no properties with public getters. This will cause an empty row to be added.", @@ -14,11 +14,19 @@ internal static class Diagnostics DiagnosticSeverity.Warning, isEnabledByDefault: true); - public static readonly DiagnosticDescriptor UnsupportedTypeForCellValue = new DiagnosticDescriptor( + public static readonly DiagnosticDescriptor UnsupportedTypeForCellValue = new( id: "SPCH1002", title: "Unsupported type for cell value", messageFormat: "The type '{0}' has a property of type '{1}' which is not supported as a cell value. The property will be ignored when creating the row.", category: Category, DiagnosticSeverity.Warning, isEnabledByDefault: true); + + public static readonly DiagnosticDescriptor DuplicateColumnOrder = new( + id: "SPCH1003", + title: "Duplicate column ordering", + messageFormat: "The type '{0}' has two or more properties with the same column order", + category: Category, + DiagnosticSeverity.Error, + isEnabledByDefault: true); } diff --git a/SpreadCheetah.SourceGenerator/Models/CompilationTypes.cs b/SpreadCheetah.SourceGenerator/Models/CompilationTypes.cs index 9c5878b2..6005e115 100644 --- a/SpreadCheetah.SourceGenerator/Models/CompilationTypes.cs +++ b/SpreadCheetah.SourceGenerator/Models/CompilationTypes.cs @@ -2,7 +2,7 @@ namespace SpreadCheetah.SourceGenerator.Models; -internal record CompilationTypes( +internal sealed record CompilationTypes( INamedTypeSymbol WorksheetRowAttribute, INamedTypeSymbol WorksheetRowGenerationOptionsAttribute, INamedTypeSymbol ColumnOrderAttribute, diff --git a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs index a75c1c65..a3bac1e5 100644 --- a/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs +++ b/SpreadCheetah.SourceGenerator/WorksheetRowGenerator.cs @@ -148,7 +148,8 @@ private static bool TryParseColumnOrderAttribute( return true; } - private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, CompilationTypes compilationTypes, ITypeSymbol classType) + private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, CompilationTypes compilationTypes, + ITypeSymbol classType, SourceProductionContext context) { var implicitOrderPropertyNames = new List(); var explicitOrderPropertyNames = new SortedDictionary(); @@ -172,18 +173,12 @@ private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, continue; } - if (!TryGetExplicitColumnOrder(p, compilationTypes.ColumnOrderAttribute, out var columnOrder)) - { + if (!TryGetExplicitColumnOrder(p, compilationTypes.ColumnOrderAttribute, context.CancellationToken, out var columnOrder, out var location)) implicitOrderPropertyNames.Add(p.Name); - } - else if (explicitOrderPropertyNames.ContainsKey(columnOrder)) - { - // TODO: Fail - } - else - { + else if (!explicitOrderPropertyNames.ContainsKey(columnOrder)) explicitOrderPropertyNames.Add(columnOrder, p.Name); - } + else + context.ReportDiagnostic(Diagnostic.Create(Diagnostics.DuplicateColumnOrder, location, classType.Name)); } explicitOrderPropertyNames.AddWithImplicitKeys(implicitOrderPropertyNames); @@ -191,14 +186,19 @@ private static TypePropertiesInfo AnalyzeTypeProperties(Compilation compilation, return new TypePropertiesInfo(explicitOrderPropertyNames, unsupportedPropertyNames); } - private static bool TryGetExplicitColumnOrder(IPropertySymbol property, INamedTypeSymbol columnOrderAttribute, out int columnOrder) + private static bool TryGetExplicitColumnOrder(IPropertySymbol property, INamedTypeSymbol columnOrderAttribute, + CancellationToken token, out int columnOrder, out Location? location) { columnOrder = 0; + location = null; foreach (var attribute in property.GetAttributes()) { - if (TryParseColumnOrderAttribute(attribute, columnOrderAttribute, out columnOrder)) - return true; + if (!TryParseColumnOrderAttribute(attribute, columnOrderAttribute, out columnOrder)) + continue; + + location = attribute.ApplicationSyntaxReference?.GetSyntax(token).GetLocation(); + return true; } return false; @@ -312,7 +312,7 @@ private static void GenerateCode(StringBuilder sb, ContextClass contextClass, Co sb.AppendLine(2, $"private WorksheetRowTypeInfo<{rowTypeFullName}>? _{rowTypeName};"); sb.AppendLine(2, $"public WorksheetRowTypeInfo<{rowTypeFullName}> {rowTypeName} => _{rowTypeName} ??= WorksheetRowMetadataServices.CreateObjectInfo<{rowTypeFullName}>(AddAsRowAsync, AddRangeAsRowsAsync);"); - var info = AnalyzeTypeProperties(compilation, contextClass.CompilationTypes, rowType); + var info = AnalyzeTypeProperties(compilation, contextClass.CompilationTypes, rowType, context); ReportDiagnostics(info, rowType, location, contextClass.Options, context); var propertyNames = info.PropertyNames.Values; From 78b9f8356faa538c6d54fef16e15087c3477c4d4 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Fri, 29 Dec 2023 18:37:36 +0100 Subject: [PATCH 10/22] Snapshot test for class with duplicate column ordering --- .gitignore | 3 + ...#MyNamespace.MyGenRowContext.g.verified.cs | 87 +++++++++++++++++++ ...ssWithDuplicateColumnOrdering.verified.txt | 14 +++ .../WorksheetRowGeneratorColumnOrderTests.cs | 37 ++++++-- 4 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering#MyNamespace.MyGenRowContext.g.verified.cs create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering.verified.txt diff --git a/.gitignore b/.gitignore index dfcfd56f..c24583b4 100644 --- a/.gitignore +++ b/.gitignore @@ -348,3 +348,6 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +# Snapshot tests with Verify +*.received.* \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering#MyNamespace.MyGenRowContext.g.verified.cs new file mode 100644 index 00000000..fa1d7e70 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering#MyNamespace.MyGenRowContext.g.verified.cs @@ -0,0 +1,87 @@ +//HintName: MyNamespace.MyGenRowContext.g.cs +// +#nullable enable +using SpreadCheetah; +using SpreadCheetah.SourceGeneration; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MyNamespace +{ + public partial class MyGenRowContext + { + private static MyGenRowContext? _default; + public static MyGenRowContext Default => _default ??= new MyGenRowContext(); + + public MyGenRowContext() + { + } + + private WorksheetRowTypeInfo? _ClassWithDuplicateColumnOrdering; + public WorksheetRowTypeInfo ClassWithDuplicateColumnOrdering => _ClassWithDuplicateColumnOrdering ??= WorksheetRowMetadataServices.CreateObjectInfo(AddAsRowAsync, AddRangeAsRowsAsync); + + private static ValueTask AddAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, MyNamespace.ClassWithDuplicateColumnOrdering? obj, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + return AddAsRowInternalAsync(spreadsheet, obj, token); + } + + private static ValueTask AddRangeAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (objs is null) + throw new ArgumentNullException(nameof(objs)); + return AddRangeAsRowsInternalAsync(spreadsheet, objs, token); + } + + private static async ValueTask AddAsRowInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, MyNamespace.ClassWithDuplicateColumnOrdering obj, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(1); + try + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddRangeAsRowsInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(1); + try + { + await AddEnumerableAsRowsAsync(spreadsheet, objs, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddEnumerableAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, DataCell[] cells, CancellationToken token) + { + foreach (var obj in objs) + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + } + + private static ValueTask AddCellsAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, MyNamespace.ClassWithDuplicateColumnOrdering? obj, DataCell[] cells, CancellationToken token) + { + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + + cells[0] = new DataCell(obj.PropertyA); + return spreadsheet.AddRowAsync(cells.AsMemory(0, 1), token); + } + } +} diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering.verified.txt b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering.verified.txt new file mode 100644 index 00000000..34f90953 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering.verified.txt @@ -0,0 +1,14 @@ +{ + Diagnostics: [ + { + Id: SPCH1003, + Title: Duplicate column ordering, + Severity: Error, + WarningLevel: 0, + Location: : (9,5)-(9,19), + MessageFormat: The type '{0}' has two or more properties with the same column order, + Message: The type 'ClassWithDuplicateColumnOrdering' has two or more properties with the same column order, + Category: SpreadCheetah.SourceGenerator + } + ] +} \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs index 393fa566..8f5d9808 100644 --- a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs @@ -15,12 +15,39 @@ public Task WorksheetRowGenerator_Generate_ClassWithColumnOrderForAllProperties( using SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering; using System; - namespace MyNamespace + namespace MyNamespace; + + [WorksheetRow(typeof(ClassWithColumnOrderForAllProperties))] + public partial class MyGenRowContext : WorksheetRowContext + { + } + """; + + // Act & Assert + return TestHelper.CompileAndVerify(source); + } + + [Fact] + public Task WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering() + { + // Arrange + const string source = """ + using SpreadCheetah.SourceGeneration; + using System; + + namespace MyNamespace; + + public class ClassWithDuplicateColumnOrdering + { + [ColumnOrder(1)] + public string PropertyA { get; set; } + [ColumnOrder(1)] + public string PropertyB { get; set; } + } + + [WorksheetRow(typeof(ClassWithDuplicateColumnOrdering))] + public partial class MyGenRowContext : WorksheetRowContext { - [WorksheetRow(typeof(ClassWithColumnOrderForAllProperties))] - public partial class MyGenRowContext : WorksheetRowContext - { - } } """; From aadd92a5333a8ac39adc0bcff2b2edbde806c50d Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sat, 30 Dec 2023 21:19:52 +0100 Subject: [PATCH 11/22] Test for class with ColumnOrder for some properties --- .../ClassWithColumnOrderForSomeProperties.cs | 21 +++++ ...#MyNamespace.MyGenRowContext.g.verified.cs | 92 +++++++++++++++++++ .../WorksheetRowGeneratorColumnOrderTests.cs | 21 +++++ 3 files changed, 134 insertions(+) create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Models/ColumnOrdering/ClassWithColumnOrderForSomeProperties.cs create mode 100644 SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithColumnOrderForSomeProperties#MyNamespace.MyGenRowContext.g.verified.cs diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Models/ColumnOrdering/ClassWithColumnOrderForSomeProperties.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Models/ColumnOrdering/ClassWithColumnOrderForSomeProperties.cs new file mode 100644 index 00000000..d6a3bfe4 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Models/ColumnOrdering/ClassWithColumnOrderForSomeProperties.cs @@ -0,0 +1,21 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering; + +public class ClassWithColumnOrderForSomeProperties +{ + public string FirstName { get; set; } = ""; + + [ColumnOrder(-1000)] + public string? MiddleName { get; set; } + + public string LastName { get; set; } = ""; + + [ColumnOrder(500)] + public int Age { get; set; } + + public bool Employed { get; set; } + + [ColumnOrder(2)] + public double Score { get; set; } +} diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithColumnOrderForSomeProperties#MyNamespace.MyGenRowContext.g.verified.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithColumnOrderForSomeProperties#MyNamespace.MyGenRowContext.g.verified.cs new file mode 100644 index 00000000..68c4b866 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithColumnOrderForSomeProperties#MyNamespace.MyGenRowContext.g.verified.cs @@ -0,0 +1,92 @@ +//HintName: MyNamespace.MyGenRowContext.g.cs +// +#nullable enable +using SpreadCheetah; +using SpreadCheetah.SourceGeneration; +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MyNamespace +{ + public partial class MyGenRowContext + { + private static MyGenRowContext? _default; + public static MyGenRowContext Default => _default ??= new MyGenRowContext(); + + public MyGenRowContext() + { + } + + private WorksheetRowTypeInfo? _ClassWithColumnOrderForSomeProperties; + public WorksheetRowTypeInfo ClassWithColumnOrderForSomeProperties => _ClassWithColumnOrderForSomeProperties ??= WorksheetRowMetadataServices.CreateObjectInfo(AddAsRowAsync, AddRangeAsRowsAsync); + + private static ValueTask AddAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties? obj, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + return AddAsRowInternalAsync(spreadsheet, obj, token); + } + + private static ValueTask AddRangeAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + if (spreadsheet is null) + throw new ArgumentNullException(nameof(spreadsheet)); + if (objs is null) + throw new ArgumentNullException(nameof(objs)); + return AddRangeAsRowsInternalAsync(spreadsheet, objs, token); + } + + private static async ValueTask AddAsRowInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties obj, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(6); + try + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddRangeAsRowsInternalAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, CancellationToken token) + { + var cells = ArrayPool.Shared.Rent(6); + try + { + await AddEnumerableAsRowsAsync(spreadsheet, objs, cells, token).ConfigureAwait(false); + } + finally + { + ArrayPool.Shared.Return(cells, true); + } + } + + private static async ValueTask AddEnumerableAsRowsAsync(SpreadCheetah.Spreadsheet spreadsheet, IEnumerable objs, DataCell[] cells, CancellationToken token) + { + foreach (var obj in objs) + { + await AddCellsAsRowAsync(spreadsheet, obj, cells, token).ConfigureAwait(false); + } + } + + private static ValueTask AddCellsAsRowAsync(SpreadCheetah.Spreadsheet spreadsheet, SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering.ClassWithColumnOrderForSomeProperties? obj, DataCell[] cells, CancellationToken token) + { + if (obj is null) + return spreadsheet.AddRowAsync(ReadOnlyMemory.Empty, token); + + cells[0] = new DataCell(obj.MiddleName); + cells[1] = new DataCell(obj.FirstName); + cells[2] = new DataCell(obj.Score); + cells[3] = new DataCell(obj.LastName); + cells[4] = new DataCell(obj.Employed); + cells[5] = new DataCell(obj.Age); + return spreadsheet.AddRowAsync(cells.AsMemory(0, 6), token); + } + } +} diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs index 8f5d9808..7a27d938 100644 --- a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs @@ -27,6 +27,27 @@ public partial class MyGenRowContext : WorksheetRowContext return TestHelper.CompileAndVerify(source); } + [Fact] + public Task WorksheetRowGenerator_Generate_ClassWithColumnOrderForSomeProperties() + { + // Arrange + const string source = """ + using SpreadCheetah.SourceGeneration; + using SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering; + using System; + + namespace MyNamespace; + + [WorksheetRow(typeof(ClassWithColumnOrderForSomeProperties))] + public partial class MyGenRowContext : WorksheetRowContext + { + } + """; + + // Act & Assert + return TestHelper.CompileAndVerify(source); + } + [Fact] public Task WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering() { From 0df9cbc3f567079483856416a81cf78aa6b42041 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sat, 30 Dec 2023 21:22:08 +0100 Subject: [PATCH 12/22] Simplify inline code in snapshot tests --- ..._ClassWithDuplicateColumnOrdering.verified.txt | 2 +- .../WorksheetRowGeneratorColumnOrderTests.cs | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering.verified.txt b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering.verified.txt index 34f90953..389e14f3 100644 --- a/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering.verified.txt +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Snapshots/WorksheetRowGeneratorColumnOrderTests.WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering.verified.txt @@ -5,7 +5,7 @@ Title: Duplicate column ordering, Severity: Error, WarningLevel: 0, - Location: : (9,5)-(9,19), + Location: : (8,5)-(8,19), MessageFormat: The type '{0}' has two or more properties with the same column order, Message: The type 'ClassWithDuplicateColumnOrdering' has two or more properties with the same column order, Category: SpreadCheetah.SourceGenerator diff --git a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs index 7a27d938..6ab6cc32 100644 --- a/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs +++ b/SpreadCheetah.SourceGenerator.SnapshotTest/Tests/WorksheetRowGeneratorColumnOrderTests.cs @@ -13,14 +13,11 @@ public Task WorksheetRowGenerator_Generate_ClassWithColumnOrderForAllProperties( const string source = """ using SpreadCheetah.SourceGeneration; using SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering; - using System; namespace MyNamespace; [WorksheetRow(typeof(ClassWithColumnOrderForAllProperties))] - public partial class MyGenRowContext : WorksheetRowContext - { - } + public partial class MyGenRowContext : WorksheetRowContext; """; // Act & Assert @@ -34,14 +31,11 @@ public Task WorksheetRowGenerator_Generate_ClassWithColumnOrderForSomeProperties const string source = """ using SpreadCheetah.SourceGeneration; using SpreadCheetah.SourceGenerator.SnapshotTest.Models.ColumnOrdering; - using System; namespace MyNamespace; [WorksheetRow(typeof(ClassWithColumnOrderForSomeProperties))] - public partial class MyGenRowContext : WorksheetRowContext - { - } + public partial class MyGenRowContext : WorksheetRowContext; """; // Act & Assert @@ -54,7 +48,6 @@ public Task WorksheetRowGenerator_Generate_ClassWithDuplicateColumnOrdering() // Arrange const string source = """ using SpreadCheetah.SourceGeneration; - using System; namespace MyNamespace; @@ -67,9 +60,7 @@ public class ClassWithDuplicateColumnOrdering } [WorksheetRow(typeof(ClassWithDuplicateColumnOrdering))] - public partial class MyGenRowContext : WorksheetRowContext - { - } + public partial class MyGenRowContext : WorksheetRowContext; """; // Act & Assert From dbb4291209bb4f19da7af1ce41f63f86b35cd627 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sat, 30 Dec 2023 23:15:16 +0100 Subject: [PATCH 13/22] WIP for a simpler way to assert spreadsheets in tests --- .../Helpers/ISpreadsheetAssertCell.cs | 7 +++ .../Helpers/ISpreadsheetAssertSheet.cs | 7 +++ .../Helpers/OpenXml/OpenXmlAssertCell.cs | 38 ++++++++++++++ .../Helpers/OpenXml/OpenXmlAssertSheet.cs | 49 +++++++++++++++++++ .../Helpers/SpreadsheetAssert.cs | 17 +++++++ .../Tests/WorksheetRowGeneratorTests.cs | 14 +++--- 6 files changed, 124 insertions(+), 8 deletions(-) create mode 100644 SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Helpers/SpreadsheetAssert.cs diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs new file mode 100644 index 00000000..89a28830 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs @@ -0,0 +1,7 @@ +namespace SpreadCheetah.SourceGenerator.Test.Helpers; + +internal interface ISpreadsheetAssertCell +{ + int? IntValue { get; } + string? StringValue { get; } +} diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs new file mode 100644 index 00000000..0469897a --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs @@ -0,0 +1,7 @@ +namespace SpreadCheetah.SourceGenerator.Test.Helpers; + +internal interface ISpreadsheetAssertSheet : IDisposable +{ + ISpreadsheetAssertCell this[string columnName, int rowNumber] { get; } + int CellCount { get; } +} diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs new file mode 100644 index 00000000..41dc1821 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs @@ -0,0 +1,38 @@ +using System.Globalization; +using OpenXmlCell = DocumentFormat.OpenXml.Spreadsheet.Cell; + +namespace SpreadCheetah.SourceGenerator.Test.Helpers.OpenXml; + +internal sealed class OpenXmlAssertCell(OpenXmlCell cell) : ISpreadsheetAssertCell +{ + public int? IntValue + { + get + { + if (cell.CellValue is not { } value) + throw new ArgumentException($"{nameof(cell.CellValue)} was null"); + + if (value.Text is null) + return null; + + if (!int.TryParse(value.Text, NumberStyles.None, CultureInfo.InvariantCulture, out var intValue)) + throw new ArgumentException($"The value {value.Text} could not be parsed as an integer"); + + return intValue; + } + } + + public string? StringValue + { + get + { + if (cell.InlineString is not { } inlineString) + throw new ArgumentException($"{nameof(cell.InlineString)} was null"); + + if (inlineString.Text is not { } text) + throw new ArgumentException($"{nameof(inlineString.Text)} was null"); + + return text.Text; + } + } +} diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs new file mode 100644 index 00000000..c951458b --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs @@ -0,0 +1,49 @@ +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Spreadsheet; +using OpenXmlCell = DocumentFormat.OpenXml.Spreadsheet.Cell; + +namespace SpreadCheetah.SourceGenerator.Test.Helpers.OpenXml; + +internal sealed class OpenXmlAssertSheet(SpreadsheetDocument document, Worksheet worksheet) + : ISpreadsheetAssertSheet +{ + private List>? _cells; + private List> Cells => _cells ??= GetAllCells(); + + private List> GetAllCells() + { + var allCells = new List>(); + + foreach (var row in worksheet.Descendants()) + { + var rowCells = row.Descendants().ToList(); + allCells.Add(rowCells); + } + + return allCells; + } + + public ISpreadsheetAssertCell this[string columnName, int rowNumber] + { + get + { + if (!SpreadsheetUtility.TryParseColumnName(columnName.AsSpan(), out var columnNumber)) + throw new ArgumentException($"{columnName} is not a valid column name"); + + if (Cells.ElementAtOrDefault(rowNumber - 1) is not { } row) + throw new ArgumentException($"Could not find row number {rowNumber}"); + + if (row.ElementAtOrDefault(columnNumber - 1) is not { } cell) + throw new ArgumentException($"Could not find cell with reference {columnName}{rowNumber}"); + + return new OpenXmlAssertCell(cell); + } + } + + public int CellCount => Cells.Sum(x => x.Count); + + public void Dispose() + { + document.Dispose(); + } +} diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/SpreadsheetAssert.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/SpreadsheetAssert.cs new file mode 100644 index 00000000..e9c40fe9 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/SpreadsheetAssert.cs @@ -0,0 +1,17 @@ +using DocumentFormat.OpenXml.Packaging; +using SpreadCheetah.SourceGenerator.Test.Helpers.OpenXml; + +namespace SpreadCheetah.SourceGenerator.Test.Helpers; + +internal static class SpreadsheetAssert +{ + public static ISpreadsheetAssertSheet SingleSheet(Stream stream) + { + stream.Position = 0; +#pragma warning disable CA2000 // Dispose objects before losing scope + var document = SpreadsheetDocument.Open(stream, false); +#pragma warning restore CA2000 // Dispose objects before losing scope + var sheetPart = document.WorkbookPart!.WorksheetParts.Single(); + return new OpenXmlAssertSheet(document, sheetPart.Worksheet); + } +} diff --git a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs index b0264152..aab8a35b 100644 --- a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs +++ b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs @@ -1,5 +1,6 @@ using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; +using SpreadCheetah.SourceGenerator.Test.Helpers; using SpreadCheetah.SourceGenerator.Test.Models; using SpreadCheetah.SourceGenerator.Test.Models.Contexts; using Xunit; @@ -46,14 +47,11 @@ public async Task Spreadsheet_AddAsRow_ObjectWithMultipleProperties(ObjectType t } // Assert - stream.Position = 0; - using var actual = SpreadsheetDocument.Open(stream, false); - var sheetPart = actual.WorkbookPart!.WorksheetParts.Single(); - var cells = sheetPart.Worksheet.Descendants().ToList(); - Assert.Equal(firstName, cells[0].InnerText); - Assert.Equal(lastName, cells[1].InnerText); - Assert.Equal(age.ToString(), cells[2].InnerText); - Assert.Equal(3, cells.Count); + using var sheet = SpreadsheetAssert.SingleSheet(stream); + Assert.Equal(firstName, sheet["A", 1].StringValue); + Assert.Equal(lastName, sheet["B", 1].StringValue); + Assert.Equal(age, sheet["C", 1].IntValue); + Assert.Equal(3, sheet.CellCount); } [Theory] From bd909d8f50e12fb7e97ad7878e0c47b06098ab19 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 31 Dec 2023 11:22:30 +0100 Subject: [PATCH 14/22] Folder structure for SourceGenerator.Test models --- .../DefaultAccessibilityClassWithSingleProperty.cs | 2 +- .../InternalAccessibilityClassWithSingleProperty.cs | 2 +- .../Models/ClassWithNoProperties.cs | 5 ----- .../Models/Contexts/DefaultAccessibilityContext.cs | 1 + .../Models/Contexts/InternalAccessibilityContext.cs | 1 + .../Models/Contexts/MultiplePropertiesContext.cs | 1 + .../Models/Contexts/NoPropertiesContext.cs | 1 + .../{ => MultipleProperties}/ClassWithMultipleProperties.cs | 2 +- .../ReadOnlyRecordStructWithMultipleProperties.cs | 2 +- .../ReadOnlyStructWithMultipleProperties.cs | 2 +- .../RecordClassWithMultipleProperties.cs | 2 +- .../RecordStructWithMultipleProperties.cs | 2 +- .../{ => MultipleProperties}/StructWithMultipleProperties.cs | 2 +- .../Models/NoProperties/ClassWithNoProperties.cs | 5 +++++ .../ReadOnlyRecordStructWithNoProperties.cs | 2 +- .../Models/NoProperties/ReadOnlyStructWithNoProperties.cs | 5 +++++ .../Models/NoProperties/RecordClassWithNoProperties.cs | 3 +++ .../Models/NoProperties/RecordStructWithNoProperties.cs | 3 +++ .../Models/NoProperties/StructWithNoProperties.cs | 5 +++++ .../Models/ReadOnlyStructWithNoProperties.cs | 5 ----- .../Models/RecordClassWithNoProperties.cs | 3 --- .../Models/RecordStructWithNoProperties.cs | 3 --- .../Models/StructWithNoProperties.cs | 5 ----- .../Tests/WorksheetRowGeneratorTests.cs | 3 +++ 24 files changed, 37 insertions(+), 30 deletions(-) rename SpreadCheetah.SourceGenerator.Test/Models/{ => Accessibility}/DefaultAccessibilityClassWithSingleProperty.cs (58%) rename SpreadCheetah.SourceGenerator.Test/Models/{ => Accessibility}/InternalAccessibilityClassWithSingleProperty.cs (60%) delete mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ClassWithNoProperties.cs rename SpreadCheetah.SourceGenerator.Test/Models/{ => MultipleProperties}/ClassWithMultipleProperties.cs (81%) rename SpreadCheetah.SourceGenerator.Test/Models/{ => MultipleProperties}/ReadOnlyRecordStructWithMultipleProperties.cs (62%) rename SpreadCheetah.SourceGenerator.Test/Models/{ => MultipleProperties}/ReadOnlyStructWithMultipleProperties.cs (82%) rename SpreadCheetah.SourceGenerator.Test/Models/{ => MultipleProperties}/RecordClassWithMultipleProperties.cs (56%) rename SpreadCheetah.SourceGenerator.Test/Models/{ => MultipleProperties}/RecordStructWithMultipleProperties.cs (58%) rename SpreadCheetah.SourceGenerator.Test/Models/{ => MultipleProperties}/StructWithMultipleProperties.cs (81%) create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ClassWithNoProperties.cs rename SpreadCheetah.SourceGenerator.Test/Models/{ => NoProperties}/ReadOnlyRecordStructWithNoProperties.cs (51%) create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ReadOnlyStructWithNoProperties.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/NoProperties/RecordClassWithNoProperties.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/NoProperties/RecordStructWithNoProperties.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/NoProperties/StructWithNoProperties.cs delete mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyStructWithNoProperties.cs delete mode 100644 SpreadCheetah.SourceGenerator.Test/Models/RecordClassWithNoProperties.cs delete mode 100644 SpreadCheetah.SourceGenerator.Test/Models/RecordStructWithNoProperties.cs delete mode 100644 SpreadCheetah.SourceGenerator.Test/Models/StructWithNoProperties.cs diff --git a/SpreadCheetah.SourceGenerator.Test/Models/DefaultAccessibilityClassWithSingleProperty.cs b/SpreadCheetah.SourceGenerator.Test/Models/Accessibility/DefaultAccessibilityClassWithSingleProperty.cs similarity index 58% rename from SpreadCheetah.SourceGenerator.Test/Models/DefaultAccessibilityClassWithSingleProperty.cs rename to SpreadCheetah.SourceGenerator.Test/Models/Accessibility/DefaultAccessibilityClassWithSingleProperty.cs index 7a8d1bd4..68f8f3af 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/DefaultAccessibilityClassWithSingleProperty.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/Accessibility/DefaultAccessibilityClassWithSingleProperty.cs @@ -1,4 +1,4 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; +namespace SpreadCheetah.SourceGenerator.Test.Models.Accessibility; class DefaultAccessibilityClassWithSingleProperty { diff --git a/SpreadCheetah.SourceGenerator.Test/Models/InternalAccessibilityClassWithSingleProperty.cs b/SpreadCheetah.SourceGenerator.Test/Models/Accessibility/InternalAccessibilityClassWithSingleProperty.cs similarity index 60% rename from SpreadCheetah.SourceGenerator.Test/Models/InternalAccessibilityClassWithSingleProperty.cs rename to SpreadCheetah.SourceGenerator.Test/Models/Accessibility/InternalAccessibilityClassWithSingleProperty.cs index f3ac3031..6289e63a 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/InternalAccessibilityClassWithSingleProperty.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/Accessibility/InternalAccessibilityClassWithSingleProperty.cs @@ -1,4 +1,4 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; +namespace SpreadCheetah.SourceGenerator.Test.Models.Accessibility; internal class InternalAccessibilityClassWithSingleProperty { diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ClassWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/ClassWithNoProperties.cs deleted file mode 100644 index c4a09589..00000000 --- a/SpreadCheetah.SourceGenerator.Test/Models/ClassWithNoProperties.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; - -public class ClassWithNoProperties -{ -} diff --git a/SpreadCheetah.SourceGenerator.Test/Models/Contexts/DefaultAccessibilityContext.cs b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/DefaultAccessibilityContext.cs index 9e8d22dc..c6ad5570 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/Contexts/DefaultAccessibilityContext.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/DefaultAccessibilityContext.cs @@ -1,4 +1,5 @@ using SpreadCheetah.SourceGeneration; +using SpreadCheetah.SourceGenerator.Test.Models.Accessibility; namespace SpreadCheetah.SourceGenerator.Test.Models.Contexts; diff --git a/SpreadCheetah.SourceGenerator.Test/Models/Contexts/InternalAccessibilityContext.cs b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/InternalAccessibilityContext.cs index 977904fe..7bfa8e95 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/Contexts/InternalAccessibilityContext.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/InternalAccessibilityContext.cs @@ -1,4 +1,5 @@ using SpreadCheetah.SourceGeneration; +using SpreadCheetah.SourceGenerator.Test.Models.Accessibility; namespace SpreadCheetah.SourceGenerator.Test.Models.Contexts; diff --git a/SpreadCheetah.SourceGenerator.Test/Models/Contexts/MultiplePropertiesContext.cs b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/MultiplePropertiesContext.cs index 5cce7dc5..6b55e135 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/Contexts/MultiplePropertiesContext.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/MultiplePropertiesContext.cs @@ -1,4 +1,5 @@ using SpreadCheetah.SourceGeneration; +using SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; namespace SpreadCheetah.SourceGenerator.Test.Models.Contexts; diff --git a/SpreadCheetah.SourceGenerator.Test/Models/Contexts/NoPropertiesContext.cs b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/NoPropertiesContext.cs index 4beb97ca..cba0ddd9 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/Contexts/NoPropertiesContext.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/NoPropertiesContext.cs @@ -1,4 +1,5 @@ using SpreadCheetah.SourceGeneration; +using SpreadCheetah.SourceGenerator.Test.Models.NoProperties; namespace SpreadCheetah.SourceGenerator.Test.Models.Contexts; diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ClassWithMultipleProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/ClassWithMultipleProperties.cs similarity index 81% rename from SpreadCheetah.SourceGenerator.Test/Models/ClassWithMultipleProperties.cs rename to SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/ClassWithMultipleProperties.cs index b898f5fb..b1e38e03 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/ClassWithMultipleProperties.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/ClassWithMultipleProperties.cs @@ -1,4 +1,4 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; +namespace SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; public class ClassWithMultipleProperties { diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyRecordStructWithMultipleProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/ReadOnlyRecordStructWithMultipleProperties.cs similarity index 62% rename from SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyRecordStructWithMultipleProperties.cs rename to SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/ReadOnlyRecordStructWithMultipleProperties.cs index 767839e0..e97ddb85 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyRecordStructWithMultipleProperties.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/ReadOnlyRecordStructWithMultipleProperties.cs @@ -1,3 +1,3 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; +namespace SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; public readonly record struct ReadOnlyRecordStructWithMultipleProperties(string FirstName, string LastName, int Age); diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyStructWithMultipleProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/ReadOnlyStructWithMultipleProperties.cs similarity index 82% rename from SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyStructWithMultipleProperties.cs rename to SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/ReadOnlyStructWithMultipleProperties.cs index efc5b80a..b1c1ce5d 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyStructWithMultipleProperties.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/ReadOnlyStructWithMultipleProperties.cs @@ -1,4 +1,4 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; +namespace SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; public readonly struct ReadOnlyStructWithMultipleProperties { diff --git a/SpreadCheetah.SourceGenerator.Test/Models/RecordClassWithMultipleProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/RecordClassWithMultipleProperties.cs similarity index 56% rename from SpreadCheetah.SourceGenerator.Test/Models/RecordClassWithMultipleProperties.cs rename to SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/RecordClassWithMultipleProperties.cs index b0de50ab..454e8577 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/RecordClassWithMultipleProperties.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/RecordClassWithMultipleProperties.cs @@ -1,3 +1,3 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; +namespace SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; public record RecordClassWithMultipleProperties(string FirstName, string LastName, int Age); diff --git a/SpreadCheetah.SourceGenerator.Test/Models/RecordStructWithMultipleProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/RecordStructWithMultipleProperties.cs similarity index 58% rename from SpreadCheetah.SourceGenerator.Test/Models/RecordStructWithMultipleProperties.cs rename to SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/RecordStructWithMultipleProperties.cs index 8d294066..3d9e8012 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/RecordStructWithMultipleProperties.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/RecordStructWithMultipleProperties.cs @@ -1,3 +1,3 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; +namespace SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; public record struct RecordStructWithMultipleProperties(string FirstName, string LastName, int Age); diff --git a/SpreadCheetah.SourceGenerator.Test/Models/StructWithMultipleProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/StructWithMultipleProperties.cs similarity index 81% rename from SpreadCheetah.SourceGenerator.Test/Models/StructWithMultipleProperties.cs rename to SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/StructWithMultipleProperties.cs index a846dad1..81919842 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/StructWithMultipleProperties.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/MultipleProperties/StructWithMultipleProperties.cs @@ -1,4 +1,4 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; +namespace SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; public struct StructWithMultipleProperties { diff --git a/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ClassWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ClassWithNoProperties.cs new file mode 100644 index 00000000..d7292512 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ClassWithNoProperties.cs @@ -0,0 +1,5 @@ +namespace SpreadCheetah.SourceGenerator.Test.Models.NoProperties; + +public class ClassWithNoProperties +{ +} diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyRecordStructWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ReadOnlyRecordStructWithNoProperties.cs similarity index 51% rename from SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyRecordStructWithNoProperties.cs rename to SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ReadOnlyRecordStructWithNoProperties.cs index 5c17a14e..309e00ad 100644 --- a/SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyRecordStructWithNoProperties.cs +++ b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ReadOnlyRecordStructWithNoProperties.cs @@ -1,3 +1,3 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; +namespace SpreadCheetah.SourceGenerator.Test.Models.NoProperties; public readonly record struct ReadOnlyRecordStructWithNoProperties; diff --git a/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ReadOnlyStructWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ReadOnlyStructWithNoProperties.cs new file mode 100644 index 00000000..a8f6a054 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/ReadOnlyStructWithNoProperties.cs @@ -0,0 +1,5 @@ +namespace SpreadCheetah.SourceGenerator.Test.Models.NoProperties; + +public readonly struct ReadOnlyStructWithNoProperties +{ +} diff --git a/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/RecordClassWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/RecordClassWithNoProperties.cs new file mode 100644 index 00000000..306e08dd --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/RecordClassWithNoProperties.cs @@ -0,0 +1,3 @@ +namespace SpreadCheetah.SourceGenerator.Test.Models.NoProperties; + +public record RecordClassWithNoProperties; diff --git a/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/RecordStructWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/RecordStructWithNoProperties.cs new file mode 100644 index 00000000..dfbdb850 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/RecordStructWithNoProperties.cs @@ -0,0 +1,3 @@ +namespace SpreadCheetah.SourceGenerator.Test.Models.NoProperties; + +public record struct RecordStructWithNoProperties; diff --git a/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/StructWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/StructWithNoProperties.cs new file mode 100644 index 00000000..44367fdb --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/NoProperties/StructWithNoProperties.cs @@ -0,0 +1,5 @@ +namespace SpreadCheetah.SourceGenerator.Test.Models.NoProperties; + +public struct StructWithNoProperties +{ +} diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyStructWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyStructWithNoProperties.cs deleted file mode 100644 index 0a6b1074..00000000 --- a/SpreadCheetah.SourceGenerator.Test/Models/ReadOnlyStructWithNoProperties.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; - -public readonly struct ReadOnlyStructWithNoProperties -{ -} diff --git a/SpreadCheetah.SourceGenerator.Test/Models/RecordClassWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/RecordClassWithNoProperties.cs deleted file mode 100644 index da9e3892..00000000 --- a/SpreadCheetah.SourceGenerator.Test/Models/RecordClassWithNoProperties.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; - -public record RecordClassWithNoProperties; diff --git a/SpreadCheetah.SourceGenerator.Test/Models/RecordStructWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/RecordStructWithNoProperties.cs deleted file mode 100644 index ac9e0184..00000000 --- a/SpreadCheetah.SourceGenerator.Test/Models/RecordStructWithNoProperties.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; - -public record struct RecordStructWithNoProperties; diff --git a/SpreadCheetah.SourceGenerator.Test/Models/StructWithNoProperties.cs b/SpreadCheetah.SourceGenerator.Test/Models/StructWithNoProperties.cs deleted file mode 100644 index a41f4e90..00000000 --- a/SpreadCheetah.SourceGenerator.Test/Models/StructWithNoProperties.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace SpreadCheetah.SourceGenerator.Test.Models; - -public struct StructWithNoProperties -{ -} diff --git a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs index aab8a35b..0b2d3c5c 100644 --- a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs +++ b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs @@ -2,7 +2,10 @@ using DocumentFormat.OpenXml.Spreadsheet; using SpreadCheetah.SourceGenerator.Test.Helpers; using SpreadCheetah.SourceGenerator.Test.Models; +using SpreadCheetah.SourceGenerator.Test.Models.Accessibility; using SpreadCheetah.SourceGenerator.Test.Models.Contexts; +using SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; +using SpreadCheetah.SourceGenerator.Test.Models.NoProperties; using Xunit; using OpenXmlCell = DocumentFormat.OpenXml.Spreadsheet.Cell; From d0d4c9653fd7dd1e3370b5fd8c03fb28af7eb976 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 31 Dec 2023 16:45:55 +0100 Subject: [PATCH 15/22] TheoryData for ObjectType enum values --- .../Helpers/Backporting/EnumHelper.cs | 13 +++++++ .../Helpers/EnumerableExtensions.cs | 17 +++++++++ .../Helpers/TestData.cs | 10 ++++++ .../Tests/WorksheetRowGeneratorTests.cs | 35 +++---------------- 4 files changed, 45 insertions(+), 30 deletions(-) create mode 100644 SpreadCheetah.SourceGenerator.Test/Helpers/Backporting/EnumHelper.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Helpers/EnumerableExtensions.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Helpers/TestData.cs diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/Backporting/EnumHelper.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/Backporting/EnumHelper.cs new file mode 100644 index 00000000..c1ad45cb --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/Backporting/EnumHelper.cs @@ -0,0 +1,13 @@ +namespace SpreadCheetah.SourceGenerator.Test.Helpers.Backporting; + +internal static class EnumHelper +{ + public static TEnum[] GetValues() where TEnum : struct, Enum + { +#if NET5_0_OR_GREATER + return Enum.GetValues(); +#else + return (TEnum[])Enum.GetValues(typeof(TEnum)); +#endif + } +} diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/EnumerableExtensions.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/EnumerableExtensions.cs new file mode 100644 index 00000000..6edf75ca --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/EnumerableExtensions.cs @@ -0,0 +1,17 @@ +using Xunit; + +namespace SpreadCheetah.SourceGenerator.Test.Helpers; + +internal static class EnumerableExtensions +{ + public static TheoryData ToTheoryData(this IEnumerable enumerable) + { + var result = new TheoryData(); + foreach (var element in enumerable) + { + result.Add(element); + } + + return result; + } +} \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/TestData.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/TestData.cs new file mode 100644 index 00000000..b6913c5f --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/TestData.cs @@ -0,0 +1,10 @@ +using SpreadCheetah.SourceGenerator.Test.Helpers.Backporting; +using SpreadCheetah.SourceGenerator.Test.Models; +using Xunit; + +namespace SpreadCheetah.SourceGenerator.Test.Helpers; + +internal static class TestData +{ + public static TheoryData ObjectTypes => EnumHelper.GetValues().ToTheoryData(); +} diff --git a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs index 0b2d3c5c..5cd5f9a0 100644 --- a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs +++ b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs @@ -14,12 +14,7 @@ namespace SpreadCheetah.SourceGenerator.Test.Tests; public class WorksheetRowGeneratorTests { [Theory] - [InlineData(ObjectType.Class)] - [InlineData(ObjectType.RecordClass)] - [InlineData(ObjectType.Struct)] - [InlineData(ObjectType.RecordStruct)] - [InlineData(ObjectType.ReadOnlyStruct)] - [InlineData(ObjectType.ReadOnlyRecordStruct)] + [MemberData(nameof(TestData.ObjectTypes), MemberType = typeof(TestData))] public async Task Spreadsheet_AddAsRow_ObjectWithMultipleProperties(ObjectType type) { // Arrange @@ -58,12 +53,7 @@ public async Task Spreadsheet_AddAsRow_ObjectWithMultipleProperties(ObjectType t } [Theory] - [InlineData(ObjectType.Class)] - [InlineData(ObjectType.RecordClass)] - [InlineData(ObjectType.Struct)] - [InlineData(ObjectType.RecordStruct)] - [InlineData(ObjectType.ReadOnlyStruct)] - [InlineData(ObjectType.ReadOnlyRecordStruct)] + [MemberData(nameof(TestData.ObjectTypes), MemberType = typeof(TestData))] public async Task Spreadsheet_AddAsRow_ObjectWithNoProperties(ObjectType type) { // Arrange @@ -238,12 +228,7 @@ public async Task Spreadsheet_AddAsRow_ThrowsWhenNoWorksheet() } [Theory] - [InlineData(ObjectType.Class)] - [InlineData(ObjectType.RecordClass)] - [InlineData(ObjectType.Struct)] - [InlineData(ObjectType.RecordStruct)] - [InlineData(ObjectType.ReadOnlyStruct)] - [InlineData(ObjectType.ReadOnlyRecordStruct)] + [MemberData(nameof(TestData.ObjectTypes), MemberType = typeof(TestData))] public async Task Spreadsheet_AddRangeAsRows_ObjectWithMultipleProperties(ObjectType type) { // Arrange @@ -305,12 +290,7 @@ public async Task Spreadsheet_AddRangeAsRows_ObjectWithMultipleProperties(Object } [Theory] - [InlineData(ObjectType.Class)] - [InlineData(ObjectType.RecordClass)] - [InlineData(ObjectType.Struct)] - [InlineData(ObjectType.RecordStruct)] - [InlineData(ObjectType.ReadOnlyStruct)] - [InlineData(ObjectType.ReadOnlyRecordStruct)] + [MemberData(nameof(TestData.ObjectTypes), MemberType = typeof(TestData))] public async Task Spreadsheet_AddRangeAsRows_ObjectWithNoProperties(ObjectType type) { // Arrange @@ -347,12 +327,7 @@ public async Task Spreadsheet_AddRangeAsRows_ObjectWithNoProperties(ObjectType t } [Theory] - [InlineData(ObjectType.Class)] - [InlineData(ObjectType.RecordClass)] - [InlineData(ObjectType.Struct)] - [InlineData(ObjectType.RecordStruct)] - [InlineData(ObjectType.ReadOnlyStruct)] - [InlineData(ObjectType.ReadOnlyRecordStruct)] + [MemberData(nameof(TestData.ObjectTypes), MemberType = typeof(TestData))] public async Task Spreadsheet_AddRangeAsRows_EmptyEnumerable(ObjectType type) { // Arrange From b57ea49dbfef7948825fc86c5d16204463b4c513 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Mon, 1 Jan 2024 21:12:27 +0100 Subject: [PATCH 16/22] Test for AddRangeAsRows for types with ColumnOrder attribute --- .../Helpers/ISpreadsheetAssertCell.cs | 1 + .../Helpers/ISpreadsheetAssertSheet.cs | 2 + .../Helpers/OpenXml/OpenXmlAssertCell.cs | 25 +++++++++-- .../Helpers/OpenXml/OpenXmlAssertSheet.cs | 25 +++++++++-- .../ColumnOrdering/ClassWithColumnOrdering.cs | 14 ++++++ .../ReadOnlyRecordStructWithColumnOrdering.cs | 9 ++++ .../ReadOnlyStructWithColumnOrdering.cs | 14 ++++++ .../RecordClassWithColumnOrdering.cs | 9 ++++ .../RecordStructWithColumnOrdering.cs | 9 ++++ .../StructWithColumnOrdering.cs | 14 ++++++ .../Models/Contexts/ColumnOrderingContext.cs | 12 ++++++ .../Tests/WorksheetRowGeneratorTests.cs | 43 +++++++++++++++++++ 12 files changed, 170 insertions(+), 7 deletions(-) create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ClassWithColumnOrdering.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ReadOnlyRecordStructWithColumnOrdering.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ReadOnlyStructWithColumnOrdering.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/RecordClassWithColumnOrdering.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/RecordStructWithColumnOrdering.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/StructWithColumnOrdering.cs create mode 100644 SpreadCheetah.SourceGenerator.Test/Models/Contexts/ColumnOrderingContext.cs diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs index 89a28830..edaeba42 100644 --- a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs @@ -3,5 +3,6 @@ namespace SpreadCheetah.SourceGenerator.Test.Helpers; internal interface ISpreadsheetAssertCell { int? IntValue { get; } + decimal? DecimalValue { get; } string? StringValue { get; } } diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs index 0469897a..ebddb563 100644 --- a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs @@ -3,5 +3,7 @@ namespace SpreadCheetah.SourceGenerator.Test.Helpers; internal interface ISpreadsheetAssertSheet : IDisposable { ISpreadsheetAssertCell this[string columnName, int rowNumber] { get; } + IEnumerable this[string columnName] { get; } int CellCount { get; } + int RowCount { get; } } diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs index 41dc1821..d994bc9a 100644 --- a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs @@ -10,27 +10,44 @@ public int? IntValue get { if (cell.CellValue is not { } value) - throw new ArgumentException($"{nameof(cell.CellValue)} was null"); + throw new InvalidOperationException($"{nameof(cell.CellValue)} was null"); if (value.Text is null) return null; if (!int.TryParse(value.Text, NumberStyles.None, CultureInfo.InvariantCulture, out var intValue)) - throw new ArgumentException($"The value {value.Text} could not be parsed as an integer"); + throw new InvalidOperationException($"The value {value.Text} could not be parsed as an integer"); return intValue; } } + public decimal? DecimalValue + { + get + { + if (cell.CellValue is not { } value) + throw new InvalidOperationException($"{nameof(cell.CellValue)} was null"); + + if (value.Text is null) + return null; + + if (!decimal.TryParse(value.Text, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var decimalValue)) + throw new InvalidOperationException($"The value {value.Text} could not be parsed as a decimal"); + + return decimalValue; + } + } + public string? StringValue { get { if (cell.InlineString is not { } inlineString) - throw new ArgumentException($"{nameof(cell.InlineString)} was null"); + throw new InvalidOperationException($"{nameof(cell.InlineString)} was null"); if (inlineString.Text is not { } text) - throw new ArgumentException($"{nameof(inlineString.Text)} was null"); + throw new InvalidOperationException($"{nameof(inlineString.Text)} was null"); return text.Text; } diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs b/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs index c951458b..c6e8a166 100644 --- a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs +++ b/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs @@ -28,19 +28,38 @@ private List> GetAllCells() get { if (!SpreadsheetUtility.TryParseColumnName(columnName.AsSpan(), out var columnNumber)) - throw new ArgumentException($"{columnName} is not a valid column name"); + throw new InvalidOperationException($"{columnName} is not a valid column name"); if (Cells.ElementAtOrDefault(rowNumber - 1) is not { } row) - throw new ArgumentException($"Could not find row number {rowNumber}"); + throw new InvalidOperationException($"Could not find row number {rowNumber}"); if (row.ElementAtOrDefault(columnNumber - 1) is not { } cell) - throw new ArgumentException($"Could not find cell with reference {columnName}{rowNumber}"); + throw new InvalidOperationException($"Could not find cell with reference {columnName}{rowNumber}"); return new OpenXmlAssertCell(cell); } } + public IEnumerable this[string columnName] + { + get + { + if (!SpreadsheetUtility.TryParseColumnName(columnName.AsSpan(), out var columnNumber)) + throw new InvalidOperationException($"{columnName} is not a valid column name"); + + foreach (var (row, index) in Cells.Select((x, i) => (x, i))) + { + var rowNumber = index + 1; + if (row.ElementAtOrDefault(columnNumber - 1) is not { } cell) + throw new InvalidOperationException($"Could not find cell with reference {columnName}{rowNumber}"); + + yield return new OpenXmlAssertCell(cell); + } + } + } + public int CellCount => Cells.Sum(x => x.Count); + public int RowCount => Cells.Count; public void Dispose() { diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ClassWithColumnOrdering.cs b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ClassWithColumnOrdering.cs new file mode 100644 index 00000000..1cd4f76c --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ClassWithColumnOrdering.cs @@ -0,0 +1,14 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.Test.Models.ColumnOrdering; + +public class ClassWithColumnOrdering(string firstName, string lastName, decimal gpa, int age) +{ + [ColumnOrder(2)] + public string FirstName { get; } = firstName; + [ColumnOrder(1)] + public string LastName { get; } = lastName; + public decimal Gpa { get; } = gpa; + [ColumnOrder(3)] + public int Age { get; } = age; +} diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ReadOnlyRecordStructWithColumnOrdering.cs b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ReadOnlyRecordStructWithColumnOrdering.cs new file mode 100644 index 00000000..753117b4 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ReadOnlyRecordStructWithColumnOrdering.cs @@ -0,0 +1,9 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.Test.Models.ColumnOrdering; + +public readonly record struct ReadOnlyRecordStructWithColumnOrdering( + [property: ColumnOrder(2)] string FirstName, + [property: ColumnOrder(1)] string LastName, + decimal Gpa, + [property: ColumnOrder(3)] int Age); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ReadOnlyStructWithColumnOrdering.cs b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ReadOnlyStructWithColumnOrdering.cs new file mode 100644 index 00000000..eedac530 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/ReadOnlyStructWithColumnOrdering.cs @@ -0,0 +1,14 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.Test.Models.ColumnOrdering; + +public readonly struct ReadOnlyStructWithColumnOrdering(string firstName, string lastName, decimal gpa, int age) +{ + [ColumnOrder(2)] + public string FirstName { get; } = firstName; + [ColumnOrder(1)] + public string LastName { get; } = lastName; + public decimal Gpa { get; } = gpa; + [ColumnOrder(3)] + public int Age { get; } = age; +} \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/RecordClassWithColumnOrdering.cs b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/RecordClassWithColumnOrdering.cs new file mode 100644 index 00000000..c1a9d280 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/RecordClassWithColumnOrdering.cs @@ -0,0 +1,9 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.Test.Models.ColumnOrdering; + +public record RecordClassWithColumnOrdering( + [property: ColumnOrder(2)] string FirstName, + [property: ColumnOrder(1)] string LastName, + decimal Gpa, + [property: ColumnOrder(3)] int Age); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/RecordStructWithColumnOrdering.cs b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/RecordStructWithColumnOrdering.cs new file mode 100644 index 00000000..97f805c8 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/RecordStructWithColumnOrdering.cs @@ -0,0 +1,9 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.Test.Models.ColumnOrdering; + +public record struct RecordStructWithColumnOrdering( + [property: ColumnOrder(2)] string FirstName, + [property: ColumnOrder(1)] string LastName, + decimal Gpa, + [property: ColumnOrder(3)] int Age); \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/StructWithColumnOrdering.cs b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/StructWithColumnOrdering.cs new file mode 100644 index 00000000..b528b97b --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/ColumnOrdering/StructWithColumnOrdering.cs @@ -0,0 +1,14 @@ +using SpreadCheetah.SourceGeneration; + +namespace SpreadCheetah.SourceGenerator.Test.Models.ColumnOrdering; + +public struct StructWithColumnOrdering(string firstName, string lastName, decimal gpa, int age) +{ + [ColumnOrder(2)] + public string FirstName { get; } = firstName; + [ColumnOrder(1)] + public string LastName { get; } = lastName; + public decimal Gpa { get; } = gpa; + [ColumnOrder(3)] + public int Age { get; } = age; +} \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.Test/Models/Contexts/ColumnOrderingContext.cs b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/ColumnOrderingContext.cs new file mode 100644 index 00000000..687a5ea9 --- /dev/null +++ b/SpreadCheetah.SourceGenerator.Test/Models/Contexts/ColumnOrderingContext.cs @@ -0,0 +1,12 @@ +using SpreadCheetah.SourceGeneration; +using SpreadCheetah.SourceGenerator.Test.Models.ColumnOrdering; + +namespace SpreadCheetah.SourceGenerator.Test.Models.Contexts; + +[WorksheetRow(typeof(ClassWithColumnOrdering))] +[WorksheetRow(typeof(RecordClassWithColumnOrdering))] +[WorksheetRow(typeof(StructWithColumnOrdering))] +[WorksheetRow(typeof(RecordStructWithColumnOrdering))] +[WorksheetRow(typeof(ReadOnlyStructWithColumnOrdering))] +[WorksheetRow(typeof(ReadOnlyRecordStructWithColumnOrdering))] +public partial class ColumnOrderingContext : WorksheetRowContext; \ No newline at end of file diff --git a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs index 5cd5f9a0..e8a54ac9 100644 --- a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs +++ b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs @@ -3,6 +3,7 @@ using SpreadCheetah.SourceGenerator.Test.Helpers; using SpreadCheetah.SourceGenerator.Test.Models; using SpreadCheetah.SourceGenerator.Test.Models.Accessibility; +using SpreadCheetah.SourceGenerator.Test.Models.ColumnOrdering; using SpreadCheetah.SourceGenerator.Test.Models.Contexts; using SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; using SpreadCheetah.SourceGenerator.Test.Models.NoProperties; @@ -289,6 +290,48 @@ public async Task Spreadsheet_AddRangeAsRows_ObjectWithMultipleProperties(Object Assert.Equal(3, rows.Count); } + [Theory] + [MemberData(nameof(TestData.ObjectTypes), MemberType = typeof(TestData))] + public async Task Spreadsheet_AddRangeAsRows_ObjectWithColumnOrdering(ObjectType type) + { + // Arrange + var values = new (string FirstName, string LastName, decimal Gpa, int Age)[] + { + ("Ola", "Nordmann", 3.2m, 30), + ("Ingrid", "Hansen", 3.4m, 28), + ("Oskar", "Berg", 2.8m, 29) + }; + + var ctx = ColumnOrderingContext.Default; + + using var stream = new MemoryStream(); + await using var s = await Spreadsheet.CreateNewAsync(stream); + await s.StartWorksheetAsync("Sheet"); + + // Act + var task = type switch + { + ObjectType.Class => s.AddRangeAsRowsAsync(values.Select(x => new ClassWithColumnOrdering(x.FirstName, x.LastName, x.Gpa, x.Age)), ctx.ClassWithColumnOrdering), + ObjectType.RecordClass => s.AddRangeAsRowsAsync(values.Select(x => new RecordClassWithColumnOrdering(x.FirstName, x.LastName, x.Gpa, x.Age)), ctx.RecordClassWithColumnOrdering), + ObjectType.Struct => s.AddRangeAsRowsAsync(values.Select(x => new StructWithColumnOrdering(x.FirstName, x.LastName, x.Gpa, x.Age)), ctx.StructWithColumnOrdering), + ObjectType.RecordStruct => s.AddRangeAsRowsAsync(values.Select(x => new RecordStructWithColumnOrdering(x.FirstName, x.LastName, x.Gpa, x.Age)), ctx.RecordStructWithColumnOrdering), + ObjectType.ReadOnlyStruct => s.AddRangeAsRowsAsync(values.Select(x => new ReadOnlyStructWithColumnOrdering(x.FirstName, x.LastName, x.Gpa, x.Age)), ctx.ReadOnlyStructWithColumnOrdering), + ObjectType.ReadOnlyRecordStruct => s.AddRangeAsRowsAsync(values.Select(x => new ReadOnlyRecordStructWithColumnOrdering(x.FirstName, x.LastName, x.Gpa, x.Age)), ctx.ReadOnlyRecordStructWithColumnOrdering), + _ => throw new NotImplementedException() + }; + + await task; + await s.FinishAsync(); + + // Assert + using var sheet = SpreadsheetAssert.SingleSheet(stream); + Assert.Equal(values.Select(x => x.LastName), sheet["A"].Select(x => x.StringValue)); + Assert.Equal(values.Select(x => x.FirstName), sheet["B"].Select(x => x.StringValue)); + Assert.Equal(values.Select(x => x.Age), sheet["C"].Select(x => x.IntValue ?? -1)); + Assert.Equal(values.Select(x => x.Gpa), sheet["D"].Select(x => x.DecimalValue ?? -1)); + Assert.Equal(3, sheet.RowCount); + } + [Theory] [MemberData(nameof(TestData.ObjectTypes), MemberType = typeof(TestData))] public async Task Spreadsheet_AddRangeAsRows_ObjectWithNoProperties(ObjectType type) From ba33a552fc83319ac4034f041636a03e6e9e7a6e Mon Sep 17 00:00:00 2001 From: sveinungf Date: Mon, 1 Jan 2024 21:20:44 +0100 Subject: [PATCH 17/22] Move assertion helper classes to a new TestHelpers project --- .../SpreadCheetah.SourceGenerator.Test.csproj | 3 +-- .../Tests/WorksheetRowGeneratorTests.cs | 1 + .../Assertions}/ISpreadsheetAssertCell.cs | 4 ++-- .../Assertions}/ISpreadsheetAssertSheet.cs | 4 ++-- .../Assertions}/OpenXmlAssertCell.cs | 2 +- .../Assertions}/OpenXmlAssertSheet.cs | 2 +- .../Assertions}/SpreadsheetAssert.cs | 5 ++--- .../SpreadCheetah.TestHelpers.csproj | 15 +++++++++++++++ SpreadCheetah.sln | 6 ++++++ 9 files changed, 31 insertions(+), 11 deletions(-) rename {SpreadCheetah.SourceGenerator.Test/Helpers => SpreadCheetah.TestHelpers/Assertions}/ISpreadsheetAssertCell.cs (51%) rename {SpreadCheetah.SourceGenerator.Test/Helpers => SpreadCheetah.TestHelpers/Assertions}/ISpreadsheetAssertSheet.cs (64%) rename {SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml => SpreadCheetah.TestHelpers/Assertions}/OpenXmlAssertCell.cs (96%) rename {SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml => SpreadCheetah.TestHelpers/Assertions}/OpenXmlAssertSheet.cs (97%) rename {SpreadCheetah.SourceGenerator.Test/Helpers => SpreadCheetah.TestHelpers/Assertions}/SpreadsheetAssert.cs (76%) create mode 100644 SpreadCheetah.TestHelpers/SpreadCheetah.TestHelpers.csproj diff --git a/SpreadCheetah.SourceGenerator.Test/SpreadCheetah.SourceGenerator.Test.csproj b/SpreadCheetah.SourceGenerator.Test/SpreadCheetah.SourceGenerator.Test.csproj index d89542df..cc4b3b72 100644 --- a/SpreadCheetah.SourceGenerator.Test/SpreadCheetah.SourceGenerator.Test.csproj +++ b/SpreadCheetah.SourceGenerator.Test/SpreadCheetah.SourceGenerator.Test.csproj @@ -10,7 +10,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - @@ -24,8 +23,8 @@ - + diff --git a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs index e8a54ac9..45c5144c 100644 --- a/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs +++ b/SpreadCheetah.SourceGenerator.Test/Tests/WorksheetRowGeneratorTests.cs @@ -7,6 +7,7 @@ using SpreadCheetah.SourceGenerator.Test.Models.Contexts; using SpreadCheetah.SourceGenerator.Test.Models.MultipleProperties; using SpreadCheetah.SourceGenerator.Test.Models.NoProperties; +using SpreadCheetah.TestHelpers.Assertions; using Xunit; using OpenXmlCell = DocumentFormat.OpenXml.Spreadsheet.Cell; diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs b/SpreadCheetah.TestHelpers/Assertions/ISpreadsheetAssertCell.cs similarity index 51% rename from SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs rename to SpreadCheetah.TestHelpers/Assertions/ISpreadsheetAssertCell.cs index edaeba42..e7f80f84 100644 --- a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertCell.cs +++ b/SpreadCheetah.TestHelpers/Assertions/ISpreadsheetAssertCell.cs @@ -1,6 +1,6 @@ -namespace SpreadCheetah.SourceGenerator.Test.Helpers; +namespace SpreadCheetah.TestHelpers.Assertions; -internal interface ISpreadsheetAssertCell +public interface ISpreadsheetAssertCell { int? IntValue { get; } decimal? DecimalValue { get; } diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs b/SpreadCheetah.TestHelpers/Assertions/ISpreadsheetAssertSheet.cs similarity index 64% rename from SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs rename to SpreadCheetah.TestHelpers/Assertions/ISpreadsheetAssertSheet.cs index ebddb563..b59f23d8 100644 --- a/SpreadCheetah.SourceGenerator.Test/Helpers/ISpreadsheetAssertSheet.cs +++ b/SpreadCheetah.TestHelpers/Assertions/ISpreadsheetAssertSheet.cs @@ -1,6 +1,6 @@ -namespace SpreadCheetah.SourceGenerator.Test.Helpers; +namespace SpreadCheetah.TestHelpers.Assertions; -internal interface ISpreadsheetAssertSheet : IDisposable +public interface ISpreadsheetAssertSheet : IDisposable { ISpreadsheetAssertCell this[string columnName, int rowNumber] { get; } IEnumerable this[string columnName] { get; } diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs b/SpreadCheetah.TestHelpers/Assertions/OpenXmlAssertCell.cs similarity index 96% rename from SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs rename to SpreadCheetah.TestHelpers/Assertions/OpenXmlAssertCell.cs index d994bc9a..4bfbc5f2 100644 --- a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertCell.cs +++ b/SpreadCheetah.TestHelpers/Assertions/OpenXmlAssertCell.cs @@ -1,7 +1,7 @@ using System.Globalization; using OpenXmlCell = DocumentFormat.OpenXml.Spreadsheet.Cell; -namespace SpreadCheetah.SourceGenerator.Test.Helpers.OpenXml; +namespace SpreadCheetah.TestHelpers.Assertions; internal sealed class OpenXmlAssertCell(OpenXmlCell cell) : ISpreadsheetAssertCell { diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs b/SpreadCheetah.TestHelpers/Assertions/OpenXmlAssertSheet.cs similarity index 97% rename from SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs rename to SpreadCheetah.TestHelpers/Assertions/OpenXmlAssertSheet.cs index c6e8a166..196f7414 100644 --- a/SpreadCheetah.SourceGenerator.Test/Helpers/OpenXml/OpenXmlAssertSheet.cs +++ b/SpreadCheetah.TestHelpers/Assertions/OpenXmlAssertSheet.cs @@ -2,7 +2,7 @@ using DocumentFormat.OpenXml.Spreadsheet; using OpenXmlCell = DocumentFormat.OpenXml.Spreadsheet.Cell; -namespace SpreadCheetah.SourceGenerator.Test.Helpers.OpenXml; +namespace SpreadCheetah.TestHelpers.Assertions; internal sealed class OpenXmlAssertSheet(SpreadsheetDocument document, Worksheet worksheet) : ISpreadsheetAssertSheet diff --git a/SpreadCheetah.SourceGenerator.Test/Helpers/SpreadsheetAssert.cs b/SpreadCheetah.TestHelpers/Assertions/SpreadsheetAssert.cs similarity index 76% rename from SpreadCheetah.SourceGenerator.Test/Helpers/SpreadsheetAssert.cs rename to SpreadCheetah.TestHelpers/Assertions/SpreadsheetAssert.cs index e9c40fe9..08bc20f8 100644 --- a/SpreadCheetah.SourceGenerator.Test/Helpers/SpreadsheetAssert.cs +++ b/SpreadCheetah.TestHelpers/Assertions/SpreadsheetAssert.cs @@ -1,9 +1,8 @@ using DocumentFormat.OpenXml.Packaging; -using SpreadCheetah.SourceGenerator.Test.Helpers.OpenXml; -namespace SpreadCheetah.SourceGenerator.Test.Helpers; +namespace SpreadCheetah.TestHelpers.Assertions; -internal static class SpreadsheetAssert +public static class SpreadsheetAssert { public static ISpreadsheetAssertSheet SingleSheet(Stream stream) { diff --git a/SpreadCheetah.TestHelpers/SpreadCheetah.TestHelpers.csproj b/SpreadCheetah.TestHelpers/SpreadCheetah.TestHelpers.csproj new file mode 100644 index 00000000..47fbc8c9 --- /dev/null +++ b/SpreadCheetah.TestHelpers/SpreadCheetah.TestHelpers.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + + + + + + + + + + + diff --git a/SpreadCheetah.sln b/SpreadCheetah.sln index 20c01b25..f649c2c1 100644 --- a/SpreadCheetah.sln +++ b/SpreadCheetah.sln @@ -31,6 +31,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpreadCheetah.AotCompatibil EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpreadCheetah.SourceGenerator.CSharp8Test", "SpreadCheetah.SourceGenerator.CSharp8Test\SpreadCheetah.SourceGenerator.CSharp8Test.csproj", "{922F3921-1783-44CC-AF2B-DDDE039913A8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpreadCheetah.TestHelpers", "SpreadCheetah.TestHelpers\SpreadCheetah.TestHelpers.csproj", "{35778347-6F42-484A-A50A-BA33B6892B3D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -73,6 +75,10 @@ Global {922F3921-1783-44CC-AF2B-DDDE039913A8}.Debug|Any CPU.Build.0 = Debug|Any CPU {922F3921-1783-44CC-AF2B-DDDE039913A8}.Release|Any CPU.ActiveCfg = Release|Any CPU {922F3921-1783-44CC-AF2B-DDDE039913A8}.Release|Any CPU.Build.0 = Release|Any CPU + {35778347-6F42-484A-A50A-BA33B6892B3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35778347-6F42-484A-A50A-BA33B6892B3D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35778347-6F42-484A-A50A-BA33B6892B3D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35778347-6F42-484A-A50A-BA33B6892B3D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 9bc20d58ada0c08f13816c75be4ee836ec85cc66 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 7 Jan 2024 15:19:22 +0100 Subject: [PATCH 18/22] Suppress warnings for src gen attributes --- .editorconfig | 6 ++++++ .../SourceGeneration/WorksheetRowAttribute.cs | 13 +------------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/.editorconfig b/.editorconfig index 602094cf..97da656f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -148,6 +148,12 @@ dotnet_diagnostic.CA1815.severity = warning # CA2201: Do not raise reserved exception types dotnet_diagnostic.CA2201.severity = warning +[{ColumnOrderAttribute.cs,WorksheetRowAttribute.cs}] +# CA1019: Define accessors for attribute arguments +dotnet_diagnostic.CA1019.severity = none +# CS9113: Parameter is unread +dotnet_diagnostic.CS9113.severity = none + [{*Test,*.Benchmark,*.Cmd}/**.cs] # CA1305: Specify IFormatProvider dotnet_diagnostic.CA1305.severity = none diff --git a/SpreadCheetah/SourceGeneration/WorksheetRowAttribute.cs b/SpreadCheetah/SourceGeneration/WorksheetRowAttribute.cs index 6de3509e..b31a224c 100644 --- a/SpreadCheetah/SourceGeneration/WorksheetRowAttribute.cs +++ b/SpreadCheetah/SourceGeneration/WorksheetRowAttribute.cs @@ -5,15 +5,4 @@ namespace SpreadCheetah.SourceGeneration; /// specified type as a row to a worksheet. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -public sealed class WorksheetRowAttribute : Attribute -{ - /// - /// Initializes a new instance of with the specified type. - /// - /// The type to generate source code for. -#pragma warning disable CA1019 // Define accessors for attribute arguments -#pragma warning disable RCS1163 // Unused parameter. - public WorksheetRowAttribute(Type type) { } -#pragma warning restore RCS1163 // Unused parameter. -#pragma warning restore CA1019 // Define accessors for attribute arguments -} +public sealed class WorksheetRowAttribute(Type type) : Attribute; From 1020831b18ef2abac4770e72770b777ee789bc14 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 7 Jan 2024 15:24:04 +0100 Subject: [PATCH 19/22] Handle warnings for TestHelpers project --- .editorconfig | 2 +- SpreadCheetah.TestHelpers/Assertions/SpreadsheetAssert.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 97da656f..6e45256d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -205,7 +205,7 @@ dotnet_diagnostic.MA0076.severity = warning [{AutoFilterOptions.cs,ColumnOptions.cs,RowOptions.cs,SpreadCheetahOptions.cs,WorksheetOptions.cs,WorksheetRowGenerator.cs}] dotnet_diagnostic.MA0053.severity = none -[{*Test,*.Benchmark}/**.cs] +[{*Test,*TestHelpers,*.Benchmark}/**.cs] # MA0004: Use .ConfigureAwait(false) dotnet_diagnostic.MA0004.severity = none # MA0011: IFormatProvider is missing diff --git a/SpreadCheetah.TestHelpers/Assertions/SpreadsheetAssert.cs b/SpreadCheetah.TestHelpers/Assertions/SpreadsheetAssert.cs index 08bc20f8..9a6bdc74 100644 --- a/SpreadCheetah.TestHelpers/Assertions/SpreadsheetAssert.cs +++ b/SpreadCheetah.TestHelpers/Assertions/SpreadsheetAssert.cs @@ -6,6 +6,9 @@ public static class SpreadsheetAssert { public static ISpreadsheetAssertSheet SingleSheet(Stream stream) { + if (stream is null) + throw new ArgumentNullException(nameof(stream)); + stream.Position = 0; #pragma warning disable CA2000 // Dispose objects before losing scope var document = SpreadsheetDocument.Open(stream, false); From 94ca159ceb8884ff22b13b163a3ea0d106640069 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 7 Jan 2024 16:02:18 +0100 Subject: [PATCH 20/22] XML comment for ColumnOrderAttribute --- SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs b/SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs index fd8d7095..d5d88381 100644 --- a/SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs +++ b/SpreadCheetah/SourceGeneration/ColumnOrderAttribute.cs @@ -1,4 +1,14 @@ namespace SpreadCheetah.SourceGeneration; +/// +/// Instructs the SpreadCheetah source generator to specify column ordering. +/// The order can be customized by using this attribute on a type's properties. +/// +/// The order will be in ascending order based on the order parameter. E.g. a property with ColumnOrder(1) will be in the column before the column for property with ColumnOrder(2). +/// The value for the order parameter can be any integer, including negative integers. +/// Two properties can not have the same value for the order parameter. +/// Properties that don't have the attribute will implicitly get the first non-duplicate value for order starting at 1. +/// +/// [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public sealed class ColumnOrderAttribute(int order) : Attribute; From d91606549abd0e84560109f17bf78d6f185dbf84 Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 7 Jan 2024 16:19:37 +0100 Subject: [PATCH 21/22] Ignore SpreadCheetah.TestHelpers for code coverage --- codecov.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/codecov.yml b/codecov.yml index b12cf1b6..213b0cab 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,2 +1,3 @@ ignore: - "SpreadCheetah.Benchmark" + - "SpreadCheetah.TestHelpers" \ No newline at end of file From 1ad069aaf9a8fc668a75b1a8356fea3f3c372f1f Mon Sep 17 00:00:00 2001 From: sveinungf Date: Sun, 7 Jan 2024 16:33:33 +0100 Subject: [PATCH 22/22] Exclude CompilationExtensions.TryGetCompilationTypes from code coverage --- .../Extensions/CompilationExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SpreadCheetah.SourceGenerator/Extensions/CompilationExtensions.cs b/SpreadCheetah.SourceGenerator/Extensions/CompilationExtensions.cs index a4fe064f..10e00e51 100644 --- a/SpreadCheetah.SourceGenerator/Extensions/CompilationExtensions.cs +++ b/SpreadCheetah.SourceGenerator/Extensions/CompilationExtensions.cs @@ -6,6 +6,7 @@ namespace SpreadCheetah.SourceGenerator.Extensions; internal static class CompilationExtensions { + [ExcludeFromCodeCoverage] public static bool TryGetCompilationTypes( this Compilation compilation, [NotNullWhen(true)] out CompilationTypes? result)