+@using Microsoft.AspNetCore.Mvc.TagHelpers
+
diff --git a/sample/Sample.Pages/Program.cs b/sample/Sample.Pages/Program.cs
index 078dbfab6..cce8d0756 100644
--- a/sample/Sample.Pages/Program.cs
+++ b/sample/Sample.Pages/Program.cs
@@ -36,7 +36,7 @@
"/health",
new()
{
- ResponseWriter = WriteResponse,
+ ResponseWriter = LaunchPadHelpers.DefaultResponseWriter,
ResultStatusCodes = new Dictionary
{
{ HealthStatus.Healthy, StatusCodes.Status200OK },
@@ -125,4 +125,4 @@ static Task WriteResponse(HttpContext context, HealthReport healthReport)
);
}
-public partial class Program;
\ No newline at end of file
+public partial class Program;
diff --git a/sample/Sample.Pages/Sample.Pages.csproj b/sample/Sample.Pages/Sample.Pages.csproj
index d024166fb..01dfdf89a 100644
--- a/sample/Sample.Pages/Sample.Pages.csproj
+++ b/sample/Sample.Pages/Sample.Pages.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net9.0
diff --git a/sample/Sample.Restful.Client/Sample.Restful.Client.csproj b/sample/Sample.Restful.Client/Sample.Restful.Client.csproj
index 123ef9988..7f4e37c76 100644
--- a/sample/Sample.Restful.Client/Sample.Restful.Client.csproj
+++ b/sample/Sample.Restful.Client/Sample.Restful.Client.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net8.0;net9.0
true
@@ -11,12 +11,11 @@
/>
-
+
-
-
\ No newline at end of file
+
diff --git a/sample/Sample.Restful/Controllers/WeatherForecastController.cs b/sample/Sample.Restful/Controllers/WeatherForecastController.cs
deleted file mode 100644
index eb13fa488..000000000
--- a/sample/Sample.Restful/Controllers/WeatherForecastController.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-using Rocket.Surgery.LaunchPad.AspNetCore;
-
-namespace Sample.Restful.Controllers;
-
-[Route("[controller]")]
-public class WeatherForecastController : RestfulApiController
-{
- private static readonly string[] Summaries =
- {
- "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
- };
-
- [HttpGet]
- public IEnumerable Get()
- {
- var rng = new Random();
- return Enumerable.Range(1, 5).Select(
- index => new WeatherForecast
- {
- Date = DateTime.Now.AddDays(index),
- TemperatureC = rng.Next(-20, 55),
- Summary = Summaries[rng.Next(Summaries.Length)]
- }
- )
- .ToArray();
- }
-}
diff --git a/sample/Sample.Restful/Program.cs b/sample/Sample.Restful/Program.cs
index 4394549e8..1c2a1a76f 100644
--- a/sample/Sample.Restful/Program.cs
+++ b/sample/Sample.Restful/Program.cs
@@ -2,7 +2,6 @@
using System.Text;
using System.Text.Json;
using FluentValidation;
-using Hellang.Middleware.ProblemDetails;
using Humanizer;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Options;
@@ -10,41 +9,29 @@
using Rocket.Surgery.LaunchPad.AspNetCore;
using Sample.Restful;
using Serilog;
-using Swashbuckle.AspNetCore.SwaggerGen;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers().AddControllersAsServices();
builder.Services.AddHostedService();
-builder.Services
- .Configure(
- c => c.SwaggerDoc(
- "v1",
- new()
- {
- Version = typeof(Program).GetCustomAttribute()?.Version
- ?? typeof(Program).GetCustomAttribute()?.Version ?? "0.1.0",
- Title = "Test Application",
- }
- )
- );
var app = await builder
.LaunchWith(RocketBooster.For(Imports.Instance));
-app.UseProblemDetails();
+app.UseExceptionHandler();
app.UseHttpsRedirection();
// Should this move into an extension method?
app.UseSerilogRequestLogging(
x =>
{
- x.GetLevel = LaunchPadLogHelpers.DefaultGetLevel;
- x.EnrichDiagnosticContext = LaunchPadLogHelpers.DefaultEnrichDiagnosticContext;
+ x.GetLevel = LaunchPadHelpers.DefaultGetLevel;
+ x.EnrichDiagnosticContext = LaunchPadHelpers.DefaultEnrichDiagnosticContext;
}
);
app.UseRouting();
+app.MapOpenApi();
app
.UseSwaggerUI()
.UseReDoc();
@@ -54,7 +41,7 @@
"/health",
new()
{
- ResponseWriter = WriteResponse,
+ ResponseWriter = LaunchPadHelpers.DefaultResponseWriter,
ResultStatusCodes = new Dictionary
{
{ HealthStatus.Healthy, StatusCodes.Status200OK },
@@ -66,87 +53,8 @@
app.MapControllers();
-// Should this move into an extension method?
-app.MapSwagger();
-
app.Run();
-static Task WriteResponse(HttpContext context, HealthReport healthReport)
-{
- context.Response.ContentType = "application/json; charset=utf-8";
-
- var options = new JsonWriterOptions { Indented = true, };
-
- using var memoryStream = new MemoryStream();
- using (var jsonWriter = new Utf8JsonWriter(memoryStream, options))
- {
- jsonWriter.WriteStartObject();
- jsonWriter.WriteString("status", healthReport.Status.ToString());
- jsonWriter.WriteStartObject("results");
-
- foreach (var healthReportEntry in healthReport.Entries)
- {
- jsonWriter.WriteStartObject(healthReportEntry.Key);
- jsonWriter.WriteString(
- "status",
- healthReportEntry.Value.Status.ToString()
- );
- jsonWriter.WriteString(
- "duration",
- healthReportEntry.Value.Duration.Humanize()
- );
- jsonWriter.WriteString(
- "description",
- healthReportEntry.Value.Description
- );
-
- jsonWriter.WriteStartObject("data");
- foreach (var item in healthReportEntry.Value.Data)
- {
- jsonWriter.WritePropertyName(item.Key);
-
- JsonSerializer.Serialize(
- jsonWriter,
- item.Value,
- item.Value.GetType()
- );
- }
-
- jsonWriter.WriteEndObject();
-
- if (healthReportEntry.Value.Tags.Any())
- {
- jsonWriter.WriteStartArray("tags");
- foreach (var item in healthReportEntry.Value.Tags)
- {
- jsonWriter.WriteStringValue(item);
- }
-
- jsonWriter.WriteEndArray();
- }
-
- if (healthReportEntry.Value.Exception != null)
- {
- var ex = healthReportEntry.Value.Exception;
- jsonWriter.WriteStartObject("exception");
- jsonWriter.WriteString("message", ex.Message);
- jsonWriter.WriteString("stacktrace", ex.StackTrace);
- jsonWriter.WriteString("inner", ex.InnerException?.ToString());
- jsonWriter.WriteEndObject();
- }
-
- jsonWriter.WriteEndObject();
- }
-
- jsonWriter.WriteEndObject();
- jsonWriter.WriteEndObject();
- }
-
- return context.Response.WriteAsync(
- Encoding.UTF8.GetString(memoryStream.ToArray())
- );
-}
-
public partial class Program;
internal class CustomHostedServiceOptions
@@ -171,4 +79,4 @@ protected override Task ExecuteAsync(CancellationToken stoppingToken)
var v = options.Value.A;
return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/sample/Sample.Restful/Sample.Restful.csproj b/sample/Sample.Restful/Sample.Restful.csproj
index b705e2f5a..5747ca074 100644
--- a/sample/Sample.Restful/Sample.Restful.csproj
+++ b/sample/Sample.Restful/Sample.Restful.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net9.0
true
true
true
@@ -9,10 +9,13 @@
-
+
+
+
diff --git a/sample/Sample.Restful/WeatherForecast.cs b/sample/Sample.Restful/WeatherForecast.cs
deleted file mode 100644
index 05ed7c985..000000000
--- a/sample/Sample.Restful/WeatherForecast.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Sample.Restful;
-
-public class WeatherForecast
-{
- public DateTime Date { get; set; }
-
- public int TemperatureC { get; set; }
-
- public int TemperatureF => 32 + (int)( TemperatureC / 0.5556 );
-
- public string? Summary { get; set; }
-}
diff --git a/sample/Sample.Worker/Sample.Worker.csproj b/sample/Sample.Worker/Sample.Worker.csproj
index e3bc18b8a..7ee64884a 100644
--- a/sample/Sample.Worker/Sample.Worker.csproj
+++ b/sample/Sample.Worker/Sample.Worker.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net8.0;net9.0
diff --git a/src/Analyzers.roslyn4.6/Rocket.Surgery.LaunchPad.Analyzers.roslyn4.6.csproj b/src/Analyzers.roslyn4.6/Rocket.Surgery.LaunchPad.Analyzers.roslyn4.6.csproj
index bd2b9103e..210580076 100644
--- a/src/Analyzers.roslyn4.6/Rocket.Surgery.LaunchPad.Analyzers.roslyn4.6.csproj
+++ b/src/Analyzers.roslyn4.6/Rocket.Surgery.LaunchPad.Analyzers.roslyn4.6.csproj
@@ -12,7 +12,9 @@
-
+
+ 4.11.0
+
diff --git a/src/Analyzers/GraphqlMutationActionBodyGenerator.cs b/src/Analyzers/GraphqlMutationActionBodyGenerator.cs
index 019b583bc..2a884a155 100644
--- a/src/Analyzers/GraphqlMutationActionBodyGenerator.cs
+++ b/src/Analyzers/GraphqlMutationActionBodyGenerator.cs
@@ -18,24 +18,24 @@ public class GraphqlMutationActionBodyGenerator : IIncrementalGenerator
INamedTypeSymbol mediator,
INamedTypeSymbol claimsPrincipal,
INamedTypeSymbol cancellationToken,
- MethodDeclarationSyntax syntax,
- IMethodSymbol symbol,
- IParameterSymbol parameter,
+ MethodDeclarationSyntax methodSyntax,
+ IMethodSymbol methodSymbol,
+ IParameterSymbol requestParameter,
ITypeSymbol requestType,
ExpressionSyntax requestExpression
)
{
- var otherParams = symbol.Parameters.Remove(parameter);
+ var otherParams = methodSymbol.Parameters.Remove(requestParameter);
var isUnit = requestType.AllInterfaces.Any(z => z.MetadataName == "IRequest");
- var returnsMediatorUnit = symbol.ReturnType is INamedTypeSymbol { MetadataName: "Task`1", TypeArguments: [{ MetadataName: "Unit", },], };
+ var returnsMediatorUnit = methodSymbol.ReturnType is INamedTypeSymbol { MetadataName: "Task`1", TypeArguments: [{ MetadataName: "Unit", },], };
isUnit = returnsMediatorUnit || isUnit;
- var isStream = symbol.ReturnType.MetadataName == "IAsyncEnumerable`1";
+ var isStream = methodSymbol.ReturnType.MetadataName == "IAsyncEnumerable`1";
- var newSyntax = syntax
+ var newSyntax = methodSyntax
.WithParameterList(
// ReSharper disable once NullableWarningSuppressionIsUsed
- syntax.ParameterList.RemoveNodes(
- syntax.ParameterList.Parameters.SelectMany(z => z.AttributeLists),
+ methodSyntax.ParameterList.RemoveNodes(
+ methodSyntax.ParameterList.Parameters.SelectMany(z => z.AttributeLists),
SyntaxRemoveOptions.KeepNoTrivia
)!
)
@@ -47,7 +47,7 @@ ExpressionSyntax requestExpression
.AddModifiers(Token(SyntaxKind.AsyncKeyword));
var block = Block();
- var resultName = parameter.Name == "result" ? "r" : "result";
+ var resultName = requestParameter.Name == "result" ? "r" : "result";
var mediatorParameter = otherParams.FirstOrDefault(param => SymbolEqualityComparer.Default.Equals(mediator, param.Type));
var claimsPrincipalParameter = otherParams.FirstOrDefault(param => SymbolEqualityComparer.Default.Equals(claimsPrincipal, param.Type));
var cancellationTokenParameter = otherParams.FirstOrDefault(param => SymbolEqualityComparer.Default.Equals(cancellationToken, param.Type));
@@ -55,8 +55,8 @@ ExpressionSyntax requestExpression
context.ReportDiagnostic(
Diagnostic.Create(
GeneratorDiagnostics.ParameterMustExist,
- parameter.Locations.First(),
- parameter.Locations.Skip(1),
+ requestParameter.Locations.First(),
+ requestParameter.Locations.Skip(1),
mediator,
requestType.Name
)
@@ -79,8 +79,8 @@ ExpressionSyntax requestExpression
context.ReportDiagnostic(
Diagnostic.Create(
GeneratorDiagnostics.ParameterMustExist,
- parameter.Locations.First(),
- parameter.Locations.Skip(1),
+ requestParameter.Locations.First(),
+ requestParameter.Locations.Skip(1),
claimsPrincipal,
requestType.Name
)
@@ -95,10 +95,10 @@ ExpressionSyntax requestExpression
VariableDeclaration(
IdentifierName(Identifier(TriviaList(), SyntaxKind.VarKeyword, "var", "var", TriviaList()))
)
- .WithVariables(SingletonSeparatedList(VariableDeclarator("_" + parameter.Name).WithInitializer(EqualsValueClause(requestExpression))))
+ .WithVariables(SingletonSeparatedList(VariableDeclarator("_" + requestParameter.Name).WithInitializer(EqualsValueClause(requestExpression))))
)
);
- requestExpression = IdentifierName("_" + parameter.Name);
+ requestExpression = IdentifierName("_" + requestParameter.Name);
}
var sendRequestExpression = isStream
@@ -118,7 +118,6 @@ ExpressionSyntax requestExpression
)
);
}
-
if (requestType.IsRecord)
{
var expressions = new List();
@@ -167,7 +166,7 @@ ExpressionSyntax requestExpression
SyntaxKind.SimpleAssignmentExpression,
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
- IdentifierName("_" + parameter.Name),
+ IdentifierName("_" + requestParameter.Name),
IdentifierName(claimsPrincipalProperty!.Name)
),
IdentifierName(claimsPrincipalParameter!.Name)
@@ -201,6 +200,20 @@ ExpressionSyntax requestExpression
ReturnStatement(IdentifierName(resultName))
);
+// if (compilation.GetTypeByMetadataName("FluentValidation.ValidationException") is { })
+// {
+// newSyntax = newSyntax.AddAttributeLists(GetErrorAttribute("FluentValidation.ValidationException"));
+// }
+//
+// if (compilation.GetTypeByMetadataName("Rocket.Surgery.LaunchPad.Foundation.NotFoundException") is { })
+// {
+// newSyntax = newSyntax.AddAttributeLists(GetErrorAttribute("Rocket.Surgery.LaunchPad.Foundation.NotFoundException"));
+// }
+//
+// if (compilation.GetTypeByMetadataName("Rocket.Surgery.LaunchPad.Foundation.RequestFailedException") is { })
+// {
+// newSyntax = newSyntax.AddAttributeLists(GetErrorAttribute("Rocket.Surgery.LaunchPad.Foundation.RequestFailedException"));
+// }
return newSyntax
.WithBody(block.NormalizeWhitespace())
@@ -262,6 +275,30 @@ static ExpressionSyntax streamMediatorRequest(
)
.WithArgumentList(ArgumentList(SeparatedList(arguments)));
}
+
+ static AttributeListSyntax GetErrorAttribute(string exceptionType)
+ {
+ return AttributeList(
+ SingletonSeparatedList(
+ Attribute(
+ QualifiedName(
+ QualifiedName(
+ IdentifierName("HotChocolate"),
+ IdentifierName("Types")
+ ),
+ GenericName(
+ Identifier("Error")
+ )
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(ParseName(exceptionType))
+ )
+ )
+ )
+ )
+ )
+ );
+ }
}
private void GenerateMethods(
@@ -435,4 +472,4 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
context.RegisterSourceOutput(syntaxProvider, GenerateMethods);
}
-}
\ No newline at end of file
+}
diff --git a/src/Analyzers/PropertyTrackingGenerator.cs b/src/Analyzers/PropertyTrackingGenerator.cs
index 1dd84ee05..a3beeb9e1 100644
--- a/src/Analyzers/PropertyTrackingGenerator.cs
+++ b/src/Analyzers/PropertyTrackingGenerator.cs
@@ -215,13 +215,11 @@ INamedTypeSymbol targetSymbol
AssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
IdentifierName(propertySymbol.Name),
- InvocationExpression(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName(propertySymbol.Name),
- IdentifierName("HasBeenSet")
+ IdentifierName("HasValue")
)
- )
)
);
createMethodInitializer = createMethodInitializer.AddExpressions(
@@ -405,13 +403,11 @@ bool isRecord
)
{
return IfStatement(
- InvocationExpression(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName(propertySymbol.Name),
- IdentifierName("HasBeenSet")
- )
- ),
+ IdentifierName("HasValue")
+ ),
Block(
SingletonList(
ExpressionStatement(
@@ -541,4 +537,4 @@ and TypeDeclarationSyntax
static (productionContext, tuple) => GeneratePropertyTracking(productionContext, tuple.syntax, tuple.symbol, tuple.targetSymbol!)
);
}
-}
\ No newline at end of file
+}
diff --git a/src/AspNetCore.Blazor/Rocket.Surgery.LaunchPad.AspNetCore.Blazor.csproj b/src/AspNetCore.Blazor/Rocket.Surgery.LaunchPad.AspNetCore.Blazor.csproj
index a56f57d9f..c2e5e8b02 100644
--- a/src/AspNetCore.Blazor/Rocket.Surgery.LaunchPad.AspNetCore.Blazor.csproj
+++ b/src/AspNetCore.Blazor/Rocket.Surgery.LaunchPad.AspNetCore.Blazor.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net9.0
$(PackageTags)
diff --git a/src/AspNetCore.FluentValidation.OpenApi/BetweenPropertyRule.cs b/src/AspNetCore.FluentValidation.OpenApi/BetweenPropertyRule.cs
new file mode 100644
index 000000000..548a12783
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/BetweenPropertyRule.cs
@@ -0,0 +1,27 @@
+using FluentValidation.Validators;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public sealed class BetweenPropertyRule : IPropertyRuleHandler
+{
+ Task IPropertyRuleHandler.HandleAsync(OpenApiValidationContext context, CancellationToken cancellationToken)
+ {
+ if (context is not { PropertyValidator: IBetweenValidator validator }) return Task.CompletedTask;
+
+ var schemaProperty = context.PropertySchema;
+ if (validator.From.IsNumeric())
+ {
+ schemaProperty.Minimum = Convert.ToDecimal(validator.From);
+ if (validator.Name == "ExclusiveBetweenValidator") schemaProperty.ExclusiveMinimum = true;
+ }
+
+ if (validator.To.IsNumeric())
+ {
+ schemaProperty.Maximum = Convert.ToDecimal(validator.To);
+ if (validator.Name == "ExclusiveBetweenValidator") schemaProperty.ExclusiveMaximum = true;
+ }
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/src/AspNetCore.FluentValidation.OpenApi/ComparisonPropertyRule.cs b/src/AspNetCore.FluentValidation.OpenApi/ComparisonPropertyRule.cs
new file mode 100644
index 000000000..c9709a43f
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/ComparisonPropertyRule.cs
@@ -0,0 +1,47 @@
+using FluentValidation.Validators;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public sealed class ComparisonPropertyRule : IPropertyRuleHandler
+{
+ Task IPropertyRuleHandler.HandleAsync(OpenApiValidationContext context, CancellationToken cancellationToken)
+ {
+ if (context is not { PropertyValidator: IComparisonValidator validator }) return Task.CompletedTask;
+
+ if (!validator.ValueToCompare.IsNumeric()) return Task.CompletedTask;
+ var valueToCompare = Convert.ToDecimal(validator.ValueToCompare);
+ var schemaProperty = context.PropertySchema;
+
+ switch (validator)
+ {
+ case { Comparison: Comparison.GreaterThanOrEqual }:
+ {
+ schemaProperty.Minimum = valueToCompare;
+ return Task.CompletedTask;
+ }
+
+ case { Comparison: Comparison.GreaterThan }:
+ {
+ schemaProperty.Minimum = valueToCompare;
+ schemaProperty.ExclusiveMinimum = true;
+ return Task.CompletedTask;
+ }
+
+ case { Comparison: Comparison.LessThanOrEqual }:
+ {
+ schemaProperty.Maximum = valueToCompare;
+ return Task.CompletedTask;
+ }
+
+ case { Comparison: Comparison.LessThan }:
+ {
+ schemaProperty.Maximum = valueToCompare;
+ schemaProperty.ExclusiveMaximum = true;
+ return Task.CompletedTask;
+ }
+ }
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/src/AspNetCore.FluentValidation.OpenApi/Constants.cs b/src/AspNetCore.FluentValidation.OpenApi/Constants.cs
new file mode 100644
index 000000000..f83d11db1
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/Constants.cs
@@ -0,0 +1,8 @@
+using System.Numerics;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+internal static class Constants
+{
+ public const string ExperimentalId = "RSGEXP";
+}
diff --git a/src/AspNetCore.FluentValidation.OpenApi/EmailPropertyRule.cs b/src/AspNetCore.FluentValidation.OpenApi/EmailPropertyRule.cs
new file mode 100644
index 000000000..470a01cb0
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/EmailPropertyRule.cs
@@ -0,0 +1,14 @@
+using FluentValidation.Validators;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public sealed class EmailPropertyRule : IPropertyRuleHandler
+{
+ Task IPropertyRuleHandler.HandleAsync(OpenApiValidationContext context, CancellationToken cancellationToken)
+ {
+ if (context is not { PropertyValidator: IEmailValidator validator }) return Task.CompletedTask;
+ context.PropertySchema.Format = "email";
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/src/AspNetCore.FluentValidation.OpenApi/Extensions.cs b/src/AspNetCore.FluentValidation.OpenApi/Extensions.cs
new file mode 100644
index 000000000..f955e820b
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/Extensions.cs
@@ -0,0 +1,6 @@
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+internal static class Extensions
+{
+ internal static bool IsNumeric(this object value) => value is int || value is long || value is float || value is double || value is decimal;
+}
\ No newline at end of file
diff --git a/src/AspNetCore.FluentValidation.OpenApi/FluentValidationOpenApiSchemaTransformer.cs b/src/AspNetCore.FluentValidation.OpenApi/FluentValidationOpenApiSchemaTransformer.cs
new file mode 100644
index 000000000..90bd81c38
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/FluentValidationOpenApiSchemaTransformer.cs
@@ -0,0 +1,44 @@
+using FluentValidation;
+using Microsoft.AspNetCore.OpenApi;
+using Microsoft.OpenApi.Models;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public class FluentValidationOpenApiSchemaTransformer(IEnumerable ruleDefinitionHandlers) : IOpenApiSchemaTransformer
+{
+ public async Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext context, CancellationToken cancellationToken)
+ {
+ var validatorType = typeof(IValidator<>).MakeGenericType(context.JsonTypeInfo.Type);
+ if (context.ApplicationServices.GetService(validatorType) is not IValidator validator) return;
+
+ var descriptor = validator.CreateDescriptor();
+ foreach (var (validators, propertyKey, property) in descriptor
+ .GetMembersWithValidators()
+ .Join(
+ schema.Properties,
+ z => z.Key,
+ z => z.Key,
+ (z, y) => ( validators: z.AsEnumerable(), property: y.Key, schema: y.Value ),
+ StringComparer.OrdinalIgnoreCase
+ ))
+
+ {
+ foreach (var (propertyValidator, component) in validators)
+ {
+ foreach (var item in ruleDefinitionHandlers)
+ {
+ var ctx = new OpenApiValidationContext(
+ schema,
+ property,
+ context,
+ propertyValidator,
+ propertyKey,
+ component
+ );
+ await item.HandleAsync(ctx, cancellationToken);
+ }
+ }
+ }
+ }
+}
diff --git a/src/AspNetCore.FluentValidation.OpenApi/IPropertyRuleHandler.cs b/src/AspNetCore.FluentValidation.OpenApi/IPropertyRuleHandler.cs
new file mode 100644
index 000000000..d4de4498a
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/IPropertyRuleHandler.cs
@@ -0,0 +1,7 @@
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public interface IPropertyRuleHandler
+{
+ Task HandleAsync(OpenApiValidationContext context, CancellationToken cancellationToken);
+}
\ No newline at end of file
diff --git a/src/AspNetCore.FluentValidation.OpenApi/LengthPropertyRule.cs b/src/AspNetCore.FluentValidation.OpenApi/LengthPropertyRule.cs
new file mode 100644
index 000000000..a914e0869
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/LengthPropertyRule.cs
@@ -0,0 +1,30 @@
+using FluentValidation.Validators;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public sealed class LengthPropertyRule : IPropertyRuleHandler
+{
+ Task IPropertyRuleHandler.HandleAsync(OpenApiValidationContext context, CancellationToken cancellationToken)
+ {
+ if (context.PropertyValidator is not ILengthValidator validator) return Task.CompletedTask;
+
+ if (context.PropertySchema.Type == "array")
+ {
+ if (validator.Max > 0)
+ context.PropertySchema.MaxItems = validator.Max;
+
+ if (validator.Min > 0)
+ context.PropertySchema.MinItems = validator.Min;
+ }
+ else
+ {
+ if (validator.Max > 0)
+ context.PropertySchema.MaxLength = validator.Max;
+ if (validator.Min > 0)
+ context.PropertySchema.MinLength = validator.Min;
+ }
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/src/AspNetCore.FluentValidation.OpenApi/NotEmptyPropertyRule.cs b/src/AspNetCore.FluentValidation.OpenApi/NotEmptyPropertyRule.cs
new file mode 100644
index 000000000..bc1f8992c
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/NotEmptyPropertyRule.cs
@@ -0,0 +1,15 @@
+using FluentValidation.Validators;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public sealed class NotEmptyPropertyRule : IPropertyRuleHandler
+{
+ Task IPropertyRuleHandler.HandleAsync(OpenApiValidationContext context, CancellationToken cancellationToken)
+ {
+ if (context is { PropertyValidator: not INotEmptyValidator } or { PropertySchema.MinLength: > 1 } or { PropertySchema.Type: not ("string" or "array") })
+ return Task.CompletedTask;
+ context.PropertySchema.MinLength = 1;
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/src/AspNetCore.FluentValidation.OpenApi/OpenApiValidationContext.cs b/src/AspNetCore.FluentValidation.OpenApi/OpenApiValidationContext.cs
new file mode 100644
index 000000000..4354cdb92
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/OpenApiValidationContext.cs
@@ -0,0 +1,17 @@
+using System.Text.Json.Serialization.Metadata;
+using FluentValidation.Internal;
+using FluentValidation.Validators;
+using Microsoft.AspNetCore.OpenApi;
+using Microsoft.OpenApi.Models;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public record OpenApiValidationContext
+(
+ OpenApiSchema TypeSchema,
+ OpenApiSchema PropertySchema,
+ OpenApiSchemaTransformerContext TransformerContext,
+ IPropertyValidator PropertyValidator,
+ string PropertyKey,
+ IRuleComponent RuleComponent);
diff --git a/src/AspNetCore.FluentValidation.OpenApi/RegularExpressionPropertyRule.cs b/src/AspNetCore.FluentValidation.OpenApi/RegularExpressionPropertyRule.cs
new file mode 100644
index 000000000..e679001fd
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/RegularExpressionPropertyRule.cs
@@ -0,0 +1,26 @@
+using FluentValidation.Validators;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public sealed class RegularExpressionPropertyRule : IPropertyRuleHandler
+{
+ Task IPropertyRuleHandler.HandleAsync(OpenApiValidationContext context, CancellationToken cancellationToken)
+ {
+ if (context is not { PropertyValidator: IRegularExpressionValidator validator }) return Task.CompletedTask;
+
+ var anyPatterns = context.PropertySchema.AllOf.Any(schema => schema.Pattern is { });
+ if (context.PropertySchema is { Pattern: { } } || anyPatterns)
+ {
+ if (!anyPatterns) context.PropertySchema.AllOf.Add(new() { Pattern = context.PropertySchema.Pattern });
+ context.PropertySchema.AllOf.Add(new() { Pattern = validator.Expression });
+ context.PropertySchema.Pattern = null;
+ }
+ else
+ {
+ context.PropertySchema.Pattern = validator.Expression;
+ }
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/src/AspNetCore.FluentValidation.OpenApi/RequiredPropertyRuleHandler.cs b/src/AspNetCore.FluentValidation.OpenApi/RequiredPropertyRuleHandler.cs
new file mode 100644
index 000000000..daa223c58
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/RequiredPropertyRuleHandler.cs
@@ -0,0 +1,14 @@
+using FluentValidation.Validators;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public sealed class RequiredPropertyRuleHandler : IPropertyRuleHandler
+{
+ Task IPropertyRuleHandler.HandleAsync(OpenApiValidationContext context, CancellationToken cancellationToken)
+ {
+ if (context.PropertyValidator is not (INotNullValidator or INotEmptyValidator)) return Task.CompletedTask;
+ context.TypeSchema.Required.Add(context.PropertyKey);
+ return Task.CompletedTask;
+ }
+}
diff --git a/src/AspNetCore.FluentValidation.OpenApi/Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi.csproj b/src/AspNetCore.FluentValidation.OpenApi/Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi.csproj
new file mode 100644
index 000000000..d8be2d6d3
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi.csproj
@@ -0,0 +1,14 @@
+
+
+ net9.0
+
+ The goal of this package is be a minimal and experimental implementation of open api integration of fluent validation for aspnet core
+
+ fluentvalidation,openapi
+
+
+
+
+
+
+
diff --git a/src/AspNetCore.FluentValidation.OpenApi/ServiceCollectionExtensions.cs b/src/AspNetCore.FluentValidation.OpenApi/ServiceCollectionExtensions.cs
new file mode 100644
index 000000000..669020fbe
--- /dev/null
+++ b/src/AspNetCore.FluentValidation.OpenApi/ServiceCollectionExtensions.cs
@@ -0,0 +1,28 @@
+using FluentValidation.AspNetCore;
+using Microsoft.AspNetCore.OpenApi;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+[Experimental(Constants.ExperimentalId)]
+public static class ServiceCollectionExtensions
+{
+ public static IServiceCollection AddFluentValidationOpenApi(this IServiceCollection services)
+ {
+ services.AddOpenApi();
+ services.AddFluentValidationAutoValidation();
+ services.Configure(
+ "v1",
+ options => { options.AddSchemaTransformer(); }
+ );
+ services.TryAddEnumerable(ServiceDescriptor.Transient());
+ services.TryAddEnumerable(ServiceDescriptor.Transient());
+ services.TryAddEnumerable(ServiceDescriptor.Transient());
+ services.TryAddEnumerable(ServiceDescriptor.Transient());
+ services.TryAddEnumerable(ServiceDescriptor.Transient());
+ services.TryAddEnumerable(ServiceDescriptor.Transient());
+ services.TryAddEnumerable(ServiceDescriptor.Transient());
+ return services;
+ }
+}
\ No newline at end of file
diff --git a/src/AspNetCore.NewtonsoftJson/Rocket.Surgery.LaunchPad.AspNetCore.NewtonsoftJson.csproj b/src/AspNetCore.NewtonsoftJson/Rocket.Surgery.LaunchPad.AspNetCore.NewtonsoftJson.csproj
index a4b21ce90..d84359a19 100644
--- a/src/AspNetCore.NewtonsoftJson/Rocket.Surgery.LaunchPad.AspNetCore.NewtonsoftJson.csproj
+++ b/src/AspNetCore.NewtonsoftJson/Rocket.Surgery.LaunchPad.AspNetCore.NewtonsoftJson.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net9.0
$(PackageTags)
Rocket.Surgery.LaunchPad.AspNetCore
diff --git a/src/AspNetCore.Spatial/Conventions/AspNetCoreSpatialConvention.cs b/src/AspNetCore.Spatial/Conventions/AspNetCoreSpatialConvention.cs
index 54158f607..3daa02376 100644
--- a/src/AspNetCore.Spatial/Conventions/AspNetCoreSpatialConvention.cs
+++ b/src/AspNetCore.Spatial/Conventions/AspNetCoreSpatialConvention.cs
@@ -3,7 +3,6 @@
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.DependencyInjection;
using Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-using Swashbuckle.AspNetCore.SwaggerGen;
namespace Rocket.Surgery.LaunchPad.AspNetCore.Conventions;
@@ -18,6 +17,6 @@ public class AspNetCoreSpatialConvention : IServiceConvention
///
public void Register(IConventionContext context, IConfiguration configuration, IServiceCollection services)
{
- services.Configure(o => o.ConfigureForNetTopologySuite());
+// services.Configure(o => o.ConfigureForNetTopologySuite());
}
}
diff --git a/src/AspNetCore.Spatial/OpenApi/NetTopologySuiteSwashbuckleExtensions.cs b/src/AspNetCore.Spatial/OpenApi/NetTopologySuiteSwashbuckleExtensions.cs
index 74556cf28..edd912e2f 100644
--- a/src/AspNetCore.Spatial/OpenApi/NetTopologySuiteSwashbuckleExtensions.cs
+++ b/src/AspNetCore.Spatial/OpenApi/NetTopologySuiteSwashbuckleExtensions.cs
@@ -1,466 +1,465 @@
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Interfaces;
-using Microsoft.OpenApi.Models;
-using NetTopologySuite.Features;
-using NetTopologySuite.Geometries;
-using Swashbuckle.AspNetCore.SwaggerGen;
-
-namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-
-[ExcludeFromCodeCoverage]
-internal static class NetTopologySuiteSwashbuckleExtensions
-{
- public static SwaggerGenOptions ConfigureForNetTopologySuite(this SwaggerGenOptions c)
- {
- c.DocumentFilter();
- c.MapType(
- () => new OpenApiSchema
- {
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("http://geojson.org/geojson-spec.html#geometry-objects"),
- },
- Type = "object",
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(Geometry).FullName)
- },
- Description = "GeoJSon geometry",
- Discriminator = new OpenApiDiscriminator
- {
- PropertyName = "type",
- },
- Required = new HashSet { "type" },
- Properties = new Dictionary
- {
- ["type"] = new()
- {
- Type = "string",
- Enum = new List
- {
- new OpenApiString("Point"),
- new OpenApiString("LineString"),
- new OpenApiString("Polygon"),
- new OpenApiString("MultiPoint"),
- new OpenApiString("MultiLineString"),
- new OpenApiString("MultiPolygon"),
- },
- Description = "the geometry type"
- }
- }
- }
- );
-
- c.MapType(
- () => new OpenApiSchema
- {
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("http://geojson.org/geojson-spec.html#id2"),
- },
- Type = "object",
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(Point).FullName)
- },
- Description = "GeoJSon geometry",
- AllOf = new List
- {
- new()
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Geometry",
- }
- },
- new()
- {
- Properties = new Dictionary
- {
- ["coordinates"] = new()
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Point3D"
- }
- }
- }
- }
- },
- }
- );
- c.MapType(
- () => new OpenApiSchema
- {
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("http://geojson.org/geojson-spec.html#id3"),
- },
- Type = "object",
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(LineString).FullName)
- },
- Description = "GeoJSon geometry",
- AllOf = new List
- {
- new()
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Geometry",
- }
- },
- new()
- {
- Properties = new Dictionary
- {
- ["coordinates"] = new()
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Point3D"
- }
- }
- }
- }
- }
- },
- }
- );
- c.MapType(
- () => new OpenApiSchema
- {
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("http://geojson.org/geojson-spec.html#id4"),
- },
- Type = "object",
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(Polygon).FullName)
- },
- Description = "GeoJSon geometry",
- AllOf = new List
- {
- new()
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Geometry",
- }
- },
- new()
- {
- Properties = new Dictionary
- {
- ["coordinates"] = new()
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Point3D"
- }
- }
- }
- }
- }
- }
- },
- }
- );
- c.MapType(
- () => new OpenApiSchema
- {
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("http://geojson.org/geojson-spec.html#id4"),
- },
- Type = "object",
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(MultiPoint).FullName)
- },
- Description = "GeoJSon geometry",
- AllOf = new List
- {
- new()
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Geometry",
- }
- },
- new()
- {
- Properties = new Dictionary
- {
- ["coordinates"] = new()
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Point3D"
- }
- }
- }
- }
- }
- },
- }
- );
- c.MapType(
- () => new OpenApiSchema
- {
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("http://geojson.org/geojson-spec.html#id5"),
- },
- Type = "object",
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(MultiLineString).FullName)
- },
- Description = "GeoJSon geometry",
- AllOf = new List
- {
- new()
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Geometry",
- }
- },
- new()
- {
- Properties = new Dictionary
- {
- ["coordinates"] = new()
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Point3D"
- }
- }
- }
- }
- }
- }
- },
- }
- );
- c.MapType(
- () => new OpenApiSchema
- {
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("http://geojson.org/geojson-spec.html#id6"),
- },
- Type = "object",
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(MultiPolygon).FullName)
- },
- Description = "GeoJSon geometry",
- AllOf = new List
- {
- new()
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Geometry",
- }
- },
- new()
- {
- Properties = new Dictionary
- {
- ["coordinates"] = new()
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Point3D"
- }
- }
- }
- }
- }
- }
- }
- },
- }
- );
- c.MapType(
- () => new OpenApiSchema
- {
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("http://geojson.org/geojson-spec.html#geometrycollection"),
- },
- Type = "object",
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(GeometryCollection).FullName)
- },
- Required = new HashSet { "type", "geometries" },
- Description = "GeoJSon geometry collection",
- Properties = new Dictionary
- {
- ["type"] = new()
- {
- Type = "string",
- Enum = new List { new OpenApiString("GeometryCollection") },
- },
- ["geometries"] = new()
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Geometry"
- }
- }
- }
- }
- }
- );
-
- c.MapType(
- () => new OpenApiSchema
- {
- Type = "object",
- Description = "GeoJSon Feature",
- Required = new HashSet { "type", "id", "geometry" },
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("https://tools.ietf.org/html/rfc7946#section-3.2")
- },
- Properties = new Dictionary
- {
- ["type"] = new()
- {
- Type = "string",
- Enum = new List { new OpenApiString("Feature") }
- },
- ["id"] = new()
- {
- Type = "integer",
- },
- ["geometry"] = new()
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "GeometryCollection",
- }
- },
- ["properties"] = new()
- {
- Type = "object"
- }
- }
- }
- );
-
- c.MapType(
- () => new OpenApiSchema
- {
- Type = "object",
- Description = "GeoJSon Feature collection",
- Required = new HashSet { "type", "features" },
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("https://tools.ietf.org/html/rfc7946#section-3.2")
- },
- Properties = new Dictionary
- {
- ["type"] = new()
- {
- Type = "string",
- Enum = new List { new OpenApiString("FeatureCollection") }
- },
- ["features"] = new()
- {
- Type = "array",
- Items = new OpenApiSchema
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.Schema,
- Id = "Feature"
- }
- }
- }
- }
- }
- );
-
-
- return c;
- }
-
- private class DocumentFilter : IDocumentFilter
- {
- public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
- {
- swaggerDoc.Components.Schemas.Add(
- "Point3D",
- new OpenApiSchema
- {
- Type = "array",
- Description = "Point in 3D space",
- ExternalDocs = new OpenApiExternalDocs
- {
- Url = new Uri("http://geojson.org/geojson-spec.html#id2")
- },
- MinItems = 2,
- MaxItems = 3,
- Items = new OpenApiSchema
- {
- Type = "number"
- }
- }
- );
- }
- }
-}
+//using Microsoft.Extensions.DependencyInjection;
+//using Microsoft.OpenApi.Any;
+//using Microsoft.OpenApi.Interfaces;
+//using Microsoft.OpenApi.Models;
+//using NetTopologySuite.Features;
+//using NetTopologySuite.Geometries;
+//
+//namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
+//
+//[ExcludeFromCodeCoverage]
+//internal static class NetTopologySuiteSwashbuckleExtensions
+//{
+// public static SwaggerGenOptions ConfigureForNetTopologySuite(this SwaggerGenOptions c)
+// {
+// c.DocumentFilter();
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("http://geojson.org/geojson-spec.html#geometry-objects"),
+// },
+// Type = "object",
+// Extensions = new Dictionary
+// {
+// ["clrType"] = new OpenApiString(typeof(Geometry).FullName)
+// },
+// Description = "GeoJSon geometry",
+// Discriminator = new OpenApiDiscriminator
+// {
+// PropertyName = "type",
+// },
+// Required = new HashSet { "type" },
+// Properties = new Dictionary
+// {
+// ["type"] = new()
+// {
+// Type = "string",
+// Enum = new List
+// {
+// new OpenApiString("Point"),
+// new OpenApiString("LineString"),
+// new OpenApiString("Polygon"),
+// new OpenApiString("MultiPoint"),
+// new OpenApiString("MultiLineString"),
+// new OpenApiString("MultiPolygon"),
+// },
+// Description = "the geometry type"
+// }
+// }
+// }
+// );
+//
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("http://geojson.org/geojson-spec.html#id2"),
+// },
+// Type = "object",
+// Extensions = new Dictionary
+// {
+// ["clrType"] = new OpenApiString(typeof(Point).FullName)
+// },
+// Description = "GeoJSon geometry",
+// AllOf = new List
+// {
+// new()
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Geometry",
+// }
+// },
+// new()
+// {
+// Properties = new Dictionary
+// {
+// ["coordinates"] = new()
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Point3D"
+// }
+// }
+// }
+// }
+// },
+// }
+// );
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("http://geojson.org/geojson-spec.html#id3"),
+// },
+// Type = "object",
+// Extensions = new Dictionary
+// {
+// ["clrType"] = new OpenApiString(typeof(LineString).FullName)
+// },
+// Description = "GeoJSon geometry",
+// AllOf = new List
+// {
+// new()
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Geometry",
+// }
+// },
+// new()
+// {
+// Properties = new Dictionary
+// {
+// ["coordinates"] = new()
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Point3D"
+// }
+// }
+// }
+// }
+// }
+// },
+// }
+// );
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("http://geojson.org/geojson-spec.html#id4"),
+// },
+// Type = "object",
+// Extensions = new Dictionary
+// {
+// ["clrType"] = new OpenApiString(typeof(Polygon).FullName)
+// },
+// Description = "GeoJSon geometry",
+// AllOf = new List
+// {
+// new()
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Geometry",
+// }
+// },
+// new()
+// {
+// Properties = new Dictionary
+// {
+// ["coordinates"] = new()
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Point3D"
+// }
+// }
+// }
+// }
+// }
+// }
+// },
+// }
+// );
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("http://geojson.org/geojson-spec.html#id4"),
+// },
+// Type = "object",
+// Extensions = new Dictionary
+// {
+// ["clrType"] = new OpenApiString(typeof(MultiPoint).FullName)
+// },
+// Description = "GeoJSon geometry",
+// AllOf = new List
+// {
+// new()
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Geometry",
+// }
+// },
+// new()
+// {
+// Properties = new Dictionary
+// {
+// ["coordinates"] = new()
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Point3D"
+// }
+// }
+// }
+// }
+// }
+// },
+// }
+// );
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("http://geojson.org/geojson-spec.html#id5"),
+// },
+// Type = "object",
+// Extensions = new Dictionary
+// {
+// ["clrType"] = new OpenApiString(typeof(MultiLineString).FullName)
+// },
+// Description = "GeoJSon geometry",
+// AllOf = new List
+// {
+// new()
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Geometry",
+// }
+// },
+// new()
+// {
+// Properties = new Dictionary
+// {
+// ["coordinates"] = new()
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Point3D"
+// }
+// }
+// }
+// }
+// }
+// }
+// },
+// }
+// );
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("http://geojson.org/geojson-spec.html#id6"),
+// },
+// Type = "object",
+// Extensions = new Dictionary
+// {
+// ["clrType"] = new OpenApiString(typeof(MultiPolygon).FullName)
+// },
+// Description = "GeoJSon geometry",
+// AllOf = new List
+// {
+// new()
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Geometry",
+// }
+// },
+// new()
+// {
+// Properties = new Dictionary
+// {
+// ["coordinates"] = new()
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Point3D"
+// }
+// }
+// }
+// }
+// }
+// }
+// }
+// },
+// }
+// );
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("http://geojson.org/geojson-spec.html#geometrycollection"),
+// },
+// Type = "object",
+// Extensions = new Dictionary
+// {
+// ["clrType"] = new OpenApiString(typeof(GeometryCollection).FullName)
+// },
+// Required = new HashSet { "type", "geometries" },
+// Description = "GeoJSon geometry collection",
+// Properties = new Dictionary
+// {
+// ["type"] = new()
+// {
+// Type = "string",
+// Enum = new List { new OpenApiString("GeometryCollection") },
+// },
+// ["geometries"] = new()
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Geometry"
+// }
+// }
+// }
+// }
+// }
+// );
+//
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// Type = "object",
+// Description = "GeoJSon Feature",
+// Required = new HashSet { "type", "id", "geometry" },
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("https://tools.ietf.org/html/rfc7946#section-3.2")
+// },
+// Properties = new Dictionary
+// {
+// ["type"] = new()
+// {
+// Type = "string",
+// Enum = new List { new OpenApiString("Feature") }
+// },
+// ["id"] = new()
+// {
+// Type = "integer",
+// },
+// ["geometry"] = new()
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "GeometryCollection",
+// }
+// },
+// ["properties"] = new()
+// {
+// Type = "object"
+// }
+// }
+// }
+// );
+//
+// c.MapType(
+// () => new OpenApiSchema
+// {
+// Type = "object",
+// Description = "GeoJSon Feature collection",
+// Required = new HashSet { "type", "features" },
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("https://tools.ietf.org/html/rfc7946#section-3.2")
+// },
+// Properties = new Dictionary
+// {
+// ["type"] = new()
+// {
+// Type = "string",
+// Enum = new List { new OpenApiString("FeatureCollection") }
+// },
+// ["features"] = new()
+// {
+// Type = "array",
+// Items = new OpenApiSchema
+// {
+// Reference = new OpenApiReference
+// {
+// Type = ReferenceType.Schema,
+// Id = "Feature"
+// }
+// }
+// }
+// }
+// }
+// );
+//
+//
+// return c;
+// }
+//
+// private class DocumentFilter : IDocumentFilter
+// {
+// public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
+// {
+// swaggerDoc.Components.Schemas.Add(
+// "Point3D",
+// new OpenApiSchema
+// {
+// Type = "array",
+// Description = "Point in 3D space",
+// ExternalDocs = new OpenApiExternalDocs
+// {
+// Url = new Uri("http://geojson.org/geojson-spec.html#id2")
+// },
+// MinItems = 2,
+// MaxItems = 3,
+// Items = new OpenApiSchema
+// {
+// Type = "number"
+// }
+// }
+// );
+// }
+// }
+//}
diff --git a/src/AspNetCore.Spatial/Rocket.Surgery.LaunchPad.AspNetCore.Spatial.csproj b/src/AspNetCore.Spatial/Rocket.Surgery.LaunchPad.AspNetCore.Spatial.csproj
index 058372507..c48a91fcb 100644
--- a/src/AspNetCore.Spatial/Rocket.Surgery.LaunchPad.AspNetCore.Spatial.csproj
+++ b/src/AspNetCore.Spatial/Rocket.Surgery.LaunchPad.AspNetCore.Spatial.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net9.0
$(PackageTags)
Rocket.Surgery.LaunchPad.AspNetCore
diff --git a/src/AspNetCore.Testing/LaunchPadExtension.cs b/src/AspNetCore.Testing/LaunchPadExtension.cs
index 2f1a7e0ab..1b8b6f5cc 100644
--- a/src/AspNetCore.Testing/LaunchPadExtension.cs
+++ b/src/AspNetCore.Testing/LaunchPadExtension.cs
@@ -5,6 +5,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
+using Rocket.Surgery.Conventions;
namespace Rocket.Surgery.LaunchPad.AspNetCore.Testing;
@@ -62,4 +63,4 @@ public virtual IHostBuilder Configure(IHostBuilder builder)
}
}
#pragma warning restore CA1816
-#pragma warning restore CA1063
\ No newline at end of file
+#pragma warning restore CA1063
diff --git a/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs b/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs
index 992007de5..de0c3a61d 100644
--- a/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs
+++ b/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs
@@ -41,7 +41,8 @@ protected LaunchPadWebAppFixture(params IAlbaExtension[] extensions)
///
public async Task InitializeAsync()
{
- _host = await Alba.AlbaHost.For(_extensions);
+ _host = await Alba.AlbaHost.For([.._extensions]);
+ await ResetAsync();
}
///
@@ -191,4 +192,4 @@ public bool IsEnabled(LogLevel logLevel)
return _logger?.BeginScope(state);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/AspNetCore.Testing/Rocket.Surgery.LaunchPad.AspNetCore.Testing.csproj b/src/AspNetCore.Testing/Rocket.Surgery.LaunchPad.AspNetCore.Testing.csproj
index 1d572900d..8e7f447b5 100644
--- a/src/AspNetCore.Testing/Rocket.Surgery.LaunchPad.AspNetCore.Testing.csproj
+++ b/src/AspNetCore.Testing/Rocket.Surgery.LaunchPad.AspNetCore.Testing.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net9.0
$(PackageTags)
@@ -15,8 +15,8 @@
-
-
-
+
+
+
diff --git a/src/AspNetCore/Composition/IRestfulApiMethodMatcher.cs b/src/AspNetCore/Composition/IRestfulApiMethodMatcher.cs
index 0f752e897..a42f15528 100644
--- a/src/AspNetCore/Composition/IRestfulApiMethodMatcher.cs
+++ b/src/AspNetCore/Composition/IRestfulApiMethodMatcher.cs
@@ -10,6 +10,5 @@ internal interface IRestfulApiMethodMatcher
string[] Names { get; }
IDictionary Parameters { get; }
- [RequiresUnreferencedCode("DynamicBehavior is incompatible with trimming.")]
bool IsMatch(ActionModel actionModel);
}
diff --git a/src/AspNetCore/Composition/RestfulApiActionModelConvention.cs b/src/AspNetCore/Composition/RestfulApiActionModelConvention.cs
index 4dc2e008e..1337d16eb 100644
--- a/src/AspNetCore/Composition/RestfulApiActionModelConvention.cs
+++ b/src/AspNetCore/Composition/RestfulApiActionModelConvention.cs
@@ -6,14 +6,14 @@
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Routing;
+using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Rocket.Surgery.LaunchPad.AspNetCore.Validation;
-using Swashbuckle.AspNetCore.SwaggerGen;
namespace Rocket.Surgery.LaunchPad.AspNetCore.Composition;
-internal class RestfulApiActionModelConvention : IActionModelConvention, ISchemaFilter
+internal class RestfulApiActionModelConvention : IActionModelConvention, IOpenApiSchemaTransformer
{
private static string? GetHttpMethod(ActionModel action)
{
@@ -157,7 +157,7 @@ ActionModel actionModel
}
// TODO: Make a source generator for this to work without generics
- [RequiresUnreferencedCode("DynamicBehavior is incompatible with trimming.")]
+ [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")]
public void Apply(ActionModel action)
{
if (!typeof(RestfulApiController).IsAssignableFrom(action.Controller.ControllerType)) return;
@@ -170,14 +170,18 @@ public void Apply(ActionModel action)
ExtractParameterDetails(action);
}
- public void Apply(OpenApiSchema schema, SchemaFilterContext context)
+ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext context, CancellationToken cancellationToken)
{
- if (_propertiesToHideFromOpenApi.TryGetValue(context.Type, out var propertiesToRemove))
- foreach (var property in propertiesToRemove
- .Join(schema.Properties, z => z, z => z.Key, (_, b) => b.Key, StringComparer.OrdinalIgnoreCase)
- .ToArray())
- {
- schema.Properties.Remove(property);
- }
+ if (!_propertiesToHideFromOpenApi.TryGetValue(context.JsonTypeInfo.Type, out var propertiesToRemove)) return Task.CompletedTask;
+
+ foreach (var property in propertiesToRemove
+ .Join(schema.Properties, z => z, z => z.Key, (_, b) => b.Key, StringComparer.OrdinalIgnoreCase)
+ .ToArray()
+ )
+ {
+ schema.Properties.Remove(property);
+ }
+
+ return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/src/AspNetCore/Conventions/AspNetCoreConvention.cs b/src/AspNetCore/Conventions/AspNetCoreConvention.cs
index 16163ebdc..ca424bc6e 100644
--- a/src/AspNetCore/Conventions/AspNetCoreConvention.cs
+++ b/src/AspNetCore/Conventions/AspNetCoreConvention.cs
@@ -108,7 +108,7 @@ public void Register(IConventionContext context, IConfiguration configuration, I
// ReSharper disable once NullableWarningSuppressionIsUsed
GetServiceFromCollection(services)!,
context
- .AssemblyProvider.GetAssemblies(s => s.FromAssemblyDependenciesOf(typeof(AspNetCoreConvention)))
+ .TypeProvider.GetAssemblies(s => s.FromAssemblyDependenciesOf(typeof(AspNetCoreConvention)))
.Where(_options.AssemblyPartFilter)
.SelectMany(GetApplicationPartAssemblies)
);
diff --git a/src/AspNetCore/Conventions/FluentValidationConvention.cs b/src/AspNetCore/Conventions/FluentValidationConvention.cs
index 2b8f1a4f9..abc3b839b 100644
--- a/src/AspNetCore/Conventions/FluentValidationConvention.cs
+++ b/src/AspNetCore/Conventions/FluentValidationConvention.cs
@@ -1,17 +1,10 @@
-using System.Reflection;
-using FluentValidation.AspNetCore;
-using FluentValidation.Validators;
-using MicroElements.OpenApi.FluentValidation;
-using MicroElements.Swashbuckle.FluentValidation;
+using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.OpenApi.Any;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.DependencyInjection;
-using Rocket.Surgery.Extensions;
using Rocket.Surgery.LaunchPad.AspNetCore.Validation;
-using Rocket.Surgery.LaunchPad.Foundation.Validation;
using MvcJsonOptions = Microsoft.AspNetCore.Mvc.JsonOptions;
using HttpJsonOptions = Microsoft.AspNetCore.Http.Json.JsonOptions;
@@ -29,95 +22,6 @@ namespace Rocket.Surgery.LaunchPad.AspNetCore.Conventions;
[ConventionCategory(ConventionCategory.Application)]
public partial class FluentValidationConvention : IServiceConvention
{
- private static void AddFluentValidationRules(IServiceCollection services)
- {
- services.AddSingleton(
- new FluentValidationRule("NotEmpty")
- .WithCondition(propertyValidator => propertyValidator is INotEmptyValidator)
- .WithApply(
- context =>
- {
- var ruleContext = ( (ValidationRuleContext)context
- .GetType()
- .GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)
- .First(z => z.PropertyType == typeof(ValidationRuleContext))
- .GetValue(context)! )
- .GetReflectionContext();
- var propertyType = ruleContext?.PropertyInfo?.DeclaringType;
- if (propertyType == typeof(string))
- {
- ( context.Schema.Properties[context.PropertyKey] ??= new() ).MinLength = 1;
- }
- }
- )
- );
-
- services.AddSingleton(
- new FluentValidationRule("ValueTypeOrEnum")
- .WithApply(
- context =>
- {
- var ruleContext = ( (ValidationRuleContext)context
- .GetType()
- .GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)
- .First(z => z.PropertyType == typeof(ValidationRuleContext))
- .GetValue(context)! )
- .GetReflectionContext();
- var propertyType = ruleContext?.PropertyInfo?.DeclaringType;
- if (propertyType != null && ( ( propertyType.IsValueType && Nullable.GetUnderlyingType(propertyType) == null ) || propertyType.IsEnum ))
- {
- context.Schema.Required.Add(context.PropertyKey);
- ( context.Schema.Properties[context.PropertyKey] ??= new() ).Nullable = false;
- }
- }
- )
- );
-
- services.AddSingleton(
- new FluentValidationRule("Nullable")
- .WithApply(
- context =>
- {
- var ruleContext = ( (ValidationRuleContext)context
- .GetType()
- .GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)
- .First(z => z.PropertyType == typeof(ValidationRuleContext))
- .GetValue(context)! )
- .GetReflectionContext();
- ( context.Schema.Properties[context.PropertyKey] ??= new() ).Nullable =
- context.PropertyValidator is not (INotNullValidator or INotEmptyValidator)
- || ( ruleContext is { PropertyInfo: FieldInfo fi, } && getNullableValue(fi.GetNullability(), fi.FieldType) )
- ;
-
- static bool getNullableValue(Nullability nullability, Type propertyType)
- {
- return nullability switch
- {
- Nullability.Nullable => true,
- Nullability.NonNullable => false,
- Nullability.NotDefined => !propertyType.IsValueType || Nullable.GetUnderlyingType(propertyType) is { },
- _ => false,
- };
- }
- }
- )
- );
-
- services.AddSingleton(
- new FluentValidationRule("IsOneOf")
- .WithCondition(propertyValidator => propertyValidator is IStringInValidator)
- .WithApply(
- context =>
- {
- var validator = context.PropertyValidator as IStringInValidator;
- ( context.Schema.Properties[context.PropertyKey] ??= new() ).Enum =
- // ReSharper disable once NullableWarningSuppressionIsUsed
- validator!.Values.Select(x => new OpenApiString(x)).Cast().ToList();
- }
- )
- );
- }
-
///
/// Registers the specified context.
///
@@ -129,7 +33,7 @@ public void Register(IConventionContext context, IConfiguration configuration, I
services.AddFluentValidationClientsideAdapters();
services
.Configure(mvcOptions => mvcOptions.Filters.Insert(0, new ValidationExceptionFilter()))
- .Configure(options => options.JsonSerializerOptions.Converters.Add(new ValidationProblemDetailsConverter()))
+ .Configure(options => options.JsonSerializerOptions.Converters.Add(new ValidationProblemDetailsConverter ()))
.Configure(options => options.SerializerOptions.Converters.Add(new ValidationProblemDetailsConverter()));
// AddFluentValidationRules(services);
diff --git a/src/AspNetCore/Conventions/OpenApiConvention.cs b/src/AspNetCore/Conventions/OpenApiConvention.cs
new file mode 100644
index 000000000..3432a6dd6
--- /dev/null
+++ b/src/AspNetCore/Conventions/OpenApiConvention.cs
@@ -0,0 +1,73 @@
+using System.Text;
+using System.Text.Json;
+using FluentValidation;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.OpenApi;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Microsoft.OpenApi.Models;
+using Rocket.Surgery.Conventions;
+using Rocket.Surgery.Conventions.DependencyInjection;
+using Rocket.Surgery.LaunchPad.AspNetCore.Composition;
+using Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+using Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
+
+namespace Rocket.Surgery.LaunchPad.AspNetCore.Conventions;
+
+///
+/// ValidationConvention.
+/// Implements the
+///
+///
+///
+[PublicAPI]
+[ExportConvention]
+[AfterConvention(typeof(AspNetCoreConvention))]
+[ConventionCategory(ConventionCategory.Application)]
+public partial class OpenApiConvention : IServiceConvention
+{
+ [LoggerMessage(
+ EventId = 0,
+ Level = LogLevel.Debug,
+ Message = "Error adding XML comments from {XmlFile}"
+ )]
+ internal static partial void ErrorAddingXMLComments(ILogger logger, Exception exception, string xmlFile);
+
+ ///
+ /// Registers the specified context.
+ ///
+ /// The context.
+ ///
+ ///
+ public void Register(IConventionContext context, IConfiguration configuration, IServiceCollection services)
+ {
+ ArgumentNullException.ThrowIfNull(context);
+
+ services.AddOpenApi(
+ options =>
+ {
+ options.AddSchemaTransformer();
+ options.AddSchemaTransformer();
+ options.AddSchemaTransformer();
+ options.AddSchemaTransformer();
+ options.AddOperationTransformer();
+ options.AddOperationTransformer();
+ options.AddOperationTransformer();
+ options.AddOperationTransformer();
+
+ });
+ services.AddFluentValidationOpenApi();
+ }
+}
+
+internal class NestedTypeSchemaFilter : IOpenApiSchemaTransformer
+{
+ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext context, CancellationToken cancellationToken)
+ {
+ if (context is not { JsonTypeInfo.Type.DeclaringType: {} }) return Task.CompletedTask;
+ schema.Annotations["x-schema-id"] = $"{context.JsonTypeInfo.Type.DeclaringType.Name}{context.JsonTypeInfo.Type.Name}";
+ return Task.CompletedTask;
+ }
+}
diff --git a/src/AspNetCore/Conventions/ProblemDetailsConvention.cs b/src/AspNetCore/Conventions/ProblemDetailsConvention.cs
index b94437753..36d07629d 100644
--- a/src/AspNetCore/Conventions/ProblemDetailsConvention.cs
+++ b/src/AspNetCore/Conventions/ProblemDetailsConvention.cs
@@ -1,17 +1,15 @@
using FluentValidation;
using FluentValidation.Results;
-using Hellang.Middleware.ProblemDetails;
-using Hellang.Middleware.ProblemDetails.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.DependencyInjection;
using Rocket.Surgery.LaunchPad.AspNetCore.Validation;
using Rocket.Surgery.LaunchPad.Foundation;
-using ProblemDetailsOptions = Hellang.Middleware.ProblemDetails.ProblemDetailsOptions;
namespace Rocket.Surgery.LaunchPad.AspNetCore.Conventions;
@@ -30,57 +28,88 @@ public class ProblemDetailsConvention : IServiceConvention
///
public void Register(IConventionContext context, IConfiguration configuration, IServiceCollection services)
{
- ProblemDetailsExtensions
- .AddProblemDetails(services)
- .AddProblemDetailsConventions();
+ services.AddProblemDetails();
+ services.AddExceptionHandler(
+ options =>
+ {
+ var old = options.StatusCodeSelector;
+ options.StatusCodeSelector = (exception) => exception switch
+ {
+ NotFoundException => StatusCodes.Status404NotFound,
+ RequestFailedException => StatusCodes.Status400BadRequest,
+ NotAuthorizedException => StatusCodes.Status403Forbidden,
+ ValidationException => StatusCodes.Status422UnprocessableEntity,
+ _ => old?.Invoke(exception) ?? StatusCodes.Status500InternalServerError,
+ };
+ }
+ );
+ services.TryAddEnumerable(ServiceDescriptor.Singleton());
+ services.TryAddEnumerable(ServiceDescriptor.Singleton());
+ services.TryAddEnumerable(ServiceDescriptor.Singleton());
services
.AddOptions()
.Configure(static options => options.SuppressModelStateInvalidFilter = true);
- services
- .AddOptions()
- .Configure>(
- static (builder, apiBehaviorOptions) =>
- {
- var currentIncludeExceptionDetails = builder.IncludeExceptionDetails;
- builder.IncludeExceptionDetails = (httpContext, exception) =>
- exception is not IProblemDetailsData && currentIncludeExceptionDetails(httpContext, exception);
- builder.OnBeforeWriteDetails = (_, problemDetails) =>
- {
- if (
- !problemDetails.Status.HasValue
- || !apiBehaviorOptions.Value.ClientErrorMapping.TryGetValue(
- problemDetails.Status.Value,
- out var clientErrorData
- )
- )
- return;
+ }
+}
+
+class OnBeforeWriteProblemDetailsWriter(IOptions apiBehaviorOptions) : IProblemDetailsWriter
+{
+ public ValueTask WriteAsync(ProblemDetailsContext context) => throw new NotImplementedException();
+
+ public bool CanWrite(ProblemDetailsContext context)
+ {
+ if (!context.ProblemDetails.Status.HasValue
+ || !apiBehaviorOptions.Value.ClientErrorMapping.TryGetValue(context.ProblemDetails.Status.Value, out var clientErrorData))
+ return false;
+
+ context.ProblemDetails.Title ??= clientErrorData.Title;
+ context.ProblemDetails.Type ??= clientErrorData.Link;
+ return false;
+ }
+}
+
+class FluentValidationProblemDetailsWriter(IOptions apiBehaviorOptions) : IProblemDetailsWriter
+{
+ public ValueTask WriteAsync(ProblemDetailsContext context)
+ {
+ if (context is not { Exception: IProblemDetailsData details }
+ || context.HttpContext.Items[typeof(ValidationResult)] is not ValidationResult validationResult) return ValueTask.CompletedTask;
+
+ context.ProblemDetails = new FluentValidationProblemDetails(validationResult.Errors)
+ {
+ Status = StatusCodes.Status422UnprocessableEntity,
+ Title = details.Title ?? context.ProblemDetails.Title,
+ Type = details.Link ?? context.ProblemDetails.Type,
+ Detail = context.ProblemDetails.Detail,
+ Instance = details.Instance ?? context.ProblemDetails.Instance,
+ Extensions = context.ProblemDetails.Extensions,
+ };
+ return ValueTask.CompletedTask;
+ }
- problemDetails.Title ??= clientErrorData.Title;
- problemDetails.Type ??= clientErrorData.Link;
- };
-// builder.MapToProblemDetailsDataException(StatusCodes.Status404NotFound);
-// builder.MapToProblemDetailsDataException(StatusCodes.Status400BadRequest);
-// builder.MapToProblemDetailsDataException(StatusCodes.Status403Forbidden);
- builder.Map(
- static exception => new FluentValidationProblemDetails(exception.Errors)
- {
- Status = StatusCodes.Status422UnprocessableEntity,
- }
- );
- builder.Map(
- static (ctx, ex) => ex is not IProblemDetailsData && ctx.Items[typeof(ValidationResult)] is ValidationResult,
- static (ctx, _) =>
- {
- var result = ctx.Items[typeof(ValidationResult)] as ValidationResult;
- // ReSharper disable once NullableWarningSuppressionIsUsed
- return new FluentValidationProblemDetails(result!.Errors)
- {
- Status = StatusCodes.Status422UnprocessableEntity,
- };
- }
- );
- }
- );
+ public bool CanWrite(ProblemDetailsContext context)
+ {
+ return context.Exception is not IProblemDetailsData && context.HttpContext.Items[typeof(ValidationResult)] is ValidationResult;
}
}
+
+class ValidationExceptionProblemDetailsWriter(IOptions apiBehaviorOptions) : IProblemDetailsWriter
+{
+ public ValueTask WriteAsync(ProblemDetailsContext context)
+ {
+ if (context.Exception is not ValidationException validationException) return ValueTask.CompletedTask;
+ context.ProblemDetails = new FluentValidationProblemDetails(validationException.Errors)
+ {
+ Status = StatusCodes.Status422UnprocessableEntity,
+ Title = context.ProblemDetails.Title,
+ Type = context.ProblemDetails.Type,
+ Detail = context.ProblemDetails.Detail,
+ Instance = context.ProblemDetails.Instance,
+ Extensions = context.ProblemDetails.Extensions,
+ };
+ return ValueTask.CompletedTask;
+ }
+
+ public bool CanWrite(ProblemDetailsContext context) => context.Exception is ValidationException;
+}
diff --git a/src/AspNetCore/Conventions/ProblemDetailsOptionsExtensions.cs b/src/AspNetCore/Conventions/ProblemDetailsOptionsExtensions.cs
deleted file mode 100644
index 12f7b1990..000000000
--- a/src/AspNetCore/Conventions/ProblemDetailsOptionsExtensions.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using Hellang.Middleware.ProblemDetails;
-using Microsoft.AspNetCore.Mvc;
-using Rocket.Surgery.LaunchPad.Foundation;
-
-namespace Rocket.Surgery.LaunchPad.AspNetCore.Conventions;
-
-///
-/// Extensions to ProblemDetailsOptions
-///
-public static class ProblemDetailsOptionsExtensions
-{
- ///
- /// Creates a mapping for an exception that implements with the given status code
- ///
- ///
- ///
- ///
- public static void MapToProblemDetailsDataException(this ProblemDetailsOptions options, int statusCode)
- where TException : Exception, IProblemDetailsData
- {
- options.Map((_, ex) => ConstructProblemDetails(ex, statusCode));
- }
-
- private static ProblemDetails ConstructProblemDetails(TException ex, int statusCode) where TException : Exception, IProblemDetailsData
- {
- var details = new ProblemDetails
- {
- Detail = ex.Message,
- Title = ex.Title,
- Type = ex.Link,
- Instance = ex.Instance,
- Status = statusCode
- };
- foreach (var item in ex.Properties)
- {
- if (details.Extensions.ContainsKey(item.Key)) continue;
- details.Extensions.Add(item);
- }
-
- return details;
- }
-}
diff --git a/src/AspNetCore/Conventions/SwashbuckleConvention.cs b/src/AspNetCore/Conventions/SwashbuckleConvention.cs
deleted file mode 100644
index 22319a353..000000000
--- a/src/AspNetCore/Conventions/SwashbuckleConvention.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-using System.Text;
-using System.Text.Json;
-using FluentValidation;
-using MicroElements.Swashbuckle.FluentValidation.AspNetCore;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Rocket.Surgery.Conventions;
-using Rocket.Surgery.Conventions.DependencyInjection;
-using Rocket.Surgery.LaunchPad.AspNetCore.Composition;
-using Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-using Swashbuckle.AspNetCore.SwaggerGen;
-
-namespace Rocket.Surgery.LaunchPad.AspNetCore.Conventions;
-
-///
-/// ValidationConvention.
-/// Implements the
-///
-///
-///
-[PublicAPI]
-[ExportConvention]
-[AfterConvention(typeof(AspNetCoreConvention))]
-[ConventionCategory(ConventionCategory.Application)]
-public partial class SwashbuckleConvention : IServiceConvention
-{
- [LoggerMessage(
- EventId = 0,
- Level = LogLevel.Debug,
- Message = "Error adding XML comments from {XmlFile}"
- )]
- internal static partial void ErrorAddingXMLComments(ILogger logger, Exception exception, string xmlFile);
-
- ///
- /// Registers the specified context.
- ///
- /// The context.
- ///
- ///
- public void Register(IConventionContext context, IConfiguration configuration, IServiceCollection services)
- {
- ArgumentNullException.ThrowIfNull(context);
-
- services.ConfigureOptions();
-
- services.AddFluentValidationRulesToSwagger(
- options => options.SetNotNullableIfMinLengthGreaterThenZero = true,
- options => options.ServiceLifetime = ServiceLifetime.Singleton
- );
-
-// services.TryAddEnumerable(ServiceDescriptor.Transient());
-
- services
- .AddOptions()
- .Configure>(
- (options, mvcOptions) => options.ConfigureForNodaTime(mvcOptions.Value.JsonSerializerOptions)
- );
- services.AddSwaggerGen(
- options =>
- {
- options.SchemaFilter();
- options.SchemaFilter();
- options.SchemaFilter();
- options.OperationFilter();
- options.OperationFilter();
- options.OperationFilter();
- options.OperationFilter();
-
- options.MapType(
- () => new()
- {
- Type = "object",
- AdditionalPropertiesAllowed = true,
- }
- );
- options.MapType(
- () => new()
- {
- Type = "object",
- AdditionalPropertiesAllowed = true,
- Nullable = true,
- }
- );
-
- options.DocInclusionPredicate(
- (_, apiDesc) =>
- {
- if (!apiDesc.TryGetMethodInfo(out var methodInfo))
- return false;
- return methodInfo.DeclaringType?.GetCustomAttributes(true).OfType().Any() == true;
- }
- );
-
- string nestedTypeName(Type type)
- {
- // ReSharper disable once NullableWarningSuppressionIsUsed
- return type.IsNested ? schemaIdSelector(type.DeclaringType!) + type.Name : type.Name;
- }
-
- string schemaIdSelector(Type type)
- {
- if (type == typeof(Severity)) return $"Validation{nameof(Severity)}";
- if (type.IsGenericType)
- {
- var sb = new StringBuilder();
- var name = nestedTypeName(type);
- name = name[..name.IndexOf('`', StringComparison.Ordinal)];
- sb.Append(name);
- foreach (var gt in type.GetGenericArguments())
- {
- sb.Append('_').Append(schemaIdSelector(gt));
- }
-
- return sb.ToString();
- }
-
- return nestedTypeName(type);
- }
-
- options.CustomSchemaIds(schemaIdSelector);
-
- foreach (var item in Directory
- .EnumerateFiles(AppContext.BaseDirectory, "*.xml")
- .Where(x => File.Exists(Path.ChangeExtension(x, "dll"))))
- {
- try
- {
- options.IncludeXmlComments(item, true);
- }
- #pragma warning disable CA1031
- catch (Exception e)
- #pragma warning restore CA1031
- {
- ErrorAddingXMLComments(context.Logger, e, item);
- }
- }
- }
- );
- }
-}
diff --git a/src/AspNetCore/Conventions/SystemJsonTextConvention.cs b/src/AspNetCore/Conventions/SystemJsonTextConvention.cs
index 6bbbf4490..6e2a4e0ee 100644
--- a/src/AspNetCore/Conventions/SystemJsonTextConvention.cs
+++ b/src/AspNetCore/Conventions/SystemJsonTextConvention.cs
@@ -1,6 +1,7 @@
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.DependencyInjection;
using Rocket.Surgery.LaunchPad.Foundation;
@@ -44,17 +45,9 @@ public void Register(IConventionContext context, IConfiguration configuration, I
services
.AddOptions()
- .Configure(
- (options, provider) => ActivatorUtilities
- .CreateInstance>(provider, options.JsonSerializerOptions)
- .Create(nameof(MvcJsonOptions))
- );
+ .Configure((options, provider) => ExistingValueOptions.Apply(provider, options.JsonSerializerOptions, Options.DefaultName));
services
.AddOptions()
- .Configure(
- (options, provider) => ActivatorUtilities
- .CreateInstance>(provider, options.SerializerOptions)
- .Create(nameof(HttpJsonOptions))
- );
+ .Configure((options, provider) => ExistingValueOptions.Apply(provider, options.SerializerOptions, Options.DefaultName));
}
}
diff --git a/src/AspNetCore/LaunchPadHelpers.cs b/src/AspNetCore/LaunchPadHelpers.cs
index 13aee1ba8..47ee095bc 100644
--- a/src/AspNetCore/LaunchPadHelpers.cs
+++ b/src/AspNetCore/LaunchPadHelpers.cs
@@ -1,4 +1,7 @@
+using System.Text.Json;
+using Humanizer;
using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
using Serilog;
using Serilog.Events;
@@ -7,7 +10,7 @@ namespace Rocket.Surgery.LaunchPad.AspNetCore;
///
/// Helpers for during application startup and in middleware
///
-public static class LaunchPadLogHelpers
+public static class LaunchPadHelpers
{
///
/// Setup the with default values from the request
@@ -62,4 +65,87 @@ private static bool IsHealthCheckEndpoint(HttpContext ctx)
// No endpoint, so not a health check endpoint
return false;
}
-}
\ No newline at end of file
+
+ ///
+ /// The default response writer for health checks
+ ///
+ ///
+ ///
+ ///
+ public static Task DefaultResponseWriter (HttpContext context, HealthReport report)
+ {
+ context.Response.ContentType = "application/json; charset=utf-8";
+
+ var options = new JsonWriterOptions { Indented = true, };
+
+ using var memoryStream = new MemoryStream();
+ using (var jsonWriter = new Utf8JsonWriter(memoryStream, options))
+ {
+ jsonWriter.WriteStartObject();
+ jsonWriter.WriteString("status", report.Status.ToString());
+ jsonWriter.WriteStartObject("results");
+
+ foreach (var healthReportEntry in report.Entries)
+ {
+ jsonWriter.WriteStartObject(healthReportEntry.Key);
+ jsonWriter.WriteString(
+ "status",
+ healthReportEntry.Value.Status.ToString()
+ );
+ jsonWriter.WriteString(
+ "duration",
+ healthReportEntry.Value.Duration.Humanize()
+ );
+ jsonWriter.WriteString(
+ "description",
+ healthReportEntry.Value.Description
+ );
+
+ jsonWriter.WriteStartObject("data");
+ foreach (var item in healthReportEntry.Value.Data)
+ {
+ jsonWriter.WritePropertyName(item.Key);
+
+ JsonSerializer.Serialize(
+ jsonWriter,
+ item.Value,
+ item.Value.GetType()
+ );
+ }
+
+ jsonWriter.WriteEndObject();
+
+ if (healthReportEntry.Value.Tags.Any())
+ {
+ jsonWriter.WriteStartArray("tags");
+ foreach (var item in healthReportEntry.Value.Tags)
+ {
+ jsonWriter.WriteStringValue(item);
+ }
+
+ jsonWriter.WriteEndArray();
+ }
+
+ if (healthReportEntry.Value.Exception != null)
+ {
+ var ex = healthReportEntry.Value.Exception;
+ jsonWriter.WriteStartObject("exception");
+ jsonWriter.WriteString("message", ex.Message);
+ jsonWriter.WriteString("stacktrace", ex.StackTrace);
+ jsonWriter.WriteString("inner", ex.InnerException?.ToString());
+ jsonWriter.WriteEndObject();
+ }
+
+ jsonWriter.WriteEndObject();
+ }
+
+ jsonWriter.WriteEndObject();
+ jsonWriter.WriteEndObject();
+ }
+
+ return context.Response.WriteAsync(
+ System.Text.Encoding.UTF8.GetString(memoryStream.ToArray())
+ );
+
+ }
+}
diff --git a/src/AspNetCore/OpenApi/AuthorizeFilter.cs b/src/AspNetCore/OpenApi/AuthorizeFilter.cs
index 1aed4d4a1..6c50a8386 100644
--- a/src/AspNetCore/OpenApi/AuthorizeFilter.cs
+++ b/src/AspNetCore/OpenApi/AuthorizeFilter.cs
@@ -1,11 +1,11 @@
-using Microsoft.OpenApi.Models;
-using Swashbuckle.AspNetCore.SwaggerGen;
+using Microsoft.AspNetCore.OpenApi;
+using Microsoft.OpenApi.Models;
namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-internal class AuthorizeFilter : IOperationFilter
+internal class AuthorizeFilter : IOpenApiOperationTransformer
{
- public void Apply(OpenApiOperation operation, OperationFilterContext context)
+ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken)
{
// enhance the 401/403 with the media response
if (operation.Responses.TryGetValue("401", out var value))
@@ -29,5 +29,7 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context)
Description = "The error details",
}
);
+
+ return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/src/AspNetCore/OpenApi/NodaTimeSwashbuckleExtensions.cs b/src/AspNetCore/OpenApi/NodaTimeSwashbuckleExtensions.cs
deleted file mode 100644
index 600a56b56..000000000
--- a/src/AspNetCore/OpenApi/NodaTimeSwashbuckleExtensions.cs
+++ /dev/null
@@ -1,167 +0,0 @@
-using System.Text.Json;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Interfaces;
-using Microsoft.OpenApi.Models;
-using NodaTime;
-using Swashbuckle.AspNetCore.SwaggerGen;
-
-namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-
-[ExcludeFromCodeCoverage]
-internal static class NodaTimeSwashbuckleExtensions
-{
- public static SwaggerGenOptions ConfigureForNodaTime(this SwaggerGenOptions c, JsonSerializerOptions settings)
- {
- IEnumerable<(Type type, Func schema)> createStringSchema(
- Type type,
- object value,
- string? format = null
- )
- {
- yield return ( type,
- () => new()
- {
- Type = "string",
- Format = format,
- Example = new OpenApiString(JsonSerializer.Serialize(value, settings).Trim('"')),
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(type.FullName),
- },
- } );
- if (type.IsValueType)
- yield return ( typeof(Nullable<>).MakeGenericType(type),
- () => new()
- {
- Type = "string",
- Format = format,
- Example = new OpenApiString(
- JsonSerializer.Serialize(value, settings).Trim('"')
- ),
- Nullable = true,
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(type.FullName),
- },
- } );
- }
-
- var instant = Instant.FromUnixTimeSeconds(1573000000);
- var interval = new Interval(
- instant,
- instant
- .PlusTicks(TimeSpan.TicksPerDay)
- .PlusTicks(TimeSpan.TicksPerHour)
- .PlusTicks(TimeSpan.TicksPerMinute)
- .PlusTicks(TimeSpan.TicksPerSecond)
- .PlusTicks(TimeSpan.TicksPerMillisecond)
- );
- var dateTimeZone = DateTimeZoneProviders.Tzdb["America/New_York"];
- var zonedDateTime = instant.InZone(dateTimeZone);
- var instantSchemas =
- createStringSchema(typeof(Instant), Instant.FromUnixTimeSeconds(1573000000), "date-time").ToArray();
- var period = Period.Between(
- zonedDateTime.LocalDateTime,
- interval.End.InZone(dateTimeZone).LocalDateTime,
- PeriodUnits.AllUnits
- );
- foreach (( var type, var schema ) in instantSchemas)
- {
- c.MapType(type, schema);
- }
-
- foreach (( var type, var schema ) in createStringSchema(
- typeof(LocalDate),
- LocalDate.FromDateTime(instant.ToDateTimeUtc()),
- "date"
- ))
- {
- c.MapType(type, schema);
- }
-
- foreach (( var type, var schema ) in createStringSchema(
- typeof(LocalTime),
- LocalTime.FromSecondsSinceMidnight(86400 - 12300),
- "time"
- ))
- {
- c.MapType(type, schema);
- }
-
- foreach (( var type, var schema ) in createStringSchema(
- typeof(LocalDateTime),
- LocalDateTime.FromDateTime(instant.ToDateTimeUtc()),
- "date-time"
- ))
- {
- c.MapType(type, schema);
- }
-
- foreach (( var type, var schema ) in createStringSchema(
- typeof(OffsetDateTime),
- OffsetDateTime.FromDateTimeOffset(instant.ToDateTimeOffset()),
- "date-time"
- ))
- {
- c.MapType(type, schema);
- }
-
- foreach (( var type, var schema ) in createStringSchema(typeof(ZonedDateTime), zonedDateTime, "date-time"))
- {
- c.MapType(type, schema);
- }
-
- foreach (( var type, var schema ) in createStringSchema(typeof(Offset), zonedDateTime.Offset))
- {
- c.MapType(type, schema);
- }
-
- foreach (( var type, var schema ) in createStringSchema(typeof(Period), period))
- {
- c.MapType(type, schema);
- }
-
- foreach (( var type, var schema ) in createStringSchema(typeof(Duration), interval.Duration))
- {
- c.MapType(type, schema);
- }
-
- foreach (( var type, var schema ) in createStringSchema(typeof(DateTimeZone), dateTimeZone))
- {
- c.MapType(type, schema);
- }
-
- c.MapType(
- () =>
- {
- var instantSchema = instantSchemas[0].schema();
- return new()
- {
- Type = "object",
- Nullable = false,
- Properties = { ["start"] = instantSchema, ["end"] = instantSchema, },
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(Interval).FullName),
- },
- };
- }
- );
- c.MapType(
- () => new()
- {
- Type = "object",
- Nullable = true,
- Properties = { ["start"] = instantSchemas[0].schema(), ["end"] = instantSchemas[0].schema(), },
-
- Extensions = new Dictionary
- {
- ["clrType"] = new OpenApiString(typeof(Interval).FullName),
- },
- }
- );
-
- return c;
- }
-}
\ No newline at end of file
diff --git a/src/AspNetCore/OpenApi/OpenApiDefaultOptions.cs b/src/AspNetCore/OpenApi/OpenApiDefaultOptions.cs
deleted file mode 100644
index 71f46448d..000000000
--- a/src/AspNetCore/OpenApi/OpenApiDefaultOptions.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using Microsoft.Extensions.Options;
-using Swashbuckle.AspNetCore.ReDoc;
-using Swashbuckle.AspNetCore.Swagger;
-using Swashbuckle.AspNetCore.SwaggerGen;
-using Swashbuckle.AspNetCore.SwaggerUI;
-
-namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-
-internal class OpenApiDefaultOptions : IConfigureOptions,
- IConfigureOptions,
- IConfigureOptions,
- IConfigureOptions
-{
- void IConfigureOptions.Configure(ReDocOptions options)
- {
- }
-
- void IConfigureOptions.Configure(SwaggerGenOptions options)
- {
- }
-
- void IConfigureOptions.Configure(SwaggerOptions options)
- {
- }
-
- void IConfigureOptions.Configure(SwaggerUIOptions options)
- {
- options.ConfigObject.DeepLinking = true;
- options.ConfigObject.ShowExtensions = true;
- options.ConfigObject.ShowCommonExtensions = true;
- options.ConfigObject.Filter = string.Empty;
- options.ConfigObject.DisplayRequestDuration = true;
- options.ConfigObject.DisplayOperationId = true;
- }
-}
diff --git a/src/AspNetCore/OpenApi/OperationIdFilter.cs b/src/AspNetCore/OpenApi/OperationIdFilter.cs
index 97625e9ae..28fd933fc 100644
--- a/src/AspNetCore/OpenApi/OperationIdFilter.cs
+++ b/src/AspNetCore/OpenApi/OperationIdFilter.cs
@@ -1,12 +1,12 @@
using System.Globalization;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Mvc.Controllers;
+using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;
-using Swashbuckle.AspNetCore.SwaggerGen;
namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-internal class OperationIdFilter : IOperationFilter
+internal class OperationIdFilter : IOpenApiOperationTransformer
{
///
/// By default, pascalize converts strings to UpperCamelCase also removing underscores
@@ -31,14 +31,16 @@ private static string Camelize(string input)
#pragma warning restore CA1308
}
- public void Apply(OpenApiOperation operation, OperationFilterContext context)
+ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken)
{
- if (string.IsNullOrWhiteSpace(operation.OperationId) && context.ApiDescription.ActionDescriptor is ControllerActionDescriptor cad)
+ if (string.IsNullOrWhiteSpace(operation.OperationId) && context.Description.ActionDescriptor is ControllerActionDescriptor cad)
operation.OperationId = cad.ActionName;
+ if (operation.Parameters is null) return Task.CompletedTask;
foreach (var parameter in operation.Parameters)
{
parameter.Name = Camelize(parameter.Name);
}
+ return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/src/AspNetCore/OpenApi/OperationMediaTypesFilter.cs b/src/AspNetCore/OpenApi/OperationMediaTypesFilter.cs
index 3aee8dd4d..3eb1d47ad 100644
--- a/src/AspNetCore/OpenApi/OperationMediaTypesFilter.cs
+++ b/src/AspNetCore/OpenApi/OperationMediaTypesFilter.cs
@@ -1,22 +1,24 @@
-using Microsoft.OpenApi.Models;
-using Swashbuckle.AspNetCore.SwaggerGen;
+using Microsoft.AspNetCore.OpenApi;
+using Microsoft.OpenApi.Models;
namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-internal class OperationMediaTypesFilter : IOperationFilter
-{
- public void Apply(OpenApiOperation operation, OperationFilterContext context)
+ internal class OperationMediaTypesFilter : IOpenApiOperationTransformer
+ {
+ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken)
{
var contentCollections =
- operation.Responses.Values.Select(x => x.Content ?? new Dictionary())
- .Concat(new[] { operation.RequestBody?.Content ?? new Dictionary() })
- .Where(x => x.ContainsKey("text/plain"))
- .ToArray();
+ operation
+ .Responses.Values.Select(x => x.Content ?? new Dictionary())
+ .Concat([operation.RequestBody?.Content ?? new Dictionary()])
+ .Where(x => x.ContainsKey("text/plain"))
+ .ToArray();
var patchCollections =
- operation.Responses.Values.Select(x => x.Content ?? new Dictionary())
- .Concat(new[] { operation.RequestBody?.Content ?? new Dictionary() })
- .Where(x => x.Keys.Any(z => z.Contains("patch", StringComparison.OrdinalIgnoreCase)))
- .ToArray();
+ operation
+ .Responses.Values.Select(x => x.Content ?? new Dictionary())
+ .Concat([operation.RequestBody?.Content ?? new Dictionary()])
+ .Where(x => x.Keys.Any(z => z.Contains("patch", StringComparison.OrdinalIgnoreCase)))
+ .ToArray();
foreach (var item in contentCollections)
{
@@ -31,5 +33,7 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context)
item.Remove(p.Key);
}
}
+
+ return Task.CompletedTask;
}
}
diff --git a/src/AspNetCore/OpenApi/ProblemDetailsSchemaFilter.cs b/src/AspNetCore/OpenApi/ProblemDetailsSchemaFilter.cs
index fffaf3253..5854d4ff3 100644
--- a/src/AspNetCore/OpenApi/ProblemDetailsSchemaFilter.cs
+++ b/src/AspNetCore/OpenApi/ProblemDetailsSchemaFilter.cs
@@ -1,23 +1,23 @@
using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;
-using Swashbuckle.AspNetCore.SwaggerGen;
namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-internal class ProblemDetailsSchemaFilter : ISchemaFilter
+internal class ProblemDetailsSchemaFilter : IOpenApiSchemaTransformer
{
- public void Apply(OpenApiSchema schema, SchemaFilterContext context)
+ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext context, CancellationToken cancellationToken)
{
- if (typeof(ProblemDetails).IsAssignableFrom(context.Type))
+ if (true) return Task.CompletedTask;
+ if (!typeof(ProblemDetails).IsAssignableFrom(context.JsonTypeInfo.Type)) return Task.CompletedTask;
+ schema.AdditionalPropertiesAllowed = true;
+ schema.Properties.Remove(nameof(ProblemDetails.Extensions));
+ schema.Properties.Remove("extensions");
+ if (schema.Properties.TryGetValue("validationErrors", out var v))
{
- schema.AdditionalPropertiesAllowed = true;
- schema.Properties.Remove(nameof(ProblemDetails.Extensions));
- schema.Properties.Remove("extensions");
- if (schema.Properties.TryGetValue("validationErrors", out var v))
- {
- schema.Properties["errors"] = v;
- schema.Properties.Remove("validationErrors");
- }
+ schema.Properties["errors"] = v;
+ schema.Properties.Remove("validationErrors");
}
+ return Task.CompletedTask;
}
}
diff --git a/src/AspNetCore/OpenApi/StatusCode201Filter.cs b/src/AspNetCore/OpenApi/StatusCode201Filter.cs
index 530a36e3d..31a82a8a4 100644
--- a/src/AspNetCore/OpenApi/StatusCode201Filter.cs
+++ b/src/AspNetCore/OpenApi/StatusCode201Filter.cs
@@ -1,15 +1,15 @@
-using Microsoft.OpenApi.Models;
-using Swashbuckle.AspNetCore.SwaggerGen;
+using Microsoft.AspNetCore.OpenApi;
+using Microsoft.OpenApi.Models;
namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-internal class StatusCode201Filter : IOperationFilter
+internal class StatusCode201Filter : IOpenApiOperationTransformer
{
- public void Apply(OpenApiOperation operation, OperationFilterContext context)
+ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransformerContext context, CancellationToken cancellationToken)
{
// enhance the 201 with the response header
if (!operation.Responses.TryGetValue("201", out var value))
- return;
+ return Task.CompletedTask;
value.Headers.Add(
"location",
new OpenApiHeader
@@ -19,5 +19,6 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context)
Description = "The location of the entity that was created"
}
);
+ return Task.CompletedTask;
}
}
diff --git a/src/AspNetCore/OpenApi/StronglyTypedIdSchemaFilter.cs b/src/AspNetCore/OpenApi/StronglyTypedIdSchemaFilter.cs
index 418aa1c89..8f0f88fe6 100644
--- a/src/AspNetCore/OpenApi/StronglyTypedIdSchemaFilter.cs
+++ b/src/AspNetCore/OpenApi/StronglyTypedIdSchemaFilter.cs
@@ -1,18 +1,16 @@
using System.Reflection;
+using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;
-using Swashbuckle.AspNetCore.SwaggerGen;
namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
internal static class StronglyTypedIdHelpers
{
- [RequiresUnreferencedCode("DynamicBehavior is incompatible with trimming.")]
public static bool IsStronglyTypedId(Type? type)
{
return GetStronglyTypedIdType(type) is { };
}
- [RequiresUnreferencedCode("DynamicBehavior is incompatible with trimming.")]
public static Type? GetStronglyTypedIdType(Type? type)
{
if (type?.GetMember("New", BindingFlags.Static | BindingFlags.Public).FirstOrDefault() is MethodInfo
@@ -24,25 +22,12 @@ public static bool IsStronglyTypedId(Type? type)
}
}
-internal class StronglyTypedIdSchemaFilter : ISchemaFilter
+internal class StronglyTypedIdSchemaFilter : IOpenApiSchemaTransformer
{
- // TODO: Make a source generator for this to work without generics
- [RequiresUnreferencedCode("DynamicBehavior is incompatible with trimming.")]
- public void Apply(OpenApiSchema schema, SchemaFilterContext context)
+ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext context, CancellationToken cancellationToken)
{
- if (StronglyTypedIdHelpers.GetStronglyTypedIdType(context.Type) is not { } type) return;
- schema.Properties.Clear();
- var s2 = context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository, context.MemberInfo, context.ParameterInfo);
- schema.Format = s2.Format;
- schema.Type = s2.Type;
- schema.Enum = s2.Enum;
- schema.Default = s2.Default;
- schema.Maximum = s2.Maximum;
- schema.Minimum = s2.Minimum;
- schema.Reference = s2.Reference;
- schema.Pattern = s2.Pattern;
- schema.Nullable = s2.Nullable;
- schema.Required = s2.Required;
- schema.Not = s2.Not;
+ if (StronglyTypedIdHelpers.GetStronglyTypedIdType(context.JsonPropertyInfo?.PropertyType) is not { } type) return Task.CompletedTask;
+// TODO: Solve this
+ return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/src/AspNetCore/OpenApi/SwashbuckleAddAllDocumentEndpoints.cs b/src/AspNetCore/OpenApi/SwashbuckleAddAllDocumentEndpoints.cs
deleted file mode 100644
index 44eaf3e50..000000000
--- a/src/AspNetCore/OpenApi/SwashbuckleAddAllDocumentEndpoints.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Microsoft.AspNetCore.Builder;
-using Microsoft.Extensions.Options;
-using Swashbuckle.AspNetCore.SwaggerGen;
-using Swashbuckle.AspNetCore.SwaggerUI;
-
-namespace Rocket.Surgery.LaunchPad.AspNetCore.OpenApi;
-
-internal class SwashbuckleAddAllDocumentEndpoints(IOptions options) : IConfigureOptions
-{
- public void Configure(SwaggerUIOptions options1)
- {
- foreach (var item in options.Value.SwaggerGeneratorOptions.SwaggerDocs)
- {
- options1.SwaggerEndpoint($"/swagger/{item.Key}/swagger.json", item.Value.Title);
- }
- }
-}
diff --git a/src/AspNetCore/Rocket.Surgery.LaunchPad.AspNetCore.csproj b/src/AspNetCore/Rocket.Surgery.LaunchPad.AspNetCore.csproj
index 5bdcd4809..28ddffcd7 100644
--- a/src/AspNetCore/Rocket.Surgery.LaunchPad.AspNetCore.csproj
+++ b/src/AspNetCore/Rocket.Surgery.LaunchPad.AspNetCore.csproj
@@ -1,10 +1,9 @@
- net8.0
+ net9.0
$(PackageTags)
false
- false
@@ -13,17 +12,16 @@
+
+
+
-
-
-
-
diff --git a/src/AspNetCore/RocketSurgeryMvcCoreExtensions.cs b/src/AspNetCore/RocketSurgeryMvcCoreExtensions.cs
index 68ba5cf53..2ddc72eae 100644
--- a/src/AspNetCore/RocketSurgeryMvcCoreExtensions.cs
+++ b/src/AspNetCore/RocketSurgeryMvcCoreExtensions.cs
@@ -40,8 +40,8 @@ public static IApplicationBuilder UseLaunchPadRequestLogging(this IApplicationBu
return app.UseSerilogRequestLogging(
x =>
{
- x.GetLevel = LaunchPadLogHelpers.DefaultGetLevel;
- x.EnrichDiagnosticContext = LaunchPadLogHelpers.DefaultEnrichDiagnosticContext;
+ x.GetLevel = LaunchPadHelpers.DefaultGetLevel;
+ x.EnrichDiagnosticContext = LaunchPadHelpers.DefaultEnrichDiagnosticContext;
}
);
}
diff --git a/src/AspNetCore/Validation/ValidationExceptionFilter.cs b/src/AspNetCore/Validation/ValidationExceptionFilter.cs
index 5998e0fe6..4d3348dea 100644
--- a/src/AspNetCore/Validation/ValidationExceptionFilter.cs
+++ b/src/AspNetCore/Validation/ValidationExceptionFilter.cs
@@ -19,7 +19,7 @@ public Task OnExceptionAsync(ExceptionContext context)
///
public void OnException(ExceptionContext context)
{
- if (!( context.Exception is ValidationException validationException )) return;
+ if (context.Exception is not ValidationException validationException) return;
context.ExceptionHandled = true;
context.Result = new UnprocessableEntityObjectResult(new FluentValidationProblemDetails(validationException.Errors));
}
diff --git a/src/EntityFramework/Rocket.Surgery.LaunchPad.EntityFramework.csproj b/src/EntityFramework/Rocket.Surgery.LaunchPad.EntityFramework.csproj
index daa22425d..e19188843 100644
--- a/src/EntityFramework/Rocket.Surgery.LaunchPad.EntityFramework.csproj
+++ b/src/EntityFramework/Rocket.Surgery.LaunchPad.EntityFramework.csproj
@@ -1,11 +1,11 @@
-
- net8.0
-
- $(PackageTags)
-
-
-
-
-
+
+ net8.0;net9.0
+
+ $(PackageTags)
+
+
+
+
+
diff --git a/src/Foundation.NewtonsoftJson/Rocket.Surgery.LaunchPad.Foundation.NewtonsoftJson.csproj b/src/Foundation.NewtonsoftJson/Rocket.Surgery.LaunchPad.Foundation.NewtonsoftJson.csproj
index 3f7d63226..9e4a64f50 100644
--- a/src/Foundation.NewtonsoftJson/Rocket.Surgery.LaunchPad.Foundation.NewtonsoftJson.csproj
+++ b/src/Foundation.NewtonsoftJson/Rocket.Surgery.LaunchPad.Foundation.NewtonsoftJson.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net8.0;net9.0
$(PackageTags)
Rocket.Surgery.LaunchPad.Foundation
diff --git a/src/Foundation/Assigned.cs b/src/Foundation/Assigned.cs
index a538f7164..4417851ae 100644
--- a/src/Foundation/Assigned.cs
+++ b/src/Foundation/Assigned.cs
@@ -87,13 +87,9 @@ private Assigned(T? value, bool hasValue)
public T? Value { get; }
///
- /// true if the Assigned was explicitly set.
+ /// true if the Assigned was explicitly set.
///
- ///
- public bool HasBeenSet()
- {
- return _hasValue;
- }
+ public bool HasValue => _hasValue;
///
/// Provides the name string.
@@ -151,4 +147,4 @@ public bool Equals(Assigned? other)
return Equals(Value, other.Value);
}
-}
\ No newline at end of file
+}
diff --git a/src/Foundation/Conventions/DefaultConvention.cs b/src/Foundation/Conventions/DefaultConvention.cs
index 76a0422b3..d5c97cbda 100644
--- a/src/Foundation/Conventions/DefaultConvention.cs
+++ b/src/Foundation/Conventions/DefaultConvention.cs
@@ -27,5 +27,7 @@ public void Register(IConventionContext context, IConfiguration configuration, I
.AddOptions()
.AddLogging()
.AddExecuteScopedServices();
+
+ services.AddCompiledServiceRegistrations(context.TypeProvider);
}
}
diff --git a/src/Foundation/Conventions/FluentValidationConvention.cs b/src/Foundation/Conventions/FluentValidationConvention.cs
index b8d1d4e9e..3418f3a48 100644
--- a/src/Foundation/Conventions/FluentValidationConvention.cs
+++ b/src/Foundation/Conventions/FluentValidationConvention.cs
@@ -8,7 +8,7 @@
using Microsoft.Extensions.Options;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.DependencyInjection;
-using Rocket.Surgery.Conventions.Reflection;
+using Rocket.Surgery.DependencyInjection.Compiled;
using Rocket.Surgery.LaunchPad.Foundation.Validation;
namespace Rocket.Surgery.LaunchPad.Foundation.Conventions;
@@ -47,7 +47,7 @@ public void Register(IConventionContext context, IConfiguration configuration, I
{
ArgumentNullException.ThrowIfNull(context);
- var types = context.AssemblyProvider.GetTypes(
+ var types = context.TypeProvider.GetTypes(
z => z
.FromAssemblyDependenciesOf()
.GetTypes(
@@ -57,13 +57,17 @@ public void Register(IConventionContext context, IConfiguration configuration, I
.NotInfoOf(TypeInfoFilter.GenericType)
)
);
- foreach (var validator in types)
- {
- if (validator is not { BaseType: { IsGenericType: true, GenericTypeArguments: [var innerType,], }, }) continue;
- var interfaceType = typeof(IValidator<>).MakeGenericType(innerType);
- services.Add(new(interfaceType, validator, _options.ValidatorLifetime));
- services.Add(new(validator, validator, _options.ValidatorLifetime));
- }
+
+ context.TypeProvider
+ .Scan(
+ services,
+ z => z
+ .FromAssemblyDependenciesOf()
+ .AddClasses(t => t.AssignableTo().NotAssignableTo(typeof(CompositeValidator<>)))
+ .AsSelf()
+ .AsImplementedInterfaces(a => a.AssignableTo())
+ .WithTransientLifetime()
+ );
if (_options.RegisterValidationOptionsAsHealthChecks == true
|| ( !_options.RegisterValidationOptionsAsHealthChecks.HasValue
diff --git a/src/Foundation/Conventions/HealthChecksConvention.cs b/src/Foundation/Conventions/HealthChecksConvention.cs
index 6b014159a..78d3c9eb1 100644
--- a/src/Foundation/Conventions/HealthChecksConvention.cs
+++ b/src/Foundation/Conventions/HealthChecksConvention.cs
@@ -8,9 +8,9 @@ namespace Rocket.Surgery.LaunchPad.Foundation.Conventions;
///
/// EnvironmentLoggingConvention.
-/// Implements the
+/// Implements the
///
-///
+///
[PublicAPI]
[ExportConvention]
[ConventionCategory(ConventionCategory.Core)]
diff --git a/src/Foundation/Conventions/MediatRConvention.cs b/src/Foundation/Conventions/MediatRConvention.cs
index 1e550e367..f8b2fddda 100644
--- a/src/Foundation/Conventions/MediatRConvention.cs
+++ b/src/Foundation/Conventions/MediatRConvention.cs
@@ -35,9 +35,8 @@ public MediatRConvention(FoundationOptions? options = null)
///
public void Register(IConventionContext context, IConfiguration configuration, IServiceCollection services)
{
- // TODO: Look at converting this to use the assembly type provider
- var assemblies = context.AssemblyProvider.GetAssemblies(x => x.FromAssemblyDependenciesOf()).ToArray();
- if (!assemblies.Any()) return;
+ var assemblies = context.TypeProvider.GetAssemblies(x => x.FromAssemblyDependenciesOf()).ToArray();
+ if (!assemblies.Any()) throw new ArgumentException("No assemblies found that reference MediatR");
services.AddMediatR(
c =>
diff --git a/src/Foundation/Conventions/OptionsConvention.cs b/src/Foundation/Conventions/OptionsConvention.cs
index 8bcbb05fe..424a491e8 100644
--- a/src/Foundation/Conventions/OptionsConvention.cs
+++ b/src/Foundation/Conventions/OptionsConvention.cs
@@ -11,6 +11,7 @@ namespace Rocket.Surgery.LaunchPad.Foundation.Conventions;
///
[ExportConvention]
[ConventionCategory(ConventionCategory.Core)]
+[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)]
public class OptionsConvention : IServiceConvention
{
private readonly MethodInfo _configureMethod;
@@ -20,22 +21,28 @@ public class OptionsConvention : IServiceConvention
///
public OptionsConvention()
{
- _configureMethod = typeof(OptionsConfigurationServiceCollectionExtensions).GetMethod(
- nameof(OptionsConfigurationServiceCollectionExtensions.Configure),
- [typeof(IServiceCollection), typeof(string), typeof(IConfiguration),]
- )!;
+ _configureMethod = GetType().GetMethod(nameof(Configure), BindingFlags.NonPublic | BindingFlags.Static)!;
}
///
public void Register(IConventionContext context, IConfiguration configuration, IServiceCollection services)
{
- var classes = context.AssemblyProvider.GetTypes(
+ var classes = context.TypeProvider.GetTypes(
s => s.FromAssemblyDependenciesOf().GetTypes(f => f.WithAttribute())
);
foreach (var options in classes)
{
var attribute = options.GetCustomAttribute()!;
+ #pragma warning disable IL2060
_configureMethod.MakeGenericMethod(options).Invoke(null, [services, attribute.OptionsName, configuration.GetSection(attribute.ConfigurationKey),]);
+ #pragma warning restore IL2060
}
}
+
+ [RequiresUnreferencedCode("Calls Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure(String, IConfiguration)")]
+ private static IServiceCollection Configure<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TOptions>(IServiceCollection services, string? name, IConfiguration config)
+ where TOptions : class
+ {
+ return services.Configure(name, config);
+ }
}
diff --git a/src/Foundation/Conventions/TimeConvention.cs b/src/Foundation/Conventions/TimeConvention.cs
index bb59a8d1a..3b6eceb01 100644
--- a/src/Foundation/Conventions/TimeConvention.cs
+++ b/src/Foundation/Conventions/TimeConvention.cs
@@ -33,7 +33,7 @@ public TimeConvention(FoundationOptions? options = null)
///
public void Register(IConventionContext context, IConfiguration configuration, IServiceProvider services, LoggerConfiguration loggerConfiguration)
{
- loggerConfiguration.Destructure.NodaTimeTypes(services.GetRequiredService());
+ loggerConfiguration.Destructure.NodaTimeTypes();
}
///
@@ -46,8 +46,9 @@ public void Register(IConventionContext context, IConfiguration configuration, I
{
ArgumentNullException.ThrowIfNull(context);
+ // Try add so that unit tests can insert fakes
services.TryAddSingleton(TimeProvider.System);
services.TryAddSingleton(SystemClock.Instance);
- services.TryAddSingleton(new DateTimeZoneCache(_options.DateTimeZoneSource));
+ services.TryAddSingleton(DateTimeZoneProviders.Tzdb);
}
}
diff --git a/src/Foundation/ExistingValueOptionsFactory.cs b/src/Foundation/ExistingValueOptionsFactory.cs
index 605d1f511..125d8ea8b 100644
--- a/src/Foundation/ExistingValueOptionsFactory.cs
+++ b/src/Foundation/ExistingValueOptionsFactory.cs
@@ -1,7 +1,51 @@
+using System.Text.Json;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace Rocket.Surgery.LaunchPad.Foundation;
+///
+/// Helper methods for creating instances.
+///
+public static class ExistingValueOptions
+{
+ ///
+ /// Applys all of the , , and instances to the options instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void Apply(IServiceProvider serviceProvider, TOptions options, string name) where TOptions : class, new()
+ {
+ var setups = serviceProvider.GetServices>();
+ var postConfigures = serviceProvider.GetServices>();
+ var validations = serviceProvider.GetServices>();
+
+ foreach (var setup in setups)
+ {
+ if (setup is IConfigureNamedOptions namedSetup)
+ namedSetup.Configure(name, options);
+ else if (name == Options.DefaultName) setup.Configure(options);
+ }
+
+ foreach (var post in postConfigures)
+ {
+ post.PostConfigure(name, options);
+ }
+
+ var failures = new List();
+ foreach (var validate in validations)
+ {
+ var result = validate.Validate(name, options);
+ if (result.Failed) failures.AddRange(result.Failures);
+ }
+
+ if (failures.Count > 0) throw new OptionsValidationException(name, typeof(TOptions), failures);
+ }
+}
+
///
/// Implementation of .
///
@@ -53,18 +97,16 @@ public TOptions Create(string name)
post.PostConfigure(name, options);
}
- if (_validations != null)
+ if (_validations is null) return options;
+ var failures = new List();
+ foreach (var validate in _validations)
{
- var failures = new List();
- foreach (var validate in _validations)
- {
- var result = validate.Validate(name, options);
- if (result.Failed) failures.AddRange(result.Failures);
- }
-
- if (failures.Count > 0) throw new OptionsValidationException(name, typeof(TOptions), failures);
+ var result = validate.Validate(name, options);
+ if (result.Failed) failures.AddRange(result.Failures);
}
+ if (failures.Count > 0) throw new OptionsValidationException(name, typeof(TOptions), failures);
+
return options;
}
-}
\ No newline at end of file
+}
diff --git a/src/Foundation/FluentValidationProblemDetail.cs b/src/Foundation/FluentValidationProblemDetail.cs
index e74df7522..f75093659 100644
--- a/src/Foundation/FluentValidationProblemDetail.cs
+++ b/src/Foundation/FluentValidationProblemDetail.cs
@@ -11,25 +11,6 @@ namespace Rocket.Surgery.LaunchPad.Foundation;
[PublicAPI]
public class FluentValidationProblemDetail
{
- ///
- /// Convert the problem details into a dictionary of information in graphql
- ///
- ///
- ///
- public static implicit operator ReadOnlyDictionary(FluentValidationProblemDetail detail)
- {
- return new(
- new Dictionary
- {
- ["propertyName"] = detail.PropertyName,
- ["errorMessage"] = detail.ErrorMessage,
- ["attemptedValue"] = detail.AttemptedValue,
- ["severity"] = detail.Severity,
- ["errorCode"] = detail.ErrorCode,
- }
- );
- }
-
///
/// A validation error problem
///
@@ -64,15 +45,6 @@ public FluentValidationProblemDetail(ValidationFailure validationFailure)
[JsonPropertyName("errorCode")]
public string ErrorCode { get; set; }
- ///
- /// Convert the problem details into a dictionary of information in graphql
- ///
- ///
- public ReadOnlyDictionary ToReadOnlyDictionary()
- {
- return this;
- }
-
internal class Validator : AbstractValidator
{
public Validator()
@@ -82,4 +54,4 @@ public Validator()
RuleFor(x => x.ErrorMessage).NotNull();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Foundation/NodaTimeLoggerConfigurationExtensions.cs b/src/Foundation/NodaTimeLoggerConfigurationExtensions.cs
index c794538b2..b4d78bd2c 100644
--- a/src/Foundation/NodaTimeLoggerConfigurationExtensions.cs
+++ b/src/Foundation/NodaTimeLoggerConfigurationExtensions.cs
@@ -13,9 +13,8 @@ public static class NodaTimeLoggerConfigurationExtensions
/// Enable destructuring of JSON.NET dynamic objects.
///
/// The logger configuration to apply configuration to.
- ///
/// An object allowing configuration to continue.
- public static LoggerConfiguration NodaTimeTypes(this LoggerDestructuringConfiguration configuration, IDateTimeZoneProvider provider)
+ public static LoggerConfiguration NodaTimeTypes(this LoggerDestructuringConfiguration configuration)
{
return configuration
.AsScalar()
@@ -24,4 +23,4 @@ public static LoggerConfiguration NodaTimeTypes(this LoggerDestructuringConfigur
.Destructure
.With(new NodaTimeDestructuringPolicy());
}
-}
\ No newline at end of file
+}
diff --git a/src/Foundation/Rocket.Surgery.LaunchPad.Foundation.csproj b/src/Foundation/Rocket.Surgery.LaunchPad.Foundation.csproj
index 48e16f977..c309f5d34 100644
--- a/src/Foundation/Rocket.Surgery.LaunchPad.Foundation.csproj
+++ b/src/Foundation/Rocket.Surgery.LaunchPad.Foundation.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net8.0;net9.0
$(PackageTags)
@@ -24,6 +24,10 @@
+
+
+
+
@@ -34,20 +38,8 @@
-
-
-
+
+
diff --git a/src/Grpc/Rocket.Surgery.LaunchPad.Grpc.csproj b/src/Grpc/Rocket.Surgery.LaunchPad.Grpc.csproj
index 0275c3a48..ab0037ac8 100644
--- a/src/Grpc/Rocket.Surgery.LaunchPad.Grpc.csproj
+++ b/src/Grpc/Rocket.Surgery.LaunchPad.Grpc.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net9.0
$(PackageTags)
false
diff --git a/src/Hosting/Conventions/EnvironmentLoggingConvention.cs b/src/Hosting/Conventions/EnvironmentLoggingConvention.cs
index 064a1d3f2..edf18c2c7 100644
--- a/src/Hosting/Conventions/EnvironmentLoggingConvention.cs
+++ b/src/Hosting/Conventions/EnvironmentLoggingConvention.cs
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.LaunchPad.Serilog;
diff --git a/src/Hosting/Conventions/SerilogHostingConvention.cs b/src/Hosting/Conventions/SerilogHostingConvention.cs
index d1b50dd30..91e5a369b 100644
--- a/src/Hosting/Conventions/SerilogHostingConvention.cs
+++ b/src/Hosting/Conventions/SerilogHostingConvention.cs
@@ -1,8 +1,10 @@
using App.Metrics;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Rocket.Surgery.Conventions;
+using Rocket.Surgery.Conventions.DependencyInjection;
using Rocket.Surgery.Conventions.Hosting;
using Rocket.Surgery.Hosting;
using Serilog;
@@ -22,43 +24,15 @@ namespace Rocket.Surgery.LaunchPad.Hosting.Conventions;
[PublicAPI]
[ExportConvention]
[ConventionCategory(ConventionCategory.Core)]
-public class SerilogHostingConvention : IHostApplicationConvention, IHostCreatedConvention
+public class SerilogHostingConvention : IServiceConvention
{
- private void CustomAddSerilog(
- IServiceCollection collection,
- Action configureLogger
- )
- {
- collection.AddSingleton(new LoggerProviderCollection());
- collection.AddSingleton(
- services =>
- {
- var loggerConfiguration = new LoggerConfiguration();
- loggerConfiguration.WriteTo.Providers(services.GetRequiredService());
- configureLogger(services, loggerConfiguration);
- return loggerConfiguration.CreateLogger();
- }
- );
- collection.AddSingleton(services => services.GetRequiredService().ForContext(new NullEnricher()));
- collection.AddSingleton(
- services => new SerilogLoggerFactory(
- services.GetRequiredService(),
- true,
- services.GetRequiredService()
- )
- );
- collection.AddSingleton(services => new DiagnosticContext(services.GetRequiredService()));
- collection.AddSingleton(services => services.GetRequiredService());
- }
-
///
- public void Register(IConventionContext context, IHostApplicationBuilder builder)
+ public void Register(IConventionContext context, IConfiguration configuration, IServiceCollection services)
{
ArgumentNullException.ThrowIfNull(context);
// removes default console loggers and such
- foreach (var item in builder
- .Services
+ foreach (var item in services
.Where(
x =>
{
@@ -70,44 +44,12 @@ public void Register(IConventionContext context, IHostApplicationBuilder builder
.ToArray()
)
{
- builder.Services.Remove(item);
- }
-
- if (context.Get() is { } logger)
- {
- builder.Services.AddSerilog(logger);
- }
- else
- {
- CustomAddSerilog(
- builder.Services,
- (services, loggerConfiguration) => loggerConfiguration.ApplyConventions(context, builder.Configuration, services)
- );
+ services.Remove(item);
}
- if (context.Get() != null)
- // ReSharper disable once NullableWarningSuppressionIsUsed
- builder.Services.AddSingleton(context.Get()!);
- }
-
- ///
- public void Register(IConventionContext context, IHost host)
- {
- host
- .Services
- .GetServices()
- .Aggregate(
- host.Services.GetRequiredService(),
- (factory, loggerProvider) =>
- {
- factory.AddProvider(loggerProvider);
- return factory;
- }
- );
- }
-
- private class NullEnricher : ILogEventEnricher
- {
- public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { }
+ services.ActivateSingleton();
+ services.ActivateSingleton();
+ services.AddSingleton(sp => new DiagnosticContext(sp.GetRequiredService()));
+ services.AddSingleton(sp => sp.GetRequiredService());
}
}
diff --git a/src/Hosting/Rocket.Surgery.LaunchPad.Hosting.csproj b/src/Hosting/Rocket.Surgery.LaunchPad.Hosting.csproj
index aa3a2a342..5a1aee5e4 100644
--- a/src/Hosting/Rocket.Surgery.LaunchPad.Hosting.csproj
+++ b/src/Hosting/Rocket.Surgery.LaunchPad.Hosting.csproj
@@ -1,19 +1,16 @@
- net8.0
+ net8.0;net9.0
$(PackageTags)
-
-
-
diff --git a/src/HotChocolate/Conventions/GraphqlConvention.cs b/src/HotChocolate/Conventions/GraphqlConvention.cs
index f30fe0233..8998bbe03 100644
--- a/src/HotChocolate/Conventions/GraphqlConvention.cs
+++ b/src/HotChocolate/Conventions/GraphqlConvention.cs
@@ -1,11 +1,14 @@
-using MediatR;
+using FairyBread;
+using FluentValidation;
+using HotChocolate.Resolvers;
+using HotChocolate.Types;
+using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.DependencyInjection;
using Rocket.Surgery.LaunchPad.Foundation;
-using Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
using Rocket.Surgery.LaunchPad.HotChocolate.Types;
using IConventionContext = Rocket.Surgery.Conventions.IConventionContext;
@@ -42,9 +45,13 @@ public void Register(IConventionContext context, IConfiguration configuration, I
{
var sb = context
.GetOrAdd(() => services.AddGraphQL())
- .AddFairyBread()
+// .AddMutationConventions()
+ .AddFairyBread(
+ options => { options.ThrowIfNoValidatorsFound = false; }
+ )
.AddErrorFilter()
.BindRuntimeType();
+ services.Replace(ServiceDescriptor.Singleton());
if (!_rocketChocolateOptions.IncludeAssemblyInfoQuery) return;
@@ -52,3 +59,37 @@ public void Register(IConventionContext context, IConfiguration configuration, I
sb.AddType();
}
}
+
+//class LaunchPadValidatorProvider : IValidatorProvider
+//{
+// public IEnumerable GetValidators(IMiddlewareContext context, IInputField argument)
+// {
+// yield break;
+// }
+//}
+
+class LaunchPadValidatorRegistry(IServiceProvider serviceProvider) : IValidatorRegistry
+{
+ private readonly Lazy>> _cache = new(
+ () =>
+ {
+ var dictionary = new Dictionary>();
+ var scope = serviceProvider.CreateScope();
+ var validators = scope.ServiceProvider.GetServices();
+ foreach (var validator in validators)
+ {
+ var type = validator.GetType().GetInterfaces().First(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IValidator<>)).GetGenericArguments()[0];
+ if (!dictionary.TryGetValue(type, out var list))
+ {
+ list = new ();
+ dictionary[type] = list;
+ }
+
+ list.Add(new (validator.GetType()));
+ }
+ return dictionary;
+ }
+ );
+
+ public Dictionary> Cache => _cache.Value;
+}
diff --git a/src/HotChocolate/FairyBread/ArgumentValidationResult.cs b/src/HotChocolate/FairyBread/ArgumentValidationResult.cs
deleted file mode 100644
index 23f1a9c43..000000000
--- a/src/HotChocolate/FairyBread/ArgumentValidationResult.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using FluentValidation;
-using FluentValidation.Results;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-public record ArgumentValidationResult
-{
- public ArgumentValidationResult(
- string argumentName,
- IValidator validator,
- ValidationResult result
- )
- {
- ArgumentName = argumentName;
- Validator = validator;
- Result = result ?? throw new ArgumentNullException(nameof(result));
- }
-
- ///
- /// Name of the argument this result is for.
- ///
- public string ArgumentName { get; }
-
- ///
- /// The validator that caused this result.
- ///
- public IValidator Validator { get; }
-
- ///
- /// The validation result.
- ///
- public ValidationResult Result { get; }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/DefaultFairyBreadOptions.cs b/src/HotChocolate/FairyBread/DefaultFairyBreadOptions.cs
deleted file mode 100644
index 9f06a1d0d..000000000
--- a/src/HotChocolate/FairyBread/DefaultFairyBreadOptions.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using HotChocolate.Types.Descriptors.Definitions;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-public class DefaultFairyBreadOptions : IFairyBreadOptions
-{
- ///
- public virtual bool ThrowIfNoValidatorsFound { get; set; } = true;
-
- ///
- public Func ShouldValidateArgument { get; set; }
- = (o, f, a) => true;
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/DefaultValidationErrorsHandler.cs b/src/HotChocolate/FairyBread/DefaultValidationErrorsHandler.cs
deleted file mode 100644
index bf1dcab0a..000000000
--- a/src/HotChocolate/FairyBread/DefaultValidationErrorsHandler.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using FluentValidation;
-using FluentValidation.Results;
-using HotChocolate;
-using HotChocolate.Resolvers;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-public class DefaultValidationErrorsHandler : IValidationErrorsHandler
-{
- protected virtual IErrorBuilder CreateErrorBuilder(
- IMiddlewareContext context,
- string argumentName,
- IValidator validator,
- ValidationFailure failure
- )
- {
- var builder = ErrorBuilder
- .New()
- .SetPath(context.Path)
- .SetMessage(failure.ErrorMessage)
- .SetCode("FairyBread_ValidationError")
- .SetExtension("argumentName", argumentName)
- .SetExtension("validatorName", validator.GetType().Name)
- .SetExtension("errorCode", failure.ErrorCode)
- .SetExtension("errorMessage", failure.ErrorMessage)
- .SetExtension("attemptedValue", failure.AttemptedValue)
- .SetExtension("severity", failure.Severity)
- .SetExtension("formattedMessagePlaceholderValues", failure.FormattedMessagePlaceholderValues);
-
- if (!string.IsNullOrWhiteSpace(failure.PropertyName))
- {
- builder = builder
- .SetExtension("propertyName", failure.PropertyName);
- }
-
- return builder;
- }
-
- public virtual void Handle(
- IMiddlewareContext context,
- IEnumerable invalidResults
- )
- {
- foreach (var invalidResult in invalidResults)
- {
- foreach (var failure in invalidResult.Result.Errors)
- {
- var errorBuilder = CreateErrorBuilder(context, invalidResult.ArgumentName, invalidResult.Validator, failure);
- var error = errorBuilder.Build();
- context.ReportError(error);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/DefaultValidatorProvider.cs b/src/HotChocolate/FairyBread/DefaultValidatorProvider.cs
deleted file mode 100644
index 6f1b38ed4..000000000
--- a/src/HotChocolate/FairyBread/DefaultValidatorProvider.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using FluentValidation;
-using HotChocolate.Resolvers;
-using HotChocolate.Types;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-public class DefaultValidatorProvider : IValidatorProvider
-{
- protected readonly IValidatorRegistry ValidatorRegistry;
-
- public DefaultValidatorProvider(
- IValidatorRegistry validatorRegistry
- )
- {
- ValidatorRegistry = validatorRegistry;
- }
-
- public virtual IEnumerable GetValidators(IMiddlewareContext context, IInputField argument)
- {
- if (!argument.ContextData.TryGetValue(
- WellKnownContextData.ValidatorDescriptors,
- out var validatorDescriptorsRaw
- )
- || validatorDescriptorsRaw is not IEnumerable validatorDescriptors)
- {
- yield break;
- }
-
- foreach (var validatorDescriptor in validatorDescriptors)
- {
- if (validatorDescriptor.RequiresOwnScope)
- {
- var scope = context.Services.CreateScope(); // disposed by middleware
- var validator = (IValidator)scope.ServiceProvider.GetRequiredService(validatorDescriptor.ValidatorType);
- yield return new(validator, scope);
- }
- else
- {
- var validator = (IValidator)context.Services.GetRequiredService(validatorDescriptor.ValidatorType);
- yield return new(validator);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/DefaultValidatorRegistry.cs b/src/HotChocolate/FairyBread/DefaultValidatorRegistry.cs
deleted file mode 100644
index 6c079db4f..000000000
--- a/src/HotChocolate/FairyBread/DefaultValidatorRegistry.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using FluentValidation;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-public class DefaultValidatorRegistry : IValidatorRegistry
-{
- private readonly IServiceProvider _serviceProvider;
-
- private readonly Dictionary _cache = new();
-
- public DefaultValidatorRegistry(IServiceProvider serviceProvider)
- {
- _serviceProvider = serviceProvider;
- }
-
- public bool TryGetValidator(Type type, [NotNullWhen(true)] out ValidatorDescriptor? descriptor)
- {
- if (_cache.TryGetValue(type, out var validator))
- {
- descriptor = validator;
- return true;
- }
-
- var validatorType = typeof(IValidator<>).MakeGenericType(type);
- if (_serviceProvider.GetService(typeof(IValidator<>).MakeGenericType(type)) is { })
- {
- descriptor = _cache[type] = new(validatorType);
- return true;
- }
-
- descriptor = null;
- return false;
- }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/DontValidateAttribute.cs b/src/HotChocolate/FairyBread/DontValidateAttribute.cs
deleted file mode 100644
index 653d40e37..000000000
--- a/src/HotChocolate/FairyBread/DontValidateAttribute.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using HotChocolate.Types;
-using HotChocolate.Types.Descriptors;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-///
-/// Instructs FairyBread to not run any validation on the annotated argument.
-///
-[AttributeUsage(AttributeTargets.Parameter)]
-public class DontValidateAttribute : ArgumentDescriptorAttribute
-{
- protected override void OnConfigure(
- IDescriptorContext context,
- IArgumentDescriptor descriptor,
- ParameterInfo parameter
- )
- {
- descriptor.DontValidate();
- }
-}
-
-public static class DontValidateArgumentDescriptorExtensions
-{
- ///
- /// Instructs FairyBread to not run any validation for this argument.
- ///
- public static IArgumentDescriptor DontValidate(
- this IArgumentDescriptor descriptor
- )
- {
- descriptor.Extend().OnBeforeNaming((completionContext, argDef) => { argDef.ContextData[WellKnownContextData.DontValidate] = true; });
-
- return descriptor;
- }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/DontValidateImplicitlyAttribute.cs b/src/HotChocolate/FairyBread/DontValidateImplicitlyAttribute.cs
deleted file mode 100644
index 05c76e389..000000000
--- a/src/HotChocolate/FairyBread/DontValidateImplicitlyAttribute.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Reflection;
-using HotChocolate.Types;
-using HotChocolate.Types.Descriptors;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-///
-/// Instructs FairyBread to not run any validators that
-/// are implicitly associated with the annotated argument's type.
-/// Explicit validators will still be run.
-///
-[AttributeUsage(AttributeTargets.Parameter)]
-public class DontValidateImplicitlyAttribute : ArgumentDescriptorAttribute
-{
- protected override void OnConfigure(
- IDescriptorContext context,
- IArgumentDescriptor descriptor,
- ParameterInfo parameter
- )
- {
- descriptor.DontValidateImplicitly();
- }
-}
-
-public static class DontValidateImplicitlyArgumentDescriptorExtensions
-{
- ///
- /// Instructs FairyBread to not run any validators that
- /// are implicitly associated with this argument's runtime type.
- /// Explicit validators will still be run.
- ///
- public static IArgumentDescriptor DontValidateImplicitly(
- this IArgumentDescriptor descriptor
- )
- {
- descriptor.Extend().OnBeforeNaming((completionContext, argDef) => { argDef.ContextData[WellKnownContextData.DontValidateImplicitly] = true; });
-
- return descriptor;
- }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/IExplicitUsageOnlyValidator.cs b/src/HotChocolate/FairyBread/IExplicitUsageOnlyValidator.cs
deleted file mode 100644
index c4d7be924..000000000
--- a/src/HotChocolate/FairyBread/IExplicitUsageOnlyValidator.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-///
-/// Marker interface for indicating that a validator
-/// should only be run by FairyBread on a field resolver argument
-/// if it is explicitly assigned to that argument.
-///
-public interface IExplicitUsageOnlyValidator { }
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/IFairyBreadOptions.cs b/src/HotChocolate/FairyBread/IFairyBreadOptions.cs
deleted file mode 100644
index ee9c56e1c..000000000
--- a/src/HotChocolate/FairyBread/IFairyBreadOptions.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using HotChocolate.Types.Descriptors.Definitions;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-public interface IFairyBreadOptions
-{
- ///
- /// If true, FairyBread will throw on startup if no validators are found.
- /// This is true by default to avoid an accidental release with no validators
- /// that continues to function silently but would obviously be very dangerous.
- ///
- bool ThrowIfNoValidatorsFound { get; set; }
-
- ///
- /// A function that evaluates an argument during schema building.
- /// If it returns true, validation will occur on this argument at runtime, else it won't.
- /// The default implementation always returns true.
- ///
- Func ShouldValidateArgument { get; set; }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/IRequestExecutorBuilderExtensions.cs b/src/HotChocolate/FairyBread/IRequestExecutorBuilderExtensions.cs
deleted file mode 100644
index 6df15ce53..000000000
--- a/src/HotChocolate/FairyBread/IRequestExecutorBuilderExtensions.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using HotChocolate.Execution.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.DependencyInjection.Extensions;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-public static class IRequestExecutorBuilderExtensions
-{
- public static IRequestExecutorBuilder AddFairyBread(
- this IRequestExecutorBuilder requestExecutorBuilder,
- Action? configureOptions = null
- )
- {
- // Services
- var services = requestExecutorBuilder.Services;
-
- var options = new DefaultFairyBreadOptions();
- configureOptions?.Invoke(options);
-
- services.TryAddSingleton(options);
- services.TryAddSingleton();
- services.TryAddSingleton();
- services.TryAddSingleton();
-
- // Executor builder
- requestExecutorBuilder.TryAddTypeInterceptor();
-
- return requestExecutorBuilder;
- }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/IRequiresOwnScopeValidator.cs b/src/HotChocolate/FairyBread/IRequiresOwnScopeValidator.cs
deleted file mode 100644
index 061e10a07..000000000
--- a/src/HotChocolate/FairyBread/IRequiresOwnScopeValidator.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using FluentValidation;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-///
-/// Marker interface for validators that should be resolved
-/// from the service provider in it's own scope.
-///
-public interface IRequiresOwnScopeValidator : IValidator { }
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/IValidationErrorsHandler.cs b/src/HotChocolate/FairyBread/IValidationErrorsHandler.cs
deleted file mode 100644
index ada9c5514..000000000
--- a/src/HotChocolate/FairyBread/IValidationErrorsHandler.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using HotChocolate.Resolvers;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-public interface IValidationErrorsHandler
-{
- void Handle(
- IMiddlewareContext context,
- IEnumerable invalidResults
- );
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/IValidatorProvider.cs b/src/HotChocolate/FairyBread/IValidatorProvider.cs
deleted file mode 100644
index 4cfa10ebd..000000000
--- a/src/HotChocolate/FairyBread/IValidatorProvider.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using HotChocolate.Resolvers;
-using HotChocolate.Types;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-///
-/// Resolves validators at query execution time.
-///
-public interface IValidatorProvider
-{
- IEnumerable GetValidators(IMiddlewareContext context, IInputField argument);
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/IValidatorRegistry.cs b/src/HotChocolate/FairyBread/IValidatorRegistry.cs
deleted file mode 100644
index ab89b1168..000000000
--- a/src/HotChocolate/FairyBread/IValidatorRegistry.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-///
-/// Maintains a registry of implicit validators
-/// keyed by the target runtime type for validation.
-///
-public interface IValidatorRegistry
-{
- ///
- /// Try and get the validator descriptor for the specified type.
- ///
- ///
- ///
- ///
- bool TryGetValidator(Type type, [NotNullWhen(true)] out ValidatorDescriptor? descriptor);
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/ResolvedValidator.cs b/src/HotChocolate/FairyBread/ResolvedValidator.cs
deleted file mode 100644
index 79f72ab3d..000000000
--- a/src/HotChocolate/FairyBread/ResolvedValidator.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using FluentValidation;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-public struct ResolvedValidator
-{
- public IValidator Validator { get; }
-
- public IServiceScope? Scope { get; }
-
- public ResolvedValidator(IValidator validator)
- {
- Validator = validator;
- Scope = null;
- }
-
- public ResolvedValidator(IValidator validator, IServiceScope scope)
- {
- Validator = validator;
- Scope = scope;
- }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/ValidateAttribute.cs b/src/HotChocolate/FairyBread/ValidateAttribute.cs
deleted file mode 100644
index 1f059f1b2..000000000
--- a/src/HotChocolate/FairyBread/ValidateAttribute.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-using System.Reflection;
-using FluentValidation;
-using HotChocolate.Types;
-using HotChocolate.Types.Descriptors;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-///
-/// Instructs FairyBread to add the given validator/s for the annotated argument.
-///
-[AttributeUsage(AttributeTargets.Parameter)]
-public class ValidateAttribute : ArgumentDescriptorAttribute
-{
- public Type[] ValidatorTypes;
-
- public ValidateAttribute(params Type[] validatorTypes)
- {
- ValidatorTypes = validatorTypes;
- }
-
- protected override void OnConfigure(
- IDescriptorContext context,
- IArgumentDescriptor descriptor,
- ParameterInfo parameter
- )
- {
- if (parameter.GetCustomAttribute() is not ValidateAttribute attr)
- {
- return;
- }
-
- descriptor.ValidateWith(attr.ValidatorTypes);
- }
-}
-
-public static class ValidateArgumentDescriptorExtensions
-{
- ///
- /// Instructs FairyBread to add the given validator to the argument.
- ///
- public static IArgumentDescriptor ValidateWith(
- this IArgumentDescriptor descriptor
- )
- where TValidator : IValidator
- {
- return descriptor.ValidateWith(typeof(TValidator));
- }
-
- ///
- /// Instructs FairyBread to add the given validator/s to the argument.
- ///
- public static IArgumentDescriptor ValidateWith(
- this IArgumentDescriptor descriptor,
- params Type[] validatorTypes
- )
- {
- descriptor
- .Extend()
- .OnBeforeNaming(
- (completionContext, argDef) =>
- {
- if (!argDef.ContextData.TryGetValue(WellKnownContextData.ExplicitValidatorTypes, out var explicitValidatorTypesRaw)
- || explicitValidatorTypesRaw is not List explicitValidatorTypes)
- {
- argDef.ContextData[WellKnownContextData.ExplicitValidatorTypes]
- = new List(validatorTypes.Distinct());
- return;
- }
-
- foreach (var validatorType in validatorTypes)
- {
- if (!explicitValidatorTypes.Contains(validatorType))
- {
- explicitValidatorTypes.Add(validatorType);
- }
- }
- }
- );
-
- return descriptor;
- }
-}
\ No newline at end of file
diff --git a/src/HotChocolate/FairyBread/ValidationMiddleware.cs b/src/HotChocolate/FairyBread/ValidationMiddleware.cs
deleted file mode 100644
index 29251a047..000000000
--- a/src/HotChocolate/FairyBread/ValidationMiddleware.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using FluentValidation;
-using HotChocolate.Resolvers;
-
-namespace Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-[UsedImplicitly]
-internal class ValidationMiddleware
-(
- FieldDelegate next,
- IValidatorProvider validatorProvider,
- IValidationErrorsHandler validationErrorsHandler
-)
-{
- public async Task InvokeAsync(IMiddlewareContext context)
- {
- var arguments = context.Selection.Field.Arguments;
-
- var invalidResults = new List();
-
- foreach (var argument in arguments)
- {
- var resolvedValidators = validatorProvider
- .GetValidators(context, argument)
- .ToArray();
- if (resolvedValidators.Length > 0)
- try
- {
- var value = context.ArgumentValue
/// The container.
/// The delegate.
+ ///
+ ///
/// IConventionHostBuilder.
public static ConventionContextBuilder ConfigureOpenTelemetry(
this ConventionContextBuilder container,
@@ -98,6 +102,8 @@ public static ConventionContextBuilder ConfigureOpenTelemetry(
///
/// The container.
/// The delegate.
+ ///
+ ///
/// IConventionHostBuilder.
public static ConventionContextBuilder ConfigureOpenTelemetry(
this ConventionContextBuilder container,
@@ -119,6 +125,8 @@ public static ConventionContextBuilder ConfigureOpenTelemetry(
///
/// The container.
/// The delegate.
+ ///
+ ///
/// IConventionHostBuilder.
public static ConventionContextBuilder ConfigureOpenTelemetry(
this ConventionContextBuilder container,
@@ -140,6 +148,8 @@ public static ConventionContextBuilder ConfigureOpenTelemetry(
///
/// The container.
/// The delegate.
+ ///
+ ///
/// IConventionHostBuilder.
public static ConventionContextBuilder ConfigureOpenTelemetry(
this ConventionContextBuilder container,
diff --git a/src/Testing/Rocket.Surgery.LaunchPad.Testing.csproj b/src/Testing/Rocket.Surgery.LaunchPad.Testing.csproj
index 5690eceef..2d99c38c7 100644
--- a/src/Testing/Rocket.Surgery.LaunchPad.Testing.csproj
+++ b/src/Testing/Rocket.Surgery.LaunchPad.Testing.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net8.0;net9.0
$(PackageTags)
@@ -12,6 +12,6 @@
-
+
diff --git a/test/Analyzers.Tests.roslyn4.6/Analyzers.Tests.roslyn4.6.csproj b/test/Analyzers.Tests.roslyn4.6/Analyzers.Tests.roslyn4.6.csproj
index 2971fbe37..b7ff1889c 100644
--- a/test/Analyzers.Tests.roslyn4.6/Analyzers.Tests.roslyn4.6.csproj
+++ b/test/Analyzers.Tests.roslyn4.6/Analyzers.Tests.roslyn4.6.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net9.0
<_Analyzer_Roslyn_Version_>$(MSBuildProjectName.Replace("Analyzers.Tests.", ""))
$(DefineConstants);ROSLYN4_6
Analyzers.Tests
@@ -13,16 +13,13 @@
-
+
-
+
-
+
diff --git a/test/Analyzers.Tests/Analyzers.Tests.csproj b/test/Analyzers.Tests/Analyzers.Tests.csproj
index 940637c69..f3d8bca52 100644
--- a/test/Analyzers.Tests/Analyzers.Tests.csproj
+++ b/test/Analyzers.Tests/Analyzers.Tests.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net9.0
$(DefineConstants);ROSLYN_CURRENT;ROSLYN4_8
diff --git a/test/Analyzers.Tests/ControllerActionBodyGeneratorTests.cs b/test/Analyzers.Tests/ControllerActionBodyGeneratorTests.cs
index b434cb136..8eeccf43c 100644
--- a/test/Analyzers.Tests/ControllerActionBodyGeneratorTests.cs
+++ b/test/Analyzers.Tests/ControllerActionBodyGeneratorTests.cs
@@ -722,4 +722,4 @@ public override async Task InitializeAsync()
"
);
}
-}
\ No newline at end of file
+}
diff --git a/test/Analyzers.Tests/GeneratorTest.cs b/test/Analyzers.Tests/GeneratorTest.cs
index aa2e35b22..09abd57a8 100644
--- a/test/Analyzers.Tests/GeneratorTest.cs
+++ b/test/Analyzers.Tests/GeneratorTest.cs
@@ -1,10 +1,8 @@
using System.Reflection;
using System.Runtime.Loader;
-using Microsoft.CodeAnalysis;
+using HotChocolate.Types;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
using Rocket.Surgery.Conventions;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.Extensions.Testing.SourceGenerators;
namespace Analyzers.Tests.Helpers;
@@ -22,12 +20,8 @@ public void Dispose()
}
}
-public abstract class GeneratorTest(ITestOutputHelper testOutputHelper) : LoggerTest(testOutputHelper, LogLevel.Trace), IAsyncLifetime
+public abstract class GeneratorTest(ITestOutputHelper testOutputHelper) : LoggerTest(XUnitDefaults.CreateTestContext(testOutputHelper)), IAsyncLifetime
{
- private readonly HashSet _metadataReferences = new(ReferenceEqualityComparer.Instance);
- private readonly HashSet _generators = new();
- private readonly List _sources = new();
-
public AssemblyLoadContext AssemblyLoadContext { get; } = new CollectibleTestAssemblyLoadContext();
protected GeneratorTestContextBuilder Builder { get; set; } = null!;
@@ -40,7 +34,8 @@ public virtual Task InitializeAsync()
.AddReferences(
typeof(ActivatorUtilities).Assembly,
typeof(ConventionContext).Assembly,
- typeof(IConventionContext).Assembly
+ typeof(IConventionContext).Assembly,
+ typeof(ErrorAttribute<>).Assembly
);
return Task.CompletedTask;
@@ -53,4 +48,4 @@ public virtual Task DisposeAsync()
Disposables.Dispose();
return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/test/Analyzers.Tests/GraphqlMutationActionBodyGeneratorTests.cs b/test/Analyzers.Tests/GraphqlMutationActionBodyGeneratorTests.cs
index fbcb1b6c3..33f3d6bec 100644
--- a/test/Analyzers.Tests/GraphqlMutationActionBodyGeneratorTests.cs
+++ b/test/Analyzers.Tests/GraphqlMutationActionBodyGeneratorTests.cs
@@ -1330,4 +1330,4 @@ public override async Task InitializeAsync()
"
);
}
-}
\ No newline at end of file
+}
diff --git a/test/Analyzers.Tests/GraphqlOptionalPropertyTrackingGeneratorTests.cs b/test/Analyzers.Tests/GraphqlOptionalPropertyTrackingGeneratorTests.cs
index 8cc5a7793..9d6e31a1e 100644
--- a/test/Analyzers.Tests/GraphqlOptionalPropertyTrackingGeneratorTests.cs
+++ b/test/Analyzers.Tests/GraphqlOptionalPropertyTrackingGeneratorTests.cs
@@ -681,22 +681,22 @@ public record Changes
public Changes GetChangedState()
{
return new Changes()
- {SerialNumber = SerialNumber.HasBeenSet(), Type = Type.HasBeenSet(), PlannedDate = PlannedDate.HasBeenSet()};
+ {SerialNumber = SerialNumber.HasValue, Type = Type.HasValue, PlannedDate = PlannedDate.HasValue};
}
public Request ApplyChanges(Request value)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
value = value with {SerialNumber = SerialNumber};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
value = value with {Type = Type};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
value.PlannedDate = PlannedDate;
}
@@ -749,22 +749,22 @@ public class Changes
public Changes GetChangedState()
{
return new Changes()
- {SerialNumber = SerialNumber.HasBeenSet(), Type = Type.HasBeenSet(), PlannedDate = PlannedDate.HasBeenSet()};
+ {SerialNumber = SerialNumber.HasValue, Type = Type.HasValue, PlannedDate = PlannedDate.HasValue};
}
public Request ApplyChanges(Request value)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
value.SerialNumber = SerialNumber;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
value.Type = Type;
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
value.PlannedDate = PlannedDate;
}
@@ -1323,4 +1323,4 @@ public class RocketModel
"
);
}
-}
\ No newline at end of file
+}
diff --git a/test/Analyzers.Tests/InheritFromGeneratorTests.cs b/test/Analyzers.Tests/InheritFromGeneratorTests.cs
index 04dec895b..d219927c3 100644
--- a/test/Analyzers.Tests/InheritFromGeneratorTests.cs
+++ b/test/Analyzers.Tests/InheritFromGeneratorTests.cs
@@ -879,4 +879,4 @@ public class RocketModel
"
);
}
-}
\ No newline at end of file
+}
diff --git a/test/Analyzers.Tests/ModuleInitializer.cs b/test/Analyzers.Tests/ModuleInitializer.cs
index 188cd0d42..57b2a8c30 100644
--- a/test/Analyzers.Tests/ModuleInitializer.cs
+++ b/test/Analyzers.Tests/ModuleInitializer.cs
@@ -13,7 +13,6 @@ public static class ModuleInitializer
public static void Init()
{
VerifyGeneratorTextContext.Initialize(DiagnosticSeverity.Error, Customizers.Empty);
-
DiffRunner.Disabled = true;
DerivePathInfo(
(sourceFile, _, type, method) =>
@@ -42,4 +41,4 @@ static string GetTypeName(Type type)
}
);
}
-}
\ No newline at end of file
+}
diff --git a/test/Analyzers.Tests/MutableGeneratorTests.cs b/test/Analyzers.Tests/MutableGeneratorTests.cs
index cdcf8e8f1..df2c45f7c 100644
--- a/test/Analyzers.Tests/MutableGeneratorTests.cs
+++ b/test/Analyzers.Tests/MutableGeneratorTests.cs
@@ -15,4 +15,4 @@ public override async Task InitializeAsync()
typeof(MutableAttribute)
);
}
-}
\ No newline at end of file
+}
diff --git a/test/Analyzers.Tests/PropertyTrackingGeneratorTests.cs b/test/Analyzers.Tests/PropertyTrackingGeneratorTests.cs
index 9d59f79ad..5c6213355 100644
--- a/test/Analyzers.Tests/PropertyTrackingGeneratorTests.cs
+++ b/test/Analyzers.Tests/PropertyTrackingGeneratorTests.cs
@@ -1068,4 +1068,4 @@ public class RocketModel
"
);
}
-}
\ No newline at end of file
+}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters2_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters2_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs
index b5c588e14..5ed01bb50 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters2_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters2_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs
@@ -24,14 +24,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- LaunchId = LaunchId.HasBeenSet()
+ LaunchId = LaunchId.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.GetRocketLaunchRecord.Request ApplyChanges(global::TestNamespace.GetRocketLaunchRecord.Request state)
{
- if (LaunchId.HasBeenSet())
+ if (LaunchId.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters3_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters3_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs
index 15a248568..fec5dfe5e 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters3_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters3_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs
@@ -24,14 +24,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- LaunchRecordId = LaunchRecordId.HasBeenSet()
+ LaunchRecordId = LaunchRecordId.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.GetRocketLaunchRecord.Request ApplyChanges(global::TestNamespace.GetRocketLaunchRecord.Request state)
{
- if (LaunchRecordId.HasBeenSet())
+ if (LaunchRecordId.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters4_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters4_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs
index 919b517fd..a3a4426c2 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters4_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodiesWithMultipleParameters4_sources=#Input2_GetRocketLaunchRecord_PatchRequest_PropertyTracking.verified.cs
@@ -24,14 +24,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- LaunchRecordId = LaunchRecordId.HasBeenSet()
+ LaunchRecordId = LaunchRecordId.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.GetRocketLaunchRecord.Request ApplyChanges(global::TestNamespace.GetRocketLaunchRecord.Request state)
{
- if (LaunchRecordId.HasBeenSet())
+ if (LaunchRecordId.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithCancellationToken_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithCancellationToken_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
index 2f0042e8a..4bef6132e 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithCancellationToken_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithCancellationToken_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
@@ -25,14 +25,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- Name = Name.HasBeenSet()
+ Name = Name.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.GetRocket.Request ApplyChanges(global::TestNamespace.GetRocket.Request state)
{
- if (Name.HasBeenSet())
+ if (Name.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipal2_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipal2_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
index b95047aba..208f472a4 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipal2_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipal2_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
@@ -25,14 +25,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- Name = Name.HasBeenSet()
+ Name = Name.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.GetRocket.Request ApplyChanges(global::TestNamespace.GetRocket.Request state)
{
- if (Name.HasBeenSet())
+ if (Name.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipalAndCancellationToken_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipalAndCancellationToken_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
index 7d33903a9..e9487b169 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipalAndCancellationToken_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipalAndCancellationToken_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
@@ -26,14 +26,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- Name = Name.HasBeenSet()
+ Name = Name.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.GetRocket.Request ApplyChanges(global::TestNamespace.GetRocket.Request state)
{
- if (Name.HasBeenSet())
+ if (Name.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipalConstructor_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipalConstructor_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
index d7ed98445..5fa93dae2 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipalConstructor_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipalConstructor_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
@@ -26,14 +26,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- Name = Name.HasBeenSet()
+ Name = Name.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.GetRocket.Request ApplyChanges(global::TestNamespace.GetRocket.Request state)
{
- if (Name.HasBeenSet())
+ if (Name.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipal_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipal_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
index 67319712f..732cabd5e 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipal_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequestWithClaimsPrincipal_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
@@ -25,14 +25,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- Name = Name.HasBeenSet()
+ Name = Name.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.GetRocket.Request ApplyChanges(global::TestNamespace.GetRocket.Request state)
{
- if (Name.HasBeenSet())
+ if (Name.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequest_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequest_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
index 54b507aae..ccc279ed9 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequest_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyForRequest_sources=#Input2_GetRocket_PatchRequest_PropertyTracking.verified.cs
@@ -24,14 +24,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- Name = Name.HasBeenSet()
+ Name = Name.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.GetRocket.Request ApplyChanges(global::TestNamespace.GetRocket.Request state)
{
- if (Name.HasBeenSet())
+ if (Name.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithCancellationTokenAndClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithCancellationTokenAndClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
index d5931f89a..1202c1bcc 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithCancellationTokenAndClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithCancellationTokenAndClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
@@ -34,16 +34,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- Sn = Sn.HasBeenSet(),
- ClaimsPrincipal = ClaimsPrincipal.HasBeenSet(),
- Other = Other.HasBeenSet()
+ Sn = Sn.HasValue,
+ ClaimsPrincipal = ClaimsPrincipal.HasValue,
+ Other = Other.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.Save2Rocket.Request ApplyChanges(global::TestNamespace.Save2Rocket.Request state)
{
- if (Sn.HasBeenSet())
+ if (Sn.HasValue)
{
state = state with
{
@@ -51,7 +51,7 @@ public Changes GetChangedState()
};
}
- if (ClaimsPrincipal.HasBeenSet())
+ if (ClaimsPrincipal.HasValue)
{
state = state with
{
@@ -59,7 +59,7 @@ public Changes GetChangedState()
};
}
- if (Other.HasBeenSet())
+ if (Other.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
index d8723e634..675f52b36 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
@@ -29,15 +29,15 @@ public Changes GetChangedState()
{
return new Changes()
{
- Sn = Sn.HasBeenSet(),
- Other = Other.HasBeenSet()
+ Sn = Sn.HasValue,
+ Other = Other.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.Save2Rocket.Request ApplyChanges(global::TestNamespace.Save2Rocket.Request state)
{
- if (Sn.HasBeenSet())
+ if (Sn.HasValue)
{
state = state with
{
@@ -45,7 +45,7 @@ public Changes GetChangedState()
};
}
- if (Other.HasBeenSet())
+ if (Other.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
index 3a6aa91a3..b30ed8690 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
@@ -33,16 +33,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- Sn = Sn.HasBeenSet(),
- ClaimsPrincipal = ClaimsPrincipal.HasBeenSet(),
- Other = Other.HasBeenSet()
+ Sn = Sn.HasValue,
+ ClaimsPrincipal = ClaimsPrincipal.HasValue,
+ Other = Other.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.Save2Rocket.Request ApplyChanges(global::TestNamespace.Save2Rocket.Request state)
{
- if (Sn.HasBeenSet())
+ if (Sn.HasValue)
{
state = state with
{
@@ -50,7 +50,7 @@ public Changes GetChangedState()
};
}
- if (ClaimsPrincipal.HasBeenSet())
+ if (ClaimsPrincipal.HasValue)
{
state = state with
{
@@ -58,7 +58,7 @@ public Changes GetChangedState()
};
}
- if (Other.HasBeenSet())
+ if (Other.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithDifferentlyNamedCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithDifferentlyNamedCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
index d8723e634..675f52b36 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithDifferentlyNamedCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithDifferentlyNamedCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
@@ -29,15 +29,15 @@ public Changes GetChangedState()
{
return new Changes()
{
- Sn = Sn.HasBeenSet(),
- Other = Other.HasBeenSet()
+ Sn = Sn.HasValue,
+ Other = Other.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.Save2Rocket.Request ApplyChanges(global::TestNamespace.Save2Rocket.Request state)
{
- if (Sn.HasBeenSet())
+ if (Sn.HasValue)
{
state = state with
{
@@ -45,7 +45,7 @@ public Changes GetChangedState()
};
}
- if (Other.HasBeenSet())
+ if (Other.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithDifferentlyNamedClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithDifferentlyNamedClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
index 3a6aa91a3..b30ed8690 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithDifferentlyNamedClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithDifferentlyNamedClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
@@ -33,16 +33,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- Sn = Sn.HasBeenSet(),
- ClaimsPrincipal = ClaimsPrincipal.HasBeenSet(),
- Other = Other.HasBeenSet()
+ Sn = Sn.HasValue,
+ ClaimsPrincipal = ClaimsPrincipal.HasValue,
+ Other = Other.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.Save2Rocket.Request ApplyChanges(global::TestNamespace.Save2Rocket.Request state)
{
- if (Sn.HasBeenSet())
+ if (Sn.HasValue)
{
state = state with
{
@@ -50,7 +50,7 @@ public Changes GetChangedState()
};
}
- if (ClaimsPrincipal.HasBeenSet())
+ if (ClaimsPrincipal.HasValue)
{
state = state with
{
@@ -58,7 +58,7 @@ public Changes GetChangedState()
};
}
- if (Other.HasBeenSet())
+ if (Other.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithoutCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithoutCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
index 09fff2a7c..7aa2356b4 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithoutCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithoutCancellationToken_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
@@ -28,15 +28,15 @@ public Changes GetChangedState()
{
return new Changes()
{
- Sn = Sn.HasBeenSet(),
- Other = Other.HasBeenSet()
+ Sn = Sn.HasValue,
+ Other = Other.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.Save2Rocket.Request ApplyChanges(global::TestNamespace.Save2Rocket.Request state)
{
- if (Sn.HasBeenSet())
+ if (Sn.HasValue)
{
state = state with
{
@@ -44,7 +44,7 @@ public Changes GetChangedState()
};
}
- if (Other.HasBeenSet())
+ if (Other.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithoutClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithoutClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
index b61c81515..1fa8f7440 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithoutClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlMutationActionBodyGeneratorTests.Should_Generate_Method_Bodies_With_Optional_Tracking_key=GenerateBodyWithoutClaimsPrincipal_sources=#Input2_Save2Rocket_PatchRequest_PropertyTracking.verified.cs
@@ -33,16 +33,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- Sn = Sn.HasBeenSet(),
- ClaimsPrincipal = ClaimsPrincipal.HasBeenSet(),
- Other = Other.HasBeenSet()
+ Sn = Sn.HasValue,
+ ClaimsPrincipal = ClaimsPrincipal.HasValue,
+ Other = Other.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::TestNamespace.Save2Rocket.Request ApplyChanges(global::TestNamespace.Save2Rocket.Request state)
{
- if (Sn.HasBeenSet())
+ if (Sn.HasValue)
{
state = state with
{
@@ -50,7 +50,7 @@ public Changes GetChangedState()
};
}
- if (ClaimsPrincipal.HasBeenSet())
+ if (ClaimsPrincipal.HasValue)
{
state = state with
{
@@ -58,7 +58,7 @@ public Changes GetChangedState()
};
}
- if (Other.HasBeenSet())
+ if (Other.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_modelType=Class_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_modelType=Class_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 38adc21f3..eb55ee6fb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_modelType=Class_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_modelType=Class_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,26 +31,26 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state.PlannedDate = PlannedDate!;
}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_modelType=Record_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_modelType=Record_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 65c740c34..709bf8ffb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_modelType=Record_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_modelType=Record_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,16 +31,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -48,7 +48,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -56,7 +56,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_modelType=Class_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_modelType=Class_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 38adc21f3..eb55ee6fb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_modelType=Class_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_modelType=Class_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,26 +31,26 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state.PlannedDate = PlannedDate!;
}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_modelType=Record_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_modelType=Record_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 65c740c34..709bf8ffb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_modelType=Record_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_modelType=Record_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,16 +31,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -48,7 +48,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -56,7 +56,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator#Input1_PatchRocket_PropertyTracking.verified.cs
index 47d68654a..bffe4b197 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -29,16 +29,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- PlannedDate = PlannedDate.HasBeenSet(),
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ PlannedDate = PlannedDate.HasValue,
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
@@ -46,7 +46,7 @@ public Changes GetChangedState()
};
}
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -54,7 +54,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator.verified.txt b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator.verified.txt
index 5a48cfb22..dce81d7aa 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator.verified.txt
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator.verified.txt
@@ -7,6 +7,7 @@
},
References: [
HotChocolate.Abstractions.dll,
+ HotChocolate.Types.Errors.dll,
MediatR.Contracts.dll,
MediatR.dll,
Microsoft.Extensions.DependencyInjection.Abstractions.dll,
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=OtherAssembly.verified.txt b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=OtherAssembly.verified.txt
index 550da3229..8da916c5b 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=OtherAssembly.verified.txt
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=OtherAssembly.verified.txt
@@ -6,6 +6,7 @@
},
References: [
HotChocolate.Abstractions.dll,
+ HotChocolate.Types.Errors.dll,
MediatR.Contracts.dll,
MediatR.dll,
Microsoft.Extensions.DependencyInjection.Abstractions.dll,
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 38adc21f3..eb55ee6fb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,26 +31,26 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state.PlannedDate = PlannedDate!;
}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=SameAssembly.verified.txt b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=SameAssembly.verified.txt
index 5a48cfb22..dce81d7aa 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=SameAssembly.verified.txt
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute2_propertyTracking=SameAssembly.verified.txt
@@ -7,6 +7,7 @@
},
References: [
HotChocolate.Abstractions.dll,
+ HotChocolate.Types.Errors.dll,
MediatR.Contracts.dll,
MediatR.dll,
Microsoft.Extensions.DependencyInjection.Abstractions.dll,
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=OtherAssembly.verified.txt b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=OtherAssembly.verified.txt
index 550da3229..8da916c5b 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=OtherAssembly.verified.txt
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=OtherAssembly.verified.txt
@@ -6,6 +6,7 @@
},
References: [
HotChocolate.Abstractions.dll,
+ HotChocolate.Types.Errors.dll,
MediatR.Contracts.dll,
MediatR.dll,
Microsoft.Extensions.DependencyInjection.Abstractions.dll,
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 59ae9dfe6..9c7f1bd87 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,26 +31,26 @@ public Changes GetChangedState()
{
return new Changes()
{
- PlannedDate = PlannedDate.HasBeenSet(),
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ PlannedDate = PlannedDate.HasValue,
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state.PlannedDate = PlannedDate!;
}
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=SameAssembly.verified.txt b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=SameAssembly.verified.txt
index 5a48cfb22..dce81d7aa 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=SameAssembly.verified.txt
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_Attribute_propertyTracking=SameAssembly.verified.txt
@@ -7,6 +7,7 @@
},
References: [
HotChocolate.Abstractions.dll,
+ HotChocolate.Types.Errors.dll,
MediatR.Contracts.dll,
MediatR.dll,
Microsoft.Extensions.DependencyInjection.Abstractions.dll,
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=OtherAssembly.verified.txt b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=OtherAssembly.verified.txt
index 9f5ebe93a..36d030f0a 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=OtherAssembly.verified.txt
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=OtherAssembly.verified.txt
@@ -23,6 +23,7 @@
},
References: [
HotChocolate.Abstractions.dll,
+ HotChocolate.Types.Errors.dll,
MediatR.Contracts.dll,
MediatR.dll,
Microsoft.Extensions.DependencyInjection.Abstractions.dll,
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index b0d20bac1..d16284242 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -27,20 +27,20 @@ public Changes GetChangedState()
{
return new Changes()
{
- PlannedDate = PlannedDate.HasBeenSet(),
- Type = Type.HasBeenSet()
+ PlannedDate = PlannedDate.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state.PlannedDate = PlannedDate!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=SameAssembly.verified.txt b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=SameAssembly.verified.txt
index 5a48cfb22..dce81d7aa 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=SameAssembly.verified.txt
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude_propertyTracking=SameAssembly.verified.txt
@@ -7,6 +7,7 @@
},
References: [
HotChocolate.Abstractions.dll,
+ HotChocolate.Types.Errors.dll,
MediatR.Contracts.dll,
MediatR.dll,
Microsoft.Extensions.DependencyInjection.Abstractions.dll,
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 38adc21f3..eb55ee6fb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,26 +31,26 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state.PlannedDate = PlannedDate!;
}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 38adc21f3..eb55ee6fb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,26 +31,26 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state.PlannedDate = PlannedDate!;
}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 65c740c34..709bf8ffb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_IPropertyTracking_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,16 +31,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -48,7 +48,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -56,7 +56,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 65c740c34..709bf8ffb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_IPropertyTracking_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,16 +31,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -48,7 +48,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -56,7 +56,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 65c740c34..709bf8ffb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Create_property=SerialNumber_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,16 +31,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -48,7 +48,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -56,7 +56,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
index 65c740c34..709bf8ffb 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Create_property=Type_value=12345_propertyTracking=SameAssembly#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,16 +31,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -48,7 +48,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -56,7 +56,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Partial_Type_Declaration#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Partial_Type_Declaration#Input1_PatchRocket_PropertyTracking.verified.cs
index ccfc2fa46..532de5e59 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Partial_Type_Declaration#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Partial_Type_Declaration#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,26 +31,26 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state.PlannedDate = PlannedDate!;
}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Same_Type_As_Class#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Same_Type_As_Class#Input1_PatchRocket_PropertyTracking.verified.cs
index ccfc2fa46..532de5e59 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Same_Type_As_Class#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Same_Type_As_Class#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,26 +31,26 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state.PlannedDate = PlannedDate!;
}
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Same_Type_As_Record#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Same_Type_As_Record#Input1_PatchRocket_PropertyTracking.verified.cs
index 9b8d68150..1baba74e7 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Same_Type_As_Record#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Require_Same_Type_As_Record#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,16 +31,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -48,7 +48,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -56,7 +56,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Builtin_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Builtin_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs
index 314e78bb6..6cda22602 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Builtin_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Builtin_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -26,15 +26,15 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -42,7 +42,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Class_Property#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Class_Property#Input1_PatchRocket_PropertyTracking.verified.cs
index ec72d5393..32dfb06c4 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Class_Property#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Class_Property#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,16 +31,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -48,7 +48,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -56,7 +56,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Enum_Property#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Enum_Property#Input1_PatchRocket_PropertyTracking.verified.cs
index 8bec92b73..1e87d6bd0 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Enum_Property#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Enum_Property#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -32,16 +32,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -49,7 +49,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -57,7 +57,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs
index e946baefe..5ac23b079 100644
--- a/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/GraphqlOptionalPropertyTrackingGeneratorTests.Should_Support_Nullable_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -31,16 +31,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet(),
- PlannedDate = PlannedDate.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue,
+ PlannedDate = PlannedDate.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -48,7 +48,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
@@ -56,7 +56,7 @@ public Changes GetChangedState()
};
}
- if (PlannedDate.HasBeenSet())
+ if (PlannedDate.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_And_Exclude_Properties#Input1_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_And_Exclude_Properties#Input1_PatchRequest_PropertyTracking.verified.cs
index 05cc9bf59..cbacf386e 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_And_Exclude_Properties#Input1_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_And_Exclude_Properties#Input1_PatchRequest_PropertyTracking.verified.cs
@@ -21,14 +21,14 @@ public Changes GetChangedState()
{
return new Changes()
{
- Name = Name.HasBeenSet()
+ Name = Name.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (Name.HasBeenSet())
+ if (Name.HasValue)
{
state.Name = Name!;
}
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator#Input1_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator#Input1_PatchRequest_PropertyTracking.verified.cs
index 119ff2d64..2d8703ff6 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator#Input1_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator#Input1_PatchRequest_PropertyTracking.verified.cs
@@ -24,20 +24,20 @@ public Changes GetChangedState()
{
return new Changes()
{
- Type = Type.HasBeenSet(),
- SerialNumber = SerialNumber.HasBeenSet()
+ Type = Type.HasValue,
+ SerialNumber = SerialNumber.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude#Input1_PatchRequest_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude#Input1_PatchRequest_PropertyTracking.verified.cs
index 505b8a46f..ca4c88254 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude#Input1_PatchRequest_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_IPropertyTracking_Properties_When_Using_InheritsFromGenerator_Exclude#Input1_PatchRequest_PropertyTracking.verified.cs
@@ -24,20 +24,20 @@ public Changes GetChangedState()
{
return new Changes()
{
- Type = Type.HasBeenSet(),
- Something = Something.HasBeenSet()
+ Type = Type.HasValue,
+ Something = Something.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
- if (Something.HasBeenSet())
+ if (Something.HasValue)
{
state.Something = Something!;
}
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Apply_Changes_property=SerialNumber_value=12345#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Apply_Changes_property=SerialNumber_value=12345#Input1_PatchRocket_PropertyTracking.verified.cs
index 2b29c19be..3aa7895f6 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Apply_Changes_property=SerialNumber_value=12345#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Apply_Changes_property=SerialNumber_value=12345#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -24,20 +24,20 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Apply_Changes_property=Type_value=12345#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Apply_Changes_property=Type_value=12345#Input1_PatchRocket_PropertyTracking.verified.cs
index 2b29c19be..3aa7895f6 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Apply_Changes_property=Type_value=12345#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Apply_Changes_property=Type_value=12345#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -24,20 +24,20 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Track_Changes#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Track_Changes#Input1_PatchRocket_PropertyTracking.verified.cs
index b6faffe2e..345a4a89b 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Track_Changes#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Class_With_Underlying_Properties_And_Track_Changes#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -24,20 +24,20 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state.SerialNumber = SerialNumber!;
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state.Type = Type!;
}
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Apply_Changes_property=SerialNumber#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Apply_Changes_property=SerialNumber#Input1_PatchRocket_PropertyTracking.verified.cs
index 046bad8a4..5a993a4d8 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Apply_Changes_property=SerialNumber#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Apply_Changes_property=SerialNumber#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -28,16 +28,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- Id = Id.HasBeenSet(),
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ Id = Id.HasValue,
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (Id.HasBeenSet())
+ if (Id.HasValue)
{
state = state with
{
@@ -45,7 +45,7 @@ public Changes GetChangedState()
};
}
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -53,7 +53,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Apply_Changes_property=Type#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Apply_Changes_property=Type#Input1_PatchRocket_PropertyTracking.verified.cs
index 046bad8a4..5a993a4d8 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Apply_Changes_property=Type#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Apply_Changes_property=Type#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -28,16 +28,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- Id = Id.HasBeenSet(),
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ Id = Id.HasValue,
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (Id.HasBeenSet())
+ if (Id.HasValue)
{
state = state with
{
@@ -45,7 +45,7 @@ public Changes GetChangedState()
};
}
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -53,7 +53,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Track_Changes#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Track_Changes#Input1_PatchRocket_PropertyTracking.verified.cs
index 046bad8a4..5a993a4d8 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Track_Changes#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Generate_Record_With_Underlying_Properties_And_Track_Changes#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -28,16 +28,16 @@ public Changes GetChangedState()
{
return new Changes()
{
- Id = Id.HasBeenSet(),
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ Id = Id.HasValue,
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Request ApplyChanges(global::Request state)
{
- if (Id.HasBeenSet())
+ if (Id.HasValue)
{
state = state with
{
@@ -45,7 +45,7 @@ public Changes GetChangedState()
};
}
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -53,7 +53,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Require_Partial_Parent_Type_Declaration#Input1_PublicClass_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Require_Partial_Parent_Type_Declaration#Input1_PublicClass_PatchRocket_PropertyTracking.verified.cs
index 642b296ac..f99559fb5 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Require_Partial_Parent_Type_Declaration#Input1_PublicClass_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Require_Partial_Parent_Type_Declaration#Input1_PublicClass_PatchRocket_PropertyTracking.verified.cs
@@ -28,15 +28,15 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -44,7 +44,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Support_Nullable_Class_Property#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Support_Nullable_Class_Property#Input1_PatchRocket_PropertyTracking.verified.cs
index 83de36e9d..5b3f102fb 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Support_Nullable_Class_Property#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Support_Nullable_Class_Property#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -26,15 +26,15 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -42,7 +42,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
diff --git a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Support_Nullable_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Support_Nullable_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs
index 441abfde0..9a88b7543 100644
--- a/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Support_Nullable_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs
+++ b/test/Analyzers.Tests/snapshots/PropertyTrackingGeneratorTests.Should_Support_Nullable_Struct_Property#Input1_PatchRocket_PropertyTracking.verified.cs
@@ -26,15 +26,15 @@ public Changes GetChangedState()
{
return new Changes()
{
- SerialNumber = SerialNumber.HasBeenSet(),
- Type = Type.HasBeenSet()
+ SerialNumber = SerialNumber.HasValue,
+ Type = Type.HasValue
};
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage, System.CodeDom.Compiler.GeneratedCode("Rocket.Surgery.LaunchPad.Analyzers", "version"), System.Runtime.CompilerServices.CompilerGenerated]
public global::Sample.Core.Operations.Rockets.Request ApplyChanges(global::Sample.Core.Operations.Rockets.Request state)
{
- if (SerialNumber.HasBeenSet())
+ if (SerialNumber.HasValue)
{
state = state with
{
@@ -42,7 +42,7 @@ public Changes GetChangedState()
};
}
- if (Type.HasBeenSet())
+ if (Type.HasValue)
{
state = state with
{
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/AspNetCore.FluentValidation.OpenApi.Tests.csproj b/test/AspNetCore.FluentValidation.OpenApi.Tests/AspNetCore.FluentValidation.OpenApi.Tests.csproj
new file mode 100644
index 000000000..ea5d32966
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/AspNetCore.FluentValidation.OpenApi.Tests.csproj
@@ -0,0 +1,11 @@
+
+
+ net9.0
+
+
+
+
+
+
+
+
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-decimal-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-decimal-gtelt.verified.txt
new file mode 100644
index 000000000..a9cabb5cb
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-decimal-gtelt.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ exclusiveMaximum: true,
+ minimum: 1.1,
+ exclusiveMinimum: true,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-decimal-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-decimal-gtlte.verified.txt
new file mode 100644
index 000000000..a9cabb5cb
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-decimal-gtlte.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ exclusiveMaximum: true,
+ minimum: 1.1,
+ exclusiveMinimum: true,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-integer-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-integer-gtelt.verified.txt
new file mode 100644
index 000000000..55a68e389
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-integer-gtelt.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 11,
+ exclusiveMaximum: true,
+ minimum: 2,
+ exclusiveMinimum: true,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-integer-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-integer-gtlte.verified.txt
new file mode 100644
index 000000000..59093b609
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-integer-gtlte.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 10,
+ exclusiveMaximum: true,
+ minimum: 2,
+ exclusiveMinimum: true,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-decimal-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-decimal-gtelt.verified.txt
new file mode 100644
index 000000000..767982839
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-decimal-gtelt.verified.txt
@@ -0,0 +1,18 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ exclusiveMaximum: true,
+ minimum: 1.1,
+ exclusiveMinimum: true,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-decimal-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-decimal-gtlte.verified.txt
new file mode 100644
index 000000000..767982839
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-decimal-gtlte.verified.txt
@@ -0,0 +1,18 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ exclusiveMaximum: true,
+ minimum: 1.1,
+ exclusiveMinimum: true,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-integer-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-integer-gtelt.verified.txt
new file mode 100644
index 000000000..67a622bb7
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-integer-gtelt.verified.txt
@@ -0,0 +1,18 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 11,
+ exclusiveMaximum: true,
+ minimum: 2,
+ exclusiveMinimum: true,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-integer-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-integer-gtlte.verified.txt
new file mode 100644
index 000000000..f5af261f9
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-exclusive-nullable-integer-gtlte.verified.txt
@@ -0,0 +1,18 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 10,
+ exclusiveMaximum: true,
+ minimum: 2,
+ exclusiveMinimum: true,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-decimal-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-decimal-gtelt.verified.txt
new file mode 100644
index 000000000..1d4df2571
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-decimal-gtelt.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ minimum: 1.1,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-decimal-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-decimal-gtlte.verified.txt
new file mode 100644
index 000000000..1d4df2571
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-decimal-gtlte.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ minimum: 1.1,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-integer-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-integer-gtelt.verified.txt
new file mode 100644
index 000000000..48a368bda
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-integer-gtelt.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 11,
+ minimum: 2,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-integer-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-integer-gtlte.verified.txt
new file mode 100644
index 000000000..bfe19112d
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-integer-gtlte.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 10,
+ minimum: 2,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-decimal-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-decimal-gtelt.verified.txt
new file mode 100644
index 000000000..da9bccb21
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-decimal-gtelt.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ minimum: 1.1,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-decimal-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-decimal-gtlte.verified.txt
new file mode 100644
index 000000000..da9bccb21
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-decimal-gtlte.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ minimum: 1.1,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-integer-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-integer-gtelt.verified.txt
new file mode 100644
index 000000000..a609342d4
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-integer-gtelt.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 11,
+ minimum: 2,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-integer-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-integer-gtlte.verified.txt
new file mode 100644
index 000000000..af3bb23b4
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_between_properties_result=-comparison-inclusive-nullable-integer-gtlte.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 10,
+ minimum: 2,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gt.verified.txt
new file mode 100644
index 000000000..0411aaffa
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gt.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ minimum: 2.1,
+ exclusiveMinimum: true,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gte.verified.txt
new file mode 100644
index 000000000..eb59ec699
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gte.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ minimum: 2.1,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gtelt.verified.txt
new file mode 100644
index 000000000..39acbe8e7
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gtelt.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ exclusiveMaximum: true,
+ minimum: 1.1,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gtlte.verified.txt
new file mode 100644
index 000000000..5fc14e3ee
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-gtlte.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ minimum: 1.1,
+ exclusiveMinimum: true,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-lt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-lt.verified.txt
new file mode 100644
index 000000000..ec08e0974
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-lt.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 1.1,
+ exclusiveMaximum: true,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-lte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-lte.verified.txt
new file mode 100644
index 000000000..158fab3e9
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-decimal-lte.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ DecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 1.1,
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gt.verified.txt
new file mode 100644
index 000000000..5d9aa198e
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gt.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ minimum: 2,
+ exclusiveMinimum: true,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gte.verified.txt
new file mode 100644
index 000000000..3b0958705
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gte.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ minimum: 2,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gtelt.verified.txt
new file mode 100644
index 000000000..07c461629
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gtelt.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 11,
+ exclusiveMaximum: true,
+ minimum: 2,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gtlte.verified.txt
new file mode 100644
index 000000000..83a9d82e4
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-gtlte.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 10,
+ minimum: 2,
+ exclusiveMinimum: true,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-lt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-lt.verified.txt
new file mode 100644
index 000000000..a47392ffa
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-lt.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 1,
+ exclusiveMaximum: true,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-lte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-lte.verified.txt
new file mode 100644
index 000000000..38c81cc4f
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-integer-lte.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ IntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 1,
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gt.verified.txt
new file mode 100644
index 000000000..042ae3700
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gt.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ minimum: 2.1,
+ exclusiveMinimum: true,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gte.verified.txt
new file mode 100644
index 000000000..259894dcd
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gte.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ minimum: 2.1,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gtelt.verified.txt
new file mode 100644
index 000000000..04a5e3c9b
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gtelt.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ exclusiveMaximum: true,
+ minimum: 1.1,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gtlte.verified.txt
new file mode 100644
index 000000000..d9a1b9311
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-gtlte.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 2.2,
+ minimum: 1.1,
+ exclusiveMinimum: true,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-lt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-lt.verified.txt
new file mode 100644
index 000000000..78a774fa5
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-lt.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 1.1,
+ exclusiveMaximum: true,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-lte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-lte.verified.txt
new file mode 100644
index 000000000..90421faff
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-decimal-lte.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 1.1,
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gt.verified.txt
new file mode 100644
index 000000000..286f20a13
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gt.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ minimum: 2,
+ exclusiveMinimum: true,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gte.verified.txt
new file mode 100644
index 000000000..9d8829309
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gte.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ minimum: 2,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gtelt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gtelt.verified.txt
new file mode 100644
index 000000000..827002907
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gtelt.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 11,
+ exclusiveMaximum: true,
+ minimum: 2,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gtlte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gtlte.verified.txt
new file mode 100644
index 000000000..e4be27006
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-gtlte.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 10,
+ minimum: 2,
+ exclusiveMinimum: true,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-lt.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-lt.verified.txt
new file mode 100644
index 000000000..6158248fd
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-lt.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 1,
+ exclusiveMaximum: true,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-lte.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-lte.verified.txt
new file mode 100644
index 000000000..432db3841
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_comparison_properties_result=-comparison-nullable-integer-lte.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ type: object,
+ properties: {
+ value: {
+ maximum: 1,
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_email_properties_result=-email-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_email_properties_result=-email-collection.verified.txt
new file mode 100644
index 000000000..f27a287c9
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_email_properties_result=-email-collection.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ CollectionContainer: {
+ type: object,
+ properties: {
+ value: {
+ type: array,
+ items: {
+ type: string
+ },
+ format: email
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_email_properties_result=-email-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_email_properties_result=-email-nullable-string.verified.txt
new file mode 100644
index 000000000..655151fd3
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_email_properties_result=-email-nullable-string.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ type: object,
+ properties: {
+ value: {
+ type: string,
+ format: email,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_email_properties_result=-email-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_email_properties_result=-email-string.verified.txt
new file mode 100644
index 000000000..b51764ceb
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_email_properties_result=-email-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: string,
+ format: email
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-1-100-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-1-100-collection.verified.txt
new file mode 100644
index 000000000..2c0397614
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-1-100-collection.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ CollectionContainer: {
+ type: object,
+ properties: {
+ value: {
+ maxItems: 50,
+ minItems: 5,
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-1-100-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-1-100-nullable-string.verified.txt
new file mode 100644
index 000000000..3fbd80e78
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-1-100-nullable-string.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ type: object,
+ properties: {
+ value: {
+ maxLength: 100,
+ minLength: 1,
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-1-100-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-1-100-string.verified.txt
new file mode 100644
index 000000000..846ec50a8
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-1-100-string.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ maxLength: 50,
+ minLength: 5,
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-5-50-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-5-50-collection.verified.txt
new file mode 100644
index 000000000..2c0397614
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-5-50-collection.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ CollectionContainer: {
+ type: object,
+ properties: {
+ value: {
+ maxItems: 50,
+ minItems: 5,
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-5-50-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-5-50-nullable-string.verified.txt
new file mode 100644
index 000000000..6a34e62a8
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-5-50-nullable-string.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ type: object,
+ properties: {
+ value: {
+ maxLength: 50,
+ minLength: 5,
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-5-50-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-5-50-string.verified.txt
new file mode 100644
index 000000000..846ec50a8
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-length-5-50-string.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ maxLength: 50,
+ minLength: 5,
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-100-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-100-collection.verified.txt
new file mode 100644
index 000000000..e741fe7c5
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-100-collection.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ CollectionContainer: {
+ type: object,
+ properties: {
+ value: {
+ maxItems: 100,
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-100-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-100-nullable-string.verified.txt
new file mode 100644
index 000000000..049ea477a
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-100-nullable-string.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ type: object,
+ properties: {
+ value: {
+ maxLength: 100,
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-100-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-100-string.verified.txt
new file mode 100644
index 000000000..f593db1f5
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-100-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ maxLength: 100,
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-50-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-50-nullable-string.verified.txt
new file mode 100644
index 000000000..a480e4758
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-50-nullable-string.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ type: object,
+ properties: {
+ value: {
+ maxLength: 50,
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-50-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-50-string.verified.txt
new file mode 100644
index 000000000..0ac257539
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-max-length-50-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ maxLength: 50,
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-1-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-1-nullable-string.verified.txt
new file mode 100644
index 000000000..434c83df2
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-1-nullable-string.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ type: object,
+ properties: {
+ value: {
+ minLength: 1,
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-1-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-1-string.verified.txt
new file mode 100644
index 000000000..4e8304077
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-1-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ minLength: 1,
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-5-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-5-collection.verified.txt
new file mode 100644
index 000000000..ecb044f8f
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-5-collection.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ CollectionContainer: {
+ type: object,
+ properties: {
+ value: {
+ minItems: 5,
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-5-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-5-nullable-string.verified.txt
new file mode 100644
index 000000000..3b59eb5ec
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-5-nullable-string.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ type: object,
+ properties: {
+ value: {
+ minLength: 5,
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-5-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-5-string.verified.txt
new file mode 100644
index 000000000..d96be1c3b
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_length_properties_result=-min-length-5-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ minLength: 5,
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_regex_properties_result=-regex-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_regex_properties_result=-regex-collection.verified.txt
new file mode 100644
index 000000000..3a03e364f
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_regex_properties_result=-regex-collection.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ CollectionContainer: {
+ type: object,
+ properties: {
+ value: {
+ pattern: ^[a-zA-Z0-9]*$,
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_regex_properties_result=-regex-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_regex_properties_result=-regex-nullable-string.verified.txt
new file mode 100644
index 000000000..427787351
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_regex_properties_result=-regex-nullable-string.verified.txt
@@ -0,0 +1,14 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ type: object,
+ properties: {
+ value: {
+ pattern: ^[a-zA-Z0-9]*$,
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_regex_properties_result=-regex-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_regex_properties_result=-regex-string.verified.txt
new file mode 100644
index 000000000..91b8ac0cd
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_regex_properties_result=-regex-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ pattern: ^[a-zA-Z0-9]*$,
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-boolean.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-boolean.verified.txt
new file mode 100644
index 000000000..f4ecf85e6
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-boolean.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ BooleanContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: boolean
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-collection.verified.txt
new file mode 100644
index 000000000..df17ac39c
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-collection.verified.txt
@@ -0,0 +1,19 @@
+{
+ schemas: {
+ CollectionContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ minLength: 1,
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-decimal.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-decimal.verified.txt
new file mode 100644
index 000000000..5912a7f6c
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-decimal.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ DecimalContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-integer.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-integer.verified.txt
new file mode 100644
index 000000000..d21c40e0e
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-integer.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ IntegerContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-boolean.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-boolean.verified.txt
new file mode 100644
index 000000000..00a98546d
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-boolean.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableBooleanContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: boolean,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-decimal.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-decimal.verified.txt
new file mode 100644
index 000000000..f472689b2
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-decimal.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-integer.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-integer.verified.txt
new file mode 100644
index 000000000..0e05f92a8
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-integer.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-string.verified.txt
new file mode 100644
index 000000000..876d1bd81
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-nullable-string.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ minLength: 1,
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-string.verified.txt
new file mode 100644
index 000000000..4e8304077
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_and_min_length_result=-notempty-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ minLength: 1,
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-boolean.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-boolean.verified.txt
new file mode 100644
index 000000000..f4ecf85e6
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-boolean.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ BooleanContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: boolean
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-collection.verified.txt
new file mode 100644
index 000000000..6ab29be53
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-collection.verified.txt
@@ -0,0 +1,18 @@
+{
+ schemas: {
+ CollectionContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-decimal.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-decimal.verified.txt
new file mode 100644
index 000000000..5912a7f6c
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-decimal.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ DecimalContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-integer.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-integer.verified.txt
new file mode 100644
index 000000000..d21c40e0e
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-integer.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ IntegerContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-boolean.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-boolean.verified.txt
new file mode 100644
index 000000000..00a98546d
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-boolean.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableBooleanContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: boolean,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-decimal.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-decimal.verified.txt
new file mode 100644
index 000000000..f472689b2
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-decimal.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-integer.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-integer.verified.txt
new file mode 100644
index 000000000..0e05f92a8
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-integer.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-string.verified.txt
new file mode 100644
index 000000000..91f12472c
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-nullable-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-string.verified.txt
new file mode 100644
index 000000000..d03262f16
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/PropertyRuleHandlerTests.Should_generate_required_property_result=-notnull-string.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property.verified.txt
new file mode 100644
index 000000000..fe3db7e75
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property.verified.txt
@@ -0,0 +1,54 @@
+{
+ openapi: 3.0.1,
+ info: {
+ title: ReSharperTestRunner | v1,
+ version: 1.0.0
+ },
+ paths: {
+ /default/boolean: {
+ post: {
+ tags: [
+ ReSharperTestRunner
+ ],
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/BooleanContainer
+ }
+ }
+ }
+ },
+ responses: {
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/BooleanContainer
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ components: {
+ schemas: {
+ BooleanContainer: {
+ type: object,
+ properties: {
+ value: {
+ type: boolean
+ }
+ }
+ }
+ }
+ },
+ tags: [
+ {
+ name: ReSharperTestRunner
+ }
+ ]
+}
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-boolean.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-boolean.verified.txt
new file mode 100644
index 000000000..5f282702b
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-boolean.verified.txt
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-collection.verified.txt
new file mode 100644
index 000000000..5f282702b
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-collection.verified.txt
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-decimal.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-decimal.verified.txt
new file mode 100644
index 000000000..5f282702b
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-decimal.verified.txt
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-integer.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-integer.verified.txt
new file mode 100644
index 000000000..5f282702b
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-integer.verified.txt
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-string.verified.txt
new file mode 100644
index 000000000..5f282702b
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-default-string.verified.txt
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-boolean.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-boolean.verified.txt
new file mode 100644
index 000000000..f4ecf85e6
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-boolean.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ BooleanContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: boolean
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-collection.verified.txt
new file mode 100644
index 000000000..df17ac39c
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-collection.verified.txt
@@ -0,0 +1,19 @@
+{
+ schemas: {
+ CollectionContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ minLength: 1,
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-decimal.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-decimal.verified.txt
new file mode 100644
index 000000000..5912a7f6c
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-decimal.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ DecimalContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-integer.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-integer.verified.txt
new file mode 100644
index 000000000..d21c40e0e
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-integer.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ IntegerContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-boolean.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-boolean.verified.txt
new file mode 100644
index 000000000..00a98546d
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-boolean.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableBooleanContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: boolean,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-decimal.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-decimal.verified.txt
new file mode 100644
index 000000000..f472689b2
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-decimal.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-integer.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-integer.verified.txt
new file mode 100644
index 000000000..0e05f92a8
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-integer.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-string.verified.txt
new file mode 100644
index 000000000..876d1bd81
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-nullable-string.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ minLength: 1,
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-string.verified.txt
new file mode 100644
index 000000000..4e8304077
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notempty-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ minLength: 1,
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-boolean.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-boolean.verified.txt
new file mode 100644
index 000000000..f4ecf85e6
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-boolean.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ BooleanContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: boolean
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-collection.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-collection.verified.txt
new file mode 100644
index 000000000..6ab29be53
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-collection.verified.txt
@@ -0,0 +1,18 @@
+{
+ schemas: {
+ CollectionContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: array,
+ items: {
+ type: string
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-decimal.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-decimal.verified.txt
new file mode 100644
index 000000000..5912a7f6c
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-decimal.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ DecimalContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: number,
+ format: double
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-integer.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-integer.verified.txt
new file mode 100644
index 000000000..d21c40e0e
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-integer.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ IntegerContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: integer,
+ format: int32
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-boolean.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-boolean.verified.txt
new file mode 100644
index 000000000..00a98546d
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-boolean.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableBooleanContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: boolean,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-decimal.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-decimal.verified.txt
new file mode 100644
index 000000000..f472689b2
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-decimal.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableDecimalContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: number,
+ format: double,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-integer.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-integer.verified.txt
new file mode 100644
index 000000000..0e05f92a8
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-integer.verified.txt
@@ -0,0 +1,17 @@
+{
+ schemas: {
+ NullableIntegerContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: integer,
+ format: int32,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-string.verified.txt
new file mode 100644
index 000000000..91f12472c
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-nullable-string.verified.txt
@@ -0,0 +1,16 @@
+{
+ schemas: {
+ NullableStringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-string.verified.txt b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-string.verified.txt
new file mode 100644
index 000000000..d03262f16
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RequiredPropertyRuleTests.Should_generate_required_property_result=-notnull-string.verified.txt
@@ -0,0 +1,15 @@
+{
+ schemas: {
+ StringContainer: {
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: string
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/AspNetCore.FluentValidation.OpenApi.Tests/RuleTestBase.cs b/test/AspNetCore.FluentValidation.OpenApi.Tests/RuleTestBase.cs
new file mode 100644
index 000000000..e15df4b88
--- /dev/null
+++ b/test/AspNetCore.FluentValidation.OpenApi.Tests/RuleTestBase.cs
@@ -0,0 +1,257 @@
+using System.Runtime.CompilerServices;
+using System.Text.RegularExpressions;
+using Argon;
+using DiffEngine;
+using FluentValidation;
+using FluentValidation.AspNetCore;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.DependencyInjection;
+using Rocket.Surgery.LaunchPad.AspNetCore.FluentValidation.OpenApi;
+
+namespace AspNetCore.FluentValidation.OpenApi.Tests;
+
+class StringContainer
+{
+ public required string Value { get; set; }
+}
+
+class NullableStringContainer
+{
+ public string? Value { get; set; }
+}
+
+class CollectionContainer
+{
+ public IEnumerable Value { get; set; } = [];
+}
+
+class NullableIntegerContainer
+{
+ public int? Value { get; set; }
+}
+
+class IntegerContainer
+{
+ public int Value { get; set; }
+}
+
+class BooleanContainer
+{
+ public bool Value { get; set; }
+}
+
+class NullableBooleanContainer
+{
+ public bool? Value { get; set; }
+}
+
+class DecimalContainer
+{
+ public decimal Value { get; set; }
+}
+
+class NullableDecimalContainer
+{
+ public decimal? Value { get; set; }
+}
+
+[Experimental(Constants.ExperimentalId)]
+public class PropertyRuleHandlerTests : RuleTestBase
+{
+ [Theory]
+ [MemberData(nameof(GetNotNullValidators))]
+ public Task Should_generate_required_property(OpenApiResult result) => VerifyJson(result.JsonFactory()).UseParameters(result.Path);
+
+ [Theory]
+ [MemberData(nameof(GetNotEmptyValidators))]
+ public Task Should_generate_required_property_and_min_length(OpenApiResult result) => VerifyJson(result.JsonFactory()).UseParameters(result.Path);
+
+ [Theory]
+ [MemberData(nameof(GetLengthValidators))]
+ public Task Should_generate_length_properties(OpenApiResult result) => VerifyJson(result.JsonFactory()).UseParameters(result.Path);
+
+ [Theory]
+ [MemberData(nameof(RegularExpressionValidators))]
+ public Task Should_generate_regex_properties(OpenApiResult result) => VerifyJson(result.JsonFactory()).UseParameters(result.Path);
+
+ [Theory]
+ [MemberData(nameof(EmailAddressValidators))]
+ public Task Should_generate_email_properties(OpenApiResult result) => VerifyJson(result.JsonFactory()).UseParameters(result.Path);
+
+ [Theory]
+ [MemberData(nameof(ComparisonValidators))]
+ public Task Should_generate_comparison_properties(OpenApiResult result) => VerifyJson(result.JsonFactory()).UseParameters(result.Path);
+
+ [Theory]
+ [MemberData(nameof(BetweenValidators))]
+ public Task Should_generate_between_properties(OpenApiResult result) => VerifyJson(result.JsonFactory()).UseParameters(result.Path);
+
+ public static IEnumerable GetNotNullValidators()
+ {
+ yield return [GetOpenApiDocument("/notnull/boolean", x => x.RuleFor(y => y.Value).NotNull())];
+ yield return [GetOpenApiDocument("/notnull/collection", x => x.RuleFor(y => y.Value).NotNull())];
+ yield return [GetOpenApiDocument("/notnull/decimal", x => x.RuleFor(y => y.Value).NotNull())];
+ yield return [GetOpenApiDocument("/notnull/integer", x => x.RuleFor(y => y.Value).NotNull())];
+ yield return [GetOpenApiDocument("/notnull/string", x => x.RuleFor(y => y.Value).NotNull())];
+ yield return [GetOpenApiDocument("/notnull/nullable/boolean", x => x.RuleFor(y => y.Value).NotNull())];
+ yield return [GetOpenApiDocument("/notnull/nullable/decimal", x => x.RuleFor(y => y.Value).NotNull())];
+ yield return [GetOpenApiDocument("/notnull/nullable/integer", x => x.RuleFor(y => y.Value).NotNull())];
+ yield return [GetOpenApiDocument("/notnull/nullable/string", x => x.RuleFor(y => y.Value).NotNull())];
+ }
+
+ public static IEnumerable GetNotEmptyValidators()
+ {
+ yield return [GetOpenApiDocument("/notempty/boolean", x => x.RuleFor(y => y.Value).NotEmpty())];
+ yield return [GetOpenApiDocument("/notempty/collection", x => x.RuleFor(y => y.Value).NotEmpty())];
+ yield return [GetOpenApiDocument("/notempty/decimal", x => x.RuleFor(y => y.Value).NotEmpty())];
+ yield return [GetOpenApiDocument("/notempty/integer", x => x.RuleFor(y => y.Value).NotEmpty())];
+ yield return [GetOpenApiDocument("/notempty/string", x => x.RuleFor(y => y.Value).NotEmpty())];
+ yield return [GetOpenApiDocument("/notempty/nullable/boolean", x => x.RuleFor(y => y.Value).NotEmpty())];
+ yield return [GetOpenApiDocument("/notempty/nullable/decimal", x => x.RuleFor(y => y.Value).NotEmpty())];
+ yield return [GetOpenApiDocument("/notempty/nullable/integer", x => x.RuleFor(y => y.Value).NotEmpty())];
+ yield return [GetOpenApiDocument("/notempty/nullable/string", x => x.RuleFor(y => y.Value).NotEmpty())];
+ }
+
+ public static IEnumerable GetLengthValidators()
+ {
+ yield return [GetOpenApiDocument("/min-length-5/string", x => x.RuleFor(y => y.Value).MinimumLength(5))];
+ yield return [GetOpenApiDocument("/max-length-100/string", x => x.RuleFor(y => y.Value).MaximumLength(100))];
+ yield return [GetOpenApiDocument("/length-5-50/string", x => x.RuleFor(y => y.Value).Length(5, 50))];
+ yield return [GetOpenApiDocument("/min-length-5/nullable/string", x => x.RuleFor(y => y.Value).MinimumLength(5))];
+ yield return [GetOpenApiDocument("/max-length-100/nullable/string", x => x.RuleFor(y => y.Value).MaximumLength(100))];
+ yield return [GetOpenApiDocument("/length-5-50/nullable/string", x => x.RuleFor(y => y.Value).Length(5, 50))];
+ yield return [GetOpenApiDocument("/min-length-5/collection", x => x.RuleForEach(y => y.Value).MinimumLength(5))];
+ yield return [GetOpenApiDocument("/max-length-100/collection", x => x.RuleForEach(y => y.Value).MaximumLength(100))];
+ yield return [GetOpenApiDocument("/length-5-50/collection", x => x.RuleForEach(y => y.Value).Length(5, 50))];
+ }
+
+ public static IEnumerable RegularExpressionValidators()
+ {
+ yield return [GetOpenApiDocument("/regex/string", x => x.RuleFor(y => y.Value).Matches(new Regex("^[a-zA-Z0-9]*$")))];
+ yield return [GetOpenApiDocument("/regex/nullable/string", x => x.RuleFor(y => y.Value).Matches(new Regex("^[a-zA-Z0-9]*$")))];
+ yield return [GetOpenApiDocument("/regex/collection", x => x.RuleForEach(y => y.Value).Matches(new Regex("^[a-zA-Z0-9]*$")))];
+ }
+
+ public static IEnumerable EmailAddressValidators()
+ {
+ yield return [GetOpenApiDocument("/email/string", x => x.RuleFor(y => y.Value).EmailAddress())];
+ yield return [GetOpenApiDocument("/email/nullable/string", x => x.RuleFor(y => y.Value).EmailAddress())];
+ yield return [GetOpenApiDocument("/email/collection", x => x.RuleForEach(y => y.Value).EmailAddress())];
+ }
+
+ public static IEnumerable ComparisonValidators()
+ {
+ yield return [GetOpenApiDocument("/comparison/decimal/gt", x => x.RuleFor(y => y.Value).GreaterThan(2.1m))];
+ yield return [GetOpenApiDocument("/comparison/decimal/gte", x => x.RuleFor(y => y.Value).GreaterThanOrEqualTo(2.1m))];
+ yield return [GetOpenApiDocument("/comparison/decimal/lt", x => x.RuleFor(y => y.Value).LessThan(1.1m))];
+ yield return [GetOpenApiDocument("/comparison/decimal/lte", x => x.RuleFor(y => y.Value).LessThanOrEqualTo(1.1m))];
+ yield return [GetOpenApiDocument("/comparison/decimal/gtlte", x => x.RuleFor(y => y.Value).GreaterThan(1.1m).LessThanOrEqualTo(2.2m))];
+ yield return [GetOpenApiDocument("/comparison/decimal/gtelt", x => x.RuleFor(y => y.Value).GreaterThanOrEqualTo(1.1m).LessThan(2.2m))];
+
+ yield return [GetOpenApiDocument("/comparison/integer/gt", x => x.RuleFor(y => y.Value).GreaterThan(2))];
+ yield return [GetOpenApiDocument("/comparison/integer/gte", x => x.RuleFor(y => y.Value).GreaterThanOrEqualTo(2))];
+ yield return [GetOpenApiDocument("/comparison/integer/lt", x => x.RuleFor(y => y.Value).LessThan(1))];
+ yield return [GetOpenApiDocument("/comparison/integer/lte", x => x.RuleFor(y => y.Value).LessThanOrEqualTo(1))];
+ yield return [GetOpenApiDocument("/comparison/integer/gtlte", x => x.RuleFor(y => y.Value).GreaterThan(2).LessThanOrEqualTo(10))];
+ yield return [GetOpenApiDocument("/comparison/integer/gtelt", x => x.RuleFor(y => y.Value).GreaterThanOrEqualTo(2).LessThan(11))];
+
+ yield return [GetOpenApiDocument("/comparison/nullable/integer/gt", x => x.RuleFor(y => y.Value).GreaterThan(2))];
+ yield return [GetOpenApiDocument("/comparison/nullable/integer/gte", x => x.RuleFor(y => y.Value).GreaterThanOrEqualTo(2))];
+ yield return [GetOpenApiDocument("/comparison/nullable/integer/lt", x => x.RuleFor(y => y.Value).LessThan(1))];
+ yield return [GetOpenApiDocument("/comparison/nullable/integer/lte", x => x.RuleFor(y => y.Value).LessThanOrEqualTo(1))];
+ yield return [GetOpenApiDocument("/comparison/nullable/integer/gtlte", x => x.RuleFor(y => y.Value).GreaterThan(2).LessThanOrEqualTo(10))];
+ yield return [GetOpenApiDocument("/comparison/nullable/integer/gtelt", x => x.RuleFor(y => y.Value).GreaterThanOrEqualTo(2).LessThan(11))];
+
+ yield return [GetOpenApiDocument("/comparison/nullable/decimal/gt", x => x.RuleFor(y => y.Value).GreaterThan(2.1m))];
+ yield return [GetOpenApiDocument("/comparison/nullable/decimal/gte", x => x.RuleFor(y => y.Value).GreaterThanOrEqualTo(2.1m))];
+ yield return [GetOpenApiDocument("/comparison/nullable/decimal/lt", x => x.RuleFor(y => y.Value).LessThan(1.1m))];
+ yield return [GetOpenApiDocument("/comparison/nullable/decimal/lte", x => x.RuleFor(y => y.Value).LessThanOrEqualTo(1.1m))];
+ yield return [GetOpenApiDocument("/comparison/nullable/decimal/gtlte", x => x.RuleFor(y => y.Value).GreaterThan(1.1m).LessThanOrEqualTo(2.2m))];
+ yield return [GetOpenApiDocument("/comparison/nullable/decimal/gtelt", x => x.RuleFor(y => y.Value).GreaterThanOrEqualTo(1.1m).LessThan(2.2m))];
+ }
+
+ public static IEnumerable BetweenValidators()
+ {
+ yield return [GetOpenApiDocument("/comparison/exclusive/decimal/gtlte", x => x.RuleFor(y => y.Value).ExclusiveBetween(1.1m, 2.2m))];
+ yield return [GetOpenApiDocument("/comparison/exclusive/decimal/gtelt", x => x.RuleFor(y => y.Value).ExclusiveBetween(1.1m, 2.2m))];
+ yield return [GetOpenApiDocument("/comparison/exclusive/integer/gtlte", x => x.RuleFor(y => y.Value).ExclusiveBetween(2, 10))];
+ yield return [GetOpenApiDocument("/comparison/exclusive/integer/gtelt", x => x.RuleFor(y => y.Value).ExclusiveBetween(2, 11))];
+ yield return [GetOpenApiDocument("/comparison/exclusive/nullable/integer/gtlte", x => x.RuleFor(y => y.Value).ExclusiveBetween(2, 10))];
+ yield return [GetOpenApiDocument("/comparison/exclusive/nullable/integer/gtelt", x => x.RuleFor(y => y.Value).ExclusiveBetween(2, 11))];
+ yield return [GetOpenApiDocument("/comparison/exclusive/nullable/decimal/gtlte", x => x.RuleFor(y => y.Value).ExclusiveBetween(1.1m, 2.2m))];
+ yield return [GetOpenApiDocument("/comparison/exclusive/nullable/decimal/gtelt", x => x.RuleFor(y => y.Value).ExclusiveBetween(1.1m, 2.2m))];
+
+ yield return [GetOpenApiDocument("/comparison/inclusive/decimal/gtlte", x => x.RuleFor(y => y.Value).InclusiveBetween(1.1m, 2.2m))];
+ yield return [GetOpenApiDocument("/comparison/inclusive/decimal/gtelt", x => x.RuleFor(y => y.Value).InclusiveBetween(1.1m, 2.2m))];
+ yield return [GetOpenApiDocument("/comparison/inclusive/integer/gtlte", x => x.RuleFor(y => y.Value).InclusiveBetween(2, 10))];
+ yield return [GetOpenApiDocument("/comparison/inclusive/integer/gtelt", x => x.RuleFor(y => y.Value).InclusiveBetween(2, 11))];
+ yield return [GetOpenApiDocument("/comparison/inclusive/nullable/integer/gtlte", x => x.RuleFor(y => y.Value).InclusiveBetween(2, 10))];
+ yield return [GetOpenApiDocument("/comparison/inclusive/nullable/integer/gtelt", x => x.RuleFor(y => y.Value).InclusiveBetween(2, 11))];
+ yield return [GetOpenApiDocument("/comparison/inclusive/nullable/decimal/gtlte", x => x.RuleFor(y => y.Value).InclusiveBetween(1.1m, 2.2m))];
+ yield return [GetOpenApiDocument("/comparison/inclusive/nullable/decimal/gtelt", x => x.RuleFor(y => y.Value).InclusiveBetween(1.1m, 2.2m))];
+ }
+
+ private static OpenApiResult GetOpenApiDocument(string path, Action> configureValidator)
+ {
+ return new(
+ path,
+ async () =>
+ {
+ var builder = WebApplication.CreateSlimBuilder(
+ new WebApplicationOptions()
+ {
+ ApplicationName = typeof(TObject).Name,
+ }
+ );
+ builder.WebHost.UseTestServer();
+ builder.Services.AddOpenApi();
+ builder.Services.AddFluentValidationAutoValidation();
+ builder.Services.AddFluentValidationOpenApi();
+ var validator = new InlineValidator();
+ configureValidator(validator);
+ builder.Services.AddSingleton>(validator);
+
+ #pragma warning disable CA2007
+ await using var app = builder.Build();
+
+ app.MapOpenApi();
+
+ app.MapPost(path, (TObject container) => container);
+
+ await app.StartAsync().ConfigureAwait(false);
+ var testServer = (TestServer)app.Services.GetRequiredService();
+ var _client = testServer.CreateClient();
+
+ var response = await _client.GetAsync("/openapi/v1.json");
+ response.EnsureSuccessStatusCode();
+ var json = JObject.Parse(await response.Content.ReadAsStringAsync());
+ return json["components"].ToString();
+ #pragma warning restore CA2007
+ }
+ );
+ }
+}
+
+public record OpenApiResult(string Path, Func> JsonFactory)
+{
+ public override string ToString() => Path;
+}
+
+static class ModuleInitializer
+{
+ [ModuleInitializer]
+ public static void Initialize()
+ {
+ DiffRunner.Disabled = true;
+ DiffTools.UseOrder(DiffTool.Rider, DiffTool.VisualStudioCode, DiffTool.VisualStudio);
+// Verify
+ }
+}
+
+#pragma warning disable RSGEXP
+public abstract class RuleTestBase
+ #pragma warning restore RSGEXP
+{ }
diff --git a/test/AspNetCore.Tests/AspNetCore.Tests.csproj b/test/AspNetCore.Tests/AspNetCore.Tests.csproj
index 0dcffc9ef..e4cfa1656 100644
--- a/test/AspNetCore.Tests/AspNetCore.Tests.csproj
+++ b/test/AspNetCore.Tests/AspNetCore.Tests.csproj
@@ -1,9 +1,9 @@
-
- net8.0
-
-
-
-
-
+
+ net9.0
+
+
+
+
+
diff --git a/test/AspNetCore.Tests/Restful/RestfulApiMethodBuilderTests.cs b/test/AspNetCore.Tests/Restful/RestfulApiMethodBuilderTests.cs
index e53645b8a..a4519548b 100644
--- a/test/AspNetCore.Tests/Restful/RestfulApiMethodBuilderTests.cs
+++ b/test/AspNetCore.Tests/Restful/RestfulApiMethodBuilderTests.cs
@@ -2,13 +2,12 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.AspNetCore;
using Rocket.Surgery.LaunchPad.AspNetCore.Composition;
namespace AspNetCore.Tests.Restful;
-public class RestfulApiMethodBuilderTests(ITestOutputHelper testOutputHelper) : LoggerTest(testOutputHelper)
+public class RestfulApiMethodBuilderTests(ITestOutputHelper testOutputHelper) : LoggerTest(XUnitDefaults.CreateTestContext(testOutputHelper))
{
[Fact]
public void Should_Have_Method()
diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets
index 944095f16..2bfb719a2 100644
--- a/test/Directory.Build.targets
+++ b/test/Directory.Build.targets
@@ -4,7 +4,7 @@
-
+
@@ -18,14 +18,14 @@
-
+
-
\ No newline at end of file
+
diff --git a/test/Extensions.Tests/ChangeTrackingTests.cs b/test/Extensions.Tests/ChangeTrackingTests.cs
index 1f7de03ce..ed72e056a 100644
--- a/test/Extensions.Tests/ChangeTrackingTests.cs
+++ b/test/Extensions.Tests/ChangeTrackingTests.cs
@@ -1,17 +1,16 @@
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Foundation;
namespace Extensions.Tests;
-public partial class ChangeTrackingTests(ITestOutputHelper testOutputHelper) : LoggerTest(testOutputHelper)
+public partial class ChangeTrackingTests(ITestOutputHelper testOutputHelper) : LoggerTest(XUnitDefaults.CreateTestContext(testOutputHelper))
{
[Fact]
public void ShouldTrackChanges_For_Classes()
{
var tracking = new ClassWithTracking(1);
- tracking.Name.HasBeenSet().Should().BeFalse();
+ tracking.Name.HasValue.Should().BeFalse();
tracking.Name = "Test";
- tracking.Name.HasBeenSet().Should().BeTrue();
+ tracking.Name.HasValue.Should().BeTrue();
}
[Fact]
@@ -22,7 +21,7 @@ public void ShouldResetChanges_For_Classes()
Name = "Test",
};
tracking.ResetChanges();
- tracking.Name.HasBeenSet().Should().BeFalse();
+ tracking.Name.HasValue.Should().BeFalse();
}
[Fact]
@@ -51,8 +50,8 @@ public void ShouldCreate_For_Classes()
};
var tracking = ClassWithTracking.TrackChanges(instance);
tracking.Description = "My New description";
- tracking.Name.HasBeenSet().Should().BeFalse();
- tracking.Description.HasBeenSet().Should().BeTrue();
+ tracking.Name.HasValue.Should().BeFalse();
+ tracking.Description.HasValue.Should().BeTrue();
tracking.ApplyChanges(instance);
instance.Name.Should().Be("MyName");
@@ -63,9 +62,9 @@ public void ShouldCreate_For_Classes()
public void ShouldTrackChanges_For_Records()
{
var tracking = new RecordWithTracking(1);
- tracking.Name.HasBeenSet().Should().BeFalse();
+ tracking.Name.HasValue.Should().BeFalse();
tracking.Name = "Test";
- tracking.Name.HasBeenSet().Should().BeTrue();
+ tracking.Name.HasValue.Should().BeTrue();
}
[Fact]
@@ -76,7 +75,7 @@ public void ShouldResetChanges_For_Records()
Name = "Test",
};
tracking.ResetChanges();
- tracking.Name.HasBeenSet().Should().BeFalse();
+ tracking.Name.HasValue.Should().BeFalse();
}
[Fact]
@@ -101,8 +100,8 @@ public void ShouldCreate_For_Records()
};
var tracking = RecordWithTracking.TrackChanges(instance);
tracking.Description = "My New description";
- tracking.Name.HasBeenSet().Should().BeFalse();
- tracking.Description.HasBeenSet().Should().BeTrue();
+ tracking.Name.HasValue.Should().BeFalse();
+ tracking.Description.HasValue.Should().BeTrue();
instance = tracking.ApplyChanges(instance);
instance.Name.Should().Be("MyName");
@@ -127,4 +126,4 @@ public partial record Record(int Id, string? Name)
}
public partial record RecordWithTracking(int Id) : IPropertyTracking;
-}
\ No newline at end of file
+}
diff --git a/test/Extensions.Tests/ConventionFakeTest.cs b/test/Extensions.Tests/ConventionFakeTest.cs
index 773999ba5..52c79c609 100644
--- a/test/Extensions.Tests/ConventionFakeTest.cs
+++ b/test/Extensions.Tests/ConventionFakeTest.cs
@@ -2,18 +2,18 @@
using Microsoft.Extensions.DependencyInjection;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.Testing;
-using Rocket.Surgery.Extensions.Testing;
namespace Extensions.Tests;
-public abstract class ConventionFakeTest(ITestOutputHelper testOutputHelper) : AutoFakeTest(testOutputHelper)
+public abstract class ConventionFakeTest(ITestOutputHelper testOutputHelper) : AutoFakeTest(XUnitDefaults.CreateTestContext(testOutputHelper))
{
protected async Task Init(Action? action = null)
{
+ var factory = CreateLoggerFactory();
var conventionContextBuilder = ConventionContextBuilder
.Create()
- .ForTesting(Imports.Instance, LoggerFactory)
- .WithLogger(Logger);
+ .ForTesting(Imports.Instance, factory)
+ .WithLogger(factory.CreateLogger("Test"));
action?.Invoke(conventionContextBuilder);
var context = await ConventionContext.FromAsync(conventionContextBuilder);
@@ -22,4 +22,4 @@ protected async Task Init(Action? action = null)
Populate(await new ServiceCollection().ApplyConventionsAsync(context));
}
-}
\ No newline at end of file
+}
diff --git a/test/Extensions.Tests/Extensions.Tests.csproj b/test/Extensions.Tests/Extensions.Tests.csproj
index 58a56169b..f81acb15b 100644
--- a/test/Extensions.Tests/Extensions.Tests.csproj
+++ b/test/Extensions.Tests/Extensions.Tests.csproj
@@ -1,16 +1,16 @@
- net8.0
+ net8.0;net9.0
-
+
-
-
+
+
(XUnitDefaults.CreateTestContext(testOutputHelper))
{
protected SettingsTask VerifyMethod(MethodResult result, object mapper, params object[] instances)
{
diff --git a/test/Extensions.Tests/MediatRTests.cs b/test/Extensions.Tests/MediatRTests.cs
index 987814902..dc0efbd24 100644
--- a/test/Extensions.Tests/MediatRTests.cs
+++ b/test/Extensions.Tests/MediatRTests.cs
@@ -4,13 +4,11 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Rocket.Surgery.Conventions;
-using Rocket.Surgery.Conventions.Reflection;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Foundation.Conventions;
namespace Extensions.Tests;
-public class MediatRTests(ITestOutputHelper outputHelper) : AutoFakeTest(outputHelper)
+public class MediatRTests(ITestOutputHelper outputHelper) : AutoFakeTest(XUnitDefaults.CreateTestContext(outputHelper))
{
[Fact]
public async Task Test1()
@@ -76,42 +74,6 @@ public async Task Test2()
.MustHaveHappenedOnceExactly();
}
- private class TestAssemblyProvider : IAssemblyProvider
- {
- public IEnumerable GetAssemblies()
- {
- return new[]
- {
- typeof(TestAssemblyProvider).GetTypeInfo().Assembly,
- typeof(MediatRConvention).GetTypeInfo().Assembly,
- };
- }
-
- public IEnumerable GetAssemblies(
- Action action,
- int lineNumber = 0,
- string filePath = "",
- string argumentExpression = ""
- )
- {
- return new[]
- {
- typeof(TestAssemblyProvider).GetTypeInfo().Assembly,
- typeof(MediatRConvention).GetTypeInfo().Assembly,
- };
- }
-
- public IEnumerable GetTypes(
- Func> selector,
- int lineNumber = 0,
- string filePath = "",
- string argumentExpression = ""
- )
- {
- return Enumerable.Empty();
- }
- }
-
public class Request : IRequest;
private class TestHandler : IRequestHandler
diff --git a/test/Extensions.Tests/ModuleInitializer.cs b/test/Extensions.Tests/ModuleInitializer.cs
index 36a7a529a..102d13bf0 100644
--- a/test/Extensions.Tests/ModuleInitializer.cs
+++ b/test/Extensions.Tests/ModuleInitializer.cs
@@ -28,4 +28,4 @@ static string GetTypeName(Type type)
}
);
}
-}
\ No newline at end of file
+}
diff --git a/test/Extensions.Tests/NewtonsoftJsonNetTopologySuiteGeoJsonTests.cs b/test/Extensions.Tests/NewtonsoftJsonNetTopologySuiteGeoJsonTests.cs
index 2d2bd173b..28b379655 100644
--- a/test/Extensions.Tests/NewtonsoftJsonNetTopologySuiteGeoJsonTests.cs
+++ b/test/Extensions.Tests/NewtonsoftJsonNetTopologySuiteGeoJsonTests.cs
@@ -1,12 +1,11 @@
using FluentAssertions.Primitives;
using NetTopologySuite.Geometries;
using Newtonsoft.Json;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Spatial;
namespace Extensions.Tests;
-public class NewtonsoftJsonNetTopologySuiteGeoJsonTests(ITestOutputHelper outputHelper) : LoggerTest(outputHelper)
+public class NewtonsoftJsonNetTopologySuiteGeoJsonTests(ITestOutputHelper outputHelper) : LoggerTest(XUnitDefaults.CreateTestContext(outputHelper))
{
private readonly JsonSerializerSettings _settings = new JsonSerializerSettings().ConfigureGeoJsonForLaunchPad(null);
diff --git a/test/Extensions.Tests/NewtonsoftJsonNetTopologySuiteWellKnownTextTests.cs b/test/Extensions.Tests/NewtonsoftJsonNetTopologySuiteWellKnownTextTests.cs
index 8a42a267f..2dc3e29ec 100644
--- a/test/Extensions.Tests/NewtonsoftJsonNetTopologySuiteWellKnownTextTests.cs
+++ b/test/Extensions.Tests/NewtonsoftJsonNetTopologySuiteWellKnownTextTests.cs
@@ -1,12 +1,11 @@
using FluentAssertions.Primitives;
using NetTopologySuite.Geometries;
using Newtonsoft.Json;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Spatial;
namespace Extensions.Tests;
-public class NewtonsoftJsonNetTopologySuiteWellKnownTextTests(ITestOutputHelper outputHelper) : LoggerTest(outputHelper)
+public class NewtonsoftJsonNetTopologySuiteWellKnownTextTests(ITestOutputHelper outputHelper) : LoggerTest(XUnitDefaults.CreateTestContext(outputHelper))
{
private static T DeserializeObject(string geom, JsonSerializerSettings settings)
{
diff --git a/test/Extensions.Tests/NewtonsoftJsonNodaTimeTests.cs b/test/Extensions.Tests/NewtonsoftJsonNodaTimeTests.cs
index 5673629eb..fc7f20c99 100644
--- a/test/Extensions.Tests/NewtonsoftJsonNodaTimeTests.cs
+++ b/test/Extensions.Tests/NewtonsoftJsonNodaTimeTests.cs
@@ -1,11 +1,10 @@
using Newtonsoft.Json;
using NodaTime;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Foundation;
namespace Extensions.Tests;
-public class NewtonsoftJsonNodaTimeTests(ITestOutputHelper outputHelper) : LoggerTest(outputHelper)
+public class NewtonsoftJsonNodaTimeTests(ITestOutputHelper outputHelper) : LoggerTest(XUnitDefaults.CreateTestContext(outputHelper))
{
private JsonSerializerSettings _settings = new JsonSerializerSettings()
.ConfigureNodaTimeForLaunchPad(DateTimeZoneProviders.Tzdb);
diff --git a/test/Extensions.Tests/SerilogDestructuringTests.cs b/test/Extensions.Tests/SerilogDestructuringTests.cs
index 9e94f0a52..53fbbd994 100644
--- a/test/Extensions.Tests/SerilogDestructuringTests.cs
+++ b/test/Extensions.Tests/SerilogDestructuringTests.cs
@@ -5,21 +5,21 @@
using Newtonsoft.Json.Linq;
using NodaTime;
using NodaTime.Testing;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Foundation;
using Rocket.Surgery.LaunchPad.Spatial;
using Serilog.Context;
+using Serilog.Events;
namespace Extensions.Tests;
-public class SerilogDestructuringTests : LoggerTest
+public class SerilogDestructuringTests : LoggerTest
{
[Fact]
public async Task Should_Destructure_Sjt_Values_JsonElement()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation(
+ Logger.Information(
"This is just a test {@Data}",
JsonSerializer.Deserialize(JsonSerializer.Serialize(new { test = true, system = new { data = "1234", }, }), options: null)
);
@@ -32,7 +32,7 @@ public async Task Should_Destructure_Sjt_Values_JsonDocument()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation(
+ Logger.Information(
"This is just a test {@Data}",
JsonSerializer.Deserialize(JsonSerializer.Serialize(new { test = true, system = new { data = "1234", }, }), options: null)
);
@@ -45,7 +45,7 @@ public async Task Should_Destructure_NewtonsoftJson_JObject()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", JObject.FromObject(new { test = true, system = new { data = "1234", }, }));
+ Logger.Information("This is just a test {@Data}", JObject.FromObject(new { test = true, system = new { data = "1234", }, }));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -55,7 +55,7 @@ public async Task Should_Destructure_NewtonsoftJson_JArray()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", JArray.FromObject(new object[] { 1, "2", 3d, }));
+ Logger.Information("This is just a test {@Data}", JArray.FromObject(new object[] { 1, "2", 3d, }));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -69,7 +69,7 @@ public async Task Should_Destructure_NewtonsoftJson_JValue()
};
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", new JValue(faker.Random.Guid()));
+ Logger.Information("This is just a test {@Data}", new JValue(faker.Random.Guid()));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -85,7 +85,7 @@ public async Task Should_Destructure_NetTopologySuite_AttributesTable()
);
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", value);
+ Logger.Information("This is just a test {@Data}", value);
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -93,7 +93,7 @@ public async Task Should_Destructure_NetTopologySuite_AttributesTable()
public async Task Should_Destructure_NodaTime_Instant()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", _clock.GetCurrentInstant());
+ Logger.Information("This is just a test {@Data}", _clock.GetCurrentInstant());
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -101,7 +101,7 @@ public async Task Should_Destructure_NodaTime_Instant()
public async Task Should_Destructure_NodaTime_LocalDateTime()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", LocalDateTime.FromDateTime(_clock.GetCurrentInstant().ToDateTimeUtc()));
+ Logger.Information("This is just a test {@Data}", LocalDateTime.FromDateTime(_clock.GetCurrentInstant().ToDateTimeUtc()));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -109,7 +109,7 @@ public async Task Should_Destructure_NodaTime_LocalDateTime()
public async Task Should_Destructure_NodaTime_LocalDate()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", LocalDate.FromDateTime(_clock.GetCurrentInstant().ToDateTimeUtc()));
+ Logger.Information("This is just a test {@Data}", LocalDate.FromDateTime(_clock.GetCurrentInstant().ToDateTimeUtc()));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -117,7 +117,7 @@ public async Task Should_Destructure_NodaTime_LocalDate()
public async Task Should_Destructure_NodaTime_LocalTime()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", LocalTime.FromHoursSinceMidnight(4));
+ Logger.Information("This is just a test {@Data}", LocalTime.FromHoursSinceMidnight(4));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -125,7 +125,7 @@ public async Task Should_Destructure_NodaTime_LocalTime()
public async Task Should_Destructure_NodaTime_OffsetDateTime()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", OffsetDateTime.FromDateTimeOffset(_clock.GetCurrentInstant().ToDateTimeOffset()));
+ Logger.Information("This is just a test {@Data}", OffsetDateTime.FromDateTimeOffset(_clock.GetCurrentInstant().ToDateTimeOffset()));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -133,7 +133,7 @@ public async Task Should_Destructure_NodaTime_OffsetDateTime()
public async Task Should_Destructure_NodaTime_OffsetDate()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", OffsetDateTime.FromDateTimeOffset(_clock.GetCurrentInstant().ToDateTimeOffset()).ToOffsetDate());
+ Logger.Information("This is just a test {@Data}", OffsetDateTime.FromDateTimeOffset(_clock.GetCurrentInstant().ToDateTimeOffset()).ToOffsetDate());
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -141,7 +141,7 @@ public async Task Should_Destructure_NodaTime_OffsetDate()
public async Task Should_Destructure_NodaTime_OffsetTime()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", OffsetDateTime.FromDateTimeOffset(_clock.GetCurrentInstant().ToDateTimeOffset()).ToOffsetTime());
+ Logger.Information("This is just a test {@Data}", OffsetDateTime.FromDateTimeOffset(_clock.GetCurrentInstant().ToDateTimeOffset()).ToOffsetTime());
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -149,7 +149,7 @@ public async Task Should_Destructure_NodaTime_OffsetTime()
public async Task Should_Destructure_NodaTime_ZonedDateTime()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", ZonedDateTime.FromDateTimeOffset(_clock.GetCurrentInstant().ToDateTimeOffset()));
+ Logger.Information("This is just a test {@Data}", ZonedDateTime.FromDateTimeOffset(_clock.GetCurrentInstant().ToDateTimeOffset()));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -157,7 +157,7 @@ public async Task Should_Destructure_NodaTime_ZonedDateTime()
public async Task Should_Destructure_NodaTime_DateTimeZone()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", DateTimeZoneProviders.Tzdb["America/New_York"]);
+ Logger.Information("This is just a test {@Data}", DateTimeZoneProviders.Tzdb["America/New_York"]);
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -165,7 +165,7 @@ public async Task Should_Destructure_NodaTime_DateTimeZone()
public async Task Should_Destructure_NodaTime_Duration()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", Duration.FromDays(1));
+ Logger.Information("This is just a test {@Data}", Duration.FromDays(1));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -173,7 +173,7 @@ public async Task Should_Destructure_NodaTime_Duration()
public async Task Should_Destructure_NodaTime_Period()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", Period.FromDays(1));
+ Logger.Information("This is just a test {@Data}", Period.FromDays(1));
await Verify(logs.Select(z => z.RenderMessage()));
}
@@ -181,19 +181,22 @@ public async Task Should_Destructure_NodaTime_Period()
public async Task Should_Destructure_NodaTime_Interval()
{
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", new Interval(_clock.GetCurrentInstant(), _clock.GetCurrentInstant()));
+ Logger.Information("This is just a test {@Data}", new Interval(_clock.GetCurrentInstant(), _clock.GetCurrentInstant()));
await Verify(logs.Select(z => z.RenderMessage()));
}
public SerilogDestructuringTests(ITestOutputHelper outputHelper) : base(
- outputHelper,
- LogLevel.Information,
- configureLogger: configuration => configuration
- .Destructure.NewtonsoftJsonTypes()
- .Destructure.SystemTextJsonTypes()
- .Destructure.NetTopologySuiteTypes()
- .Destructure.NodaTimeTypes(DateTimeZoneProviders.Tzdb)
+ XUnitTestContext.Create(
+ outputHelper,
+ LogEventLevel.Information,
+ configureLogger: (_, configuration) => configuration
+ .Destructure.NewtonsoftJsonTypes()
+ .Destructure.SystemTextJsonTypes()
+ .Destructure.NetTopologySuiteTypes()
+ .Destructure.NodaTimeTypes()
+ )
)
+
{
LogContext.PushProperty("SourceContext", nameof(SerilogDestructuringTests));
_clock = new(
@@ -241,7 +244,7 @@ public async Task Should_Destructure_NetTopologySuite_FeatureCollection(OgcGeome
}
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", fc);
+ Logger.Information("This is just a test {@Data}", fc);
await Verify(logs.Select(z => z.RenderMessage())).UseParameters(type, num, threeD);
}
@@ -263,7 +266,7 @@ public async Task Should_Destructure_NetTopologySuite_Geometry(OgcGeometryType t
var geometry = new FeatureFactory().CreateRandomGeometry(type, threeD);
using var _ = CaptureLogs(out var logs);
- Logger.LogInformation("This is just a test {@Data}", geometry);
+ Logger.Information("This is just a test {@Data}", geometry);
await Verify(logs.Select(z => z.RenderMessage())).UseParameters(type, threeD);
}
-}
\ No newline at end of file
+}
diff --git a/test/Extensions.Tests/StringInValidatorTests.cs b/test/Extensions.Tests/StringInValidatorTests.cs
index 6bda48b1f..6a56741e2 100644
--- a/test/Extensions.Tests/StringInValidatorTests.cs
+++ b/test/Extensions.Tests/StringInValidatorTests.cs
@@ -95,4 +95,4 @@ public Validator()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Extensions.Tests/SystemTextJsonNetTopologySuiteGeoJsonTests.cs b/test/Extensions.Tests/SystemTextJsonNetTopologySuiteGeoJsonTests.cs
index a01dda36f..decf8237c 100644
--- a/test/Extensions.Tests/SystemTextJsonNetTopologySuiteGeoJsonTests.cs
+++ b/test/Extensions.Tests/SystemTextJsonNetTopologySuiteGeoJsonTests.cs
@@ -1,12 +1,11 @@
using System.Text.Json;
using FluentAssertions.Primitives;
using NetTopologySuite.Geometries;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Spatial;
namespace Extensions.Tests;
-public class SystemTextJsonNetTopologySuiteGeoJsonTests(ITestOutputHelper outputHelper) : LoggerTest(outputHelper)
+public class SystemTextJsonNetTopologySuiteGeoJsonTests(ITestOutputHelper outputHelper) : LoggerTest(XUnitDefaults.CreateTestContext(outputHelper))
{
private readonly JsonSerializerOptions _settings = new JsonSerializerOptions().ConfigureGeoJsonForLaunchPad(null);
diff --git a/test/Extensions.Tests/SystemTextJsonNetTopologySuiteWellKnownTextTests.cs b/test/Extensions.Tests/SystemTextJsonNetTopologySuiteWellKnownTextTests.cs
index 13aba10e9..ae64ed43a 100644
--- a/test/Extensions.Tests/SystemTextJsonNetTopologySuiteWellKnownTextTests.cs
+++ b/test/Extensions.Tests/SystemTextJsonNetTopologySuiteWellKnownTextTests.cs
@@ -1,12 +1,11 @@
using System.Text.Json;
using FluentAssertions.Primitives;
using NetTopologySuite.Geometries;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Spatial;
namespace Extensions.Tests;
-public class SystemTextJsonNetTopologySuiteWellKnownTextTests(ITestOutputHelper outputHelper) : LoggerTest(outputHelper)
+public class SystemTextJsonNetTopologySuiteWellKnownTextTests(ITestOutputHelper outputHelper) : LoggerTest(XUnitDefaults.CreateTestContext(outputHelper))
{
private static T DeserializeObject(string geom, JsonSerializerOptions settings)
{
diff --git a/test/Extensions.Tests/SystemTextJsonNodaTimeTests.cs b/test/Extensions.Tests/SystemTextJsonNodaTimeTests.cs
index c3483b8e2..9a7770f5d 100644
--- a/test/Extensions.Tests/SystemTextJsonNodaTimeTests.cs
+++ b/test/Extensions.Tests/SystemTextJsonNodaTimeTests.cs
@@ -1,11 +1,10 @@
using System.Text.Json;
using NodaTime;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Foundation;
namespace Extensions.Tests;
-public class SystemTextJsonNodaTimeTests(ITestOutputHelper outputHelper) : LoggerTest(outputHelper)
+public class SystemTextJsonNodaTimeTests(ITestOutputHelper outputHelper) : LoggerTest(XUnitDefaults.CreateTestContext(outputHelper))
{
private JsonSerializerOptions _settings = new JsonSerializerOptions().ConfigureNodaTimeForLaunchPad(DateTimeZoneProviders.Tzdb);
diff --git a/test/Extensions.Tests/Validation/HealthCheckOptionsValidationTests.cs b/test/Extensions.Tests/Validation/HealthCheckOptionsValidationTests.cs
index 6f8a53b49..b19682bcf 100644
--- a/test/Extensions.Tests/Validation/HealthCheckOptionsValidationTests.cs
+++ b/test/Extensions.Tests/Validation/HealthCheckOptionsValidationTests.cs
@@ -4,13 +4,12 @@
using Microsoft.Extensions.Options;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.Testing;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Foundation;
using Rocket.Surgery.LaunchPad.Foundation.Validation;
namespace Extensions.Tests.Validation;
-public class HealthCheckOptionsValidationTests(ITestOutputHelper outputHelper) : AutoFakeTest(outputHelper), IAsyncLifetime
+public class HealthCheckOptionsValidationTests(ITestOutputHelper outputHelper) : AutoFakeTest(XUnitDefaults.CreateTestContext(outputHelper)), IAsyncLifetime
{
[Fact]
public async Task Should_Validate_Options_And_Throw()
@@ -142,16 +141,17 @@ public Validator()
public async Task InitializeAsync()
{
+ var loggerFactory = CreateLoggerFactory();
var conventionContextBuilder = ConventionContextBuilder
.Create()
- .ForTesting(Imports.Instance, LoggerFactory)
+ .ForTesting(Imports.Instance, loggerFactory)
.Set(
new FoundationOptions
{
RegisterValidationOptionsAsHealthChecks = true,
}
)
- .WithLogger(Logger);
+ .WithLogger(loggerFactory.CreateLogger("Test"));
var context = await ConventionContext.FromAsync(conventionContextBuilder);
Populate(await new ServiceCollection().ApplyConventionsAsync(context));
@@ -161,4 +161,4 @@ public Task DisposeAsync()
{
return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/test/Extensions.Tests/Validation/OptionsValidationTests.cs b/test/Extensions.Tests/Validation/OptionsValidationTests.cs
index e89b329d3..1736fa5df 100644
--- a/test/Extensions.Tests/Validation/OptionsValidationTests.cs
+++ b/test/Extensions.Tests/Validation/OptionsValidationTests.cs
@@ -4,12 +4,11 @@
using Microsoft.Extensions.Options;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.Testing;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Foundation;
namespace Extensions.Tests.Validation;
-public class OptionsValidationTests(ITestOutputHelper outputHelper) : AutoFakeTest(outputHelper), IAsyncLifetime
+public class OptionsValidationTests(ITestOutputHelper outputHelper) : AutoFakeTest(XUnitDefaults.CreateTestContext(outputHelper)), IAsyncLifetime
{
[Fact]
public async Task Should_Validate_Options_And_Throw()
@@ -88,11 +87,12 @@ public Validator()
public async Task InitializeAsync()
{
+ var loggerFactory = CreateLoggerFactory();
var conventionContextBuilder = ConventionContextBuilder
.Create()
- .ForTesting(Imports.Instance, LoggerFactory)
+ .ForTesting(Imports.Instance, loggerFactory)
.Set(new FoundationOptions { RegisterValidationOptionsAsHealthChecks = false, })
- .WithLogger(Logger);
+ .WithLogger(loggerFactory.CreateLogger("Test"));
var context = await ConventionContext.FromAsync(conventionContextBuilder);
Populate(await new ServiceCollection().ApplyConventionsAsync(context));
@@ -102,4 +102,4 @@ public Task DisposeAsync()
{
return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/test/Extensions.Tests/Validation/ValidatorFactoryTests.cs b/test/Extensions.Tests/Validation/ValidatorFactoryTests.cs
index b8b1eef1d..7f7145dc5 100644
--- a/test/Extensions.Tests/Validation/ValidatorFactoryTests.cs
+++ b/test/Extensions.Tests/Validation/ValidatorFactoryTests.cs
@@ -1,10 +1,9 @@
using FluentValidation;
-using Microsoft.Extensions.Logging;
-using Rocket.Surgery.Extensions.Testing;
+using Serilog.Events;
namespace Extensions.Tests.Validation;
-public class ValidatorFactoryTests(ITestOutputHelper outputHelper) : AutoFakeTest(outputHelper, LogLevel.Information)
+public class ValidatorFactoryTests(ITestOutputHelper outputHelper) : AutoFakeTest(XUnitTestContext.Create(outputHelper, LogEventLevel.Information))
{
// [Fact]
// public void Should_Aggregate_Validators()
@@ -25,7 +24,7 @@ public interface IThing
public string? Thing { get; set; }
}
- private class AModel : IThing
+ public class AModel : IThing
{
[UsedImplicitly] public string? Id { get; set; }
[UsedImplicitly] public string? Other { get; set; }
diff --git a/test/Metadata.Tests/GitVersionTests.cs b/test/Metadata.Tests/GitVersionTests.cs
index 09b3724c6..f5c251c5a 100644
--- a/test/Metadata.Tests/GitVersionTests.cs
+++ b/test/Metadata.Tests/GitVersionTests.cs
@@ -1,10 +1,9 @@
using System.Reflection;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.Metadata;
namespace Metadata.Tests;
-public class GitVersionTests(ITestOutputHelper outputHelper) : AutoFakeTest(outputHelper)
+public class GitVersionTests(ITestOutputHelper outputHelper) : AutoFakeTest(XUnitDefaults.CreateTestContext(outputHelper))
{
[Fact(Skip = "Disabled for CI")]
public void ReturnsInformationForVersionedAssembly()
diff --git a/test/Metadata.Tests/Metadata.Tests.csproj b/test/Metadata.Tests/Metadata.Tests.csproj
index 7da054fed..7b3f1e288 100644
--- a/test/Metadata.Tests/Metadata.Tests.csproj
+++ b/test/Metadata.Tests/Metadata.Tests.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net8.0;net9.0
diff --git a/test/Sample.BlazorServer.Tests/Helpers/WebAppFixtureTest.cs b/test/Sample.BlazorServer.Tests/Helpers/WebAppFixtureTest.cs
index 0fe835a37..2c82e7dbd 100644
--- a/test/Sample.BlazorServer.Tests/Helpers/WebAppFixtureTest.cs
+++ b/test/Sample.BlazorServer.Tests/Helpers/WebAppFixtureTest.cs
@@ -1,59 +1,27 @@
using Alba;
using Microsoft.Extensions.Logging;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.AspNetCore.Testing;
using Serilog;
using Serilog.Events;
namespace Sample.BlazorServer.Tests.Helpers;
-public abstract class WebAppFixtureTest : LoggerTest, IClassFixture, IAsyncLifetime
+public abstract class WebAppFixtureTest
+ (ITestOutputHelper outputHelper, TAppFixture rocketSurgeryWebAppFixture)
+ : LoggerTest(XUnitTestContext.Create(outputHelper)), IClassFixture, IAsyncLifetime
where TAppFixture : class, ILaunchPadWebAppFixture
{
- private readonly ILaunchPadWebAppFixture _rocketSurgeryWebAppFixture;
- protected IAlbaHost AlbaHost => _rocketSurgeryWebAppFixture.AlbaHost;
+ protected IAlbaHost AlbaHost => rocketSurgeryWebAppFixture.AlbaHost;
///
/// The Service Provider
///
protected IServiceProvider ServiceProvider => AlbaHost.Services;
- protected WebAppFixtureTest(
- ITestOutputHelper outputHelper,
- TAppFixture rocketSurgeryWebAppFixture,
- string? logFormat = null,
- Action? configureLogger = null
- ) : base(outputHelper, logFormat, configureLogger)
- {
- _rocketSurgeryWebAppFixture = rocketSurgeryWebAppFixture;
- }
-
- protected WebAppFixtureTest(
- ITestOutputHelper outputHelper,
- TAppFixture rocketSurgeryWebAppFixture,
- LogLevel minLevel,
- string? logFormat = null,
- Action? configureLogger = null
- ) : base(outputHelper, minLevel, logFormat, configureLogger)
- {
- _rocketSurgeryWebAppFixture = rocketSurgeryWebAppFixture;
- }
-
- protected WebAppFixtureTest(
- ITestOutputHelper outputHelper,
- TAppFixture rocketSurgeryWebAppFixture,
- LogEventLevel minLevel,
- string? logFormat = null,
- Action? configureLogger = null
- ) : base(outputHelper, minLevel, logFormat, configureLogger)
- {
- _rocketSurgeryWebAppFixture = rocketSurgeryWebAppFixture;
- }
-
public virtual Task InitializeAsync()
{
- _rocketSurgeryWebAppFixture.SetLoggerFactory(LoggerFactory);
- return _rocketSurgeryWebAppFixture.ResetAsync();
+ rocketSurgeryWebAppFixture.SetLoggerFactory(CreateLoggerFactory());
+ return rocketSurgeryWebAppFixture.ResetAsync();
}
public virtual Task DisposeAsync()
diff --git a/test/Sample.BlazorServer.Tests/ModuleInitializer.cs b/test/Sample.BlazorServer.Tests/ModuleInitializer.cs
new file mode 100644
index 000000000..fda6c1b1b
--- /dev/null
+++ b/test/Sample.BlazorServer.Tests/ModuleInitializer.cs
@@ -0,0 +1,30 @@
+using System.Runtime.CompilerServices;
+using DiffEngine;
+using Path = System.IO.Path;
+
+namespace Sample.BlazorServer.Tests;
+
+public static class ModuleInitializer
+{
+ [ModuleInitializer]
+ public static void Init()
+ {
+ DiffRunner.Disabled = true;
+ VerifierSettings.DontScrubDateTimes();
+ VerifierSettings.DisableRequireUniquePrefix();
+ DerivePathInfo(
+ (sourceFile, _, type, method) =>
+ {
+ static string GetTypeName(Type type)
+ {
+ return type.IsNested ? $"{type.ReflectedType!.Name}.{type.Name}" : type.Name;
+ }
+
+ var typeName = GetTypeName(type);
+
+ var path = Path.Combine(Path.GetDirectoryName(sourceFile)!, "snapshots");
+ return new(path, typeName, method.Name);
+ }
+ );
+ }
+}
diff --git a/test/Sample.BlazorServer.Tests/Sample.BlazorServer.Tests.csproj b/test/Sample.BlazorServer.Tests/Sample.BlazorServer.Tests.csproj
index 9f704ccc9..8a8abf670 100644
--- a/test/Sample.BlazorServer.Tests/Sample.BlazorServer.Tests.csproj
+++ b/test/Sample.BlazorServer.Tests/Sample.BlazorServer.Tests.csproj
@@ -1,13 +1,13 @@
- net8.0
+ net9.0
-
-
+
+
diff --git a/test/Sample.BlazorWasm.Tests/HandleTestHostBase.cs b/test/Sample.BlazorWasm.Tests/HandleTestHostBase.cs
index 99c536216..9914bdb31 100644
--- a/test/Sample.BlazorWasm.Tests/HandleTestHostBase.cs
+++ b/test/Sample.BlazorWasm.Tests/HandleTestHostBase.cs
@@ -3,26 +3,23 @@
using Microsoft.Extensions.Logging;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.Testing;
-using Rocket.Surgery.Extensions.Testing;
+using Serilog.Events;
namespace Sample.BlazorWasm.Tests;
-public abstract class HandleTestHostBase(ITestOutputHelper outputHelper, LogLevel logLevel = LogLevel.Information) : AutoFakeTest(
- outputHelper,
- logLevel,
- "[{Timestamp:HH:mm:ss} {Level:w4}] {Message} <{SourceContext}>{NewLine}{Exception}"
-), IAsyncLifetime
+public abstract class HandleTestHostBase(ITestOutputHelper outputHelper, LogEventLevel logLevel = LogEventLevel.Information) : AutoFakeTest(XUnitTestContext.Create(outputHelper, logLevel)), IAsyncLifetime
{
private IConventionContext _hostBuilder = null!;
public async Task InitializeAsync()
{
+ var loggerFactory = CreateLoggerFactory();
_hostBuilder =
await ConventionContext.FromAsync(
ConventionContextBuilder
.Create()
- .ForTesting(Imports.Instance, LoggerFactory)
- .WithLogger(Logger)
+ .ForTesting(Imports.Instance, loggerFactory)
+ .WithLogger(loggerFactory.CreateLogger("Test"))
);
ExcludeSourceContext(nameof(WebAssemblyHostBuilder));
ExcludeSourceContext(nameof(WebAssemblyHost));
diff --git a/test/Sample.BlazorWasm.Tests/Sample.BlazorWasm.Tests.csproj b/test/Sample.BlazorWasm.Tests/Sample.BlazorWasm.Tests.csproj
index ff064c9f5..a91f497c2 100644
--- a/test/Sample.BlazorWasm.Tests/Sample.BlazorWasm.Tests.csproj
+++ b/test/Sample.BlazorWasm.Tests/Sample.BlazorWasm.Tests.csproj
@@ -1,6 +1,6 @@
- net8.0-browser
+ net9.0-browser
diff --git a/test/Sample.Classic.Restful.Tests/ClassicFoundationTests.OpenApiDocument.verified.txt b/test/Sample.Classic.Restful.Tests/ClassicFoundationTests.OpenApiDocument.verified.txt
new file mode 100644
index 000000000..560834311
--- /dev/null
+++ b/test/Sample.Classic.Restful.Tests/ClassicFoundationTests.OpenApiDocument.verified.txt
@@ -0,0 +1,1906 @@
+{
+ openapi: 3.0.1,
+ info: {
+ title: Sample.Classic.Restful | v1,
+ version: 1.0.0
+ },
+ paths: {
+ /LaunchRecord: {
+ get: {
+ tags: [
+ LaunchRecord
+ ],
+ operationId: ListLaunchRecords,
+ parameters: [
+ {
+ name: rocketType,
+ in: query,
+ schema: {
+ type: string
+ }
+ }
+ ],
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/LaunchRecordModel
+ }
+ }
+ },
+ text/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/LaunchRecordModel
+ }
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ },
+ post: {
+ tags: [
+ LaunchRecord
+ ],
+ operationId: CreateLaunchRecord,
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/CreateLaunchRecordRequest
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/CreateLaunchRecordRequest
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/CreateLaunchRecordRequest
+ }
+ }
+ },
+ required: true
+ },
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 201: {
+ description: Created,
+ headers: {
+ location: {
+ description: The location of the entity that was created,
+ schema: {
+ type: string
+ }
+ }
+ },
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/CreateLaunchRecordResponse
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/CreateLaunchRecordResponse
+ }
+ }
+ }
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ /LaunchRecord/{id}: {
+ get: {
+ tags: [
+ LaunchRecord
+ ],
+ operationId: GetLaunchRecord,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/LaunchRecordModel
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/LaunchRecordModel
+ }
+ }
+ }
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ },
+ put: {
+ tags: [
+ LaunchRecord
+ ],
+ operationId: EditLaunchRecord,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/EditLaunchRecordRequest
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/EditLaunchRecordRequest
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/EditLaunchRecordRequest
+ }
+ }
+ },
+ required: true
+ },
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 204: {
+ description: No Content
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ },
+ patch: {
+ tags: [
+ LaunchRecord
+ ],
+ operationId: PatchLaunchRecord,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/EditLaunchRecordPatchRequest
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/EditLaunchRecordPatchRequest
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/EditLaunchRecordPatchRequest
+ }
+ }
+ },
+ required: true
+ },
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 204: {
+ description: No Content
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ },
+ delete: {
+ tags: [
+ LaunchRecord
+ ],
+ operationId: DeleteLaunchRecord,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 204: {
+ description: No Content
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ /Rocket: {
+ get: {
+ tags: [
+ Rocket
+ ],
+ operationId: ListRockets,
+ parameters: [
+ {
+ name: rocketType,
+ in: query,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/RocketModel
+ }
+ }
+ },
+ text/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/RocketModel
+ }
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ },
+ post: {
+ tags: [
+ Rocket
+ ],
+ operationId: CreateRocket,
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/CreateRocketRequest
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/CreateRocketRequest
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/CreateRocketRequest
+ }
+ }
+ },
+ required: true
+ },
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 201: {
+ description: Created,
+ headers: {
+ location: {
+ description: The location of the entity that was created,
+ schema: {
+ type: string
+ }
+ }
+ },
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/CreateRocketResponse
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/CreateRocketResponse
+ }
+ }
+ }
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ /Rocket/{id}: {
+ get: {
+ tags: [
+ Rocket
+ ],
+ operationId: GetRocket,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/RocketModel
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/RocketModel
+ }
+ }
+ }
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ },
+ put: {
+ tags: [
+ Rocket
+ ],
+ operationId: EditRocket,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/EditRocketRequest
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/EditRocketRequest
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/EditRocketRequest
+ }
+ }
+ },
+ required: true
+ },
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/RocketModel
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/RocketModel
+ }
+ }
+ }
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ },
+ patch: {
+ tags: [
+ Rocket
+ ],
+ operationId: PatchRocket,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ requestBody: {
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/EditRocketPatchRequest
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/EditRocketPatchRequest
+ }
+ },
+ application/*+json: {
+ schema: {
+ $ref: #/components/schemas/EditRocketPatchRequest
+ }
+ }
+ },
+ required: true
+ },
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/RocketModel
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/RocketModel
+ }
+ }
+ }
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ },
+ delete: {
+ tags: [
+ Rocket
+ ],
+ operationId: RemoveRocket,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 204: {
+ description: No Content
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ /Rocket/{id}/launch-records: {
+ get: {
+ tags: [
+ Rocket
+ ],
+ operationId: GetRocketLaunchRecords,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/LaunchRecordModel
+ }
+ }
+ },
+ text/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/LaunchRecordModel
+ }
+ }
+ }
+ }
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ /Rocket/{id}/launch-records/{launchRecordId}: {
+ get: {
+ tags: [
+ Rocket
+ ],
+ operationId: GetRocketLaunchRecord,
+ parameters: [
+ {
+ name: id,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ },
+ {
+ name: launchRecordId,
+ in: path,
+ required: true,
+ schema: {
+ type: string,
+ format: uuid
+ }
+ }
+ ],
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/LaunchRecordModel
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/LaunchRecordModel
+ }
+ }
+ }
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ /WeatherForecast: {
+ get: {
+ tags: [
+ WeatherForecast
+ ],
+ operationId: Get,
+ responses: {
+ default: {
+ description: ,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 200: {
+ description: OK,
+ content: {
+ application/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/WeatherForecast
+ }
+ }
+ },
+ text/json: {
+ schema: {
+ type: array,
+ items: {
+ $ref: #/components/schemas/WeatherForecast
+ }
+ }
+ }
+ }
+ },
+ 404: {
+ description: Not Found,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 400: {
+ description: Bad Request,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/ProblemDetails
+ }
+ }
+ }
+ },
+ 422: {
+ description: Unprocessable Entity,
+ content: {
+ application/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ },
+ text/json: {
+ schema: {
+ $ref: #/components/schemas/FluentValidationProblemDetails
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ components: {
+ schemas: {
+ AssignedOfdouble: {
+ minimum: 0,
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: number,
+ format: double
+ },
+ hasValue: {
+ type: boolean
+ }
+ }
+ },
+ AssignedOfInstant: {
+ minimum: 0,
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ $ref: #/components/schemas/RocketId2
+ },
+ hasValue: {
+ type: boolean
+ }
+ }
+ },
+ AssignedOfNullableOfInstant: {
+ minimum: 0,
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ $ref: #/components/schemas/RocketId2
+ },
+ hasValue: {
+ type: boolean
+ }
+ }
+ },
+ AssignedOfRocketId: {
+ minimum: 0,
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ $ref: #/components/schemas/RocketId2
+ },
+ hasValue: {
+ type: boolean
+ }
+ }
+ },
+ AssignedOfRocketType: {
+ maxLength: 30,
+ minLength: 10,
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ $ref: #/components/schemas/RocketType
+ },
+ hasValue: {
+ type: boolean
+ }
+ }
+ },
+ AssignedOfstring: {
+ minimum: 0,
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: string,
+ nullable: true
+ },
+ hasValue: {
+ type: boolean
+ }
+ }
+ },
+ AssignedOfstring2: {
+ maxLength: 30,
+ minLength: 10,
+ required: [
+ value
+ ],
+ type: object,
+ properties: {
+ value: {
+ type: string,
+ nullable: true
+ },
+ hasValue: {
+ type: boolean
+ }
+ }
+ },
+ CreateLaunchRecordRequest: {
+ required: [
+ rocketId,
+ partner,
+ payload,
+ payloadWeightKg,
+ actualLaunchDate,
+ scheduledLaunchDate
+ ],
+ type: object,
+ properties: {
+ rocketId: {
+ $ref: #/components/schemas/Instant2
+ },
+ partner: {
+ minimum: 0,
+ minLength: 1,
+ type: string,
+ nullable: true
+ },
+ payload: {
+ minimum: 0,
+ minLength: 1,
+ type: string,
+ nullable: true
+ },
+ payloadWeightKg: {
+ minimum: 0,
+ type: number,
+ format: double
+ },
+ actualLaunchDate: {
+ $ref: #/components/schemas/Instant2
+ },
+ scheduledLaunchDate: {
+ $ref: #/components/schemas/Instant2
+ }
+ }
+ },
+ CreateLaunchRecordResponse: {
+ type: object,
+ properties: {
+ id: {
+ $ref: #/components/schemas/LaunchRecordId
+ }
+ }
+ },
+ CreateRocketRequest: {
+ required: [
+ serialNumber,
+ type
+ ],
+ type: object,
+ properties: {
+ serialNumber: {
+ maxLength: 30,
+ minLength: 10,
+ type: string
+ },
+ type: {
+ $ref: #/components/schemas/RocketType2
+ }
+ }
+ },
+ CreateRocketResponse: {
+ type: object,
+ properties: {
+ id: {
+ $ref: #/components/schemas/RocketId2
+ }
+ }
+ },
+ EditLaunchRecordPatchRequest: {
+ required: [
+ id,
+ partner,
+ payload,
+ payloadWeightKg,
+ actualLaunchDate,
+ scheduledLaunchDate,
+ rocketId
+ ],
+ type: object,
+ properties: {
+ partner: {
+ $ref: #/components/schemas/AssignedOfstring
+ },
+ payload: {
+ $ref: #/components/schemas/AssignedOfstring
+ },
+ payloadWeightKg: {
+ $ref: #/components/schemas/AssignedOfdouble
+ },
+ actualLaunchDate: {
+ $ref: #/components/schemas/AssignedOfNullableOfInstant
+ },
+ scheduledLaunchDate: {
+ $ref: #/components/schemas/AssignedOfInstant
+ },
+ rocketId: {
+ $ref: #/components/schemas/AssignedOfRocketId
+ }
+ }
+ },
+ EditLaunchRecordRequest: {
+ required: [
+ partner,
+ payload,
+ payloadWeightKg,
+ actualLaunchDate,
+ scheduledLaunchDate,
+ rocketId
+ ],
+ type: object,
+ properties: {
+ partner: {
+ minimum: 0,
+ minLength: 1,
+ type: string
+ },
+ payload: {
+ minimum: 0,
+ minLength: 1,
+ type: string
+ },
+ payloadWeightKg: {
+ minimum: 0,
+ type: number,
+ format: double
+ },
+ actualLaunchDate: {
+ $ref: #/components/schemas/RocketId
+ },
+ scheduledLaunchDate: {
+ $ref: #/components/schemas/RocketId
+ },
+ rocketId: {
+ $ref: #/components/schemas/RocketId
+ }
+ }
+ },
+ EditRocketPatchRequest: {
+ required: [
+ serialNumber,
+ type
+ ],
+ type: object,
+ properties: {
+ serialNumber: {
+ $ref: #/components/schemas/AssignedOfstring2
+ },
+ type: {
+ $ref: #/components/schemas/AssignedOfRocketType
+ }
+ }
+ },
+ EditRocketRequest: {
+ required: [
+ serialNumber,
+ type
+ ],
+ type: object,
+ properties: {
+ serialNumber: {
+ maxLength: 30,
+ minLength: 10,
+ type: string
+ },
+ type: {
+ $ref: #/components/schemas/RocketType2
+ }
+ }
+ },
+ Instant2: {
+ minimum: 0
+ },
+ LaunchRecordModel: {
+ type: object,
+ properties: {
+ id: {
+ $ref: #/components/schemas/Instant
+ },
+ partner: {
+ type: string
+ },
+ payload: {
+ type: string
+ },
+ payloadWeightKg: {
+ type: integer,
+ format: int64
+ },
+ actualLaunchDate: {
+ $ref: #/components/schemas/Instant
+ },
+ scheduledLaunchDate: {
+ $ref: #/components/schemas/Instant
+ },
+ rocketSerialNumber: {
+ type: string
+ },
+ rocketType: {
+ $ref: #/components/schemas/RocketType
+ }
+ }
+ },
+ ProblemDetails: {
+ required: [
+ type,
+ title,
+ status,
+ detail,
+ instance
+ ],
+ type: object,
+ properties: {
+ type: {
+ type: string,
+ nullable: true
+ },
+ title: {
+ type: string,
+ nullable: true
+ },
+ status: {
+ type: integer,
+ format: int32,
+ nullable: true
+ },
+ detail: {
+ type: string,
+ nullable: true
+ },
+ instance: {
+ type: string,
+ nullable: true
+ }
+ }
+ },
+ RocketId: {
+ minimum: 0
+ },
+ RocketModel: {
+ type: object,
+ properties: {
+ id: {
+ $ref: #/components/schemas/RocketId2
+ },
+ sn: {
+ type: string
+ },
+ type: {
+ $ref: #/components/schemas/RocketType
+ }
+ }
+ },
+ RocketType: {
+ enum: [
+ falcon9,
+ falconHeavy,
+ atlasV
+ ]
+ },
+ RocketType2: {
+ maxLength: 30,
+ minLength: 10,
+ enum: [
+ falcon9,
+ falconHeavy,
+ atlasV
+ ]
+ },
+ WeatherForecast: {
+ type: object,
+ properties: {
+ date: {
+ type: string,
+ format: date-time
+ },
+ temperatureC: {
+ type: integer,
+ format: int32
+ },
+ temperatureF: {
+ type: integer,
+ format: int32
+ },
+ summary: {
+ type: string,
+ nullable: true
+ }
+ }
+ }
+ }
+ },
+ tags: [
+ {
+ name: LaunchRecord
+ },
+ {
+ name: Rocket
+ },
+ {
+ name: WeatherForecast
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test/Sample.Classic.Restful.Tests/ClassicFoundationTests.cs b/test/Sample.Classic.Restful.Tests/ClassicFoundationTests.cs
index 7abeb4443..a7e49cb98 100644
--- a/test/Sample.Classic.Restful.Tests/ClassicFoundationTests.cs
+++ b/test/Sample.Classic.Restful.Tests/ClassicFoundationTests.cs
@@ -1,9 +1,5 @@
using System.Net;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
using Sample.Classic.Restful.Tests.Helpers;
-using Swashbuckle.AspNetCore.Swagger;
-using Swashbuckle.AspNetCore.SwaggerGen;
namespace Sample.Classic.Restful.Tests;
@@ -18,18 +14,10 @@ public async Task Starts()
}
[Fact]
- public void OpenApiDocument()
+ public async Task OpenApiDocument()
{
- var docs = ServiceProvider
- .GetRequiredService>()
- .Value.SwaggerDocs.Keys;
- foreach (var document in docs)
- {
- ServiceProvider
- .GetRequiredService()
- .GetSwagger(document)
- .Should()
- .NotBeNull();
- }
+ var response = await AlbaHost.Server.CreateClient().GetAsync("/openapi/v1.json");
+ var document = await response.Content.ReadAsStringAsync();
+ await Verify(document, extension: "json");
}
-}
\ No newline at end of file
+}
diff --git a/test/Sample.Classic.Restful.Tests/Helpers/WebAppFixtureTest.cs b/test/Sample.Classic.Restful.Tests/Helpers/WebAppFixtureTest.cs
index c1ea3df12..a9e083fb2 100644
--- a/test/Sample.Classic.Restful.Tests/Helpers/WebAppFixtureTest.cs
+++ b/test/Sample.Classic.Restful.Tests/Helpers/WebAppFixtureTest.cs
@@ -1,16 +1,17 @@
using Alba;
using Microsoft.Extensions.Logging;
-using Rocket.Surgery.Extensions.Testing;
using Rocket.Surgery.LaunchPad.AspNetCore.Testing;
using Serilog;
using Serilog.Events;
namespace Sample.Classic.Restful.Tests.Helpers;
-public abstract class WebAppFixtureTest : LoggerTest, IClassFixture, IAsyncLifetime
+public abstract class WebAppFixtureTest
+ (ITestOutputHelper outputHelper, TAppFixture rocketSurgeryWebAppFixture)
+ : LoggerTest(XUnitTestContext.Create(outputHelper)), IClassFixture, IAsyncLifetime
where TAppFixture : class, ILaunchPadWebAppFixture
{
- private readonly ILaunchPadWebAppFixture _rocketSurgeryWebAppFixture;
+ private readonly ILaunchPadWebAppFixture _rocketSurgeryWebAppFixture = rocketSurgeryWebAppFixture;
protected IAlbaHost AlbaHost => _rocketSurgeryWebAppFixture.AlbaHost;
///
@@ -18,41 +19,9 @@ public abstract class WebAppFixtureTest : LoggerTest, IClassFixture
///
protected IServiceProvider ServiceProvider => AlbaHost.Services;
- protected WebAppFixtureTest(
- ITestOutputHelper outputHelper,
- TAppFixture rocketSurgeryWebAppFixture,
- string? logFormat = null,
- Action? configureLogger = null
- ) : base(outputHelper, logFormat, configureLogger)
- {
- _rocketSurgeryWebAppFixture = rocketSurgeryWebAppFixture;
- }
-
- protected WebAppFixtureTest(
- ITestOutputHelper outputHelper,
- TAppFixture rocketSurgeryWebAppFixture,
- LogLevel minLevel,
- string? logFormat = null,
- Action? configureLogger = null
- ) : base(outputHelper, minLevel, logFormat, configureLogger)
- {
- _rocketSurgeryWebAppFixture = rocketSurgeryWebAppFixture;
- }
-
- protected WebAppFixtureTest(
- ITestOutputHelper outputHelper,
- TAppFixture rocketSurgeryWebAppFixture,
- LogEventLevel minLevel,
- string? logFormat = null,
- Action? configureLogger = null
- ) : base(outputHelper, minLevel, logFormat, configureLogger)
- {
- _rocketSurgeryWebAppFixture = rocketSurgeryWebAppFixture;
- }
-
public virtual Task InitializeAsync()
{
- _rocketSurgeryWebAppFixture.SetLoggerFactory(LoggerFactory);
+ _rocketSurgeryWebAppFixture.SetLoggerFactory(CreateLoggerFactory());
return _rocketSurgeryWebAppFixture.ResetAsync();
}
@@ -60,4 +29,4 @@ public virtual Task DisposeAsync()
{
return Task.CompletedTask;
}
-}
\ No newline at end of file
+}
diff --git a/test/Sample.Classic.Restful.Tests/ModuleInitializer.cs b/test/Sample.Classic.Restful.Tests/ModuleInitializer.cs
new file mode 100644
index 000000000..431eb0939
--- /dev/null
+++ b/test/Sample.Classic.Restful.Tests/ModuleInitializer.cs
@@ -0,0 +1,31 @@
+using System.Runtime.CompilerServices;
+using DiffEngine;
+using Path = System.IO.Path;
+
+namespace Sample.Restful.Tests;
+
+internal static class ModuleInitializer
+{
+ [ModuleInitializer]
+ public static void Init()
+ {
+ DiffRunner.Disabled = true;
+ VerifierSettings.DontScrubDateTimes();
+ VerifierSettings.DisableRequireUniquePrefix();
+ DerivePathInfo(
+ (sourceFile, _, type, method) =>
+ {
+ static string GetTypeName(Type type)
+ {
+ return type.IsNested ? $"{type.ReflectedType!.Name}.{type.Name}" : type.Name;
+ }
+
+ var typeName = GetTypeName(type);
+
+ var path = Path.Combine(Path.GetDirectoryName(sourceFile)!, "snapshots");
+ return new(path, typeName, method.Name);
+ }
+ );
+ }
+
+}
diff --git a/test/Sample.Classic.Restful.Tests/Sample.Classic.Restful.Tests.csproj b/test/Sample.Classic.Restful.Tests/Sample.Classic.Restful.Tests.csproj
index afe297663..2c714d071 100644
--- a/test/Sample.Classic.Restful.Tests/Sample.Classic.Restful.Tests.csproj
+++ b/test/Sample.Classic.Restful.Tests/Sample.Classic.Restful.Tests.csproj
@@ -1,14 +1,14 @@
- net8.0
+ net9.0
-
-
-
+
+
+
diff --git a/test/Sample.Classic.Restful.Tests/snapshots/ClassicFoundationTests.OpenApiDocument.verified.json b/test/Sample.Classic.Restful.Tests/snapshots/ClassicFoundationTests.OpenApiDocument.verified.json
new file mode 100644
index 000000000..10b5184a6
--- /dev/null
+++ b/test/Sample.Classic.Restful.Tests/snapshots/ClassicFoundationTests.OpenApiDocument.verified.json
@@ -0,0 +1,1849 @@
+{
+ "openapi": "3.0.1",
+ "info": {
+ "title": "Sample.Classic.Restful | v1",
+ "version": "1.0.0"
+ },
+ "paths": {
+ "/LaunchRecord": {
+ "get": {
+ "tags": [
+ "LaunchRecord"
+ ],
+ "operationId": "ListLaunchRecords",
+ "parameters": [
+ {
+ "name": "rocketType",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LaunchRecordModel"
+ }
+ }
+ },
+ "text/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LaunchRecordModel"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "LaunchRecord"
+ ],
+ "operationId": "CreateLaunchRecord",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateLaunchRecordRequest"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateLaunchRecordRequest"
+ }
+ },
+ "application/*+json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateLaunchRecordRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Created",
+ "headers": {
+ "location": {
+ "description": "The location of the entity that was created",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateLaunchRecordResponse"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateLaunchRecordResponse"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/LaunchRecord/{id}": {
+ "get": {
+ "tags": [
+ "LaunchRecord"
+ ],
+ "operationId": "GetLaunchRecord",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LaunchRecordModel"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LaunchRecordModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "LaunchRecord"
+ ],
+ "operationId": "EditLaunchRecord",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditLaunchRecordRequest"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditLaunchRecordRequest"
+ }
+ },
+ "application/*+json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditLaunchRecordRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "No Content"
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "LaunchRecord"
+ ],
+ "operationId": "PatchLaunchRecord",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditLaunchRecordPatchRequest"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditLaunchRecordPatchRequest"
+ }
+ },
+ "application/*+json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditLaunchRecordPatchRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "No Content"
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "LaunchRecord"
+ ],
+ "operationId": "DeleteLaunchRecord",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "No Content"
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/Rocket": {
+ "get": {
+ "tags": [
+ "Rocket"
+ ],
+ "operationId": "ListRockets",
+ "parameters": [
+ {
+ "name": "rocketType",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/RocketModel"
+ }
+ }
+ },
+ "text/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/RocketModel"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Rocket"
+ ],
+ "operationId": "CreateRocket",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateRocketRequest"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateRocketRequest"
+ }
+ },
+ "application/*+json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateRocketRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "201": {
+ "description": "Created",
+ "headers": {
+ "location": {
+ "description": "The location of the entity that was created",
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateRocketResponse"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateRocketResponse"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/Rocket/{id}": {
+ "get": {
+ "tags": [
+ "Rocket"
+ ],
+ "operationId": "GetRocket",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RocketModel"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RocketModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "Rocket"
+ ],
+ "operationId": "EditRocket",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditRocketRequest"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditRocketRequest"
+ }
+ },
+ "application/*+json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditRocketRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RocketModel"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RocketModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Rocket"
+ ],
+ "operationId": "PatchRocket",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditRocketPatchRequest"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditRocketPatchRequest"
+ }
+ },
+ "application/*+json": {
+ "schema": {
+ "$ref": "#/components/schemas/EditRocketPatchRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RocketModel"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/RocketModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Rocket"
+ ],
+ "operationId": "RemoveRocket",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "No Content"
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/Rocket/{id}/launch-records": {
+ "get": {
+ "tags": [
+ "Rocket"
+ ],
+ "operationId": "GetRocketLaunchRecords",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LaunchRecordModel"
+ }
+ }
+ },
+ "text/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LaunchRecordModel"
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/Rocket/{id}/launch-records/{launchRecordId}": {
+ "get": {
+ "tags": [
+ "Rocket"
+ ],
+ "operationId": "GetRocketLaunchRecord",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ {
+ "name": "launchRecordId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LaunchRecordModel"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LaunchRecordModel"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/WeatherForecast": {
+ "get": {
+ "tags": [
+ "WeatherForecast"
+ ],
+ "operationId": "Get",
+ "responses": {
+ "default": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WeatherForecast"
+ }
+ }
+ },
+ "text/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/WeatherForecast"
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad Request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Unprocessable Entity",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/FluentValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "AssignedOfdouble": {
+ "required": [
+ "value"
+ ],
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "number",
+ "format": "double"
+ },
+ "hasValue": {
+ "type": "boolean"
+ }
+ }
+ },
+ "AssignedOfInstant": {
+ "required": [
+ "value"
+ ],
+ "type": "object",
+ "properties": {
+ "value": {
+ "$ref": "#/components/schemas/RocketId"
+ },
+ "hasValue": {
+ "type": "boolean"
+ }
+ }
+ },
+ "AssignedOfNullableOfInstant": {
+ "required": [
+ "value"
+ ],
+ "type": "object",
+ "properties": {
+ "value": {
+ "$ref": "#/components/schemas/RocketId"
+ },
+ "hasValue": {
+ "type": "boolean"
+ }
+ }
+ },
+ "AssignedOfRocketId": {
+ "required": [
+ "value"
+ ],
+ "type": "object",
+ "properties": {
+ "value": {
+ "$ref": "#/components/schemas/RocketId"
+ },
+ "hasValue": {
+ "type": "boolean"
+ }
+ }
+ },
+ "AssignedOfRocketType": {
+ "required": [
+ "value"
+ ],
+ "type": "object",
+ "properties": {
+ "value": {
+ "$ref": "#/components/schemas/RocketType"
+ },
+ "hasValue": {
+ "type": "boolean"
+ }
+ }
+ },
+ "AssignedOfstring": {
+ "required": [
+ "value"
+ ],
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "string",
+ "nullable": true
+ },
+ "hasValue": {
+ "type": "boolean"
+ }
+ }
+ },
+ "CreateLaunchRecordRequest": {
+ "required": [
+ "partner",
+ "rocketId",
+ "payload",
+ "scheduledLaunchDate"
+ ],
+ "type": "object",
+ "properties": {
+ "rocketId": {
+ "$ref": "#/components/schemas/Instant"
+ },
+ "partner": {
+ "minLength": 1,
+ "type": "string",
+ "nullable": true
+ },
+ "payload": {
+ "minLength": 1,
+ "type": "string",
+ "nullable": true
+ },
+ "payloadWeightKg": {
+ "minimum": 0,
+ "type": "number",
+ "format": "double"
+ },
+ "actualLaunchDate": {
+ "$ref": "#/components/schemas/Instant"
+ },
+ "scheduledLaunchDate": {
+ "$ref": "#/components/schemas/Instant"
+ }
+ }
+ },
+ "CreateLaunchRecordResponse": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "$ref": "#/components/schemas/LaunchRecordId"
+ }
+ }
+ },
+ "CreateRocketRequest": {
+ "required": [
+ "serialNumber"
+ ],
+ "type": "object",
+ "properties": {
+ "serialNumber": {
+ "maxLength": 30,
+ "minLength": 10,
+ "type": "string"
+ },
+ "type": {
+ "$ref": "#/components/schemas/RocketType"
+ }
+ }
+ },
+ "CreateRocketResponse": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "$ref": "#/components/schemas/RocketId"
+ }
+ }
+ },
+ "EditLaunchRecordPatchRequest": {
+ "required": [
+ "id"
+ ],
+ "type": "object",
+ "properties": {
+ "partner": {
+ "$ref": "#/components/schemas/AssignedOfstring"
+ },
+ "payload": {
+ "$ref": "#/components/schemas/AssignedOfstring"
+ },
+ "payloadWeightKg": {
+ "$ref": "#/components/schemas/AssignedOfdouble"
+ },
+ "actualLaunchDate": {
+ "$ref": "#/components/schemas/AssignedOfNullableOfInstant"
+ },
+ "scheduledLaunchDate": {
+ "$ref": "#/components/schemas/AssignedOfInstant"
+ },
+ "rocketId": {
+ "$ref": "#/components/schemas/AssignedOfRocketId"
+ }
+ }
+ },
+ "EditLaunchRecordRequest": {
+ "required": [
+ "partner",
+ "rocketId",
+ "payload",
+ "scheduledLaunchDate"
+ ],
+ "type": "object",
+ "properties": {
+ "partner": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "payload": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "payloadWeightKg": {
+ "minimum": 0,
+ "type": "number",
+ "format": "double"
+ },
+ "actualLaunchDate": {
+ "$ref": "#/components/schemas/RocketId"
+ },
+ "scheduledLaunchDate": {
+ "$ref": "#/components/schemas/RocketId"
+ },
+ "rocketId": {
+ "$ref": "#/components/schemas/RocketId"
+ }
+ }
+ },
+ "EditRocketPatchRequest": {
+ "type": "object",
+ "properties": {
+ "serialNumber": {
+ "$ref": "#/components/schemas/AssignedOfstring"
+ },
+ "type": {
+ "$ref": "#/components/schemas/AssignedOfRocketType"
+ }
+ }
+ },
+ "EditRocketRequest": {
+ "required": [
+ "type",
+ "serialNumber"
+ ],
+ "type": "object",
+ "properties": {
+ "serialNumber": {
+ "maxLength": 30,
+ "minLength": 10,
+ "type": "string"
+ },
+ "type": {
+ "$ref": "#/components/schemas/RocketType"
+ }
+ }
+ },
+ "FluentValidationProblemDetails": { },
+ "Instant": { },
+ "LaunchRecordId": { },
+ "LaunchRecordModel": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "$ref": "#/components/schemas/Instant"
+ },
+ "partner": {
+ "type": "string"
+ },
+ "payload": {
+ "type": "string"
+ },
+ "payloadWeightKg": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "actualLaunchDate": {
+ "$ref": "#/components/schemas/Instant"
+ },
+ "scheduledLaunchDate": {
+ "$ref": "#/components/schemas/Instant"
+ },
+ "rocketSerialNumber": {
+ "type": "string"
+ },
+ "rocketType": {
+ "$ref": "#/components/schemas/RocketType"
+ }
+ }
+ },
+ "ProblemDetails": {
+ "required": [
+ "type",
+ "title"
+ ],
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "nullable": true
+ },
+ "title": {
+ "type": "string",
+ "nullable": true
+ },
+ "status": {
+ "type": "integer",
+ "format": "int32",
+ "nullable": true
+ },
+ "detail": {
+ "type": "string",
+ "nullable": true
+ },
+ "instance": {
+ "type": "string",
+ "nullable": true
+ }
+ }
+ },
+ "RocketId": { },
+ "RocketModel": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "$ref": "#/components/schemas/RocketId"
+ },
+ "sn": {
+ "type": "string"
+ },
+ "type": {
+ "$ref": "#/components/schemas/RocketType"
+ }
+ }
+ },
+ "RocketType": {
+ "enum": [
+ "falcon9",
+ "falconHeavy",
+ "atlasV"
+ ]
+ },
+ "WeatherForecast": {
+ "type": "object",
+ "properties": {
+ "date": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "temperatureC": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "temperatureF": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "summary": {
+ "type": "string",
+ "nullable": true
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ {
+ "name": "LaunchRecord"
+ },
+ {
+ "name": "Rocket"
+ },
+ {
+ "name": "WeatherForecast"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test/Sample.Command.Tests/Sample.Command.Tests.csproj b/test/Sample.Command.Tests/Sample.Command.Tests.csproj
index 77972d30a..c51bd4470 100644
--- a/test/Sample.Command.Tests/Sample.Command.Tests.csproj
+++ b/test/Sample.Command.Tests/Sample.Command.Tests.csproj
@@ -1,11 +1,11 @@
-
- net8.0
-
-
-
-
-
-
-
+
+ net8.0;net9.0
+
+
+
+
+
+
+
diff --git a/test/Sample.Core.Tests/HandleTestHostBase.cs b/test/Sample.Core.Tests/HandleTestHostBase.cs
index bfd398abe..2efadf523 100644
--- a/test/Sample.Core.Tests/HandleTestHostBase.cs
+++ b/test/Sample.Core.Tests/HandleTestHostBase.cs
@@ -1,31 +1,25 @@
-using Microsoft.Data.Sqlite;
+using DryIoc;
+using DryIoc.Microsoft.DependencyInjection;
+using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
using Rocket.Surgery.Conventions;
using Rocket.Surgery.Conventions.Testing;
using Rocket.Surgery.DependencyInjection;
-using Rocket.Surgery.Extensions.Testing;
using Sample.Core.Domain;
+using Serilog.Events;
namespace Sample.Core.Tests;
-public abstract class HandleTestHostBase : AutoFakeTest, IAsyncLifetime
+public abstract class HandleTestHostBase : AutoFakeTest, IAsyncLifetime
{
- private readonly ConventionContextBuilder _context;
+ private ConventionContextBuilder? _context;
private SqliteConnection? _connection;
- protected HandleTestHostBase(ITestOutputHelper outputHelper, LogLevel logLevel = LogLevel.Information) : base(
- outputHelper,
- logLevel,
- "[{Timestamp:HH:mm:ss} {Level:w4}] {Message} <{SourceContext}>{NewLine}{Exception}"
+ protected HandleTestHostBase(ITestOutputHelper outputHelper, LogEventLevel logLevel = LogEventLevel.Information) : base(
+ XUnitTestContext.Create(outputHelper, logLevel)
)
{
- _context =
- ConventionContextBuilder
- .Create()
- .ForTesting(Imports.Instance, LoggerFactory)
- .WithLogger(LoggerFactory.CreateLogger(nameof(AutoFakeTest)));
ExcludeSourceContext(nameof(AutoFakeTest));
}
@@ -33,29 +27,28 @@ public async Task InitializeAsync()
{
_connection = new("DataSource=:memory:");
await _connection.OpenAsync();
-
- _context
- .ConfigureServices(
- (_, services) =>
- {
- services.AddDbContextPool(
- z => z
- .EnableDetailedErrors()
- .EnableSensitiveDataLogging()
- .UseSqlite(
- _connection
+ var factory = CreateLoggerFactory();
+ _context = ConventionContextBuilder
+ .Create()
+ .ForTesting(Imports.Instance, factory)
+ .WithLogger(factory.CreateLogger(GetType().Name));
+
+ var services = await new ServiceCollection()
+ .AddDbContextPool(
+ z => z
+ .EnableDetailedErrors()
+ .EnableSensitiveDataLogging()
+ .UseSqlite(_connection)
)
- );
- }
- );
-
- Populate(await new ServiceCollection().ApplyConventionsAsync(await ConventionContext.FromAsync(_context)));
-
- await ServiceProvider.WithScoped().Invoke(context => context.Database.EnsureCreatedAsync());
+ .ApplyConventionsAsync(await ConventionContext.FromAsync(_context));
+ Populate(services);
+ await Container.WithScoped().Invoke(context => context.Database.EnsureCreatedAsync());
}
public async Task DisposeAsync()
{
await _connection!.DisposeAsync();
}
-}
\ No newline at end of file
+
+ protected override IContainer BuildContainer(IContainer container) => container.WithDependencyInjectionAdapter().Container;
+}
diff --git a/test/Sample.Core.Tests/LaunchRecords/CreateLaunchRecordTests.cs b/test/Sample.Core.Tests/LaunchRecords/CreateLaunchRecordTests.cs
index b9e978766..9886fbcfd 100644
--- a/test/Sample.Core.Tests/LaunchRecords/CreateLaunchRecordTests.cs
+++ b/test/Sample.Core.Tests/LaunchRecords/CreateLaunchRecordTests.cs
@@ -1,13 +1,13 @@
using MediatR;
-using Microsoft.Extensions.Logging;
using NodaTime;
using Rocket.Surgery.DependencyInjection;
using Sample.Core.Domain;
using Sample.Core.Operations.LaunchRecords;
+using Serilog.Events;
namespace Sample.Core.Tests.LaunchRecords;
-public class CreateLaunchRecordTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class CreateLaunchRecordTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_Create_A_LaunchRecord()
diff --git a/test/Sample.Core.Tests/LaunchRecords/GetLaunchRecordTests.cs b/test/Sample.Core.Tests/LaunchRecords/GetLaunchRecordTests.cs
index 8fb2ed0f0..5ee5fbd3b 100644
--- a/test/Sample.Core.Tests/LaunchRecords/GetLaunchRecordTests.cs
+++ b/test/Sample.Core.Tests/LaunchRecords/GetLaunchRecordTests.cs
@@ -1,15 +1,15 @@
using MediatR;
-using Microsoft.Extensions.Logging;
using NodaTime;
using Rocket.Surgery.DependencyInjection;
using Rocket.Surgery.LaunchPad.Foundation;
using Sample.Core.Domain;
using Sample.Core.Models;
using Sample.Core.Operations.LaunchRecords;
+using Serilog.Events;
namespace Sample.Core.Tests.LaunchRecords;
-public class GetLaunchRecordTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class GetLaunchRecordTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_Get_A_LaunchRecord()
@@ -42,7 +42,7 @@ public async Task Should_Get_A_LaunchRecord()
);
var response = await ServiceProvider.WithScoped().Invoke(
- mediator => mediator.Send(new GetLaunchRecord.Request { Id = record.Id })
+ mediator => mediator.Send(new GetLaunchRecord.Request( record.Id))
);
response.Partner.Should().Be("partner");
@@ -56,7 +56,7 @@ public async Task Should_Get_A_LaunchRecord()
public async Task Should_Not_Get_A_Missing_Launch_Record()
{
Func action = () => ServiceProvider.WithScoped().Invoke(
- mediator => mediator.Send(new GetLaunchRecord.Request { Id = LaunchRecordId.New() })
+ mediator => mediator.Send(new GetLaunchRecord.Request (LaunchRecordId.New()))
);
await action.Should().ThrowAsync();
diff --git a/test/Sample.Core.Tests/LaunchRecords/ListLaunchRecordsTests.cs b/test/Sample.Core.Tests/LaunchRecords/ListLaunchRecordsTests.cs
index 17e4410cd..68c0fe4a8 100644
--- a/test/Sample.Core.Tests/LaunchRecords/ListLaunchRecordsTests.cs
+++ b/test/Sample.Core.Tests/LaunchRecords/ListLaunchRecordsTests.cs
@@ -1,12 +1,12 @@
using MediatR;
-using Microsoft.Extensions.Logging;
using Rocket.Surgery.DependencyInjection;
using Sample.Core.Domain;
using Sample.Core.Operations.LaunchRecords;
+using Serilog.Events;
namespace Sample.Core.Tests.LaunchRecords;
-public class ListLaunchRecordsTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class ListLaunchRecordsTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_List_LaunchRecords()
diff --git a/test/Sample.Core.Tests/LaunchRecords/RemoveLaunchRecordsTests.cs b/test/Sample.Core.Tests/LaunchRecords/RemoveLaunchRecordsTests.cs
index 1dc6ce2ec..d5cee44b6 100644
--- a/test/Sample.Core.Tests/LaunchRecords/RemoveLaunchRecordsTests.cs
+++ b/test/Sample.Core.Tests/LaunchRecords/RemoveLaunchRecordsTests.cs
@@ -1,14 +1,14 @@
using MediatR;
-using Microsoft.Extensions.Logging;
using Rocket.Surgery.DependencyInjection;
using Rocket.Surgery.LaunchPad.Foundation;
using Sample.Core.Domain;
using Sample.Core.Models;
using Sample.Core.Operations.LaunchRecords;
+using Serilog.Events;
namespace Sample.Core.Tests.LaunchRecords;
-public class RemoveLaunchRecordsTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class RemoveLaunchRecordsTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_Remove_LaunchRecord()
@@ -29,7 +29,7 @@ public async Task Should_Remove_LaunchRecord()
);
await ServiceProvider.WithScoped().Invoke(
- mediator => mediator.Send(new DeleteLaunchRecord.Request { Id = id })
+ mediator => mediator.Send(new DeleteLaunchRecord.Request(id))
);
ServiceProvider.WithScoped().Invoke(c => c.LaunchRecords.Should().BeEmpty());
@@ -56,7 +56,7 @@ await ServiceProvider.WithScoped()
);
Func action = () => ServiceProvider.WithScoped().Invoke(
- mediator => mediator.Send(new DeleteLaunchRecord.Request { Id = id })
+ mediator => mediator.Send(new DeleteLaunchRecord.Request(id))
);
await action.Should().ThrowAsync();
}
diff --git a/test/Sample.Core.Tests/LaunchRecords/UpdateLaunchRecordTests.cs b/test/Sample.Core.Tests/LaunchRecords/UpdateLaunchRecordTests.cs
index 39de39c07..21f52e628 100644
--- a/test/Sample.Core.Tests/LaunchRecords/UpdateLaunchRecordTests.cs
+++ b/test/Sample.Core.Tests/LaunchRecords/UpdateLaunchRecordTests.cs
@@ -1,15 +1,15 @@
using MediatR;
-using Microsoft.Extensions.Logging;
using NodaTime;
using NodaTime.Extensions;
using Rocket.Surgery.DependencyInjection;
using Sample.Core.Domain;
using Sample.Core.Models;
using Sample.Core.Operations.LaunchRecords;
+using Serilog.Events;
namespace Sample.Core.Tests.LaunchRecords;
-public class UpdateLaunchRecordTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class UpdateLaunchRecordTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_Update_A_LaunchRecord()
diff --git a/test/Sample.Core.Tests/Rockets/CreateRocketTests.cs b/test/Sample.Core.Tests/Rockets/CreateRocketTests.cs
index 3015f6a13..1ff7e5403 100644
--- a/test/Sample.Core.Tests/Rockets/CreateRocketTests.cs
+++ b/test/Sample.Core.Tests/Rockets/CreateRocketTests.cs
@@ -1,15 +1,15 @@
using MediatR;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
using Rocket.Surgery.DependencyInjection;
using Rocket.Surgery.LaunchPad.Foundation;
using Sample.Core.Domain;
using Sample.Core.Operations.Rockets;
+using Serilog.Events;
using ValidationException = FluentValidation.ValidationException;
namespace Sample.Core.Tests.Rockets;
-public class CreateRocketTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class CreateRocketTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_Create_A_Rocket()
diff --git a/test/Sample.Core.Tests/Rockets/GetRocketTests.cs b/test/Sample.Core.Tests/Rockets/GetRocketTests.cs
index 0674c2ff7..5df6b6ec4 100644
--- a/test/Sample.Core.Tests/Rockets/GetRocketTests.cs
+++ b/test/Sample.Core.Tests/Rockets/GetRocketTests.cs
@@ -1,14 +1,14 @@
using MediatR;
-using Microsoft.Extensions.Logging;
using Rocket.Surgery.DependencyInjection;
using Rocket.Surgery.LaunchPad.Foundation;
using Sample.Core.Domain;
using Sample.Core.Models;
using Sample.Core.Operations.Rockets;
+using Serilog.Events;
namespace Sample.Core.Tests.Rockets;
-public class GetRocketTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class GetRocketTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_Get_A_Rocket()
@@ -30,7 +30,7 @@ public async Task Should_Get_A_Rocket()
);
var response = await ServiceProvider.WithScoped().Invoke(
- mediator => mediator.Send(new GetRocket.Request { Id = rocket })
+ mediator => mediator.Send(new GetRocket.Request(rocket))
);
response.Type.Should().Be(RocketType.Falcon9);
@@ -41,7 +41,7 @@ public async Task Should_Get_A_Rocket()
public async Task Should_Not_Get_A_Missing_Rocket()
{
Func action = () => ServiceProvider.WithScoped().Invoke(
- mediator => mediator.Send(new GetRocket.Request { Id = RocketId.New() })
+ mediator => mediator.Send(new GetRocket.Request(RocketId.New()))
);
await action.Should().ThrowAsync();
diff --git a/test/Sample.Core.Tests/Rockets/ListRocketsTests.cs b/test/Sample.Core.Tests/Rockets/ListRocketsTests.cs
index 77d6e9ebd..957214696 100644
--- a/test/Sample.Core.Tests/Rockets/ListRocketsTests.cs
+++ b/test/Sample.Core.Tests/Rockets/ListRocketsTests.cs
@@ -1,12 +1,12 @@
using MediatR;
-using Microsoft.Extensions.Logging;
using Rocket.Surgery.DependencyInjection;
using Sample.Core.Domain;
using Sample.Core.Operations.Rockets;
+using Serilog.Events;
namespace Sample.Core.Tests.Rockets;
-public class ListRocketsTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class ListRocketsTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_List_Rockets()
diff --git a/test/Sample.Core.Tests/Rockets/RemoveRocketsTests.cs b/test/Sample.Core.Tests/Rockets/RemoveRocketsTests.cs
index 549be9711..5c649855e 100644
--- a/test/Sample.Core.Tests/Rockets/RemoveRocketsTests.cs
+++ b/test/Sample.Core.Tests/Rockets/RemoveRocketsTests.cs
@@ -1,12 +1,12 @@
using MediatR;
-using Microsoft.Extensions.Logging;
using Rocket.Surgery.DependencyInjection;
using Sample.Core.Domain;
using Sample.Core.Operations.Rockets;
+using Serilog.Events;
namespace Sample.Core.Tests.Rockets;
-public class RemoveRocketsTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class RemoveRocketsTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_Remove_Rocket()
@@ -25,7 +25,7 @@ public async Task Should_Remove_Rocket()
);
await ServiceProvider.WithScoped().Invoke(
- mediator => mediator.Send(new DeleteRocket.Request { Id = id })
+ mediator => mediator.Send(new DeleteRocket.Request(id))
);
ServiceProvider.WithScoped().Invoke(c => c.Rockets.Should().BeEmpty());
diff --git a/test/Sample.Core.Tests/Rockets/UpdateRocketTests.cs b/test/Sample.Core.Tests/Rockets/UpdateRocketTests.cs
index 80f0e7719..c12ee47dc 100644
--- a/test/Sample.Core.Tests/Rockets/UpdateRocketTests.cs
+++ b/test/Sample.Core.Tests/Rockets/UpdateRocketTests.cs
@@ -1,15 +1,15 @@
using MediatR;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
using Rocket.Surgery.DependencyInjection;
using Sample.Core.Domain;
using Sample.Core.Models;
using Sample.Core.Operations.Rockets;
+using Serilog.Events;
using ValidationException = FluentValidation.ValidationException;
namespace Sample.Core.Tests.Rockets;
-public class UpdateRocketTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogLevel.Trace)
+public class UpdateRocketTests(ITestOutputHelper outputHelper) : HandleTestHostBase(outputHelper, LogEventLevel.Verbose)
{
[Fact]
public async Task Should_Update_A_Rocket()
diff --git a/test/Sample.Core.Tests/Sample.Core.Tests.csproj b/test/Sample.Core.Tests/Sample.Core.Tests.csproj
index 71806a311..a0211cc23 100644
--- a/test/Sample.Core.Tests/Sample.Core.Tests.csproj
+++ b/test/Sample.Core.Tests/Sample.Core.Tests.csproj
@@ -1,6 +1,6 @@
- net8.0
+ net8.0;net9.0
diff --git a/test/Sample.Graphql.Tests/FairyBread.Tests/CustomizationTests.cs b/test/Sample.Graphql.Tests/FairyBread.Tests/CustomizationTests.cs
deleted file mode 100644
index 3ea4c3279..000000000
--- a/test/Sample.Graphql.Tests/FairyBread.Tests/CustomizationTests.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-using FluentValidation;
-using FluentValidation.Results;
-using HotChocolate;
-using HotChocolate.Execution;
-using HotChocolate.Resolvers;
-using HotChocolate.Types;
-using Microsoft.Extensions.DependencyInjection;
-using Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-using IOperationResult = HotChocolate.Execution.IOperationResult;
-
-namespace FairyBread.Tests;
-
-public class CustomizationTests
-{
- [Fact]
- public async Task CustomValidationResultHandler_Works()
- {
- // Arrange
- var executor = await GetRequestExecutorAsync(services => { services.AddSingleton(); });
-
- // Act
- var result = await executor.ExecuteAsync(Query) as IOperationResult;
-
- // Assert
- Assert.NotNull(result);
- Assert.NotNull(result!.Errors);
- Assert.NotEmpty(result.Errors);
- Assert.True(result.Errors!.All(e => e.Message == "lol"));
- }
-
- [Fact]
- public async Task CustomValidatorProvider_Works()
- {
- // Arrange
- var executor = await GetRequestExecutorAsync(services => { services.AddSingleton(); });
-
- // Act
- var result = await executor.ExecuteAsync(Query);
-
- // Assert
- await Verify(result);
- }
-
- private const string Query = @"query { read(foo: { someInteger: 1, someString: ""hello"" }) }";
-
- private static async Task GetRequestExecutorAsync(
- Action preBuildProviderAction
- )
- {
- var services = new ServiceCollection();
- services.AddValidatorsFromAssemblyContaining();
- preBuildProviderAction?.Invoke(services);
-
- return await services
- .AddGraphQL()
- .AddQueryType()
- .AddMutationType()
- .AddFairyBread()
- .BuildRequestExecutorAsync();
- }
-
- public class CustomValidationErrorsHandler : DefaultValidationErrorsHandler
- {
- protected override IErrorBuilder CreateErrorBuilder(IMiddlewareContext context, string argName, IValidator val, ValidationFailure failure)
- {
- return base
- .CreateErrorBuilder(context, argName, val, failure)
- .SetMessage("lol");
- }
- }
-
- public class CustomValidatorProvider : DefaultValidatorProvider
- {
- public CustomValidatorProvider(IServiceProvider serviceProvider, IFairyBreadOptions options)
- : base(null!) { }
-
- public override IEnumerable GetValidators(IMiddlewareContext context, IInputField argument)
- {
- return argument.RuntimeType == typeof(FooInputDto)
- ? new ResolvedValidator[] { new(new CustomValidator()), }
- : base.GetValidators(context, argument);
- }
- }
- #pragma warning disable CA1822 // Mark members as static
- public class QueryType
- {
- public string Read(FooInputDto foo)
- {
- return $"{foo};";
- }
- }
-
- public class MutationType
- {
- public string Write(FooInputDto foo)
- {
- return $"{foo};";
- }
- }
-
- public class FooInputDto
- {
- public int SomeInteger { get; set; }
-
- public string SomeString { get; set; } = "";
-
- public override string ToString()
- {
- return $"SomeInteger: {SomeInteger}, " + $"SomeString: {SomeString}";
- }
- }
-
- public class CustomValidator : AbstractValidator
- {
- public CustomValidator()
- {
- RuleFor(x => x.SomeInteger)
- .GreaterThanOrEqualTo(999);
- }
- }
-}
\ No newline at end of file
diff --git a/test/Sample.Graphql.Tests/FairyBread.Tests/GeneralTests.cs b/test/Sample.Graphql.Tests/FairyBread.Tests/GeneralTests.cs
deleted file mode 100644
index 453cedc88..000000000
--- a/test/Sample.Graphql.Tests/FairyBread.Tests/GeneralTests.cs
+++ /dev/null
@@ -1,415 +0,0 @@
-using FluentValidation;
-using HotChocolate.Execution;
-using HotChocolate.Types;
-using Microsoft.Extensions.DependencyInjection;
-using Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-namespace FairyBread.Tests;
-
-public class GeneralTests
-{
- [Fact]
- public async Task Multi_TopLevelFields_And_MultiRuns_Works()
- {
- // Arrange
- var executor = await GetRequestExecutorAsync();
-
- var query = @"
- query {
- read(foo: { someInteger: -1, someString: ""hello"" })
- read(foo: { someInteger: -1, someString: ""hello"" })
- }";
-
- // Act
- var result1 = await executor.ExecuteAsync(query);
- var result2 = await executor.ExecuteAsync(query);
- var result3 = await executor.ExecuteAsync(query);
-
-
- // Assert
- await Verify(new { result1, result2, result3, });
- }
-
- [Fact]
- public async Task Ignores_Null_Argument_Value()
- {
- // Arrange
- var caseData = (CaseData)Cases().First()[0];
- var executor = await GetRequestExecutorAsync();
-
- var query = "query { read(foo: " + caseData.FooInput + ") }";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- var verifySettings = new VerifySettings();
- await Verify(result, verifySettings);
- }
-
- [Fact]
- public async Task Doesnt_Call_Field_Resolver_If_Invalid()
- {
- // Arrange
- var executor = await GetRequestExecutorAsync();
-
- var query = @"query { someResolver(foo: { someInteger: -1, someString: ""hello"" }) }";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- Assert.False(Query.WasFieldResolverCalled);
- await Verify(result);
- }
-
- [Fact]
- public async Task Should_Respect_ShouldValidateArgument_Option()
- {
- // Arrange
- var executor = await GetRequestExecutorAsync(
- options =>
- {
- options.ShouldValidateArgument = (o, t, a)
- => a.Parameter is { } p && p.ParameterType != typeof(FooInputDto);
- }
- );
-
- var query = @"mutation {
- write(
- foo: { someInteger: -1, someString: ""hello"" },
- bar: { emailAddress: ""ben@lol.com"" }) }";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- await Verify(result);
- }
-
- static GeneralTests()
- {
- VerifierSettings.NameForParameter(_ => _.CaseId);
- }
-
- private static async Task GetRequestExecutorAsync(
- Action? configureOptions = null,
- Action? configureServices = null,
- bool registerValidators = true
- )
- {
- var services = new ServiceCollection();
- configureServices?.Invoke(services);
-
- if (registerValidators)
- {
- services.AddValidator();
- services.AddValidator();
- services.AddValidator>();
- services.AddValidator();
- services.AddValidator();
- services.AddValidator();
- }
-
- var builder = services
- .AddGraphQL()
- .AddQueryType()
- .AddMutationType()
- .AddFairyBread(options => { configureOptions?.Invoke(options); });
-
- return await builder
- .BuildRequestExecutorAsync();
- }
-
- [Theory]
- [MemberData(nameof(Cases))]
- public async Task Query_Works(CaseData caseData)
- {
- // Arrange
- var executor = await GetRequestExecutorAsync();
-
- var query = "query { read(foo: " + caseData.FooInput + ", bar: " + caseData.BarInput + ") }";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- var verifySettings = new VerifySettings();
- verifySettings.UseParameters(caseData);
- await Verify(result, verifySettings);
- }
-
- [Theory]
- [MemberData(nameof(Cases))]
- public async Task Mutation_Works(CaseData caseData)
- {
- // Arrange
- var executor = await GetRequestExecutorAsync();
-
- var query = "mutation { write(foo: " + caseData.FooInput + ", bar: " + caseData.BarInput + ") }";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- var verifySettings = new VerifySettings();
- verifySettings.UseParameters(caseData);
- await Verify(result, verifySettings);
- }
-
- // TODO: Unit tests for:
- // - cancellation
- // - does adding validators after fairybread still work ok?
-
- public static IEnumerable Cases()
- {
- var caseId = 1;
- yield return new object[]
- {
- // Happy days
- new CaseData(caseId++, @"{ someInteger: 1, someString: ""hello"" }", @"{ emailAddress: ""ben@lol.com"" }"),
- };
- yield return new object[]
- {
- // Sync error
- new CaseData(caseId++, @"{ someInteger: -1, someString: ""hello"" }", @"{ emailAddress: ""ben@lol.com"" }"),
- };
- yield return new object[]
- {
- // Async error
- new CaseData(caseId++, @"{ someInteger: 1, someString: ""hello"" }", @"{ emailAddress: ""-1"" }"),
- };
- yield return new object[]
- {
- // Multiple sync errors and async error
- new CaseData(caseId++, @"{ someInteger: -1, someString: ""-1"" }", @"{ emailAddress: ""-1"" }"),
- };
- }
-
- public class CaseData
- {
- public CaseData(int caseId, string fooInput, string barInput)
- {
- CaseId = caseId.ToString();
- FooInput = fooInput;
- BarInput = barInput;
- }
-
- public string CaseId { get; set; }
- public string FooInput { get; set; }
- public string BarInput { get; set; }
- }
-
- [Theory]
- [MemberData(nameof(CollectionCases))]
- public async Task Query_Array_Works(CollectionCaseData caseData)
- {
- // Arrange
- var executor = await GetRequestExecutorAsync();
-
- var query = "query { readWithArrayArg(foos: " + caseData.FoosInput + ") }";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- var verifySettings = new VerifySettings();
- verifySettings.UseParameters(caseData.CaseId);
- await Verify(result, verifySettings);
- }
-
- [Theory]
- [MemberData(nameof(CollectionCases))]
- public async Task Query_List_Works(CollectionCaseData caseData)
- {
- // Arrange
- var executor = await GetRequestExecutorAsync();
-
- var query = "query { readWithListArg(foos: " + caseData.FoosInput + ") }";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- var verifySettings = new VerifySettings();
- verifySettings.UseParameters(caseData.CaseId);
- await Verify(result, verifySettings);
- }
-
- public static IEnumerable CollectionCases()
- {
- var caseId = 1;
- yield return new object[]
- {
- // Happy days, implied array
- new CollectionCaseData(caseId++, @"{ someInteger: 1, someString: ""hello"" }"),
- };
- yield return new object[]
- {
- // Happy days, explicit array
- new CollectionCaseData(caseId++, @"[{ someInteger: 1, someString: ""hello"" }]"),
- };
- yield return new object[]
- {
- // Happy days, multiple items
- new CollectionCaseData(caseId++, @"[{ someInteger: 1, someString: ""hello"" }, { someInteger: 1, someString: ""hello"" }]"),
- };
- yield return new object[]
- {
- // Error, implied array
- new CollectionCaseData(caseId++, @"{ someInteger: -1, someString: ""hello"" }"),
- };
- yield return new object[]
- {
- // Error, explicit array
- new CollectionCaseData(caseId++, @"[{ someInteger: -1, someString: ""hello"" }]"),
- };
- yield return new object[]
- {
- // Error, multiple items
- new CollectionCaseData(caseId++, @"[{ someInteger: -1, someString: ""hello"" }, { someInteger: -1, someString: ""hello"" }]"),
- };
- }
-
- public class CollectionCaseData
- {
- public CollectionCaseData(int caseId, string foosInput)
- {
- CaseId = caseId.ToString();
- FoosInput = foosInput;
- }
-
- public string CaseId { get; set; }
- public string FoosInput { get; set; }
- }
- #pragma warning disable CA1822 // Mark members as static
- public class Query
- {
- public static bool WasFieldResolverCalled { get; private set; }
-
- public string Read(FooInputDto foo, BarInputDto? bar)
- {
- return $"{foo}; {bar}";
- }
-
- public string ReadWithArrayArg(FooInputDto[] foos)
- {
- return string.Join(", ", foos.Select(f => f.ToString()));
- }
-
- public string ReadWithListArg(List foos)
- {
- return string.Join(", ", foos.Select(f => f.ToString()));
- }
-
- public string SomeResolver(FooInputDto foo, BarInputDto? bar)
- {
- WasFieldResolverCalled = true;
- return $"{foo}; {bar}";
- }
-
- public string IntResolver(int count)
- {
- return count.ToString();
- }
-
- public string NullableIntResolver(int? count)
- {
- return count?.ToString() ?? "null";
- }
- }
-
- public class Mutation
- {
- public string Write(FooInputDto foo, BarInputDto bar)
- {
- return $"{foo}; {bar}";
- }
- }
-
- public class MyInput : InputObjectType
- {
- protected override void Configure(IInputObjectTypeDescriptor descriptor)
- {
- descriptor.BindFieldsImplicitly();
- }
- }
-
- public class FooInputDto
- {
- public int SomeInteger { get; set; }
-
- public string SomeString { get; set; } = "";
-
- public override string ToString()
- {
- return $"SomeInteger: {SomeInteger}, " + $"SomeString: {SomeString}";
- }
- }
-
- public class FooInputDtoValidator : AbstractValidator
- {
- public FooInputDtoValidator()
- {
- RuleFor(x => x.SomeInteger).Equal(1);
- RuleFor(x => x.SomeString).Equal("hello");
- }
- }
-
- public class ArrayOfFooInputDtoValidator : AbstractValidator
- {
- public ArrayOfFooInputDtoValidator()
- {
- RuleForEach(x => x).SetValidator(new FooInputDtoValidator());
- }
- }
-
- public class ListOfFooInputDtoValidator : AbstractValidator>
- {
- public ListOfFooInputDtoValidator()
- {
- RuleForEach(x => x).SetValidator(new FooInputDtoValidator());
- }
- }
-
- public class BarInputDto
- {
- public string EmailAddress { get; set; } = "";
-
- public override string ToString()
- {
- return $"EmailAddress: {EmailAddress}";
- }
- }
-
- public abstract class BarInputDtoValidatorBase : AbstractValidator
- {
- public BarInputDtoValidatorBase()
- {
- RuleFor(x => x.EmailAddress).NotNull();
- }
- }
-
- public class BarInputDtoValidator : BarInputDtoValidatorBase { }
-
- public class BarInputDtoAsyncValidator : AbstractValidator
- {
- public BarInputDtoAsyncValidator()
- {
- RuleFor(x => x.EmailAddress)
- // TODO: Cancellation unit test
- .MustAsync((val, _) => Task.FromResult(val == "ben@lol.com"));
- }
- }
-
- public class NullableIntValidator : AbstractValidator
- {
- public NullableIntValidator()
- {
- RuleFor(x => x)
- //.Null()
- .GreaterThan(0)
- .When(x => x is { });
- }
- }
-}
\ No newline at end of file
diff --git a/test/Sample.Graphql.Tests/FairyBread.Tests/IServiceCollectionExtensions.cs b/test/Sample.Graphql.Tests/FairyBread.Tests/IServiceCollectionExtensions.cs
deleted file mode 100644
index 0785c4016..000000000
--- a/test/Sample.Graphql.Tests/FairyBread.Tests/IServiceCollectionExtensions.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using FluentValidation;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace FairyBread.Tests;
-
-public static class IServiceCollectionExtensions
-{
- public static IServiceCollection AddValidator(this IServiceCollection services)
- where TValidator : AbstractValidator
- {
- // Add the validator as its interface and its self as per
- // how FV does it and so that FairyBread can search it for the registry (via interface)
- // but instantiate it directly from the provider
- // https://github.com/FluentValidation/FluentValidation/blob/0e45f4efbab956d84f425b0b7d207ada516720bd/src/FluentValidation.DependencyInjectionExtensions/ServiceCollectionExtensions.cs#L90
- return services
- .AddTransient, TValidator>()
- .AddTransient();
- }
-}
\ No newline at end of file
diff --git a/test/Sample.Graphql.Tests/FairyBread.Tests/InjectorTests.cs b/test/Sample.Graphql.Tests/FairyBread.Tests/InjectorTests.cs
deleted file mode 100644
index 359945d4f..000000000
--- a/test/Sample.Graphql.Tests/FairyBread.Tests/InjectorTests.cs
+++ /dev/null
@@ -1,478 +0,0 @@
-using FluentValidation;
-using HotChocolate.Data;
-using HotChocolate.Execution;
-using HotChocolate.Types;
-using Microsoft.Extensions.DependencyInjection;
-using Rocket.Surgery.LaunchPad.HotChocolate.FairyBread;
-
-namespace FairyBread.Tests;
-
-public class InjectorTests
-{
- private static async Task GetRequestExecutorAsync(
- Action? configureOptions = null,
- Action? configureServices = null,
- bool registerValidators = true
- )
- {
- var services = new ServiceCollection();
- configureServices?.Invoke(services);
-
- if (registerValidators)
- {
- services.AddValidator();
- services.AddValidator();
- services.AddValidator();
- services.AddValidator();
- services.AddValidator();
- services.AddValidator();
- services.AddValidator>();
- services.AddValidator>>();
- services.AddValidator();
- services.AddValidator();
- }
-
- var builder = services
- .AddGraphQL()
- .AddQueryType()
- .AddType()
- .AddSorting()
- .AddFiltering()
- .AddFairyBread(options => { configureOptions?.Invoke(options); });
-
- return await builder
- .BuildRequestExecutorAsync();
- }
-
- [Theory]
- [InlineData(false)]
- [InlineData(true)]
- public async Task Works(bool registerValidators)
- {
- // Arrange
- var executor = await GetRequestExecutorAsync(
- registerValidators: registerValidators,
- configureOptions: options =>
- {
- if (!registerValidators)
- {
- options.ThrowIfNoValidatorsFound = false;
- }
- }
- );
-
- var query = "query { "
- + "noArgs "
- + "scalarArgsA(a: 0, b: false) "
- + "scalarArgsB(a: 0, b: false) "
- + "scalarArgsC(a: 0, b: false) "
- + "scalarArgsD(a: 0, b: false) "
- + "nullableScalarArgsA(a: 0, b: false) "
- + "nullableScalarArgsB(a: 0, b: false) "
- + "nullableScalarArgsC(a: 0, b: false) "
- + "nullableScalarArgsD(a: 0, b: false) "
- + "objectArgA(input: { a: 0, b: false }) "
- + "objectArgB(input: { a: 0, b: false }) "
- + "objectArgC(input: { a: 0, b: false }) "
- + "objectArgD(input: { a: 0, b: false }) "
- + "arrayArgA(items: [0, 0]) "
- + "listArgA(items: [0, 0]) "
- + "listArgB(items: [0, 0]) "
- + "listArgC(items: [0, 0]) "
- + "listArgD(items: [0, 0]) "
- + "listOfListArgC(items: [[0, 0], [0, 0]]) "
- + "filterSortAndPagingArgs(first: 10) { nodes { a } }"
- + "}";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- var verifySettings = new VerifySettings();
- verifySettings.UseParameters(registerValidators);
- await Verify(result, verifySettings);
- }
-
- [Theory]
- [InlineData(false)]
- [InlineData(true)]
- public async Task Should_Respect_ExplicitValidationAttributes(bool valid)
- {
- // Arrange
- var executor = await GetRequestExecutorAsync();
-
- var args = valid
- ? @"fooInt: 1,
- barInt: 1,
- lolInt: 1,
- fooInput: { a: 1, b: true },
- barInput: { a: 1, b: true },
- lolInput: { a: 1, b: true },
- dblInput: { a: 1, b: true }"
- : @"fooInt: -1,
- barInt: -1,
- lolInt: -1,
- fooInput: { a: 0, b: false },
- barInput: { a: 0, b: false },
- lolInput: { a: 0, b: false },
- dblInput: { a: 0, b: false }";
-
- var query = @"
- query {
- readWithExplicitValidation("
- + args
- + @")
- }";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- await Verify(result).UseParameters(valid);
- }
-
- [Theory]
- [InlineData(false)]
- [InlineData(true)]
- public async Task Should_Respect_ExplicitValidationFluent(bool valid)
- {
- // Arrange
- var executor = await GetRequestExecutorAsync();
-
- var args = valid
- ? @"fooInt: 1,
- barInt: 1,
- lolInt: 1,
- fooInput: { a: 1, b: true },
- barInput: { a: 1, b: true },
- lolInput: { a: 1, b: true },
- dblInput: { a: 1, b: true }"
- : @"fooInt: -1,
- barInt: -1,
- lolInt: -1,
- fooInput: { a: 0, b: false },
- barInput: { a: 0, b: false },
- lolInput: { a: 0, b: false },
- dblInput: { a: 0, b: false }";
-
- var query = @"
- query {
- readWithExplicitValidationFluent("
- + args
- + @")
- }";
-
- // Act
- var result = await executor.ExecuteAsync(query);
-
- // Assert
- await Verify(result).UseParameters(valid);
- }
- #pragma warning disable CA1822 // Mark members as static
- public class QueryI
- {
- public string NoArgs => "foo";
-
- public string ScalarArgsA(int a, bool b)
- {
- return $"{a} | {b}";
- }
-
- public string NullableScalarArgsA(int? a, bool? b)
- {
- return $"{a} | {b}";
- }
-
- public string ObjectArgA(TestInput input)
- {
- return input.ToString();
- }
-
- public string ArrayArgA(int?[] items)
- {
- return string.Join(", ", items);
- }
-
- public string ListArgA(List items)
- {
- return string.Join(", ", items);
- }
-
- [UsePaging]
- [UseFiltering]
- [UseSorting]
- public IEnumerable GetFilterSortAndPagingArgs()
- {
- return new FooI[] { new(), };
- }
-
- public string ReadWithExplicitValidation(
- // Should validate explicitly
- [Validate(typeof(PositiveIntValidator))]
- int fooInt,
- // Shouldn't validate implicitly
- [Validate(typeof(PositiveIntValidator))] [DontValidateImplicitly]
- int barInt,
- // Shouldn't validate
- [Validate(typeof(PositiveIntValidator))] [DontValidate]
- int lolInt,
- // Should validate explicitly
- [Validate(typeof(TestInputExplicitValidator))]
- TestInput fooInput,
- // Shouldn't validate implicitly
- [Validate(typeof(TestInputExplicitValidator))] [DontValidateImplicitly]
- TestInput barInput,
- // Shouldn't validate
- [Validate(typeof(TestInputExplicitValidator))] [DontValidate]
- TestInput lolInput,
- // Shouldn't add an implicitly added validator again
- [Validate(typeof(TestInputValidator))]
- TestInput dblInput
- )
- {
- return $"{fooInt} {barInt} {lolInt} {fooInput} {barInput} {lolInput}";
- }
- }
-
- public class QueryIType
- : ObjectType
- {
- protected override void Configure(IObjectTypeDescriptor descriptor)
- {
- descriptor
- .Field("scalarArgsB")
- .Argument("a", arg => arg.Type>())
- .Argument("b", arg => arg.Type