< 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@5f1d2b981c9d7292c11fd448428c6ab6c811c5de
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 11/19/2025 - 17:40:50 Line coverage: 100% (21/21) Branch coverage: 100% (22/22) Total lines: 73 Tag: Kestrun/Kestrun@fcf33342333cef0516fe0d0912a86709874fd026 11/19/2025 - 17:40:50 Line coverage: 100% (21/21) Branch coverage: 100% (22/22) Total lines: 73 Tag: Kestrun/Kestrun@fcf33342333cef0516fe0d0912a86709874fd026

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    {
 7918        if (dest is null || src is null)
 19        {
 220            throw new ArgumentNullException();
 21        }
 22
 7723        var skip = new HashSet<string>
 7724        {
 7725            nameof(KestrelServerOptions.ApplicationServices), // owned by the WebHost
 7726           //nameof(KestrelServerOptions.ListenOptions)        // you add those yourself
 7727        };
 28
 29        // ── 1. copy all simple writable props ───────────────────────────────
 200230        foreach (var p in typeof(KestrelServerOptions)
 7731                                   .GetProperties(BindingFlags.Public | BindingFlags.Instance))
 32        {
 92433            if (!p.CanRead || !p.CanWrite)
 34            {
 35                continue;              // read-only
 36            }
 37
 84738            if (p.GetIndexParameters().Length > 0)
 39            {
 40                continue;              // indexer
 41            }
 42
 84743            if (skip.Contains(p.Name))
 44            {
 45                continue;              // infrastructure
 46            }
 47
 77048            p.SetValue(dest, p.GetValue(src));
 49        }
 50
 51        // ── 2. deep-copy the Limits object (property itself is read-only) ──
 7752        CopyLimits(dest.Limits, src.Limits);
 7753    }
 54
 55    private static void CopyLimits(KestrelServerLimits dest, KestrelServerLimits src)
 56    {
 231057        foreach (var p in typeof(KestrelServerLimits)
 7758                                   .GetProperties(BindingFlags.Public | BindingFlags.Instance))
 59        {
 107860            if (!p.CanRead || !p.CanWrite)
 61            {
 62                continue;
 63            }
 64
 92465            if (p.GetIndexParameters().Length > 0)
 66            {
 67                continue;
 68            }
 69
 92470            p.SetValue(dest, p.GetValue(src));
 71        }
 7772    }
 73}