diff --git a/eng/Dependencies.props b/eng/Dependencies.props index 51d1105d9e2e..18be2fda9f68 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -189,6 +189,7 @@ and are generated based on the last package release. + diff --git a/eng/Versions.props b/eng/Versions.props index 1a5f3a180b9b..dbea555cdc29 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -257,6 +257,7 @@ $(MessagePackVersion) 4.10.0 0.11.2 + 2.2.1 1.0.2 13.0.1 13.0.4 diff --git a/src/Http/Http.Results/Directory.Build.props b/src/Http/Http.Results/Directory.Build.props new file mode 100644 index 000000000000..dcd7ca497754 --- /dev/null +++ b/src/Http/Http.Results/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + $(MSBuildThisFileDirectory)\src + + diff --git a/src/Http/Http.Results/src/Microsoft.AspNetCore.Http.Results.csproj b/src/Http/Http.Results/src/Microsoft.AspNetCore.Http.Results.csproj index cfa2eb2e0da9..0d9845104cc4 100644 --- a/src/Http/Http.Results/src/Microsoft.AspNetCore.Http.Results.csproj +++ b/src/Http/Http.Results/src/Microsoft.AspNetCore.Http.Results.csproj @@ -28,4 +28,16 @@ + + + + + + + + TextTemplatingFileGenerator + ResultsCache.StatusCodes.cs + + + diff --git a/src/Http/Http.Results/src/Results.cs b/src/Http/Http.Results/src/Results.cs index 89b9c12bde7d..35187a07d435 100644 --- a/src/Http/Http.Results/src/Results.cs +++ b/src/Http/Http.Results/src/Results.cs @@ -495,7 +495,7 @@ public static IResult RedirectToRoute(string? routeName = null, object? routeVal /// The status code to set on the response. /// The created object for the response. public static IResult StatusCode(int statusCode) - => new StatusCodeHttpResult(statusCode); + => ResultsCache.StatusCode(statusCode); /// /// Produces a response. @@ -503,14 +503,14 @@ public static IResult StatusCode(int statusCode) /// The value to be included in the HTTP response body. /// The created for the response. public static IResult NotFound(object? value = null) - => new NotFoundObjectHttpResult(value); + => value is null ? ResultsCache.NotFound : new NotFoundObjectHttpResult(value); /// /// Produces a response. /// /// The created for the response. public static IResult Unauthorized() - => new UnauthorizedHttpResult(); + => ResultsCache.Unauthorized; /// /// Produces a response. @@ -518,7 +518,7 @@ public static IResult Unauthorized() /// An error object to be included in the HTTP response body. /// The created for the response. public static IResult BadRequest(object? error = null) - => new BadRequestObjectHttpResult(error); + => error is null ? ResultsCache.BadRequest : new BadRequestObjectHttpResult(error); /// /// Produces a response. @@ -526,14 +526,14 @@ public static IResult BadRequest(object? error = null) /// An error object to be included in the HTTP response body. /// The created for the response. public static IResult Conflict(object? error = null) - => new ConflictObjectHttpResult(error); + => error is null ? ResultsCache.Conflict : new ConflictObjectHttpResult(error); /// /// Produces a response. /// /// The created for the response. public static IResult NoContent() - => new NoContentHttpResult(); + => ResultsCache.NoContent; /// /// Produces a response. @@ -541,7 +541,7 @@ public static IResult NoContent() /// The value to be included in the HTTP response body. /// The created for the response. public static IResult Ok(object? value = null) - => new OkObjectHttpResult(value); + => value is null ? ResultsCache.Ok : new OkObjectHttpResult(value); /// /// Produces a response. @@ -549,7 +549,7 @@ public static IResult Ok(object? value = null) /// An error object to be included in the HTTP response body. /// The created for the response. public static IResult UnprocessableEntity(object? error = null) - => new UnprocessableEntityObjectHttpResult(error); + => error is null ? ResultsCache.UnprocessableEntity : new UnprocessableEntityObjectHttpResult(error); /// /// Produces a response. diff --git a/src/Http/Http.Results/src/ResultsCache.StatusCodes.cs b/src/Http/Http.Results/src/ResultsCache.StatusCodes.cs new file mode 100644 index 000000000000..4e255cd9449c --- /dev/null +++ b/src/Http/Http.Results/src/ResultsCache.StatusCodes.cs @@ -0,0 +1,151 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +#nullable enable + +using System.CodeDom.Compiler; + +namespace Microsoft.AspNetCore.Http; + +[GeneratedCode("TextTemplatingFileGenerator", "")] +internal partial class ResultsCache +{ + private static StatusCodeHttpResult? _status101SwitchingProtocols; + private static StatusCodeHttpResult? _status102Processing; + private static StatusCodeHttpResult? _status200OK; + private static StatusCodeHttpResult? _status201Created; + private static StatusCodeHttpResult? _status202Accepted; + private static StatusCodeHttpResult? _status203NonAuthoritative; + private static StatusCodeHttpResult? _status204NoContent; + private static StatusCodeHttpResult? _status205ResetContent; + private static StatusCodeHttpResult? _status206PartialContent; + private static StatusCodeHttpResult? _status207MultiStatus; + private static StatusCodeHttpResult? _status208AlreadyReported; + private static StatusCodeHttpResult? _status226IMUsed; + private static StatusCodeHttpResult? _status300MultipleChoices; + private static StatusCodeHttpResult? _status301MovedPermanently; + private static StatusCodeHttpResult? _status302Found; + private static StatusCodeHttpResult? _status303SeeOther; + private static StatusCodeHttpResult? _status304NotModified; + private static StatusCodeHttpResult? _status305UseProxy; + private static StatusCodeHttpResult? _status306SwitchProxy; + private static StatusCodeHttpResult? _status307TemporaryRedirect; + private static StatusCodeHttpResult? _status308PermanentRedirect; + private static StatusCodeHttpResult? _status400BadRequest; + private static StatusCodeHttpResult? _status401Unauthorized; + private static StatusCodeHttpResult? _status402PaymentRequired; + private static StatusCodeHttpResult? _status403Forbidden; + private static StatusCodeHttpResult? _status404NotFound; + private static StatusCodeHttpResult? _status405MethodNotAllowed; + private static StatusCodeHttpResult? _status406NotAcceptable; + private static StatusCodeHttpResult? _status407ProxyAuthenticationRequired; + private static StatusCodeHttpResult? _status408RequestTimeout; + private static StatusCodeHttpResult? _status409Conflict; + private static StatusCodeHttpResult? _status410Gone; + private static StatusCodeHttpResult? _status411LengthRequired; + private static StatusCodeHttpResult? _status412PreconditionFailed; + private static StatusCodeHttpResult? _status413RequestEntityTooLarge; + private static StatusCodeHttpResult? _status414RequestUriTooLong; + private static StatusCodeHttpResult? _status415UnsupportedMediaType; + private static StatusCodeHttpResult? _status416RequestedRangeNotSatisfiable; + private static StatusCodeHttpResult? _status417ExpectationFailed; + private static StatusCodeHttpResult? _status418ImATeapot; + private static StatusCodeHttpResult? _status419AuthenticationTimeout; + private static StatusCodeHttpResult? _status421MisdirectedRequest; + private static StatusCodeHttpResult? _status422UnprocessableEntity; + private static StatusCodeHttpResult? _status423Locked; + private static StatusCodeHttpResult? _status424FailedDependency; + private static StatusCodeHttpResult? _status426UpgradeRequired; + private static StatusCodeHttpResult? _status428PreconditionRequired; + private static StatusCodeHttpResult? _status429TooManyRequests; + private static StatusCodeHttpResult? _status431RequestHeaderFieldsTooLarge; + private static StatusCodeHttpResult? _status451UnavailableForLegalReasons; + private static StatusCodeHttpResult? _status500InternalServerError; + private static StatusCodeHttpResult? _status501NotImplemented; + private static StatusCodeHttpResult? _status502BadGateway; + private static StatusCodeHttpResult? _status503ServiceUnavailable; + private static StatusCodeHttpResult? _status504GatewayTimeout; + private static StatusCodeHttpResult? _status505HttpVersionNotsupported; + private static StatusCodeHttpResult? _status506VariantAlsoNegotiates; + private static StatusCodeHttpResult? _status507InsufficientStorage; + private static StatusCodeHttpResult? _status508LoopDetected; + private static StatusCodeHttpResult? _status510NotExtended; + private static StatusCodeHttpResult? _status511NetworkAuthenticationRequired; + + internal static StatusCodeHttpResult StatusCode(int statusCode) + { + if (statusCode is (< 100) or (> 599)) + { + // No HTTP status code assigned outside the 100..599 range + // so, it will not be available in the cache + return new StatusCodeHttpResult(statusCode); + } + + return statusCode switch + { + StatusCodes.Status101SwitchingProtocols => _status101SwitchingProtocols ??= new(StatusCodes.Status101SwitchingProtocols), + StatusCodes.Status102Processing => _status102Processing ??= new(StatusCodes.Status102Processing), + StatusCodes.Status200OK => _status200OK ??= new(StatusCodes.Status200OK), + StatusCodes.Status201Created => _status201Created ??= new(StatusCodes.Status201Created), + StatusCodes.Status202Accepted => _status202Accepted ??= new(StatusCodes.Status202Accepted), + StatusCodes.Status203NonAuthoritative => _status203NonAuthoritative ??= new(StatusCodes.Status203NonAuthoritative), + StatusCodes.Status204NoContent => _status204NoContent ??= new(StatusCodes.Status204NoContent), + StatusCodes.Status205ResetContent => _status205ResetContent ??= new(StatusCodes.Status205ResetContent), + StatusCodes.Status206PartialContent => _status206PartialContent ??= new(StatusCodes.Status206PartialContent), + StatusCodes.Status207MultiStatus => _status207MultiStatus ??= new(StatusCodes.Status207MultiStatus), + StatusCodes.Status208AlreadyReported => _status208AlreadyReported ??= new(StatusCodes.Status208AlreadyReported), + StatusCodes.Status226IMUsed => _status226IMUsed ??= new(StatusCodes.Status226IMUsed), + StatusCodes.Status300MultipleChoices => _status300MultipleChoices ??= new(StatusCodes.Status300MultipleChoices), + StatusCodes.Status301MovedPermanently => _status301MovedPermanently ??= new(StatusCodes.Status301MovedPermanently), + StatusCodes.Status302Found => _status302Found ??= new(StatusCodes.Status302Found), + StatusCodes.Status303SeeOther => _status303SeeOther ??= new(StatusCodes.Status303SeeOther), + StatusCodes.Status304NotModified => _status304NotModified ??= new(StatusCodes.Status304NotModified), + StatusCodes.Status305UseProxy => _status305UseProxy ??= new(StatusCodes.Status305UseProxy), + StatusCodes.Status306SwitchProxy => _status306SwitchProxy ??= new(StatusCodes.Status306SwitchProxy), + StatusCodes.Status307TemporaryRedirect => _status307TemporaryRedirect ??= new(StatusCodes.Status307TemporaryRedirect), + StatusCodes.Status308PermanentRedirect => _status308PermanentRedirect ??= new(StatusCodes.Status308PermanentRedirect), + StatusCodes.Status400BadRequest => _status400BadRequest ??= new(StatusCodes.Status400BadRequest), + StatusCodes.Status401Unauthorized => _status401Unauthorized ??= new(StatusCodes.Status401Unauthorized), + StatusCodes.Status402PaymentRequired => _status402PaymentRequired ??= new(StatusCodes.Status402PaymentRequired), + StatusCodes.Status403Forbidden => _status403Forbidden ??= new(StatusCodes.Status403Forbidden), + StatusCodes.Status404NotFound => _status404NotFound ??= new(StatusCodes.Status404NotFound), + StatusCodes.Status405MethodNotAllowed => _status405MethodNotAllowed ??= new(StatusCodes.Status405MethodNotAllowed), + StatusCodes.Status406NotAcceptable => _status406NotAcceptable ??= new(StatusCodes.Status406NotAcceptable), + StatusCodes.Status407ProxyAuthenticationRequired => _status407ProxyAuthenticationRequired ??= new(StatusCodes.Status407ProxyAuthenticationRequired), + StatusCodes.Status408RequestTimeout => _status408RequestTimeout ??= new(StatusCodes.Status408RequestTimeout), + StatusCodes.Status409Conflict => _status409Conflict ??= new(StatusCodes.Status409Conflict), + StatusCodes.Status410Gone => _status410Gone ??= new(StatusCodes.Status410Gone), + StatusCodes.Status411LengthRequired => _status411LengthRequired ??= new(StatusCodes.Status411LengthRequired), + StatusCodes.Status412PreconditionFailed => _status412PreconditionFailed ??= new(StatusCodes.Status412PreconditionFailed), + StatusCodes.Status413RequestEntityTooLarge => _status413RequestEntityTooLarge ??= new(StatusCodes.Status413RequestEntityTooLarge), + StatusCodes.Status414RequestUriTooLong => _status414RequestUriTooLong ??= new(StatusCodes.Status414RequestUriTooLong), + StatusCodes.Status415UnsupportedMediaType => _status415UnsupportedMediaType ??= new(StatusCodes.Status415UnsupportedMediaType), + StatusCodes.Status416RequestedRangeNotSatisfiable => _status416RequestedRangeNotSatisfiable ??= new(StatusCodes.Status416RequestedRangeNotSatisfiable), + StatusCodes.Status417ExpectationFailed => _status417ExpectationFailed ??= new(StatusCodes.Status417ExpectationFailed), + StatusCodes.Status418ImATeapot => _status418ImATeapot ??= new(StatusCodes.Status418ImATeapot), + StatusCodes.Status419AuthenticationTimeout => _status419AuthenticationTimeout ??= new(StatusCodes.Status419AuthenticationTimeout), + StatusCodes.Status421MisdirectedRequest => _status421MisdirectedRequest ??= new(StatusCodes.Status421MisdirectedRequest), + StatusCodes.Status422UnprocessableEntity => _status422UnprocessableEntity ??= new(StatusCodes.Status422UnprocessableEntity), + StatusCodes.Status423Locked => _status423Locked ??= new(StatusCodes.Status423Locked), + StatusCodes.Status424FailedDependency => _status424FailedDependency ??= new(StatusCodes.Status424FailedDependency), + StatusCodes.Status426UpgradeRequired => _status426UpgradeRequired ??= new(StatusCodes.Status426UpgradeRequired), + StatusCodes.Status428PreconditionRequired => _status428PreconditionRequired ??= new(StatusCodes.Status428PreconditionRequired), + StatusCodes.Status429TooManyRequests => _status429TooManyRequests ??= new(StatusCodes.Status429TooManyRequests), + StatusCodes.Status431RequestHeaderFieldsTooLarge => _status431RequestHeaderFieldsTooLarge ??= new(StatusCodes.Status431RequestHeaderFieldsTooLarge), + StatusCodes.Status451UnavailableForLegalReasons => _status451UnavailableForLegalReasons ??= new(StatusCodes.Status451UnavailableForLegalReasons), + StatusCodes.Status500InternalServerError => _status500InternalServerError ??= new(StatusCodes.Status500InternalServerError), + StatusCodes.Status501NotImplemented => _status501NotImplemented ??= new(StatusCodes.Status501NotImplemented), + StatusCodes.Status502BadGateway => _status502BadGateway ??= new(StatusCodes.Status502BadGateway), + StatusCodes.Status503ServiceUnavailable => _status503ServiceUnavailable ??= new(StatusCodes.Status503ServiceUnavailable), + StatusCodes.Status504GatewayTimeout => _status504GatewayTimeout ??= new(StatusCodes.Status504GatewayTimeout), + StatusCodes.Status505HttpVersionNotsupported => _status505HttpVersionNotsupported ??= new(StatusCodes.Status505HttpVersionNotsupported), + StatusCodes.Status506VariantAlsoNegotiates => _status506VariantAlsoNegotiates ??= new(StatusCodes.Status506VariantAlsoNegotiates), + StatusCodes.Status507InsufficientStorage => _status507InsufficientStorage ??= new(StatusCodes.Status507InsufficientStorage), + StatusCodes.Status508LoopDetected => _status508LoopDetected ??= new(StatusCodes.Status508LoopDetected), + StatusCodes.Status510NotExtended => _status510NotExtended ??= new(StatusCodes.Status510NotExtended), + StatusCodes.Status511NetworkAuthenticationRequired => _status511NetworkAuthenticationRequired ??= new(StatusCodes.Status511NetworkAuthenticationRequired), + _ => new StatusCodeHttpResult(statusCode), + }; + } +} diff --git a/src/Http/Http.Results/src/ResultsCache.StatusCodes.tt b/src/Http/Http.Results/src/ResultsCache.StatusCodes.tt new file mode 100644 index 000000000000..578deef36952 --- /dev/null +++ b/src/Http/Http.Results/src/ResultsCache.StatusCodes.tt @@ -0,0 +1,106 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ output extension=".cs" #> +<# + /// A collection of constants for + /// HTTP status codes. + var statusCodes = new[] + { + new { StatusCode = 101, Name = "101SwitchingProtocols"}, + new { StatusCode = 102, Name = "102Processing"}, + new { StatusCode = 200, Name = "200OK"}, + new { StatusCode = 201, Name = "201Created"}, + new { StatusCode = 202, Name = "202Accepted"}, + new { StatusCode = 203, Name = "203NonAuthoritative"}, + new { StatusCode = 204, Name = "204NoContent"}, + new { StatusCode = 205, Name = "205ResetContent"}, + new { StatusCode = 206, Name = "206PartialContent"}, + new { StatusCode = 207, Name = "207MultiStatus"}, + new { StatusCode = 208, Name = "208AlreadyReported"}, + new { StatusCode = 226, Name = "226IMUsed"}, + new { StatusCode = 300, Name = "300MultipleChoices"}, + new { StatusCode = 301, Name = "301MovedPermanently"}, + new { StatusCode = 302, Name = "302Found"}, + new { StatusCode = 303, Name = "303SeeOther"}, + new { StatusCode = 304, Name = "304NotModified"}, + new { StatusCode = 305, Name = "305UseProxy"}, + new { StatusCode = 306, Name = "306SwitchProxy"}, + new { StatusCode = 307, Name = "307TemporaryRedirect"}, + new { StatusCode = 308, Name = "308PermanentRedirect"}, + new { StatusCode = 400, Name = "400BadRequest"}, + new { StatusCode = 401, Name = "401Unauthorized"}, + new { StatusCode = 402, Name = "402PaymentRequired"}, + new { StatusCode = 403, Name = "403Forbidden"}, + new { StatusCode = 404, Name = "404NotFound"}, + new { StatusCode = 405, Name = "405MethodNotAllowed"}, + new { StatusCode = 406, Name = "406NotAcceptable"}, + new { StatusCode = 407, Name = "407ProxyAuthenticationRequired"}, + new { StatusCode = 408, Name = "408RequestTimeout"}, + new { StatusCode = 409, Name = "409Conflict"}, + new { StatusCode = 410, Name = "410Gone"}, + new { StatusCode = 411, Name = "411LengthRequired"}, + new { StatusCode = 412, Name = "412PreconditionFailed"}, + new { StatusCode = 413, Name = "413RequestEntityTooLarge"}, + new { StatusCode = 414, Name = "414RequestUriTooLong"}, + new { StatusCode = 415, Name = "415UnsupportedMediaType"}, + new { StatusCode = 416, Name = "416RequestedRangeNotSatisfiable"}, + new { StatusCode = 417, Name = "417ExpectationFailed"}, + new { StatusCode = 418, Name = "418ImATeapot"}, + new { StatusCode = 419, Name = "419AuthenticationTimeout"}, + new { StatusCode = 421, Name = "421MisdirectedRequest"}, + new { StatusCode = 422, Name = "422UnprocessableEntity"}, + new { StatusCode = 423, Name = "423Locked"}, + new { StatusCode = 424, Name = "424FailedDependency"}, + new { StatusCode = 426, Name = "426UpgradeRequired"}, + new { StatusCode = 428, Name = "428PreconditionRequired"}, + new { StatusCode = 429, Name = "429TooManyRequests"}, + new { StatusCode = 431, Name = "431RequestHeaderFieldsTooLarge"}, + new { StatusCode = 451, Name = "451UnavailableForLegalReasons"}, + new { StatusCode = 500, Name = "500InternalServerError"}, + new { StatusCode = 501, Name = "501NotImplemented"}, + new { StatusCode = 502, Name = "502BadGateway"}, + new { StatusCode = 503, Name = "503ServiceUnavailable"}, + new { StatusCode = 504, Name = "504GatewayTimeout"}, + new { StatusCode = 505, Name = "505HttpVersionNotsupported"}, + new { StatusCode = 506, Name = "506VariantAlsoNegotiates"}, + new { StatusCode = 507, Name = "507InsufficientStorage"}, + new { StatusCode = 508, Name = "508LoopDetected"}, + new { StatusCode = 510, Name = "510NotExtended"}, + new { StatusCode = 511, Name = "511NetworkAuthenticationRequired"}, + }; +#> +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +#nullable enable + +using System.CodeDom.Compiler; + +namespace Microsoft.AspNetCore.Http; + +[GeneratedCode("TextTemplatingFileGenerator", "")] +internal partial class ResultsCache +{ +<# foreach (var statusCode in statusCodes) { #> + private static StatusCodeHttpResult? _status<#= statusCode.Name #>; +<# } #> + + internal static StatusCodeHttpResult StatusCode(int statusCode) + { + if (statusCode is (< 100) or (> 599)) + { + // No HTTP status code assigned outside the 100..599 range + // so, it will not be available in the cache + return new StatusCodeHttpResult(statusCode); + } + + return statusCode switch + { +<# foreach (var statusCode in statusCodes) { #> + StatusCodes.Status<#= statusCode.Name #> => _status<#= statusCode.Name #> ??= new(StatusCodes.Status<#= statusCode.Name #>), +<# } #> + _ => new StatusCodeHttpResult(statusCode), + }; + } +} diff --git a/src/Http/Http.Results/src/ResultsCache.cs b/src/Http/Http.Results/src/ResultsCache.cs new file mode 100644 index 000000000000..dcdcaf092fb0 --- /dev/null +++ b/src/Http/Http.Results/src/ResultsCache.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.AspNetCore.Http; + +internal static partial class ResultsCache +{ + public static NotFoundObjectHttpResult NotFound { get; } = new(null); + public static UnauthorizedHttpResult Unauthorized { get; } = new(); + public static BadRequestObjectHttpResult BadRequest { get; } = new(null); + public static ConflictObjectHttpResult Conflict { get; } = new(null); + public static NoContentHttpResult NoContent { get; } = new(); + public static OkObjectHttpResult Ok { get; } = new(null); + public static UnprocessableEntityObjectHttpResult UnprocessableEntity { get; } = new(null); +} diff --git a/src/Http/Http.Results/test/Microsoft.AspNetCore.Http.Results.Tests.csproj b/src/Http/Http.Results/test/Microsoft.AspNetCore.Http.Results.Tests.csproj index f59c42ded08a..e89f39527936 100644 --- a/src/Http/Http.Results/test/Microsoft.AspNetCore.Http.Results.Tests.csproj +++ b/src/Http/Http.Results/test/Microsoft.AspNetCore.Http.Results.Tests.csproj @@ -1,4 +1,4 @@ - + $(DefaultNetCoreTargetFramework) @@ -8,12 +8,14 @@ + - - + + + diff --git a/src/Http/Http.Results/test/ResultsCacheTests.cs b/src/Http/Http.Results/test/ResultsCacheTests.cs new file mode 100644 index 000000000000..15593f88fdea --- /dev/null +++ b/src/Http/Http.Results/test/ResultsCacheTests.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.AspNetCore.Http.Results.Tests; + +using Mono.TextTemplating; + +public class ResultsCacheTests +{ + [Fact] + public void GeneratedCodeIsUpToDate() + { + var currentContentPath = Path.Combine(AppContext.BaseDirectory, "Shared", "GeneratedContent", "ResultsCache.StatusCodes.cs"); + var templatePath = Path.Combine(AppContext.BaseDirectory, "Shared", "GeneratedContent", "ResultsCache.StatusCodes.tt"); + + var generator = new TemplateGenerator(); + var compiledTemplate = generator.CompileTemplate(File.ReadAllText(templatePath)); + + var generatedContent = compiledTemplate.Process(); + var currentContent = File.ReadAllText(currentContentPath); + + Assert.Equal(currentContent, generatedContent); + } +} diff --git a/src/Http/README.md b/src/Http/README.md index b8be410bf8c4..8204a3985644 100644 --- a/src/Http/README.md +++ b/src/Http/README.md @@ -25,6 +25,13 @@ The following contains a description of each sub-directory in the `Http` directo ## Development Setup +To run the code generation using [T4 Text Templates](https://docs.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates), you can use an IDE that supports it (eg. Visual Studio or JetBrains Rider) or install the cross-platform open-source dotnet tool [Mono/T4](https://github.com/mono/t4). + +```powershell +> dotnet tool install -g dotnet-t4 +> t4 Http.Results\ResultsCache.StatusCodes.tt +``` + ### Build To build this specific project from source, follow the instructions [on building the project](../../docs/BuildFromSource.md#step-3-build-the-repo).