Skip to content

Commit

Permalink
.Net8 and integration tests (#191)
Browse files Browse the repository at this point in the history
- Upgraded to .Net8
- Added a new project containing builders for our entities, which should
ease the writing of tests
- Added a shared setup for our integration tests
- Added a few integration tests to demonstrate the new setup
  • Loading branch information
TTA777 authored Feb 13, 2024
1 parent 7aa6c9b commit 12368a9
Show file tree
Hide file tree
Showing 37 changed files with 792 additions and 157 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/core-build.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Build and test solution

env:
DOTNET_VERSION: 6
DOTNET_VERSION: 8

on:
workflow_call:
Expand Down
5 changes: 2 additions & 3 deletions coffeecard/CoffeeCard.Common/CoffeeCard.Common.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ProjectGuid>33C1BE09-BD3A-4584-B195-C57B47B9063C</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="NetEscapades.Configuration.Validation" Version="2.0.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>
</Project>
</Project>
134 changes: 134 additions & 0 deletions coffeecard/CoffeeCard.Generators/Builder/BuilderGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;

namespace CoffeeCard.Generators.Builder;

[Generator]
public class BuilderGenerator : IIncrementalGenerator

Check warning on line 9 in coffeecard/CoffeeCard.Generators/Builder/BuilderGenerator.cs

View workflow job for this annotation

GitHub Actions / dev-deploy / Build codebase / Build codebase / Build and test analog-core

'CoffeeCard.Generators.Builder.BuilderGenerator': A project containing analyzers or source generators should specify the property '<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>'
{
private const string BuilderForAttribute = "CoffeeCard.Tests.Common.BuilderForAttribute";

public void Initialize(IncrementalGeneratorInitializationContext context)
{
var namedTypeSymbols = context.SyntaxProvider
.ForAttributeWithMetadataName(
fullyQualifiedMetadataName: BuilderForAttribute,
predicate: IsSyntaxTargetForGeneration,
transform: GetSemanticTargetForGeneration)
.Where(t => t is not null).Collect();

context.RegisterSourceOutput(namedTypeSymbols, (productionContext, array) =>
{
foreach (var typeSymbol in array)
{
//Retrieve the entity it is a builder for
var entity = (INamedTypeSymbol)typeSymbol.GetAttributes()

Check warning on line 27 in coffeecard/CoffeeCard.Generators/Builder/BuilderGenerator.cs

View workflow job for this annotation

GitHub Actions / dev-deploy / Build codebase / Build codebase / Build and test analog-core

Converting null literal or possible null value to non-nullable type.
.Single(attr => attr.AttributeClass.Name == "BuilderForAttribute").ConstructorArguments[0].Value;

Check warning on line 28 in coffeecard/CoffeeCard.Generators/Builder/BuilderGenerator.cs

View workflow job for this annotation

GitHub Actions / dev-deploy / Build codebase / Build codebase / Build and test analog-core

Dereference of a possibly null reference.
var code = GenerateBuilderCode(typeSymbol, entity);

Check warning on line 29 in coffeecard/CoffeeCard.Generators/Builder/BuilderGenerator.cs

View workflow job for this annotation

GitHub Actions / dev-deploy / Build codebase / Build codebase / Build and test analog-core

Possible null reference argument for parameter 'entity' in 'string BuilderGenerator.GenerateBuilderCode(INamedTypeSymbol typeSymbol, ITypeSymbol entity)'.
var sourceText = SourceText.From(code, Encoding.UTF8);
productionContext.AddSource($"{typeSymbol.Name}.g.cs", sourceText);
}
});
}

private static bool IsSyntaxTargetForGeneration(
SyntaxNode syntaxNode,
CancellationToken cancellationToken)
{
return syntaxNode is ClassDeclarationSyntax classDeclaration;
}

private static INamedTypeSymbol GetSemanticTargetForGeneration(GeneratorAttributeSyntaxContext context,
CancellationToken cancellationToken)
{
return (INamedTypeSymbol)context.TargetSymbol;
}

private string GenerateBuilderCode(INamedTypeSymbol typeSymbol, ITypeSymbol entity)
{
var codeBuilder = new StringBuilder();

codeBuilder.AppendLine("// <auto-generated/>");
codeBuilder.AppendLine("using System;");
codeBuilder.AppendLine("using AutoBogus.Conventions;");
codeBuilder.AppendLine($"using {entity.ContainingNamespace};");
codeBuilder.AppendLine();
codeBuilder.AppendLine($"namespace {typeSymbol.ContainingNamespace};");
codeBuilder.AppendLine();

codeBuilder.AppendLine($"public partial class {typeSymbol.Name} : BaseBuilder<{entity.Name}>, IBuilder<{typeSymbol.Name}>");
codeBuilder.AppendLine("{");

// Retrieve all properties of the given entity
var properties = entity.GetMembers().OfType<IPropertySymbol>().Where(p => p.Kind == SymbolKind.Property);

var entityNameChar = entity.Name.ToLowerInvariant()[0];
// Generate builder methods for all properties
var configBuilder = new StringBuilder();
foreach (var property in properties)
{
if (property.Name.Contains("Id"))
{
configBuilder.AppendLine($" .WithSkip<{entity.Name}>(\"{property.Name}\")");
}
AddWithPropertyValueToCodeBuilder(codeBuilder: codeBuilder,
typeSymbol: typeSymbol,
property: property,
entityNameChar: entityNameChar);

AddWithPropertySetterToCodeBuilder(
codeBuilder: codeBuilder,
typeSymbol: typeSymbol,
property: property,
entityNameChar: entityNameChar);
}
AddPrivateConstructorToCodeBuilder(codeBuilder, typeSymbol, configBuilder);

// End class
codeBuilder.AppendLine("}");

return codeBuilder.ToString();
}

/// <summary>
/// Generates a private constructor for the builder, to ensure the simple, or typical methods are used for instantiation
/// </summary>
/// <param name="codeBuilder"></param>
/// <param name="typeSymbol"></param>
/// <param name="configBuilder"></param>
private void AddPrivateConstructorToCodeBuilder(StringBuilder codeBuilder, ITypeSymbol typeSymbol, StringBuilder configBuilder)
{
codeBuilder.AppendLine(
$" private {typeSymbol.Name} ()");
codeBuilder.AppendLine(" {");
codeBuilder.AppendLine(" Faker.Configure(builder => builder");
codeBuilder.Append($"{configBuilder}");
codeBuilder.AppendLine(" .WithConventions());");
codeBuilder.AppendLine(" }");
}

private void AddWithPropertyValueToCodeBuilder(StringBuilder codeBuilder, ITypeSymbol typeSymbol, IPropertySymbol property, char entityNameChar)
{
codeBuilder.AppendLine(
$" public {typeSymbol.Name} With{property.Name}({property.Type} {property.Name}Value)");
codeBuilder.AppendLine(" {");

codeBuilder.AppendLine(
$" Faker.RuleFor({entityNameChar} => {entityNameChar}.{property.Name}, {property.Name}Value);");
codeBuilder.AppendLine(" return this;");
codeBuilder.AppendLine(" }");
}
private void AddWithPropertySetterToCodeBuilder(StringBuilder codeBuilder, ITypeSymbol typeSymbol, IPropertySymbol property, char entityNameChar)
{
codeBuilder.AppendLine(
$" public {typeSymbol.Name} With{property.Name}(Func<Bogus.Faker, {property.Type}> {property.Name}Setter)");
codeBuilder.AppendLine(" {");

codeBuilder.AppendLine(
$" Faker.RuleFor({entityNameChar} => {entityNameChar}.{property.Name}, {property.Name}Setter);");
codeBuilder.AppendLine(" return this;");
codeBuilder.AppendLine(" }");
}
}
23 changes: 23 additions & 0 deletions coffeecard/CoffeeCard.Generators/CoffeeCard.Generators.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>11.0</LangVersion>
</PropertyGroup>
<PropertyGroup>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)GeneratedCode\</CompilerGeneratedFilesOutputPath>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.7.0" />
</ItemGroup>

