< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Hosting.Options.KestrelOptionsExtensions
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Hosting/Options/KestrelOptionsExtensions.cs
Tag: Kestrun/Kestrun@2d87023b37eb91155071c91dd3d6a2eeb3004705
Line coverage
100%
Covered lines: 21
Uncovered lines: 0
Coverable lines: 21
Total lines: 73
Line coverage: 100%
Branch coverage
100%
Covered branches: 22
Total branches: 22
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 08/26/2025 - 01:25:22 Line coverage: 100% (21/21) Branch coverage: 100% (22/22) Total lines: 73 Tag: Kestrun/Kestrun@07f821172e5dc3657f1be7e6818f18d6721cf38a 08/26/2025 - 01:25:22 Line coverage: 100% (21/21) Branch coverage: 100% (22/22) Total lines: 73 Tag: Kestrun/Kestrun@07f821172e5dc3657f1be7e6818f18d6721cf38a

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
CopyFromTemplate(...)100%1414100%
CopyLimits(...)100%88100%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Hosting/Options/KestrelOptionsExtensions.cs

#LineLine coverage
 1using System.Reflection;
 2using Microsoft.AspNetCore.Server.Kestrel.Core;
 3namespace Kestrun.Hosting.Options;
 4
 5/// <summary>
 6/// Provides extension methods for copying configuration between <see cref="KestrelServerOptions"/> instances.
 7/// </summary>
 8public static class KestrelOptionsExtensions
 9{
 10    /// <summary>
 11    /// Shallow-copies every writable property from <paramref name="src"/> to <paramref name="dest"/>,
 12    /// then deep-copies the nested <see cref="KestrelServerLimits"/>.
 13    /// A small “skip” list prevents us from overwriting framework internals.
 14    /// </summary>
 15    public static void CopyFromTemplate(this KestrelServerOptions dest,
 16                                        KestrelServerOptions src)
 17    {
 5818        if (dest is null || src is null)
 19        {
 220            throw new ArgumentNullException();
 21        }
 22
 5623        var skip = new HashSet<string>
 5624        {
 5625            nameof(KestrelServerOptions.ApplicationServices), // owned by the WebHost
 5626           //nameof(KestrelServerOptions.ListenOptions)        // you add those yourself
 5627        };
 28
 29        // ── 1. copy all simple writable props ───────────────────────────────
 145630        foreach (var p in typeof(KestrelServerOptions)
 5631                                   .GetProperties(BindingFlags.Public | BindingFlags.Instance))
 32        {
 67233            if (!p.CanRead || !p.CanWrite)
 34            {
 35                continue;              // read-only
 36            }
 37
 61638            if (p.GetIndexParameters().Length > 0)
 39            {
 40                continue;              // indexer
 41            }
 42
 61643            if (skip.Contains(p.Name))
 44            {
 45                continue;              // infrastructure
 46            }
 47
 56048            p.SetValue(dest, p.GetValue(src));
 49        }
 50
 51        // ── 2. deep-copy the Limits object (property itself is read-only) ──
 5652        CopyLimits(dest.Limits, src.Limits);
 5653    }
 54
 55    private static void CopyLimits(KestrelServerLimits dest, KestrelServerLimits src)
 56    {
 168057        foreach (var p in typeof(KestrelServerLimits)
 5658                                   .GetProperties(BindingFlags.Public | BindingFlags.Instance))
 59        {
 78460            if (!p.CanRead || !p.CanWrite)
 61            {
 62                continue;
 63            }
 64
 67265            if (p.GetIndexParameters().Length > 0)
 66            {
 67                continue;
 68            }
 69
 67270            p.SetValue(dest, p.GetValue(src));
 71        }
 5672    }
 73}