< Summary - Kestrun — Combined Coverage

Information
Class: PowerShellAttributes
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/OpenApi/PowerShellAttributes.cs
Tag: Kestrun/Kestrun@0d738bf294e6281b936d031e1979d928007495ff
Line coverage
4%
Covered lines: 3
Uncovered lines: 65
Coverable lines: 68
Total lines: 215
Line coverage: 4.4%
Branch coverage
2%
Covered branches: 2
Total branches: 72
Branch coverage: 2.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 12/12/2025 - 17:27:19 Line coverage: 4.4% (3/68) Branch coverage: 2.7% (2/72) Total lines: 215 Tag: Kestrun/Kestrun@826bf9dcf9db118c5de4c78a3259bce9549f0dcd 12/12/2025 - 17:27:19 Line coverage: 4.4% (3/68) Branch coverage: 2.7% (2/72) Total lines: 215 Tag: Kestrun/Kestrun@826bf9dcf9db118c5de4c78a3259bce9549f0dcd

Metrics

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/OpenApi/PowerShellAttributes.cs

#LineLine coverage
 1
 2using System.Management.Automation;
 3using System.Management.Automation.Internal;
 4using System.Reflection;
 5using System.Text.Json.Nodes;
 6using Kestrun.OpenApi;
 7using Microsoft.OpenApi;
 8
 9internal static class PowerShellAttributes
 10{
 11    /// <summary>
 12    /// Applies PowerShell CmdletMetadataAttribute validations to an OpenAPI schema.
 13    /// </summary>
 14    /// <param name="attr">The CmdletMetadataAttribute to apply.</param>
 15    /// <param name="schema">The OpenAPI schema to modify.</param>
 16    internal static void ApplyPowerShellAttribute(CmdletMetadataAttribute attr, OpenApiSchema schema)
 17    {
 018        _ = attr switch
 019        {
 020            ValidateRangeAttribute a => ApplyValidateRangeAttribute(a, schema),
 021
 022            ValidateLengthAttribute a => ApplyValidateLengthAttribute(a, schema),
 023
 024            ValidateSetAttribute a => ApplyValidateSetAttribute(a, schema),
 025
 026            ValidatePatternAttribute a => ApplyValidatePatternAttribute(a, schema),
 027
 028            ValidateCountAttribute a => ApplyValidateCountAttribute(a, schema),
 029
 030            ValidateNotNullOrEmptyAttribute => ApplyNotNullOrEmpty(schema),
 031            ValidateNotNullAttribute => ApplyNotNull(schema),
 032            ValidateNotNullOrWhiteSpaceAttribute => ApplyNotNullOrWhiteSpace(schema),
 033            _ => null
 034        };
 035    }
 36
 37    /// <summary>
 38    /// Applies PowerShell validation attributes declared on a property to the specified schema.
 39    /// </summary>
 40    /// <param name="p">The property info to inspect for validation attributes.</param>
 41    /// <param name="s">The OpenAPI schema to apply constraints to.</param>
 42    internal static void ApplyPowerShellAttributes(PropertyInfo p, IOpenApiSchema s)
 43    {
 2744        if (s is not OpenApiSchema sc)
 45        {
 46            // constraints only applicable on a concrete schema, not a $ref proxy
 047            return;
 48        }
 49
 50        // Only pick PowerShell cmdlet metadata / validation attributes;
 51        // no magic string on Type.Name needed.
 5452        foreach (var attr in p.GetCustomAttributes<CmdletMetadataAttribute>(inherit: false))
 53        {
 054            ApplyPowerShellAttribute(attr, sc);
 55        }
 2756    }
 57
 58    /// <summary>
 59    /// Applies a ValidateRangeAttribute to an OpenApiSchema.
 60    /// </summary>
 61    /// <param name="attr">The ValidateRangeAttribute to apply.</param>
 62    /// <param name="schema">The OpenApiSchema to modify.</param>
 63    /// <returns>Returns always null.</returns>
 64    private static object? ApplyValidateRangeAttribute(ValidateRangeAttribute attr, OpenApiSchema schema)
 65    {
 066        var min = attr.MinRange;
 067        var max = attr.MaxRange;
 068        if (min is not null)
 69        {
 070            schema.Minimum = min.ToString();
 71        }
 072        if (max is not null)
 73        {
 074            schema.Maximum = max.ToString();
 75        }
 076        return null;
 77    }
 78
 79    /// <summary>
 80    /// Applies a ValidateLengthAttribute to an OpenApiSchema.
 81    /// </summary>
 82    /// <param name="attr">The ValidateLengthAttribute to apply.</param>
 83    /// <param name="schema">The OpenApiSchema to modify.</param>
 84    /// <returns>Returns always null.</returns>
 85    private static object? ApplyValidateLengthAttribute(ValidateLengthAttribute attr, OpenApiSchema schema)
 86    {
 087        var minLen = attr.MinLength;
 088        var maxLen = attr.MaxLength;
 089        if (minLen >= 0)
 90        {
 091            schema.MinLength = minLen;
 92        }
 093        if (maxLen >= 0)
 94        {
 095            schema.MaxLength = maxLen;
 96        }
 097        return null;
 98    }
 99
 100    /// <summary>
 101    /// Applies a ValidateSetAttribute to an OpenApiSchema.
 102    /// </summary>
 103    /// <param name="attr">The ValidateSetAttribute to apply.</param>
 104    /// <param name="sc">The OpenApiSchema to modify.</param>
 105    /// <returns>Returns always null.</returns>
 106    private static object? ApplyValidateSetAttribute(ValidateSetAttribute attr, OpenApiSchema sc)
 107    {
 0108        var vals = attr.ValidValues;
 0109        if (vals is not null)
 110        {
 0111            var list = new List<JsonNode>();
 0112            foreach (var node in vals.Select(OpenApiDocDescriptor.ToNode))
 113            {
 0114                if (node is not null)
 115                {
 0116                    list.Add(node);
 117                }
 118            }
 119
 0120            if (list.Count > 0)
 121            {
 0122                var existing = sc.Enum?.ToList() ?? [];
 0123                existing.AddRange(list);
 0124                sc.Enum = existing;
 125            }
 126        }
 0127        return null;
 128    }
 129
 130    /// <summary>
 131    /// Applies a ValidatePatternAttribute to an OpenApiSchema.
 132    /// </summary>
 133    /// <param name="attr">The ValidatePatternAttribute to apply.</param>
 134    /// <param name="sc">The OpenApiSchema to modify.</param>
 135    /// <returns>Returns always null.</returns>
 136    private static object? ApplyValidatePatternAttribute(ValidatePatternAttribute attr, OpenApiSchema sc)
 137    {
 0138        if (string.IsNullOrWhiteSpace(sc.Pattern))
 139        {
 0140            sc.Pattern = attr.RegexPattern;
 141        }
 0142        return null;
 143    }
 144
 145    /// <summary>
 146    /// Applies a ValidateCountAttribute to an OpenApiSchema.
 147    /// </summary>
 148    /// <param name="attr">The ValidateCountAttribute to apply.</param>
 149    /// <param name="sc">The OpenApiSchema to modify.</param>
 150    /// <returns>Returns always null.</returns>
 151    private static object? ApplyValidateCountAttribute(ValidateCountAttribute attr, OpenApiSchema sc)
 152    {
 0153        if (attr.MinLength >= 0)
 154        {
 0155            sc.MinItems = attr.MinLength;
 156        }
 157
 0158        if (attr.MaxLength >= 0)
 159        {
 0160            sc.MaxItems = attr.MaxLength;
 161        }
 0162        return null;
 163    }
 164
 165    /// <summary>
 166    /// Applies a ValidateNotNullOrEmptyAttribute to an OpenApiSchema.
 167    /// </summary>
 168    /// <param name="sc">The OpenApiSchema to modify.</param>
 169    /// <returns>Returns always null.</returns>
 170    private static object? ApplyNotNullOrEmpty(OpenApiSchema sc)
 171    {
 172        // string → minLength >= 1
 0173        if (sc.Type == JsonSchemaType.String && (sc.MinLength is null or < 1))
 174        {
 0175            sc.MinLength = 1;
 176        }
 177
 178        // array → minItems >= 1
 0179        if (sc.Type == JsonSchemaType.Array && (sc.MinItems is null or < 1))
 180        {
 0181            sc.MinItems = 1;
 182        }
 183
 0184        return null;
 185    }
 186
 187    /// <summary>
 188    /// Applies a ValidateNotNullOrWhiteSpaceAttribute to an OpenApiSchema.
 189    /// </summary>
 190    /// <param name="sc">The OpenApiSchema to modify.</param>
 191    /// <returns>Returns always null.</returns>
 192    private static object? ApplyNotNullOrWhiteSpace(OpenApiSchema sc)
 193    {
 0194        if (sc.Type == JsonSchemaType.String)
 195        {
 0196            if (sc.MinLength is null or < 1)
 197            {
 0198                sc.MinLength = 1;
 199            }
 0200            if (string.IsNullOrEmpty(sc.Pattern))
 201            {
 202                // No existing pattern → just require a non-whitespace character
 0203                sc.Pattern = @"\S";
 204            }
 205        }
 0206        return null;
 207    }
 208
 209    /// <summary>
 210    /// Applies a ValidateNotNullAttribute to an OpenApiSchema.
 211    /// </summary>
 212    /// <param name="schema">The OpenApiSchema to modify.</param>
 213    /// <returns>Returns always null.</returns>
 0214    private static object? ApplyNotNull(OpenApiSchema schema) => ApplyNotNullOrEmpty(schema);
 215}