</Project>
81 changes: 37 additions & 44 deletions coffeecard/CoffeeCard.Library/CoffeeCard.Library.csproj
Original file line number Diff line number Diff line change
@@ -1,46 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>8</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MailKit" Version="3.4.2" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="4.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.11">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="6.0.11" />
<PackageReference Include="MimeKit" Version="3.4.2" />
<PackageReference Include="NetEscapades.Configuration.Validation" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.11" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.10" />
<PackageReference Include="RestSharp" Version="108.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
<PackageReference Include="Serilog.Enrichers.CorrelationId" Version="3.0.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.25.0" />
<PackageReference Include="TimeZoneConverter" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CoffeeCard.Common\CoffeeCard.Common.csproj" />
<ProjectReference Include="..\CoffeeCard.MobilePay\CoffeeCard.MobilePay.csproj" />
<ProjectReference Include="..\CoffeeCard.Models\CoffeeCard.Models.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Migrations\20220519210629_RestApiV2Changes.cs" />
<Compile Remove="Migrations\20220519210629_RestApiV2Changes.Designer.cs" />
<Compile Remove="Migrations\20191012125617_Initial - test.cs" />
<Compile Remove="Migrations\20191012125617_Initial - test.Designer.cs" />
</ItemGroup>

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>default</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MailKit" Version="3.4.2" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.1" />
<PackageReference Include="MimeKit" Version="3.4.2" />
<PackageReference Include="NetEscapades.Configuration.Validation" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.10" />
<PackageReference Include="RestSharp" Version="108.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
<PackageReference Include="Serilog.Enrichers.CorrelationId" Version="3.0.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
<PackageReference Include="TimeZoneConverter" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CoffeeCard.Common\CoffeeCard.Common.csproj" />
<ProjectReference Include="..\CoffeeCard.MobilePay\CoffeeCard.MobilePay.csproj" />
<ProjectReference Include="..\CoffeeCard.Models\CoffeeCard.Models.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Migrations\20220519210629_RestApiV2Changes.cs" />
<Compile Remove="Migrations\20220519210629_RestApiV2Changes.Designer.cs" />
<Compile Remove="Migrations\20191012125617_Initial - test.cs" />
<Compile Remove="Migrations\20191012125617_Initial - test.Designer.cs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>8</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NSwag.CodeGeneration.CSharp" Version="13.17.0" />
<PackageReference Include="NSwag.Core" Version="13.17.0" />
</ItemGroup>

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>default</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NSwag.CodeGeneration.CSharp" Version="13.17.0" />
<PackageReference Include="NSwag.Core" Version="13.17.0" />
</ItemGroup>
</Project>
11 changes: 5 additions & 6 deletions coffeecard/CoffeeCard.MobilePay/CoffeeCard.MobilePay.csproj
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ProjectGuid>AFF9D584-58F4-4A8D-A6BF-515890A9A3EF</ProjectGuid>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="jose-jwt" Version="4.0.1" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CoffeeCard.Common\CoffeeCard.Common.csproj" />
Expand Down
36 changes: 16 additions & 20 deletions coffeecard/CoffeeCard.Models/CoffeeCard.Models.csproj
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Nullable>enable</Nullable>
<LangVersion>default</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\CoffeeCard.Common\CoffeeCard.Common.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="6.0.11" />
<PackageReference Include="NJsonSchema" Version="10.8.0" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" PrivateAssets="all" />
<PackageReference Include="System.Text.Encoding.Extensions" Version="4.3.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.NETCore.Targets" Version="5.0.0" ExcludeAssets="all" PrivateAssets="all" />
</ItemGroup>

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Nullable>enable</Nullable>
<LangVersion>default</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\CoffeeCard.Common\CoffeeCard.Common.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NJsonSchema" Version="11.0.0" />
<PackageReference Include="Microsoft.NETCore.Targets" Version="5.0.0" ExcludeAssets="all" PrivateAssets="all" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="8.0.0" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" PrivateAssets="all" />
<PackageReference Include="System.Text.Encoding.Extensions" Version="4.3.0" PrivateAssets="all" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using NJsonSchema.Converters;

namespace CoffeeCard.Models.DataTransferObjects.v2.Purchase
{
Expand All @@ -14,7 +12,6 @@ namespace CoffeeCard.Models.DataTransferObjects.v2.Purchase
/// }
/// </example>
[KnownType(typeof(FreePurchasePaymentDetails))]
[JsonConverter(typeof(JsonInheritanceConverter))]
public class FreePurchasePaymentDetails : PaymentDetails
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Newtonsoft.Json;
using NJsonSchema.Converters;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;

Expand All @@ -17,7 +16,6 @@ namespace CoffeeCard.Models.DataTransferObjects.v2.Purchase
/// }
/// </example>
[KnownType(typeof(MobilePayPaymentDetails))]
[JsonConverter(typeof(JsonInheritanceConverter))]
public class MobilePayPaymentDetails : PaymentDetails
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using NJsonSchema.Converters;

namespace CoffeeCard.Models.DataTransferObjects.v2.Purchase
{
[KnownType(typeof(MobilePayPaymentDetails))]
[KnownType(typeof(FreePurchasePaymentDetails))]
[JsonConverter(typeof(JsonInheritanceConverter))]
public abstract class PaymentDetails
{
/// <summary>
Expand Down
Loading

0 comments on commit 12368a9

Please sign in to comment.